summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-papr-pmem2
-rw-r--r--Documentation/ABI/testing/sysfs-devices-system-cpu3
-rw-r--r--Documentation/ABI/testing/sysfs-firmware-dmi-entries2
-rw-r--r--Documentation/PCI/pci-error-recovery.rst4
-rw-r--r--Documentation/admin-guide/cgroup-v2.rst10
-rw-r--r--Documentation/admin-guide/dynamic-debug-howto.rst2
-rw-r--r--Documentation/admin-guide/efi-stub.rst2
-rw-r--r--Documentation/admin-guide/hw-vuln/mds.rst34
-rw-r--r--Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst13
-rw-r--r--Documentation/admin-guide/hw-vuln/tsx_async_abort.rst33
-rw-r--r--Documentation/admin-guide/kdump/kdump.rst37
-rw-r--r--Documentation/admin-guide/kdump/vmcoreinfo.rst30
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt8
-rw-r--r--Documentation/admin-guide/mm/memory-hotplug.rst12
-rw-r--r--Documentation/admin-guide/perf/ampere_cspmu.rst29
-rw-r--r--Documentation/admin-guide/perf/index.rst1
-rw-r--r--Documentation/admin-guide/spkguide.txt11
-rw-r--r--Documentation/admin-guide/sysctl/fs.rst16
-rw-r--r--Documentation/admin-guide/sysctl/kernel.rst23
-rw-r--r--Documentation/admin-guide/sysctl/vm.rst4
-rw-r--r--Documentation/arch/arm64/cpu-feature-registers.rst2
-rw-r--r--Documentation/arch/arm64/elf_hwcaps.rst9
-rw-r--r--Documentation/arch/ia64/aliasing.rst246
-rw-r--r--Documentation/arch/ia64/efirtc.rst144
-rw-r--r--Documentation/arch/ia64/err_inject.rst1067
-rw-r--r--Documentation/arch/ia64/features.rst3
-rw-r--r--Documentation/arch/ia64/fsys.rst303
-rw-r--r--Documentation/arch/ia64/ia64.rst49
-rw-r--r--Documentation/arch/ia64/index.rst19
-rw-r--r--Documentation/arch/ia64/irq-redir.rst80
-rw-r--r--Documentation/arch/ia64/mca.rst198
-rw-r--r--Documentation/arch/ia64/serial.rst165
-rw-r--r--Documentation/arch/index.rst5
-rw-r--r--Documentation/arch/powerpc/associativity.rst (renamed from Documentation/powerpc/associativity.rst)0
-rw-r--r--Documentation/arch/powerpc/booting.rst (renamed from Documentation/powerpc/booting.rst)0
-rw-r--r--Documentation/arch/powerpc/bootwrapper.rst (renamed from Documentation/powerpc/bootwrapper.rst)0
-rw-r--r--Documentation/arch/powerpc/cpu_families.rst (renamed from Documentation/powerpc/cpu_families.rst)0
-rw-r--r--Documentation/arch/powerpc/cpu_features.rst (renamed from Documentation/powerpc/cpu_features.rst)0
-rw-r--r--Documentation/arch/powerpc/cxl.rst (renamed from Documentation/powerpc/cxl.rst)0
-rw-r--r--Documentation/arch/powerpc/cxlflash.rst (renamed from Documentation/powerpc/cxlflash.rst)2
-rw-r--r--Documentation/arch/powerpc/dawr-power9.rst (renamed from Documentation/powerpc/dawr-power9.rst)0
-rw-r--r--Documentation/arch/powerpc/dexcr.rst (renamed from Documentation/powerpc/dexcr.rst)0
-rw-r--r--Documentation/arch/powerpc/dscr.rst (renamed from Documentation/powerpc/dscr.rst)0
-rw-r--r--Documentation/arch/powerpc/eeh-pci-error-recovery.rst (renamed from Documentation/powerpc/eeh-pci-error-recovery.rst)0
-rw-r--r--Documentation/arch/powerpc/elf_hwcaps.rst (renamed from Documentation/powerpc/elf_hwcaps.rst)6
-rw-r--r--Documentation/arch/powerpc/elfnote.rst (renamed from Documentation/powerpc/elfnote.rst)0
-rw-r--r--Documentation/arch/powerpc/features.rst (renamed from Documentation/powerpc/features.rst)0
-rw-r--r--Documentation/arch/powerpc/firmware-assisted-dump.rst (renamed from Documentation/powerpc/firmware-assisted-dump.rst)0
-rw-r--r--Documentation/arch/powerpc/hvcs.rst (renamed from Documentation/powerpc/hvcs.rst)0
-rw-r--r--Documentation/arch/powerpc/imc.rst (renamed from Documentation/powerpc/imc.rst)0
-rw-r--r--Documentation/arch/powerpc/index.rst (renamed from Documentation/powerpc/index.rst)0
-rw-r--r--Documentation/arch/powerpc/isa-versions.rst (renamed from Documentation/powerpc/isa-versions.rst)0
-rw-r--r--Documentation/arch/powerpc/kasan.txt (renamed from Documentation/powerpc/kasan.txt)0
-rw-r--r--Documentation/arch/powerpc/kaslr-booke32.rst (renamed from Documentation/powerpc/kaslr-booke32.rst)0
-rw-r--r--Documentation/arch/powerpc/mpc52xx.rst (renamed from Documentation/powerpc/mpc52xx.rst)0
-rw-r--r--Documentation/arch/powerpc/papr_hcalls.rst (renamed from Documentation/powerpc/papr_hcalls.rst)0
-rw-r--r--Documentation/arch/powerpc/pci_iov_resource_on_powernv.rst (renamed from Documentation/powerpc/pci_iov_resource_on_powernv.rst)0
-rw-r--r--Documentation/arch/powerpc/pmu-ebb.rst (renamed from Documentation/powerpc/pmu-ebb.rst)0
-rw-r--r--Documentation/arch/powerpc/ptrace.rst (renamed from Documentation/powerpc/ptrace.rst)0
-rw-r--r--Documentation/arch/powerpc/qe_firmware.rst (renamed from Documentation/powerpc/qe_firmware.rst)0
-rw-r--r--Documentation/arch/powerpc/syscall64-abi.rst (renamed from Documentation/powerpc/syscall64-abi.rst)0
-rw-r--r--Documentation/arch/powerpc/transactional_memory.rst (renamed from Documentation/powerpc/transactional_memory.rst)0
-rw-r--r--Documentation/arch/powerpc/ultravisor.rst (renamed from Documentation/powerpc/ultravisor.rst)0
-rw-r--r--Documentation/arch/powerpc/vas-api.rst (renamed from Documentation/powerpc/vas-api.rst)0
-rw-r--r--Documentation/arch/powerpc/vcpudispatch_stats.rst (renamed from Documentation/powerpc/vcpudispatch_stats.rst)0
-rw-r--r--Documentation/arch/powerpc/vmemmap_dedup.rst (renamed from Documentation/powerpc/vmemmap_dedup.rst)0
-rw-r--r--Documentation/arch/riscv/acpi.rst (renamed from Documentation/riscv/acpi.rst)0
-rw-r--r--Documentation/arch/riscv/boot-image-header.rst (renamed from Documentation/riscv/boot-image-header.rst)0
-rw-r--r--Documentation/arch/riscv/boot.rst (renamed from Documentation/riscv/boot.rst)0
-rw-r--r--Documentation/arch/riscv/features.rst (renamed from Documentation/riscv/features.rst)0
-rw-r--r--Documentation/arch/riscv/hwprobe.rst (renamed from Documentation/riscv/hwprobe.rst)0
-rw-r--r--Documentation/arch/riscv/index.rst (renamed from Documentation/riscv/index.rst)0
-rw-r--r--Documentation/arch/riscv/patch-acceptance.rst (renamed from Documentation/riscv/patch-acceptance.rst)0
-rw-r--r--Documentation/arch/riscv/uabi.rst (renamed from Documentation/riscv/uabi.rst)0
-rw-r--r--Documentation/arch/riscv/vector.rst (renamed from Documentation/riscv/vector.rst)0
-rw-r--r--Documentation/arch/riscv/vm-layout.rst (renamed from Documentation/riscv/vm-layout.rst)0
-rw-r--r--Documentation/block/blk-mq.rst2
-rw-r--r--Documentation/block/ioprio.rst3
-rw-r--r--Documentation/core-api/cpu_hotplug.rst6
-rw-r--r--Documentation/core-api/debugging-via-ohci1394.rst6
-rw-r--r--Documentation/dev-tools/kselftest.rst6
-rw-r--r--Documentation/devicetree/bindings/arm/amd,pensando.yaml26
-rw-r--r--Documentation/devicetree/bindings/arm/amlogic.yaml3
-rw-r--r--Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml1
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-at91.yaml7
-rw-r--r--Documentation/devicetree/bindings/arm/cpus.yaml4
-rw-r--r--Documentation/devicetree/bindings/arm/fsl.yaml43
-rw-r--r--Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml16
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek.yaml16
-rw-r--r--Documentation/devicetree/bindings/arm/qcom.yaml45
-rw-r--r--Documentation/devicetree/bindings/arm/rockchip.yaml25
-rw-r--r--Documentation/devicetree/bindings/arm/sti.yaml23
-rw-r--r--Documentation/devicetree/bindings/arm/stm32/stm32.yaml1
-rw-r--r--Documentation/devicetree/bindings/arm/sunxi.yaml16
-rw-r--r--Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml393
-rw-r--r--Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml2
-rw-r--r--Documentation/devicetree/bindings/cache/qcom,llcc.yaml10
-rw-r--r--Documentation/devicetree/bindings/firmware/arm,scmi.yaml15
-rw-r--r--Documentation/devicetree/bindings/firmware/qcom,scm.yaml10
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml2
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-mswi.yaml43
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ingenic,nemc.yaml1
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml2
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml2
-rw-r--r--Documentation/devicetree/bindings/mmc/npcm,sdhci.yaml45
-rw-r--r--Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml2
-rw-r--r--Documentation/devicetree/bindings/mmc/sdhci-msm.yaml9
-rw-r--r--Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml2
-rw-r--r--Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml4
-rw-r--r--Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml3
-rw-r--r--Documentation/devicetree/bindings/power/mediatek,power-controller.yaml6
-rw-r--r--Documentation/devicetree/bindings/power/power-domain.yaml17
-rw-r--r--Documentation/devicetree/bindings/power/qcom,rpmpd.yaml82
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml1
-rw-r--r--Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.yaml11
-rw-r--r--Documentation/devicetree/bindings/riscv/cpus.yaml1
-rw-r--r--Documentation/devicetree/bindings/riscv/sophgo.yaml32
-rw-r--r--Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml1
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml2
-rw-r--r--Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml1
-rw-r--r--Documentation/devicetree/bindings/soc/renesas/renesas.yaml28
-rw-r--r--Documentation/devicetree/bindings/soc/sti/st,sti-syscon.yaml46
-rw-r--r--Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml416
-rw-r--r--Documentation/devicetree/bindings/timer/sifive,clint.yaml1
-rw-r--r--Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml43
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.yaml22
-rw-r--r--Documentation/doc-guide/contributing.rst4
-rw-r--r--Documentation/driver-api/driver-model/devres.rst14
-rw-r--r--Documentation/driver-api/pps.rst16
-rw-r--r--Documentation/driver-api/pwm.rst6
-rw-r--r--Documentation/features/core/cBPF-JIT/arch-support.txt1
-rw-r--r--Documentation/features/core/eBPF-JIT/arch-support.txt1
-rw-r--r--Documentation/features/core/generic-idle-thread/arch-support.txt1
-rw-r--r--Documentation/features/core/jump-labels/arch-support.txt1
-rw-r--r--Documentation/features/core/thread-info-in-task/arch-support.txt1
-rw-r--r--Documentation/features/core/tracehook/arch-support.txt1
-rw-r--r--Documentation/features/debug/KASAN/arch-support.txt1
-rw-r--r--Documentation/features/debug/debug-vm-pgtable/arch-support.txt1
-rw-r--r--Documentation/features/debug/gcov-profile-all/arch-support.txt1
-rw-r--r--Documentation/features/debug/kcov/arch-support.txt1
-rw-r--r--Documentation/features/debug/kgdb/arch-support.txt1
-rw-r--r--Documentation/features/debug/kmemleak/arch-support.txt1
-rw-r--r--Documentation/features/debug/kprobes-on-ftrace/arch-support.txt1
-rw-r--r--Documentation/features/debug/kprobes/arch-support.txt1
-rw-r--r--Documentation/features/debug/kretprobes/arch-support.txt1
-rw-r--r--Documentation/features/debug/optprobes/arch-support.txt1
-rw-r--r--Documentation/features/debug/stackprotector/arch-support.txt1
-rw-r--r--Documentation/features/debug/uprobes/arch-support.txt1
-rw-r--r--Documentation/features/debug/user-ret-profiler/arch-support.txt1
-rw-r--r--Documentation/features/io/dma-contiguous/arch-support.txt1
-rw-r--r--Documentation/features/locking/cmpxchg-local/arch-support.txt1
-rw-r--r--Documentation/features/locking/lockdep/arch-support.txt1
-rw-r--r--Documentation/features/locking/queued-rwlocks/arch-support.txt1
-rw-r--r--Documentation/features/locking/queued-spinlocks/arch-support.txt1
-rw-r--r--Documentation/features/perf/kprobes-event/arch-support.txt1
-rw-r--r--Documentation/features/perf/perf-regs/arch-support.txt1
-rw-r--r--Documentation/features/perf/perf-stackdump/arch-support.txt1
-rw-r--r--Documentation/features/sched/membarrier-sync-core/arch-support.txt1
-rw-r--r--Documentation/features/sched/numa-balancing/arch-support.txt1
-rw-r--r--Documentation/features/seccomp/seccomp-filter/arch-support.txt1
-rw-r--r--Documentation/features/time/arch-tick-broadcast/arch-support.txt1
-rw-r--r--Documentation/features/time/clockevents/arch-support.txt1
-rw-r--r--Documentation/features/time/context-tracking/arch-support.txt1
-rw-r--r--Documentation/features/time/irq-time-acct/arch-support.txt1
-rw-r--r--Documentation/features/time/virt-cpuacct/arch-support.txt1
-rw-r--r--Documentation/features/vm/ELF-ASLR/arch-support.txt1
-rw-r--r--Documentation/features/vm/PG_uncached/arch-support.txt1
-rw-r--r--Documentation/features/vm/THP/arch-support.txt1
-rw-r--r--Documentation/features/vm/TLB/arch-support.txt1
-rw-r--r--Documentation/features/vm/huge-vmap/arch-support.txt1
-rw-r--r--Documentation/features/vm/ioremap_prot/arch-support.txt1
-rw-r--r--Documentation/features/vm/pte_special/arch-support.txt1
-rw-r--r--Documentation/filesystems/proc.rst8
-rw-r--r--Documentation/filesystems/xfs-online-fsck-design.rst2
-rw-r--r--Documentation/kbuild/makefiles.rst2
-rw-r--r--Documentation/maintainer/maintainer-entry-profile.rst2
-rw-r--r--Documentation/mm/overcommit-accounting.rst3
-rw-r--r--Documentation/mm/page_tables.rst127
-rw-r--r--Documentation/mm/vmemmap_dedup.rst2
-rw-r--r--Documentation/networking/device_drivers/ethernet/neterion/s2io.rst4
-rw-r--r--Documentation/process/backporting.rst604
-rw-r--r--Documentation/process/index.rst3
-rw-r--r--Documentation/process/submitting-patches.rst10
-rw-r--r--Documentation/scheduler/sched-arch.rst4
-rw-r--r--Documentation/security/index.rst1
-rw-r--r--Documentation/security/snp-tdx-threat-model.rst253
-rw-r--r--Documentation/sphinx/cdomain.py4
-rw-r--r--Documentation/sphinx/kernel_abi.py2
-rw-r--r--Documentation/sphinx/kernel_feat.py2
-rw-r--r--Documentation/sphinx/kerneldoc.py4
-rw-r--r--Documentation/sphinx/kfigure.py2
-rwxr-xr-xDocumentation/sphinx/maintainers_include.py8
-rw-r--r--Documentation/subsystem-apis.rst2
-rw-r--r--Documentation/trace/kprobes.rst1
-rw-r--r--Documentation/translations/it_IT/riscv/patch-acceptance.rst2
-rw-r--r--Documentation/translations/sp_SP/process/embargoed-hardware-issues.rst341
-rw-r--r--Documentation/translations/sp_SP/process/index.rst2
-rw-r--r--Documentation/translations/sp_SP/process/security-bugs.rst103
-rw-r--r--Documentation/translations/zh_CN/arch/index.rst3
-rw-r--r--Documentation/translations/zh_CN/arch/riscv/boot-image-header.rst (renamed from Documentation/translations/zh_CN/riscv/boot-image-header.rst)4
-rw-r--r--Documentation/translations/zh_CN/arch/riscv/index.rst (renamed from Documentation/translations/zh_CN/riscv/index.rst)4
-rw-r--r--Documentation/translations/zh_CN/arch/riscv/patch-acceptance.rst (renamed from Documentation/translations/zh_CN/riscv/patch-acceptance.rst)4
-rw-r--r--Documentation/translations/zh_CN/arch/riscv/vm-layout.rst (renamed from Documentation/translations/zh_CN/riscv/vm-layout.rst)4
-rw-r--r--Documentation/translations/zh_CN/core-api/cpu_hotplug.rst6
-rw-r--r--Documentation/translations/zh_CN/index.rst5
-rw-r--r--Documentation/translations/zh_CN/maintainer/maintainer-entry-profile.rst2
-rw-r--r--Documentation/translations/zh_CN/scheduler/sched-arch.rst5
-rw-r--r--Documentation/translations/zh_CN/subsystem-apis.rst110
-rw-r--r--Documentation/translations/zh_TW/admin-guide/README.rst164
-rw-r--r--Documentation/translations/zh_TW/admin-guide/bootconfig.rst294
-rw-r--r--Documentation/translations/zh_TW/admin-guide/bug-bisect.rst10
-rw-r--r--Documentation/translations/zh_TW/admin-guide/bug-hunting.rst38
-rw-r--r--Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst4
-rw-r--r--Documentation/translations/zh_TW/admin-guide/cpu-load.rst8
-rw-r--r--Documentation/translations/zh_TW/admin-guide/cputopology.rst97
-rw-r--r--Documentation/translations/zh_TW/admin-guide/index.rst137
-rw-r--r--Documentation/translations/zh_TW/admin-guide/init.rst36
-rw-r--r--Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst67
-rw-r--r--Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst30
-rw-r--r--Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst264
-rw-r--r--Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst229
-rw-r--r--Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst125
-rw-r--r--Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst592
-rw-r--r--Documentation/translations/zh_TW/admin-guide/mm/index.rst50
-rw-r--r--Documentation/translations/zh_TW/admin-guide/mm/ksm.rst199
-rw-r--r--Documentation/translations/zh_TW/admin-guide/reporting-issues.rst727
-rw-r--r--Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst371
-rw-r--r--Documentation/translations/zh_TW/admin-guide/security-bugs.rst26
-rw-r--r--Documentation/translations/zh_TW/admin-guide/sysrq.rst281
-rw-r--r--Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst84
-rw-r--r--Documentation/translations/zh_TW/admin-guide/unicode.rst10
-rw-r--r--Documentation/translations/zh_TW/arch/arm/Booting176
-rw-r--r--Documentation/translations/zh_TW/arch/arm/kernel_user_helpers.txt285
-rw-r--r--Documentation/translations/zh_TW/arch/arm64/amu.rst6
-rw-r--r--Documentation/translations/zh_TW/arch/arm64/booting.txt28
-rw-r--r--Documentation/translations/zh_TW/arch/arm64/elf_hwcaps.rst10
-rw-r--r--Documentation/translations/zh_TW/arch/arm64/legacy_instructions.txt14
-rw-r--r--Documentation/translations/zh_TW/arch/arm64/memory.txt16
-rw-r--r--Documentation/translations/zh_TW/arch/arm64/perf.rst2
-rw-r--r--Documentation/translations/zh_TW/arch/arm64/silicon-errata.txt28
-rw-r--r--Documentation/translations/zh_TW/arch/arm64/tagged-pointers.txt10
-rw-r--r--Documentation/translations/zh_TW/arch/index.rst29
-rw-r--r--Documentation/translations/zh_TW/arch/loongarch/booting.rst49
-rw-r--r--Documentation/translations/zh_TW/arch/loongarch/features.rst9
-rw-r--r--Documentation/translations/zh_TW/arch/loongarch/index.rst28
-rw-r--r--Documentation/translations/zh_TW/arch/loongarch/introduction.rst354
-rw-r--r--Documentation/translations/zh_TW/arch/loongarch/irq-chip-model.rst158
-rw-r--r--Documentation/translations/zh_TW/arch/mips/booting.rst35
-rw-r--r--Documentation/translations/zh_TW/arch/mips/features.rst14
-rw-r--r--Documentation/translations/zh_TW/arch/mips/index.rst30
-rw-r--r--Documentation/translations/zh_TW/arch/mips/ingenic-tcu.rst73
-rw-r--r--Documentation/translations/zh_TW/arch/openrisc/index.rst33
-rw-r--r--Documentation/translations/zh_TW/arch/openrisc/openrisc_port.rst128
-rw-r--r--Documentation/translations/zh_TW/arch/openrisc/todo.rst24
-rw-r--r--Documentation/translations/zh_TW/arch/parisc/debugging.rst46
-rw-r--r--Documentation/translations/zh_TW/arch/parisc/index.rst32
-rw-r--r--Documentation/translations/zh_TW/arch/parisc/registers.rst157
-rw-r--r--Documentation/translations/zh_TW/cpu-freq/core.rst38
-rw-r--r--Documentation/translations/zh_TW/cpu-freq/cpu-drivers.rst158
-rw-r--r--Documentation/translations/zh_TW/cpu-freq/cpufreq-stats.rst52
-rw-r--r--Documentation/translations/zh_TW/cpu-freq/index.rst13
-rw-r--r--Documentation/translations/zh_TW/dev-tools/gcov.rst265
-rw-r--r--Documentation/translations/zh_TW/dev-tools/gdb-kernel-debugging.rst168
-rw-r--r--Documentation/translations/zh_TW/dev-tools/index.rst43
-rw-r--r--Documentation/translations/zh_TW/dev-tools/kasan.rst463
-rw-r--r--Documentation/translations/zh_TW/dev-tools/sparse.rst (renamed from Documentation/translations/zh_TW/sparse.txt)4
-rw-r--r--Documentation/translations/zh_TW/dev-tools/testing-overview.rst162
-rw-r--r--Documentation/translations/zh_TW/filesystems/debugfs.rst47
-rw-r--r--Documentation/translations/zh_TW/filesystems/index.rst2
-rw-r--r--Documentation/translations/zh_TW/filesystems/sysfs.txt14
-rw-r--r--Documentation/translations/zh_TW/filesystems/tmpfs.rst35
-rw-r--r--Documentation/translations/zh_TW/filesystems/virtiofs.rst9
-rw-r--r--Documentation/translations/zh_TW/index.rst7
-rw-r--r--Documentation/translations/zh_TW/process/1.Intro.rst78
-rw-r--r--Documentation/translations/zh_TW/process/2.Process.rst130
-rw-r--r--Documentation/translations/zh_TW/process/3.Early-stage.rst44
-rw-r--r--Documentation/translations/zh_TW/process/4.Coding.rst104
-rw-r--r--Documentation/translations/zh_TW/process/5.Posting.rst80
-rw-r--r--Documentation/translations/zh_TW/process/6.Followthrough.rst46
-rw-r--r--Documentation/translations/zh_TW/process/7.AdvancedTopics.rst56
-rw-r--r--Documentation/translations/zh_TW/process/8.Conclusion.rst14
-rw-r--r--Documentation/translations/zh_TW/process/code-of-conduct-interpretation.rst52
-rw-r--r--Documentation/translations/zh_TW/process/code-of-conduct.rst18
-rw-r--r--Documentation/translations/zh_TW/process/coding-style.rst405
-rw-r--r--Documentation/translations/zh_TW/process/development-process.rst2
-rw-r--r--Documentation/translations/zh_TW/process/email-clients.rst279
-rw-r--r--Documentation/translations/zh_TW/process/embargoed-hardware-issues.rst76
-rw-r--r--Documentation/translations/zh_TW/process/index.rst5
-rw-r--r--Documentation/translations/zh_TW/process/kernel-driver-statement.rst2
-rw-r--r--Documentation/translations/zh_TW/process/license-rules.rst54
-rw-r--r--Documentation/translations/zh_TW/process/management-style.rst60
-rw-r--r--Documentation/translations/zh_TW/process/stable-api-nonsense.rst86
-rw-r--r--Documentation/translations/zh_TW/process/stable-kernel-rules.rst36
-rw-r--r--Documentation/translations/zh_TW/process/submit-checklist.rst92
-rw-r--r--Documentation/translations/zh_TW/process/submitting-patches.rst749
-rw-r--r--Documentation/translations/zh_TW/process/volatile-considered-harmful.rst32
-rw-r--r--Documentation/usb/gadget_uvc.rst2
-rw-r--r--MAINTAINERS75
-rw-r--r--Makefile8
-rw-r--r--arch/Kconfig1
-rw-r--r--arch/alpha/kernel/syscalls/syscall.tbl4
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/Kconfig.debug12
-rw-r--r--arch/arm/boot/dts/allwinner/Makefile1
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-r40.dtsi2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-v3s-anbernic-rg-nano.dts276
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi35
-rw-r--r--arch/arm/boot/dts/aspeed/Makefile1
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtjade.dts66
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts302
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva-cmc.dts265
-rw-r--r--arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm-ns.dtsi34
-rw-r--r--arch/arm/boot/dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac87u.dts11
-rw-r--r--arch/arm/boot/dts/broadcom/bcm4709-linksys-ea9200.dts38
-rw-r--r--arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts18
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts24
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts8
-rw-r--r--arch/arm/boot/dts/broadcom/bcm5301x.dtsi34
-rw-r--r--arch/arm/boot/dts/broadcom/bcm953012er.dts8
-rw-r--r--arch/arm/boot/dts/intel/ixp/Makefile3
-rw-r--r--arch/arm/boot/dts/intel/ixp/intel-ixp42x-dlink-dsm-g600.dts2
-rw-r--r--arch/arm/boot/dts/intel/ixp/intel-ixp42x-freecom-fsg-3.dts2
-rw-r--r--arch/arm/boot/dts/intel/ixp/intel-ixp42x-iomega-nas100d.dts2
-rw-r--r--arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts4
-rw-r--r--arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-wrv54g.dts2
-rw-r--r--arch/arm/boot/dts/intel/ixp/intel-ixp42x-usrobotics-usr8200.dts229
-rw-r--r--arch/arm/boot/dts/mediatek/mt2701-evb.dts2
-rw-r--r--arch/arm/boot/dts/mediatek/mt6323.dtsi58
-rw-r--r--arch/arm/boot/dts/mediatek/mt7623n.dtsi4
-rw-r--r--arch/arm/boot/dts/mediatek/mt7629-rfb.dts2
-rw-r--r--arch/arm/boot/dts/microchip/Makefile2
-rw-r--r--arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts4
-rw-r--r--arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts600
-rw-r--r--arch/arm/boot/dts/microchip/sama5d4.dtsi2
-rw-r--r--arch/arm/boot/dts/nuvoton/nuvoton-npcm730-gsj.dts4
-rw-r--r--arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts2
-rw-r--r--arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts4
-rw-r--r--arch/arm/boot/dts/nvidia/tegra20-acer-a500-picasso.dts2
-rw-r--r--arch/arm/boot/dts/nvidia/tegra20-asus-tf101.dts2
-rw-r--r--arch/arm/boot/dts/nvidia/tegra30-asus-lvds-display.dtsi2
-rw-r--r--arch/arm/boot/dts/nvidia/tegra30-asus-tf700t.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/Makefile3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx25.dtsi7
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx51.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4-lvds.dts97
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4-rgb.dts112
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4.dtsi45
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53.dtsi4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-b650v3.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-var-mx6customboard.dts247
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi46
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-gw5910.dtsi1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-gw5912.dtsi1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi569
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-aster.dts1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-eval-v3.dts1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris-v2.dts3
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris.dts1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-colibri-eval-v3.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-aster.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-eval-v3.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris-v2.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-emmc.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-nand.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi5
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-aster.dts1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-eval-v3.dts1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris-v2.dts1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris.dts1
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7d-pico-pi.dts4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7s.dtsi7
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/mba6ulx.dtsi9
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx23-evk.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx23-xfi3.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx23.dtsi4
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-apf28dev.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-cfa10049.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-cfa10055.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-cfa10057.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-cfa10058.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-eukrea-mbmx28lc.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-evk.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-m28cu3.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-m28evk.dts2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts6
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28.dtsi6
-rw-r--r--arch/arm/boot/dts/nxp/vf/vfxxx.dtsi27
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts4
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts1
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8064-asus-nexus7-flo.dts1
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8064-ifc6410.dts1
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8064.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/qcom-ipq8064-rb3011.dts55
-rw-r--r--arch/arm/boot/dts/qcom/qcom-ipq8064-v1.0.dtsi122
-rw-r--r--arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi14
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8226.dtsi32
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974.dtsi32
-rw-r--r--arch/arm/boot/dts/qcom/qcom-sdx55.dtsi32
-rw-r--r--arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts4
-rw-r--r--arch/arm/boot/dts/qcom/qcom-sdx65.dtsi7
-rw-r--r--arch/arm/boot/dts/renesas/r7s72100-genmai.dts82
-rw-r--r--arch/arm/boot/dts/renesas/r7s72100-gr-peach.dts6
-rw-r--r--arch/arm/boot/dts/renesas/r7s72100-rskrza1.dts71
-rw-r--r--arch/arm/boot/dts/renesas/r7s72100.dtsi7
-rw-r--r--arch/arm/boot/dts/renesas/r7s9210-rza2mevb.dts5
-rw-r--r--arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts2
-rw-r--r--arch/arm/boot/dts/renesas/r8a7778-bockw.dts34
-rw-r--r--arch/arm/boot/dts/renesas/r8a7779-marzen.dts32
-rw-r--r--arch/arm/boot/dts/renesas/r8a7779.dtsi7
-rw-r--r--arch/arm/boot/dts/renesas/r8a7790-lager.dts5
-rw-r--r--arch/arm/boot/dts/renesas/r8a7791-koelsch.dts5
-rw-r--r--arch/arm/boot/dts/renesas/r8a7792-blanche.dts34
-rw-r--r--arch/arm/boot/dts/renesas/r8a7792-wheat.dts34
-rw-r--r--arch/arm/boot/dts/renesas/r8a7792.dtsi7
-rw-r--r--arch/arm/boot/dts/renesas/r8a7794-alt.dts5
-rw-r--r--arch/arm/boot/dts/rockchip/rk3128.dtsi61
-rw-r--r--arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts4
-rw-r--r--arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi16
-rw-r--r--arch/arm/boot/dts/rockchip/rv1126.dtsi22
-rw-r--r--arch/arm/boot/dts/samsung/exynos4210.dtsi12
-rw-r--r--arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi41
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-galaxy-s3.dtsi43
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-midas.dtsi8
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-n710x.dts39
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-odroidu3.dts13
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-odroidx.dts9
-rw-r--r--arch/arm/boot/dts/samsung/exynos5422-odroidxu3-audio.dtsi19
-rw-r--r--arch/arm/boot/dts/samsung/exynos5422-odroidxu4.dts2
-rw-r--r--arch/arm/boot/dts/samsung/s5pv210-fascinate4g.dts33
-rw-r--r--arch/arm/boot/dts/samsung/s5pv210-galaxys.dts37
-rw-r--r--arch/arm/boot/dts/st/Makefile1
-rw-r--r--arch/arm/boot/dts/st/spear1310-evb.dts2
-rw-r--r--arch/arm/boot/dts/st/spear1340-evb.dts2
-rw-r--r--arch/arm/boot/dts/st/ste-href-tvk1281618-r2.dtsi4
-rw-r--r--arch/arm/boot/dts/st/stih407-family.dtsi1
-rw-r--r--arch/arm/boot/dts/st/stih418-b2264.dts16
-rw-r--r--arch/arm/boot/dts/st/stm32746g-eval.dts3
-rw-r--r--arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi23
-rw-r--r--arch/arm/boot/dts/st/stm32f746-disco.dts3
-rw-r--r--arch/arm/boot/dts/st/stm32f769-disco.dts3
-rw-r--r--arch/arm/boot/dts/st/stm32mp131.dtsi19
-rw-r--r--arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi342
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-osd32mp1-red.dts225
-rw-r--r--arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi4
-rw-r--r--arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi6
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts57
-rw-r--r--arch/arm/boot/dts/ti/omap/am3517-evm.dts35
-rw-r--r--arch/arm/boot/dts/ti/omap/am3517.dtsi1
-rw-r--r--arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi20
-rw-r--r--arch/arm/boot/dts/ti/omap/omap3-devkit8000-common.dtsi4
-rw-r--r--arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts55
-rw-r--r--arch/arm/configs/aspeed_g4_defconfig1
-rw-r--r--arch/arm/configs/aspeed_g5_defconfig8
-rw-r--r--arch/arm/configs/exynos_defconfig3
-rw-r--r--arch/arm/configs/keystone_defconfig1
-rw-r--r--arch/arm/configs/multi_v7_defconfig7
-rw-r--r--arch/arm/configs/omap2plus_defconfig8
-rw-r--r--arch/arm/configs/s5pv210_defconfig1
-rw-r--r--arch/arm/configs/shmobile_defconfig2
-rw-r--r--arch/arm/kernel/isa.c4
-rw-r--r--arch/arm/mach-shmobile/pm-rcar-gen2.c5
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c9
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c10
-rw-r--r--arch/arm/tools/syscall.tbl3
-rw-r--r--arch/arm/xen/enlighten.c25
-rw-r--r--arch/arm64/Kconfig2
-rw-r--r--arch/arm64/Kconfig.platforms12
-rw-r--r--arch/arm64/boot/dts/allwinner/Makefile2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts35
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi138
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts63
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi7
-rw-r--r--arch/arm64/boot/dts/amd/Makefile1
-rw-r--r--arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts1
-rw-r--r--arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts1
-rw-r--r--arch/arm64/boot/dts/amd/elba-16core.dtsi197
-rw-r--r--arch/arm64/boot/dts/amd/elba-asic-common.dtsi70
-rw-r--r--arch/arm64/boot/dts/amd/elba-asic.dts28
-rw-r--r--arch/arm64/boot/dts/amd/elba-flash-parts.dtsi117
-rw-r--r--arch/arm64/boot/dts/amd/elba.dtsi191
-rw-r--r--arch/arm64/boot/dts/amlogic/Makefile3
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi28
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts147
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-a1.dtsi369
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-axg.dtsi13
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12.dtsi40
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts341
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts10
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-a311d-libretech-cc.dts121
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts10
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts10
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts60
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts39
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi614
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-s4.dtsi20
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-s905d3-libretech-cc.dts89
-rw-r--r--arch/arm64/boot/dts/apm/apm-shadowcat.dtsi2
-rw-r--r--arch/arm64/boot/dts/apm/apm-storm.dtsi2
-rw-r--r--arch/arm64/boot/dts/bitmain/bm1880.dtsi6
-rw-r--r--arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts2
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi27
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7.dtsi1
-rw-r--r--arch/arm64/boot/dts/exynos/exynos850-e850-96.dts73
-rw-r--r--arch/arm64/boot/dts/exynos/exynos850.dtsi30
-rw-r--r--arch/arm64/boot/dts/freescale/Makefile19
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a-tqmls1043a-mbls10xxa.dts49
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a-tqmls1043a.dtsi32
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi14
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1046a-tqmls1046a-mbls10xxa.dts56
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1046a-tqmls1046a.dtsi42
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1088a-tqmls1088a-mbls10xxa.dts64
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1088a-tqmls1088a.dtsi42
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi46
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi7
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts376
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi73
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi11
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi98
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi42
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi117
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi36
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi25
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl-evk.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi38
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi6
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi76
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dts1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-phg.dts5
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts489
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx-lvds-tm070jvhg33.dtso45
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi5
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi11
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts4
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts3
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts3
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts3
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-beacon-baseboard.dtsi38
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2.dts1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtso45
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi5
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts3
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts65
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts3
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts4
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts70
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi154
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts154
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi13
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi10
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso80
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp.dtsi148
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi7
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts14
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-thor96.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33.dtso49
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq.dtsi106
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-mek.dts26
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi56
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-mek.dts26
-rw-r--r--arch/arm64/boot/dts/freescale/imx8ulp.dtsi23
-rw-r--r--arch/arm64/boot/dts/freescale/imx8x-colibri-iris-v2.dtsi4
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts15
-rw-r--r--arch/arm64/boot/dts/freescale/imx93.dtsi159
-rw-r--r--arch/arm64/boot/dts/freescale/mba8mx.dtsi93
-rw-r--r--arch/arm64/boot/dts/freescale/tqmls104xa-mbls10xxa-fman.dtsi104
-rw-r--r--arch/arm64/boot/dts/freescale/tqmls1088a-mbls10xxa-mc.dtsi146
-rw-r--r--arch/arm64/boot/dts/freescale/tqmls10xxa-mbls10xxa.dtsi136
-rw-r--r--arch/arm64/boot/dts/freescale/tqmls10xxa.dtsi58
-rw-r--r--arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi4
-rw-r--r--arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts47
-rw-r--r--arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi8
-rw-r--r--arch/arm64/boot/dts/marvell/cn9130-crb.dtsi4
-rw-r--r--arch/arm64/boot/dts/marvell/cn9130-db.dtsi4
-rw-r--r--arch/arm64/boot/dts/mediatek/Makefile3
-rw-r--r--arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts101
-rw-r--r--arch/arm64/boot/dts/mediatek/mt6795.dtsi253
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts6
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts6
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-evb.dts48
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi40
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts12
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt1015p-rt5682.dtsi19
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt1015p.dtsi26
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt5682.dtsi21
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts19
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r5-sku2.dts64
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts19
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r4.dts77
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi28
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi33
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-demo.dts2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8365.dtsi210
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts901
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra132.dtsi2
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-smaug.dts66
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi33
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi53
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts1
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi33
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts13
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi1
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234.dtsi52
-rw-r--r--arch/arm64/boot/dts/qcom/Makefile12
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-sbc-usb-host.dtso8
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-sbc.dts30
-rw-r--r--arch/arm64/boot/dts/qcom/apq8039-t2.dts8
-rw-r--r--arch/arm64/boot/dts/qcom/apq8096-db820c.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/ipq5018.dtsi8
-rw-r--r--arch/arm64/boot/dts/qcom/ipq5332-rdp468.dts23
-rw-r--r--arch/arm64/boot/dts/qcom/ipq5332.dtsi57
-rw-r--r--arch/arm64/boot/dts/qcom/ipq6018.dtsi36
-rw-r--r--arch/arm64/boot/dts/qcom/ipq8074.dtsi69
-rw-r--r--arch/arm64/boot/dts/qcom/ipq9574.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts21
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts4
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts4
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-gt510.dts86
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-gt58.dts64
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi51
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts5
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-j5x.dts15
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi33
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916.dtsi41
-rw-r--r--arch/arm64/boot/dts/qcom/msm8939-longcheer-l9100.dts334
-rw-r--r--arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts4
-rw-r--r--arch/arm64/boot/dts/qcom/msm8939-sony-xperia-kanuti-tulip.dts8
-rw-r--r--arch/arm64/boot/dts/qcom/msm8939.dtsi39
-rw-r--r--arch/arm64/boot/dts/qcom/msm8976.dtsi15
-rw-r--r--arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996-oneplus-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996.dtsi3
-rw-r--r--arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8998-mtp.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8998-xiaomi-sagit.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8998.dtsi33
-rw-r--r--arch/arm64/boot/dts/qcom/pm6150.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/pm7250b.dtsi14
-rw-r--r--arch/arm64/boot/dts/qcom/pm8150b.dtsi40
-rw-r--r--arch/arm64/boot/dts/qcom/pm8150l.dtsi10
-rw-r--r--arch/arm64/boot/dts/qcom/pm8350c.dtsi6
-rw-r--r--arch/arm64/boot/dts/qcom/pm8916.dtsi3
-rw-r--r--arch/arm64/boot/dts/qcom/pmr735d_a.dtsi (renamed from arch/arm64/boot/dts/qcom/pmr735d.dtsi)45
-rw-r--r--arch/arm64/boot/dts/qcom/pmr735d_b.dtsi59
-rw-r--r--arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts667
-rw-r--r--arch/arm64/boot/dts/qcom/qrb2210-rb1.dts147
-rw-r--r--arch/arm64/boot/dts/qcom/qrb5165-rb5.dts125
-rw-r--r--arch/arm64/boot/dts/qcom/sa8775p-ride.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sa8775p.dtsi8
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi3
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts13
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r10.dts29
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r9.dts7
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r10.dts45
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r4.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r9.dts11
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts23
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts27
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10.dts19
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts5
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts5
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9.dts5
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-parade.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-ti.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-parade.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-ti.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel360.dtsi13
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-rt5682i-sku.dtsi38
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-rt5682s-sku.dtsi38
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe-rt5682s.dts17
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx-rt5682s.dts15
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi27
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180.dtsi187
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi24
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-crd-r3.dts4
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280.dtsi239
-rw-r--r--arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts3
-rw-r--r--arch/arm64/boot/dts/qcom/sc8180x-primus.dts3
-rw-r--r--arch/arm64/boot/dts/qcom/sc8180x.dtsi177
-rw-r--r--arch/arm64/boot/dts/qcom/sdm630.dtsi68
-rw-r--r--arch/arm64/boot/dts/qcom/sdm670.dtsi3
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi32
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-mtp.dts90
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akari.dts170
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts168
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-apollo.dts170
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi91
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845.dtsi130
-rw-r--r--arch/arm64/boot/dts/qcom/sdx75-idp.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts59
-rw-r--r--arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts4
-rw-r--r--arch/arm64/boot/dts/qcom/sm6125.dtsi257
-rw-r--r--arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi423
-rw-r--r--arch/arm64/boot/dts/qcom/sm7125-xiaomi-joyeuse.dts16
-rw-r--r--arch/arm64/boot/dts/qcom/sm7125.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts35
-rw-r--r--arch/arm64/boot/dts/qcom/sm8150.dtsi117
-rw-r--r--arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi5
-rw-r--r--arch/arm64/boot/dts/qcom/sm8250.dtsi554
-rw-r--r--arch/arm64/boot/dts/qcom/sm8350-hdk.dts81
-rw-r--r--arch/arm64/boot/dts/qcom/sm8350-mtp.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sm8350.dtsi5
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450-hdk.dts24
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450-qrd.dts1
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450.dtsi90
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-mtp.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-qrd.dts49
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550.dtsi48
-rw-r--r--arch/arm64/boot/dts/renesas/Makefile38
-rw-r--r--arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/ebisu.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/hihope-rev4.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774a1.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774b1.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774c0.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774e1.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77951.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77960.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77961.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77965.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77990.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77995.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi24
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f0.dtsi134
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts240
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f4.dtsi12
-rw-r--r--arch/arm64/boot/dts/renesas/r9a08g045.dtsi170
-rw-r--r--arch/arm64/boot/dts/renesas/r9a08g045s33-smarc.dts18
-rw-r--r--arch/arm64/boot/dts/renesas/r9a08g045s33.dtsi14
-rw-r--r--arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi14
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi20
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi20
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi24
-rw-r--r--arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi142
-rw-r--r--arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi28
-rw-r--r--arch/arm64/boot/dts/renesas/salvator-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-audio-graph-card-mix+split.dtsi16
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-audio-graph-card.dtsi17
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2-mix+split.dtsi13
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card-mix+split.dtsi57
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card.dtsi27
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2-mix+split.dtsi108
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2.dtsi14
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card-mix+split.dtsi152
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card.dtsi77
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-simple-audio-card-mix+split.dtsi8
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-simple-audio-card.dtsi8
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/Makefile5
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399.dtsi1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts161
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts4
-rw-r--r--arch/arm64/boot/dts/rockchip/rk356x.dtsi7
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts136
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts28
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts848
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts1137
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts145
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dts21
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi614
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts84
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts662
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi44
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s.dtsi40
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi2
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi4
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi2
-rw-r--r--arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi54
-rw-r--r--arch/arm64/boot/dts/st/stm32mp251.dtsi19
-rw-r--r--arch/arm64/boot/dts/st/stm32mp257f-ev1.dts27
-rw-r--r--arch/arm64/boot/dts/ti/Makefile11
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-main.dtsi12
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi6
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62.dtsi3
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts28
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-sk.dts27
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a-main.dtsi60
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a7-sk.dts189
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-main.dtsi766
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi190
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi47
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi69
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p.dtsi7
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p5-sk.dts510
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi16
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-main.dtsi37
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi11
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-evm.dts37
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-sk.dts29
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts84
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi12
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-main.dtsi38
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-base-board.dts7
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso145
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-idk.dtso296
-rw-r--r--arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts56
-rw-r--r--arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi208
-rw-r--r--arch/arm64/boot/dts/ti/k3-am69-sk.dts536
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-main.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi9
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-main.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi9
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi232
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi82
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi208
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-evm.dts117
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi497
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi40
-rw-r--r--arch/arm64/boot/dts/ti/k3-serdes.h2
-rw-r--r--arch/arm64/configs/defconfig19
-rw-r--r--arch/arm64/include/asm/Kbuild2
-rw-r--r--arch/arm64/include/asm/alternative-macros.h8
-rw-r--r--arch/arm64/include/asm/arch_gicv3.h8
-rw-r--r--arch/arm64/include/asm/archrandom.h2
-rw-r--r--arch/arm64/include/asm/cacheflush.h2
-rw-r--r--arch/arm64/include/asm/cpu.h6
-rw-r--r--arch/arm64/include/asm/cpucaps.h67
-rw-r--r--arch/arm64/include/asm/cpufeature.h98
-rw-r--r--arch/arm64/include/asm/cputype.h3
-rw-r--r--arch/arm64/include/asm/fpsimd.h36
-rw-r--r--arch/arm64/include/asm/hwcap.h3
-rw-r--r--arch/arm64/include/asm/irq.h3
-rw-r--r--arch/arm64/include/asm/irqflags.h20
-rw-r--r--arch/arm64/include/asm/kvm_emulate.h4
-rw-r--r--arch/arm64/include/asm/kvm_host.h2
-rw-r--r--arch/arm64/include/asm/kvm_mmu.h2
-rw-r--r--arch/arm64/include/asm/lse.h9
-rw-r--r--arch/arm64/include/asm/mmu.h2
-rw-r--r--arch/arm64/include/asm/mmu_context.h28
-rw-r--r--arch/arm64/include/asm/module.h3
-rw-r--r--arch/arm64/include/asm/mte.h4
-rw-r--r--arch/arm64/include/asm/pgtable-prot.h6
-rw-r--r--arch/arm64/include/asm/pgtable.h34
-rw-r--r--arch/arm64/include/asm/smp.h4
-rw-r--r--arch/arm64/include/asm/spectre.h2
-rw-r--r--arch/arm64/include/asm/tlbflush.h7
-rw-r--r--arch/arm64/include/asm/unistd32.h6
-rw-r--r--arch/arm64/include/asm/vectors.h2
-rw-r--r--arch/arm64/include/uapi/asm/hwcap.h3
-rw-r--r--arch/arm64/kernel/acpi_parking_protocol.c2
-rw-r--r--arch/arm64/kernel/armv8_deprecated.c8
-rw-r--r--arch/arm64/kernel/cpu_errata.c17
-rw-r--r--arch/arm64/kernel/cpufeature.c272
-rw-r--r--arch/arm64/kernel/cpuinfo.c3
-rw-r--r--arch/arm64/kernel/efi.c3
-rw-r--r--arch/arm64/kernel/fpsimd.c151
-rw-r--r--arch/arm64/kernel/idle.c4
-rw-r--r--arch/arm64/kernel/module-plts.c13
-rw-r--r--arch/arm64/kernel/mte.c4
-rw-r--r--arch/arm64/kernel/process.c3
-rw-r--r--arch/arm64/kernel/proton-pack.c2
-rw-r--r--arch/arm64/kernel/smp.c147
-rw-r--r--arch/arm64/kernel/suspend.c13
-rw-r--r--arch/arm64/kernel/sys_compat.c2
-rw-r--r--arch/arm64/kernel/traps.c2
-rw-r--r--arch/arm64/kernel/vdso.c2
-rw-r--r--arch/arm64/kvm/arm.c10
-rw-r--r--arch/arm64/kvm/guest.c6
-rw-r--r--arch/arm64/kvm/hyp/nvhe/ffa.c10
-rw-r--r--arch/arm64/kvm/hyp/pgtable.c4
-rw-r--r--arch/arm64/kvm/mmu.c2
-rw-r--r--arch/arm64/kvm/sys_regs.c2
-rw-r--r--arch/arm64/kvm/vgic/vgic-v3.c2
-rw-r--r--arch/arm64/lib/delay.c2
-rw-r--r--arch/arm64/mm/fault.c2
-rw-r--r--arch/arm64/mm/hugetlbpage.c3
-rw-r--r--arch/arm64/mm/init.c11
-rw-r--r--arch/arm64/mm/mmap.c2
-rw-r--r--arch/arm64/mm/mmu.c3
-rw-r--r--arch/arm64/mm/proc.S3
-rw-r--r--arch/arm64/tools/Makefile4
-rw-r--r--arch/arm64/tools/cpucaps2
-rwxr-xr-xarch/arm64/tools/gen-cpucaps.awk6
-rw-r--r--arch/arm64/tools/sysreg8
-rw-r--r--arch/csky/abiv1/alignment.c1
-rw-r--r--arch/hexagon/include/asm/ptrace.h25
-rw-r--r--arch/hexagon/include/uapi/asm/ptrace.h13
-rw-r--r--arch/ia64/Kbuild3
-rw-r--r--arch/ia64/Kconfig394
-rw-r--r--arch/ia64/Kconfig.debug55
-rw-r--r--arch/ia64/Makefile82
-rw-r--r--arch/ia64/configs/bigsur_defconfig102
-rw-r--r--arch/ia64/configs/generic_defconfig206
-rw-r--r--arch/ia64/configs/gensparse_defconfig184
-rw-r--r--arch/ia64/configs/tiger_defconfig169
-rw-r--r--arch/ia64/configs/zx1_defconfig148
-rw-r--r--arch/ia64/hp/common/Makefile10
-rw-r--r--arch/ia64/hp/common/aml_nfw.c232
-rw-r--r--arch/ia64/hp/common/sba_iommu.c2155
-rw-r--r--arch/ia64/include/asm/Kbuild6
-rw-r--r--arch/ia64/include/asm/acenv.h49
-rw-r--r--arch/ia64/include/asm/acpi-ext.h17
-rw-r--r--arch/ia64/include/asm/acpi.h110
-rw-r--r--arch/ia64/include/asm/asm-offsets.h1
-rw-r--r--arch/ia64/include/asm/asm-prototypes.h30
-rw-r--r--arch/ia64/include/asm/asmmacro.h136
-rw-r--r--arch/ia64/include/asm/atomic.h216
-rw-r--r--arch/ia64/include/asm/barrier.h79
-rw-r--r--arch/ia64/include/asm/bitops.h453
-rw-r--r--arch/ia64/include/asm/bug.h19
-rw-r--r--arch/ia64/include/asm/cache.h30
-rw-r--r--arch/ia64/include/asm/cacheflush.h39
-rw-r--r--arch/ia64/include/asm/checksum.h63
-rw-r--r--arch/ia64/include/asm/clocksource.h11
-rw-r--r--arch/ia64/include/asm/cmpxchg.h33
-rw-r--r--arch/ia64/include/asm/cpu.h18
-rw-r--r--arch/ia64/include/asm/cputime.h21
-rw-r--r--arch/ia64/include/asm/current.h18
-rw-r--r--arch/ia64/include/asm/cyclone.h16
-rw-r--r--arch/ia64/include/asm/delay.h89
-rw-r--r--arch/ia64/include/asm/device.h14
-rw-r--r--arch/ia64/include/asm/div64.h1
-rw-r--r--arch/ia64/include/asm/dma-mapping.h16
-rw-r--r--arch/ia64/include/asm/dma.h17
-rw-r--r--arch/ia64/include/asm/dmi.h15
-rw-r--r--arch/ia64/include/asm/early_ioremap.h11
-rw-r--r--arch/ia64/include/asm/efi.h13
-rw-r--r--arch/ia64/include/asm/elf.h233
-rw-r--r--arch/ia64/include/asm/emergency-restart.h6
-rw-r--r--arch/ia64/include/asm/esi.h30
-rw-r--r--arch/ia64/include/asm/exception.h23
-rw-r--r--arch/ia64/include/asm/extable.h12
-rw-r--r--arch/ia64/include/asm/fb.h42
-rw-r--r--arch/ia64/include/asm/fpswa.h74
-rw-r--r--arch/ia64/include/asm/ftrace.h28
-rw-r--r--arch/ia64/include/asm/futex.h109
-rw-r--r--arch/ia64/include/asm/gcc_intrin.h13
-rw-r--r--arch/ia64/include/asm/hardirq.h27
-rw-r--r--arch/ia64/include/asm/hugetlb.h34
-rw-r--r--arch/ia64/include/asm/hw_irq.h167
-rw-r--r--arch/ia64/include/asm/idle.h8
-rw-r--r--arch/ia64/include/asm/intrinsics.h13
-rw-r--r--arch/ia64/include/asm/io.h271
-rw-r--r--arch/ia64/include/asm/iommu.h22
-rw-r--r--arch/ia64/include/asm/iosapic.h106
-rw-r--r--arch/ia64/include/asm/irq.h37
-rw-r--r--arch/ia64/include/asm/irq_regs.h1
-rw-r--r--arch/ia64/include/asm/irq_remapping.h5
-rw-r--r--arch/ia64/include/asm/irqflags.h95
-rw-r--r--arch/ia64/include/asm/kdebug.h45
-rw-r--r--arch/ia64/include/asm/kexec.h46
-rw-r--r--arch/ia64/include/asm/kprobes.h116
-rw-r--r--arch/ia64/include/asm/kregs.h166
-rw-r--r--arch/ia64/include/asm/libata-portmap.h9
-rw-r--r--arch/ia64/include/asm/linkage.h19
-rw-r--r--arch/ia64/include/asm/local.h1
-rw-r--r--arch/ia64/include/asm/mca.h185
-rw-r--r--arch/ia64/include/asm/mca_asm.h245
-rw-r--r--arch/ia64/include/asm/meminit.h59
-rw-r--r--arch/ia64/include/asm/mman.h18
-rw-r--r--arch/ia64/include/asm/mmiowb.h17
-rw-r--r--arch/ia64/include/asm/mmu.h14
-rw-r--r--arch/ia64/include/asm/mmu_context.h194
-rw-r--r--arch/ia64/include/asm/mmzone.h35
-rw-r--r--arch/ia64/include/asm/module.h35
-rw-r--r--arch/ia64/include/asm/module.lds.h14
-rw-r--r--arch/ia64/include/asm/msidef.h43
-rw-r--r--arch/ia64/include/asm/native/inst.h119
-rw-r--r--arch/ia64/include/asm/native/irq.h20
-rw-r--r--arch/ia64/include/asm/native/patchlist.h24
-rw-r--r--arch/ia64/include/asm/nodedata.h63
-rw-r--r--arch/ia64/include/asm/numa.h83
-rw-r--r--arch/ia64/include/asm/page.h208
-rw-r--r--arch/ia64/include/asm/pal.h1827
-rw-r--r--arch/ia64/include/asm/param.h18
-rw-r--r--arch/ia64/include/asm/parport.h20
-rw-r--r--arch/ia64/include/asm/patch.h28
-rw-r--r--arch/ia64/include/asm/pci.h66
-rw-r--r--arch/ia64/include/asm/percpu.h53
-rw-r--r--arch/ia64/include/asm/pgalloc.h64
-rw-r--r--arch/ia64/include/asm/pgtable.h545
-rw-r--r--arch/ia64/include/asm/processor.h660
-rw-r--r--arch/ia64/include/asm/ptrace.h146
-rw-r--r--arch/ia64/include/asm/sal.h919
-rw-r--r--arch/ia64/include/asm/sections.h33
-rw-r--r--arch/ia64/include/asm/serial.h17
-rw-r--r--arch/ia64/include/asm/shmparam.h13
-rw-r--r--arch/ia64/include/asm/signal.h33
-rw-r--r--arch/ia64/include/asm/smp.h103
-rw-r--r--arch/ia64/include/asm/sn/intr.h15
-rw-r--r--arch/ia64/include/asm/sn/sn_sal.h124
-rw-r--r--arch/ia64/include/asm/sparsemem.h28
-rw-r--r--arch/ia64/include/asm/spinlock.h265
-rw-r--r--arch/ia64/include/asm/spinlock_types.h22
-rw-r--r--arch/ia64/include/asm/string.h22
-rw-r--r--arch/ia64/include/asm/switch_to.h71
-rw-r--r--arch/ia64/include/asm/syscall.h65
-rw-r--r--arch/ia64/include/asm/thread_info.h131
-rw-r--r--arch/ia64/include/asm/timex.h47
-rw-r--r--arch/ia64/include/asm/tlb.h50
-rw-r--r--arch/ia64/include/asm/tlbflush.h128
-rw-r--r--arch/ia64/include/asm/topology.h56
-rw-r--r--arch/ia64/include/asm/types.h32
-rw-r--r--arch/ia64/include/asm/uaccess.h265
-rw-r--r--arch/ia64/include/asm/uncached.h9
-rw-r--r--arch/ia64/include/asm/unistd.h38
-rw-r--r--arch/ia64/include/asm/unwind.h234
-rw-r--r--arch/ia64/include/asm/user.h53
-rw-r--r--arch/ia64/include/asm/ustack.h12
-rw-r--r--arch/ia64/include/asm/uv/uv.h30
-rw-r--r--arch/ia64/include/asm/uv/uv_hub.h315
-rw-r--r--arch/ia64/include/asm/uv/uv_mmrs.h825
-rw-r--r--arch/ia64/include/asm/vermagic.h15
-rw-r--r--arch/ia64/include/asm/vga.h26
-rw-r--r--arch/ia64/include/asm/vmalloc.h4
-rw-r--r--arch/ia64/include/asm/xor.h30
-rw-r--r--arch/ia64/include/asm/xtp.h46
-rw-r--r--arch/ia64/include/uapi/asm/Kbuild2
-rw-r--r--arch/ia64/include/uapi/asm/auxvec.h14
-rw-r--r--arch/ia64/include/uapi/asm/bitsperlong.h9
-rw-r--r--arch/ia64/include/uapi/asm/break.h23
-rw-r--r--arch/ia64/include/uapi/asm/byteorder.h7
-rw-r--r--arch/ia64/include/uapi/asm/cmpxchg.h138
-rw-r--r--arch/ia64/include/uapi/asm/fcntl.h15
-rw-r--r--arch/ia64/include/uapi/asm/fpu.h67
-rw-r--r--arch/ia64/include/uapi/asm/gcc_intrin.h619
-rw-r--r--arch/ia64/include/uapi/asm/ia64regs.h101
-rw-r--r--arch/ia64/include/uapi/asm/intrinsics.h82
-rw-r--r--arch/ia64/include/uapi/asm/mman.h17
-rw-r--r--arch/ia64/include/uapi/asm/param.h30
-rw-r--r--arch/ia64/include/uapi/asm/posix_types.h9
-rw-r--r--arch/ia64/include/uapi/asm/ptrace.h248
-rw-r--r--arch/ia64/include/uapi/asm/ptrace_offsets.h269
-rw-r--r--arch/ia64/include/uapi/asm/resource.h8
-rw-r--r--arch/ia64/include/uapi/asm/rse.h67
-rw-r--r--arch/ia64/include/uapi/asm/setup.h25
-rw-r--r--arch/ia64/include/uapi/asm/sigcontext.h71
-rw-r--r--arch/ia64/include/uapi/asm/siginfo.h28
-rw-r--r--arch/ia64/include/uapi/asm/signal.h98
-rw-r--r--arch/ia64/include/uapi/asm/stat.h52
-rw-r--r--arch/ia64/include/uapi/asm/statfs.h21
-rw-r--r--arch/ia64/include/uapi/asm/swab.h35
-rw-r--r--arch/ia64/include/uapi/asm/types.h32
-rw-r--r--arch/ia64/include/uapi/asm/ucontext.h13
-rw-r--r--arch/ia64/include/uapi/asm/unistd.h22
-rw-r--r--arch/ia64/include/uapi/asm/ustack.h13
-rwxr-xr-xarch/ia64/install.sh30
-rw-r--r--arch/ia64/kernel/Makefile46
-rw-r--r--arch/ia64/kernel/Makefile.gate29
-rw-r--r--arch/ia64/kernel/acpi-ext.c101
-rw-r--r--arch/ia64/kernel/acpi.c913
-rw-r--r--arch/ia64/kernel/asm-offsets.c289
-rw-r--r--arch/ia64/kernel/audit.c63
-rw-r--r--arch/ia64/kernel/brl_emu.c217
-rw-r--r--arch/ia64/kernel/crash.c257
-rw-r--r--arch/ia64/kernel/crash_dump.c27
-rw-r--r--arch/ia64/kernel/cyclone.c125
-rw-r--r--arch/ia64/kernel/dma-mapping.c9
-rw-r--r--arch/ia64/kernel/efi.c1360
-rw-r--r--arch/ia64/kernel/efi_stub.S87
-rw-r--r--arch/ia64/kernel/elfcore.c77
-rw-r--r--arch/ia64/kernel/entry.S1427
-rw-r--r--arch/ia64/kernel/entry.h83
-rw-r--r--arch/ia64/kernel/err_inject.c273
-rw-r--r--arch/ia64/kernel/esi.c193
-rw-r--r--arch/ia64/kernel/esi_stub.S99
-rw-r--r--arch/ia64/kernel/fsys.S837
-rw-r--r--arch/ia64/kernel/fsyscall_gtod_data.h30
-rw-r--r--arch/ia64/kernel/ftrace.c196
-rw-r--r--arch/ia64/kernel/gate-data.S3
-rw-r--r--arch/ia64/kernel/gate.S380
-rw-r--r--arch/ia64/kernel/gate.lds.S108
-rw-r--r--arch/ia64/kernel/head.S1167
-rw-r--r--arch/ia64/kernel/iosapic.c1137
-rw-r--r--arch/ia64/kernel/irq.c181
-rw-r--r--arch/ia64/kernel/irq.h3
-rw-r--r--arch/ia64/kernel/irq_ia64.c645
-rw-r--r--arch/ia64/kernel/irq_lsapic.c45
-rw-r--r--arch/ia64/kernel/ivt.S1688
-rw-r--r--arch/ia64/kernel/kprobes.c911
-rw-r--r--arch/ia64/kernel/machine_kexec.c163
-rw-r--r--arch/ia64/kernel/mca.c2111
-rw-r--r--arch/ia64/kernel/mca_asm.S1123
-rw-r--r--arch/ia64/kernel/mca_drv.c796
-rw-r--r--arch/ia64/kernel/mca_drv.h123
-rw-r--r--arch/ia64/kernel/mca_drv_asm.S56
-rw-r--r--arch/ia64/kernel/minstate.h251
-rw-r--r--arch/ia64/kernel/module.c959
-rw-r--r--arch/ia64/kernel/msi_ia64.c198
-rw-r--r--arch/ia64/kernel/numa.c73
-rw-r--r--arch/ia64/kernel/pal.S306
-rw-r--r--arch/ia64/kernel/palinfo.c942
-rw-r--r--arch/ia64/kernel/patch.c237
-rw-r--r--arch/ia64/kernel/pci-dma.c33
-rw-r--r--arch/ia64/kernel/perfmon_itanium.h116
-rw-r--r--arch/ia64/kernel/process.c611
-rw-r--r--arch/ia64/kernel/ptrace.c2012
-rw-r--r--arch/ia64/kernel/relocate_kernel.S321
-rw-r--r--arch/ia64/kernel/sal.c400
-rw-r--r--arch/ia64/kernel/salinfo.c646
-rw-r--r--arch/ia64/kernel/setup.c1081
-rw-r--r--arch/ia64/kernel/sigframe.h26
-rw-r--r--arch/ia64/kernel/signal.c412
-rw-r--r--arch/ia64/kernel/smp.c335
-rw-r--r--arch/ia64/kernel/smpboot.c839
-rw-r--r--arch/ia64/kernel/stacktrace.c40
-rw-r--r--arch/ia64/kernel/sys_ia64.c197
-rw-r--r--arch/ia64/kernel/syscalls/Makefile32
-rw-r--r--arch/ia64/kernel/syscalls/syscall.tbl378
-rw-r--r--arch/ia64/kernel/time.c463
-rw-r--r--arch/ia64/kernel/topology.c410
-rw-r--r--arch/ia64/kernel/traps.c612
-rw-r--r--arch/ia64/kernel/unaligned.c1560
-rw-r--r--arch/ia64/kernel/uncached.c273
-rw-r--r--arch/ia64/kernel/unwind.c2320
-rw-r--r--arch/ia64/kernel/unwind_decoder.c460
-rw-r--r--arch/ia64/kernel/unwind_i.h165
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S224
-rw-r--r--arch/ia64/lib/Makefile48
-rw-r--r--arch/ia64/lib/checksum.c102
-rw-r--r--arch/ia64/lib/clear_page.S79
-rw-r--r--arch/ia64/lib/clear_user.S212
-rw-r--r--arch/ia64/lib/copy_page.S101
-rw-r--r--arch/ia64/lib/copy_page_mck.S188
-rw-r--r--arch/ia64/lib/copy_user.S613
-rw-r--r--arch/ia64/lib/csum_partial_copy.c98
-rw-r--r--arch/ia64/lib/do_csum.S324
-rw-r--r--arch/ia64/lib/flush.S119
-rw-r--r--arch/ia64/lib/idiv32.S86
-rw-r--r--arch/ia64/lib/idiv64.S83
-rw-r--r--arch/ia64/lib/io.c51
-rw-r--r--arch/ia64/lib/ip_fast_csum.S148
-rw-r--r--arch/ia64/lib/memcpy.S304
-rw-r--r--arch/ia64/lib/memcpy_mck.S659
-rw-r--r--arch/ia64/lib/memset.S365
-rw-r--r--arch/ia64/lib/strlen.S195
-rw-r--r--arch/ia64/lib/strncpy_from_user.S47
-rw-r--r--arch/ia64/lib/strnlen_user.S48
-rw-r--r--arch/ia64/lib/xor.S181
-rw-r--r--arch/ia64/mm/Makefile11
-rw-r--r--arch/ia64/mm/contig.c208
-rw-r--r--arch/ia64/mm/discontig.c635
-rw-r--r--arch/ia64/mm/extable.c24
-rw-r--r--arch/ia64/mm/fault.c251
-rw-r--r--arch/ia64/mm/hugetlbpage.c186
-rw-r--r--arch/ia64/mm/init.c532
-rw-r--r--arch/ia64/mm/ioremap.c94
-rw-r--r--arch/ia64/mm/numa.c80
-rw-r--r--arch/ia64/mm/tlb.c591
-rw-r--r--arch/ia64/pci/Makefile5
-rw-r--r--arch/ia64/pci/fixup.c80
-rw-r--r--arch/ia64/pci/pci.c576
-rwxr-xr-xarch/ia64/scripts/check-gas16
-rw-r--r--arch/ia64/scripts/check-gas-asm.S2
-rw-r--r--arch/ia64/scripts/check-model.c1
-rw-r--r--arch/ia64/scripts/check-segrel.S5
-rw-r--r--arch/ia64/scripts/check-segrel.lds13
-rw-r--r--arch/ia64/scripts/check-serialize.S2
-rw-r--r--arch/ia64/scripts/check-text-align.S7
-rwxr-xr-xarch/ia64/scripts/toolchain-flags54
-rw-r--r--arch/ia64/scripts/unwcheck.py65
-rw-r--r--arch/ia64/uv/Makefile12
-rw-r--r--arch/ia64/uv/kernel/Makefile12
-rw-r--r--arch/ia64/uv/kernel/setup.c120
-rw-r--r--arch/m68k/68000/entry.S7
-rw-r--r--arch/m68k/Kconfig9
-rw-r--r--arch/m68k/Kconfig.cpu12
-rw-r--r--arch/m68k/amiga/amiga.h5
-rw-r--r--arch/m68k/amiga/amisound.c2
-rw-r--r--arch/m68k/amiga/config.c4
-rw-r--r--arch/m68k/amiga/pcmcia.c3
-rw-r--r--arch/m68k/apollo/apollo.h4
-rw-r--r--arch/m68k/apollo/config.c45
-rw-r--r--arch/m68k/apollo/dn_ints.c8
-rw-r--r--arch/m68k/atari/ataints.c3
-rw-r--r--arch/m68k/atari/atakeyb.c2
-rw-r--r--arch/m68k/atari/atari.h15
-rw-r--r--arch/m68k/atari/atasound.c1
-rw-r--r--arch/m68k/atari/config.c13
-rw-r--r--arch/m68k/atari/stdma.c1
-rw-r--r--arch/m68k/atari/stram.c2
-rw-r--r--arch/m68k/atari/time.c2
-rw-r--r--arch/m68k/bvme6000/config.c7
-rw-r--r--arch/m68k/coldfire/entry.S7
-rw-r--r--arch/m68k/configs/amiga_defconfig1
-rw-r--r--arch/m68k/configs/apollo_defconfig2
-rw-r--r--arch/m68k/configs/atari_defconfig1
-rw-r--r--arch/m68k/configs/bvme6000_defconfig2
-rw-r--r--arch/m68k/configs/hp300_defconfig2
-rw-r--r--arch/m68k/configs/mac_defconfig1
-rw-r--r--arch/m68k/configs/multi_defconfig1
-rw-r--r--arch/m68k/configs/mvme147_defconfig2
-rw-r--r--arch/m68k/configs/mvme16x_defconfig2
-rw-r--r--arch/m68k/configs/q40_defconfig1
-rw-r--r--arch/m68k/configs/sun3_defconfig2
-rw-r--r--arch/m68k/configs/sun3x_defconfig2
-rw-r--r--arch/m68k/configs/virt_defconfig3
-rw-r--r--arch/m68k/emu/natfeat.c9
-rw-r--r--arch/m68k/emu/nfeth.c2
-rw-r--r--arch/m68k/fpsp040/slogn.S88
-rw-r--r--arch/m68k/hp300/time.c2
-rw-r--r--arch/m68k/ifpsp060/Makefile6
-rw-r--r--arch/m68k/include/asm/dvma.h8
-rw-r--r--arch/m68k/include/asm/io_mm.h24
-rw-r--r--arch/m68k/include/asm/irq.h5
-rw-r--r--arch/m68k/include/asm/oplib.h4
-rw-r--r--arch/m68k/include/asm/page_mm.h45
-rw-r--r--arch/m68k/include/asm/pgtable.h9
-rw-r--r--arch/m68k/include/asm/pgtable_no.h1
-rw-r--r--arch/m68k/include/asm/raw_io.h32
-rw-r--r--arch/m68k/include/asm/sun3_pgalloc.h10
-rw-r--r--arch/m68k/include/asm/syscalls.h19
-rw-r--r--arch/m68k/include/asm/tlbflush.h73
-rw-r--r--arch/m68k/kernel/Makefile2
-rw-r--r--arch/m68k/kernel/dma.c34
-rw-r--r--arch/m68k/kernel/early_printk.c4
-rw-r--r--arch/m68k/kernel/entry.S7
-rw-r--r--arch/m68k/kernel/head.S8
-rw-r--r--arch/m68k/kernel/ints.c2
-rw-r--r--arch/m68k/kernel/ints.h7
-rw-r--r--arch/m68k/kernel/process.c1
-rw-r--r--arch/m68k/kernel/process.h8
-rw-r--r--arch/m68k/kernel/ptrace.c2
-rw-r--r--arch/m68k/kernel/ptrace.h6
-rw-r--r--arch/m68k/kernel/setup_mm.c2
-rw-r--r--arch/m68k/kernel/signal.c4
-rw-r--r--arch/m68k/kernel/signal.h7
-rw-r--r--arch/m68k/kernel/sys_m68k.c4
-rw-r--r--arch/m68k/kernel/syscalls/syscall.tbl3
-rw-r--r--arch/m68k/kernel/traps.c19
-rw-r--r--arch/m68k/kernel/traps.h10
-rw-r--r--arch/m68k/kernel/vectors.c3
-rw-r--r--arch/m68k/kernel/vectors.h3
-rw-r--r--arch/m68k/lib/Makefile3
-rw-r--r--arch/m68k/lib/ashldi3.c61
-rw-r--r--arch/m68k/lib/ashrdi3.c62
-rw-r--r--arch/m68k/lib/lshrdi3.c61
-rw-r--r--arch/m68k/lib/muldi3.c1
-rw-r--r--arch/m68k/mac/baboon.c2
-rw-r--r--arch/m68k/mac/config.c14
-rw-r--r--arch/m68k/mac/iop.c2
-rw-r--r--arch/m68k/mac/mac.h25
-rw-r--r--arch/m68k/mac/macboing.c11
-rw-r--r--arch/m68k/mac/misc.c5
-rw-r--r--arch/m68k/mac/oss.c2
-rw-r--r--arch/m68k/mac/psc.c2
-rw-r--r--arch/m68k/mac/via.c2
-rw-r--r--arch/m68k/math-emu/fp_arith.c49
-rw-r--r--arch/m68k/math-emu/fp_arith.h49
-rw-r--r--arch/m68k/math-emu/fp_log.c46
-rw-r--r--arch/m68k/math-emu/fp_log.h44
-rw-r--r--arch/m68k/math-emu/fp_trig.c54
-rw-r--r--arch/m68k/math-emu/fp_trig.h25
-rw-r--r--arch/m68k/math-emu/multi_arith.h8
-rw-r--r--arch/m68k/mm/fault.c2
-rw-r--r--arch/m68k/mm/fault.h7
-rw-r--r--arch/m68k/mm/hwtest.c2
-rw-r--r--arch/m68k/mm/sun3kmap.c6
-rw-r--r--arch/m68k/mm/sun3mmu.c2
-rw-r--r--arch/m68k/mvme147/config.c7
-rw-r--r--arch/m68k/mvme16x/config.c10
-rw-r--r--arch/m68k/mvme16x/mvme16x.h6
-rw-r--r--arch/m68k/q40/config.c11
-rw-r--r--arch/m68k/q40/q40.h6
-rw-r--r--arch/m68k/q40/q40ints.c2
-rw-r--r--arch/m68k/sun3/config.c13
-rw-r--r--arch/m68k/sun3/idprom.c4
-rw-r--r--arch/m68k/sun3/intersil.c1
-rw-r--r--arch/m68k/sun3/leds.c2
-rw-r--r--arch/m68k/sun3/mmu_emu.c43
-rw-r--r--arch/m68k/sun3/prom/printf.c5
-rw-r--r--arch/m68k/sun3/sun3.h22
-rw-r--r--arch/m68k/sun3/sun3dvma.c17
-rw-r--r--arch/m68k/sun3/sun3ints.c12
-rw-r--r--arch/m68k/sun3x/config.c6
-rw-r--r--arch/m68k/sun3x/dvma.c5
-rw-r--r--arch/m68k/sun3x/prom.c2
-rw-r--r--arch/microblaze/kernel/syscalls/syscall.tbl3
-rw-r--r--arch/mips/kernel/syscalls/syscall_n32.tbl3
-rw-r--r--arch/mips/kernel/syscalls/syscall_n64.tbl3
-rw-r--r--arch/mips/kernel/syscalls/syscall_o32.tbl3
-rw-r--r--arch/parisc/Kconfig2
-rw-r--r--arch/parisc/boot/Makefile2
-rw-r--r--arch/parisc/include/asm/processor.h1
-rw-r--r--arch/parisc/include/uapi/asm/pdc.h28
-rw-r--r--arch/parisc/kernel/drivers.c4
-rw-r--r--arch/parisc/kernel/entry.S81
-rw-r--r--arch/parisc/kernel/firmware.c14
-rw-r--r--arch/parisc/kernel/processor.c6
-rw-r--r--arch/parisc/kernel/setup.c3
-rw-r--r--arch/parisc/kernel/smp.c8
-rw-r--r--arch/parisc/kernel/syscalls/syscall.tbl3
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S6
-rw-r--r--arch/powerpc/kernel/idle.c1
-rw-r--r--arch/powerpc/kernel/paca.c2
-rw-r--r--arch/powerpc/kernel/syscalls/syscall.tbl3
-rw-r--r--arch/powerpc/kvm/book3s_64_entry.S2
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig6
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c1
-rw-r--r--arch/powerpc/platforms/pseries/plpks_sed_ops.c131
-rw-r--r--arch/riscv/Kconfig.socs6
-rw-r--r--arch/riscv/boot/dts/Makefile1
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-common-regulators.dtsi2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-dongshan-nezha-stu.dts2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-480p.dts2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-720p.dts2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel.dtsi2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv.dts2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1-nezha.dts2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1.dtsi2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1s-mangopi-mq.dts2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi45
-rw-r--r--arch/riscv/boot/dts/allwinner/sunxi-d1-t113.dtsi2
-rw-r--r--arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi2
-rw-r--r--arch/riscv/boot/dts/microchip/mpfs.dtsi15
-rw-r--r--arch/riscv/boot/dts/renesas/r9a07g043f.dtsi13
-rw-r--r--arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi23
-rw-r--r--arch/riscv/boot/dts/renesas/rzfive-smarc.dtsi56
-rw-r--r--arch/riscv/boot/dts/sifive/fu540-c000.dtsi15
-rw-r--r--arch/riscv/boot/dts/sifive/fu740-c000.dtsi15
-rw-r--r--arch/riscv/boot/dts/sophgo/Makefile3
-rw-r--r--arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts38
-rw-r--r--arch/riscv/boot/dts/sophgo/cv1800b.dtsi123
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042-cpus.dtsi2000
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts19
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042.dtsi325
-rw-r--r--arch/riscv/boot/dts/starfive/jh7100.dtsi6
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-pinfunc.h4
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi111
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110.dtsi93
-rw-r--r--arch/riscv/boot/dts/thead/th1520.dtsi12
-rw-r--r--arch/riscv/configs/defconfig3
-rw-r--r--arch/riscv/include/uapi/asm/hwprobe.h2
-rw-r--r--arch/riscv/kernel/sys_riscv.c2
-rw-r--r--arch/riscv/kernel/vector.c1
-rw-r--r--arch/s390/appldata/appldata_base.c4
-rw-r--r--arch/s390/kernel/debug.c1
-rw-r--r--arch/s390/kernel/syscalls/syscall.tbl5
-rw-r--r--arch/s390/kernel/topology.c1
-rw-r--r--arch/s390/mm/cmm.c1
-rw-r--r--arch/s390/mm/pgalloc.c1
-rw-r--r--arch/sh/kernel/syscalls/syscall.tbl3
-rw-r--r--arch/sparc/kernel/syscalls/syscall.tbl3
-rw-r--r--arch/x86/Kconfig12
-rw-r--r--arch/x86/Makefile2
-rw-r--r--arch/x86/boot/compressed/tdx.c6
-rw-r--r--arch/x86/coco/tdx/tdcall.S234
-rw-r--r--arch/x86/coco/tdx/tdx-shared.c28
-rw-r--r--arch/x86/coco/tdx/tdx.c138
-rw-r--r--arch/x86/entry/syscalls/syscall_32.tbl3
-rw-r--r--arch/x86/entry/syscalls/syscall_64.tbl2
-rw-r--r--arch/x86/entry/vdso/vdso32-setup.c1
-rw-r--r--arch/x86/hyperv/ivm.c10
-rw-r--r--arch/x86/include/asm/shared/tdx.h89
-rw-r--r--arch/x86/include/asm/tdx.h11
-rw-r--r--arch/x86/kernel/asm-offsets.c33
-rw-r--r--arch/x86/kernel/cpu/intel.c1
-rw-r--r--arch/x86/kernel/itmt.c1
-rw-r--r--arch/x86/virt/Makefile (renamed from arch/ia64/kernel/.gitignore)3
-rw-r--r--arch/x86/virt/vmx/Makefile2
-rw-r--r--arch/x86/virt/vmx/tdx/Makefile2
-rw-r--r--arch/x86/virt/vmx/tdx/seamcall.S61
-rw-r--r--arch/x86/virt/vmx/tdx/tdxcall.S226
-rw-r--r--arch/xtensa/kernel/syscalls/syscall.tbl3
-rw-r--r--block/Kconfig1
-rw-r--r--block/badblocks.c1618
-rw-r--r--block/blk-flush.c11
-rw-r--r--block/blk-mq-debugfs.c1
-rw-r--r--block/blk-mq.c45
-rw-r--r--block/blk-mq.h57
-rw-r--r--block/partitions/ibm.c98
-rw-r--r--block/sed-opal.c18
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/acpi/Kconfig6
-rw-r--r--drivers/acpi/numa/Kconfig4
-rw-r--r--drivers/acpi/osl.c2
-rw-r--r--drivers/acpi/processor_core.c2
-rw-r--r--drivers/ata/ahci.c6
-rw-r--r--drivers/ata/ahci_imx.c10
-rw-r--r--drivers/ata/ahci_xgene.c11
-rw-r--r--drivers/ata/libahci.c2
-rw-r--r--drivers/ata/libata-core.c185
-rw-r--r--drivers/ata/libata-eh.c54
-rw-r--r--drivers/ata/libata-sata.c5
-rw-r--r--drivers/ata/libata-scsi.c53
-rw-r--r--drivers/ata/libata-sff.c10
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/pata_cs5520.c2
-rw-r--r--drivers/ata/sata_mv.c9
-rw-r--r--drivers/base/firmware_loader/fallback_table.c1
-rw-r--r--drivers/base/power/domain.c11
-rw-r--r--drivers/block/aoe/aoenet.c3
-rw-r--r--drivers/block/null_blk/main.c22
-rw-r--r--drivers/block/ublk_drv.c342
-rw-r--r--drivers/block/virtio_blk.c2
-rw-r--r--drivers/bus/Kconfig2
-rw-r--r--drivers/bus/vexpress-config.c2
-rw-r--r--drivers/cdrom/cdrom.c1
-rw-r--r--drivers/cdx/cdx.c32
-rw-r--r--drivers/cdx/controller/cdx_controller.c4
-rw-r--r--drivers/cdx/controller/mcdi_functions.c58
-rw-r--r--drivers/cdx/controller/mcdi_functions.h13
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/agp/Kconfig16
-rw-r--r--drivers/char/agp/Makefile2
-rw-r--r--drivers/char/agp/hp-agp.c550
-rw-r--r--drivers/char/agp/i460-agp.c659
-rw-r--r--drivers/char/agp/parisc-agp.c16
-rw-r--r--drivers/char/hpet.c31
-rw-r--r--drivers/char/hw_random/Kconfig2
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c1
-rw-r--r--drivers/char/mem.c12
-rw-r--r--drivers/char/mspec.c295
-rw-r--r--drivers/char/random.c1
-rw-r--r--drivers/clk/clk-scmi.c96
-rw-r--r--drivers/clocksource/arm_arch_timer.c36
-rw-r--r--drivers/cpufreq/Kconfig11
-rw-r--r--drivers/cpufreq/Makefile1
-rw-r--r--drivers/cpufreq/ia64-acpi-cpufreq.c353
-rw-r--r--drivers/cpufreq/scmi-cpufreq.c52
-rw-r--r--drivers/firmware/Kconfig39
-rw-r--r--drivers/firmware/Makefile4
-rw-r--r--drivers/firmware/arm_ffa/bus.c16
-rw-r--r--drivers/firmware/arm_ffa/driver.c770
-rw-r--r--drivers/firmware/arm_scmi/Kconfig12
-rw-r--r--drivers/firmware/arm_scmi/Makefile1
-rw-r--r--drivers/firmware/arm_scmi/clock.c402
-rw-r--r--drivers/firmware/arm_scmi/driver.c1
-rw-r--r--drivers/firmware/arm_scmi/perf.c112
-rw-r--r--drivers/firmware/arm_scmi/powercap.c4
-rw-r--r--drivers/firmware/arm_scmi/smc.c35
-rw-r--r--drivers/firmware/arm_scpi.c13
-rw-r--r--drivers/firmware/efi/Kconfig6
-rw-r--r--drivers/firmware/efi/efi.c13
-rw-r--r--drivers/firmware/imx/Kconfig6
-rw-r--r--drivers/firmware/meson/meson_sm.c25
-rw-r--r--drivers/firmware/pcdp.c135
-rw-r--r--drivers/firmware/pcdp.h108
-rw-r--r--drivers/firmware/qcom/Kconfig56
-rw-r--r--drivers/firmware/qcom/Makefile9
-rw-r--r--drivers/firmware/qcom/qcom_qseecom.c120
-rw-r--r--drivers/firmware/qcom/qcom_qseecom_uefisecapp.c871
-rw-r--r--drivers/firmware/qcom/qcom_scm-legacy.c (renamed from drivers/firmware/qcom_scm-legacy.c)0
-rw-r--r--drivers/firmware/qcom/qcom_scm-smc.c (renamed from drivers/firmware/qcom_scm-smc.c)0
-rw-r--r--drivers/firmware/qcom/qcom_scm.c (renamed from drivers/firmware/qcom_scm.c)448
-rw-r--r--drivers/firmware/qcom/qcom_scm.h (renamed from drivers/firmware/qcom_scm.h)16
-rw-r--r--drivers/firmware/raspberrypi.c1
-rw-r--r--drivers/firmware/tegra/bpmp.c30
-rw-r--r--drivers/firmware/ti_sci.c69
-rw-r--r--drivers/gpu/drm/drm_ioc32.c4
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c2
-rw-r--r--drivers/gpu/drm/i915/i915_perf.c1
-rw-r--r--drivers/hv/hv_common.c1
-rw-r--r--drivers/infiniband/core/iwcm.c1
-rw-r--r--drivers/infiniband/core/ucma.c1
-rw-r--r--drivers/input/serio/i8042.h2
-rw-r--r--drivers/iommu/Kconfig8
-rw-r--r--drivers/iommu/amd/Kconfig1
-rw-r--r--drivers/iommu/amd/amd_iommu_types.h12
-rw-r--r--drivers/iommu/amd/io_pgtable.c68
-rw-r--r--drivers/iommu/amd/iommu.c147
-rw-r--r--drivers/iommu/intel/Kconfig3
-rw-r--r--drivers/iommu/intel/Makefile2
-rw-r--r--drivers/iommu/intel/iommu.c156
-rw-r--r--drivers/iommu/intel/iommu.h64
-rw-r--r--drivers/iommu/intel/nested.c117
-rw-r--r--drivers/iommu/intel/pasid.c221
-rw-r--r--drivers/iommu/intel/pasid.h6
-rw-r--r--drivers/iommu/iommufd/Makefile1
-rw-r--r--drivers/iommu/iommufd/device.c174
-rw-r--r--drivers/iommu/iommufd/hw_pagetable.c304
-rw-r--r--drivers/iommu/iommufd/io_pagetable.c200
-rw-r--r--drivers/iommu/iommufd/iommufd_private.h84
-rw-r--r--drivers/iommu/iommufd/iommufd_test.h39
-rw-r--r--drivers/iommu/iommufd/iova_bitmap.c (renamed from drivers/vfio/iova_bitmap.c)5
-rw-r--r--drivers/iommu/iommufd/main.c17
-rw-r--r--drivers/iommu/iommufd/pages.c2
-rw-r--r--drivers/iommu/iommufd/selftest.c326
-rw-r--r--drivers/iommu/iommufd/vfio_compat.c6
-rw-r--r--drivers/irqchip/irq-gic-v3.c82
-rw-r--r--drivers/macintosh/mac_hid.c1
-rw-r--r--drivers/md/dm-cache-metadata.c6
-rw-r--r--drivers/md/dm-crypt.c26
-rw-r--r--drivers/md/dm-delay.c103
-rw-r--r--drivers/md/dm-integrity.c30
-rw-r--r--drivers/md/dm-ioctl.c4
-rw-r--r--drivers/md/dm-linear.c2
-rw-r--r--drivers/md/dm-log-userspace-base.c2
-rw-r--r--drivers/md/dm-raid.c17
-rw-r--r--drivers/md/dm-stripe.c2
-rw-r--r--drivers/md/dm-table.c23
-rw-r--r--drivers/md/dm-target.c106
-rw-r--r--drivers/md/dm.c121
-rw-r--r--drivers/md/dm.h2
-rw-r--r--drivers/md/md-autodetect.c4
-rw-r--r--drivers/md/md-bitmap.c61
-rw-r--r--drivers/md/md-cluster.c15
-rw-r--r--drivers/md/md-linear.c28
-rw-r--r--drivers/md/md-linear.h2
-rw-r--r--drivers/md/md.c823
-rw-r--r--drivers/md/md.h70
-rw-r--r--drivers/md/raid1.c6
-rw-r--r--drivers/md/raid10.c3
-rw-r--r--drivers/md/raid5-cache.c64
-rw-r--r--drivers/md/raid5.c103
-rw-r--r--drivers/media/cec/platform/Kconfig2
-rw-r--r--drivers/memory/atmel-ebi.c16
-rw-r--r--drivers/memory/brcmstb_memc.c9
-rw-r--r--drivers/memory/fsl-corenet-cf.c11
-rw-r--r--drivers/memory/tegra/tegra234.c64
-rw-r--r--drivers/memstick/host/jmb38x_ms.c2
-rw-r--r--drivers/misc/Kconfig2
-rw-r--r--drivers/misc/sgi-gru/gru.h4
-rw-r--r--drivers/misc/sgi-gru/gru_instructions.h12
-rw-r--r--drivers/misc/sgi-gru/grufile.c72
-rw-r--r--drivers/misc/sgi-gru/gruhandles.c6
-rw-r--r--drivers/misc/sgi-gru/grumain.c4
-rw-r--r--drivers/misc/sgi-xp/xp.h2
-rw-r--r--drivers/misc/sgi-xp/xp_uv.c24
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c33
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c85
-rw-r--r--drivers/mmc/core/debugfs.c51
-rw-r--r--drivers/mmc/core/mmc.c7
-rw-r--r--drivers/mmc/core/queue.c6
-rw-r--r--drivers/mmc/host/Kconfig12
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/atmel-mci.c9
-rw-r--r--drivers/mmc/host/dw_mmc-starfive.c137
-rw-r--r--drivers/mmc/host/jz4740_mmc.c15
-rw-r--r--drivers/mmc/host/meson-gx-mmc.c1
-rw-r--r--drivers/mmc/host/mmc_hsq.c22
-rw-r--r--drivers/mmc/host/mmc_hsq.h11
-rw-r--r--drivers/mmc/host/mmci.c3
-rw-r--r--drivers/mmc/host/mmci.h2
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c52
-rw-r--r--drivers/mmc/host/sdhci-npcm.c94
-rw-r--r--drivers/mmc/host/sdhci-pci-core.c5
-rw-r--r--drivers/mmc/host/sdhci-pci-gli.c14
-rw-r--r--drivers/mmc/host/sdhci-pltfm.c38
-rw-r--r--drivers/mmc/host/vub300.c22
-rw-r--r--drivers/net/amt.c1
-rw-r--r--drivers/net/dummy.c1
-rw-r--r--drivers/net/eql.c1
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c2
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.h1
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c86
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c2
-rw-r--r--drivers/net/ifb.c1
-rw-r--r--drivers/net/macvtap.c1
-rw-r--r--drivers/net/netdevsim/netdev.c1
-rw-r--r--drivers/net/sungem_phy.c1
-rw-r--r--drivers/net/tap.c1
-rw-r--r--drivers/net/vrf.c1
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/usb.c1
-rw-r--r--drivers/nvme/common/Kconfig13
-rw-r--r--drivers/nvme/common/Makefile3
-rw-r--r--drivers/nvme/common/auth.c68
-rw-r--r--drivers/nvme/common/keyring.c182
-rw-r--r--drivers/nvme/host/Kconfig24
-rw-r--r--drivers/nvme/host/Makefile2
-rw-r--r--drivers/nvme/host/auth.c30
-rw-r--r--drivers/nvme/host/core.c14
-rw-r--r--drivers/nvme/host/fabrics.c67
-rw-r--r--drivers/nvme/host/fabrics.h9
-rw-r--r--drivers/nvme/host/nvme.h5
-rw-r--r--drivers/nvme/host/pci.c1
-rw-r--r--drivers/nvme/host/sysfs.c27
-rw-r--r--drivers/nvme/host/tcp.c184
-rw-r--r--drivers/nvme/target/Kconfig22
-rw-r--r--drivers/nvme/target/auth.c31
-rw-r--r--drivers/nvme/target/configfs.c128
-rw-r--r--drivers/nvme/target/fc.c3
-rw-r--r--drivers/nvme/target/nvmet.h11
-rw-r--r--drivers/nvme/target/tcp.c341
-rw-r--r--drivers/parisc/power.c67
-rw-r--r--drivers/parisc/sba_iommu.c2
-rw-r--r--drivers/parport/procfs.c28
-rw-r--r--drivers/pci/vgaarb.c2
-rw-r--r--drivers/perf/amlogic/meson_g12_ddr_pmu.c1
-rw-r--r--drivers/perf/arm-cmn.c154
-rw-r--r--drivers/perf/arm_cspmu/Kconfig19
-rw-r--r--drivers/perf/arm_cspmu/Makefile8
-rw-r--r--drivers/perf/arm_cspmu/ampere_cspmu.c272
-rw-r--r--drivers/perf/arm_cspmu/arm_cspmu.c201
-rw-r--r--drivers/perf/arm_cspmu/arm_cspmu.h32
-rw-r--r--drivers/perf/arm_cspmu/nvidia_cspmu.c34
-rw-r--r--drivers/perf/arm_cspmu/nvidia_cspmu.h17
-rw-r--r--drivers/perf/arm_pmuv3.c47
-rw-r--r--drivers/perf/hisilicon/hisi_pcie_pmu.c9
-rw-r--r--drivers/perf/hisilicon/hisi_uncore_pa_pmu.c4
-rw-r--r--drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c4
-rw-r--r--drivers/perf/hisilicon/hns3_pmu.c8
-rw-r--r--drivers/perf/xgene_pmu.c37
-rw-r--r--drivers/pmdomain/Kconfig21
-rw-r--r--drivers/pmdomain/Makefile1
-rw-r--r--drivers/pmdomain/actions/Kconfig (renamed from drivers/soc/actions/Kconfig)0
-rw-r--r--drivers/pmdomain/actions/owl-sps.c16
-rw-r--r--drivers/pmdomain/amlogic/Kconfig39
-rw-r--r--drivers/pmdomain/amlogic/meson-ee-pwrc.c2
-rw-r--r--drivers/pmdomain/amlogic/meson-secure-pwrc.c127
-rw-r--r--drivers/pmdomain/apple/Kconfig18
-rw-r--r--drivers/pmdomain/arm/Makefile4
-rw-r--r--drivers/pmdomain/arm/scmi_perf_domain.c184
-rw-r--r--drivers/pmdomain/arm/scmi_pm_domain.c (renamed from drivers/firmware/arm_scmi/scmi_pm_domain.c)0
-rw-r--r--drivers/pmdomain/bcm/Kconfig42
-rw-r--r--drivers/pmdomain/bcm/bcm2835-power.c2
-rw-r--r--drivers/pmdomain/imx/Kconfig29
-rw-r--r--drivers/pmdomain/imx/gpc.c8
-rw-r--r--drivers/pmdomain/mediatek/Kconfig29
-rw-r--r--drivers/pmdomain/mediatek/mt6795-pm-domains.h16
-rw-r--r--drivers/pmdomain/mediatek/mt8167-pm-domains.h20
-rw-r--r--drivers/pmdomain/mediatek/mt8173-pm-domains.h16
-rw-r--r--drivers/pmdomain/mediatek/mt8183-pm-domains.h125
-rw-r--r--drivers/pmdomain/mediatek/mt8186-pm-domains.h236
-rw-r--r--drivers/pmdomain/mediatek/mt8188-pm-domains.h223
-rw-r--r--drivers/pmdomain/mediatek/mt8192-pm-domains.h112
-rw-r--r--drivers/pmdomain/mediatek/mt8195-pm-domains.h199
-rw-r--r--drivers/pmdomain/mediatek/mt8365-pm-domains.h197
-rw-r--r--drivers/pmdomain/mediatek/mtk-pm-domains.c157
-rw-r--r--drivers/pmdomain/mediatek/mtk-pm-domains.h51
-rw-r--r--drivers/pmdomain/qcom/Kconfig41
-rw-r--r--drivers/pmdomain/qcom/cpr.c7
-rw-r--r--drivers/pmdomain/qcom/rpmhpd.c83
-rw-r--r--drivers/pmdomain/qcom/rpmpd.c98
-rw-r--r--drivers/pmdomain/renesas/Kconfig109
-rw-r--r--drivers/pmdomain/renesas/rmobile-sysc.c2
-rw-r--r--drivers/pmdomain/rockchip/Kconfig16
-rw-r--r--drivers/pmdomain/rockchip/pm-domains.c13
-rw-r--r--drivers/pmdomain/samsung/Kconfig8
-rw-r--r--drivers/pmdomain/st/Kconfig5
-rw-r--r--drivers/pmdomain/st/Makefile2
-rw-r--r--drivers/pmdomain/starfive/Kconfig (renamed from drivers/soc/starfive/Kconfig)4
-rw-r--r--drivers/pmdomain/starfive/jh71xx-pmu.c139
-rw-r--r--drivers/pmdomain/sunxi/Kconfig10
-rw-r--r--drivers/pmdomain/tegra/Kconfig6
-rw-r--r--drivers/pmdomain/ti/Kconfig22
-rw-r--r--drivers/pmdomain/ti/Makefile2
-rw-r--r--drivers/pmdomain/ti/ti_sci_pm_domains.c8
-rw-r--r--drivers/pmdomain/xilinx/Kconfig10
-rw-r--r--drivers/scsi/scsi_sysctl.c1
-rw-r--r--drivers/scsi/sd.c9
-rw-r--r--drivers/scsi/sg.c1
-rw-r--r--drivers/soc/Kconfig2
-rw-r--r--drivers/soc/amlogic/Kconfig35
-rw-r--r--drivers/soc/apple/Kconfig13
-rw-r--r--drivers/soc/aspeed/aspeed-lpc-ctrl.c6
-rw-r--r--drivers/soc/aspeed/aspeed-lpc-snoop.c6
-rw-r--r--drivers/soc/aspeed/aspeed-p2a-ctrl.c6
-rw-r--r--drivers/soc/aspeed/aspeed-uart-routing.c6
-rw-r--r--drivers/soc/bcm/Kconfig53
-rw-r--r--drivers/soc/dove/pmu.c5
-rw-r--r--drivers/soc/fsl/dpaa2-console.c6
-rw-r--r--drivers/soc/fsl/qe/qe.c2
-rw-r--r--drivers/soc/fsl/qe/qmc.c6
-rw-r--r--drivers/soc/fsl/qe/tsa.c5
-rw-r--r--drivers/soc/fujitsu/a64fx-diag.c6
-rw-r--r--drivers/soc/hisilicon/kunpeng_hccs.c6
-rw-r--r--drivers/soc/imx/Kconfig19
-rw-r--r--drivers/soc/ixp4xx/ixp4xx-npe.c6
-rw-r--r--drivers/soc/ixp4xx/ixp4xx-qmgr.c5
-rw-r--r--drivers/soc/litex/litex_soc_ctrl.c5
-rw-r--r--drivers/soc/loongson/loongson2_guts.c6
-rw-r--r--drivers/soc/mediatek/Kconfig23
-rw-r--r--drivers/soc/mediatek/mtk-devapc.c6
-rw-r--r--drivers/soc/mediatek/mtk-mmsys.c6
-rw-r--r--drivers/soc/mediatek/mtk-svs.c184
-rw-r--r--drivers/soc/microchip/mpfs-sys-controller.c6
-rw-r--r--drivers/soc/pxa/ssp.c6
-rw-r--r--drivers/soc/qcom/Kconfig37
-rw-r--r--drivers/soc/qcom/apr.c4
-rw-r--r--drivers/soc/qcom/cmd-db.c8
-rw-r--r--drivers/soc/qcom/icc-bwmon.c6
-rw-r--r--drivers/soc/qcom/kryo-l2-accessors.c4
-rw-r--r--drivers/soc/qcom/llcc-qcom.c367
-rw-r--r--drivers/soc/qcom/ocmem.c12
-rw-r--r--drivers/soc/qcom/pdr_interface.c8
-rw-r--r--drivers/soc/qcom/pmic_glink.c6
-rw-r--r--drivers/soc/qcom/pmic_glink_altmode.c46
-rw-r--r--drivers/soc/qcom/qcom-geni-se.c38
-rw-r--r--drivers/soc/qcom/qcom_aoss.c12
-rw-r--r--drivers/soc/qcom/qcom_gsbi.c6
-rw-r--r--drivers/soc/qcom/qcom_stats.c6
-rw-r--r--drivers/soc/qcom/qmi_encdec.c6
-rw-r--r--drivers/soc/qcom/qmi_interface.c20
-rw-r--r--drivers/soc/qcom/rmtfs_mem.c15
-rw-r--r--drivers/soc/qcom/rpmh.c8
-rw-r--r--drivers/soc/qcom/smd-rpm.c2
-rw-r--r--drivers/soc/qcom/smem.c10
-rw-r--r--drivers/soc/qcom/smp2p.c6
-rw-r--r--drivers/soc/qcom/smsm.c6
-rw-r--r--drivers/soc/qcom/socinfo.c17
-rw-r--r--drivers/soc/qcom/wcnss_ctrl.c3
-rw-r--r--drivers/soc/renesas/Kconfig111
-rw-r--r--drivers/soc/renesas/renesas-soc.c15
-rw-r--r--drivers/soc/rockchip/Kconfig12
-rw-r--r--drivers/soc/rockchip/io-domain.c6
-rw-r--r--drivers/soc/samsung/Kconfig4
-rw-r--r--drivers/soc/samsung/exynos-chipid.c6
-rw-r--r--drivers/soc/sifive/Kconfig2
-rw-r--r--drivers/soc/sunxi/Kconfig9
-rw-r--r--drivers/soc/tegra/Kconfig5
-rw-r--r--drivers/soc/tegra/cbb/tegra194-cbb.c6
-rw-r--r--drivers/soc/tegra/pmc.c8
-rw-r--r--drivers/soc/ti/Kconfig12
-rw-r--r--drivers/soc/ti/k3-ringacc.c5
-rw-r--r--drivers/soc/ti/k3-socinfo.c7
-rw-r--r--drivers/soc/ti/knav_dma.c6
-rw-r--r--drivers/soc/ti/knav_qmss_queue.c13
-rw-r--r--drivers/soc/ti/pm33xx.c5
-rw-r--r--drivers/soc/ti/pruss.c6
-rw-r--r--drivers/soc/ti/smartreflex.c5
-rw-r--r--drivers/soc/ti/wkup_m3_ipc.c6
-rw-r--r--drivers/soc/xilinx/Kconfig9
-rw-r--r--drivers/tty/hvc/hvcs.c2
-rw-r--r--drivers/tty/serial/8250/Kconfig2
-rw-r--r--drivers/tty/tty_io.c1
-rw-r--r--drivers/tty/vt/keyboard.c2
-rw-r--r--drivers/vfio/Makefile3
-rw-r--r--drivers/vfio/cdx/main.c57
-rw-r--r--drivers/vfio/cdx/private.h2
-rw-r--r--drivers/vfio/pci/mlx5/Kconfig1
-rw-r--r--drivers/vfio/pci/mlx5/cmd.c103
-rw-r--r--drivers/vfio/pci/mlx5/cmd.h28
-rw-r--r--drivers/vfio/pci/mlx5/main.c284
-rw-r--r--drivers/vfio/pci/pds/Kconfig1
-rw-r--r--drivers/vfio/pci/pds/pci_drv.c1
-rw-r--r--drivers/vfio/vfio_main.c11
-rw-r--r--drivers/video/fbdev/Kconfig2
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/xen/Kconfig8
-rw-r--r--drivers/xen/balloon.c1
-rw-r--r--drivers/xen/events/events_base.c3
-rw-r--r--drivers/xen/evtchn.c2
-rw-r--r--drivers/xen/privcmd.c407
-rw-r--r--drivers/xen/xen-pciback/conf_space.c19
-rw-r--r--drivers/xen/xen-pciback/conf_space_capability.c8
-rw-r--r--drivers/xen/xen-pciback/conf_space_header.c21
-rw-r--r--drivers/xen/xenbus/xenbus_dev_frontend.c4
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c2
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/afs/main.c2
-rw-r--r--fs/proc/bootconfig.c6
-rw-r--r--fs/proc/proc_sysctl.c8
-rw-r--r--fs/xfs/xfs_ioctl32.h2
-rw-r--r--include/asm-generic/Kbuild2
-rw-r--r--include/dt-bindings/arm/qcom,ids.h5
-rw-r--r--include/dt-bindings/power/amlogic,t7-pwrc.h63
-rw-r--r--include/dt-bindings/power/mediatek,mt8365-power.h19
-rw-r--r--include/dt-bindings/power/qcom,rpmhpd.h2
-rw-r--r--include/dt-bindings/power/qcom-rpmpd.h21
-rw-r--r--include/dt-bindings/power/starfive,jh7110-pmu.h6
-rw-r--r--include/kunit/test.h14
-rw-r--r--include/linux/acpi.h14
-rw-r--r--include/linux/arm_ffa.h79
-rw-r--r--include/linux/badblocks.h30
-rw-r--r--include/linux/blk-mq.h2
-rw-r--r--include/linux/bpf-cgroup.h9
-rw-r--r--include/linux/cdx/cdx_bus.h18
-rw-r--r--include/linux/compat.h1
-rw-r--r--include/linux/cpuhotplug.h2
-rw-r--r--include/linux/efi.h7
-rw-r--r--include/linux/firmware/meson/meson_sm.h2
-rw-r--r--include/linux/firmware/qcom/qcom_qseecom.h52
-rw-r--r--include/linux/firmware/qcom/qcom_scm.h123
-rw-r--r--include/linux/freelist.h129
-rw-r--r--include/linux/io-pgtable.h4
-rw-r--r--include/linux/io_uring.h19
-rw-r--r--include/linux/io_uring_types.h15
-rw-r--r--include/linux/iommu.h146
-rw-r--r--include/linux/iova_bitmap.h26
-rw-r--r--include/linux/key.h1
-rw-r--r--include/linux/kprobes.h11
-rw-r--r--include/linux/libata.h25
-rw-r--r--include/linux/mm.h2
-rw-r--r--include/linux/mmc/host.h1
-rw-r--r--include/linux/moduleparam.h2
-rw-r--r--include/linux/nvme-auth.h7
-rw-r--r--include/linux/nvme-keyring.h36
-rw-r--r--include/linux/nvme-tcp.h6
-rw-r--r--include/linux/nvme.h10
-rw-r--r--include/linux/nvmem-consumer.h6
-rw-r--r--include/linux/objpool.h181
-rw-r--r--include/linux/pm_domain.h5
-rw-r--r--include/linux/raid/pq.h2
-rw-r--r--include/linux/rethook.h16
-rw-r--r--include/linux/sched/signal.h17
-rw-r--r--include/linux/scmi_protocol.h43
-rw-r--r--include/linux/sed-opal-key.h26
-rw-r--r--include/linux/soc/mediatek/infracfg.h41
-rw-r--r--include/linux/soc/qcom/llcc-qcom.h2
-rw-r--r--include/linux/syscalls.h1
-rw-r--r--include/linux/sysctl.h6
-rw-r--r--include/linux/ucs2_string.h1
-rw-r--r--include/net/gro.h2
-rw-r--r--include/net/ipv6_stubs.h3
-rw-r--r--include/net/sock.h6
-rw-r--r--include/net/xfrm.h18
-rw-r--r--include/scsi/scsi_device.h1
-rw-r--r--include/soc/fsl/qe/qe.h2
-rw-r--r--include/soc/tegra/bpmp-abi.h2
-rw-r--r--include/soc/tegra/bpmp.h6
-rw-r--r--include/trace/events/mmflags.h2
-rw-r--r--include/uapi/asm-generic/siginfo.h5
-rw-r--r--include/uapi/asm-generic/unistd.h6
-rw-r--r--include/uapi/linux/io_uring.h20
-rw-r--r--include/uapi/linux/iommufd.h180
-rw-r--r--include/uapi/linux/vfio.h47
-rw-r--r--include/uapi/linux/xfrm.h3
-rw-r--r--include/uapi/xen/privcmd.h22
-rw-r--r--include/video/sticore.h2
-rw-r--r--include/xen/interface/hvm/ioreq.h51
-rw-r--r--init/Kconfig2
-rw-r--r--init/main.c4
-rw-r--r--io_uring/Makefile4
-rw-r--r--io_uring/cancel.c10
-rw-r--r--io_uring/cancel.h4
-rw-r--r--io_uring/futex.c386
-rw-r--r--io_uring/futex.h36
-rw-r--r--io_uring/io_uring.c50
-rw-r--r--io_uring/io_uring.h1
-rw-r--r--io_uring/kbuf.c58
-rw-r--r--io_uring/opdef.c58
-rw-r--r--io_uring/opdef.h2
-rw-r--r--io_uring/poll.c2
-rw-r--r--io_uring/rsrc.c37
-rw-r--r--io_uring/rw.c92
-rw-r--r--io_uring/rw.h2
-rw-r--r--io_uring/uring_cmd.c102
-rw-r--r--io_uring/waitid.c372
-rw-r--r--io_uring/waitid.h15
-rw-r--r--kernel/bpf/cgroup.c25
-rw-r--r--kernel/cpu.c3
-rw-r--r--kernel/dma/Kconfig11
-rw-r--r--kernel/dma/debug.c2
-rw-r--r--kernel/dma/direct.c37
-rw-r--r--kernel/dma/swiotlb.c12
-rw-r--r--kernel/exit.c131
-rw-r--r--kernel/exit.h30
-rw-r--r--kernel/fork.c17
-rw-r--r--kernel/futex/futex.h20
-rw-r--r--kernel/futex/requeue.c3
-rw-r--r--kernel/futex/syscalls.c18
-rw-r--r--kernel/futex/waitwake.c49
-rw-r--r--kernel/kprobes.c91
-rw-r--r--kernel/sched/core.c29
-rw-r--r--kernel/signal.c25
-rw-r--r--kernel/sys_ni.c2
-rw-r--r--kernel/sysctl.c9
-rw-r--r--kernel/trace/fprobe.c28
-rw-r--r--kernel/trace/rethook.c90
-rw-r--r--kernel/trace/trace_eprobe.c5
-rw-r--r--kernel/watchdog.c7
-rw-r--r--lib/Kconfig.debug13
-rw-r--r--lib/Makefile4
-rw-r--r--lib/decompress_unxz.c3
-rw-r--r--lib/kunit/assert.c14
-rw-r--r--lib/kunit/debugfs.c36
-rw-r--r--lib/kunit/executor.c23
-rw-r--r--lib/kunit/executor_test.c36
-rw-r--r--lib/kunit/kunit-example-test.c5
-rw-r--r--lib/kunit/kunit-test.c56
-rw-r--r--lib/kunit/string-stream-test.c525
-rw-r--r--lib/kunit/string-stream.c100
-rw-r--r--lib/kunit/string-stream.h16
-rw-r--r--lib/kunit/test.c56
-rw-r--r--lib/objpool.c280
-rw-r--r--lib/raid6/Makefile4
-rw-r--r--lib/raid6/algos.c4
-rw-r--r--lib/raid6/int.uc9
-rw-r--r--lib/test_objpool.c690
-rw-r--r--lib/ucs2_string.c52
-rw-r--r--lib/xz/Kconfig5
-rw-r--r--mm/mmap.c6
-rw-r--r--net/802/fddi.c1
-rw-r--r--net/802/garp.c1
-rw-r--r--net/802/mrp.c1
-rw-r--r--net/802/p8022.c1
-rw-r--r--net/802/psnap.c1
-rw-r--r--net/802/stp.c1
-rw-r--r--net/8021q/vlan.c1
-rw-r--r--net/core/dev_addr_lists_test.c1
-rw-r--r--net/core/selftests.c1
-rw-r--r--net/core/sock.c8
-rw-r--r--net/ipv4/esp4_offload.c6
-rw-r--r--net/ipv4/icmp.c2
-rw-r--r--net/ipv4/ip_vti.c4
-rw-r--r--net/ipv4/netfilter.c2
-rw-r--r--net/ipv4/tcp_ao.c6
-rw-r--r--net/ipv4/udp.c16
-rw-r--r--net/ipv4/xfrm4_input.c95
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/esp6_offload.c10
-rw-r--r--net/ipv6/icmp.c2
-rw-r--r--net/ipv6/ip6_vti.c4
-rw-r--r--net/ipv6/netfilter.c2
-rw-r--r--net/ipv6/xfrm6_input.c103
-rw-r--r--net/netfilter/nf_nat_proto.c2
-rw-r--r--net/socket.c104
-rw-r--r--net/xfrm/xfrm_input.c6
-rw-r--r--net/xfrm/xfrm_interface_core.c4
-rw-r--r--net/xfrm/xfrm_policy.c299
-rw-r--r--samples/kprobes/kretprobe_example.c2
-rw-r--r--samples/vfio-mdev/mbochs.c2
-rw-r--r--samples/vfio-mdev/mdpy.c2
-rw-r--r--samples/vfio-mdev/mtty.c829
-rwxr-xr-xscripts/headers_install.sh1
-rwxr-xr-xscripts/kernel-doc2
-rw-r--r--security/keys/key.c1
-rw-r--r--tools/arch/ia64/include/asm/barrier.h59
-rw-r--r--tools/arch/ia64/include/uapi/asm/bitsperlong.h9
-rw-r--r--tools/arch/ia64/include/uapi/asm/mman.h7
-rw-r--r--tools/include/io_uring/mini_liburing.h282
-rw-r--r--tools/include/uapi/asm-generic/unistd.h2
-rw-r--r--tools/include/uapi/linux/io_uring.h757
-rw-r--r--tools/objtool/noreturns.h1
-rw-r--r--tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl2
-rw-r--r--tools/perf/arch/powerpc/entry/syscalls/syscall.tbl2
-rw-r--r--tools/perf/arch/s390/entry/syscalls/syscall.tbl2
-rw-r--r--tools/perf/arch/x86/entry/syscalls/syscall_64.tbl2
-rwxr-xr-xtools/power/x86/amd_pstate_tracer/amd_pstate_trace.py3
-rwxr-xr-xtools/testing/selftests/amd-pstate/gitsource.sh17
-rwxr-xr-xtools/testing/selftests/amd-pstate/run.sh21
-rwxr-xr-xtools/testing/selftests/amd-pstate/tbench.sh4
-rw-r--r--tools/testing/selftests/arm64/abi/hwcap.c54
-rw-r--r--tools/testing/selftests/arm64/fp/sve-test.S19
-rw-r--r--tools/testing/selftests/bpf/prog_tests/sockopt.c113
-rw-r--r--tools/testing/selftests/cachestat/test_cachestat.c2
-rw-r--r--tools/testing/selftests/capabilities/Makefile2
-rw-r--r--tools/testing/selftests/capabilities/test_execve.c8
-rw-r--r--tools/testing/selftests/capabilities/validate_cap.c8
-rw-r--r--tools/testing/selftests/clone3/clone3.c265
-rw-r--r--tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c2
-rw-r--r--tools/testing/selftests/clone3/clone3_clear_sighand.c4
-rw-r--r--tools/testing/selftests/clone3/clone3_selftests.h13
-rw-r--r--tools/testing/selftests/clone3/clone3_set_tid.c2
-rw-r--r--tools/testing/selftests/core/close_range_test.c28
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/debugfs_attrs.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/debugfs_duplicate_context_creation.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/debugfs_empty_targets.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/debugfs_huge_count_read_write.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/debugfs_rm_non_contexts.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/debugfs_schemes.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/debugfs_target_ids.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/lru_sort.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/reclaim.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/sysfs.sh0
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/damon/sysfs_update_removed_scheme_dir.sh0
-rw-r--r--tools/testing/selftests/dmabuf-heaps/.gitignore1
-rw-r--r--tools/testing/selftests/efivarfs/create-read.c2
-rw-r--r--tools/testing/selftests/exec/execveat.c87
-rw-r--r--tools/testing/selftests/firmware/fw_namespace.c4
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc6
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc3
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc4
-rw-r--r--tools/testing/selftests/iommu/iommufd.c379
-rw-r--r--tools/testing/selftests/iommu/iommufd_fail_nth.c7
-rw-r--r--tools/testing/selftests/iommu/iommufd_utils.h233
-rw-r--r--tools/testing/selftests/kselftest.h46
-rw-r--r--tools/testing/selftests/kvm/include/test_util.h8
-rw-r--r--tools/testing/selftests/mm/mremap_test.c2
-rw-r--r--tools/testing/selftests/mm/pkey-helpers.h2
-rw-r--r--tools/testing/selftests/net/Makefile1
-rw-r--r--tools/testing/selftests/net/io_uring_zerocopy_tx.c268
-rw-r--r--tools/testing/selftests/openat2/openat2_test.c2
-rw-r--r--tools/testing/selftests/pidfd/pidfd_fdinfo_test.c2
-rw-r--r--tools/testing/selftests/pidfd/pidfd_test.c12
-rw-r--r--tools/testing/selftests/resctrl/Makefile2
-rw-r--r--tools/testing/selftests/resctrl/cache.c7
-rw-r--r--tools/testing/selftests/resctrl/cat_test.c21
-rw-r--r--tools/testing/selftests/resctrl/cmt_test.c37
-rw-r--r--tools/testing/selftests/resctrl/mba_test.c6
-rw-r--r--tools/testing/selftests/resctrl/mbm_test.c11
-rw-r--r--tools/testing/selftests/resctrl/resctrl.h24
-rw-r--r--tools/testing/selftests/resctrl/resctrl_tests.c180
-rw-r--r--tools/testing/selftests/resctrl/resctrl_val.c86
-rw-r--r--tools/testing/selftests/resctrl/resctrlfs.c162
-rw-r--r--tools/testing/selftests/rseq/param_test.c20
-rw-r--r--tools/testing/selftests/sigaltstack/sas.c2
-rwxr-xr-xtools/testing/selftests/static_keys/test_static_keys.sh8
-rw-r--r--tools/testing/selftests/tdx/.gitignore1
-rw-r--r--tools/testing/selftests/timers/nsleep-lat.c26
-rw-r--r--tools/testing/selftests/timers/posix_timers.c81
-rw-r--r--tools/testing/selftests/uevent/uevent_filtering.c8
-rw-r--r--tools/testing/selftests/user_events/.gitignore4
-rw-r--r--usr/include/Makefile6
2068 files changed, 64737 insertions, 78029 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem
index 46cfe02058fd..34ee8c59ab25 100644
--- a/Documentation/ABI/testing/sysfs-bus-papr-pmem
+++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem
@@ -8,7 +8,7 @@ Description:
more bits set in the dimm-health-bitmap retrieved in
response to H_SCM_HEALTH hcall. The details of the bit
flags returned in response to this hcall is available
- at 'Documentation/powerpc/papr_hcalls.rst' . Below are
+ at 'Documentation/arch/powerpc/papr_hcalls.rst' . Below are
the flags reported in this sysfs file:
* "not_armed"
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index 7ecd5c8161a6..a1db6db47505 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -354,9 +354,6 @@ Description: Parameters for the CPU cache attributes
- ReadWriteAllocate:
both writeallocate and readallocate
- attributes:
- LEGACY used only on IA64 and is same as write_policy
-
coherency_line_size:
the minimum amount of data in bytes that gets
transferred from memory to cache
diff --git a/Documentation/ABI/testing/sysfs-firmware-dmi-entries b/Documentation/ABI/testing/sysfs-firmware-dmi-entries
index fe0289c87768..b6c23807b804 100644
--- a/Documentation/ABI/testing/sysfs-firmware-dmi-entries
+++ b/Documentation/ABI/testing/sysfs-firmware-dmi-entries
@@ -2,7 +2,7 @@ What: /sys/firmware/dmi/entries/
Date: February 2011
Contact: Mike Waychison <mikew@google.com>
Description:
- Many machines' firmware (x86 and ia64) export DMI /
+ Many machines' firmware (x86 and arm64) export DMI /
SMBIOS tables to the operating system. Getting at this
information is often valuable to userland, especially in
cases where there are OEM extensions used.
diff --git a/Documentation/PCI/pci-error-recovery.rst b/Documentation/PCI/pci-error-recovery.rst
index 0c7552a00c8c..42e1e78353f3 100644
--- a/Documentation/PCI/pci-error-recovery.rst
+++ b/Documentation/PCI/pci-error-recovery.rst
@@ -364,7 +364,7 @@ Note, however, not all failures are truly "permanent". Some are
caused by over-heating, some by a poorly seated card. Many
PCI error events are caused by software bugs, e.g. DMAs to
wild addresses or bogus split transactions due to programming
-errors. See the discussion in Documentation/powerpc/eeh-pci-error-recovery.rst
+errors. See the discussion in Documentation/arch/powerpc/eeh-pci-error-recovery.rst
for additional detail on real-life experience of the causes of
software errors.
@@ -404,7 +404,7 @@ That is, the recovery API only requires that:
.. note::
Implementation details for the powerpc platform are discussed in
- the file Documentation/powerpc/eeh-pci-error-recovery.rst
+ the file Documentation/arch/powerpc/eeh-pci-error-recovery.rst
As of this writing, there is a growing list of device drivers with
patches implementing error recovery. Not all of these patches are in
diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
index e440aee4fe94..3f081459a5be 100644
--- a/Documentation/admin-guide/cgroup-v2.rst
+++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -2030,7 +2030,7 @@ IO Priority
~~~~~~~~~~~
A single attribute controls the behavior of the I/O priority cgroup policy,
-namely the blkio.prio.class attribute. The following values are accepted for
+namely the io.prio.class attribute. The following values are accepted for
that attribute:
no-change
@@ -2059,9 +2059,11 @@ The following numerical values are associated with the I/O priority policies:
+----------------+---+
| no-change | 0 |
+----------------+---+
-| rt-to-be | 2 |
+| promote-to-rt | 1 |
+----------------+---+
-| all-to-idle | 3 |
+| restrict-to-be | 2 |
++----------------+---+
+| idle | 3 |
+----------------+---+
The numerical value that corresponds to each I/O priority class is as follows:
@@ -2081,7 +2083,7 @@ The algorithm to set the I/O priority class for a request is as follows:
- If I/O priority class policy is promote-to-rt, change the request I/O
priority class to IOPRIO_CLASS_RT and change the request I/O priority
level to 4.
-- If I/O priorityt class is not promote-to-rt, translate the I/O priority
+- If I/O priority class policy is not promote-to-rt, translate the I/O priority
class policy into a number, then change the request I/O priority class
into the maximum of the I/O priority class policy number and the numerical
I/O priority class.
diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
index 0b3d39c610d9..0c526dac8428 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -259,7 +259,7 @@ Debug Messages at Module Initialization Time
When ``modprobe foo`` is called, modprobe scans ``/proc/cmdline`` for
``foo.params``, strips ``foo.``, and passes them to the kernel along with
-params given in modprobe args or ``/etc/modprob.d/*.conf`` files,
+params given in modprobe args or ``/etc/modprobe.d/*.conf`` files,
in the following order:
1. parameters given via ``/etc/modprobe.d/*.conf``::
diff --git a/Documentation/admin-guide/efi-stub.rst b/Documentation/admin-guide/efi-stub.rst
index b24e7c40d832..090f3a185e18 100644
--- a/Documentation/admin-guide/efi-stub.rst
+++ b/Documentation/admin-guide/efi-stub.rst
@@ -15,7 +15,7 @@ between architectures is in drivers/firmware/efi/libstub.
For arm64, there is no compressed kernel support, so the Image itself
masquerades as a PE/COFF image and the EFI stub is linked into the
-kernel. The arm64 EFI stub lives in arch/arm64/kernel/efi-entry.S
+kernel. The arm64 EFI stub lives in drivers/firmware/efi/libstub/arm64.c
and drivers/firmware/efi/libstub/arm64-stub.c.
By using the EFI boot stub it's possible to boot a Linux kernel
diff --git a/Documentation/admin-guide/hw-vuln/mds.rst b/Documentation/admin-guide/hw-vuln/mds.rst
index 48ca0bd85604..48c7b0b72aed 100644
--- a/Documentation/admin-guide/hw-vuln/mds.rst
+++ b/Documentation/admin-guide/hw-vuln/mds.rst
@@ -102,9 +102,19 @@ The possible values in this file are:
* - 'Vulnerable'
- The processor is vulnerable, but no mitigation enabled
* - 'Vulnerable: Clear CPU buffers attempted, no microcode'
- - The processor is vulnerable but microcode is not updated.
-
- The mitigation is enabled on a best effort basis. See :ref:`vmwerv`
+ - The processor is vulnerable but microcode is not updated. The
+ mitigation is enabled on a best effort basis.
+
+ If the processor is vulnerable but the availability of the microcode
+ based mitigation mechanism is not advertised via CPUID, the kernel
+ selects a best effort mitigation mode. This mode invokes the mitigation
+ instructions without a guarantee that they clear the CPU buffers.
+
+ This is done to address virtualization scenarios where the host has the
+ microcode update applied, but the hypervisor is not yet updated to
+ expose the CPUID to the guest. If the host has updated microcode the
+ protection takes effect; otherwise a few CPU cycles are wasted
+ pointlessly.
* - 'Mitigation: Clear CPU buffers'
- The processor is vulnerable and the CPU buffer clearing mitigation is
enabled.
@@ -119,24 +129,6 @@ to the above information:
'SMT Host state unknown' Kernel runs in a VM, Host SMT state unknown
======================== ============================================
-.. _vmwerv:
-
-Best effort mitigation mode
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- If the processor is vulnerable, but the availability of the microcode based
- mitigation mechanism is not advertised via CPUID the kernel selects a best
- effort mitigation mode. This mode invokes the mitigation instructions
- without a guarantee that they clear the CPU buffers.
-
- This is done to address virtualization scenarios where the host has the
- microcode update applied, but the hypervisor is not yet updated to expose
- the CPUID to the guest. If the host has updated microcode the protection
- takes effect otherwise a few cpu cycles are wasted pointlessly.
-
- The state in the mds sysfs file reflects this situation accordingly.
-
-
Mitigation mechanism
-------------------------
diff --git a/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
index c98fd11907cc..1302fd1b55e8 100644
--- a/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
+++ b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
@@ -225,8 +225,19 @@ The possible values in this file are:
* - 'Vulnerable'
- The processor is vulnerable, but no mitigation enabled
* - 'Vulnerable: Clear CPU buffers attempted, no microcode'
- - The processor is vulnerable, but microcode is not updated. The
+ - The processor is vulnerable but microcode is not updated. The
mitigation is enabled on a best effort basis.
+
+ If the processor is vulnerable but the availability of the microcode
+ based mitigation mechanism is not advertised via CPUID, the kernel
+ selects a best effort mitigation mode. This mode invokes the mitigation
+ instructions without a guarantee that they clear the CPU buffers.
+
+ This is done to address virtualization scenarios where the host has the
+ microcode update applied, but the hypervisor is not yet updated to
+ expose the CPUID to the guest. If the host has updated microcode the
+ protection takes effect; otherwise a few CPU cycles are wasted
+ pointlessly.
* - 'Mitigation: Clear CPU buffers'
- The processor is vulnerable and the CPU buffer clearing mitigation is
enabled.
diff --git a/Documentation/admin-guide/hw-vuln/tsx_async_abort.rst b/Documentation/admin-guide/hw-vuln/tsx_async_abort.rst
index 014167ef8dd1..444f84e22a91 100644
--- a/Documentation/admin-guide/hw-vuln/tsx_async_abort.rst
+++ b/Documentation/admin-guide/hw-vuln/tsx_async_abort.rst
@@ -98,7 +98,19 @@ The possible values in this file are:
* - 'Vulnerable'
- The CPU is affected by this vulnerability and the microcode and kernel mitigation are not applied.
* - 'Vulnerable: Clear CPU buffers attempted, no microcode'
- - The system tries to clear the buffers but the microcode might not support the operation.
+ - The processor is vulnerable but microcode is not updated. The
+ mitigation is enabled on a best effort basis.
+
+ If the processor is vulnerable but the availability of the microcode
+ based mitigation mechanism is not advertised via CPUID, the kernel
+ selects a best effort mitigation mode. This mode invokes the mitigation
+ instructions without a guarantee that they clear the CPU buffers.
+
+ This is done to address virtualization scenarios where the host has the
+ microcode update applied, but the hypervisor is not yet updated to
+ expose the CPUID to the guest. If the host has updated microcode the
+ protection takes effect; otherwise a few CPU cycles are wasted
+ pointlessly.
* - 'Mitigation: Clear CPU buffers'
- The microcode has been updated to clear the buffers. TSX is still enabled.
* - 'Mitigation: TSX disabled'
@@ -106,25 +118,6 @@ The possible values in this file are:
* - 'Not affected'
- The CPU is not affected by this issue.
-.. _ucode_needed:
-
-Best effort mitigation mode
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If the processor is vulnerable, but the availability of the microcode-based
-mitigation mechanism is not advertised via CPUID the kernel selects a best
-effort mitigation mode. This mode invokes the mitigation instructions
-without a guarantee that they clear the CPU buffers.
-
-This is done to address virtualization scenarios where the host has the
-microcode update applied, but the hypervisor is not yet updated to expose the
-CPUID to the guest. If the host has updated microcode the protection takes
-effect; otherwise a few CPU cycles are wasted pointlessly.
-
-The state in the tsx_async_abort sysfs file reflects this situation
-accordingly.
-
-
Mitigation mechanism
--------------------
diff --git a/Documentation/admin-guide/kdump/kdump.rst b/Documentation/admin-guide/kdump/kdump.rst
index a748e7eb4429..5762e7477a0c 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -17,7 +17,7 @@ You can use common commands, such as cp, scp or makedumpfile to copy
the memory image to a dump file on the local disk, or across the network
to a remote system.
-Kdump and kexec are currently supported on the x86, x86_64, ppc64, ia64,
+Kdump and kexec are currently supported on the x86, x86_64, ppc64,
s390x, arm and arm64 architectures.
When the system kernel boots, it reserves a small section of memory for
@@ -113,7 +113,7 @@ There are two possible methods of using Kdump.
2) Or use the system kernel binary itself as dump-capture kernel and there is
no need to build a separate dump-capture kernel. This is possible
only with the architectures which support a relocatable kernel. As
- of today, i386, x86_64, ppc64, ia64, arm and arm64 architectures support
+ of today, i386, x86_64, ppc64, arm and arm64 architectures support
relocatable kernel.
Building a relocatable kernel is advantageous from the point of view that
@@ -236,24 +236,6 @@ Dump-capture kernel config options (Arch Dependent, ppc64)
Make and install the kernel and its modules.
-Dump-capture kernel config options (Arch Dependent, ia64)
-----------------------------------------------------------
-
-- No specific options are required to create a dump-capture kernel
- for ia64, other than those specified in the arch independent section
- above. This means that it is possible to use the system kernel
- as a dump-capture kernel if desired.
-
- The crashkernel region can be automatically placed by the system
- kernel at runtime. This is done by specifying the base address as 0,
- or omitting it all together::
-
- crashkernel=256M@0
-
- or::
-
- crashkernel=256M
-
Dump-capture kernel config options (Arch Dependent, arm)
----------------------------------------------------------
@@ -348,11 +330,6 @@ Boot into System Kernel
On ppc64, use "crashkernel=128M@32M".
- On ia64, 256M@256M is a generous value that typically works.
- The region may be automatically placed on ia64, see the
- dump-capture kernel config option notes above.
- If use sparse memory, the size should be rounded to GRANULE boundaries.
-
On s390x, typically use "crashkernel=xxM". The value of xx is dependent
on the memory consumption of the kdump system. In general this is not
dependent on the memory size of the production system.
@@ -383,10 +360,6 @@ For ppc64:
- Use vmlinux
-For ia64:
-
- - Use vmlinux or vmlinuz.gz
-
For s390x:
- Use image or bzImage
@@ -428,14 +401,10 @@ to load dump-capture kernel::
--initrd=<initrd-for-dump-capture-kernel> \
--append="root=<root-dev> <arch-specific-options>"
-Please note, that --args-linux does not need to be specified for ia64.
-It is planned to make this a no-op on that architecture, but for now
-it should be omitted
-
Following are the arch specific command line options to be used while
loading dump-capture kernel.
-For i386, x86_64 and ia64:
+For i386 and x86_64:
"1 irqpoll nr_cpus=1 reset_devices"
diff --git a/Documentation/admin-guide/kdump/vmcoreinfo.rst b/Documentation/admin-guide/kdump/vmcoreinfo.rst
index 599e8d3bcbc3..78e4d2e7ba14 100644
--- a/Documentation/admin-guide/kdump/vmcoreinfo.rst
+++ b/Documentation/admin-guide/kdump/vmcoreinfo.rst
@@ -413,36 +413,6 @@ of a higher page table lookup overhead, and also consumes more page
table space per process. Used to check whether PAE was enabled in the
crash kernel when converting virtual addresses to physical addresses.
-ia64
-====
-
-pgdat_list|(pgdat_list, MAX_NUMNODES)
--------------------------------------
-
-pg_data_t array storing all NUMA nodes information. MAX_NUMNODES
-indicates the number of the nodes.
-
-node_memblk|(node_memblk, NR_NODE_MEMBLKS)
-------------------------------------------
-
-List of node memory chunks. Filled when parsing the SRAT table to obtain
-information about memory nodes. NR_NODE_MEMBLKS indicates the number of
-node memory chunks.
-
-These values are used to compute the number of nodes the crashed kernel used.
-
-node_memblk_s|(node_memblk_s, start_paddr)|(node_memblk_s, size)
-----------------------------------------------------------------
-
-The size of a struct node_memblk_s and the offsets of the
-node_memblk_s's members. Used to compute the number of nodes.
-
-PGTABLE_3|PGTABLE_4
--------------------
-
-User-space tools need to know whether the crash kernel was in 3-level or
-4-level paging mode. Used to distinguish the page table.
-
ARM64
=====
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 758bb25ea3e6..07625c60aa8a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1453,7 +1453,7 @@
See comment before function elanfreq_setup() in
arch/x86/kernel/cpu/cpufreq/elanfreq.c.
- elfcorehdr=[size[KMG]@]offset[KMG] [IA64,PPC,SH,X86,S390]
+ elfcorehdr=[size[KMG]@]offset[KMG] [PPC,SH,X86,S390]
Specifies physical address of start of kernel core
image elf header and optionally the size. Generally
kexec loader will pass this option to capture kernel.
@@ -1516,12 +1516,6 @@
floppy= [HW]
See Documentation/admin-guide/blockdev/floppy.rst.
- force_pal_cache_flush
- [IA-64] Avoid check_sal_cache_flush which may hang on
- buggy SAL_CACHE_FLUSH implementations. Using this
- parameter will force ia64_sal_cache_flush to call
- ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.
-
forcepae [X86-32]
Forcefully enable Physical Address Extension (PAE).
Many Pentium M systems disable PAE but may have a
diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst
index cfe034cf1e87..098f14d83e99 100644
--- a/Documentation/admin-guide/mm/memory-hotplug.rst
+++ b/Documentation/admin-guide/mm/memory-hotplug.rst
@@ -33,7 +33,7 @@ used to expose persistent memory, other performance-differentiated memory and
reserved memory regions as ordinary system RAM to Linux.
Linux only supports memory hot(un)plug on selected 64 bit architectures, such as
-x86_64, arm64, ppc64, s390x and ia64.
+x86_64, arm64, ppc64 and s390x.
Memory Hot(Un)Plug Granularity
------------------------------
@@ -75,7 +75,7 @@ Memory hotunplug consists of two phases:
(1) Offlining memory blocks
(2) Removing the memory from Linux
-In the fist phase, memory is "hidden" from the page allocator again, for
+In the first phase, memory is "hidden" from the page allocator again, for
example, by migrating busy memory to other memory locations and removing all
relevant free pages from the page allocator After this phase, the memory is no
longer visible in memory statistics of the system.
@@ -250,15 +250,15 @@ Observing the State of Memory Blocks
The state (online/offline/going-offline) of a memory block can be observed
either via::
- % cat /sys/device/system/memory/memoryXXX/state
+ % cat /sys/devices/system/memory/memoryXXX/state
Or alternatively (1/0) via::
- % cat /sys/device/system/memory/memoryXXX/online
+ % cat /sys/devices/system/memory/memoryXXX/online
For an online memory block, the managing zone can be observed via::
- % cat /sys/device/system/memory/memoryXXX/valid_zones
+ % cat /sys/devices/system/memory/memoryXXX/valid_zones
Configuring Memory Hot(Un)Plug
==============================
@@ -326,7 +326,7 @@ however, a memory block might span memory holes. A memory block spanning memory
holes cannot be offlined.
For example, assume 1 GiB memory block size. A device for a memory starting at
-0x100000000 is ``/sys/device/system/memory/memory4``::
+0x100000000 is ``/sys/devices/system/memory/memory4``::
(0x100000000 / 1Gib = 4)
diff --git a/Documentation/admin-guide/perf/ampere_cspmu.rst b/Documentation/admin-guide/perf/ampere_cspmu.rst
new file mode 100644
index 000000000000..94f93f5aee6c
--- /dev/null
+++ b/Documentation/admin-guide/perf/ampere_cspmu.rst
@@ -0,0 +1,29 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============================================
+Ampere SoC Performance Monitoring Unit (PMU)
+============================================
+
+Ampere SoC PMU is a generic PMU IP that follows Arm CoreSight PMU architecture.
+Therefore, the driver is implemented as a submodule of arm_cspmu driver. At the
+first phase it's used for counting MCU events on AmpereOne.
+
+
+MCU PMU events
+--------------
+
+The PMU driver supports setting filters for "rank", "bank", and "threshold".
+Note, that the filters are per PMU instance rather than per event.
+
+
+Example for perf tool use::
+
+ / # perf list ampere
+
+ ampere_mcu_pmu_0/act_sent/ [Kernel PMU event]
+ <...>
+ ampere_mcu_pmu_1/rd_sent/ [Kernel PMU event]
+ <...>
+
+ / # perf stat -a -e ampere_mcu_pmu_0/act_sent,bank=5,rank=3,threshold=2/,ampere_mcu_pmu_1/rd_sent/ \
+ sleep 1
diff --git a/Documentation/admin-guide/perf/index.rst b/Documentation/admin-guide/perf/index.rst
index f60be04e4e33..a2e6f2c81146 100644
--- a/Documentation/admin-guide/perf/index.rst
+++ b/Documentation/admin-guide/perf/index.rst
@@ -22,3 +22,4 @@ Performance monitor support
nvidia-pmu
meson-ddr-pmu
cxl
+ ampere_cspmu
diff --git a/Documentation/admin-guide/spkguide.txt b/Documentation/admin-guide/spkguide.txt
index 74ea7f391942..0d5965138f8f 100644
--- a/Documentation/admin-guide/spkguide.txt
+++ b/Documentation/admin-guide/spkguide.txt
@@ -7,7 +7,7 @@ Last modified on Mon Sep 27 14:26:31 2010
Document version 1.3
Copyright (c) 2005 Gene Collins
-Copyright (c) 2008 Samuel Thibault
+Copyright (c) 2008, 2023 Samuel Thibault
Copyright (c) 2009, 2010 the Speakup Team
Permission is granted to copy, distribute and/or modify this document
@@ -83,8 +83,7 @@ spkout -- Speak Out
txprt -- Transport
dummy -- Plain text terminal
-Note: Speakup does * NOT * support usb connections! Speakup also does *
-NOT * support the internal Tripletalk!
+Note: Speakup does * NOT * support the internal Tripletalk!
Speakup does support two other synthesizers, but because they work in
conjunction with other software, they must be loaded as modules after
@@ -94,6 +93,12 @@ These are as follows:
decpc -- DecTalk PC (not available at boot up)
soft -- One of several software synthesizers (not available at boot up)
+By default speakup looks for the synthesizer on the ttyS0 serial port. This can
+be changed with the device parameter of the modules, for instance for
+DoubleTalk LT:
+
+speakup_ltlk.dev=ttyUSB0
+
See the sections on loading modules and software synthesizers later in
this manual for further details. It should be noted here that the
speakup.synth boot parameter will have no effect if Speakup has been
diff --git a/Documentation/admin-guide/sysctl/fs.rst b/Documentation/admin-guide/sysctl/fs.rst
index a321b84eccaa..47499a1742bd 100644
--- a/Documentation/admin-guide/sysctl/fs.rst
+++ b/Documentation/admin-guide/sysctl/fs.rst
@@ -42,16 +42,16 @@ pre-allocation or re-sizing of any kernel data structures.
dentry-state
------------
-This file shows the values in ``struct dentry_stat``, as defined in
-``linux/include/linux/dcache.h``::
+This file shows the values in ``struct dentry_stat_t``, as defined in
+``fs/dcache.c``::
struct dentry_stat_t dentry_stat {
- int nr_dentry;
- int nr_unused;
- int age_limit; /* age in seconds */
- int want_pages; /* pages requested by system */
- int nr_negative; /* # of unused negative dentries */
- int dummy; /* Reserved for future use */
+ long nr_dentry;
+ long nr_unused;
+ long age_limit; /* age in seconds */
+ long want_pages; /* pages requested by system */
+ long nr_negative; /* # of unused negative dentries */
+ long dummy; /* Reserved for future use */
};
Dentries are dynamically allocated and deallocated.
diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
index d89ac2bd8dc4..6584a1f9bfe3 100644
--- a/Documentation/admin-guide/sysctl/kernel.rst
+++ b/Documentation/admin-guide/sysctl/kernel.rst
@@ -436,7 +436,7 @@ ignore-unaligned-usertrap
On architectures where unaligned accesses cause traps, and where this
feature is supported (``CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN``;
-currently, ``arc``, ``ia64`` and ``loongarch``), controls whether all
+currently, ``arc`` and ``loongarch``), controls whether all
unaligned traps are logged.
= =============================================================
@@ -445,10 +445,7 @@ unaligned traps are logged.
setting.
= =============================================================
-See also `unaligned-trap`_ and `unaligned-dump-stack`_. On ``ia64``,
-this allows system administrators to override the
-``IA64_THREAD_UAC_NOPRINT`` ``prctl`` and avoid logs being flooded.
-
+See also `unaligned-trap`_.
io_uring_disabled
=================
@@ -1539,22 +1536,6 @@ See Documentation/admin-guide/kernel-parameters.rst and
Documentation/trace/boottime-trace.rst.
-.. _unaligned-dump-stack:
-
-unaligned-dump-stack (ia64)
-===========================
-
-When logging unaligned accesses, controls whether the stack is
-dumped.
-
-= ===================================================
-0 Do not dump the stack. This is the default setting.
-1 Dump the stack.
-= ===================================================
-
-See also `ignore-unaligned-usertrap`_.
-
-
unaligned-trap
==============
diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst
index 45ba1f4dc004..c59889de122b 100644
--- a/Documentation/admin-guide/sysctl/vm.rst
+++ b/Documentation/admin-guide/sysctl/vm.rst
@@ -742,8 +742,8 @@ overcommit_memory
This value contains a flag that enables memory overcommitment.
-When this flag is 0, the kernel attempts to estimate the amount
-of free memory left when userspace requests more memory.
+When this flag is 0, the kernel compares the userspace memory request
+size against total memory plus swap and rejects obvious overcommits.
When this flag is 1, the kernel pretends there is always enough
memory until it actually runs out.
diff --git a/Documentation/arch/arm64/cpu-feature-registers.rst b/Documentation/arch/arm64/cpu-feature-registers.rst
index de6d8a4790e2..44f9bd78539d 100644
--- a/Documentation/arch/arm64/cpu-feature-registers.rst
+++ b/Documentation/arch/arm64/cpu-feature-registers.rst
@@ -268,6 +268,8 @@ infrastructure:
+------------------------------+---------+---------+
| SHA3 | [35-32] | y |
+------------------------------+---------+---------+
+ | B16B16 | [27-24] | y |
+ +------------------------------+---------+---------+
| BF16 | [23-20] | y |
+------------------------------+---------+---------+
| BitPerm | [19-16] | y |
diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst
index 76ff9d7398fd..4b8399ac592b 100644
--- a/Documentation/arch/arm64/elf_hwcaps.rst
+++ b/Documentation/arch/arm64/elf_hwcaps.rst
@@ -308,6 +308,15 @@ HWCAP2_MOPS
HWCAP2_HBC
Functionality implied by ID_AA64ISAR2_EL1.BC == 0b0001.
+HWCAP2_SVE_B16B16
+ Functionality implied by ID_AA64ZFR0_EL1.B16B16 == 0b0001.
+
+HWCAP2_LRCPC3
+ Functionality implied by ID_AA64ISAR1_EL1.LRCPC == 0b0011.
+
+HWCAP2_LSE128
+ Functionality implied by ID_AA64ISAR0_EL1.Atomic == 0b0011.
+
4. Unused AT_HWCAP bits
-----------------------
diff --git a/Documentation/arch/ia64/aliasing.rst b/Documentation/arch/ia64/aliasing.rst
deleted file mode 100644
index 36a1e1d4842b..000000000000
--- a/Documentation/arch/ia64/aliasing.rst
+++ /dev/null
@@ -1,246 +0,0 @@
-==================================
-Memory Attribute Aliasing on IA-64
-==================================
-
-Bjorn Helgaas <bjorn.helgaas@hp.com>
-
-May 4, 2006
-
-
-Memory Attributes
-=================
-
- Itanium supports several attributes for virtual memory references.
- The attribute is part of the virtual translation, i.e., it is
- contained in the TLB entry. The ones of most interest to the Linux
- kernel are:
-
- == ======================
- WB Write-back (cacheable)
- UC Uncacheable
- WC Write-coalescing
- == ======================
-
- System memory typically uses the WB attribute. The UC attribute is
- used for memory-mapped I/O devices. The WC attribute is uncacheable
- like UC is, but writes may be delayed and combined to increase
- performance for things like frame buffers.
-
- The Itanium architecture requires that we avoid accessing the same
- page with both a cacheable mapping and an uncacheable mapping[1].
-
- The design of the chipset determines which attributes are supported
- on which regions of the address space. For example, some chipsets
- support either WB or UC access to main memory, while others support
- only WB access.
-
-Memory Map
-==========
-
- Platform firmware describes the physical memory map and the
- supported attributes for each region. At boot-time, the kernel uses
- the EFI GetMemoryMap() interface. ACPI can also describe memory
- devices and the attributes they support, but Linux/ia64 currently
- doesn't use this information.
-
- The kernel uses the efi_memmap table returned from GetMemoryMap() to
- learn the attributes supported by each region of physical address
- space. Unfortunately, this table does not completely describe the
- address space because some machines omit some or all of the MMIO
- regions from the map.
-
- The kernel maintains another table, kern_memmap, which describes the
- memory Linux is actually using and the attribute for each region.
- This contains only system memory; it does not contain MMIO space.
-
- The kern_memmap table typically contains only a subset of the system
- memory described by the efi_memmap. Linux/ia64 can't use all memory
- in the system because of constraints imposed by the identity mapping
- scheme.
-
- The efi_memmap table is preserved unmodified because the original
- boot-time information is required for kexec.
-
-Kernel Identity Mappings
-========================
-
- Linux/ia64 identity mappings are done with large pages, currently
- either 16MB or 64MB, referred to as "granules." Cacheable mappings
- are speculative[2], so the processor can read any location in the
- page at any time, independent of the programmer's intentions. This
- means that to avoid attribute aliasing, Linux can create a cacheable
- identity mapping only when the entire granule supports cacheable
- access.
-
- Therefore, kern_memmap contains only full granule-sized regions that
- can referenced safely by an identity mapping.
-
- Uncacheable mappings are not speculative, so the processor will
- generate UC accesses only to locations explicitly referenced by
- software. This allows UC identity mappings to cover granules that
- are only partially populated, or populated with a combination of UC
- and WB regions.
-
-User Mappings
-=============
-
- User mappings are typically done with 16K or 64K pages. The smaller
- page size allows more flexibility because only 16K or 64K has to be
- homogeneous with respect to memory attributes.
-
-Potential Attribute Aliasing Cases
-==================================
-
- There are several ways the kernel creates new mappings:
-
-mmap of /dev/mem
-----------------
-
- This uses remap_pfn_range(), which creates user mappings. These
- mappings may be either WB or UC. If the region being mapped
- happens to be in kern_memmap, meaning that it may also be mapped
- by a kernel identity mapping, the user mapping must use the same
- attribute as the kernel mapping.
-
- If the region is not in kern_memmap, the user mapping should use
- an attribute reported as being supported in the EFI memory map.
-
- Since the EFI memory map does not describe MMIO on some
- machines, this should use an uncacheable mapping as a fallback.
-
-mmap of /sys/class/pci_bus/.../legacy_mem
------------------------------------------
-
- This is very similar to mmap of /dev/mem, except that legacy_mem
- only allows mmap of the one megabyte "legacy MMIO" area for a
- specific PCI bus. Typically this is the first megabyte of
- physical address space, but it may be different on machines with
- several VGA devices.
-
- "X" uses this to access VGA frame buffers. Using legacy_mem
- rather than /dev/mem allows multiple instances of X to talk to
- different VGA cards.
-
- The /dev/mem mmap constraints apply.
-
-mmap of /proc/bus/pci/.../??.?
-------------------------------
-
- This is an MMIO mmap of PCI functions, which additionally may or
- may not be requested as using the WC attribute.
-
- If WC is requested, and the region in kern_memmap is either WC
- or UC, and the EFI memory map designates the region as WC, then
- the WC mapping is allowed.
-
- Otherwise, the user mapping must use the same attribute as the
- kernel mapping.
-
-read/write of /dev/mem
-----------------------
-
- This uses copy_from_user(), which implicitly uses a kernel
- identity mapping. This is obviously safe for things in
- kern_memmap.
-
- There may be corner cases of things that are not in kern_memmap,
- but could be accessed this way. For example, registers in MMIO
- space are not in kern_memmap, but could be accessed with a UC
- mapping. This would not cause attribute aliasing. But
- registers typically can be accessed only with four-byte or
- eight-byte accesses, and the copy_from_user() path doesn't allow
- any control over the access size, so this would be dangerous.
-
-ioremap()
----------
-
- This returns a mapping for use inside the kernel.
-
- If the region is in kern_memmap, we should use the attribute
- specified there.
-
- If the EFI memory map reports that the entire granule supports
- WB, we should use that (granules that are partially reserved
- or occupied by firmware do not appear in kern_memmap).
-
- If the granule contains non-WB memory, but we can cover the
- region safely with kernel page table mappings, we can use
- ioremap_page_range() as most other architectures do.
-
- Failing all of the above, we have to fall back to a UC mapping.
-
-Past Problem Cases
-==================
-
-mmap of various MMIO regions from /dev/mem by "X" on Intel platforms
---------------------------------------------------------------------
-
- The EFI memory map may not report these MMIO regions.
-
- These must be allowed so that X will work. This means that
- when the EFI memory map is incomplete, every /dev/mem mmap must
- succeed. It may create either WB or UC user mappings, depending
- on whether the region is in kern_memmap or the EFI memory map.
-
-mmap of 0x0-0x9FFFF /dev/mem by "hwinfo" on HP sx1000 with VGA enabled
-----------------------------------------------------------------------
-
- The EFI memory map reports the following attributes:
-
- =============== ======= ==================
- 0x00000-0x9FFFF WB only
- 0xA0000-0xBFFFF UC only (VGA frame buffer)
- 0xC0000-0xFFFFF WB only
- =============== ======= ==================
-
- This mmap is done with user pages, not kernel identity mappings,
- so it is safe to use WB mappings.
-
- The kernel VGA driver may ioremap the VGA frame buffer at 0xA0000,
- which uses a granule-sized UC mapping. This granule will cover some
- WB-only memory, but since UC is non-speculative, the processor will
- never generate an uncacheable reference to the WB-only areas unless
- the driver explicitly touches them.
-
-mmap of 0x0-0xFFFFF legacy_mem by "X"
--------------------------------------
-
- If the EFI memory map reports that the entire range supports the
- same attributes, we can allow the mmap (and we will prefer WB if
- supported, as is the case with HP sx[12]000 machines with VGA
- disabled).
-
- If EFI reports the range as partly WB and partly UC (as on sx[12]000
- machines with VGA enabled), we must fail the mmap because there's no
- safe attribute to use.
-
- If EFI reports some of the range but not all (as on Intel firmware
- that doesn't report the VGA frame buffer at all), we should fail the
- mmap and force the user to map just the specific region of interest.
-
-mmap of 0xA0000-0xBFFFF legacy_mem by "X" on HP sx1000 with VGA disabled
-------------------------------------------------------------------------
-
- The EFI memory map reports the following attributes::
-
- 0x00000-0xFFFFF WB only (no VGA MMIO hole)
-
- This is a special case of the previous case, and the mmap should
- fail for the same reason as above.
-
-read of /sys/devices/.../rom
-----------------------------
-
- For VGA devices, this may cause an ioremap() of 0xC0000. This
- used to be done with a UC mapping, because the VGA frame buffer
- at 0xA0000 prevents use of a WB granule. The UC mapping causes
- an MCA on HP sx[12]000 chipsets.
-
- We should use WB page table mappings to avoid covering the VGA
- frame buffer.
-
-Notes
-=====
-
- [1] SDM rev 2.2, vol 2, sec 4.4.1.
- [2] SDM rev 2.2, vol 2, sec 4.4.6.
diff --git a/Documentation/arch/ia64/efirtc.rst b/Documentation/arch/ia64/efirtc.rst
deleted file mode 100644
index fd8328408301..000000000000
--- a/Documentation/arch/ia64/efirtc.rst
+++ /dev/null
@@ -1,144 +0,0 @@
-==========================
-EFI Real Time Clock driver
-==========================
-
-S. Eranian <eranian@hpl.hp.com>
-
-March 2000
-
-1. Introduction
-===============
-
-This document describes the efirtc.c driver has provided for
-the IA-64 platform.
-
-The purpose of this driver is to supply an API for kernel and user applications
-to get access to the Time Service offered by EFI version 0.92.
-
-EFI provides 4 calls one can make once the OS is booted: GetTime(),
-SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this
-driver. We describe those calls as well the design of the driver in the
-following sections.
-
-2. Design Decisions
-===================
-
-The original ideas was to provide a very simple driver to get access to,
-at first, the time of day service. This is required in order to access, in a
-portable way, the CMOS clock. A program like /sbin/hwclock uses such a clock
-to initialize the system view of the time during boot.
-
-Because we wanted to minimize the impact on existing user-level apps using
-the CMOS clock, we decided to expose an API that was very similar to the one
-used today with the legacy RTC driver (driver/char/rtc.c). However, because
-EFI provides a simpler services, not all ioctl() are available. Also
-new ioctl()s have been introduced for things that EFI provides but not the
-legacy.
-
-EFI uses a slightly different way of representing the time, noticeably
-the reference date is different. Year is the using the full 4-digit format.
-The Epoch is January 1st 1998. For backward compatibility reasons we don't
-expose this new way of representing time. Instead we use something very
-similar to the struct tm, i.e. struct rtc_time, as used by hwclock.
-One of the reasons for doing it this way is to allow for EFI to still evolve
-without necessarily impacting any of the user applications. The decoupling
-enables flexibility and permits writing wrapper code is ncase things change.
-
-The driver exposes two interfaces, one via the device file and a set of
-ioctl()s. The other is read-only via the /proc filesystem.
-
-As of today we don't offer a /proc/sys interface.
-
-To allow for a uniform interface between the legacy RTC and EFI time service,
-we have created the include/linux/rtc.h header file to contain only the
-"public" API of the two drivers. The specifics of the legacy RTC are still
-in include/linux/mc146818rtc.h.
-
-
-3. Time of day service
-======================
-
-The part of the driver gives access to the time of day service of EFI.
-Two ioctl()s, compatible with the legacy RTC calls:
-
- Read the CMOS clock::
-
- ioctl(d, RTC_RD_TIME, &rtc);
-
- Write the CMOS clock::
-
- ioctl(d, RTC_SET_TIME, &rtc);
-
-The rtc is a pointer to a data structure defined in rtc.h which is close
-to a struct tm::
-
- struct rtc_time {
- int tm_sec;
- int tm_min;
- int tm_hour;
- int tm_mday;
- int tm_mon;
- int tm_year;
- int tm_wday;
- int tm_yday;
- int tm_isdst;
- };
-
-The driver takes care of converting back an forth between the EFI time and
-this format.
-
-Those two ioctl()s can be exercised with the hwclock command:
-
-For reading::
-
- # /sbin/hwclock --show
- Mon Mar 6 15:32:32 2000 -0.910248 seconds
-
-For setting::
-
- # /sbin/hwclock --systohc
-
-Root privileges are required to be able to set the time of day.
-
-4. Wakeup Alarm service
-=======================
-
-EFI provides an API by which one can program when a machine should wakeup,
-i.e. reboot. This is very different from the alarm provided by the legacy
-RTC which is some kind of interval timer alarm. For this reason we don't use
-the same ioctl()s to get access to the service. Instead we have
-introduced 2 news ioctl()s to the interface of an RTC.
-
-We have added 2 new ioctl()s that are specific to the EFI driver:
-
- Read the current state of the alarm::
-
- ioctl(d, RTC_WKALM_RD, &wkt)
-
- Set the alarm or change its status::
-
- ioctl(d, RTC_WKALM_SET, &wkt)
-
-The wkt structure encapsulates a struct rtc_time + 2 extra fields to get
-status information::
-
- struct rtc_wkalrm {
-
- unsigned char enabled; /* =1 if alarm is enabled */
- unsigned char pending; /* =1 if alarm is pending */
-
- struct rtc_time time;
- }
-
-As of today, none of the existing user-level apps supports this feature.
-However writing such a program should be hard by simply using those two
-ioctl().
-
-Root privileges are required to be able to set the alarm.
-
-5. References
-=============
-
-Checkout the following Web site for more information on EFI:
-
-http://developer.intel.com/technology/efi/
diff --git a/Documentation/arch/ia64/err_inject.rst b/Documentation/arch/ia64/err_inject.rst
deleted file mode 100644
index 900f71e93a29..000000000000
--- a/Documentation/arch/ia64/err_inject.rst
+++ /dev/null
@@ -1,1067 +0,0 @@
-========================================
-IPF Machine Check (MC) error inject tool
-========================================
-
-IPF Machine Check (MC) error inject tool is used to inject MC
-errors from Linux. The tool is a test bed for IPF MC work flow including
-hardware correctable error handling, OS recoverable error handling, MC
-event logging, etc.
-
-The tool includes two parts: a kernel driver and a user application
-sample. The driver provides interface to PAL to inject error
-and query error injection capabilities. The driver code is in
-arch/ia64/kernel/err_inject.c. The application sample (shown below)
-provides a combination of various errors and calls the driver's interface
-(sysfs interface) to inject errors or query error injection capabilities.
-
-The tool can be used to test Intel IPF machine MC handling capabilities.
-It's especially useful for people who can not access hardware MC injection
-tool to inject error. It's also very useful to integrate with other
-software test suits to do stressful testing on IPF.
-
-Below is a sample application as part of the whole tool. The sample
-can be used as a working test tool. Or it can be expanded to include
-more features. It also can be a integrated into a library or other user
-application to have more thorough test.
-
-The sample application takes err.conf as error configuration input. GCC
-compiles the code. After you install err_inject driver, you can run
-this sample application to inject errors.
-
-Errata: Itanium 2 Processors Specification Update lists some errata against
-the pal_mc_error_inject PAL procedure. The following err.conf has been tested
-on latest Montecito PAL.
-
-err.conf::
-
- #This is configuration file for err_inject_tool.
- #The format of the each line is:
- #cpu, loop, interval, err_type_info, err_struct_info, err_data_buffer
- #where
- # cpu: logical cpu number the error will be inject in.
- # loop: times the error will be injected.
- # interval: In second. every so often one error is injected.
- # err_type_info, err_struct_info: PAL parameters.
- #
- #Note: All values are hex w/o or w/ 0x prefix.
-
-
- #On cpu2, inject only total 0x10 errors, interval 5 seconds
- #corrected, data cache, hier-2, physical addr(assigned by tool code).
- #working on Montecito latest PAL.
- 2, 10, 5, 4101, 95
-
- #On cpu4, inject and consume total 0x10 errors, interval 5 seconds
- #corrected, data cache, hier-2, physical addr(assigned by tool code).
- #working on Montecito latest PAL.
- 4, 10, 5, 4109, 95
-
- #On cpu15, inject and consume total 0x10 errors, interval 5 seconds
- #recoverable, DTR0, hier-2.
- #working on Montecito latest PAL.
- 0xf, 0x10, 5, 4249, 15
-
-The sample application source code:
-
-err_injection_tool.c::
-
- /*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Copyright (C) 2006 Intel Co
- * Fenghua Yu <fenghua.yu@intel.com>
- *
- */
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <sched.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <errno.h>
- #include <time.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <sys/wait.h>
- #include <sys/mman.h>
- #include <sys/shm.h>
-
- #define MAX_FN_SIZE 256
- #define MAX_BUF_SIZE 256
- #define DATA_BUF_SIZE 256
- #define NR_CPUS 512
- #define MAX_TASK_NUM 2048
- #define MIN_INTERVAL 5 // seconds
- #define ERR_DATA_BUFFER_SIZE 3 // Three 8-byte.
- #define PARA_FIELD_NUM 5
- #define MASK_SIZE (NR_CPUS/64)
- #define PATH_FORMAT "/sys/devices/system/cpu/cpu%d/err_inject/"
-
- int sched_setaffinity(pid_t pid, unsigned int len, unsigned long *mask);
-
- int verbose;
- #define vbprintf if (verbose) printf
-
- int log_info(int cpu, const char *fmt, ...)
- {
- FILE *log;
- char fn[MAX_FN_SIZE];
- char buf[MAX_BUF_SIZE];
- va_list args;
-
- sprintf(fn, "%d.log", cpu);
- log=fopen(fn, "a+");
- if (log==NULL) {
- perror("Error open:");
- return -1;
- }
-
- va_start(args, fmt);
- vprintf(fmt, args);
- memset(buf, 0, MAX_BUF_SIZE);
- vsprintf(buf, fmt, args);
- va_end(args);
-
- fwrite(buf, sizeof(buf), 1, log);
- fclose(log);
-
- return 0;
- }
-
- typedef unsigned long u64;
- typedef unsigned int u32;
-
- typedef union err_type_info_u {
- struct {
- u64 mode : 3, /* 0-2 */
- err_inj : 3, /* 3-5 */
- err_sev : 2, /* 6-7 */
- err_struct : 5, /* 8-12 */
- struct_hier : 3, /* 13-15 */
- reserved : 48; /* 16-63 */
- } err_type_info_u;
- u64 err_type_info;
- } err_type_info_t;
-
- typedef union err_struct_info_u {
- struct {
- u64 siv : 1, /* 0 */
- c_t : 2, /* 1-2 */
- cl_p : 3, /* 3-5 */
- cl_id : 3, /* 6-8 */
- cl_dp : 1, /* 9 */
- reserved1 : 22, /* 10-31 */
- tiv : 1, /* 32 */
- trigger : 4, /* 33-36 */
- trigger_pl : 3, /* 37-39 */
- reserved2 : 24; /* 40-63 */
- } err_struct_info_cache;
- struct {
- u64 siv : 1, /* 0 */
- tt : 2, /* 1-2 */
- tc_tr : 2, /* 3-4 */
- tr_slot : 8, /* 5-12 */
- reserved1 : 19, /* 13-31 */
- tiv : 1, /* 32 */
- trigger : 4, /* 33-36 */
- trigger_pl : 3, /* 37-39 */
- reserved2 : 24; /* 40-63 */
- } err_struct_info_tlb;
- struct {
- u64 siv : 1, /* 0 */
- regfile_id : 4, /* 1-4 */
- reg_num : 7, /* 5-11 */
- reserved1 : 20, /* 12-31 */
- tiv : 1, /* 32 */
- trigger : 4, /* 33-36 */
- trigger_pl : 3, /* 37-39 */
- reserved2 : 24; /* 40-63 */
- } err_struct_info_register;
- struct {
- u64 reserved;
- } err_struct_info_bus_processor_interconnect;
- u64 err_struct_info;
- } err_struct_info_t;
-
- typedef union err_data_buffer_u {
- struct {
- u64 trigger_addr; /* 0-63 */
- u64 inj_addr; /* 64-127 */
- u64 way : 5, /* 128-132 */
- index : 20, /* 133-152 */
- : 39; /* 153-191 */
- } err_data_buffer_cache;
- struct {
- u64 trigger_addr; /* 0-63 */
- u64 inj_addr; /* 64-127 */
- u64 way : 5, /* 128-132 */
- index : 20, /* 133-152 */
- reserved : 39; /* 153-191 */
- } err_data_buffer_tlb;
- struct {
- u64 trigger_addr; /* 0-63 */
- } err_data_buffer_register;
- struct {
- u64 reserved; /* 0-63 */
- } err_data_buffer_bus_processor_interconnect;
- u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
- } err_data_buffer_t;
-
- typedef union capabilities_u {
- struct {
- u64 i : 1,
- d : 1,
- rv : 1,
- tag : 1,
- data : 1,
- mesi : 1,
- dp : 1,
- reserved1 : 3,
- pa : 1,
- va : 1,
- wi : 1,
- reserved2 : 20,
- trigger : 1,
- trigger_pl : 1,
- reserved3 : 30;
- } capabilities_cache;
- struct {
- u64 d : 1,
- i : 1,
- rv : 1,
- tc : 1,
- tr : 1,
- reserved1 : 27,
- trigger : 1,
- trigger_pl : 1,
- reserved2 : 30;
- } capabilities_tlb;
- struct {
- u64 gr_b0 : 1,
- gr_b1 : 1,
- fr : 1,
- br : 1,
- pr : 1,
- ar : 1,
- cr : 1,
- rr : 1,
- pkr : 1,
- dbr : 1,
- ibr : 1,
- pmc : 1,
- pmd : 1,
- reserved1 : 3,
- regnum : 1,
- reserved2 : 15,
- trigger : 1,
- trigger_pl : 1,
- reserved3 : 30;
- } capabilities_register;
- struct {
- u64 reserved;
- } capabilities_bus_processor_interconnect;
- } capabilities_t;
-
- typedef struct resources_s {
- u64 ibr0 : 1,
- ibr2 : 1,
- ibr4 : 1,
- ibr6 : 1,
- dbr0 : 1,
- dbr2 : 1,
- dbr4 : 1,
- dbr6 : 1,
- reserved : 48;
- } resources_t;
-
-
- long get_page_size(void)
- {
- long page_size=sysconf(_SC_PAGESIZE);
- return page_size;
- }
-
- #define PAGE_SIZE (get_page_size()==-1?0x4000:get_page_size())
- #define SHM_SIZE (2*PAGE_SIZE*NR_CPUS)
- #define SHM_VA 0x2000000100000000
-
- int shmid;
- void *shmaddr;
-
- int create_shm(void)
- {
- key_t key;
- char fn[MAX_FN_SIZE];
-
- /* cpu0 is always existing */
- sprintf(fn, PATH_FORMAT, 0);
- if ((key = ftok(fn, 's')) == -1) {
- perror("ftok");
- return -1;
- }
-
- shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT);
- if (shmid == -1) {
- if (errno==EEXIST) {
- shmid = shmget(key, SHM_SIZE, 0);
- if (shmid == -1) {
- perror("shmget");
- return -1;
- }
- }
- else {
- perror("shmget");
- return -1;
- }
- }
- vbprintf("shmid=%d", shmid);
-
- /* connect to the segment: */
- shmaddr = shmat(shmid, (void *)SHM_VA, 0);
- if (shmaddr == (void*)-1) {
- perror("shmat");
- return -1;
- }
-
- memset(shmaddr, 0, SHM_SIZE);
- mlock(shmaddr, SHM_SIZE);
-
- return 0;
- }
-
- int free_shm()
- {
- munlock(shmaddr, SHM_SIZE);
- shmdt(shmaddr);
- semctl(shmid, 0, IPC_RMID);
-
- return 0;
- }
-
- #ifdef _SEM_SEMUN_UNDEFINED
- union semun
- {
- int val;
- struct semid_ds *buf;
- unsigned short int *array;
- struct seminfo *__buf;
- };
- #endif
-
- u32 mode=1; /* 1: physical mode; 2: virtual mode. */
- int one_lock=1;
- key_t key[NR_CPUS];
- int semid[NR_CPUS];
-
- int create_sem(int cpu)
- {
- union semun arg;
- char fn[MAX_FN_SIZE];
- int sid;
-
- sprintf(fn, PATH_FORMAT, cpu);
- sprintf(fn, "%s/%s", fn, "err_type_info");
- if ((key[cpu] = ftok(fn, 'e')) == -1) {
- perror("ftok");
- return -1;
- }
-
- if (semid[cpu]!=0)
- return 0;
-
- /* clear old semaphore */
- if ((sid = semget(key[cpu], 1, 0)) != -1)
- semctl(sid, 0, IPC_RMID);
-
- /* get one semaphore */
- if ((semid[cpu] = semget(key[cpu], 1, IPC_CREAT | IPC_EXCL)) == -1) {
- perror("semget");
- printf("Please remove semaphore with key=0x%lx, then run the tool.\n",
- (u64)key[cpu]);
- return -1;
- }
-
- vbprintf("semid[%d]=0x%lx, key[%d]=%lx\n",cpu,(u64)semid[cpu],cpu,
- (u64)key[cpu]);
- /* initialize the semaphore to 1: */
- arg.val = 1;
- if (semctl(semid[cpu], 0, SETVAL, arg) == -1) {
- perror("semctl");
- return -1;
- }
-
- return 0;
- }
-
- static int lock(int cpu)
- {
- struct sembuf lock;
-
- lock.sem_num = cpu;
- lock.sem_op = 1;
- semop(semid[cpu], &lock, 1);
-
- return 0;
- }
-
- static int unlock(int cpu)
- {
- struct sembuf unlock;
-
- unlock.sem_num = cpu;
- unlock.sem_op = -1;
- semop(semid[cpu], &unlock, 1);
-
- return 0;
- }
-
- void free_sem(int cpu)
- {
- semctl(semid[cpu], 0, IPC_RMID);
- }
-
- int wr_multi(char *fn, unsigned long *data, int size)
- {
- int fd;
- char buf[MAX_BUF_SIZE];
- int ret;
-
- if (size==1)
- sprintf(buf, "%lx", *data);
- else if (size==3)
- sprintf(buf, "%lx,%lx,%lx", data[0], data[1], data[2]);
- else {
- fprintf(stderr,"write to file with wrong size!\n");
- return -1;
- }
-
- fd=open(fn, O_RDWR);
- if (!fd) {
- perror("Error:");
- return -1;
- }
- ret=write(fd, buf, sizeof(buf));
- close(fd);
- return ret;
- }
-
- int wr(char *fn, unsigned long data)
- {
- return wr_multi(fn, &data, 1);
- }
-
- int rd(char *fn, unsigned long *data)
- {
- int fd;
- char buf[MAX_BUF_SIZE];
-
- fd=open(fn, O_RDONLY);
- if (fd<0) {
- perror("Error:");
- return -1;
- }
- read(fd, buf, MAX_BUF_SIZE);
- *data=strtoul(buf, NULL, 16);
- close(fd);
- return 0;
- }
-
- int rd_status(char *path, int *status)
- {
- char fn[MAX_FN_SIZE];
- sprintf(fn, "%s/status", path);
- if (rd(fn, (u64*)status)<0) {
- perror("status reading error.\n");
- return -1;
- }
-
- return 0;
- }
-
- int rd_capabilities(char *path, u64 *capabilities)
- {
- char fn[MAX_FN_SIZE];
- sprintf(fn, "%s/capabilities", path);
- if (rd(fn, capabilities)<0) {
- perror("capabilities reading error.\n");
- return -1;
- }
-
- return 0;
- }
-
- int rd_all(char *path)
- {
- unsigned long err_type_info, err_struct_info, err_data_buffer;
- int status;
- unsigned long capabilities, resources;
- char fn[MAX_FN_SIZE];
-
- sprintf(fn, "%s/err_type_info", path);
- if (rd(fn, &err_type_info)<0) {
- perror("err_type_info reading error.\n");
- return -1;
- }
- printf("err_type_info=%lx\n", err_type_info);
-
- sprintf(fn, "%s/err_struct_info", path);
- if (rd(fn, &err_struct_info)<0) {
- perror("err_struct_info reading error.\n");
- return -1;
- }
- printf("err_struct_info=%lx\n", err_struct_info);
-
- sprintf(fn, "%s/err_data_buffer", path);
- if (rd(fn, &err_data_buffer)<0) {
- perror("err_data_buffer reading error.\n");
- return -1;
- }
- printf("err_data_buffer=%lx\n", err_data_buffer);
-
- sprintf(fn, "%s/status", path);
- if (rd("status", (u64*)&status)<0) {
- perror("status reading error.\n");
- return -1;
- }
- printf("status=%d\n", status);
-
- sprintf(fn, "%s/capabilities", path);
- if (rd(fn,&capabilities)<0) {
- perror("capabilities reading error.\n");
- return -1;
- }
- printf("capabilities=%lx\n", capabilities);
-
- sprintf(fn, "%s/resources", path);
- if (rd(fn, &resources)<0) {
- perror("resources reading error.\n");
- return -1;
- }
- printf("resources=%lx\n", resources);
-
- return 0;
- }
-
- int query_capabilities(char *path, err_type_info_t err_type_info,
- u64 *capabilities)
- {
- char fn[MAX_FN_SIZE];
- err_struct_info_t err_struct_info;
- err_data_buffer_t err_data_buffer;
-
- err_struct_info.err_struct_info=0;
- memset(err_data_buffer.err_data_buffer, -1, ERR_DATA_BUFFER_SIZE*8);
-
- sprintf(fn, "%s/err_type_info", path);
- wr(fn, err_type_info.err_type_info);
- sprintf(fn, "%s/err_struct_info", path);
- wr(fn, 0x0);
- sprintf(fn, "%s/err_data_buffer", path);
- wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
-
- // Fire pal_mc_error_inject procedure.
- sprintf(fn, "%s/call_start", path);
- wr(fn, mode);
-
- if (rd_capabilities(path, capabilities)<0)
- return -1;
-
- return 0;
- }
-
- int query_all_capabilities()
- {
- int status;
- err_type_info_t err_type_info;
- int err_sev, err_struct, struct_hier;
- int cap=0;
- u64 capabilities;
- char path[MAX_FN_SIZE];
-
- err_type_info.err_type_info=0; // Initial
- err_type_info.err_type_info_u.mode=0; // Query mode;
- err_type_info.err_type_info_u.err_inj=0;
-
- printf("All capabilities implemented in pal_mc_error_inject:\n");
- sprintf(path, PATH_FORMAT ,0);
- for (err_sev=0;err_sev<3;err_sev++)
- for (err_struct=0;err_struct<5;err_struct++)
- for (struct_hier=0;struct_hier<5;struct_hier++)
- {
- status=-1;
- capabilities=0;
- err_type_info.err_type_info_u.err_sev=err_sev;
- err_type_info.err_type_info_u.err_struct=err_struct;
- err_type_info.err_type_info_u.struct_hier=struct_hier;
-
- if (query_capabilities(path, err_type_info, &capabilities)<0)
- continue;
-
- if (rd_status(path, &status)<0)
- continue;
-
- if (status==0) {
- cap=1;
- printf("For err_sev=%d, err_struct=%d, struct_hier=%d: ",
- err_sev, err_struct, struct_hier);
- printf("capabilities 0x%lx\n", capabilities);
- }
- }
- if (!cap) {
- printf("No capabilities supported.\n");
- return 0;
- }
-
- return 0;
- }
-
- int err_inject(int cpu, char *path, err_type_info_t err_type_info,
- err_struct_info_t err_struct_info,
- err_data_buffer_t err_data_buffer)
- {
- int status;
- char fn[MAX_FN_SIZE];
-
- log_info(cpu, "err_type_info=%lx, err_struct_info=%lx, ",
- err_type_info.err_type_info,
- err_struct_info.err_struct_info);
- log_info(cpu,"err_data_buffer=[%lx,%lx,%lx]\n",
- err_data_buffer.err_data_buffer[0],
- err_data_buffer.err_data_buffer[1],
- err_data_buffer.err_data_buffer[2]);
- sprintf(fn, "%s/err_type_info", path);
- wr(fn, err_type_info.err_type_info);
- sprintf(fn, "%s/err_struct_info", path);
- wr(fn, err_struct_info.err_struct_info);
- sprintf(fn, "%s/err_data_buffer", path);
- wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
-
- // Fire pal_mc_error_inject procedure.
- sprintf(fn, "%s/call_start", path);
- wr(fn,mode);
-
- if (rd_status(path, &status)<0) {
- vbprintf("fail: read status\n");
- return -100;
- }
-
- if (status!=0) {
- log_info(cpu, "fail: status=%d\n", status);
- return status;
- }
-
- return status;
- }
-
- static int construct_data_buf(char *path, err_type_info_t err_type_info,
- err_struct_info_t err_struct_info,
- err_data_buffer_t *err_data_buffer,
- void *va1)
- {
- char fn[MAX_FN_SIZE];
- u64 virt_addr=0, phys_addr=0;
-
- vbprintf("va1=%lx\n", (u64)va1);
- memset(&err_data_buffer->err_data_buffer_cache, 0, ERR_DATA_BUFFER_SIZE*8);
-
- switch (err_type_info.err_type_info_u.err_struct) {
- case 1: // Cache
- switch (err_struct_info.err_struct_info_cache.cl_id) {
- case 1: //Virtual addr
- err_data_buffer->err_data_buffer_cache.inj_addr=(u64)va1;
- break;
- case 2: //Phys addr
- sprintf(fn, "%s/virtual_to_phys", path);
- virt_addr=(u64)va1;
- if (wr(fn,virt_addr)<0)
- return -1;
- rd(fn, &phys_addr);
- err_data_buffer->err_data_buffer_cache.inj_addr=phys_addr;
- break;
- default:
- printf("Not supported cl_id\n");
- break;
- }
- break;
- case 2: // TLB
- break;
- case 3: // Register file
- break;
- case 4: // Bus/system interconnect
- default:
- printf("Not supported err_struct\n");
- break;
- }
-
- return 0;
- }
-
- typedef struct {
- u64 cpu;
- u64 loop;
- u64 interval;
- u64 err_type_info;
- u64 err_struct_info;
- u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
- } parameters_t;
-
- parameters_t line_para;
- int para;
-
- static int empty_data_buffer(u64 *err_data_buffer)
- {
- int empty=1;
- int i;
-
- for (i=0;i<ERR_DATA_BUFFER_SIZE; i++)
- if (err_data_buffer[i]!=-1)
- empty=0;
-
- return empty;
- }
-
- int err_inj()
- {
- err_type_info_t err_type_info;
- err_struct_info_t err_struct_info;
- err_data_buffer_t err_data_buffer;
- int count;
- FILE *fp;
- unsigned long cpu, loop, interval, err_type_info_conf, err_struct_info_conf;
- u64 err_data_buffer_conf[ERR_DATA_BUFFER_SIZE];
- int num;
- int i;
- char path[MAX_FN_SIZE];
- parameters_t parameters[MAX_TASK_NUM]={};
- pid_t child_pid[MAX_TASK_NUM];
- time_t current_time;
- int status;
-
- if (!para) {
- fp=fopen("err.conf", "r");
- if (fp==NULL) {
- perror("Error open err.conf");
- return -1;
- }
-
- num=0;
- while (!feof(fp)) {
- char buf[256];
- memset(buf,0,256);
- fgets(buf, 256, fp);
- count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
- &cpu, &loop, &interval,&err_type_info_conf,
- &err_struct_info_conf,
- &err_data_buffer_conf[0],
- &err_data_buffer_conf[1],
- &err_data_buffer_conf[2]);
- if (count!=PARA_FIELD_NUM+3) {
- err_data_buffer_conf[0]=-1;
- err_data_buffer_conf[1]=-1;
- err_data_buffer_conf[2]=-1;
- count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx\n",
- &cpu, &loop, &interval,&err_type_info_conf,
- &err_struct_info_conf);
- if (count!=PARA_FIELD_NUM)
- continue;
- }
-
- parameters[num].cpu=cpu;
- parameters[num].loop=loop;
- parameters[num].interval= interval>MIN_INTERVAL
- ?interval:MIN_INTERVAL;
- parameters[num].err_type_info=err_type_info_conf;
- parameters[num].err_struct_info=err_struct_info_conf;
- memcpy(parameters[num++].err_data_buffer,
- err_data_buffer_conf,ERR_DATA_BUFFER_SIZE*8) ;
-
- if (num>=MAX_TASK_NUM)
- break;
- }
- }
- else {
- parameters[0].cpu=line_para.cpu;
- parameters[0].loop=line_para.loop;
- parameters[0].interval= line_para.interval>MIN_INTERVAL
- ?line_para.interval:MIN_INTERVAL;
- parameters[0].err_type_info=line_para.err_type_info;
- parameters[0].err_struct_info=line_para.err_struct_info;
- memcpy(parameters[0].err_data_buffer,
- line_para.err_data_buffer,ERR_DATA_BUFFER_SIZE*8) ;
-
- num=1;
- }
-
- /* Create semaphore: If one_lock, one semaphore for all processors.
- Otherwise, one semaphore for each processor. */
- if (one_lock) {
- if (create_sem(0)) {
- printf("Can not create semaphore...exit\n");
- free_sem(0);
- return -1;
- }
- }
- else {
- for (i=0;i<num;i++) {
- if (create_sem(parameters[i].cpu)) {
- printf("Can not create semaphore for cpu%d...exit\n",i);
- free_sem(parameters[num].cpu);
- return -1;
- }
- }
- }
-
- /* Create a shm segment which will be used to inject/consume errors on.*/
- if (create_shm()==-1) {
- printf("Error to create shm...exit\n");
- return -1;
- }
-
- for (i=0;i<num;i++) {
- pid_t pid;
-
- current_time=time(NULL);
- log_info(parameters[i].cpu, "\nBegine at %s", ctime(&current_time));
- log_info(parameters[i].cpu, "Configurations:\n");
- log_info(parameters[i].cpu,"On cpu%ld: loop=%lx, interval=%lx(s)",
- parameters[i].cpu,
- parameters[i].loop,
- parameters[i].interval);
- log_info(parameters[i].cpu," err_type_info=%lx,err_struct_info=%lx\n",
- parameters[i].err_type_info,
- parameters[i].err_struct_info);
-
- sprintf(path, PATH_FORMAT, (int)parameters[i].cpu);
- err_type_info.err_type_info=parameters[i].err_type_info;
- err_struct_info.err_struct_info=parameters[i].err_struct_info;
- memcpy(err_data_buffer.err_data_buffer,
- parameters[i].err_data_buffer,
- ERR_DATA_BUFFER_SIZE*8);
-
- pid=fork();
- if (pid==0) {
- unsigned long mask[MASK_SIZE];
- int j, k;
-
- void *va1, *va2;
-
- /* Allocate two memory areas va1 and va2 in shm */
- va1=shmaddr+parameters[i].cpu*PAGE_SIZE;
- va2=shmaddr+parameters[i].cpu*PAGE_SIZE+PAGE_SIZE;
-
- vbprintf("va1=%lx, va2=%lx\n", (u64)va1, (u64)va2);
- memset(va1, 0x1, PAGE_SIZE);
- memset(va2, 0x2, PAGE_SIZE);
-
- if (empty_data_buffer(err_data_buffer.err_data_buffer))
- /* If not specified yet, construct data buffer
- * with va1
- */
- construct_data_buf(path, err_type_info,
- err_struct_info, &err_data_buffer,va1);
-
- for (j=0;j<MASK_SIZE;j++)
- mask[j]=0;
-
- cpu=parameters[i].cpu;
- k = cpu%64;
- j = cpu/64;
- mask[j] = 1UL << k;
-
- if (sched_setaffinity(0, MASK_SIZE*8, mask)==-1) {
- perror("Error sched_setaffinity:");
- return -1;
- }
-
- for (j=0; j<parameters[i].loop; j++) {
- log_info(parameters[i].cpu,"Injection ");
- log_info(parameters[i].cpu,"on cpu%ld: #%d/%ld ",
-
- parameters[i].cpu,j+1, parameters[i].loop);
-
- /* Hold the lock */
- if (one_lock)
- lock(0);
- else
- /* Hold lock on this cpu */
- lock(parameters[i].cpu);
-
- if ((status=err_inject(parameters[i].cpu,
- path, err_type_info,
- err_struct_info, err_data_buffer))
- ==0) {
- /* consume the error for "inject only"*/
- memcpy(va2, va1, PAGE_SIZE);
- memcpy(va1, va2, PAGE_SIZE);
- log_info(parameters[i].cpu,
- "successful\n");
- }
- else {
- log_info(parameters[i].cpu,"fail:");
- log_info(parameters[i].cpu,
- "status=%d\n", status);
- unlock(parameters[i].cpu);
- break;
- }
- if (one_lock)
- /* Release the lock */
- unlock(0);
- /* Release lock on this cpu */
- else
- unlock(parameters[i].cpu);
-
- if (j < parameters[i].loop-1)
- sleep(parameters[i].interval);
- }
- current_time=time(NULL);
- log_info(parameters[i].cpu, "Done at %s", ctime(&current_time));
- return 0;
- }
- else if (pid<0) {
- perror("Error fork:");
- continue;
- }
- child_pid[i]=pid;
- }
- for (i=0;i<num;i++)
- waitpid(child_pid[i], NULL, 0);
-
- if (one_lock)
- free_sem(0);
- else
- for (i=0;i<num;i++)
- free_sem(parameters[i].cpu);
-
- printf("All done.\n");
-
- return 0;
- }
-
- void help()
- {
- printf("err_inject_tool:\n");
- printf("\t-q: query all capabilities. default: off\n");
- printf("\t-m: procedure mode. 1: physical 2: virtual. default: 1\n");
- printf("\t-i: inject errors. default: off\n");
- printf("\t-l: one lock per cpu. default: one lock for all\n");
- printf("\t-e: error parameters:\n");
- printf("\t\tcpu,loop,interval,err_type_info,err_struct_info[,err_data_buffer[0],err_data_buffer[1],err_data_buffer[2]]\n");
- printf("\t\t cpu: logical cpu number the error will be inject in.\n");
- printf("\t\t loop: times the error will be injected.\n");
- printf("\t\t interval: In second. every so often one error is injected.\n");
- printf("\t\t err_type_info, err_struct_info: PAL parameters.\n");
- printf("\t\t err_data_buffer: PAL parameter. Optional. If not present,\n");
- printf("\t\t it's constructed by tool automatically. Be\n");
- printf("\t\t careful to provide err_data_buffer and make\n");
- printf("\t\t sure it's working with the environment.\n");
- printf("\t Note:no space between error parameters.\n");
- printf("\t default: Take error parameters from err.conf instead of command line.\n");
- printf("\t-v: verbose. default: off\n");
- printf("\t-h: help\n\n");
- printf("The tool will take err.conf file as ");
- printf("input to inject single or multiple errors ");
- printf("on one or multiple cpus in parallel.\n");
- }
-
- int main(int argc, char **argv)
- {
- char c;
- int do_err_inj=0;
- int do_query_all=0;
- int count;
- u32 m;
-
- /* Default one lock for all cpu's */
- one_lock=1;
- while ((c = getopt(argc, argv, "m:iqvhle:")) != EOF)
- switch (c) {
- case 'm': /* Procedure mode. 1: phys 2: virt */
- count=sscanf(optarg, "%x", &m);
- if (count!=1 || (m!=1 && m!=2)) {
- printf("Wrong mode number.\n");
- help();
- return -1;
- }
- mode=m;
- break;
- case 'i': /* Inject errors */
- do_err_inj=1;
- break;
- case 'q': /* Query */
- do_query_all=1;
- break;
- case 'v': /* Verbose */
- verbose=1;
- break;
- case 'l': /* One lock per cpu */
- one_lock=0;
- break;
- case 'e': /* error arguments */
- /* Take parameters:
- * #cpu, loop, interval, err_type_info, err_struct_info[, err_data_buffer]
- * err_data_buffer is optional. Recommend not to specify
- * err_data_buffer. Better to use tool to generate it.
- */
- count=sscanf(optarg,
- "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
- &line_para.cpu,
- &line_para.loop,
- &line_para.interval,
- &line_para.err_type_info,
- &line_para.err_struct_info,
- &line_para.err_data_buffer[0],
- &line_para.err_data_buffer[1],
- &line_para.err_data_buffer[2]);
- if (count!=PARA_FIELD_NUM+3) {
- line_para.err_data_buffer[0]=-1,
- line_para.err_data_buffer[1]=-1,
- line_para.err_data_buffer[2]=-1;
- count=sscanf(optarg, "%lx, %lx, %lx, %lx, %lx\n",
- &line_para.cpu,
- &line_para.loop,
- &line_para.interval,
- &line_para.err_type_info,
- &line_para.err_struct_info);
- if (count!=PARA_FIELD_NUM) {
- printf("Wrong error arguments.\n");
- help();
- return -1;
- }
- }
- para=1;
- break;
- continue;
- break;
- case 'h':
- help();
- return 0;
- default:
- break;
- }
-
- if (do_query_all)
- query_all_capabilities();
- if (do_err_inj)
- err_inj();
-
- if (!do_query_all && !do_err_inj)
- help();
-
- return 0;
- }
diff --git a/Documentation/arch/ia64/features.rst b/Documentation/arch/ia64/features.rst
deleted file mode 100644
index d7226fdcf5f8..000000000000
--- a/Documentation/arch/ia64/features.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. kernel-feat:: $srctree/Documentation/features ia64
diff --git a/Documentation/arch/ia64/fsys.rst b/Documentation/arch/ia64/fsys.rst
deleted file mode 100644
index a702d2cc94b6..000000000000
--- a/Documentation/arch/ia64/fsys.rst
+++ /dev/null
@@ -1,303 +0,0 @@
-===================================
-Light-weight System Calls for IA-64
-===================================
-
- Started: 13-Jan-2003
-
- Last update: 27-Sep-2003
-
- David Mosberger-Tang
- <davidm@hpl.hp.com>
-
-Using the "epc" instruction effectively introduces a new mode of
-execution to the ia64 linux kernel. We call this mode the
-"fsys-mode". To recap, the normal states of execution are:
-
- - kernel mode:
- Both the register stack and the memory stack have been
- switched over to kernel memory. The user-level state is saved
- in a pt-regs structure at the top of the kernel memory stack.
-
- - user mode:
- Both the register stack and the kernel stack are in
- user memory. The user-level state is contained in the
- CPU registers.
-
- - bank 0 interruption-handling mode:
- This is the non-interruptible state which all
- interruption-handlers start execution in. The user-level
- state remains in the CPU registers and some kernel state may
- be stored in bank 0 of registers r16-r31.
-
-In contrast, fsys-mode has the following special properties:
-
- - execution is at privilege level 0 (most-privileged)
-
- - CPU registers may contain a mixture of user-level and kernel-level
- state (it is the responsibility of the kernel to ensure that no
- security-sensitive kernel-level state is leaked back to
- user-level)
-
- - execution is interruptible and preemptible (an fsys-mode handler
- can disable interrupts and avoid all other interruption-sources
- to avoid preemption)
-
- - neither the memory-stack nor the register-stack can be trusted while
- in fsys-mode (they point to the user-level stacks, which may
- be invalid, or completely bogus addresses)
-
-In summary, fsys-mode is much more similar to running in user-mode
-than it is to running in kernel-mode. Of course, given that the
-privilege level is at level 0, this means that fsys-mode requires some
-care (see below).
-
-
-How to tell fsys-mode
-=====================
-
-Linux operates in fsys-mode when (a) the privilege level is 0 (most
-privileged) and (b) the stacks have NOT been switched to kernel memory
-yet. For convenience, the header file <asm-ia64/ptrace.h> provides
-three macros::
-
- user_mode(regs)
- user_stack(task,regs)
- fsys_mode(task,regs)
-
-The "regs" argument is a pointer to a pt_regs structure. The "task"
-argument is a pointer to the task structure to which the "regs"
-pointer belongs to. user_mode() returns TRUE if the CPU state pointed
-to by "regs" was executing in user mode (privilege level 3).
-user_stack() returns TRUE if the state pointed to by "regs" was
-executing on the user-level stack(s). Finally, fsys_mode() returns
-TRUE if the CPU state pointed to by "regs" was executing in fsys-mode.
-The fsys_mode() macro is equivalent to the expression::
-
- !user_mode(regs) && user_stack(task,regs)
-
-How to write an fsyscall handler
-================================
-
-The file arch/ia64/kernel/fsys.S contains a table of fsyscall-handlers
-(fsyscall_table). This table contains one entry for each system call.
-By default, a system call is handled by fsys_fallback_syscall(). This
-routine takes care of entering (full) kernel mode and calling the
-normal Linux system call handler. For performance-critical system
-calls, it is possible to write a hand-tuned fsyscall_handler. For
-example, fsys.S contains fsys_getpid(), which is a hand-tuned version
-of the getpid() system call.
-
-The entry and exit-state of an fsyscall handler is as follows:
-
-Machine state on entry to fsyscall handler
-------------------------------------------
-
- ========= ===============================================================
- r10 0
- r11 saved ar.pfs (a user-level value)
- r15 system call number
- r16 "current" task pointer (in normal kernel-mode, this is in r13)
- r32-r39 system call arguments
- b6 return address (a user-level value)
- ar.pfs previous frame-state (a user-level value)
- PSR.be cleared to zero (i.e., little-endian byte order is in effect)
- - all other registers may contain values passed in from user-mode
- ========= ===============================================================
-
-Required machine state on exit to fsyscall handler
---------------------------------------------------
-
- ========= ===========================================================
- r11 saved ar.pfs (as passed into the fsyscall handler)
- r15 system call number (as passed into the fsyscall handler)
- r32-r39 system call arguments (as passed into the fsyscall handler)
- b6 return address (as passed into the fsyscall handler)
- ar.pfs previous frame-state (as passed into the fsyscall handler)
- ========= ===========================================================
-
-Fsyscall handlers can execute with very little overhead, but with that
-speed comes a set of restrictions:
-
- * Fsyscall-handlers MUST check for any pending work in the flags
- member of the thread-info structure and if any of the
- TIF_ALLWORK_MASK flags are set, the handler needs to fall back on
- doing a full system call (by calling fsys_fallback_syscall).
-
- * Fsyscall-handlers MUST preserve incoming arguments (r32-r39, r11,
- r15, b6, and ar.pfs) because they will be needed in case of a
- system call restart. Of course, all "preserved" registers also
- must be preserved, in accordance to the normal calling conventions.
-
- * Fsyscall-handlers MUST check argument registers for containing a
- NaT value before using them in any way that could trigger a
- NaT-consumption fault. If a system call argument is found to
- contain a NaT value, an fsyscall-handler may return immediately
- with r8=EINVAL, r10=-1.
-
- * Fsyscall-handlers MUST NOT use the "alloc" instruction or perform
- any other operation that would trigger mandatory RSE
- (register-stack engine) traffic.
-
- * Fsyscall-handlers MUST NOT write to any stacked registers because
- it is not safe to assume that user-level called a handler with the
- proper number of arguments.
-
- * Fsyscall-handlers need to be careful when accessing per-CPU variables:
- unless proper safe-guards are taken (e.g., interruptions are avoided),
- execution may be pre-empted and resumed on another CPU at any given
- time.
-
- * Fsyscall-handlers must be careful not to leak sensitive kernel'
- information back to user-level. In particular, before returning to
- user-level, care needs to be taken to clear any scratch registers
- that could contain sensitive information (note that the current
- task pointer is not considered sensitive: it's already exposed
- through ar.k6).
-
- * Fsyscall-handlers MUST NOT access user-memory without first
- validating access-permission (this can be done typically via
- probe.r.fault and/or probe.w.fault) and without guarding against
- memory access exceptions (this can be done with the EX() macros
- defined by asmmacro.h).
-
-The above restrictions may seem draconian, but remember that it's
-possible to trade off some of the restrictions by paying a slightly
-higher overhead. For example, if an fsyscall-handler could benefit
-from the shadow register bank, it could temporarily disable PSR.i and
-PSR.ic, switch to bank 0 (bsw.0) and then use the shadow registers as
-needed. In other words, following the above rules yields extremely
-fast system call execution (while fully preserving system call
-semantics), but there is also a lot of flexibility in handling more
-complicated cases.
-
-Signal handling
-===============
-
-The delivery of (asynchronous) signals must be delayed until fsys-mode
-is exited. This is accomplished with the help of the lower-privilege
-transfer trap: arch/ia64/kernel/process.c:do_notify_resume_user()
-checks whether the interrupted task was in fsys-mode and, if so, sets
-PSR.lp and returns immediately. When fsys-mode is exited via the
-"br.ret" instruction that lowers the privilege level, a trap will
-occur. The trap handler clears PSR.lp again and returns immediately.
-The kernel exit path then checks for and delivers any pending signals.
-
-PSR Handling
-============
-
-The "epc" instruction doesn't change the contents of PSR at all. This
-is in contrast to a regular interruption, which clears almost all
-bits. Because of that, some care needs to be taken to ensure things
-work as expected. The following discussion describes how each PSR bit
-is handled.
-
-======= =======================================================================
-PSR.be Cleared when entering fsys-mode. A srlz.d instruction is used
- to ensure the CPU is in little-endian mode before the first
- load/store instruction is executed. PSR.be is normally NOT
- restored upon return from an fsys-mode handler. In other
- words, user-level code must not rely on PSR.be being preserved
- across a system call.
-PSR.up Unchanged.
-PSR.ac Unchanged.
-PSR.mfl Unchanged. Note: fsys-mode handlers must not write-registers!
-PSR.mfh Unchanged. Note: fsys-mode handlers must not write-registers!
-PSR.ic Unchanged. Note: fsys-mode handlers can clear the bit, if needed.
-PSR.i Unchanged. Note: fsys-mode handlers can clear the bit, if needed.
-PSR.pk Unchanged.
-PSR.dt Unchanged.
-PSR.dfl Unchanged. Note: fsys-mode handlers must not write-registers!
-PSR.dfh Unchanged. Note: fsys-mode handlers must not write-registers!
-PSR.sp Unchanged.
-PSR.pp Unchanged.
-PSR.di Unchanged.
-PSR.si Unchanged.
-PSR.db Unchanged. The kernel prevents user-level from setting a hardware
- breakpoint that triggers at any privilege level other than
- 3 (user-mode).
-PSR.lp Unchanged.
-PSR.tb Lazy redirect. If a taken-branch trap occurs while in
- fsys-mode, the trap-handler modifies the saved machine state
- such that execution resumes in the gate page at
- syscall_via_break(), with privilege level 3. Note: the
- taken branch would occur on the branch invoking the
- fsyscall-handler, at which point, by definition, a syscall
- restart is still safe. If the system call number is invalid,
- the fsys-mode handler will return directly to user-level. This
- return will trigger a taken-branch trap, but since the trap is
- taken _after_ restoring the privilege level, the CPU has already
- left fsys-mode, so no special treatment is needed.
-PSR.rt Unchanged.
-PSR.cpl Cleared to 0.
-PSR.is Unchanged (guaranteed to be 0 on entry to the gate page).
-PSR.mc Unchanged.
-PSR.it Unchanged (guaranteed to be 1).
-PSR.id Unchanged. Note: the ia64 linux kernel never sets this bit.
-PSR.da Unchanged. Note: the ia64 linux kernel never sets this bit.
-PSR.dd Unchanged. Note: the ia64 linux kernel never sets this bit.
-PSR.ss Lazy redirect. If set, "epc" will cause a Single Step Trap to
- be taken. The trap handler then modifies the saved machine
- state such that execution resumes in the gate page at
- syscall_via_break(), with privilege level 3.
-PSR.ri Unchanged.
-PSR.ed Unchanged. Note: This bit could only have an effect if an fsys-mode
- handler performed a speculative load that gets NaTted. If so, this
- would be the normal & expected behavior, so no special treatment is
- needed.
-PSR.bn Unchanged. Note: fsys-mode handlers may clear the bit, if needed.
- Doing so requires clearing PSR.i and PSR.ic as well.
-PSR.ia Unchanged. Note: the ia64 linux kernel never sets this bit.
-======= =======================================================================
-
-Using fast system calls
-=======================
-
-To use fast system calls, userspace applications need simply call
-__kernel_syscall_via_epc(). For example
-
--- example fgettimeofday() call --
-
--- fgettimeofday.S --
-
-::
-
- #include <asm/asmmacro.h>
-
- GLOBAL_ENTRY(fgettimeofday)
- .prologue
- .save ar.pfs, r11
- mov r11 = ar.pfs
- .body
-
- mov r2 = 0xa000000000020660;; // gate address
- // found by inspection of System.map for the
- // __kernel_syscall_via_epc() function. See
- // below for how to do this for real.
-
- mov b7 = r2
- mov r15 = 1087 // gettimeofday syscall
- ;;
- br.call.sptk.many b6 = b7
- ;;
-
- .restore sp
-
- mov ar.pfs = r11
- br.ret.sptk.many rp;; // return to caller
- END(fgettimeofday)
-
--- end fgettimeofday.S --
-
-In reality, getting the gate address is accomplished by two extra
-values passed via the ELF auxiliary vector (include/asm-ia64/elf.h)
-
- * AT_SYSINFO : is the address of __kernel_syscall_via_epc()
- * AT_SYSINFO_EHDR : is the address of the kernel gate ELF DSO
-
-The ELF DSO is a pre-linked library that is mapped in by the kernel at
-the gate page. It is a proper ELF shared object so, with a dynamic
-loader that recognises the library, you should be able to make calls to
-the exported functions within it as with any other shared library.
-AT_SYSINFO points into the kernel DSO at the
-__kernel_syscall_via_epc() function for historical reasons (it was
-used before the kernel DSO) and as a convenience.
diff --git a/Documentation/arch/ia64/ia64.rst b/Documentation/arch/ia64/ia64.rst
deleted file mode 100644
index b725019a9492..000000000000
--- a/Documentation/arch/ia64/ia64.rst
+++ /dev/null
@@ -1,49 +0,0 @@
-===========================================
-Linux kernel release for the IA-64 Platform
-===========================================
-
- These are the release notes for Linux since version 2.4 for IA-64
- platform. This document provides information specific to IA-64
- ONLY, to get additional information about the Linux kernel also
- read the original Linux README provided with the kernel.
-
-Installing the Kernel
-=====================
-
- - IA-64 kernel installation is the same as the other platforms, see
- original README for details.
-
-
-Software Requirements
-=====================
-
- Compiling and running this kernel requires an IA-64 compliant GCC
- compiler. And various software packages also compiled with an
- IA-64 compliant GCC compiler.
-
-
-Configuring the Kernel
-======================
-
- Configuration is the same, see original README for details.
-
-
-Compiling the Kernel:
-
- - Compiling this kernel doesn't differ from other platform so read
- the original README for details BUT make sure you have an IA-64
- compliant GCC compiler.
-
-IA-64 Specifics
-===============
-
- - General issues:
-
- * Hardly any performance tuning has been done. Obvious targets
- include the library routines (IP checksum, etc.). Less
- obvious targets include making sure we don't flush the TLB
- needlessly, etc.
-
- * SMP locks cleanup/optimization
-
- * IA32 support. Currently experimental. It mostly works.
diff --git a/Documentation/arch/ia64/index.rst b/Documentation/arch/ia64/index.rst
deleted file mode 100644
index 761f2154dfa2..000000000000
--- a/Documentation/arch/ia64/index.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==================
-IA-64 Architecture
-==================
-
-.. toctree::
- :maxdepth: 1
-
- ia64
- aliasing
- efirtc
- err_inject
- fsys
- irq-redir
- mca
- serial
-
- features
diff --git a/Documentation/arch/ia64/irq-redir.rst b/Documentation/arch/ia64/irq-redir.rst
deleted file mode 100644
index 6bbbbe4f73ef..000000000000
--- a/Documentation/arch/ia64/irq-redir.rst
+++ /dev/null
@@ -1,80 +0,0 @@
-==============================
-IRQ affinity on IA64 platforms
-==============================
-
-07.01.2002, Erich Focht <efocht@ess.nec.de>
-
-
-By writing to /proc/irq/IRQ#/smp_affinity the interrupt routing can be
-controlled. The behavior on IA64 platforms is slightly different from
-that described in Documentation/core-api/irq/irq-affinity.rst for i386 systems.
-
-Because of the usage of SAPIC mode and physical destination mode the
-IRQ target is one particular CPU and cannot be a mask of several
-CPUs. Only the first non-zero bit is taken into account.
-
-
-Usage examples
-==============
-
-The target CPU has to be specified as a hexadecimal CPU mask. The
-first non-zero bit is the selected CPU. This format has been kept for
-compatibility reasons with i386.
-
-Set the delivery mode of interrupt 41 to fixed and route the
-interrupts to CPU #3 (logical CPU number) (2^3=0x08)::
-
- echo "8" >/proc/irq/41/smp_affinity
-
-Set the default route for IRQ number 41 to CPU 6 in lowest priority
-delivery mode (redirectable)::
-
- echo "r 40" >/proc/irq/41/smp_affinity
-
-The output of the command::
-
- cat /proc/irq/IRQ#/smp_affinity
-
-gives the target CPU mask for the specified interrupt vector. If the CPU
-mask is preceded by the character "r", the interrupt is redirectable
-(i.e. lowest priority mode routing is used), otherwise its route is
-fixed.
-
-
-
-Initialization and default behavior
-===================================
-
-If the platform features IRQ redirection (info provided by SAL) all
-IO-SAPIC interrupts are initialized with CPU#0 as their default target
-and the routing is the so called "lowest priority mode" (actually
-fixed SAPIC mode with hint). The XTP chipset registers are used as hints
-for the IRQ routing. Currently in Linux XTP registers can have three
-values:
-
- - minimal for an idle task,
- - normal if any other task runs,
- - maximal if the CPU is going to be switched off.
-
-The IRQ is routed to the CPU with lowest XTP register value, the
-search begins at the default CPU. Therefore most of the interrupts
-will be handled by CPU #0.
-
-If the platform doesn't feature interrupt redirection IOSAPIC fixed
-routing is used. The target CPUs are distributed in a round robin
-manner. IRQs will be routed only to the selected target CPUs. Check
-with::
-
- cat /proc/interrupts
-
-
-
-Comments
-========
-
-On large (multi-node) systems it is recommended to route the IRQs to
-the node to which the corresponding device is connected.
-For systems like the NEC AzusA we get IRQ node-affinity for free. This
-is because usually the chipsets on each node redirect the interrupts
-only to their own CPUs (as they cannot see the XTP registers on the
-other nodes).
diff --git a/Documentation/arch/ia64/mca.rst b/Documentation/arch/ia64/mca.rst
deleted file mode 100644
index 08270bba44a4..000000000000
--- a/Documentation/arch/ia64/mca.rst
+++ /dev/null
@@ -1,198 +0,0 @@
-=============================================================
-An ad-hoc collection of notes on IA64 MCA and INIT processing
-=============================================================
-
-Feel free to update it with notes about any area that is not clear.
-
----
-
-MCA/INIT are completely asynchronous. They can occur at any time, when
-the OS is in any state. Including when one of the cpus is already
-holding a spinlock. Trying to get any lock from MCA/INIT state is
-asking for deadlock. Also the state of structures that are protected
-by locks is indeterminate, including linked lists.
-
----
-
-The complicated ia64 MCA process. All of this is mandated by Intel's
-specification for ia64 SAL, error recovery and unwind, it is not as
-if we have a choice here.
-
-* MCA occurs on one cpu, usually due to a double bit memory error.
- This is the monarch cpu.
-
-* SAL sends an MCA rendezvous interrupt (which is a normal interrupt)
- to all the other cpus, the slaves.
-
-* Slave cpus that receive the MCA interrupt call down into SAL, they
- end up spinning disabled while the MCA is being serviced.
-
-* If any slave cpu was already spinning disabled when the MCA occurred
- then it cannot service the MCA interrupt. SAL waits ~20 seconds then
- sends an unmaskable INIT event to the slave cpus that have not
- already rendezvoused.
-
-* Because MCA/INIT can be delivered at any time, including when the cpu
- is down in PAL in physical mode, the registers at the time of the
- event are _completely_ undefined. In particular the MCA/INIT
- handlers cannot rely on the thread pointer, PAL physical mode can
- (and does) modify TP. It is allowed to do that as long as it resets
- TP on return. However MCA/INIT events expose us to these PAL
- internal TP changes. Hence curr_task().
-
-* If an MCA/INIT event occurs while the kernel was running (not user
- space) and the kernel has called PAL then the MCA/INIT handler cannot
- assume that the kernel stack is in a fit state to be used. Mainly
- because PAL may or may not maintain the stack pointer internally.
- Because the MCA/INIT handlers cannot trust the kernel stack, they
- have to use their own, per-cpu stacks. The MCA/INIT stacks are
- preformatted with just enough task state to let the relevant handlers
- do their job.
-
-* Unlike most other architectures, the ia64 struct task is embedded in
- the kernel stack[1]. So switching to a new kernel stack means that
- we switch to a new task as well. Because various bits of the kernel
- assume that current points into the struct task, switching to a new
- stack also means a new value for current.
-
-* Once all slaves have rendezvoused and are spinning disabled, the
- monarch is entered. The monarch now tries to diagnose the problem
- and decide if it can recover or not.
-
-* Part of the monarch's job is to look at the state of all the other
- tasks. The only way to do that on ia64 is to call the unwinder,
- as mandated by Intel.
-
-* The starting point for the unwind depends on whether a task is
- running or not. That is, whether it is on a cpu or is blocked. The
- monarch has to determine whether or not a task is on a cpu before it
- knows how to start unwinding it. The tasks that received an MCA or
- INIT event are no longer running, they have been converted to blocked
- tasks. But (and its a big but), the cpus that received the MCA
- rendezvous interrupt are still running on their normal kernel stacks!
-
-* To distinguish between these two cases, the monarch must know which
- tasks are on a cpu and which are not. Hence each slave cpu that
- switches to an MCA/INIT stack, registers its new stack using
- set_curr_task(), so the monarch can tell that the _original_ task is
- no longer running on that cpu. That gives us a decent chance of
- getting a valid backtrace of the _original_ task.
-
-* MCA/INIT can be nested, to a depth of 2 on any cpu. In the case of a
- nested error, we want diagnostics on the MCA/INIT handler that
- failed, not on the task that was originally running. Again this
- requires set_curr_task() so the MCA/INIT handlers can register their
- own stack as running on that cpu. Then a recursive error gets a
- trace of the failing handler's "task".
-
-[1]
- My (Keith Owens) original design called for ia64 to separate its
- struct task and the kernel stacks. Then the MCA/INIT data would be
- chained stacks like i386 interrupt stacks. But that required
- radical surgery on the rest of ia64, plus extra hard wired TLB
- entries with its associated performance degradation. David
- Mosberger vetoed that approach. Which meant that separate kernel
- stacks meant separate "tasks" for the MCA/INIT handlers.
-
----
-
-INIT is less complicated than MCA. Pressing the nmi button or using
-the equivalent command on the management console sends INIT to all
-cpus. SAL picks one of the cpus as the monarch and the rest are
-slaves. All the OS INIT handlers are entered at approximately the same
-time. The OS monarch prints the state of all tasks and returns, after
-which the slaves return and the system resumes.
-
-At least that is what is supposed to happen. Alas there are broken
-versions of SAL out there. Some drive all the cpus as monarchs. Some
-drive them all as slaves. Some drive one cpu as monarch, wait for that
-cpu to return from the OS then drive the rest as slaves. Some versions
-of SAL cannot even cope with returning from the OS, they spin inside
-SAL on resume. The OS INIT code has workarounds for some of these
-broken SAL symptoms, but some simply cannot be fixed from the OS side.
-
----
-
-The scheduler hooks used by ia64 (curr_task, set_curr_task) are layer
-violations. Unfortunately MCA/INIT start off as massive layer
-violations (can occur at _any_ time) and they build from there.
-
-At least ia64 makes an attempt at recovering from hardware errors, but
-it is a difficult problem because of the asynchronous nature of these
-errors. When processing an unmaskable interrupt we sometimes need
-special code to cope with our inability to take any locks.
-
----
-
-How is ia64 MCA/INIT different from x86 NMI?
-
-* x86 NMI typically gets delivered to one cpu. MCA/INIT gets sent to
- all cpus.
-
-* x86 NMI cannot be nested. MCA/INIT can be nested, to a depth of 2
- per cpu.
-
-* x86 has a separate struct task which points to one of multiple kernel
- stacks. ia64 has the struct task embedded in the single kernel
- stack, so switching stack means switching task.
-
-* x86 does not call the BIOS so the NMI handler does not have to worry
- about any registers having changed. MCA/INIT can occur while the cpu
- is in PAL in physical mode, with undefined registers and an undefined
- kernel stack.
-
-* i386 backtrace is not very sensitive to whether a process is running
- or not. ia64 unwind is very, very sensitive to whether a process is
- running or not.
-
----
-
-What happens when MCA/INIT is delivered what a cpu is running user
-space code?
-
-The user mode registers are stored in the RSE area of the MCA/INIT on
-entry to the OS and are restored from there on return to SAL, so user
-mode registers are preserved across a recoverable MCA/INIT. Since the
-OS has no idea what unwind data is available for the user space stack,
-MCA/INIT never tries to backtrace user space. Which means that the OS
-does not bother making the user space process look like a blocked task,
-i.e. the OS does not copy pt_regs and switch_stack to the user space
-stack. Also the OS has no idea how big the user space RSE and memory
-stacks are, which makes it too risky to copy the saved state to a user
-mode stack.
-
----
-
-How do we get a backtrace on the tasks that were running when MCA/INIT
-was delivered?
-
-mca.c:::ia64_mca_modify_original_stack(). That identifies and
-verifies the original kernel stack, copies the dirty registers from
-the MCA/INIT stack's RSE to the original stack's RSE, copies the
-skeleton struct pt_regs and switch_stack to the original stack, fills
-in the skeleton structures from the PAL minstate area and updates the
-original stack's thread.ksp. That makes the original stack look
-exactly like any other blocked task, i.e. it now appears to be
-sleeping. To get a backtrace, just start with thread.ksp for the
-original task and unwind like any other sleeping task.
-
----
-
-How do we identify the tasks that were running when MCA/INIT was
-delivered?
-
-If the previous task has been verified and converted to a blocked
-state, then sos->prev_task on the MCA/INIT stack is updated to point to
-the previous task. You can look at that field in dumps or debuggers.
-To help distinguish between the handler and the original tasks,
-handlers have _TIF_MCA_INIT set in thread_info.flags.
-
-The sos data is always in the MCA/INIT handler stack, at offset
-MCA_SOS_OFFSET. You can get that value from mca_asm.h or calculate it
-as KERNEL_STACK_SIZE - sizeof(struct pt_regs) - sizeof(struct
-ia64_sal_os_state), with 16 byte alignment for all structures.
-
-Also the comm field of the MCA/INIT task is modified to include the pid
-of the original task, for humans to use. For example, a comm field of
-'MCA 12159' means that pid 12159 was running when the MCA was
-delivered.
diff --git a/Documentation/arch/ia64/serial.rst b/Documentation/arch/ia64/serial.rst
deleted file mode 100644
index 1de70c305a79..000000000000
--- a/Documentation/arch/ia64/serial.rst
+++ /dev/null
@@ -1,165 +0,0 @@
-==============
-Serial Devices
-==============
-
-Serial Device Naming
-====================
-
- As of 2.6.10, serial devices on ia64 are named based on the
- order of ACPI and PCI enumeration. The first device in the
- ACPI namespace (if any) becomes /dev/ttyS0, the second becomes
- /dev/ttyS1, etc., and PCI devices are named sequentially
- starting after the ACPI devices.
-
- Prior to 2.6.10, there were confusing exceptions to this:
-
- - Firmware on some machines (mostly from HP) provides an HCDP
- table[1] that tells the kernel about devices that can be used
- as a serial console. If the user specified "console=ttyS0"
- or the EFI ConOut path contained only UART devices, the
- kernel registered the device described by the HCDP as
- /dev/ttyS0.
-
- - If there was no HCDP, we assumed there were UARTs at the
- legacy COM port addresses (I/O ports 0x3f8 and 0x2f8), so
- the kernel registered those as /dev/ttyS0 and /dev/ttyS1.
-
- Any additional ACPI or PCI devices were registered sequentially
- after /dev/ttyS0 as they were discovered.
-
- With an HCDP, device names changed depending on EFI configuration
- and "console=" arguments. Without an HCDP, device names didn't
- change, but we registered devices that might not really exist.
-
- For example, an HP rx1600 with a single built-in serial port
- (described in the ACPI namespace) plus an MP[2] (a PCI device) has
- these ports:
-
- ========== ========== ============ ============ =======
- Type MMIO pre-2.6.10 pre-2.6.10 2.6.10+
- address
- (EFI console (EFI console
- on builtin) on MP port)
- ========== ========== ============ ============ =======
- builtin 0xff5e0000 ttyS0 ttyS1 ttyS0
- MP UPS 0xf8031000 ttyS1 ttyS2 ttyS1
- MP Console 0xf8030000 ttyS2 ttyS0 ttyS2
- MP 2 0xf8030010 ttyS3 ttyS3 ttyS3
- MP 3 0xf8030038 ttyS4 ttyS4 ttyS4
- ========== ========== ============ ============ =======
-
-Console Selection
-=================
-
- EFI knows what your console devices are, but it doesn't tell the
- kernel quite enough to actually locate them. The DIG64 HCDP
- table[1] does tell the kernel where potential serial console
- devices are, but not all firmware supplies it. Also, EFI supports
- multiple simultaneous consoles and doesn't tell the kernel which
- should be the "primary" one.
-
- So how do you tell Linux which console device to use?
-
- - If your firmware supplies the HCDP, it is simplest to
- configure EFI with a single device (either a UART or a VGA
- card) as the console. Then you don't need to tell Linux
- anything; the kernel will automatically use the EFI console.
-
- (This works only in 2.6.6 or later; prior to that you had
- to specify "console=ttyS0" to get a serial console.)
-
- - Without an HCDP, Linux defaults to a VGA console unless you
- specify a "console=" argument.
-
- NOTE: Don't assume that a serial console device will be /dev/ttyS0.
- It might be ttyS1, ttyS2, etc. Make sure you have the appropriate
- entries in /etc/inittab (for getty) and /etc/securetty (to allow
- root login).
-
-Early Serial Console
-====================
-
- The kernel can't start using a serial console until it knows where
- the device lives. Normally this happens when the driver enumerates
- all the serial devices, which can happen a minute or more after the
- kernel starts booting.
-
- 2.6.10 and later kernels have an "early uart" driver that works
- very early in the boot process. The kernel will automatically use
- this if the user supplies an argument like "console=uart,io,0x3f8",
- or if the EFI console path contains only a UART device and the
- firmware supplies an HCDP.
-
-Troubleshooting Serial Console Problems
-=======================================
-
- No kernel output after elilo prints "Uncompressing Linux... done":
-
- - You specified "console=ttyS0" but Linux changed the device
- to which ttyS0 refers. Configure exactly one EFI console
- device[3] and remove the "console=" option.
-
- - The EFI console path contains both a VGA device and a UART.
- EFI and elilo use both, but Linux defaults to VGA. Remove
- the VGA device from the EFI console path[3].
-
- - Multiple UARTs selected as EFI console devices. EFI and
- elilo use all selected devices, but Linux uses only one.
- Make sure only one UART is selected in the EFI console
- path[3].
-
- - You're connected to an HP MP port[2] but have a non-MP UART
- selected as EFI console device. EFI uses the MP as a
- console device even when it isn't explicitly selected.
- Either move the console cable to the non-MP UART, or change
- the EFI console path[3] to the MP UART.
-
- Long pause (60+ seconds) between "Uncompressing Linux... done" and
- start of kernel output:
-
- - No early console because you used "console=ttyS<n>". Remove
- the "console=" option if your firmware supplies an HCDP.
-
- - If you don't have an HCDP, the kernel doesn't know where
- your console lives until the driver discovers serial
- devices. Use "console=uart,io,0x3f8" (or appropriate
- address for your machine).
-
- Kernel and init script output works fine, but no "login:" prompt:
-
- - Add getty entry to /etc/inittab for console tty. Look for
- the "Adding console on ttyS<n>" message that tells you which
- device is the console.
-
- "login:" prompt, but can't login as root:
-
- - Add entry to /etc/securetty for console tty.
-
- No ACPI serial devices found in 2.6.17 or later:
-
- - Turn on CONFIG_PNP and CONFIG_PNPACPI. Prior to 2.6.17, ACPI
- serial devices were discovered by 8250_acpi. In 2.6.17,
- 8250_acpi was replaced by the combination of 8250_pnp and
- CONFIG_PNPACPI.
-
-
-
-[1]
- http://www.dig64.org/specifications/agreement
- The table was originally defined as the "HCDP" for "Headless
- Console/Debug Port." The current version is the "PCDP" for
- "Primary Console and Debug Port Devices."
-
-[2]
- The HP MP (management processor) is a PCI device that provides
- several UARTs. One of the UARTs is often used as a console; the
- EFI Boot Manager identifies it as "Acpi(HWP0002,700)/Pci(...)/Uart".
- The external connection is usually a 25-pin connector, and a
- special dongle converts that to three 9-pin connectors, one of
- which is labelled "Console."
-
-[3]
- EFI console devices are configured using the EFI Boot Manager
- "Boot option maintenance" menu. You may have to interrupt the
- boot sequence to use this menu, and you will have to reset the
- box after changing console configuration.
diff --git a/Documentation/arch/index.rst b/Documentation/arch/index.rst
index 84b80255b851..3f9962e45c09 100644
--- a/Documentation/arch/index.rst
+++ b/Documentation/arch/index.rst
@@ -12,15 +12,14 @@ implementation.
arc/index
arm/index
arm64/index
- ia64/index
loongarch/index
m68k/index
mips/index
nios2/index
openrisc/index
parisc/index
- ../powerpc/index
- ../riscv/index
+ powerpc/index
+ riscv/index
s390/index
sh/index
sparc/index
diff --git a/Documentation/powerpc/associativity.rst b/Documentation/arch/powerpc/associativity.rst
index 4d01c7368561..4d01c7368561 100644
--- a/Documentation/powerpc/associativity.rst
+++ b/Documentation/arch/powerpc/associativity.rst
diff --git a/Documentation/powerpc/booting.rst b/Documentation/arch/powerpc/booting.rst
index 11aa440f98cc..11aa440f98cc 100644
--- a/Documentation/powerpc/booting.rst
+++ b/Documentation/arch/powerpc/booting.rst
diff --git a/Documentation/powerpc/bootwrapper.rst b/Documentation/arch/powerpc/bootwrapper.rst
index cdfa2bc8425f..cdfa2bc8425f 100644
--- a/Documentation/powerpc/bootwrapper.rst
+++ b/Documentation/arch/powerpc/bootwrapper.rst
diff --git a/Documentation/powerpc/cpu_families.rst b/Documentation/arch/powerpc/cpu_families.rst
index eb7e60649b43..eb7e60649b43 100644
--- a/Documentation/powerpc/cpu_families.rst
+++ b/Documentation/arch/powerpc/cpu_families.rst
diff --git a/Documentation/powerpc/cpu_features.rst b/Documentation/arch/powerpc/cpu_features.rst
index b7bcdd2f41bb..b7bcdd2f41bb 100644
--- a/Documentation/powerpc/cpu_features.rst
+++ b/Documentation/arch/powerpc/cpu_features.rst
diff --git a/Documentation/powerpc/cxl.rst b/Documentation/arch/powerpc/cxl.rst
index d2d77057610e..d2d77057610e 100644
--- a/Documentation/powerpc/cxl.rst
+++ b/Documentation/arch/powerpc/cxl.rst
diff --git a/Documentation/powerpc/cxlflash.rst b/Documentation/arch/powerpc/cxlflash.rst
index cea67931b3b9..e8f488acfa41 100644
--- a/Documentation/powerpc/cxlflash.rst
+++ b/Documentation/arch/powerpc/cxlflash.rst
@@ -32,7 +32,7 @@ Introduction
responsible for the initialization of the adapter, setting up the
special path for user space access, and performing error recovery. It
communicates directly the Flash Accelerator Functional Unit (AFU)
- as described in Documentation/powerpc/cxl.rst.
+ as described in Documentation/arch/powerpc/cxl.rst.
The cxlflash driver supports two, mutually exclusive, modes of
operation at the device (LUN) level:
diff --git a/Documentation/powerpc/dawr-power9.rst b/Documentation/arch/powerpc/dawr-power9.rst
index 310f2e0cea81..310f2e0cea81 100644
--- a/Documentation/powerpc/dawr-power9.rst
+++ b/Documentation/arch/powerpc/dawr-power9.rst
diff --git a/Documentation/powerpc/dexcr.rst b/Documentation/arch/powerpc/dexcr.rst
index 615a631f51fa..615a631f51fa 100644
--- a/Documentation/powerpc/dexcr.rst
+++ b/Documentation/arch/powerpc/dexcr.rst
diff --git a/Documentation/powerpc/dscr.rst b/Documentation/arch/powerpc/dscr.rst
index f735ec5375d5..f735ec5375d5 100644
--- a/Documentation/powerpc/dscr.rst
+++ b/Documentation/arch/powerpc/dscr.rst
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.rst b/Documentation/arch/powerpc/eeh-pci-error-recovery.rst
index d6643a91bdf8..d6643a91bdf8 100644
--- a/Documentation/powerpc/eeh-pci-error-recovery.rst
+++ b/Documentation/arch/powerpc/eeh-pci-error-recovery.rst
diff --git a/Documentation/powerpc/elf_hwcaps.rst b/Documentation/arch/powerpc/elf_hwcaps.rst
index 3366e5b18e67..4c896cf077c2 100644
--- a/Documentation/powerpc/elf_hwcaps.rst
+++ b/Documentation/arch/powerpc/elf_hwcaps.rst
@@ -202,7 +202,7 @@ PPC_FEATURE2_VEC_CRYPTO
PPC_FEATURE2_HTM_NOSC
System calls fail if called in a transactional state, see
- Documentation/powerpc/syscall64-abi.rst
+ Documentation/arch/powerpc/syscall64-abi.rst
PPC_FEATURE2_ARCH_3_00
The processor supports the v3.0B / v3.0C userlevel architecture. Processors
@@ -217,11 +217,11 @@ PPC_FEATURE2_DARN
PPC_FEATURE2_SCV
The scv 0 instruction may be used for system calls, see
- Documentation/powerpc/syscall64-abi.rst.
+ Documentation/arch/powerpc/syscall64-abi.rst.
PPC_FEATURE2_HTM_NO_SUSPEND
A limited Transactional Memory facility that does not support suspend is
- available, see Documentation/powerpc/transactional_memory.rst.
+ available, see Documentation/arch/powerpc/transactional_memory.rst.
PPC_FEATURE2_ARCH_3_1
The processor supports the v3.1 userlevel architecture. Processors
diff --git a/Documentation/powerpc/elfnote.rst b/Documentation/arch/powerpc/elfnote.rst
index 3ec8d61e9a33..3ec8d61e9a33 100644
--- a/Documentation/powerpc/elfnote.rst
+++ b/Documentation/arch/powerpc/elfnote.rst
diff --git a/Documentation/powerpc/features.rst b/Documentation/arch/powerpc/features.rst
index aeae73df86b0..aeae73df86b0 100644
--- a/Documentation/powerpc/features.rst
+++ b/Documentation/arch/powerpc/features.rst
diff --git a/Documentation/powerpc/firmware-assisted-dump.rst b/Documentation/arch/powerpc/firmware-assisted-dump.rst
index e363fc48529a..e363fc48529a 100644
--- a/Documentation/powerpc/firmware-assisted-dump.rst
+++ b/Documentation/arch/powerpc/firmware-assisted-dump.rst
diff --git a/Documentation/powerpc/hvcs.rst b/Documentation/arch/powerpc/hvcs.rst
index 6808acde672f..6808acde672f 100644
--- a/Documentation/powerpc/hvcs.rst
+++ b/Documentation/arch/powerpc/hvcs.rst
diff --git a/Documentation/powerpc/imc.rst b/Documentation/arch/powerpc/imc.rst
index 633bcee7dc85..633bcee7dc85 100644
--- a/Documentation/powerpc/imc.rst
+++ b/Documentation/arch/powerpc/imc.rst
diff --git a/Documentation/powerpc/index.rst b/Documentation/arch/powerpc/index.rst
index a50834798454..a50834798454 100644
--- a/Documentation/powerpc/index.rst
+++ b/Documentation/arch/powerpc/index.rst
diff --git a/Documentation/powerpc/isa-versions.rst b/Documentation/arch/powerpc/isa-versions.rst
index a8d6b6028b3e..a8d6b6028b3e 100644
--- a/Documentation/powerpc/isa-versions.rst
+++ b/Documentation/arch/powerpc/isa-versions.rst
diff --git a/Documentation/powerpc/kasan.txt b/Documentation/arch/powerpc/kasan.txt
index a4f647e4fffa..a4f647e4fffa 100644
--- a/Documentation/powerpc/kasan.txt
+++ b/Documentation/arch/powerpc/kasan.txt
diff --git a/Documentation/powerpc/kaslr-booke32.rst b/Documentation/arch/powerpc/kaslr-booke32.rst
index 5681c1d1b65b..5681c1d1b65b 100644
--- a/Documentation/powerpc/kaslr-booke32.rst
+++ b/Documentation/arch/powerpc/kaslr-booke32.rst
diff --git a/Documentation/powerpc/mpc52xx.rst b/Documentation/arch/powerpc/mpc52xx.rst
index 5243b1763fad..5243b1763fad 100644
--- a/Documentation/powerpc/mpc52xx.rst
+++ b/Documentation/arch/powerpc/mpc52xx.rst
diff --git a/Documentation/powerpc/papr_hcalls.rst b/Documentation/arch/powerpc/papr_hcalls.rst
index 80d2c0aadab5..80d2c0aadab5 100644
--- a/Documentation/powerpc/papr_hcalls.rst
+++ b/Documentation/arch/powerpc/papr_hcalls.rst
diff --git a/Documentation/powerpc/pci_iov_resource_on_powernv.rst b/Documentation/arch/powerpc/pci_iov_resource_on_powernv.rst
index f5a5793e1613..f5a5793e1613 100644
--- a/Documentation/powerpc/pci_iov_resource_on_powernv.rst
+++ b/Documentation/arch/powerpc/pci_iov_resource_on_powernv.rst
diff --git a/Documentation/powerpc/pmu-ebb.rst b/Documentation/arch/powerpc/pmu-ebb.rst
index 4f474758eb55..4f474758eb55 100644
--- a/Documentation/powerpc/pmu-ebb.rst
+++ b/Documentation/arch/powerpc/pmu-ebb.rst
diff --git a/Documentation/powerpc/ptrace.rst b/Documentation/arch/powerpc/ptrace.rst
index 5629edf4d56e..5629edf4d56e 100644
--- a/Documentation/powerpc/ptrace.rst
+++ b/Documentation/arch/powerpc/ptrace.rst
diff --git a/Documentation/powerpc/qe_firmware.rst b/Documentation/arch/powerpc/qe_firmware.rst
index a358f152b7e7..a358f152b7e7 100644
--- a/Documentation/powerpc/qe_firmware.rst
+++ b/Documentation/arch/powerpc/qe_firmware.rst
diff --git a/Documentation/powerpc/syscall64-abi.rst b/Documentation/arch/powerpc/syscall64-abi.rst
index 56490c4c0c07..56490c4c0c07 100644
--- a/Documentation/powerpc/syscall64-abi.rst
+++ b/Documentation/arch/powerpc/syscall64-abi.rst
diff --git a/Documentation/powerpc/transactional_memory.rst b/Documentation/arch/powerpc/transactional_memory.rst
index 040a20675fd1..040a20675fd1 100644
--- a/Documentation/powerpc/transactional_memory.rst
+++ b/Documentation/arch/powerpc/transactional_memory.rst
diff --git a/Documentation/powerpc/ultravisor.rst b/Documentation/arch/powerpc/ultravisor.rst
index ba6b1bf1cc44..ba6b1bf1cc44 100644
--- a/Documentation/powerpc/ultravisor.rst
+++ b/Documentation/arch/powerpc/ultravisor.rst
diff --git a/Documentation/powerpc/vas-api.rst b/Documentation/arch/powerpc/vas-api.rst
index a9625a2fa0c6..a9625a2fa0c6 100644
--- a/Documentation/powerpc/vas-api.rst
+++ b/Documentation/arch/powerpc/vas-api.rst
diff --git a/Documentation/powerpc/vcpudispatch_stats.rst b/Documentation/arch/powerpc/vcpudispatch_stats.rst
index 5704657a5987..5704657a5987 100644
--- a/Documentation/powerpc/vcpudispatch_stats.rst
+++ b/Documentation/arch/powerpc/vcpudispatch_stats.rst
diff --git a/Documentation/powerpc/vmemmap_dedup.rst b/Documentation/arch/powerpc/vmemmap_dedup.rst
index dc4db59fdf87..dc4db59fdf87 100644
--- a/Documentation/powerpc/vmemmap_dedup.rst
+++ b/Documentation/arch/powerpc/vmemmap_dedup.rst
diff --git a/Documentation/riscv/acpi.rst b/Documentation/arch/riscv/acpi.rst
index 9870a282815b..9870a282815b 100644
--- a/Documentation/riscv/acpi.rst
+++ b/Documentation/arch/riscv/acpi.rst
diff --git a/Documentation/riscv/boot-image-header.rst b/Documentation/arch/riscv/boot-image-header.rst
index df2ffc173e80..df2ffc173e80 100644
--- a/Documentation/riscv/boot-image-header.rst
+++ b/Documentation/arch/riscv/boot-image-header.rst
diff --git a/Documentation/riscv/boot.rst b/Documentation/arch/riscv/boot.rst
index 6077b587a842..6077b587a842 100644
--- a/Documentation/riscv/boot.rst
+++ b/Documentation/arch/riscv/boot.rst
diff --git a/Documentation/riscv/features.rst b/Documentation/arch/riscv/features.rst
index c70ef6ac2368..c70ef6ac2368 100644
--- a/Documentation/riscv/features.rst
+++ b/Documentation/arch/riscv/features.rst
diff --git a/Documentation/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
index a52996b22f75..a52996b22f75 100644
--- a/Documentation/riscv/hwprobe.rst
+++ b/Documentation/arch/riscv/hwprobe.rst
diff --git a/Documentation/riscv/index.rst b/Documentation/arch/riscv/index.rst
index 4dab0cb4b900..4dab0cb4b900 100644
--- a/Documentation/riscv/index.rst
+++ b/Documentation/arch/riscv/index.rst
diff --git a/Documentation/riscv/patch-acceptance.rst b/Documentation/arch/riscv/patch-acceptance.rst
index 634aa222b410..634aa222b410 100644
--- a/Documentation/riscv/patch-acceptance.rst
+++ b/Documentation/arch/riscv/patch-acceptance.rst
diff --git a/Documentation/riscv/uabi.rst b/Documentation/arch/riscv/uabi.rst
index 8960fac42c40..8960fac42c40 100644
--- a/Documentation/riscv/uabi.rst
+++ b/Documentation/arch/riscv/uabi.rst
diff --git a/Documentation/riscv/vector.rst b/Documentation/arch/riscv/vector.rst
index 75dd88a62e1d..75dd88a62e1d 100644
--- a/Documentation/riscv/vector.rst
+++ b/Documentation/arch/riscv/vector.rst
diff --git a/Documentation/riscv/vm-layout.rst b/Documentation/arch/riscv/vm-layout.rst
index 69ff6da1dbf8..69ff6da1dbf8 100644
--- a/Documentation/riscv/vm-layout.rst
+++ b/Documentation/arch/riscv/vm-layout.rst
diff --git a/Documentation/block/blk-mq.rst b/Documentation/block/blk-mq.rst
index 31f52f326971..fc06761b6ea9 100644
--- a/Documentation/block/blk-mq.rst
+++ b/Documentation/block/blk-mq.rst
@@ -56,7 +56,7 @@ sent to the software queue.
Then, after the requests are processed by software queues, they will be placed
at the hardware queue, a second stage queue where the hardware has direct access
to process those requests. However, if the hardware does not have enough
-resources to accept more requests, blk-mq will places requests on a temporary
+resources to accept more requests, blk-mq will place requests on a temporary
queue, to be sent in the future, when the hardware is able.
Software staging queues
diff --git a/Documentation/block/ioprio.rst b/Documentation/block/ioprio.rst
index f72b0de65af7..a25c6d5df87b 100644
--- a/Documentation/block/ioprio.rst
+++ b/Documentation/block/ioprio.rst
@@ -80,9 +80,6 @@ ionice.c tool::
#elif defined(__x86_64__)
#define __NR_ioprio_set 251
#define __NR_ioprio_get 252
- #elif defined(__ia64__)
- #define __NR_ioprio_set 1274
- #define __NR_ioprio_get 1275
#else
#error "Unsupported arch"
#endif
diff --git a/Documentation/core-api/cpu_hotplug.rst b/Documentation/core-api/cpu_hotplug.rst
index 9511e405aabd..dcb0e379e5e8 100644
--- a/Documentation/core-api/cpu_hotplug.rst
+++ b/Documentation/core-api/cpu_hotplug.rst
@@ -40,12 +40,6 @@ Command Line Switches
supplied here is lower than the number of physically available CPUs, then
those CPUs can not be brought online later.
-``additional_cpus=n``
- Use this to limit hotpluggable CPUs. This option sets
- ``cpu_possible_mask = cpu_present_mask + additional_cpus``
-
- This option is limited to the IA64 architecture.
-
``possible_cpus=n``
This option sets ``possible_cpus`` bits in ``cpu_possible_mask``.
diff --git a/Documentation/core-api/debugging-via-ohci1394.rst b/Documentation/core-api/debugging-via-ohci1394.rst
index 981ad4f89fd3..cb3d3228dfc8 100644
--- a/Documentation/core-api/debugging-via-ohci1394.rst
+++ b/Documentation/core-api/debugging-via-ohci1394.rst
@@ -23,9 +23,9 @@ Retrieving a full system memory dump is also possible over the FireWire,
using data transfer rates in the order of 10MB/s or more.
With most FireWire controllers, memory access is limited to the low 4 GB
-of physical address space. This can be a problem on IA64 machines where
-memory is located mostly above that limit, but it is rarely a problem on
-more common hardware such as x86, x86-64 and PowerPC.
+of physical address space. This can be a problem on machines where memory is
+located mostly above that limit, but it is rarely a problem on more common
+hardware such as x86, x86-64 and PowerPC.
At least LSI FW643e and FW643e2 controllers are known to support access to
physical addresses above 4 GB, but this feature is currently not enabled by
diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst
index deede972f254..ab376b316c36 100644
--- a/Documentation/dev-tools/kselftest.rst
+++ b/Documentation/dev-tools/kselftest.rst
@@ -112,7 +112,7 @@ You can specify multiple tests to skip::
You can also specify a restricted list of tests to run together with a
dedicated skiplist::
- $ make TARGETS="bpf breakpoints size timers" SKIP_TARGETS=bpf kselftest
+ $ make TARGETS="breakpoints size timers" SKIP_TARGETS=size kselftest
See the top-level tools/testing/selftests/Makefile for the list of all
possible targets.
@@ -165,7 +165,7 @@ To see the list of available tests, the `-l` option can be used::
The `-c` option can be used to run all the tests from a test collection, or
the `-t` option for specific single tests. Either can be used multiple times::
- $ ./run_kselftest.sh -c bpf -c seccomp -t timers:posix_timers -t timer:nanosleep
+ $ ./run_kselftest.sh -c size -c seccomp -t timers:posix_timers -t timer:nanosleep
For other features see the script usage output, seen with the `-h` option.
@@ -210,7 +210,7 @@ option is supported, such as::
tests by using variables specified in `Running a subset of selftests`_
section::
- $ make -C tools/testing/selftests gen_tar TARGETS="bpf" FORMAT=.xz
+ $ make -C tools/testing/selftests gen_tar TARGETS="size" FORMAT=.xz
.. _tar's auto-compress: https://www.gnu.org/software/tar/manual/html_node/gzip.html#auto_002dcompress
diff --git a/Documentation/devicetree/bindings/arm/amd,pensando.yaml b/Documentation/devicetree/bindings/arm/amd,pensando.yaml
new file mode 100644
index 000000000000..e5c2591834a8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/amd,pensando.yaml
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/amd,pensando.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: AMD Pensando SoC Platforms
+
+maintainers:
+ - Brad Larson <blarson@amd.com>
+
+properties:
+ $nodename:
+ const: "/"
+ compatible:
+ oneOf:
+
+ - description: Boards with Pensando Elba SoC
+ items:
+ - enum:
+ - amd,pensando-elba-ortano
+ - const: amd,pensando-elba
+
+additionalProperties: true
+
+...
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 1c1094cd6b77..caab7ceeda45 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -155,6 +155,7 @@ properties:
- enum:
- bananapi,bpi-m2s
- khadas,vim3
+ - libretech,aml-a311d-cc
- radxa,zero2
- const: amlogic,a311d
- const: amlogic,g12b
@@ -196,6 +197,7 @@ properties:
- hardkernel,odroid-hc4
- haochuangyi,h96-max
- khadas,vim3l
+ - libretech,aml-s905d3-cc
- seirobotics,sei610
- const: amlogic,sm1
@@ -203,6 +205,7 @@ properties:
items:
- enum:
- amlogic,ad401
+ - amlogic,ad402
- const: amlogic,a1
- description: Boards with the Amlogic C3 C302X/C308L SoC
diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 68f717670f78..749ee54a3ff8 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -79,6 +79,7 @@ properties:
- facebook,elbert-bmc
- facebook,fuji-bmc
- facebook,greatlakes-bmc
+ - facebook,minerva-cmc
- facebook,yosemite4-bmc
- ibm,everest-bmc
- ibm,rainier-bmc
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index dfb8fd089197..89d75fbb1de4 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -79,6 +79,13 @@ properties:
- const: atmel,sama5d2
- const: atmel,sama5
+ - description: Microchip SAMA5D29 Curiosity
+ items:
+ - const: microchip,sama5d29-curiosity
+ - const: atmel,sama5d29
+ - const: atmel,sama5d2
+ - const: atmel,sama5
+
- items:
- const: atmel,sama5d27
- const: atmel,sama5d2
diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml
index c6930fc7f690..ffd526363fda 100644
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -309,7 +309,9 @@ properties:
power-domains property.
For PSCI based platforms, the name corresponding to the index of the PSCI
- PM domain provider, must be "psci".
+ PM domain provider, must be "psci". For SCMI based platforms, the name
+ corresponding to the index of an SCMI performance domain provider, must be
+ "perf".
qcom,saw:
$ref: /schemas/types.yaml#/definitions/phandle
diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 9450b2c8a678..32b195852a75 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -25,8 +25,11 @@ properties:
- description: i.MX23 based Boards
items:
- enum:
+ - creative,x-fi3
- fsl,imx23-evk
+ - fsl,stmp378x-devb
- olimex,imx23-olinuxino
+ - sandisk,sansa_fuze_plus
- const: fsl,imx23
- description: i.MX25 Product Development Kit
@@ -385,6 +388,12 @@ properties:
- const: toradex,apalis_imx6q
- const: fsl,imx6q
+ - description: i.MX6Q Variscite VAR-SOM-MX6 Boards
+ items:
+ - const: variscite,mx6customboard
+ - const: variscite,var-som-imx6q
+ - const: fsl,imx6q
+
- description: TQ-Systems TQMa6Q SoM (variant A) on MBa6x
items:
- const: tq,imx6q-mba6x-a
@@ -975,7 +984,9 @@ properties:
- description: PHYTEC phyCORE-i.MX8MM SoM based boards
items:
- - const: phytec,imx8mm-phyboard-polis-rdk # phyBOARD-Polis RDK
+ - enum:
+ - phytec,imx8mm-phyboard-polis-rdk # phyBOARD-Polis RDK
+ - phytec,imx8mm-phygate-tauri-l # phyGATE-Tauri-L Gateway
- const: phytec,imx8mm-phycore-som # phyCORE-i.MX8MM SoM
- const: fsl,imx8mm
@@ -1389,6 +1400,13 @@ properties:
- fsl,ls1043a-qds
- const: fsl,ls1043a
+ - description: TQ-Systems LS1043A based Boards
+ items:
+ - enum:
+ - tq,ls1043a-tqmls1043a-mbls10xxa
+ - const: tq,ls1043a-tqmls1043a
+ - const: fsl,ls1043a
+
- description: LS1046A based Boards
items:
- enum:
@@ -1397,6 +1415,13 @@ properties:
- fsl,ls1046a-rdb
- const: fsl,ls1046a
+ - description: TQ-Systems LS1046A based Boards
+ items:
+ - enum:
+ - tq,ls1046a-tqmls1046a-mbls10xxa
+ - const: tq,ls1046a-tqmls1046a
+ - const: fsl,ls1046a
+
- description: LS1088A based Boards
items:
- enum:
@@ -1404,6 +1429,13 @@ properties:
- fsl,ls1088a-rdb
- const: fsl,ls1088a
+ - description: TQ-Systems LS1088A based Boards
+ items:
+ - enum:
+ - tq,ls1088a-tqmls1088a-mbls10xxa
+ - const: tq,ls1088a-tqmls1088a
+ - const: fsl,ls1088a
+
- description: LS2080A based Boards
items:
- enum:
@@ -1429,7 +1461,7 @@ properties:
- fsl,lx2162a-qds
- const: fsl,lx2160a
- - description: SolidRun LX2160A based Boards
+ - description: SolidRun LX2160A CEX-7 based Boards
items:
- enum:
- solidrun,clearfog-cx
@@ -1437,6 +1469,13 @@ properties:
- const: solidrun,lx2160a-cex7
- const: fsl,lx2160a
+ - description: SolidRun LX2162A SoM based Boards
+ items:
+ - enum:
+ - solidrun,lx2162a-clearfog
+ - const: solidrun,lx2162a-som
+ - const: fsl,lx2160a
+
- description: S32G2 based Boards
items:
- enum:
diff --git a/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml b/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
index 553dcbc70e35..d60792b1d995 100644
--- a/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
+++ b/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
@@ -16,12 +16,28 @@ properties:
oneOf:
- items:
- enum:
+ - adieng,coyote
+ - arcom,vulcan
+ - dlink,dsm-g600-a
+ - freecom,fsg-3
+ - gateway,7001
+ - gateworks,gw2348
+ - goramo,multilink-router
+ - intel,ixdp425
+ - intel,ixdpg425
+ - iom,nas-100d
- linksys,nslu2
+ - netgear,wg302v1
+ - netgear,wg302v2
+ - usr,8200
- welltech,epbx100
+ - linksys,wrv54g
+ - gemtek,gtwx5715
- const: intel,ixp42x
- items:
- enum:
- gateworks,gw2358
+ - intel,kixrp435
- const: intel,ixp43x
additionalProperties: true
diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index ae12b1cab9fb..a5999b3afc35 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -133,11 +133,22 @@ properties:
- enum:
- mediatek,mt8183-evb
- const: mediatek,mt8183
+ - description: Google Hayato rev5
+ items:
+ - const: google,hayato-rev5-sku2
+ - const: google,hayato-sku2
+ - const: google,hayato
+ - const: mediatek,mt8192
- description: Google Hayato
items:
- const: google,hayato-rev1
- const: google,hayato
- const: mediatek,mt8192
+ - description: Google Spherion rev4 (Acer Chromebook 514)
+ items:
+ - const: google,spherion-rev4
+ - const: google,spherion
+ - const: mediatek,mt8192
- description: Google Spherion (Acer Chromebook 514)
items:
- const: google,spherion-rev3
@@ -250,6 +261,11 @@ properties:
- const: mediatek,mt8365
- items:
- enum:
+ - mediatek,mt8395-evk
+ - const: mediatek,mt8395
+ - const: mediatek,mt8195
+ - items:
+ - enum:
- mediatek,mt8516-pumpkin
- const: mediatek,mt8516
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index adbfaea32343..7f80f48a0954 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -50,6 +50,7 @@ description: |
msm8998
qcs404
qcm2290
+ qcm6490
qdu1000
qrb2210
qrb4210
@@ -79,6 +80,7 @@ description: |
sm6125
sm6350
sm6375
+ sm7125
sm7225
sm8150
sm8250
@@ -189,6 +191,7 @@ properties:
- items:
- enum:
+ - longcheer,l9100
- samsung,a7
- sony,kanuti-tulip
- square,apq8039-t2
@@ -391,6 +394,11 @@ properties:
- const: qcom,qrb2210
- const: qcom,qcm2290
+ - items:
+ - enum:
+ - fairphone,fp5
+ - const: qcom,qcm6490
+
- description: Qualcomm Technologies, Inc. Distributed Unit 1000 platform
items:
- enum:
@@ -479,6 +487,11 @@ properties:
- const: google,lazor-rev8
- const: qcom,sc7180
+ - description: Acer Chromebook Spin 513 (rev9)
+ items:
+ - const: google,lazor-rev9
+ - const: qcom,sc7180
+
- description: Acer Chromebook Spin 513 (newest rev)
items:
- const: google,lazor
@@ -500,6 +513,11 @@ properties:
- const: google,lazor-rev8-sku2
- const: qcom,sc7180
+ - description: Acer Chromebook Spin 513 with KB Backlight (rev9)
+ items:
+ - const: google,lazor-rev9-sku2
+ - const: qcom,sc7180
+
- description: Acer Chromebook Spin 513 with KB Backlight (newest rev)
items:
- const: google,lazor-sku2
@@ -521,9 +539,16 @@ properties:
- const: google,lazor-rev8-sku0
- const: qcom,sc7180
+ - description: Acer Chromebook Spin 513 with LTE (rev9)
+ items:
+ - const: google,lazor-rev9-sku0
+ - const: google,lazor-rev9-sku10
+ - const: qcom,sc7180
+
- description: Acer Chromebook Spin 513 with LTE (newest rev)
items:
- const: google,lazor-sku0
+ - const: google,lazor-sku10
- const: qcom,sc7180
- description: Acer Chromebook 511 (rev4 - rev8)
@@ -535,9 +560,16 @@ properties:
- const: google,lazor-rev8-sku4
- const: qcom,sc7180
+ - description: Acer Chromebook 511 (rev9)
+ items:
+ - const: google,lazor-rev9-sku4
+ - const: google,lazor-rev9-sku15
+ - const: qcom,sc7180
+
- description: Acer Chromebook 511 (newest rev)
items:
- const: google,lazor-sku4
+ - const: google,lazor-sku15
- const: qcom,sc7180
- description: Acer Chromebook 511 without Touchscreen (rev4)
@@ -554,9 +586,16 @@ properties:
- const: google,lazor-rev8-sku6
- const: qcom,sc7180
+ - description: Acer Chromebook 511 without Touchscreen (rev9)
+ items:
+ - const: google,lazor-rev9-sku6
+ - const: google,lazor-rev9-sku18
+ - const: qcom,sc7180
+
- description: Acer Chromebook 511 without Touchscreen (newest rev)
items:
- const: google,lazor-sku6
+ - const: google,lazor-sku18
- const: qcom,sc7180
- description: Google Mrbland with AUO panel (rev0)
@@ -945,6 +984,11 @@ properties:
- items:
- enum:
+ - xiaomi,joyeuse
+ - const: qcom,sm7125
+
+ - items:
+ - enum:
- fairphone,fp4
- const: qcom,sm7225
@@ -1086,6 +1130,7 @@ allOf:
- qcom,sm6115
- qcom,sm6125
- qcom,sm6350
+ - qcom,sm7125
- qcom,sm7225
- qcom,sm8150
- qcom,sm8250
diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index ca5389862887..5f7c6c4aad8f 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -660,6 +660,11 @@ properties:
- pine64,quartz64-b
- const: rockchip,rk3566
+ - description: Pine64 QuartzPro64
+ items:
+ - const: pine64,quartzpro64
+ - const: rockchip,rk3588
+
- description: Pine64 SoQuartz SoM
items:
- enum:
@@ -669,6 +674,11 @@ properties:
- const: pine64,soquartz
- const: rockchip,rk3566
+ - description: Powkiddy RGB30
+ items:
+ - const: powkiddy,rgb30
+ - const: rockchip,rk3566
+
- description: Radxa Compute Module 3(CM3)
items:
- enum:
@@ -870,6 +880,16 @@ properties:
- const: tronsmart,orion-r68-meta
- const: rockchip,rk3368
+ - description: Turing RK1
+ items:
+ - const: turing,rk1
+ - const: rockchip,rk3588
+
+ - description: Xunlong Orange Pi 5 Plus
+ items:
+ - const: xunlong,orangepi-5-plus
+ - const: rockchip,rk3588
+
- description: Xunlong Orange Pi R1 Plus / LTS
items:
- enum:
@@ -877,6 +897,11 @@ properties:
- xunlong,orangepi-r1-plus-lts
- const: rockchip,rk3328
+ - description: Xunlong Orange Pi 5
+ items:
+ - const: xunlong,orangepi-5
+ - const: rockchip,rk3588s
+
- description: Zkmagic A95X Z2
items:
- const: zkmagic,a95x-z2
diff --git a/Documentation/devicetree/bindings/arm/sti.yaml b/Documentation/devicetree/bindings/arm/sti.yaml
index 3ca054c64377..842def3e3f2b 100644
--- a/Documentation/devicetree/bindings/arm/sti.yaml
+++ b/Documentation/devicetree/bindings/arm/sti.yaml
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/sti.yaml#
@@ -13,13 +13,20 @@ properties:
$nodename:
const: '/'
compatible:
- items:
- - enum:
- - st,stih415
- - st,stih416
- - st,stih407
- - st,stih410
- - st,stih418
+ oneOf:
+ - items:
+ - const: st,stih407-b2120
+ - const: st,stih407
+ - items:
+ - enum:
+ - st,stih410-b2120
+ - st,stih410-b2260
+ - const: st,stih410
+ - items:
+ - enum:
+ - st,stih418-b2199
+ - st,stih418-b2264
+ - const: st,stih418
additionalProperties: true
diff --git a/Documentation/devicetree/bindings/arm/stm32/stm32.yaml b/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
index 4bf28e717a56..df087c81c69e 100644
--- a/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
+++ b/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
@@ -146,6 +146,7 @@ properties:
- lxa,stm32mp157c-mc1 # Linux Automation MC-1
- lxa,stm32mp157c-tac-gen1 # Linux Automation TAC (Generation 1)
- lxa,stm32mp157c-tac-gen2 # Linux Automation TAC (Generation 2)
+ - oct,stm32mp157c-osd32-red # Octavo OSD32MP1 RED board
- const: oct,stm32mp15xx-osd32
- enum:
- st,stm32mp157
diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index e4dd678f4212..11c5ce941dd7 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -51,6 +51,11 @@ properties:
- const: allwinner,parrot
- const: allwinner,sun8i-a33
+ - description: Anbernic RG-Nano
+ items:
+ - const: anbernic,rg-nano
+ - const: allwinner,sun8i-v3s
+
- description: Amarula A64 Relic
items:
- const: amarula,a64-relic
@@ -151,6 +156,17 @@ properties:
- const: roofull,beelink-x2
- const: allwinner,sun8i-h3
+ - description: BigTreeTech Manta M4/8P
+ items:
+ - const: bigtreetech,cb1-manta
+ - const: bigtreetech,cb1
+ - const: allwinner,sun50i-h616
+
+ - description: BigTreeTech Pi
+ items:
+ - const: bigtreetech,pi
+ - const: allwinner,sun50i-h616
+
- description: Chuwi V7 CW0825
items:
- const: chuwi,v7-cw0825
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml
deleted file mode 100644
index 89191cfdf619..000000000000
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml
+++ /dev/null
@@ -1,393 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/arm/tegra/nvidia,tegra20-pmc.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Tegra Power Management Controller (PMC)
-
-maintainers:
- - Thierry Reding <thierry.reding@gmail.com>
- - Jonathan Hunter <jonathanh@nvidia.com>
-
-properties:
- compatible:
- enum:
- - nvidia,tegra20-pmc
- - nvidia,tegra30-pmc
- - nvidia,tegra114-pmc
- - nvidia,tegra124-pmc
- - nvidia,tegra210-pmc
-
- reg:
- maxItems: 1
- description:
- Offset and length of the register set for the device.
-
- clock-names:
- items:
- - const: pclk
- - const: clk32k_in
- description:
- Must includes entries pclk and clk32k_in.
- pclk is the Tegra clock of that name and clk32k_in is 32KHz clock
- input to Tegra.
-
- clocks:
- maxItems: 2
- description:
- Must contain an entry for each entry in clock-names.
- See ../clocks/clocks-bindings.txt for details.
-
- '#clock-cells':
- const: 1
- description:
- Tegra PMC has clk_out_1, clk_out_2, and clk_out_3.
- PMC also has blink control which allows 32Khz clock output to
- Tegra blink pad.
- Consumer of PMC clock should specify the desired clock by having
- the clock ID in its "clocks" phandle cell with pmc clock provider.
- See include/dt-bindings/soc/tegra-pmc.h for the list of Tegra PMC
- clock IDs.
-
- '#interrupt-cells':
- const: 2
- description:
- Specifies number of cells needed to encode an interrupt source.
- The value must be 2.
-
- interrupt-controller: true
-
- nvidia,invert-interrupt:
- $ref: /schemas/types.yaml#/definitions/flag
- description: Inverts the PMU interrupt signal.
- The PMU is an external Power Management Unit, whose interrupt output
- signal is fed into the PMC. This signal is optionally inverted, and
- then fed into the ARM GIC. The PMC is not involved in the detection
- or handling of this interrupt signal, merely its inversion.
-
- nvidia,core-power-req-active-high:
- $ref: /schemas/types.yaml#/definitions/flag
- description: Core power request active-high.
-
- nvidia,sys-clock-req-active-high:
- $ref: /schemas/types.yaml#/definitions/flag
- description: System clock request active-high.
-
- nvidia,combined-power-req:
- $ref: /schemas/types.yaml#/definitions/flag
- description: combined power request for CPU and Core.
-
- nvidia,cpu-pwr-good-en:
- $ref: /schemas/types.yaml#/definitions/flag
- description:
- CPU power good signal from external PMIC to PMC is enabled.
-
- nvidia,suspend-mode:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [0, 1, 2]
- description:
- The suspend mode that the platform should use.
- Mode 0 is for LP0, CPU + Core voltage off and DRAM in self-refresh
- Mode 1 is for LP1, CPU voltage off and DRAM in self-refresh
- Mode 2 is for LP2, CPU voltage off
-
- nvidia,cpu-pwr-good-time:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: CPU power good time in uSec.
-
- nvidia,cpu-pwr-off-time:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: CPU power off time in uSec.
-
- nvidia,core-pwr-good-time:
- $ref: /schemas/types.yaml#/definitions/uint32-array
- description:
- <Oscillator-stable-time Power-stable-time>
- Core power good time in uSec.
-
- nvidia,core-pwr-off-time:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: Core power off time in uSec.
-
- nvidia,lp0-vec:
- $ref: /schemas/types.yaml#/definitions/uint32-array
- description:
- <start length> Starting address and length of LP0 vector.
- The LP0 vector contains the warm boot code that is executed
- by AVP when resuming from the LP0 state.
- The AVP (Audio-Video Processor) is an ARM7 processor and
- always being the first boot processor when chip is power on
- or resume from deep sleep mode. When the system is resumed
- from the deep sleep mode, the warm boot code will restore
- some PLLs, clocks and then brings up CPU0 for resuming the
- system.
-
- core-supply:
- description:
- Phandle to voltage regulator connected to the SoC Core power rail.
-
- core-domain:
- type: object
- description: |
- The vast majority of hardware blocks of Tegra SoC belong to a
- Core power domain, which has a dedicated voltage rail that powers
- the blocks.
-
- properties:
- operating-points-v2:
- description:
- Should contain level, voltages and opp-supported-hw property.
- The supported-hw is a bitfield indicating SoC speedo or process
- ID mask.
-
- "#power-domain-cells":
- const: 0
-
- required:
- - operating-points-v2
- - "#power-domain-cells"
-
- additionalProperties: false
-
- i2c-thermtrip:
- type: object
- description:
- On Tegra30, Tegra114 and Tegra124 if i2c-thermtrip subnode exists,
- hardware-triggered thermal reset will be enabled.
-
- properties:
- nvidia,i2c-controller-id:
- $ref: /schemas/types.yaml#/definitions/uint32
- description:
- ID of I2C controller to send poweroff command to PMU.
- Valid values are described in section 9.2.148
- "APBDEV_PMC_SCRATCH53_0" of the Tegra K1 Technical Reference
- Manual.
-
- nvidia,bus-addr:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: Bus address of the PMU on the I2C bus.
-
- nvidia,reg-addr:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: PMU I2C register address to issue poweroff command.
-
- nvidia,reg-data:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: Poweroff command to write to PMU.
-
- nvidia,pinmux-id:
- $ref: /schemas/types.yaml#/definitions/uint32
- description:
- Pinmux used by the hardware when issuing Poweroff command.
- Defaults to 0. Valid values are described in section 12.5.2
- "Pinmux Support" of the Tegra4 Technical Reference Manual.
-
- required:
- - nvidia,i2c-controller-id
- - nvidia,bus-addr
- - nvidia,reg-addr
- - nvidia,reg-data
-
- additionalProperties: false
-
- powergates:
- type: object
- description: |
- This node contains a hierarchy of power domain nodes, which should
- match the powergates on the Tegra SoC. Each powergate node
- represents a power-domain on the Tegra SoC that can be power-gated
- by the Tegra PMC.
- Hardware blocks belonging to a power domain should contain
- "power-domains" property that is a phandle pointing to corresponding
- powergate node.
- The name of the powergate node should be one of the below. Note that
- not every powergate is applicable to all Tegra devices and the following
- list shows which powergates are applicable to which devices.
- Please refer to Tegra TRM for mode details on the powergate nodes to
- use for each power-gate block inside Tegra.
- Name Description Devices Applicable
- 3d 3D Graphics Tegra20/114/124/210
- 3d0 3D Graphics 0 Tegra30
- 3d1 3D Graphics 1 Tegra30
- aud Audio Tegra210
- dfd Debug Tegra210
- dis Display A Tegra114/124/210
- disb Display B Tegra114/124/210
- heg 2D Graphics Tegra30/114/124/210
- iram Internal RAM Tegra124/210
- mpe MPEG Encode All
- nvdec NVIDIA Video Decode Engine Tegra210
- nvjpg NVIDIA JPEG Engine Tegra210
- pcie PCIE Tegra20/30/124/210
- sata SATA Tegra30/124/210
- sor Display interfaces Tegra124/210
- ve2 Video Encode Engine 2 Tegra210
- venc Video Encode Engine All
- vdec Video Decode Engine Tegra20/30/114/124
- vic Video Imaging Compositor Tegra124/210
- xusba USB Partition A Tegra114/124/210
- xusbb USB Partition B Tegra114/124/210
- xusbc USB Partition C Tegra114/124/210
-
- patternProperties:
- "^[a-z0-9]+$":
- type: object
- additionalProperties: false
-
- properties:
- clocks:
- minItems: 1
- maxItems: 8
- description:
- Must contain an entry for each clock required by the PMC
- for controlling a power-gate.
- See ../clocks/clock-bindings.txt document for more details.
-
- resets:
- minItems: 1
- maxItems: 8
- description:
- Must contain an entry for each reset required by the PMC
- for controlling a power-gate.
- See ../reset/reset.txt for more details.
-
- power-domains:
- maxItems: 1
-
- '#power-domain-cells':
- const: 0
- description: Must be 0.
-
- required:
- - clocks
- - resets
- - '#power-domain-cells'
-
- additionalProperties: false
-
-patternProperties:
- "^[a-f0-9]+-[a-f0-9]+$":
- type: object
- description:
- This is a Pad configuration node. On Tegra SOCs a pad is a set of
- pins which are configured as a group. The pin grouping is a fixed
- attribute of the hardware. The PMC can be used to set pad power state
- and signaling voltage. A pad can be either in active or power down mode.
- The support for power state and signaling voltage configuration varies
- depending on the pad in question. 3.3V and 1.8V signaling voltages
- are supported on pins where software controllable signaling voltage
- switching is available.
-
- The pad configuration state nodes are placed under the pmc node and they
- are referred to by the pinctrl client properties. For more information
- see Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt.
- The pad name should be used as the value of the pins property in pin
- configuration nodes.
-
- The following pads are present on Tegra124 and Tegra132
- audio, bb, cam, comp, csia, csb, cse, dsi, dsib, dsic, dsid, hdmi, hsic,
- hv, lvds, mipi-bias, nand, pex-bias, pex-clk1, pex-clk2, pex-cntrl,
- sdmmc1, sdmmc3, sdmmc4, sys_ddc, uart, usb0, usb1, usb2, usb_bias.
-
- The following pads are present on Tegra210
- audio, audio-hv, cam, csia, csib, csic, csid, csie, csif, dbg,
- debug-nonao, dmic, dp, dsi, dsib, dsic, dsid, emmc, emmc2, gpio, hdmi,
- hsic, lvds, mipi-bias, pex-bias, pex-clk1, pex-clk2, pex-cntrl, sdmmc1,
- sdmmc3, spi, spi-hv, uart, usb0, usb1, usb2, usb3, usb-bias.
-
- properties:
- pins:
- $ref: /schemas/types.yaml#/definitions/string
- description: Must contain name of the pad(s) to be configured.
-
- low-power-enable:
- $ref: /schemas/types.yaml#/definitions/flag
- description: Configure the pad into power down mode.
-
- low-power-disable:
- $ref: /schemas/types.yaml#/definitions/flag
- description: Configure the pad into active mode.
-
- power-source:
- $ref: /schemas/types.yaml#/definitions/uint32
- description:
- Must contain either TEGRA_IO_PAD_VOLTAGE_1V8 or
- TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages.
- The values are defined in
- include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h.
- Power state can be configured on all Tegra124 and Tegra132
- pads. None of the Tegra124 or Tegra132 pads support signaling
- voltage switching.
- All of the listed Tegra210 pads except pex-cntrl support power
- state configuration. Signaling voltage switching is supported
- on below Tegra210 pads.
- audio, audio-hv, cam, dbg, dmic, gpio, pex-cntrl, sdmmc1,
- sdmmc3, spi, spi-hv, and uart.
-
- required:
- - pins
-
- additionalProperties: false
-
-required:
- - compatible
- - reg
- - clock-names
- - clocks
- - '#clock-cells'
-
-additionalProperties: false
-
-dependencies:
- "nvidia,suspend-mode": ["nvidia,core-pwr-off-time", "nvidia,cpu-pwr-off-time"]
- "nvidia,core-pwr-off-time": ["nvidia,core-pwr-good-time"]
- "nvidia,cpu-pwr-off-time": ["nvidia,cpu-pwr-good-time"]
-
-examples:
- - |
-
- #include <dt-bindings/clock/tegra210-car.h>
- #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
- #include <dt-bindings/soc/tegra-pmc.h>
-
- tegra_pmc: pmc@7000e400 {
- compatible = "nvidia,tegra210-pmc";
- reg = <0x7000e400 0x400>;
- core-supply = <&regulator>;
- clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
- clock-names = "pclk", "clk32k_in";
- #clock-cells = <1>;
-
- nvidia,invert-interrupt;
- nvidia,suspend-mode = <0>;
- nvidia,cpu-pwr-good-time = <0>;
- nvidia,cpu-pwr-off-time = <0>;
- nvidia,core-pwr-good-time = <4587 3876>;
- nvidia,core-pwr-off-time = <39065>;
- nvidia,core-power-req-active-high;
- nvidia,sys-clock-req-active-high;
-
- pd_core: core-domain {
- operating-points-v2 = <&core_opp_table>;
- #power-domain-cells = <0>;
- };
-
- powergates {
- pd_audio: aud {
- clocks = <&tegra_car TEGRA210_CLK_APE>,
- <&tegra_car TEGRA210_CLK_APB2APE>;
- resets = <&tegra_car 198>;
- power-domains = <&pd_core>;
- #power-domain-cells = <0>;
- };
-
- pd_xusbss: xusba {
- clocks = <&tegra_car TEGRA210_CLK_XUSB_SS>;
- resets = <&tegra_car TEGRA210_CLK_XUSB_SS>;
- power-domains = <&pd_core>;
- #power-domain-cells = <0>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml b/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
index 3c7a2425f3e6..a17297cbefcb 100644
--- a/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
+++ b/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
@@ -151,7 +151,7 @@ allOf:
- interconnects
- power-domains
-additionalProperties: true
+additionalProperties: false
examples:
- |
diff --git a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
index 44892aa589fd..580f9a97ddf7 100644
--- a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
+++ b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
@@ -20,6 +20,7 @@ description: |
properties:
compatible:
enum:
+ - qcom,qdu1000-llcc
- qcom,sc7180-llcc
- qcom,sc7280-llcc
- qcom,sc8180x-llcc
@@ -44,6 +45,14 @@ properties:
interrupts:
maxItems: 1
+ nvmem-cells:
+ items:
+ - description: Reference to an nvmem node for multi channel DDR
+
+ nvmem-cell-names:
+ items:
+ - const: multi-chan-ddr
+
required:
- compatible
- reg
@@ -92,6 +101,7 @@ allOf:
compatible:
contains:
enum:
+ - qcom,qdu1000-llcc
- qcom,sc8180x-llcc
- qcom,sc8280xp-llcc
then:
diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
index b138f3d23df8..4591523b51a0 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
@@ -38,6 +38,9 @@ properties:
with shmem address(4KB-page, offset) as parameters
items:
- const: arm,scmi-smc-param
+ - description: SCMI compliant firmware with Qualcomm SMC/HVC transport
+ items:
+ - const: qcom,scmi-smc
- description: SCMI compliant firmware with SCMI Virtio transport.
The virtio transport only supports a single device.
items:
@@ -149,8 +152,15 @@ properties:
'#clock-cells':
const: 1
- required:
- - '#clock-cells'
+ '#power-domain-cells':
+ const: 1
+
+ oneOf:
+ - required:
+ - '#clock-cells'
+
+ - required:
+ - '#power-domain-cells'
protocol@14:
$ref: '#/$defs/protocol-node'
@@ -306,6 +316,7 @@ else:
enum:
- arm,scmi-smc
- arm,scmi-smc-param
+ - qcom,scmi-smc
then:
required:
- arm,smc-id
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
index 4233ea839bfc..0613a37a851a 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
@@ -24,6 +24,7 @@ properties:
- qcom,scm-apq8064
- qcom,scm-apq8084
- qcom,scm-ipq4019
+ - qcom,scm-ipq5018
- qcom,scm-ipq5332
- qcom,scm-ipq6018
- qcom,scm-ipq806x
@@ -56,6 +57,7 @@ properties:
- qcom,scm-sm6125
- qcom,scm-sm6350
- qcom,scm-sm6375
+ - qcom,scm-sm7150
- qcom,scm-sm8150
- qcom,scm-sm8250
- qcom,scm-sm8350
@@ -89,6 +91,14 @@ properties:
protocol to handle sleeping SCM calls.
maxItems: 1
+ qcom,sdi-enabled:
+ description:
+ Indicates that the SDI (Secure Debug Image) has been enabled by TZ
+ by default and it needs to be disabled.
+ If not disabled WDT assertion or reboot will cause the board to hang
+ in the debug mode.
+ type: boolean
+
qcom,dload-mode:
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
diff --git a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
index dc1f28e55266..0c07e8dda445 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
@@ -65,6 +65,8 @@ properties:
- items:
- enum:
- allwinner,sun20i-d1-plic
+ - sophgo,cv1800b-plic
+ - sophgo,sg2042-plic
- thead,th1520-plic
- const: thead,c900-plic
- items:
diff --git a/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-mswi.yaml b/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-mswi.yaml
new file mode 100644
index 000000000000..065f2544b63b
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-mswi.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/thead,c900-aclint-mswi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo sg2042 CLINT Machine-level Software Interrupt Device
+
+maintainers:
+ - Inochi Amaoto <inochiama@outlook.com>
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - sophgo,sg2042-aclint-mswi
+ - const: thead,c900-aclint-mswi
+
+ reg:
+ maxItems: 1
+
+ interrupts-extended:
+ minItems: 1
+ maxItems: 4095
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts-extended
+
+examples:
+ - |
+ interrupt-controller@94000000 {
+ compatible = "sophgo,sg2042-aclint-mswi", "thead,c900-aclint-mswi";
+ interrupts-extended = <&cpu1intc 3>,
+ <&cpu2intc 3>,
+ <&cpu3intc 3>,
+ <&cpu4intc 3>;
+ reg = <0x94000000 0x00010000>;
+ };
+...
diff --git a/Documentation/devicetree/bindings/memory-controllers/ingenic,nemc.yaml b/Documentation/devicetree/bindings/memory-controllers/ingenic,nemc.yaml
index b40cec0eb651..ee74a362f4ca 100644
--- a/Documentation/devicetree/bindings/memory-controllers/ingenic,nemc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/ingenic,nemc.yaml
@@ -40,6 +40,7 @@ patternProperties:
".*@[0-9]+$":
type: object
$ref: mc-peripheral-props.yaml#
+ additionalProperties: true
required:
- compatible
diff --git a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
index 56e62cd0b36a..25f3bb9890ae 100644
--- a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
@@ -80,6 +80,8 @@ properties:
patternProperties:
"flash@[0-9a-f]+$":
type: object
+ additionalProperties: true
+
properties:
compatible:
contains:
diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
index b049837ee669..c7a8a041da50 100644
--- a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
@@ -130,7 +130,7 @@ patternProperties:
bus. The device can be a NAND chip, SRAM device, NOR device
or an ASIC.
$ref: ti,gpmc-child.yaml
-
+ additionalProperties: true
required:
- compatible
diff --git a/Documentation/devicetree/bindings/mmc/npcm,sdhci.yaml b/Documentation/devicetree/bindings/mmc/npcm,sdhci.yaml
new file mode 100644
index 000000000000..196fdbfa16ed
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/npcm,sdhci.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mmc/npcm,sdhci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NPCM SDHCI Controller
+
+maintainers:
+ - Tomer Maimon <tmaimon77@gmail.com>
+
+allOf:
+ - $ref: mmc-controller.yaml#
+
+properties:
+ compatible:
+ enum:
+ - nuvoton,npcm750-sdhci
+ - nuvoton,npcm845-sdhci
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ mmc@f0840000 {
+ compatible = "nuvoton,npcm750-sdhci";
+ reg = <0xf0840000 0x200>;
+ interrupts = <0 27 4>;
+ clocks = <&clk 4>;
+ };
diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
index 7756a8687eaf..94e228787630 100644
--- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
+++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
@@ -59,6 +59,7 @@ properties:
- renesas,sdhi-r9a07g043 # RZ/G2UL
- renesas,sdhi-r9a07g044 # RZ/G2{L,LC}
- renesas,sdhi-r9a07g054 # RZ/V2L
+ - renesas,sdhi-r9a08g045 # RZ/G3S
- renesas,sdhi-r9a09g011 # RZ/V2M
- const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2
- items:
@@ -122,6 +123,7 @@ allOf:
- renesas,sdhi-r9a07g043
- renesas,sdhi-r9a07g044
- renesas,sdhi-r9a07g054
+ - renesas,sdhi-r9a08g045
- renesas,sdhi-r9a09g011
then:
properties:
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml
index 10f34aa8ba8a..86fae733d9a0 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml
+++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml
@@ -58,6 +58,7 @@ properties:
- qcom,sm8350-sdhci
- qcom,sm8450-sdhci
- qcom,sm8550-sdhci
+ - qcom,sm8650-sdhci
- const: qcom,sdhci-msm-v5 # for sdcc version 5.0
reg:
@@ -85,10 +86,10 @@ properties:
- const: iface
- const: core
- const: xo
- - const: ice
- - const: bus
- - const: cal
- - const: sleep
+ - enum: [ice, bus, cal, sleep]
+ - enum: [ice, bus, cal, sleep]
+ - enum: [ice, bus, cal, sleep]
+ - enum: [ice, bus, cal, sleep]
dma-coherent: true
diff --git a/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml b/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
index 51e1b04e799f..553a75195c2e 100644
--- a/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
+++ b/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
@@ -55,7 +55,6 @@ required:
- clocks
- clock-names
- interrupts
- - starfive,sysreg
unevaluatedProperties: false
@@ -73,5 +72,4 @@ examples:
fifo-depth = <32>;
fifo-watermark-aligned;
data-addr = <0>;
- starfive,sysreg = <&sys_syscon 0x14 0x1a 0x7c000000>;
};
diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml b/Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml
index 296001e7f498..0928ec408170 100644
--- a/Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml
+++ b/Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml
@@ -23,7 +23,9 @@ properties:
- const: allwinner,sun20i-d1-sid
- const: allwinner,sun50i-a64-sid
- items:
- - const: allwinner,sun50i-a100-sid
+ - enum:
+ - allwinner,sun50i-a100-sid
+ - allwinner,sun50i-h616-sid
- const: allwinner,sun50i-a64-sid
- const: allwinner,sun50i-h5-sid
- const: allwinner,sun50i-h6-sid
diff --git a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
index d80bbedfe3aa..dab3d92bc273 100644
--- a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
+++ b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
@@ -12,7 +12,7 @@ maintainers:
- Jianxin Pan <jianxin.pan@amlogic.com>
description: |+
- Secure Power Domains used in Meson A1/C1/S4 & C3 SoCs, and should be the child node
+ Secure Power Domains used in Meson A1/C1/S4 & C3/T7 SoCs, and should be the child node
of secure-monitor.
properties:
@@ -21,6 +21,7 @@ properties:
- amlogic,meson-a1-pwrc
- amlogic,meson-s4-pwrc
- amlogic,c3-pwrc
+ - amlogic,t7-pwrc
"#power-domain-cells":
const: 1
diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
index c9acef80f452..8985e2df8a56 100644
--- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
+++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
@@ -31,6 +31,7 @@ properties:
- mediatek,mt8188-power-controller
- mediatek,mt8192-power-controller
- mediatek,mt8195-power-controller
+ - mediatek,mt8365-power-controller
'#power-domain-cells':
const: 1
@@ -88,6 +89,7 @@ $defs:
"include/dt-bindings/power/mediatek,mt8188-power.h" - for MT8188 type power domain.
"include/dt-bindings/power/mt8192-power.h" - for MT8192 type power domain.
"include/dt-bindings/power/mt8195-power.h" - for MT8195 type power domain.
+ "include/dt-bindings/power/mediatek,mt8365-power.h" - for MT8365 type power domain.
maxItems: 1
clocks:
@@ -115,6 +117,10 @@ $defs:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the device containing the INFRACFG register range.
+ mediatek,infracfg-nao:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: phandle to the device containing the INFRACFG-NAO register range.
+
mediatek,smi:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the device containing the SMI register range.
diff --git a/Documentation/devicetree/bindings/power/power-domain.yaml b/Documentation/devicetree/bindings/power/power-domain.yaml
index d1235e562041..8fdb529d560b 100644
--- a/Documentation/devicetree/bindings/power/power-domain.yaml
+++ b/Documentation/devicetree/bindings/power/power-domain.yaml
@@ -13,8 +13,9 @@ maintainers:
description: |+
System on chip designs are often divided into multiple PM domains that can be
- used for power gating of selected IP blocks for power saving by reduced leakage
- current.
+ used for power gating of selected IP blocks for power saving by reduced
+ leakage current. Moreover, in some cases the similar PM domains may also be
+ capable of scaling performance for a group of IP blocks.
This device tree binding can be used to bind PM domain consumer devices with
their PM domains provided by PM domain providers. A PM domain provider can be
@@ -25,7 +26,7 @@ description: |+
properties:
$nodename:
- pattern: "^(power-controller|power-domain)([@-].*)?$"
+ pattern: "^(power-controller|power-domain|performance-domain)([@-].*)?$"
domain-idle-states:
$ref: /schemas/types.yaml#/definitions/phandle-array
@@ -44,11 +45,11 @@ properties:
operating-points-v2:
description:
- Phandles to the OPP tables of power domains provided by a power domain
- provider. If the provider provides a single power domain only or all
- the power domains provided by the provider have identical OPP tables,
- then this shall contain a single phandle. Refer to ../opp/opp-v2-base.yaml
- for more information.
+ Phandles to the OPP tables of power domains that are capable of scaling
+ performance, provided by a power domain provider. If the provider provides
+ a single power domain only or all the power domains provided by the
+ provider have identical OPP tables, then this shall contain a single
+ phandle. Refer to ../opp/opp-v2-base.yaml for more information.
"#power-domain-cells":
description:
diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
index 9b03c41d3604..da9c5846f4e1 100644
--- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
+++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
@@ -15,42 +15,52 @@ description:
properties:
compatible:
- enum:
- - qcom,mdm9607-rpmpd
- - qcom,msm8226-rpmpd
- - qcom,msm8909-rpmpd
- - qcom,msm8916-rpmpd
- - qcom,msm8939-rpmpd
- - qcom,msm8953-rpmpd
- - qcom,msm8976-rpmpd
- - qcom,msm8994-rpmpd
- - qcom,msm8996-rpmpd
- - qcom,msm8998-rpmpd
- - qcom,qcm2290-rpmpd
- - qcom,qcs404-rpmpd
- - qcom,qdu1000-rpmhpd
- - qcom,sa8155p-rpmhpd
- - qcom,sa8540p-rpmhpd
- - qcom,sa8775p-rpmhpd
- - qcom,sdm660-rpmpd
- - qcom,sc7180-rpmhpd
- - qcom,sc7280-rpmhpd
- - qcom,sc8180x-rpmhpd
- - qcom,sc8280xp-rpmhpd
- - qcom,sdm670-rpmhpd
- - qcom,sdm845-rpmhpd
- - qcom,sdx55-rpmhpd
- - qcom,sdx65-rpmhpd
- - qcom,sdx75-rpmhpd
- - qcom,sm6115-rpmpd
- - qcom,sm6125-rpmpd
- - qcom,sm6350-rpmhpd
- - qcom,sm6375-rpmpd
- - qcom,sm8150-rpmhpd
- - qcom,sm8250-rpmhpd
- - qcom,sm8350-rpmhpd
- - qcom,sm8450-rpmhpd
- - qcom,sm8550-rpmhpd
+ oneOf:
+ - enum:
+ - qcom,mdm9607-rpmpd
+ - qcom,msm8226-rpmpd
+ - qcom,msm8909-rpmpd
+ - qcom,msm8916-rpmpd
+ - qcom,msm8917-rpmpd
+ - qcom,msm8939-rpmpd
+ - qcom,msm8953-rpmpd
+ - qcom,msm8976-rpmpd
+ - qcom,msm8994-rpmpd
+ - qcom,msm8996-rpmpd
+ - qcom,msm8998-rpmpd
+ - qcom,qcm2290-rpmpd
+ - qcom,qcs404-rpmpd
+ - qcom,qdu1000-rpmhpd
+ - qcom,qm215-rpmpd
+ - qcom,sa8155p-rpmhpd
+ - qcom,sa8540p-rpmhpd
+ - qcom,sa8775p-rpmhpd
+ - qcom,sc7180-rpmhpd
+ - qcom,sc7280-rpmhpd
+ - qcom,sc8180x-rpmhpd
+ - qcom,sc8280xp-rpmhpd
+ - qcom,sc8380xp-rpmhpd
+ - qcom,sdm660-rpmpd
+ - qcom,sdm670-rpmhpd
+ - qcom,sdm845-rpmhpd
+ - qcom,sdx55-rpmhpd
+ - qcom,sdx65-rpmhpd
+ - qcom,sdx75-rpmhpd
+ - qcom,sm6115-rpmpd
+ - qcom,sm6125-rpmpd
+ - qcom,sm6350-rpmhpd
+ - qcom,sm6375-rpmpd
+ - qcom,sm7150-rpmhpd
+ - qcom,sm8150-rpmhpd
+ - qcom,sm8250-rpmhpd
+ - qcom,sm8350-rpmhpd
+ - qcom,sm8450-rpmhpd
+ - qcom,sm8550-rpmhpd
+ - qcom,sm8650-rpmhpd
+ - items:
+ - enum:
+ - qcom,msm8937-rpmpd
+ - const: qcom,msm8917-rpmpd
'#power-domain-cells':
const: 1
diff --git a/Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml b/Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml
index f2d1dc7e7b3f..65bfb492b3a4 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml
+++ b/Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml
@@ -32,6 +32,7 @@ properties:
- rockchip,rk3308-pwm
- rockchip,rk3568-pwm
- rockchip,rk3588-pwm
+ - rockchip,rv1126-pwm
- const: rockchip,rk3328-pwm
reg:
diff --git a/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.yaml b/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.yaml
index bab982f00485..46407e9c1d4f 100644
--- a/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.yaml
+++ b/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.yaml
@@ -26,6 +26,17 @@ properties:
description: >
identifier of the client to use this region for buffers
+ qcom,use-guard-pages:
+ type: boolean
+ description: >
+ Indicates that the firmware, or hardware, does not gracefully handle
+ memory protection of this region when placed adjacent to other protected
+ memory regions, and that padding around the used portion of the memory
+ region is necessary.
+
+ When this is set, the first and last page should be left unused, and the
+ effective size of the region will thereby shrink with two pages.
+
qcom,vmid:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: >
diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml
index 97e8441eda1c..f392e367d673 100644
--- a/Documentation/devicetree/bindings/riscv/cpus.yaml
+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
@@ -47,6 +47,7 @@ properties:
- sifive,u74-mc
- thead,c906
- thead,c910
+ - thead,c920
- const: riscv
- items:
- enum:
diff --git a/Documentation/devicetree/bindings/riscv/sophgo.yaml b/Documentation/devicetree/bindings/riscv/sophgo.yaml
new file mode 100644
index 000000000000..86748c5390be
--- /dev/null
+++ b/Documentation/devicetree/bindings/riscv/sophgo.yaml
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/riscv/sophgo.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo SoC-based boards
+
+maintainers:
+ - Chao Wei <chao.wei@sophgo.com>
+ - Chen Wang <unicorn_wang@outlook.com>
+
+description:
+ Sophgo SoC-based boards
+
+properties:
+ $nodename:
+ const: '/'
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - milkv,duo
+ - const: sophgo,cv1800b
+ - items:
+ - enum:
+ - milkv,pioneer
+ - const: sophgo,sg2042
+
+additionalProperties: true
+
+...
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
index f21eb907ee90..7eda63d5682f 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
@@ -22,6 +22,7 @@ properties:
compatible:
enum:
- mediatek,mt8183-svs
+ - mediatek,mt8188-svs
- mediatek,mt8192-svs
reg:
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
index 8a4b7ba3aaf6..7b031ef09669 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
@@ -52,6 +52,8 @@ properties:
iommus:
maxItems: 1
+ dma-coherent: true
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml
index e52e176d8cb3..4386b2c3fa4d 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml
@@ -23,6 +23,7 @@ properties:
- renesas,r9a07g043-sysc # RZ/G2UL and RZ/Five
- renesas,r9a07g044-sysc # RZ/G2{L,LC}
- renesas,r9a07g054-sysc # RZ/V2L
+ - renesas,r9a08g045-sysc # RZ/G3S
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
index 53b95f348f8e..16ca3ff7b1ae 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
@@ -302,7 +302,7 @@ properties:
- description: R-Car E3 (R8A77990)
items:
- enum:
- - renesas,ebisu # Ebisu (RTP0RC77990SEB0010S)
+ - renesas,ebisu # Ebisu (RTP0RC77990SEB0010S), Ebisu-4D (RTP0RC77990SEB0020S)
- const: renesas,r8a77990
- description: R-Car D3 (R8A77995)
@@ -335,6 +335,13 @@ properties:
- const: renesas,spider-cpu
- const: renesas,r8a779f0
+ - description: R-Car S4-8 (R8A779F4)
+ items:
+ - enum:
+ - renesas,s4sk # R-Car S4 Starter Kit board (Y-ASK-RCAR-S4-1000BASE-T#WS12)
+ - const: renesas,r8a779f4
+ - const: renesas,r8a779f0
+
- description: R-Car V4H (R8A779G0)
items:
- enum:
@@ -474,6 +481,25 @@ properties:
- renesas,rzv2mevk2 # RZ/V2M Eval Board v2.0
- const: renesas,r9a09g011
+ - description: RZ/G3S (R9A08G045)
+ items:
+ - enum:
+ - renesas,r9a08g045s33 # PCIe support
+ - const: renesas,r9a08g045
+
+ - description: RZ/G3S SMARC Module (SoM)
+ items:
+ - const: renesas,rzg3s-smarcm # RZ/G3S SMARC Module (SoM)
+ - const: renesas,r9a08g045s33 # PCIe support
+ - const: renesas,r9a08g045
+
+ - description: RZ SMARC Carrier-II Evaluation Kit
+ items:
+ - const: renesas,smarc2-evk # RZ SMARC Carrier-II EVK
+ - const: renesas,rzg3s-smarcm # RZ/G3S SMARC SoM
+ - const: renesas,r9a08g045s33 # PCIe support
+ - const: renesas,r9a08g045
+
additionalProperties: true
...
diff --git a/Documentation/devicetree/bindings/soc/sti/st,sti-syscon.yaml b/Documentation/devicetree/bindings/soc/sti/st,sti-syscon.yaml
new file mode 100644
index 000000000000..5f97d9ff17fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/sti/st,sti-syscon.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/sti/st,sti-syscon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STi platform sysconfig
+
+maintainers:
+ - Patrice Chotard <patrice.chotard@foss.st.com>
+
+description: |
+ Binding for the various sysconfig nodes used within the STi
+ platform device-tree to point to some common configuration
+ registers used by other nodes.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - st,stih407-core-syscfg
+ - st,stih407-flash-syscfg
+ - st,stih407-front-syscfg
+ - st,stih407-lpm-syscfg
+ - st,stih407-rear-syscfg
+ - st,stih407-sbc-reg-syscfg
+ - st,stih407-sbc-syscfg
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ syscfg_sbc: syscon@9620000 {
+ compatible = "st,stih407-sbc-syscfg", "syscon";
+ reg = <0x9620000 0x1000>;
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml
new file mode 100644
index 000000000000..b86f6f53ca95
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml
@@ -0,0 +1,416 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/tegra/nvidia,tegra20-pmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra Power Management Controller (PMC)
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jonathan Hunter <jonathanh@nvidia.com>
+
+properties:
+ compatible:
+ enum:
+ - nvidia,tegra20-pmc
+ - nvidia,tegra30-pmc
+ - nvidia,tegra114-pmc
+ - nvidia,tegra124-pmc
+ - nvidia,tegra210-pmc
+
+ reg:
+ maxItems: 1
+
+ clock-names:
+ items:
+ # Tegra clock of the same name
+ - const: pclk
+ # 32 KHz clock input
+ - const: clk32k_in
+
+ clocks:
+ maxItems: 2
+
+ '#clock-cells':
+ const: 1
+ description: |
+ Tegra PMC has clk_out_1, clk_out_2, and clk_out_3. PMC also has blink
+ control which allows 32Khz clock output to Tegra blink pad.
+
+ Consumer of PMC clock should specify the desired clock by having the
+ clock ID in its "clocks" phandle cell with PMC clock provider. See
+ include/dt-bindings/soc/tegra-pmc.h for the list of Tegra PMC clock IDs.
+
+ '#interrupt-cells':
+ const: 2
+ description: Specifies number of cells needed to encode an interrupt
+ source.
+
+ interrupt-controller: true
+
+ nvidia,invert-interrupt:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description: Inverts the PMU interrupt signal. The PMU is an external Power
+ Management Unit, whose interrupt output signal is fed into the PMC. This
+ signal is optionally inverted, and then fed into the ARM GIC. The PMC is
+ not involved in the detection or handling of this interrupt signal,
+ merely its inversion.
+
+ nvidia,core-power-req-active-high:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description: core power request active-high
+
+ nvidia,sys-clock-req-active-high:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description: system clock request active-high
+
+ nvidia,combined-power-req:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description: combined power request for CPU and core
+
+ nvidia,cpu-pwr-good-en:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description: CPU power good signal from external PMIC to PMC is enabled
+
+ nvidia,suspend-mode:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: the suspend mode that the platform should use
+ oneOf:
+ - description: LP0, CPU + Core voltage off and DRAM in self-refresh
+ const: 0
+ - description: LP1, CPU voltage off and DRAM in self-refresh
+ const: 1
+ - description: LP2, CPU voltage off
+ const: 2
+
+ nvidia,cpu-pwr-good-time:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: CPU power good time in microseconds
+
+ nvidia,cpu-pwr-off-time:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: CPU power off time in microseconds
+
+ nvidia,core-pwr-good-time:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description: core power good time in microseconds
+ items:
+ - description: oscillator stable time
+ - description: power stable time
+
+ nvidia,core-pwr-off-time:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: core power off time in microseconds
+
+ nvidia,lp0-vec:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description: |
+ Starting address and length of LP0 vector. The LP0 vector contains the
+ warm boot code that is executed by AVP when resuming from the LP0 state.
+ The AVP (Audio-Video Processor) is an ARM7 processor and always being
+ the first boot processor when chip is power on or resume from deep sleep
+ mode. When the system is resumed from the deep sleep mode, the warm boot
+ code will restore some PLLs, clocks and then brings up CPU0 for resuming
+ the system.
+ items:
+ - description: starting address of LP0 vector
+ - description: length of LP0 vector
+
+ core-supply:
+ description: phandle to voltage regulator connected to the SoC core power
+ rail
+
+ core-domain:
+ type: object
+ description: The vast majority of hardware blocks of Tegra SoC belong to a
+ core power domain, which has a dedicated voltage rail that powers the
+ blocks.
+ additionalProperties: false
+ properties:
+ operating-points-v2:
+ description: Should contain level, voltages and opp-supported-hw
+ property. The supported-hw is a bitfield indicating SoC speedo or
+ process ID mask.
+
+ "#power-domain-cells":
+ const: 0
+
+ required:
+ - operating-points-v2
+ - "#power-domain-cells"
+
+ i2c-thermtrip:
+ type: object
+ description: On Tegra30, Tegra114 and Tegra124 if i2c-thermtrip subnode
+ exists, hardware-triggered thermal reset will be enabled.
+ additionalProperties: false
+ properties:
+ nvidia,i2c-controller-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: ID of I2C controller to send poweroff command to PMU.
+ Valid values are described in section 9.2.148 "APBDEV_PMC_SCRATCH53_0"
+ of the Tegra K1 Technical Reference Manual.
+
+ nvidia,bus-addr:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: bus address of the PMU on the I2C bus
+
+ nvidia,reg-addr:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: PMU I2C register address to issue poweroff command
+
+ nvidia,reg-data:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: power-off command to write to PMU
+
+ nvidia,pinmux-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Pinmux used by the hardware when issuing power-off command.
+ Defaults to 0. Valid values are described in section 12.5.2 "Pinmux
+ Support" of the Tegra4 Technical Reference Manual.
+
+ required:
+ - nvidia,i2c-controller-id
+ - nvidia,bus-addr
+ - nvidia,reg-addr
+ - nvidia,reg-data
+
+ powergates:
+ type: object
+ additionalProperties: false
+ description: |
+ This node contains a hierarchy of power domain nodes, which should match
+ the powergates on the Tegra SoC. Each powergate node represents a power-
+ domain on the Tegra SoC that can be power-gated by the Tegra PMC.
+
+ Hardware blocks belonging to a power domain should contain "power-domains"
+ property that is a phandle pointing to corresponding powergate node.
+
+ The name of the powergate node should be one of the below. Note that not
+ every powergate is applicable to all Tegra devices and the following list
+ shows which powergates are applicable to which devices.
+
+ Please refer to Tegra TRM for mode details on the powergate nodes to use
+ for each power-gate block inside Tegra.
+
+ Name Description Devices Applicable
+ --------------------------------------------------------------
+ 3d 3D Graphics Tegra20/114/124/210
+ 3d0 3D Graphics 0 Tegra30
+ 3d1 3D Graphics 1 Tegra30
+ aud Audio Tegra210
+ dfd Debug Tegra210
+ dis Display A Tegra114/124/210
+ disb Display B Tegra114/124/210
+ heg 2D Graphics Tegra30/114/124/210
+ iram Internal RAM Tegra124/210
+ mpe MPEG Encode All
+ nvdec NVIDIA Video Decode Engine Tegra210
+ nvjpg NVIDIA JPEG Engine Tegra210
+ pcie PCIE Tegra20/30/124/210
+ sata SATA Tegra30/124/210
+ sor Display interfaces Tegra124/210
+ ve2 Video Encode Engine 2 Tegra210
+ venc Video Encode Engine All
+ vdec Video Decode Engine Tegra20/30/114/124
+ vic Video Imaging Compositor Tegra124/210
+ xusba USB Partition A Tegra114/124/210
+ xusbb USB Partition B Tegra114/124/210
+ xusbc USB Partition C Tegra114/124/210
+
+ patternProperties:
+ "^[a-z0-9]+$":
+ type: object
+ additionalProperties: false
+ properties:
+ clocks:
+ minItems: 1
+ maxItems: 10
+
+ resets:
+ minItems: 1
+ maxItems: 8
+
+ power-domains:
+ maxItems: 1
+
+ '#power-domain-cells':
+ const: 0
+ description: Must be 0.
+
+ required:
+ - clocks
+ - resets
+ - '#power-domain-cells'
+
+ pinmux:
+ type: object
+ additionalProperties:
+ type: object
+ description: |
+ This is a pad configuration node. On Tegra SoCs a pad is a set of pins
+ which are configured as a group. The pin grouping is a fixed attribute
+ of the hardware. The PMC can be used to set pad power state and
+ signaling voltage. A pad can be either in active or power down mode.
+ The support for power state and signaling voltage configuration varies
+ depending on the pad in question. 3.3V and 1.8V signaling voltages are
+ supported on pins where software controllable signaling voltage
+ switching is available.
+
+ The pad configuration state nodes are placed under the pmc node and
+ they are referred to by the pinctrl client properties. For more
+ information see:
+
+ Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+
+ The pad name should be used as the value of the pins property in pin
+ configuration nodes.
+
+ The following pads are present on Tegra124 and Tegra132:
+
+ audio, bb, cam, comp, csia, csb, cse, dsi, dsib, dsic, dsid, hdmi,
+ hsic, hv, lvds, mipi-bias, nand, pex-bias, pex-clk1, pex-clk2,
+ pex-cntrl, sdmmc1, sdmmc3, sdmmc4, sys_ddc, uart, usb0, usb1, usb2,
+ usb_bias
+
+ The following pads are present on Tegra210:
+
+ audio, audio-hv, cam, csia, csib, csic, csid, csie, csif, dbg,
+ debug-nonao, dmic, dp, dsi, dsib, dsic, dsid, emmc, emmc2, gpio,
+ hdmi, hsic, lvds, mipi-bias, pex-bias, pex-clk1, pex-clk2, pex-cntrl,
+ sdmmc1, sdmmc3, spi, spi-hv, uart, usb0, usb1, usb2, usb3, usb-bias
+ additionalProperties: false
+ properties:
+ pins:
+ $ref: /schemas/types.yaml#/definitions/string-array
+ description: Must contain name of the pad(s) to be configured.
+
+ low-power-enable:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description: Configure the pad into power down mode.
+
+ low-power-disable:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description: Configure the pad into active mode.
+
+ power-source:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Must contain either TEGRA_IO_PAD_VOLTAGE_1V8 or
+ TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages. The
+ values are defined in:
+
+ include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h
+
+ Power state can be configured on all Tegra124 and Tegra132 pads.
+ None of the Tegra124 or Tegra132 pads support signaling voltage
+ switching. All of the listed Tegra210 pads except pex-cntrl support
+ power state configuration. Signaling voltage switching is supported
+ on the following Tegra210 pads:
+
+ audio, audio-hv, cam, dbg, dmic, gpio, pex-cntrl, sdmmc1, sdmmc3,
+ spi, spi-hv, uart
+
+ required:
+ - pins
+
+required:
+ - compatible
+ - reg
+ - clock-names
+ - clocks
+ - '#clock-cells'
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra124-pmc
+ then:
+ properties:
+ pinmux:
+ additionalProperties:
+ type: object
+ properties:
+ pins:
+ items:
+ enum: [ audio, bb, cam, comp, csia, csb, cse, dsi, dsib,
+ dsic, dsid, hdmi, hsic, hv, lvds, mipi-bias, nand,
+ pex-bias, pex-clk1, pex-clk2, pex-cntrl, sdmmc1,
+ sdmmc3, sdmmc4, sys_ddc, uart, usb0, usb1, usb2,
+ usb_bias ]
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra210-pmc
+ then:
+ properties:
+ pinmux:
+ additionalProperties:
+ type: object
+ properties:
+ pins:
+ items:
+ enum: [ audio, audio-hv, cam, csia, csib, csic, csid, csie,
+ csif, dbg, debug-nonao, dmic, dp, dsi, dsib, dsic,
+ dsid, emmc, emmc2, gpio, hdmi, hsic, lvds, mipi-bias,
+ pex-bias, pex-clk1, pex-clk2, pex-cntrl, sdmmc1,
+ sdmmc3, spi, spi-hv, uart, usb0, usb1, usb2, usb3,
+ usb-bias ]
+
+additionalProperties: false
+
+dependencies:
+ "nvidia,suspend-mode": ["nvidia,core-pwr-off-time", "nvidia,cpu-pwr-off-time"]
+ "nvidia,core-pwr-off-time": ["nvidia,core-pwr-good-time"]
+ "nvidia,cpu-pwr-off-time": ["nvidia,cpu-pwr-good-time"]
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra210-car.h>
+ #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
+ #include <dt-bindings/soc/tegra-pmc.h>
+
+ pmc@7000e400 {
+ compatible = "nvidia,tegra210-pmc";
+ reg = <0x7000e400 0x400>;
+ core-supply = <&regulator>;
+ clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
+ #clock-cells = <1>;
+
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <0>;
+ nvidia,cpu-pwr-good-time = <0>;
+ nvidia,cpu-pwr-off-time = <0>;
+ nvidia,core-pwr-good-time = <4587 3876>;
+ nvidia,core-pwr-off-time = <39065>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+
+ pd_core: core-domain {
+ operating-points-v2 = <&core_opp_table>;
+ #power-domain-cells = <0>;
+ };
+
+ powergates {
+ pd_audio: aud {
+ clocks = <&tegra_car TEGRA210_CLK_APE>,
+ <&tegra_car TEGRA210_CLK_APB2APE>;
+ resets = <&tegra_car 198>;
+ power-domains = <&pd_core>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_xusbss: xusba {
+ clocks = <&tegra_car TEGRA210_CLK_XUSB_SS>;
+ resets = <&tegra_car TEGRA210_CLK_XUSB_SS>;
+ power-domains = <&pd_core>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.yaml b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
index a0185e15a42f..e8be6c470364 100644
--- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml
+++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
@@ -37,6 +37,7 @@ properties:
- items:
- enum:
- allwinner,sun20i-d1-clint
+ - sophgo,cv1800b-clint
- thead,th1520-clint
- const: thead,c900-clint
- items:
diff --git a/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml b/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml
new file mode 100644
index 000000000000..fbd235650e52
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/timer/thead,c900-aclint-mtimer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo CLINT Timer
+
+maintainers:
+ - Inochi Amaoto <inochiama@outlook.com>
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - sophgo,sg2042-aclint-mtimer
+ - const: thead,c900-aclint-mtimer
+
+ reg:
+ maxItems: 1
+
+ interrupts-extended:
+ minItems: 1
+ maxItems: 4095
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts-extended
+
+examples:
+ - |
+ timer@ac000000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ interrupts-extended = <&cpu1intc 7>,
+ <&cpu2intc 7>,
+ <&cpu3intc 7>,
+ <&cpu4intc 7>;
+ reg = <0xac000000 0x00010000>;
+ };
+...
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 3f7624c73ed0..309b94c328c8 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -59,6 +59,8 @@ patternProperties:
description: AD Holdings Plc.
"^adi,.*":
description: Analog Devices, Inc.
+ "^adieng,.*":
+ description: ADI Engineering, Inc.
"^advantech,.*":
description: Advantech Corporation
"^aeroflexgaisler,.*":
@@ -127,6 +129,8 @@ patternProperties:
description: Arasan Chip Systems
"^archermind,.*":
description: ArcherMind Technology (Nanjing) Co., Ltd.
+ "^arcom,.*":
+ description: Arcom Controllers
"^arctic,.*":
description: Arctic Sand
"^arcx,.*":
@@ -194,6 +198,8 @@ patternProperties:
description: Shanghai Belling Co., Ltd.
"^bhf,.*":
description: Beckhoff Automation GmbH & Co. KG
+ "^bigtreetech,.*":
+ description: Shenzhen BigTree Tech Co., LTD
"^bitmain,.*":
description: Bitmain Technologies
"^blutek,.*":
@@ -484,6 +490,8 @@ patternProperties:
description: FocalTech Systems Co.,Ltd
"^forlinx,.*":
description: Baoding Forlinx Embedded Technology Co., Ltd.
+ "^freecom,.*":
+ description: Freecom Gmbh
"^frida,.*":
description: Shenzhen Frida LCD Co., Ltd.
"^friendlyarm,.*":
@@ -496,6 +504,8 @@ patternProperties:
description: FX Technology Ltd.
"^gardena,.*":
description: GARDENA GmbH
+ "^gateway,.*":
+ description: Gateway Communications
"^gateworks,.*":
description: Gateworks Corporation
"^gcw,.*":
@@ -510,6 +520,8 @@ patternProperties:
description: GE Fanuc Intelligent Platforms Embedded Systems, Inc.
"^gemei,.*":
description: Gemei Digital Technology Co., Ltd.
+ "^gemtek,.*":
+ description: Gemtek Technology Co., Ltd.
"^genesys,.*":
description: Genesys Logic, Inc.
"^geniatech,.*":
@@ -530,6 +542,8 @@ patternProperties:
description: Shenzhen Huiding Technology Co., Ltd.
"^google,.*":
description: Google, Inc.
+ "^goramo,.*":
+ description: Goramo Gorecki
"^gplus,.*":
description: GPLUS
"^grinn,.*":
@@ -865,6 +879,8 @@ patternProperties:
description: MikroElektronika d.o.o.
"^mikrotik,.*":
description: MikroTik
+ "^milkv,.*":
+ description: MilkV Technology Co., Ltd
"^miniand,.*":
description: Miniand Tech
"^minix,.*":
@@ -1279,6 +1295,8 @@ patternProperties:
description: Solomon Systech Limited
"^sony,.*":
description: Sony Corporation
+ "^sophgo,.*":
+ description: Sophgo Technology Inc.
"^sourceparts,.*":
description: Source Parts Inc.
"^spansion,.*":
@@ -1426,6 +1444,8 @@ patternProperties:
description: Truly Semiconductors Limited
"^tsd,.*":
description: Theobroma Systems Design und Consulting GmbH
+ "^turing,.*":
+ description: Turing Machines, Inc.
"^tyan,.*":
description: Tyan Computer Corporation
"^u-blox,.*":
@@ -1450,6 +1470,8 @@ patternProperties:
description: United Radiant Technology Corporation
"^usi,.*":
description: Universal Scientific Industrial Co., Ltd.
+ "^usr,.*":
+ description: U.S. Robotics Corporation
"^utoo,.*":
description: Aigo Digital Technology Co., Ltd.
"^v3,.*":
diff --git a/Documentation/doc-guide/contributing.rst b/Documentation/doc-guide/contributing.rst
index d4793826ad9a..662c7a840cd5 100644
--- a/Documentation/doc-guide/contributing.rst
+++ b/Documentation/doc-guide/contributing.rst
@@ -138,6 +138,10 @@ times, but it's highly important. If we can actually eliminate warnings
from the documentation build, then we can start expecting developers to
avoid adding new ones.
+In addition to warnings from the regular documentation build, you can also
+run ``make refcheckdocs`` to find references to nonexistent documentation
+files.
+
Languishing kerneldoc comments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
index 8be086b3f829..c5f99d834ec5 100644
--- a/Documentation/driver-api/driver-model/devres.rst
+++ b/Documentation/driver-api/driver-model/devres.rst
@@ -322,10 +322,8 @@ IOMAP
devm_platform_ioremap_resource_byname()
devm_platform_get_and_ioremap_resource()
devm_iounmap()
- pcim_iomap()
- pcim_iomap_regions() : do request_region() and iomap() on multiple BARs
- pcim_iomap_table() : array of mapped addresses indexed by BAR
- pcim_iounmap()
+
+ Note: For the PCI devices the specific pcim_*() functions may be used, see below.
IRQ
devm_free_irq()
@@ -392,8 +390,16 @@ PCI
devm_pci_alloc_host_bridge() : managed PCI host bridge allocation
devm_pci_remap_cfgspace() : ioremap PCI configuration space
devm_pci_remap_cfg_resource() : ioremap PCI configuration space resource
+
pcim_enable_device() : after success, all PCI ops become managed
+ pcim_iomap() : do iomap() on a single BAR
+ pcim_iomap_regions() : do request_region() and iomap() on multiple BARs
+ pcim_iomap_regions_request_all() : do request_region() on all and iomap() on multiple BARs
+ pcim_iomap_table() : array of mapped addresses indexed by BAR
+ pcim_iounmap() : do iounmap() on a single BAR
+ pcim_iounmap_regions() : do iounmap() and release_region() on multiple BARs
pcim_pin_device() : keep PCI device enabled after release
+ pcim_set_mwi() : enable Memory-Write-Invalidate PCI transaction
PHY
devm_usb_get_phy()
diff --git a/Documentation/driver-api/pps.rst b/Documentation/driver-api/pps.rst
index 2d6b99766ee8..78dded03e5d8 100644
--- a/Documentation/driver-api/pps.rst
+++ b/Documentation/driver-api/pps.rst
@@ -200,11 +200,17 @@ Generators
Sometimes one needs to be able not only to catch PPS signals but to produce
them also. For example, running a distributed simulation, which requires
-computers' clock to be synchronized very tightly. One way to do this is to
-invent some complicated hardware solutions but it may be neither necessary
-nor affordable. The cheap way is to load a PPS generator on one of the
-computers (master) and PPS clients on others (slaves), and use very simple
-cables to deliver signals using parallel ports, for example.
+computers' clock to be synchronized very tightly.
+
+
+Parallel port generator
+------------------------
+
+One way to do this is to invent some complicated hardware solutions but it
+may be neither necessary nor affordable. The cheap way is to load a PPS
+generator on one of the computers (master) and PPS clients on others
+(slaves), and use very simple cables to deliver signals using parallel
+ports, for example.
Parallel port cable pinout::
diff --git a/Documentation/driver-api/pwm.rst b/Documentation/driver-api/pwm.rst
index 3fdc95f7a1d1..bb264490a87a 100644
--- a/Documentation/driver-api/pwm.rst
+++ b/Documentation/driver-api/pwm.rst
@@ -111,13 +111,13 @@ channel that was exported. The following properties will then be available:
duty_cycle
The active time of the PWM signal (read/write).
- Value is in nanoseconds and must be less than the period.
+ Value is in nanoseconds and must be less than or equal to the period.
polarity
Changes the polarity of the PWM signal (read/write).
Writes to this property only work if the PWM chip supports changing
- the polarity. The polarity can only be changed if the PWM is not
- enabled. Value is the string "normal" or "inversed".
+ the polarity.
+ Value is the string "normal" or "inversed".
enable
Enable/disable the PWM signal (read/write).
diff --git a/Documentation/features/core/cBPF-JIT/arch-support.txt b/Documentation/features/core/cBPF-JIT/arch-support.txt
index 0a1f5bb7eeb9..937840080de7 100644
--- a/Documentation/features/core/cBPF-JIT/arch-support.txt
+++ b/Documentation/features/core/cBPF-JIT/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | TODO |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/core/eBPF-JIT/arch-support.txt b/Documentation/features/core/eBPF-JIT/arch-support.txt
index 6c0f3d759e6a..7434b43c2ff8 100644
--- a/Documentation/features/core/eBPF-JIT/arch-support.txt
+++ b/Documentation/features/core/eBPF-JIT/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/core/generic-idle-thread/arch-support.txt b/Documentation/features/core/generic-idle-thread/arch-support.txt
index 0b94099cf6ac..0735cb5367b4 100644
--- a/Documentation/features/core/generic-idle-thread/arch-support.txt
+++ b/Documentation/features/core/generic-idle-thread/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | ok |
- | ia64: | ok |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/core/jump-labels/arch-support.txt b/Documentation/features/core/jump-labels/arch-support.txt
index 94d9dece580f..ccada815569f 100644
--- a/Documentation/features/core/jump-labels/arch-support.txt
+++ b/Documentation/features/core/jump-labels/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/core/thread-info-in-task/arch-support.txt b/Documentation/features/core/thread-info-in-task/arch-support.txt
index 97c65ed2ac23..2afeb6bf6e64 100644
--- a/Documentation/features/core/thread-info-in-task/arch-support.txt
+++ b/Documentation/features/core/thread-info-in-task/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/core/tracehook/arch-support.txt b/Documentation/features/core/tracehook/arch-support.txt
index aed5679da651..a72330e25542 100644
--- a/Documentation/features/core/tracehook/arch-support.txt
+++ b/Documentation/features/core/tracehook/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | ok |
- | ia64: | ok |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/KASAN/arch-support.txt b/Documentation/features/debug/KASAN/arch-support.txt
index c4581c2edb28..39c6e78c0cbe 100644
--- a/Documentation/features/debug/KASAN/arch-support.txt
+++ b/Documentation/features/debug/KASAN/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
index 9ec5d13f4939..bbf029f095cb 100644
--- a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
+++ b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/gcov-profile-all/arch-support.txt b/Documentation/features/debug/gcov-profile-all/arch-support.txt
index dc4014f7e1f8..63494bddc263 100644
--- a/Documentation/features/debug/gcov-profile-all/arch-support.txt
+++ b/Documentation/features/debug/gcov-profile-all/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | ok |
diff --git a/Documentation/features/debug/kcov/arch-support.txt b/Documentation/features/debug/kcov/arch-support.txt
index de84cefbcdd3..4449e1f55cd8 100644
--- a/Documentation/features/debug/kcov/arch-support.txt
+++ b/Documentation/features/debug/kcov/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/kgdb/arch-support.txt b/Documentation/features/debug/kgdb/arch-support.txt
index 5e91ec78c80b..f287f16ce0ec 100644
--- a/Documentation/features/debug/kgdb/arch-support.txt
+++ b/Documentation/features/debug/kgdb/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | ok |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | ok |
diff --git a/Documentation/features/debug/kmemleak/arch-support.txt b/Documentation/features/debug/kmemleak/arch-support.txt
index 4e205ef70363..f45149cfa313 100644
--- a/Documentation/features/debug/kmemleak/arch-support.txt
+++ b/Documentation/features/debug/kmemleak/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | ok |
diff --git a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
index 38a0a54b79f5..02febc883588 100644
--- a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
+++ b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | TODO |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/kprobes/arch-support.txt b/Documentation/features/debug/kprobes/arch-support.txt
index aad83b57587a..1ea27aedd098 100644
--- a/Documentation/features/debug/kprobes/arch-support.txt
+++ b/Documentation/features/debug/kprobes/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | ok |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/kretprobes/arch-support.txt b/Documentation/features/debug/kretprobes/arch-support.txt
index 61380010a4a7..022be42e64f9 100644
--- a/Documentation/features/debug/kretprobes/arch-support.txt
+++ b/Documentation/features/debug/kretprobes/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | ok |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/optprobes/arch-support.txt b/Documentation/features/debug/optprobes/arch-support.txt
index 83a4639a5c0a..92f5d0f444fa 100644
--- a/Documentation/features/debug/optprobes/arch-support.txt
+++ b/Documentation/features/debug/optprobes/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | TODO |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/stackprotector/arch-support.txt b/Documentation/features/debug/stackprotector/arch-support.txt
index 4c64c5d596f7..de8f43f2e5d6 100644
--- a/Documentation/features/debug/stackprotector/arch-support.txt
+++ b/Documentation/features/debug/stackprotector/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/uprobes/arch-support.txt b/Documentation/features/debug/uprobes/arch-support.txt
index 24c8423b0abc..0c698003ce9c 100644
--- a/Documentation/features/debug/uprobes/arch-support.txt
+++ b/Documentation/features/debug/uprobes/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/debug/user-ret-profiler/arch-support.txt b/Documentation/features/debug/user-ret-profiler/arch-support.txt
index 059110a5fa6e..3e431767581d 100644
--- a/Documentation/features/debug/user-ret-profiler/arch-support.txt
+++ b/Documentation/features/debug/user-ret-profiler/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | TODO |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/io/dma-contiguous/arch-support.txt b/Documentation/features/io/dma-contiguous/arch-support.txt
index bfe0921a3853..3c6ce35d704f 100644
--- a/Documentation/features/io/dma-contiguous/arch-support.txt
+++ b/Documentation/features/io/dma-contiguous/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | ok |
diff --git a/Documentation/features/locking/cmpxchg-local/arch-support.txt b/Documentation/features/locking/cmpxchg-local/arch-support.txt
index 68329e96dffa..2c3a4b91f16d 100644
--- a/Documentation/features/locking/cmpxchg-local/arch-support.txt
+++ b/Documentation/features/locking/cmpxchg-local/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/locking/lockdep/arch-support.txt b/Documentation/features/locking/lockdep/arch-support.txt
index a36e231670d7..b6b00469f7d0 100644
--- a/Documentation/features/locking/lockdep/arch-support.txt
+++ b/Documentation/features/locking/lockdep/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | ok |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | ok |
diff --git a/Documentation/features/locking/queued-rwlocks/arch-support.txt b/Documentation/features/locking/queued-rwlocks/arch-support.txt
index 5deb845477e4..b286a5fff283 100644
--- a/Documentation/features/locking/queued-rwlocks/arch-support.txt
+++ b/Documentation/features/locking/queued-rwlocks/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/locking/queued-spinlocks/arch-support.txt b/Documentation/features/locking/queued-spinlocks/arch-support.txt
index 2d3961bfef5d..22f2990392ff 100644
--- a/Documentation/features/locking/queued-spinlocks/arch-support.txt
+++ b/Documentation/features/locking/queued-spinlocks/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/perf/kprobes-event/arch-support.txt b/Documentation/features/perf/kprobes-event/arch-support.txt
index 641a7d2ff2a3..713a69fcd697 100644
--- a/Documentation/features/perf/kprobes-event/arch-support.txt
+++ b/Documentation/features/perf/kprobes-event/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | ok |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/perf/perf-regs/arch-support.txt b/Documentation/features/perf/perf-regs/arch-support.txt
index 33866eb242c1..09431518b0e8 100644
--- a/Documentation/features/perf/perf-regs/arch-support.txt
+++ b/Documentation/features/perf/perf-regs/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/perf/perf-stackdump/arch-support.txt b/Documentation/features/perf/perf-stackdump/arch-support.txt
index c8e4c7c65012..f9db4dd8ef79 100644
--- a/Documentation/features/perf/perf-stackdump/arch-support.txt
+++ b/Documentation/features/perf/perf-stackdump/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/sched/membarrier-sync-core/arch-support.txt b/Documentation/features/sched/membarrier-sync-core/arch-support.txt
index 23260ca44946..d96b778b87ed 100644
--- a/Documentation/features/sched/membarrier-sync-core/arch-support.txt
+++ b/Documentation/features/sched/membarrier-sync-core/arch-support.txt
@@ -35,7 +35,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/sched/numa-balancing/arch-support.txt b/Documentation/features/sched/numa-balancing/arch-support.txt
index 532cc67cdf92..984601c7c479 100644
--- a/Documentation/features/sched/numa-balancing/arch-support.txt
+++ b/Documentation/features/sched/numa-balancing/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | .. |
| hexagon: | .. |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | .. |
| microblaze: | .. |
diff --git a/Documentation/features/seccomp/seccomp-filter/arch-support.txt b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
index 3a7237b989cd..13feb679649e 100644
--- a/Documentation/features/seccomp/seccomp-filter/arch-support.txt
+++ b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | ok |
| microblaze: | TODO |
diff --git a/Documentation/features/time/arch-tick-broadcast/arch-support.txt b/Documentation/features/time/arch-tick-broadcast/arch-support.txt
index 9bffac80019e..ccba965e8d07 100644
--- a/Documentation/features/time/arch-tick-broadcast/arch-support.txt
+++ b/Documentation/features/time/arch-tick-broadcast/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/time/clockevents/arch-support.txt b/Documentation/features/time/clockevents/arch-support.txt
index 625160048f68..4d4bfac52970 100644
--- a/Documentation/features/time/clockevents/arch-support.txt
+++ b/Documentation/features/time/clockevents/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | ok |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | ok |
diff --git a/Documentation/features/time/context-tracking/arch-support.txt b/Documentation/features/time/context-tracking/arch-support.txt
index 72bc5bad0348..891be9f61903 100644
--- a/Documentation/features/time/context-tracking/arch-support.txt
+++ b/Documentation/features/time/context-tracking/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/time/irq-time-acct/arch-support.txt b/Documentation/features/time/irq-time-acct/arch-support.txt
index ceb036610d09..3d10075a8a8a 100644
--- a/Documentation/features/time/irq-time-acct/arch-support.txt
+++ b/Documentation/features/time/irq-time-acct/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | .. |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/time/virt-cpuacct/arch-support.txt b/Documentation/features/time/virt-cpuacct/arch-support.txt
index c063dffd5261..21f11d47ef72 100644
--- a/Documentation/features/time/virt-cpuacct/arch-support.txt
+++ b/Documentation/features/time/virt-cpuacct/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | ok |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/vm/ELF-ASLR/arch-support.txt b/Documentation/features/vm/ELF-ASLR/arch-support.txt
index 47909c3dd602..57406c0d5353 100644
--- a/Documentation/features/vm/ELF-ASLR/arch-support.txt
+++ b/Documentation/features/vm/ELF-ASLR/arch-support.txt
@@ -13,7 +13,6 @@
| arm64: | ok |
| csky: | ok |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/vm/PG_uncached/arch-support.txt b/Documentation/features/vm/PG_uncached/arch-support.txt
index 5acd64b97dba..5a7508b8c967 100644
--- a/Documentation/features/vm/PG_uncached/arch-support.txt
+++ b/Documentation/features/vm/PG_uncached/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | TODO |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | ok |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/vm/THP/arch-support.txt b/Documentation/features/vm/THP/arch-support.txt
index 9dd7d75d0465..b4a5ce16940d 100644
--- a/Documentation/features/vm/THP/arch-support.txt
+++ b/Documentation/features/vm/THP/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | .. |
| hexagon: | .. |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | .. |
| microblaze: | .. |
diff --git a/Documentation/features/vm/TLB/arch-support.txt b/Documentation/features/vm/TLB/arch-support.txt
index 76208db88f3b..8fd22073a847 100644
--- a/Documentation/features/vm/TLB/arch-support.txt
+++ b/Documentation/features/vm/TLB/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | .. |
| microblaze: | .. |
diff --git a/Documentation/features/vm/huge-vmap/arch-support.txt b/Documentation/features/vm/huge-vmap/arch-support.txt
index 34647d9bdca4..2d6de7b04538 100644
--- a/Documentation/features/vm/huge-vmap/arch-support.txt
+++ b/Documentation/features/vm/huge-vmap/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | TODO |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/vm/ioremap_prot/arch-support.txt b/Documentation/features/vm/ioremap_prot/arch-support.txt
index a24149e59d73..1638c2cb17f1 100644
--- a/Documentation/features/vm/ioremap_prot/arch-support.txt
+++ b/Documentation/features/vm/ioremap_prot/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/features/vm/pte_special/arch-support.txt b/Documentation/features/vm/pte_special/arch-support.txt
index d2b22a06945e..3f777f8b67d5 100644
--- a/Documentation/features/vm/pte_special/arch-support.txt
+++ b/Documentation/features/vm/pte_special/arch-support.txt
@@ -12,7 +12,6 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
- | ia64: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst
index 2b59cff8be17..49ef12df631b 100644
--- a/Documentation/filesystems/proc.rst
+++ b/Documentation/filesystems/proc.rst
@@ -689,9 +689,15 @@ files are there, and which are missing.
File Content
============ ===============================================================
apm Advanced power management info
+ bootconfig Kernel command line obtained from boot config,
+ and, if there were kernel parameters from the
+ boot loader, a "# Parameters from bootloader:"
+ line followed by a line containing those
+ parameters prefixed by "# ". (5.5)
buddyinfo Kernel memory allocator information (see text) (2.5)
bus Directory containing bus specific information
- cmdline Kernel command line
+ cmdline Kernel command line, both from bootloader and embedded
+ in the kernel image
cpuinfo Info about the CPU
devices Available devices (block and character)
dma Used DMS channels
diff --git a/Documentation/filesystems/xfs-online-fsck-design.rst b/Documentation/filesystems/xfs-online-fsck-design.rst
index 1625d1131093..a0678101a7d0 100644
--- a/Documentation/filesystems/xfs-online-fsck-design.rst
+++ b/Documentation/filesystems/xfs-online-fsck-design.rst
@@ -1585,7 +1585,7 @@ The transaction sequence looks like this:
2. The second transaction contains a physical update to the free space btrees
of AG 3 to release the former BMBT block and a second physical update to the
free space btrees of AG 7 to release the unmapped file space.
- Observe that the the physical updates are resequenced in the correct order
+ Observe that the physical updates are resequenced in the correct order
when possible.
Attached to the transaction is a an extent free done (EFD) log item.
The EFD contains a pointer to the EFI logged in transaction #1 so that log
diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst
index e67eb261c9b0..47a29a36b12b 100644
--- a/Documentation/kbuild/makefiles.rst
+++ b/Documentation/kbuild/makefiles.rst
@@ -53,7 +53,7 @@ knowledge about the kernel Makefiles, plus detailed knowledge about the
public interface for kbuild.
*Arch developers* are people who work on an entire architecture, such
-as sparc or ia64. Arch developers need to know about the arch Makefile
+as sparc or x86. Arch developers need to know about the arch Makefile
as well as kbuild Makefiles.
*Kbuild developers* are people who work on the kernel build system itself.
diff --git a/Documentation/maintainer/maintainer-entry-profile.rst b/Documentation/maintainer/maintainer-entry-profile.rst
index 6b64072d4bf2..7ad4bfc2cc03 100644
--- a/Documentation/maintainer/maintainer-entry-profile.rst
+++ b/Documentation/maintainer/maintainer-entry-profile.rst
@@ -101,7 +101,7 @@ to do something different in the near future.
../doc-guide/maintainer-profile
../nvdimm/maintainer-entry-profile
- ../riscv/patch-acceptance
+ ../arch/riscv/patch-acceptance
../driver-api/media/maintainer-entry-profile
../driver-api/vfio-pci-device-specific-driver-acceptance
../nvme/feature-and-quirk-policy
diff --git a/Documentation/mm/overcommit-accounting.rst b/Documentation/mm/overcommit-accounting.rst
index a4895d6fc1c2..e2263477f6d5 100644
--- a/Documentation/mm/overcommit-accounting.rst
+++ b/Documentation/mm/overcommit-accounting.rst
@@ -8,8 +8,7 @@ The Linux kernel supports the following overcommit handling modes
Heuristic overcommit handling. Obvious overcommits of address
space are refused. Used for a typical system. It ensures a
seriously wild allocation fails while allowing overcommit to
- reduce swap usage. root is allowed to allocate slightly more
- memory in this mode. This is the default.
+ reduce swap usage. This is the default.
1
Always overcommit. Appropriate for some scientific
diff --git a/Documentation/mm/page_tables.rst b/Documentation/mm/page_tables.rst
index 7840c1891751..be47b192a596 100644
--- a/Documentation/mm/page_tables.rst
+++ b/Documentation/mm/page_tables.rst
@@ -152,3 +152,130 @@ Page table handling code that wishes to be architecture-neutral, such as the
virtual memory manager, will need to be written so that it traverses all of the
currently five levels. This style should also be preferred for
architecture-specific code, so as to be robust to future changes.
+
+
+MMU, TLB, and Page Faults
+=========================
+
+The `Memory Management Unit (MMU)` is a hardware component that handles virtual
+to physical address translations. It may use relatively small caches in hardware
+called `Translation Lookaside Buffers (TLBs)` and `Page Walk Caches` to speed up
+these translations.
+
+When CPU accesses a memory location, it provides a virtual address to the MMU,
+which checks if there is the existing translation in the TLB or in the Page
+Walk Caches (on architectures that support them). If no translation is found,
+MMU uses the page walks to determine the physical address and create the map.
+
+The dirty bit for a page is set (i.e., turned on) when the page is written to.
+Each page of memory has associated permission and dirty bits. The latter
+indicate that the page has been modified since it was loaded into memory.
+
+If nothing prevents it, eventually the physical memory can be accessed and the
+requested operation on the physical frame is performed.
+
+There are several reasons why the MMU can't find certain translations. It could
+happen because the CPU is trying to access memory that the current task is not
+permitted to, or because the data is not present into physical memory.
+
+When these conditions happen, the MMU triggers page faults, which are types of
+exceptions that signal the CPU to pause the current execution and run a special
+function to handle the mentioned exceptions.
+
+There are common and expected causes of page faults. These are triggered by
+process management optimization techniques called "Lazy Allocation" and
+"Copy-on-Write". Page faults may also happen when frames have been swapped out
+to persistent storage (swap partition or file) and evicted from their physical
+locations.
+
+These techniques improve memory efficiency, reduce latency, and minimize space
+occupation. This document won't go deeper into the details of "Lazy Allocation"
+and "Copy-on-Write" because these subjects are out of scope as they belong to
+Process Address Management.
+
+Swapping differentiates itself from the other mentioned techniques because it's
+undesirable since it's performed as a means to reduce memory under heavy
+pressure.
+
+Swapping can't work for memory mapped by kernel logical addresses. These are a
+subset of the kernel virtual space that directly maps a contiguous range of
+physical memory. Given any logical address, its physical address is determined
+with simple arithmetic on an offset. Accesses to logical addresses are fast
+because they avoid the need for complex page table lookups at the expenses of
+frames not being evictable and pageable out.
+
+If the kernel fails to make room for the data that must be present in the
+physical frames, the kernel invokes the out-of-memory (OOM) killer to make room
+by terminating lower priority processes until pressure reduces under a safe
+threshold.
+
+Additionally, page faults may be also caused by code bugs or by maliciously
+crafted addresses that the CPU is instructed to access. A thread of a process
+could use instructions to address (non-shared) memory which does not belong to
+its own address space, or could try to execute an instruction that want to write
+to a read-only location.
+
+If the above-mentioned conditions happen in user-space, the kernel sends a
+`Segmentation Fault` (SIGSEGV) signal to the current thread. That signal usually
+causes the termination of the thread and of the process it belongs to.
+
+This document is going to simplify and show an high altitude view of how the
+Linux kernel handles these page faults, creates tables and tables' entries,
+check if memory is present and, if not, requests to load data from persistent
+storage or from other devices, and updates the MMU and its caches.
+
+The first steps are architecture dependent. Most architectures jump to
+`do_page_fault()`, whereas the x86 interrupt handler is defined by the
+`DEFINE_IDTENTRY_RAW_ERRORCODE()` macro which calls `handle_page_fault()`.
+
+Whatever the routes, all architectures end up to the invocation of
+`handle_mm_fault()` which, in turn, (likely) ends up calling
+`__handle_mm_fault()` to carry out the actual work of allocating the page
+tables.
+
+The unfortunate case of not being able to call `__handle_mm_fault()` means
+that the virtual address is pointing to areas of physical memory which are not
+permitted to be accessed (at least from the current context). This
+condition resolves to the kernel sending the above-mentioned SIGSEGV signal
+to the process and leads to the consequences already explained.
+
+`__handle_mm_fault()` carries out its work by calling several functions to
+find the entry's offsets of the upper layers of the page tables and allocate
+the tables that it may need.
+
+The functions that look for the offset have names like `*_offset()`, where the
+"*" is for pgd, p4d, pud, pmd, pte; instead the functions to allocate the
+corresponding tables, layer by layer, are called `*_alloc`, using the
+above-mentioned convention to name them after the corresponding types of tables
+in the hierarchy.
+
+The page table walk may end at one of the middle or upper layers (PMD, PUD).
+
+Linux supports larger page sizes than the usual 4KB (i.e., the so called
+`huge pages`). When using these kinds of larger pages, higher level pages can
+directly map them, with no need to use lower level page entries (PTE). Huge
+pages contain large contiguous physical regions that usually span from 2MB to
+1GB. They are respectively mapped by the PMD and PUD page entries.
+
+The huge pages bring with them several benefits like reduced TLB pressure,
+reduced page table overhead, memory allocation efficiency, and performance
+improvement for certain workloads. However, these benefits come with
+trade-offs, like wasted memory and allocation challenges.
+
+At the very end of the walk with allocations, if it didn't return errors,
+`__handle_mm_fault()` finally calls `handle_pte_fault()`, which via `do_fault()`
+performs one of `do_read_fault()`, `do_cow_fault()`, `do_shared_fault()`.
+"read", "cow", "shared" give hints about the reasons and the kind of fault it's
+handling.
+
+The actual implementation of the workflow is very complex. Its design allows
+Linux to handle page faults in a way that is tailored to the specific
+characteristics of each architecture, while still sharing a common overall
+structure.
+
+To conclude this high altitude view of how Linux handles page faults, let's
+add that the page faults handler can be disabled and enabled respectively with
+`pagefault_disable()` and `pagefault_enable()`.
+
+Several code path make use of the latter two functions because they need to
+disable traps into the page faults handler, mostly to prevent deadlocks.
diff --git a/Documentation/mm/vmemmap_dedup.rst b/Documentation/mm/vmemmap_dedup.rst
index 59891f72420e..593ede6d314b 100644
--- a/Documentation/mm/vmemmap_dedup.rst
+++ b/Documentation/mm/vmemmap_dedup.rst
@@ -211,7 +211,7 @@ the device (altmap).
The following page sizes are supported in DAX: PAGE_SIZE (4K on x86_64),
PMD_SIZE (2M on x86_64) and PUD_SIZE (1G on x86_64).
-For powerpc equivalent details see Documentation/powerpc/vmemmap_dedup.rst
+For powerpc equivalent details see Documentation/arch/powerpc/vmemmap_dedup.rst
The differences with HugeTLB are relatively minor.
diff --git a/Documentation/networking/device_drivers/ethernet/neterion/s2io.rst b/Documentation/networking/device_drivers/ethernet/neterion/s2io.rst
index c5673ec4559b..d731b5a98561 100644
--- a/Documentation/networking/device_drivers/ethernet/neterion/s2io.rst
+++ b/Documentation/networking/device_drivers/ethernet/neterion/s2io.rst
@@ -64,8 +64,8 @@ c. Multi-buffer receive mode. Scattering of packet across multiple
IBM xSeries).
d. MSI/MSI-X. Can be enabled on platforms which support this feature
- (IA64, Xeon) resulting in noticeable performance improvement(up to 7%
- on certain platforms).
+ resulting in noticeable performance improvement (up to 7% on certain
+ platforms).
e. Statistics. Comprehensive MAC-level and software statistics displayed
using "ethtool -S" option.
diff --git a/Documentation/process/backporting.rst b/Documentation/process/backporting.rst
new file mode 100644
index 000000000000..e1a6ea0a1e8a
--- /dev/null
+++ b/Documentation/process/backporting.rst
@@ -0,0 +1,604 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================================
+Backporting and conflict resolution
+===================================
+
+:Author: Vegard Nossum <vegard.nossum@oracle.com>
+
+.. contents::
+ :local:
+ :depth: 3
+ :backlinks: none
+
+Introduction
+============
+
+Some developers may never really have to deal with backporting patches,
+merging branches, or resolving conflicts in their day-to-day work, so
+when a merge conflict does pop up, it can be daunting. Luckily,
+resolving conflicts is a skill like any other, and there are many useful
+techniques you can use to make the process smoother and increase your
+confidence in the result.
+
+This document aims to be a comprehensive, step-by-step guide to
+backporting and conflict resolution.
+
+Applying the patch to a tree
+============================
+
+Sometimes the patch you are backporting already exists as a git commit,
+in which case you just cherry-pick it directly using
+``git cherry-pick``. However, if the patch comes from an email, as it
+often does for the Linux kernel, you will need to apply it to a tree
+using ``git am``.
+
+If you've ever used ``git am``, you probably already know that it is
+quite picky about the patch applying perfectly to your source tree. In
+fact, you've probably had nightmares about ``.rej`` files and trying to
+edit the patch to make it apply.
+
+It is strongly recommended to instead find an appropriate base version
+where the patch applies cleanly and *then* cherry-pick it over to your
+destination tree, as this will make git output conflict markers and let
+you resolve conflicts with the help of git and any other conflict
+resolution tools you might prefer to use. For example, if you want to
+apply a patch that just arrived on LKML to an older stable kernel, you
+can apply it to the most recent mainline kernel and then cherry-pick it
+to your older stable branch.
+
+It's generally better to use the exact same base as the one the patch
+was generated from, but it doesn't really matter that much as long as it
+applies cleanly and isn't too far from the original base. The only
+problem with applying the patch to the "wrong" base is that it may pull
+in more unrelated changes in the context of the diff when cherry-picking
+it to the older branch.
+
+A good reason to prefer ``git cherry-pick`` over ``git am`` is that git
+knows the precise history of an existing commit, so it will know when
+code has moved around and changed the line numbers; this in turn makes
+it less likely to apply the patch to the wrong place (which can result
+in silent mistakes or messy conflicts).
+
+If you are using `b4`_. and you are applying the patch directly from an
+email, you can use ``b4 am`` with the options ``-g``/``--guess-base``
+and ``-3``/``--prep-3way`` to do some of this automatically (see the
+`b4 presentation`_ for more information). However, the rest of this
+article will assume that you are doing a plain ``git cherry-pick``.
+
+.. _b4: https://people.kernel.org/monsieuricon/introducing-b4-and-patch-attestation
+.. _b4 presentation: https://youtu.be/mF10hgVIx9o?t=2996
+
+Once you have the patch in git, you can go ahead and cherry-pick it into
+your source tree. Don't forget to cherry-pick with ``-x`` if you want a
+written record of where the patch came from!
+
+Note that if you are submiting a patch for stable, the format is
+slightly different; the first line after the subject line needs tobe
+either::
+
+ commit <upstream commit> upstream
+
+or::
+
+ [ Upstream commit <upstream commit> ]
+
+Resolving conflicts
+===================
+
+Uh-oh; the cherry-pick failed with a vaguely threatening message::
+
+ CONFLICT (content): Merge conflict
+
+What to do now?
+
+In general, conflicts appear when the context of the patch (i.e., the
+lines being changed and/or the lines surrounding the changes) doesn't
+match what's in the tree you are trying to apply the patch *to*.
+
+For backports, what likely happened was that the branch you are
+backporting from contains patches not in the branch you are backporting
+to. However, the reverse is also possible. In any case, the result is a
+conflict that needs to be resolved.
+
+If your attempted cherry-pick fails with a conflict, git automatically
+edits the files to include so-called conflict markers showing you where
+the conflict is and how the two branches have diverged. Resolving the
+conflict typically means editing the end result in such a way that it
+takes into account these other commits.
+
+Resolving the conflict can be done either by hand in a regular text
+editor or using a dedicated conflict resolution tool.
+
+Many people prefer to use their regular text editor and edit the
+conflict directly, as it may be easier to understand what you're doing
+and to control the final result. There are definitely pros and cons to
+each method, and sometimes there's value in using both.
+
+We will not cover using dedicated merge tools here beyond providing some
+pointers to various tools that you could use:
+
+- `Emacs Ediff mode <https://www.emacswiki.org/emacs/EdiffMode>`__
+- `vimdiff/gvimdiff <https://linux.die.net/man/1/vimdiff>`__
+- `KDiff3 <http://kdiff3.sourceforge.net/>`__
+- `TortoiseMerge <https://tortoisesvn.net/TortoiseMerge.html>`__
+- `Meld <https://meldmerge.org/help/>`__
+- `P4Merge <https://www.perforce.com/products/helix-core-apps/merge-diff-tool-p4merge>`__
+- `Beyond Compare <https://www.scootersoftware.com/>`__
+- `IntelliJ <https://www.jetbrains.com/help/idea/resolve-conflicts.html>`__
+- `VSCode <https://code.visualstudio.com/docs/editor/versioncontrol>`__
+
+To configure git to work with these, see ``git mergetool --help`` or
+the official `git-mergetool documentation`_.
+
+.. _git-mergetool documentation: https://git-scm.com/docs/git-mergetool
+
+Prerequisite patches
+--------------------
+
+Most conflicts happen because the branch you are backporting to is
+missing some patches compared to the branch you are backporting *from*.
+In the more general case (such as merging two independent branches),
+development could have happened on either branch, or the branches have
+simply diverged -- perhaps your older branch had some other backports
+applied to it that themselves needed conflict resolutions, causing a
+divergence.
+
+It's important to always identify the commit or commits that caused the
+conflict, as otherwise you cannot be confident in the correctness of
+your resolution. As an added bonus, especially if the patch is in an
+area you're not that famliar with, the changelogs of these commits will
+often give you the context to understand the code and potential problems
+or pitfalls with your conflict resolution.
+
+git log
+~~~~~~~
+
+A good first step is to look at ``git log`` for the file that has the
+conflict -- this is usually sufficient when there aren't a lot of
+patches to the file, but may get confusing if the file is big and
+frequently patched. You should run ``git log`` on the range of commits
+between your currently checked-out branch (``HEAD``) and the parent of
+the patch you are picking (``<commit>``), i.e.::
+
+ git log HEAD..<commit>^ -- <path>
+
+Even better, if you want to restrict this output to a single function
+(because that's where the conflict appears), you can use the following
+syntax::
+
+ git log -L:'\<function\>':<path> HEAD..<commit>^
+
+.. note::
+ The ``\<`` and ``\>`` around the function name ensure that the
+ matches are anchored on a word boundary. This is important, as this
+ part is actually a regex and git only follows the first match, so
+ if you use ``-L:thread_stack:kernel/fork.c`` it may only give you
+ results for the function ``try_release_thread_stack_to_cache`` even
+ though there are many other functions in that file containing the
+ string ``thread_stack`` in their names.
+
+Another useful option for ``git log`` is ``-G``, which allows you to
+filter on certain strings appearing in the diffs of the commits you are
+listing::
+
+ git log -G'regex' HEAD..<commit>^ -- <path>
+
+This can also be a handy way to quickly find when something (e.g. a
+function call or a variable) was changed, added, or removed. The search
+string is a regular expression, which means you can potentially search
+for more specific things like assignments to a specific struct member::
+
+ git log -G'\->index\>.*='
+
+git blame
+~~~~~~~~~
+
+Another way to find prerequisite commits (albeit only the most recent
+one for a given conflict) is to run ``git blame``. In this case, you
+need to run it against the parent commit of the patch you are
+cherry-picking and the file where the conflict appared, i.e.::
+
+ git blame <commit>^ -- <path>
+
+This command also accepts the ``-L`` argument (for restricting the
+output to a single function), but in this case you specify the filename
+at the end of the command as usual::
+
+ git blame -L:'\<function\>' <commit>^ -- <path>
+
+Navigate to the place where the conflict occurred. The first column of
+the blame output is the commit ID of the patch that added a given line
+of code.
+
+It might be a good idea to ``git show`` these commits and see if they
+look like they might be the source of the conflict. Sometimes there will
+be more than one of these commits, either because multiple commits
+changed different lines of the same conflict area *or* because multiple
+subsequent patches changed the same line (or lines) multiple times. In
+the latter case, you may have to run ``git blame`` again and specify the
+older version of the file to look at in order to dig further back in
+the history of the file.
+
+Prerequisite vs. incidental patches
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Having found the patch that caused the conflict, you need to determine
+whether it is a prerequisite for the patch you are backporting or
+whether it is just incidental and can be skipped. An incidental patch
+would be one that touches the same code as the patch you are
+backporting, but does not change the semantics of the code in any
+material way. For example, a whitespace cleanup patch is completely
+incidental -- likewise, a patch that simply renames a function or a
+variable would be incidental as well. On the other hand, if the function
+being changed does not even exist in your current branch then this would
+not be incidental at all and you need to carefully consider whether the
+patch adding the function should be cherry-picked first.
+
+If you find that there is a necessary prerequisite patch, then you need
+to stop and cherry-pick that instead. If you've already resolved some
+conflicts in a different file and don't want to do it again, you can
+create a temporary copy of that file.
+
+To abort the current cherry-pick, go ahead and run
+``git cherry-pick --abort``, then restart the cherry-picking process
+with the commit ID of the prerequisite patch instead.
+
+Understanding conflict markers
+------------------------------
+
+Combined diffs
+~~~~~~~~~~~~~~
+
+Let's say you've decided against picking (or reverting) additional
+patches and you just want to resolve the conflict. Git will have
+inserted conflict markers into your file. Out of the box, this will look
+something like::
+
+ <<<<<<< HEAD
+ this is what's in your current tree before cherry-picking
+ =======
+ this is what the patch wants it to be after cherry-picking
+ >>>>>>> <commit>... title
+
+This is what you would see if you opened the file in your editor.
+However, if you were to run ``git diff`` without any arguments, the
+output would look something like this::
+
+ $ git diff
+ [...]
+ ++<<<<<<<< HEAD
+ +this is what's in your current tree before cherry-picking
+ ++========
+ + this is what the patch wants it to be after cherry-picking
+ ++>>>>>>>> <commit>... title
+
+When you are resolving a conflict, the behavior of ``git diff`` differs
+from its normal behavior. Notice the two columns of diff markers
+instead of the usual one; this is a so-called "`combined diff`_", here
+showing the 3-way diff (or diff-of-diffs) between
+
+#. the current branch (before cherry-picking) and the current working
+ directory, and
+#. the current branch (before cherry-picking) and the file as it looks
+ after the original patch has been applied.
+
+.. _combined diff: https://git-scm.com/docs/diff-format#_combined_diff_format
+
+
+Better diffs
+~~~~~~~~~~~~
+
+3-way combined diffs include all the other changes that happened to the
+file between your current branch and the branch you are cherry-picking
+from. While this is useful for spotting other changes that you need to
+take into account, this also makes the output of ``git diff`` somewhat
+intimidating and difficult to read. You may instead prefer to run
+``git diff HEAD`` (or ``git diff --ours``) which shows only the diff
+between the current branch before cherry-picking and the current working
+directory. It looks like this::
+
+ $ git diff HEAD
+ [...]
+ +<<<<<<<< HEAD
+ this is what's in your current tree before cherry-picking
+ +========
+ +this is what the patch wants it to be after cherry-picking
+ +>>>>>>>> <commit>... title
+
+As you can see, this reads just like any other diff and makes it clear
+which lines are in the current branch and which lines are being added
+because they are part of the merge conflict or the patch being
+cherry-picked.
+
+Merge styles and diff3
+~~~~~~~~~~~~~~~~~~~~~~
+
+The default conflict marker style shown above is known as the ``merge``
+style. There is also another style available, known as the ``diff3``
+style, which looks like this::
+
+ <<<<<<< HEAD
+ this is what is in your current tree before cherry-picking
+ ||||||| parent of <commit> (title)
+ this is what the patch expected to find there
+ =======
+ this is what the patch wants it to be after being applied
+ >>>>>>> <commit> (title)
+
+As you can see, this has 3 parts instead of 2, and includes what git
+expected to find there but didn't. It is *highly recommended* to use
+this conflict style as it makes it much clearer what the patch actually
+changed; i.e., it allows you to compare the before-and-after versions
+of the file for the commit you are cherry-picking. This allows you to
+make better decisions about how to resolve the conflict.
+
+To change conflict marker styles, you can use the following command::
+
+ git config merge.conflictStyle diff3
+
+There is a third option, ``zdiff3``, introduced in `Git 2.35`_,
+which has the same 3 sections as ``diff3``, but where common lines have
+been trimmed off, making the conflict area smaller in some cases.
+
+.. _Git 2.35: https://github.blog/2022-01-24-highlights-from-git-2-35/
+
+Iterating on conflict resolutions
+---------------------------------
+
+The first step in any conflict resolution process is to understand the
+patch you are backporting. For the Linux kernel this is especially
+important, since an incorrect change can lead to the whole system
+crashing -- or worse, an undetected security vulnerability.
+
+Understanding the patch can be easy or difficult depending on the patch
+itself, the changelog, and your familiarity with the code being changed.
+However, a good question for every change (or every hunk of the patch)
+might be: "Why is this hunk in the patch?" The answers to these
+questions will inform your conflict resolution.
+
+Resolution process
+~~~~~~~~~~~~~~~~~~
+
+Sometimes the easiest thing to do is to just remove all but the first
+part of the conflict, leaving the file essentially unchanged, and apply
+the changes by hand. Perhaps the patch is changing a function call
+argument from ``0`` to ``1`` while a conflicting change added an
+entirely new (and insignificant) parameter to the end of the parameter
+list; in that case, it's easy enough to change the argument from ``0``
+to ``1`` by hand and leave the rest of the arguments alone. This
+technique of manually applying changes is mostly useful if the conflict
+pulled in a lot of unrelated context that you don't really need to care
+about.
+
+For particularly nasty conflicts with many conflict markers, you can use
+``git add`` or ``git add -i`` to selectively stage your resolutions to
+get them out of the way; this also lets you use ``git diff HEAD`` to
+always see what remains to be resolved or ``git diff --cached`` to see
+what your patch looks like so far.
+
+Dealing with file renames
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One of the most annoying things that can happen while backporting a
+patch is discovering that one of the files being patched has been
+renamed, as that typically means git won't even put in conflict markers,
+but will just throw up its hands and say (paraphrased): "Unmerged path!
+You do the work..."
+
+There are generally a few ways to deal with this. If the patch to the
+renamed file is small, like a one-line change, the easiest thing is to
+just go ahead and apply the change by hand and be done with it. On the
+other hand, if the change is big or complicated, you definitely don't
+want to do it by hand.
+
+As a first pass, you can try something like this, which will lower the
+rename detection threshold to 30% (by default, git uses 50%, meaning
+that two files need to have at least 50% in common for it to consider
+an add-delete pair to be a potential rename)::
+
+ git cherry-pick -strategy=recursive -Xrename-threshold=30
+
+Sometimes the right thing to do will be to also backport the patch that
+did the rename, but that's definitely not the most common case. Instead,
+what you can do is to temporarily rename the file in the branch you're
+backporting to (using ``git mv`` and committing the result), restart the
+attempt to cherry-pick the patch, rename the file back (``git mv`` and
+committing again), and finally squash the result using ``git rebase -i``
+(see the `rebase tutorial`_) so it appears as a single commit when you
+are done.
+
+.. _rebase tutorial: https://medium.com/@slamflipstrom/a-beginners-guide-to-squashing-commits-with-git-rebase-8185cf6e62ec
+
+Gotchas
+-------
+
+Function arguments
+~~~~~~~~~~~~~~~~~~
+
+Pay attention to changing function arguments! It's easy to gloss over
+details and think that two lines are the same but actually they differ
+in some small detail like which variable was passed as an argument
+(especially if the two variables are both a single character that look
+the same, like i and j).
+
+Error handling
+~~~~~~~~~~~~~~
+
+If you cherry-pick a patch that includes a ``goto`` statement (typically
+for error handling), it is absolutely imperative to double check that
+the target label is still correct in the branch you are backporting to.
+The same goes for added ``return``, ``break``, and ``continue``
+statements.
+
+Error handling is typically located at the bottom of the function, so it
+may not be part of the conflict even though could have been changed by
+other patches.
+
+A good way to ensure that you review the error paths is to always use
+``git diff -W`` and ``git show -W`` (AKA ``--function-context``) when
+inspecting your changes. For C code, this will show you the whole
+function that's being changed in a patch. One of the things that often
+go wrong during backports is that something else in the function changed
+on either of the branches that you're backporting from or to. By
+including the whole function in the diff you get more context and can
+more easily spot problems that might otherwise go unnoticed.
+
+Refactored code
+~~~~~~~~~~~~~~~
+
+Something that happens quite often is that code gets refactored by
+"factoring out" a common code sequence or pattern into a helper
+function. When backporting patches to an area where such a refactoring
+has taken place, you effectively need to do the reverse when
+backporting: a patch to a single location may need to be applied to
+multiple locations in the backported version. (One giveaway for this
+scenario is that a function was renamed -- but that's not always the
+case.)
+
+To avoid incomplete backports, it's worth trying to figure out if the
+patch fixes a bug that appears in more than one place. One way to do
+this would be to use ``git grep``. (This is actually a good idea to do
+in general, not just for backports.) If you do find that the same kind
+of fix would apply to other places, it's also worth seeing if those
+places exist upstream -- if they don't, it's likely the patch may need
+to be adjusted. ``git log`` is your friend to figure out what happened
+to these areas as ``git blame`` won't show you code that has been
+removed.
+
+If you do find other instances of the same pattern in the upstream tree
+and you're not sure whether it's also a bug, it may be worth asking the
+patch author. It's not uncommon to find new bugs during backporting!
+
+Verifying the result
+====================
+
+colordiff
+---------
+
+Having committed a conflict-free new patch, you can now compare your
+patch to the original patch. It is highly recommended that you use a
+tool such as `colordiff`_ that can show two files side by side and color
+them according to the changes between them::
+
+ colordiff -yw -W 200 <(git diff -W <upstream commit>^-) <(git diff -W HEAD^-) | less -SR
+
+.. _colordiff: https://www.colordiff.org/
+
+Here, ``-y`` means to do a side-by-side comparison; ``-w`` ignores
+whitespace, and ``-W 200`` sets the width of the output (as otherwise it
+will use 130 by default, which is often a bit too little).
+
+The ``rev^-`` syntax is a handy shorthand for ``rev^..rev``, essentially
+giving you just the diff for that single commit; also see
+the official `git rev-parse documentation`_.
+
+.. _git rev-parse documentation: https://git-scm.com/docs/git-rev-parse#_other_rev_parent_shorthand_notations
+
+Again, note the inclusion of ``-W`` for ``git diff``; this ensures that
+you will see the full function for any function that has changed.
+
+One incredibly important thing that colordiff does is to highlight lines
+that are different. For example, if an error-handling ``goto`` has
+changed labels between the original and backported patch, colordiff will
+show these side-by-side but highlighted in a different color. Thus, it
+is easy to see that the two ``goto`` statements are jumping to different
+labels. Likewise, lines that were not modified by either patch but
+differ in the context will also be highlighted and thus stand out during
+a manual inspection.
+
+Of course, this is just a visual inspection; the real test is building
+and running the patched kernel (or program).
+
+Build testing
+-------------
+
+We won't cover runtime testing here, but it can be a good idea to build
+just the files touched by the patch as a quick sanity check. For the
+Linux kernel you can build single files like this, assuming you have the
+``.config`` and build environment set up correctly::
+
+ make path/to/file.o
+
+Note that this won't discover linker errors, so you should still do a
+full build after verifying that the single file compiles. By compiling
+the single file first you can avoid having to wait for a full build *in
+case* there are compiler errors in any of the files you've changed.
+
+Runtime testing
+---------------
+
+Even a successful build or boot test is not necessarily enough to rule
+out a missing dependency somewhere. Even though the chances are small,
+there could be code changes where two independent changes to the same
+file result in no conflicts, no compile-time errors, and runtime errors
+only in exceptional cases.
+
+One concrete example of this was a pair of patches to the system call
+entry code where the first patch saved/restored a register and a later
+patch made use of the same register somewhere in the middle of this
+sequence. Since there was no overlap between the changes, one could
+cherry-pick the second patch, have no conflicts, and believe that
+everything was fine, when in fact the code was now scribbling over an
+unsaved register.
+
+Although the vast majority of errors will be caught during compilation
+or by superficially exercising the code, the only way to *really* verify
+a backport is to review the final patch with the same level of scrutiny
+as you would (or should) give to any other patch. Having unit tests and
+regression tests or other types of automatic testing can help increase
+the confidence in the correctness of a backport.
+
+Submitting backports to stable
+==============================
+
+As the stable maintainers try to cherry-pick mainline fixes onto their
+stable kernels, they may send out emails asking for backports when when
+encountering conflicts, see e.g.
+<https://lore.kernel.org/stable/2023101528-jawed-shelving-071a@gregkh/>.
+These emails typically include the exact steps you need to cherry-pick
+the patch to the correct tree and submit the patch.
+
+One thing to make sure is that your changelog conforms to the expected
+format::
+
+ <original patch title>
+
+ [ Upstream commit <mainline rev> ]
+
+ <rest of the original changelog>
+ [ <summary of the conflicts and their resolutions> ]
+ Signed-off-by: <your name and email>
+
+The "Upstream commit" line is sometimes slightly different depending on
+the stable version. Older version used this format::
+
+ commit <mainline rev> upstream.
+
+It is most common to indicate the kernel version the patch applies to
+in the email subject line (using e.g.
+``git send-email --subject-prefix='PATCH 6.1.y'``), but you can also put
+it in the Signed-off-by:-area or below the ``---`` line.
+
+The stable maintainers expect separate submissions for each active
+stable version, and each submission should also be tested separately.
+
+A few final words of advice
+===========================
+
+1) Approach the backporting process with humility.
+2) Understand the patch you are backporting; this means reading both
+ the changelog and the code.
+3) Be honest about your confidence in the result when submitting the
+ patch.
+4) Ask relevant maintainers for explicit acks.
+
+Examples
+========
+
+The above shows roughly the idealized process of backporting a patch.
+For a more concrete example, see this video tutorial where two patches
+are backported from mainline to stable:
+`Backporting Linux Kernel Patches`_.
+
+.. _Backporting Linux Kernel Patches: https://youtu.be/sBR7R1V2FeA
diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst
index b501cd977053..a1daa309b58d 100644
--- a/Documentation/process/index.rst
+++ b/Documentation/process/index.rst
@@ -66,12 +66,13 @@ lack of a better place.
:maxdepth: 1
applying-patches
+ backporting
adding-syscalls
magic-number
volatile-considered-harmful
botching-up-ioctls
clang-format
- ../riscv/patch-acceptance
+ ../arch/riscv/patch-acceptance
../core-api/unaligned-memory-access
.. only:: subproject and html
diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst
index efac910e2659..86d346bcb8ef 100644
--- a/Documentation/process/submitting-patches.rst
+++ b/Documentation/process/submitting-patches.rst
@@ -327,6 +327,8 @@ politely and address the problems they have pointed out. When sending a next
version, add a ``patch changelog`` to the cover letter or to individual patches
explaining difference against previous submission (see
:ref:`the_canonical_patch_format`).
+Notify people that commented on your patch about new versions by adding them to
+the patches CC list.
See Documentation/process/email-clients.rst for recommendations on email
clients and mailing list etiquette.
@@ -366,10 +368,10 @@ busy people and may not get to your patch right away.
Once upon a time, patches used to disappear into the void without comment,
but the development process works more smoothly than that now. You should
-receive comments within a week or so; if that does not happen, make sure
-that you have sent your patches to the right place. Wait for a minimum of
-one week before resubmitting or pinging reviewers - possibly longer during
-busy times like merge windows.
+receive comments within a few weeks (typically 2-3); if that does not
+happen, make sure that you have sent your patches to the right place.
+Wait for a minimum of one week before resubmitting or pinging reviewers
+- possibly longer during busy times like merge windows.
It's also ok to resend the patch or the patch series after a couple of
weeks with the word "RESEND" added to the subject line::
diff --git a/Documentation/scheduler/sched-arch.rst b/Documentation/scheduler/sched-arch.rst
index 505cd27f9a92..ed07efea7d02 100644
--- a/Documentation/scheduler/sched-arch.rst
+++ b/Documentation/scheduler/sched-arch.rst
@@ -10,7 +10,7 @@ Context switch
By default, the switch_to arch function is called with the runqueue
locked. This is usually not a problem unless switch_to may need to
take the runqueue lock. This is usually due to a wake up operation in
-the context switch. See arch/ia64/include/asm/switch_to.h for an example.
+the context switch.
To request the scheduler call switch_to with the runqueue unlocked,
you must `#define __ARCH_WANT_UNLOCKED_CTXSW` in a header file
@@ -68,7 +68,5 @@ Possible arch/ problems
Possible arch problems I found (and either tried to fix or didn't):
-ia64 - is safe_halt call racy vs interrupts? (does it sleep?) (See #4a)
-
sparc - IRQs on at this point(?), change local_irq_save to _disable.
- TODO: needs secondary CPUs to disable preempt (See #1)
diff --git a/Documentation/security/index.rst b/Documentation/security/index.rst
index 6ed8d2fa6f9e..59f8fc106cb0 100644
--- a/Documentation/security/index.rst
+++ b/Documentation/security/index.rst
@@ -6,6 +6,7 @@ Security Documentation
:maxdepth: 1
credentials
+ snp-tdx-threat-model
IMA-templates
keys/index
lsm
diff --git a/Documentation/security/snp-tdx-threat-model.rst b/Documentation/security/snp-tdx-threat-model.rst
new file mode 100644
index 000000000000..ec66f2ed80c9
--- /dev/null
+++ b/Documentation/security/snp-tdx-threat-model.rst
@@ -0,0 +1,253 @@
+======================================================
+Confidential Computing in Linux for x86 virtualization
+======================================================
+
+.. contents:: :local:
+
+By: Elena Reshetova <elena.reshetova@intel.com> and Carlos Bilbao <carlos.bilbao@amd.com>
+
+Motivation
+==========
+
+Kernel developers working on confidential computing for virtualized
+environments in x86 operate under a set of assumptions regarding the Linux
+kernel threat model that differ from the traditional view. Historically,
+the Linux threat model acknowledges attackers residing in userspace, as
+well as a limited set of external attackers that are able to interact with
+the kernel through various networking or limited HW-specific exposed
+interfaces (USB, thunderbolt). The goal of this document is to explain
+additional attack vectors that arise in the confidential computing space
+and discuss the proposed protection mechanisms for the Linux kernel.
+
+Overview and terminology
+========================
+
+Confidential Computing (CoCo) is a broad term covering a wide range of
+security technologies that aim to protect the confidentiality and integrity
+of data in use (vs. data at rest or data in transit). At its core, CoCo
+solutions provide a Trusted Execution Environment (TEE), where secure data
+processing can be performed and, as a result, they are typically further
+classified into different subtypes depending on the SW that is intended
+to be run in TEE. This document focuses on a subclass of CoCo technologies
+that are targeting virtualized environments and allow running Virtual
+Machines (VM) inside TEE. From now on in this document will be referring
+to this subclass of CoCo as 'Confidential Computing (CoCo) for the
+virtualized environments (VE)'.
+
+CoCo, in the virtualization context, refers to a set of HW and/or SW
+technologies that allow for stronger security guarantees for the SW running
+inside a CoCo VM. Namely, confidential computing allows its users to
+confirm the trustworthiness of all SW pieces to include in its reduced
+Trusted Computing Base (TCB) given its ability to attest the state of these
+trusted components.
+
+While the concrete implementation details differ between technologies, all
+available mechanisms aim to provide increased confidentiality and
+integrity for the VM's guest memory and execution state (vCPU registers),
+more tightly controlled guest interrupt injection, as well as some
+additional mechanisms to control guest-host page mapping. More details on
+the x86-specific solutions can be found in
+:doc:`Intel Trust Domain Extensions (TDX) </arch/x86/tdx>` and
+`AMD Memory Encryption <https://www.amd.com/system/files/techdocs/sev-snp-strengthening-vm-isolation-with-integrity-protection-and-more.pdf>`_.
+
+The basic CoCo guest layout includes the host, guest, the interfaces that
+communicate guest and host, a platform capable of supporting CoCo VMs, and
+a trusted intermediary between the guest VM and the underlying platform
+that acts as a security manager. The host-side virtual machine monitor
+(VMM) typically consists of a subset of traditional VMM features and
+is still in charge of the guest lifecycle, i.e. create or destroy a CoCo
+VM, manage its access to system resources, etc. However, since it
+typically stays out of CoCo VM TCB, its access is limited to preserve the
+security objectives.
+
+In the following diagram, the "<--->" lines represent bi-directional
+communication channels or interfaces between the CoCo security manager and
+the rest of the components (data flow for guest, host, hardware) ::
+
+ +-------------------+ +-----------------------+
+ | CoCo guest VM |<---->| |
+ +-------------------+ | |
+ | Interfaces | | CoCo security manager |
+ +-------------------+ | |
+ | Host VMM |<---->| |
+ +-------------------+ | |
+ | |
+ +--------------------+ | |
+ | CoCo platform |<--->| |
+ +--------------------+ +-----------------------+
+
+The specific details of the CoCo security manager vastly diverge between
+technologies. For example, in some cases, it will be implemented in HW
+while in others it may be pure SW.
+
+Existing Linux kernel threat model
+==================================
+
+The overall components of the current Linux kernel threat model are::
+
+ +-----------------------+ +-------------------+
+ | |<---->| Userspace |
+ | | +-------------------+
+ | External attack | | Interfaces |
+ | vectors | +-------------------+
+ | |<---->| Linux Kernel |
+ | | +-------------------+
+ +-----------------------+ +-------------------+
+ | Bootloader/BIOS |
+ +-------------------+
+ +-------------------+
+ | HW platform |
+ +-------------------+
+
+There is also communication between the bootloader and the kernel during
+the boot process, but this diagram does not represent it explicitly. The
+"Interfaces" box represents the various interfaces that allow
+communication between kernel and userspace. This includes system calls,
+kernel APIs, device drivers, etc.
+
+The existing Linux kernel threat model typically assumes execution on a
+trusted HW platform with all of the firmware and bootloaders included on
+its TCB. The primary attacker resides in the userspace, and all of the data
+coming from there is generally considered untrusted, unless userspace is
+privileged enough to perform trusted actions. In addition, external
+attackers are typically considered, including those with access to enabled
+external networks (e.g. Ethernet, Wireless, Bluetooth), exposed hardware
+interfaces (e.g. USB, Thunderbolt), and the ability to modify the contents
+of disks offline.
+
+Regarding external attack vectors, it is interesting to note that in most
+cases external attackers will try to exploit vulnerabilities in userspace
+first, but that it is possible for an attacker to directly target the
+kernel; particularly if the host has physical access. Examples of direct
+kernel attacks include the vulnerabilities CVE-2019-19524, CVE-2022-0435
+and CVE-2020-24490.
+
+Confidential Computing threat model and its security objectives
+===============================================================
+
+Confidential Computing adds a new type of attacker to the above list: a
+potentially misbehaving host (which can also include some part of a
+traditional VMM or all of it), which is typically placed outside of the
+CoCo VM TCB due to its large SW attack surface. It is important to note
+that this doesn’t imply that the host or VMM are intentionally
+malicious, but that there exists a security value in having a small CoCo
+VM TCB. This new type of adversary may be viewed as a more powerful type
+of external attacker, as it resides locally on the same physical machine
+(in contrast to a remote network attacker) and has control over the guest
+kernel communication with most of the HW::
+
+ +------------------------+
+ | CoCo guest VM |
+ +-----------------------+ | +-------------------+ |
+ | |<--->| | Userspace | |
+ | | | +-------------------+ |
+ | External attack | | | Interfaces | |
+ | vectors | | +-------------------+ |
+ | |<--->| | Linux Kernel | |
+ | | | +-------------------+ |
+ +-----------------------+ | +-------------------+ |
+ | | Bootloader/BIOS | |
+ +-----------------------+ | +-------------------+ |
+ | |<--->+------------------------+
+ | | | Interfaces |
+ | | +------------------------+
+ | CoCo security |<--->| Host/Host-side VMM |
+ | manager | +------------------------+
+ | | +------------------------+
+ | |<--->| CoCo platform |
+ +-----------------------+ +------------------------+
+
+While traditionally the host has unlimited access to guest data and can
+leverage this access to attack the guest, the CoCo systems mitigate such
+attacks by adding security features like guest data confidentiality and
+integrity protection. This threat model assumes that those features are
+available and intact.
+
+The **Linux kernel CoCo VM security objectives** can be summarized as follows:
+
+1. Preserve the confidentiality and integrity of CoCo guest's private
+memory and registers.
+
+2. Prevent privileged escalation from a host into a CoCo guest Linux kernel.
+While it is true that the host (and host-side VMM) requires some level of
+privilege to create, destroy, or pause the guest, part of the goal of
+preventing privileged escalation is to ensure that these operations do not
+provide a pathway for attackers to gain access to the guest's kernel.
+
+The above security objectives result in two primary **Linux kernel CoCo
+VM assets**:
+
+1. Guest kernel execution context.
+2. Guest kernel private memory.
+
+The host retains full control over the CoCo guest resources, and can deny
+access to them at any time. Examples of resources include CPU time, memory
+that the guest can consume, network bandwidth, etc. Because of this, the
+host Denial of Service (DoS) attacks against CoCo guests are beyond the
+scope of this threat model.
+
+The **Linux CoCo VM attack surface** is any interface exposed from a CoCo
+guest Linux kernel towards an untrusted host that is not covered by the
+CoCo technology SW/HW protection. This includes any possible
+side-channels, as well as transient execution side channels. Examples of
+explicit (not side-channel) interfaces include accesses to port I/O, MMIO
+and DMA interfaces, access to PCI configuration space, VMM-specific
+hypercalls (towards Host-side VMM), access to shared memory pages,
+interrupts allowed to be injected into the guest kernel by the host, as
+well as CoCo technology-specific hypercalls, if present. Additionally, the
+host in a CoCo system typically controls the process of creating a CoCo
+guest: it has a method to load into a guest the firmware and bootloader
+images, the kernel image together with the kernel command line. All of this
+data should also be considered untrusted until its integrity and
+authenticity is established via attestation.
+
+The table below shows a threat matrix for the CoCo guest Linux kernel but
+does not discuss potential mitigation strategies. The matrix refers to
+CoCo-specific versions of the guest, host and platform.
+
+.. list-table:: CoCo Linux guest kernel threat matrix
+ :widths: auto
+ :align: center
+ :header-rows: 1
+
+ * - Threat name
+ - Threat description
+
+ * - Guest malicious configuration
+ - A misbehaving host modifies one of the following guest's
+ configuration:
+
+ 1. Guest firmware or bootloader
+
+ 2. Guest kernel or module binaries
+
+ 3. Guest command line parameters
+
+ This allows the host to break the integrity of the code running
+ inside a CoCo guest, and violates the CoCo security objectives.
+
+ * - CoCo guest data attacks
+ - A misbehaving host retains full control of the CoCo guest's data
+ in-transit between the guest and the host-managed physical or
+ virtual devices. This allows any attack against confidentiality,
+ integrity or freshness of such data.
+
+ * - Malformed runtime input
+ - A misbehaving host injects malformed input via any communication
+ interface used by the guest's kernel code. If the code is not
+ prepared to handle this input correctly, this can result in a host
+ --> guest kernel privilege escalation. This includes traditional
+ side-channel and/or transient execution attack vectors.
+
+ * - Malicious runtime input
+ - A misbehaving host injects a specific input value via any
+ communication interface used by the guest's kernel code. The
+ difference with the previous attack vector (malformed runtime input)
+ is that this input is not malformed, but its value is crafted to
+ impact the guest's kernel security. Examples of such inputs include
+ providing a malicious time to the guest or the entropy to the guest
+ random number generator. Additionally, the timing of such events can
+ be an attack vector on its own, if it results in a particular guest
+ kernel action (i.e. processing of a host-injected interrupt).
+ resistant to supplied host input.
+
diff --git a/Documentation/sphinx/cdomain.py b/Documentation/sphinx/cdomain.py
index a99716bf44b5..4eb150bf509c 100644
--- a/Documentation/sphinx/cdomain.py
+++ b/Documentation/sphinx/cdomain.py
@@ -93,7 +93,7 @@ def markup_ctype_refs(match):
#
RE_expr = re.compile(r':c:(expr|texpr):`([^\`]+)`')
def markup_c_expr(match):
- return '\ ``' + match.group(2) + '``\ '
+ return '\\ ``' + match.group(2) + '``\\ '
#
# Parse Sphinx 3.x C markups, replacing them by backward-compatible ones
@@ -151,7 +151,7 @@ class CObject(Base_CObject):
def handle_func_like_macro(self, sig, signode):
u"""Handles signatures of function-like macros.
- If the objtype is 'function' and the the signature ``sig`` is a
+ If the objtype is 'function' and the signature ``sig`` is a
function-like macro, the name of the macro is returned. Otherwise
``False`` is returned. """
diff --git a/Documentation/sphinx/kernel_abi.py b/Documentation/sphinx/kernel_abi.py
index b5feb5b1d905..49797c55479c 100644
--- a/Documentation/sphinx/kernel_abi.py
+++ b/Documentation/sphinx/kernel_abi.py
@@ -138,7 +138,7 @@ class KernelCmd(Directive):
code_block += "\n " + l
lines = code_block + "\n\n"
- line_regex = re.compile("^\.\. LINENO (\S+)\#([0-9]+)$")
+ line_regex = re.compile(r"^\.\. LINENO (\S+)\#([0-9]+)$")
ln = 0
n = 0
f = fname
diff --git a/Documentation/sphinx/kernel_feat.py b/Documentation/sphinx/kernel_feat.py
index 27b701ed3681..b5fa2f0542a5 100644
--- a/Documentation/sphinx/kernel_feat.py
+++ b/Documentation/sphinx/kernel_feat.py
@@ -104,7 +104,7 @@ class KernelFeat(Directive):
lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env)
- line_regex = re.compile("^\.\. FILE (\S+)$")
+ line_regex = re.compile(r"^\.\. FILE (\S+)$")
out_lines = ""
diff --git a/Documentation/sphinx/kerneldoc.py b/Documentation/sphinx/kerneldoc.py
index 9395892c7ba3..7acf09963daa 100644
--- a/Documentation/sphinx/kerneldoc.py
+++ b/Documentation/sphinx/kerneldoc.py
@@ -130,7 +130,7 @@ class KernelDocDirective(Directive):
result = ViewList()
lineoffset = 0;
- line_regex = re.compile("^\.\. LINENO ([0-9]+)$")
+ line_regex = re.compile(r"^\.\. LINENO ([0-9]+)$")
for line in lines:
match = line_regex.search(line)
if match:
@@ -138,7 +138,7 @@ class KernelDocDirective(Directive):
lineoffset = int(match.group(1)) - 1
# we must eat our comments since the upset the markup
else:
- doc = env.srcdir + "/" + env.docname + ":" + str(self.lineno)
+ doc = str(env.srcdir) + "/" + env.docname + ":" + str(self.lineno)
result.append(line, doc + ": " + filename, lineoffset)
lineoffset += 1
diff --git a/Documentation/sphinx/kfigure.py b/Documentation/sphinx/kfigure.py
index cefdbb7e7523..13e885bbd499 100644
--- a/Documentation/sphinx/kfigure.py
+++ b/Documentation/sphinx/kfigure.py
@@ -309,7 +309,7 @@ def convert_image(img_node, translator, src_fname=None):
if dst_fname:
# the builder needs not to copy one more time, so pop it if exists.
translator.builder.images.pop(img_node['uri'], None)
- _name = dst_fname[len(translator.builder.outdir) + 1:]
+ _name = dst_fname[len(str(translator.builder.outdir)) + 1:]
if isNewer(dst_fname, src_fname):
kernellog.verbose(app,
diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py
index 328b3631a585..dcad0fff4723 100755
--- a/Documentation/sphinx/maintainers_include.py
+++ b/Documentation/sphinx/maintainers_include.py
@@ -77,7 +77,7 @@ class MaintainersInclude(Include):
line = line.rstrip()
# Linkify all non-wildcard refs to ReST files in Documentation/.
- pat = '(Documentation/([^\s\?\*]*)\.rst)'
+ pat = r'(Documentation/([^\s\?\*]*)\.rst)'
m = re.search(pat, line)
if m:
# maintainers.rst is in a subdirectory, so include "../".
@@ -90,11 +90,11 @@ class MaintainersInclude(Include):
output = "| %s" % (line.replace("\\", "\\\\"))
# Look for and record field letter to field name mappings:
# R: Designated *reviewer*: FullName <address@domain>
- m = re.search("\s(\S):\s", line)
+ m = re.search(r"\s(\S):\s", line)
if m:
field_letter = m.group(1)
if field_letter and not field_letter in fields:
- m = re.search("\*([^\*]+)\*", line)
+ m = re.search(r"\*([^\*]+)\*", line)
if m:
fields[field_letter] = m.group(1)
elif subsystems:
@@ -112,7 +112,7 @@ class MaintainersInclude(Include):
field_content = ""
# Collapse whitespace in subsystem name.
- heading = re.sub("\s+", " ", line)
+ heading = re.sub(r"\s+", " ", line)
output = output + "%s\n%s" % (heading, "~" * len(heading))
field_prev = ""
else:
diff --git a/Documentation/subsystem-apis.rst b/Documentation/subsystem-apis.rst
index 90a0535a932a..930dc23998a0 100644
--- a/Documentation/subsystem-apis.rst
+++ b/Documentation/subsystem-apis.rst
@@ -35,6 +35,7 @@ Human interfaces
sound/index
gpu/index
fb/index
+ leds/index
Networking interfaces
---------------------
@@ -70,7 +71,6 @@ Storage interfaces
fpga/index
i2c/index
iio/index
- leds/index
pcmcia/index
spi/index
w1/index
diff --git a/Documentation/trace/kprobes.rst b/Documentation/trace/kprobes.rst
index fc7ce76eab65..f825970a1495 100644
--- a/Documentation/trace/kprobes.rst
+++ b/Documentation/trace/kprobes.rst
@@ -315,7 +315,6 @@ architectures:
- i386 (Supports jump optimization)
- x86_64 (AMD-64, EM64T) (Supports jump optimization)
- ppc64
-- ia64 (Does not support probes on instruction slot1.)
- sparc64 (Return probes not yet implemented.)
- arm
- ppc
diff --git a/Documentation/translations/it_IT/riscv/patch-acceptance.rst b/Documentation/translations/it_IT/riscv/patch-acceptance.rst
index edf67252b3fb..2d7afb1f6959 100644
--- a/Documentation/translations/it_IT/riscv/patch-acceptance.rst
+++ b/Documentation/translations/it_IT/riscv/patch-acceptance.rst
@@ -1,6 +1,6 @@
.. include:: ../disclaimer-ita.rst
-:Original: :doc:`../../../riscv/patch-acceptance`
+:Original: :doc:`../../../arch/riscv/patch-acceptance`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
arch/riscv linee guida alla manutenzione per gli sviluppatori
diff --git a/Documentation/translations/sp_SP/process/embargoed-hardware-issues.rst b/Documentation/translations/sp_SP/process/embargoed-hardware-issues.rst
new file mode 100644
index 000000000000..c261b428b3f0
--- /dev/null
+++ b/Documentation/translations/sp_SP/process/embargoed-hardware-issues.rst
@@ -0,0 +1,341 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/embargoed-hardware-issues.rst
+:Translator: Avadhut Naik <avadhut.naik@amd.com>
+
+Problemas de hardware embargados
+================================
+
+Alcance
+-------
+
+Los problemas de hardware que resultan en problemas de seguridad son una
+categoría diferente de errores de seguridad que los errores de software
+puro que solo afectan al kernel de Linux.
+
+Los problemas de hardware como Meltdown, Spectre, L1TF, etc. deben
+tratarse de manera diferente porque usualmente afectan a todos los
+sistemas operativos (“OSâ€) y, por lo tanto, necesitan coordinación entre
+vendedores diferentes de OS, distribuciones, vendedores de hardware y
+otras partes. Para algunos de los problemas, las mitigaciones de software
+pueden depender de actualizaciones de microcódigo o firmware, los cuales
+necesitan una coordinación adicional.
+
+.. _Contacto:
+
+Contacto
+--------
+
+El equipo de seguridad de hardware del kernel de Linux es separado del
+equipo regular de seguridad del kernel de Linux.
+
+El equipo solo maneja la coordinación de los problemas de seguridad de
+hardware embargados. Los informes de errores de seguridad de software puro
+en el kernel de Linux no son manejados por este equipo y el "reportero"
+(quien informa del error) será guiado a contactar el equipo de seguridad
+del kernel de Linux (:doc:`errores de seguridad <security-bugs>`) en su
+lugar.
+
+El equipo puede contactar por correo electrónico en
+<hardware-security@kernel.org>. Esta es una lista privada de oficiales de
+seguridad que lo ayudarán a coordinar un problema de acuerdo con nuestro
+proceso documentado.
+
+La lista esta encriptada y el correo electrónico a la lista puede ser
+enviado por PGP o S/MIME encriptado y debe estar firmado con la llave de
+PGP del reportero o el certificado de S/MIME. La llave de PGP y el
+certificado de S/MIME de la lista están disponibles en las siguientes
+URLs:
+
+ - PGP: https://www.kernel.org/static/files/hardware-security.asc
+ - S/MIME: https://www.kernel.org/static/files/hardware-security.crt
+
+Si bien los problemas de seguridad del hardware a menudo son manejados por
+el vendedor de hardware afectado, damos la bienvenida al contacto de
+investigadores o individuos que hayan identificado una posible falla de
+hardware.
+
+Oficiales de seguridad de hardware
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+El equipo actual de oficiales de seguridad de hardware:
+
+ - Linus Torvalds (Linux Foundation Fellow)
+ - Greg Kroah-Hartman (Linux Foundation Fellow)
+ - Thomas Gleixner (Linux Foundation Fellow)
+
+Operación de listas de correo
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Las listas de correo encriptadas que se utilizan en nuestro proceso están
+alojados en la infraestructura de IT de la Fundación Linux. Al proporcionar
+este servicio, los miembros del personal de operaciones de IT de la
+Fundación Linux técnicamente tienen la capacidad de acceder a la
+información embargada, pero están obligados a la confidencialidad por su
+contrato de trabajo. El personal de IT de la Fundación Linux también es
+responsable para operar y administrar el resto de la infraestructura de
+kernel.org.
+
+El actual director de infraestructura de proyecto de IT de la Fundación
+Linux es Konstantin Ryabitsev.
+
+Acuerdos de no divulgación
+--------------------------
+
+El equipo de seguridad de hardware del kernel de Linux no es un organismo
+formal y, por lo tanto, no puede firmar cualquier acuerdo de no
+divulgación. La comunidad del kernel es consciente de la naturaleza
+delicada de tales problemas y ofrece un Memorando de Entendimiento en su
+lugar.
+
+Memorando de Entendimiento
+--------------------------
+
+La comunidad del kernel de Linux tiene una comprensión profunda del
+requisito de mantener los problemas de seguridad de hardware bajo embargo
+para la coordinación entre diferentes vendedores de OS, distribuidores,
+vendedores de hardware y otras partes.
+
+La comunidad del kernel de Linux ha manejado con éxito los problemas de
+seguridad del hardware en el pasado y tiene los mecanismos necesarios para
+permitir el desarrollo compatible con la comunidad bajo restricciones de
+embargo.
+
+La comunidad del kernel de Linux tiene un equipo de seguridad de hardware
+dedicado para el contacto inicial, el cual supervisa el proceso de manejo
+de tales problemas bajo las reglas de embargo.
+
+El equipo de seguridad de hardware identifica a los desarrolladores
+(expertos en dominio) que formarán el equipo de respuesta inicial para un
+problema en particular. El equipo de respuesta inicial puede involucrar
+más desarrolladores (expertos en dominio) para abordar el problema de la
+mejor manera técnica.
+
+Todos los desarrolladores involucrados se comprometen a adherirse a las
+reglas del embargo y a mantener confidencial la información recibida. La
+violación de la promesa conducirá a la exclusión inmediata del problema
+actual y la eliminación de todas las listas de correo relacionadas.
+Además, el equipo de seguridad de hardware también excluirá al
+delincuente de problemas futuros. El impacto de esta consecuencia es un
+elemento de disuasión altamente efectivo en nuestra comunidad. En caso de
+que ocurra una violación, el equipo de seguridad de hardware informará a
+las partes involucradas inmediatamente. Si usted o alguien tiene
+conocimiento de una posible violación, por favor, infórmelo inmediatamente
+a los oficiales de seguridad de hardware.
+
+Proceso
+^^^^^^^
+
+Debido a la naturaleza distribuida globalmente del desarrollo del kernel
+de Linux, las reuniones cara a cara hacen imposible abordar los
+problemas de seguridad del hardware. Las conferencias telefónicas son
+difíciles de coordinar debido a las zonas horarias y otros factores y
+solo deben usarse cuando sea absolutamente necesario. El correo
+electrónico encriptado ha demostrado ser el método de comunicación más
+efectivo y seguro para estos tipos de problemas.
+
+Inicio de la divulgación
+""""""""""""""""""""""""
+
+La divulgación comienza contactado al equipo de seguridad de hardware del
+kernel de Linux por correo electrónico. Este contacto inicial debe
+contener una descripción del problema y una lista de cualquier hardware
+afectado conocido. Si su organización fabrica o distribuye el hardware
+afectado, le animamos a considerar también que otro hardware podría estar
+afectado.
+
+El equipo de seguridad de hardware proporcionará una lista de correo
+encriptada específica para el incidente que se utilizará para la discusión
+inicial con el reportero, la divulgación adicional y la coordinación.
+
+El equipo de seguridad de hardware proporcionará a la parte reveladora una
+lista de desarrolladores (expertos de dominios) a quienes se debe informar
+inicialmente sobre el problema después de confirmar con los
+desarrolladores que se adherirán a este Memorando de Entendimiento y al
+proceso documentado. Estos desarrolladores forman el equipo de respuesta
+inicial y serán responsables de manejar el problema después del contacto
+inicial. El equipo de seguridad de hardware apoyará al equipo de
+respuesta, pero no necesariamente involucrandose en el proceso de desarrollo
+de mitigación.
+
+Si bien los desarrolladores individuales pueden estar cubiertos por un
+acuerdo de no divulgación a través de su empleador, no pueden firmar
+acuerdos individuales de no divulgación en su papel de desarrolladores
+del kernel de Linux. Sin embargo, aceptarán adherirse a este proceso
+documentado y al Memorando de Entendimiento.
+
+La parte reveladora debe proporcionar una lista de contactos para todas
+las demás entidades ya que han sido, o deberían ser, informadas sobre el
+problema. Esto sirve para varios propósitos:
+
+ - La lista de entidades divulgadas permite la comunicación en toda la
+ industria, por ejemplo, otros vendedores de OS, vendedores de HW, etc.
+
+ - Las entidades divulgadas pueden ser contactadas para nombrar a expertos
+ que deben participar en el desarrollo de la mitigación.
+
+ - Si un experto que se requiere para manejar un problema es empleado por
+ una entidad cotizada o un miembro de una entidad cotizada, los equipos
+ de respuesta pueden solicitar la divulgación de ese experto a esa
+ entidad. Esto asegura que el experto también forme parte del equipo de
+ respuesta de la entidad.
+
+Divulgación
+"""""""""""
+
+La parte reveladora proporcionará información detallada al equipo de
+respuesta inicial a través de la lista de correo encriptada especifica.
+
+Según nuestra experiencia, la documentación técnica de estos problemas
+suele ser un punto de partida suficiente y es mejor hacer aclaraciones
+técnicas adicionales a través del correo electrónico.
+
+Desarrollo de la mitigación
+"""""""""""""""""""""""""""
+
+El equipo de respuesta inicial configura una lista de correo encriptada o
+reutiliza una existente si es apropiada.
+
+El uso de una lista de correo está cerca del proceso normal de desarrollo
+de Linux y se ha utilizado con éxito en el desarrollo de mitigación para
+varios problemas de seguridad de hardware en el pasado.
+
+La lista de correo funciona en la misma manera que el desarrollo normal de
+Linux. Los parches se publican, discuten y revisan y, si se acuerda, se
+aplican a un repositorio git no público al que solo pueden acceder los
+desarrolladores participantes a través de una conexión segura. El
+repositorio contiene la rama principal de desarrollo en comparación con
+el kernel principal y las ramas backport para versiones estables del
+kernel según sea necesario.
+
+El equipo de respuesta inicial identificará a más expertos de la
+comunidad de desarrolladores del kernel de Linux según sea necesario. La
+incorporación de expertos puede ocurrir en cualquier momento del proceso
+de desarrollo y debe manejarse de manera oportuna.
+
+Si un experto es empleado por o es miembro de una entidad en la lista de
+divulgación proporcionada por la parte reveladora, entonces se solicitará
+la participación de la entidad pertinente.
+
+Si no es así, entonces se informará a la parte reveladora sobre la
+participación de los expertos. Los expertos están cubiertos por el
+Memorando de Entendimiento y se solicita a la parte reveladora que
+reconozca la participación. En caso de que la parte reveladora tenga una
+razón convincente para objetar, entonces esta objeción debe plantearse
+dentro de los cinco días laborables y resolverse con el equipo de
+incidente inmediatamente. Si la parte reveladora no reacciona dentro de
+los cinco días laborables, esto se toma como un reconocimiento silencioso.
+
+Después del reconocimiento o la resolución de una objeción, el experto es
+revelado por el equipo de incidente y se incorpora al proceso de
+desarrollo.
+
+Lanzamiento coordinado
+""""""""""""""""""""""
+
+Las partes involucradas negociarán la fecha y la hora en la que termina el
+embargo. En ese momento, las mitigaciones preparadas se integran en los
+árboles de kernel relevantes y se publican.
+
+Si bien entendemos que los problemas de seguridad del hardware requieren
+un tiempo de embargo coordinado, el tiempo de embargo debe limitarse al
+tiempo mínimo que se requiere para que todas las partes involucradas
+desarrollen, prueben y preparen las mitigaciones. Extender el tiempo de
+embargo artificialmente para cumplir con las fechas de discusión de la
+conferencia u otras razones no técnicas está creando más trabajo y carga
+para los desarrolladores y los equipos de respuesta involucrados, ya que
+los parches necesitan mantenerse actualizados para seguir el desarrollo en
+curso del kernel upstream, lo cual podría crear cambios conflictivos.
+
+Asignación de CVE
+"""""""""""""""""
+
+Ni el equipo de seguridad de hardware ni el equipo de respuesta inicial
+asignan CVEs, ni se requieren para el proceso de desarrollo. Si los CVEs
+son proporcionados por la parte reveladora, pueden usarse con fines de
+documentación.
+
+Embajadores del proceso
+-----------------------
+
+Para obtener asistencia con este proceso, hemos establecido embajadores
+en varias organizaciones, que pueden responder preguntas o proporcionar
+orientación sobre el proceso de reporte y el manejo posterior. Los
+embajadores no están involucrados en la divulgación de un problema en
+particular, a menos que lo solicite un equipo de respuesta o una parte
+revelada involucrada. La lista de embajadores actuales:
+
+ ============= ========================================================
+ AMD Tom Lendacky <thomas.lendacky@amd.com>
+ Ampere Darren Hart <darren@os.amperecomputing.com>
+ ARM Catalin Marinas <catalin.marinas@arm.com>
+ IBM Power Anton Blanchard <anton@linux.ibm.com>
+ IBM Z Christian Borntraeger <borntraeger@de.ibm.com>
+ Intel Tony Luck <tony.luck@intel.com>
+ Qualcomm Trilok Soni <tsoni@codeaurora.org>
+ Samsung Javier González <javier.gonz@samsung.com>
+
+ Microsoft James Morris <jamorris@linux.microsoft.com>
+ Xen Andrew Cooper <andrew.cooper3@citrix.com>
+
+ Canonical John Johansen <john.johansen@canonical.com>
+ Debian Ben Hutchings <ben@decadent.org.uk>
+ Oracle Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+ Red Hat Josh Poimboeuf <jpoimboe@redhat.com>
+ SUSE Jiri Kosina <jkosina@suse.cz>
+
+ Google Kees Cook <keescook@chromium.org>
+
+ LLVM Nick Desaulniers <ndesaulniers@google.com>
+ ============= ========================================================
+
+Si quiere que su organización se añada a la lista de embajadores, por
+favor póngase en contacto con el equipo de seguridad de hardware. El
+embajador nominado tiene que entender y apoyar nuestro proceso
+completamente y está idealmente bien conectado en la comunidad del kernel
+de Linux.
+
+Listas de correo encriptadas
+----------------------------
+
+Usamos listas de correo encriptadas para la comunicación. El principio de
+funcionamiento de estas listas es que el correo electrónico enviado a la
+lista se encripta con la llave PGP de la lista o con el certificado S/MIME
+de la lista. El software de lista de correo descifra el correo electrónico
+y lo vuelve a encriptar individualmente para cada suscriptor con la llave
+PGP del suscriptor o el certificado S/MIME. Los detalles sobre el software
+de la lista de correo y la configuración que se usa para asegurar la
+seguridad de las listas y la protección de los datos se pueden encontrar
+aquí: https://korg.wiki.kernel.org/userdoc/remail.
+
+Llaves de lista
+^^^^^^^^^^^^^^^
+
+Para el contacto inicial, consulte :ref:`Contacto`. Para las listas de
+correo especificas de incidentes, la llave y el certificado S/MIME se
+envían a los suscriptores por correo electrónico desde la lista
+especifica.
+
+Suscripción a listas específicas de incidentes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+La suscripción es manejada por los equipos de respuesta. Las partes
+reveladas que quieren participar en la comunicación envían una lista de
+suscriptores potenciales al equipo de respuesta para que el equipo de
+respuesta pueda validar las solicitudes de suscripción.
+
+Cada suscriptor necesita enviar una solicitud de suscripción al equipo de
+respuesta por correo electrónico. El correo electrónico debe estar firmado
+con la llave PGP del suscriptor o el certificado S/MIME. Si se usa una
+llave PGP, debe estar disponible desde un servidor de llave publica y esta
+idealmente conectada a la red de confianza PGP del kernel de Linux. Véase
+también: https://www.kernel.org/signature.html.
+
+El equipo de respuesta verifica que la solicitud del suscriptor sea válida
+y añade al suscriptor a la lista. Después de la suscripción, el suscriptor
+recibirá un correo electrónico de la lista que está firmado con la llave
+PGP de la lista o el certificado S/MIME de la lista. El cliente de correo
+electrónico del suscriptor puede extraer la llave PGP o el certificado
+S/MIME de la firma, de modo que el suscriptor pueda enviar correo
+electrónico encriptado a la lista.
diff --git a/Documentation/translations/sp_SP/process/index.rst b/Documentation/translations/sp_SP/process/index.rst
index 09bfece0f52f..d6f3ccfb160e 100644
--- a/Documentation/translations/sp_SP/process/index.rst
+++ b/Documentation/translations/sp_SP/process/index.rst
@@ -22,3 +22,5 @@
adding-syscalls
researcher-guidelines
contribution-maturity-model
+ security-bugs
+ embargoed-hardware-issues
diff --git a/Documentation/translations/sp_SP/process/security-bugs.rst b/Documentation/translations/sp_SP/process/security-bugs.rst
new file mode 100644
index 000000000000..d07c7e579b52
--- /dev/null
+++ b/Documentation/translations/sp_SP/process/security-bugs.rst
@@ -0,0 +1,103 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/security-bugs.rst
+:Translator: Avadhut Naik <avadhut.naik@amd.com>
+
+Errores de seguridad
+====================
+
+Los desarrolladores del kernel de Linux se toman la seguridad muy en
+serio. Como tal, nos gustaría saber cuándo se encuentra un error de
+seguridad para que pueda ser corregido y divulgado lo más rápido posible.
+Por favor, informe sobre los errores de seguridad al equipo de seguridad
+del kernel de Linux.
+
+Contacto
+--------
+
+El equipo de seguridad del kernel de Linux puede ser contactado por correo
+electrónico en <security@kernel.org>. Esta es una lista privada de
+oficiales de seguridad que ayudarán a verificar el informe del error y
+desarrollarán y publicarán una corrección. Si ya tiene una corrección, por
+favor, inclúyala con su informe, ya que eso puede acelerar considerablemente
+el proceso. Es posible que el equipo de seguridad traiga ayuda adicional
+de mantenedores del área para comprender y corregir la vulnerabilidad de
+seguridad.
+
+Como ocurre con cualquier error, cuanta más información se proporcione,
+más fácil será diagnosticarlo y corregirlo. Por favor, revise el
+procedimiento descrito en 'Documentation/admin-guide/reporting-issues.rst'
+si no tiene claro que información es útil. Cualquier código de explotación
+es muy útil y no será divulgado sin el consentimiento del "reportero" (el
+que envia el error) a menos que ya se haya hecho público.
+
+Por favor, envíe correos electrónicos en texto plano sin archivos
+adjuntos cuando sea posible. Es mucho más difícil tener una discusión
+citada en contexto sobre un tema complejo si todos los detalles están
+ocultos en archivos adjuntos. Piense en ello como un
+:doc:`envío de parche regular <submitting-patches>` (incluso si no tiene
+un parche todavía) describa el problema y el impacto, enumere los pasos
+de reproducción, y sígalo con una solución propuesta, todo en texto plano.
+
+
+Divulgación e información embargada
+-----------------------------------
+
+La lista de seguridad no es un canal de divulgación. Para eso, ver
+Coordinación debajo. Una vez que se ha desarrollado una solución robusta,
+comienza el proceso de lanzamiento. Las soluciones para errores conocidos
+públicamente se lanzan inmediatamente.
+
+Aunque nuestra preferencia es lanzar soluciones para errores no divulgados
+públicamente tan pronto como estén disponibles, esto puede postponerse a
+petición del reportero o una parte afectada por hasta 7 días calendario
+desde el inicio del proceso de lanzamiento, con una extensión excepcional
+a 14 días de calendario si se acuerda que la criticalidad del error requiere
+más tiempo. La única razón válida para aplazar la publicación de una
+solución es para acomodar la logística de QA y los despliegues a gran
+escala que requieren coordinación de lanzamiento.
+
+Si bien la información embargada puede compartirse con personas de
+confianza para desarrollar una solución, dicha información no se publicará
+junto con la solución o en cualquier otro canal de divulgación sin el
+permiso del reportero. Esto incluye, pero no se limita al informe original
+del error y las discusiones de seguimiento (si las hay), exploits,
+información sobre CVE o la identidad del reportero.
+
+En otras palabras, nuestro único interés es solucionar los errores. Toda
+otra información presentada a la lista de seguridad y cualquier discusión
+de seguimiento del informe se tratan confidencialmente incluso después de
+que se haya levantado el embargo, en perpetuidad.
+
+Coordinación con otros grupos
+-----------------------------
+
+El equipo de seguridad del kernel recomienda encarecidamente que los
+reporteros de posibles problemas de seguridad NUNCA contacten la lista
+de correo “linux-distros†hasta DESPUES de discutirlo con el equipo de
+seguridad del kernel. No Cc: ambas listas a la vez. Puede ponerse en
+contacto con la lista de correo linux-distros después de que se haya
+acordado una solución y comprenda completamente los requisitos que al
+hacerlo le impondrá a usted y la comunidad del kernel.
+
+Las diferentes listas tienen diferentes objetivos y las reglas de
+linux-distros no contribuyen en realidad a solucionar ningún problema de
+seguridad potencial.
+
+Asignación de CVE
+-----------------
+
+El equipo de seguridad no asigna CVEs, ni los requerimos para informes o
+correcciones, ya que esto puede complicar innecesariamente el proceso y
+puede retrasar el manejo de errores. Si un reportero desea que se le
+asigne un identificador CVE, debe buscar uno por sí mismo, por ejemplo,
+poniéndose en contacto directamente con MITRE. Sin embargo, en ningún
+caso se retrasará la inclusión de un parche para esperar a que llegue un
+identificador CVE.
+
+Acuerdos de no divulgación
+--------------------------
+
+El equipo de seguridad del kernel de Linux no es un organismo formal y,
+por lo tanto, no puede firmar cualquier acuerdo de no divulgación.
diff --git a/Documentation/translations/zh_CN/arch/index.rst b/Documentation/translations/zh_CN/arch/index.rst
index e3d273d7d599..71186d9df7c9 100644
--- a/Documentation/translations/zh_CN/arch/index.rst
+++ b/Documentation/translations/zh_CN/arch/index.rst
@@ -10,7 +10,7 @@
mips/index
arm64/index
- ../riscv/index
+ ../arch/riscv/index
openrisc/index
parisc/index
loongarch/index
@@ -18,7 +18,6 @@
TODOList:
* arm/index
-* ia64/index
* m68k/index
* nios2/index
* powerpc/index
diff --git a/Documentation/translations/zh_CN/riscv/boot-image-header.rst b/Documentation/translations/zh_CN/arch/riscv/boot-image-header.rst
index 0234c28a7114..779b5172fe24 100644
--- a/Documentation/translations/zh_CN/riscv/boot-image-header.rst
+++ b/Documentation/translations/zh_CN/arch/riscv/boot-image-header.rst
@@ -1,6 +1,6 @@
-.. include:: ../disclaimer-zh_CN.rst
+.. include:: ../../disclaimer-zh_CN.rst
-:Original: Documentation/riscv/boot-image-header.rst
+:Original: Documentation/arch/riscv/boot-image-header.rst
:翻译:
diff --git a/Documentation/translations/zh_CN/riscv/index.rst b/Documentation/translations/zh_CN/arch/riscv/index.rst
index 131e405aa857..3b041c116169 100644
--- a/Documentation/translations/zh_CN/riscv/index.rst
+++ b/Documentation/translations/zh_CN/arch/riscv/index.rst
@@ -1,8 +1,8 @@
.. SPDX-License-Identifier: GPL-2.0
-.. include:: ../disclaimer-zh_CN.rst
+.. include:: ../../disclaimer-zh_CN.rst
-:Original: Documentation/riscv/index.rst
+:Original: Documentation/arch/riscv/index.rst
:翻译:
diff --git a/Documentation/translations/zh_CN/riscv/patch-acceptance.rst b/Documentation/translations/zh_CN/arch/riscv/patch-acceptance.rst
index d180d24717bf..c8eb230ca8ee 100644
--- a/Documentation/translations/zh_CN/riscv/patch-acceptance.rst
+++ b/Documentation/translations/zh_CN/arch/riscv/patch-acceptance.rst
@@ -1,8 +1,8 @@
.. SPDX-License-Identifier: GPL-2.0
-.. include:: ../disclaimer-zh_CN.rst
+.. include:: ../../disclaimer-zh_CN.rst
-:Original: Documentation/riscv/patch-acceptance.rst
+:Original: Documentation/arch/riscv/patch-acceptance.rst
:翻译:
diff --git a/Documentation/translations/zh_CN/riscv/vm-layout.rst b/Documentation/translations/zh_CN/arch/riscv/vm-layout.rst
index 91884e2dfff8..4b9f4dcf6c19 100644
--- a/Documentation/translations/zh_CN/riscv/vm-layout.rst
+++ b/Documentation/translations/zh_CN/arch/riscv/vm-layout.rst
@@ -1,7 +1,7 @@
.. SPDX-License-Identifier: GPL-2.0
-.. include:: ../disclaimer-zh_CN.rst
+.. include:: ../../disclaimer-zh_CN.rst
-:Original: Documentation/riscv/vm-layout.rst
+:Original: Documentation/arch/riscv/vm-layout.rst
:翻译:
diff --git a/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst b/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst
index 4772a900c37a..bc0d7ea6d834 100644
--- a/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst
+++ b/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst
@@ -49,12 +49,6 @@ CPU热拔æ’支æŒçš„一个更新颖的用途是它在SMPçš„æš‚åœæ¢å¤æ”¯æŒä¸
é™åˆ¶å†…核将支æŒçš„CPU总é‡ã€‚如果这里æ供的数é‡ä½ŽäºŽå®žé™…å¯ç”¨çš„CPUæ•°é‡ï¼Œé‚£ä¹ˆå…¶ä»–CPU
以åŽå°±ä¸èƒ½ä¸Šçº¿äº†ã€‚
-``additional_cpus=n``
- 使用它æ¥é™åˆ¶å¯çƒ­æ’拔的CPU。该选项设置
- ``cpu_possible_mask = cpu_present_mask + additional_cpus``
-
- 这个选项åªé™äºŽIA64架构。
-
``possible_cpus=n``
这个选项设置 ``cpu_possible_mask`` 中的 ``possible_cpus`` ä½ã€‚
diff --git a/Documentation/translations/zh_CN/index.rst b/Documentation/translations/zh_CN/index.rst
index 299704c0818d..6ccec9657cc6 100644
--- a/Documentation/translations/zh_CN/index.rst
+++ b/Documentation/translations/zh_CN/index.rst
@@ -52,12 +52,9 @@
core-api/index
driver-api/index
+ subsystem-apis
å†…æ ¸ä¸­çš„é” <locking/index>
-TODOList:
-
-* subsystem-apis
-
å¼€å‘工具和æµç¨‹
--------------
diff --git a/Documentation/translations/zh_CN/maintainer/maintainer-entry-profile.rst b/Documentation/translations/zh_CN/maintainer/maintainer-entry-profile.rst
index a1ee99c4786e..0f5acfb1012e 100644
--- a/Documentation/translations/zh_CN/maintainer/maintainer-entry-profile.rst
+++ b/Documentation/translations/zh_CN/maintainer/maintainer-entry-profile.rst
@@ -89,4 +89,4 @@
../doc-guide/maintainer-profile
../../../nvdimm/maintainer-entry-profile
- ../../../riscv/patch-acceptance
+ ../../../arch/riscv/patch-acceptance
diff --git a/Documentation/translations/zh_CN/scheduler/sched-arch.rst b/Documentation/translations/zh_CN/scheduler/sched-arch.rst
index ce3f39d9b3cb..b2ac3c743a3a 100644
--- a/Documentation/translations/zh_CN/scheduler/sched-arch.rst
+++ b/Documentation/translations/zh_CN/scheduler/sched-arch.rst
@@ -20,8 +20,7 @@
==========
1. è¿è¡Œé˜Ÿåˆ—é”
默认情况下,switch_to arch函数在调用时é”定了è¿è¡Œé˜Ÿåˆ—。这通常ä¸æ˜¯ä¸€ä¸ªé—®é¢˜ï¼Œé™¤éž
-switch_toå¯èƒ½éœ€è¦èŽ·å–è¿è¡Œé˜Ÿåˆ—é”。这通常是由于上下文切æ¢ä¸­çš„唤醒æ“作造æˆçš„。è§
-arch/ia64/include/asm/switch_to.h的例å­ã€‚
+switch_toå¯èƒ½éœ€è¦èŽ·å–è¿è¡Œé˜Ÿåˆ—é”。这通常是由于上下文切æ¢ä¸­çš„唤醒æ“作造æˆçš„。
为了è¦æ±‚调度器在è¿è¡Œé˜Ÿåˆ—解é”的情况下调用switch_to,你必须在头文件
中`#define __ARCH_WANT_UNLOCKED_CTXSW`(通常是定义switch_to的那个文件)。
@@ -68,7 +67,5 @@ arch/x86/kernel/process.c有轮询和ç¡çœ ç©ºé—²å‡½æ•°çš„例å­ã€‚
我å‘现的å¯èƒ½çš„arch问题(并试图解决或没有解决)。:
-ia64 - safe_halt的调用与中断相比,是å¦å¾ˆè’谬? (它ç¡çœ äº†å—) (å‚考 #4a)
-
sparc - 在这一点上,IRQ是开ç€çš„(?),把local_irq_save改为_disable。
- 待办事项: 需è¦ç¬¬äºŒä¸ªCPUæ¥ç¦ç”¨æŠ¢å  (å‚考 #1)
diff --git a/Documentation/translations/zh_CN/subsystem-apis.rst b/Documentation/translations/zh_CN/subsystem-apis.rst
new file mode 100644
index 000000000000..47780bb0772f
--- /dev/null
+++ b/Documentation/translations/zh_CN/subsystem-apis.rst
@@ -0,0 +1,110 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ./disclaimer-zh_CN.rst
+
+:Original: Documentation/subsystem-apis.rst
+
+:翻译:
+
+ å”艺舟 Tang Yizhou <tangyeechou@gmail.com>
+
+==============
+内核å­ç³»ç»Ÿæ–‡æ¡£
+==============
+
+这些书ç±ä»Žå†…核开å‘者的角度,详细介ç»äº†ç‰¹å®šå†…æ ¸å­ç³»ç»Ÿ
+的如何工作。这里的大部分信æ¯ç›´æŽ¥å–自内核æºä»£ç ï¼Œå¹¶
+æ ¹æ®éœ€è¦æ·»åŠ äº†è¡¥å……æ料(或者至少是我们设法添加的 - å¯
+能 *ä¸æ˜¯* 所有的æ料都有需è¦ï¼‰ã€‚
+
+核心å­ç³»ç»Ÿ
+----------
+
+.. toctree::
+ :maxdepth: 1
+
+ core-api/index
+ driver-api/index
+ mm/index
+ power/index
+ scheduler/index
+ locking/index
+
+TODOList:
+
+* timers/index
+
+人机接å£
+--------
+
+.. toctree::
+ :maxdepth: 1
+
+ sound/index
+
+TODOList:
+
+* input/index
+* hid/index
+* gpu/index
+* fb/index
+
+网络接å£
+--------
+
+.. toctree::
+ :maxdepth: 1
+
+ infiniband/index
+
+TODOList:
+
+* networking/index
+* netlabel/index
+* isdn/index
+* mhi/index
+
+存储接å£
+--------
+
+.. toctree::
+ :maxdepth: 1
+
+ filesystems/index
+
+TODOList:
+
+* block/index
+* cdrom/index
+* scsi/index
+* target/index
+
+**Fixme**: 这里还需è¦æ›´å¤šçš„分类组织工作。
+
+.. toctree::
+ :maxdepth: 1
+
+ accounting/index
+ cpu-freq/index
+ iio/index
+ virt/index
+ PCI/index
+ peci/index
+
+TODOList:
+
+* fpga/index
+* i2c/index
+* leds/index
+* pcmcia/index
+* spi/index
+* w1/index
+* watchdog/index
+* hwmon/index
+* accel/index
+* security/index
+* crypto/index
+* bpf/index
+* usb/index
+* misc-devices/index
+* wmi/index
diff --git a/Documentation/translations/zh_TW/admin-guide/README.rst b/Documentation/translations/zh_TW/admin-guide/README.rst
index 7fc56e1e3348..4cb581f5994a 100644
--- a/Documentation/translations/zh_TW/admin-guide/README.rst
+++ b/Documentation/translations/zh_TW/admin-guide/README.rst
@@ -9,16 +9,16 @@
å³æƒ³æˆ Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com>
-Linux內核5.x版本 <http://kernel.org/>
+Linux內核6.x版本 <http://kernel.org/>
=========================================
-以下是Linux版本5的發行註記。仔細閱讀它們,
+以下是Linux版本6的發行註記。仔細閱讀它們,
它們會告訴你這些都是什麼,解釋如何安è£å…§æ ¸ï¼Œä»¥åŠé‡åˆ°å•é¡Œæ™‚該如何åšã€‚
什麼是Linux?
---------------
- Linux是Unix作業系統的克隆版本,由Linus Torvalds在一個鬆散的網絡黑客
+ Linux是Unixæ“作系統的克隆版本,由Linus Torvalds在一個鬆散的網絡黑客
(Hacker,無貶義)團隊的幫助下從頭開始編寫。它旨在實ç¾å…¼å®¹POSIXå’Œ
單一UNIXè¦ç¯„。
@@ -28,7 +28,7 @@ Linux內核5.x版本 <http://kernel.org/>
Linux在GNU通用公共許å¯è­‰ï¼Œç‰ˆæœ¬2(GNU GPLv2)下分發,詳見隨附的COPYING文件。
-它能在什麼樣的硬體上é‹è¡Œï¼Ÿ
+它能在什麼樣的硬件上é‹è¡Œï¼Ÿ
-----------------------------
雖然Linux最åˆæ˜¯çˆ²32ä½çš„x86 PC機(386或更高版本)開發的,但今天它也能é‹è¡Œåœ¨
@@ -40,16 +40,16 @@ Linux內核5.x版本 <http://kernel.org/>
單元(PMMU)和一個移æ¤çš„GNU C編譯器(gccï¼›GNU Compiler Collection,GCC的一
部分)。Linux也被移æ¤åˆ°è¨±å¤šæ²’有PMMU的體系架構中,儘管功能顯然å—到了一定的
é™åˆ¶ã€‚
- Linux也被移æ¤åˆ°äº†å…¶è‡ªå·±ä¸Šã€‚ç¾åœ¨å¯ä»¥å°‡å…§æ ¸ä½œçˆ²ç”¨æˆ¶ç©ºé–“應用程å¼é‹è¡Œâ€”—這被
+ Linux也被移æ¤åˆ°äº†å…¶è‡ªå·±ä¸Šã€‚ç¾åœ¨å¯ä»¥å°‡å…§æ ¸ä½œçˆ²ç”¨æˆ¶ç©ºé–“應用程åºé‹è¡Œâ€”—這被
稱爲用戶模å¼Linux(UML)。
文檔
-----
-網際網路上和書ç±ä¸Šéƒ½æœ‰å¤§é‡çš„é›»å­æ–‡æª”,既有Linux專屬文檔,也有與一般UNIXå•é¡Œç›¸é—œ
+因特網上和書ç±ä¸Šéƒ½æœ‰å¤§é‡çš„é›»å­æ–‡æª”,既有Linux專屬文檔,也有與一般UNIXå•é¡Œç›¸é—œ
的文檔。我建議在任何Linux FTP站點上查找LDP(Linux文檔項目)書ç±çš„文檔å­ç›®éŒ„。
本自述文件並ä¸æ˜¯é—œæ–¼ç³»çµ±çš„文檔:有更好的å¯ç”¨è³‡æºã€‚
- - 網際網路上和書ç±ä¸Šéƒ½æœ‰å¤§é‡çš„(電å­ï¼‰æ–‡æª”,既有Linux專屬文檔,也有與普通
+ - 因特網上和書ç±ä¸Šéƒ½æœ‰å¤§é‡çš„(電å­ï¼‰æ–‡æª”,既有Linux專屬文檔,也有與普通
UNIXå•é¡Œç›¸é—œçš„文檔。我建議在任何有LDP(Linux文檔項目)書ç±çš„Linux FTP
站點上查找文檔å­ç›®éŒ„。本自述文件並ä¸æ˜¯é—œæ–¼ç³»çµ±çš„文檔:有更好的å¯ç”¨è³‡æºã€‚
@@ -58,33 +58,33 @@ Linux內核5.x版本 <http://kernel.org/>
:ref:`Documentation/process/changes.rst <changes>` 文件,它包å«äº†å‡ç´šå…§æ ¸
å¯èƒ½æœƒå°Žè‡´çš„å•é¡Œçš„相關信æ¯ã€‚
-安è£å…§æ ¸åŽŸå§‹ç¢¼
+安è£å…§æ ¸æºä»£ç¢¼
---------------
- - 如果您è¦å®‰è£å®Œæ•´çš„原始碼,請把內核tar檔案包放在您有權é™çš„目錄中(例如您
+ - 如果您è¦å®‰è£å®Œæ•´çš„æºä»£ç¢¼ï¼Œè«‹æŠŠå…§æ ¸tar檔案包放在您有權é™çš„目錄中(例如您
的主目錄)並將其解包::
- xz -cd linux-5.x.tar.xz | tar xvf -
+ xz -cd linux-6.x.tar.xz | tar xvf -
- 將「Xã€æ›¿æ›æˆæœ€æ–°å…§æ ¸çš„版本號。
+ 將“Xâ€æ›¿æ›æˆæœ€æ–°å…§æ ¸çš„版本號。
- ã€ä¸è¦ã€‘使用 /usr/src/linux 目錄ï¼é€™è£¡æœ‰ä¸€çµ„庫頭文件使用的內核頭文件
+ ã€ä¸è¦ã€‘使用 /usr/src/linux 目錄ï¼é€™è£æœ‰ä¸€çµ„庫頭文件使用的內核頭文件
(通常是ä¸å®Œæ•´çš„)。它們應該與庫匹é…,而ä¸æ˜¯è¢«å…§æ ¸çš„變化æžå¾—一團糟。
- - 您還å¯ä»¥é€šéŽæ‰“補ä¸åœ¨5.x版本之間å‡ç´šã€‚補ä¸ä»¥xzæ ¼å¼åˆ†ç™¼ã€‚è¦é€šéŽæ‰“補ä¸é€²è¡Œ
- 安è£ï¼Œè«‹ç²å–所有較新的補ä¸æ–‡ä»¶ï¼Œé€²å…¥å…§æ ¸åŽŸå§‹ç¢¼ï¼ˆlinux-5.x)的目錄並
+ - 您還å¯ä»¥é€šéŽæ‰“補ä¸åœ¨6.x版本之間å‡ç´šã€‚補ä¸ä»¥xzæ ¼å¼åˆ†ç™¼ã€‚è¦é€šéŽæ‰“補ä¸é€²è¡Œ
+ 安è£ï¼Œè«‹ç²å–所有較新的補ä¸æ–‡ä»¶ï¼Œé€²å…¥å…§æ ¸æºä»£ç¢¼ï¼ˆlinux-6.x)的目錄並
執行::
- xz -cd ../patch-5.x.xz | patch -p1
+ xz -cd ../patch-6.x.xz | patch -p1
- è«‹ã€æŒ‰é †åºã€‘替æ›æ‰€æœ‰å¤§æ–¼ç•¶å‰åŽŸå§‹ç¢¼æ¨¹ç‰ˆæœ¬çš„「xã€ï¼Œé€™æ¨£å°±å¯ä»¥äº†ã€‚您å¯èƒ½æƒ³è¦
+ è«‹ã€æŒ‰é †åºã€‘替æ›æ‰€æœ‰å¤§æ–¼ç•¶å‰æºä»£ç¢¼æ¨¹ç‰ˆæœ¬çš„“xâ€ï¼Œé€™æ¨£å°±å¯ä»¥äº†ã€‚您å¯èƒ½æƒ³è¦
刪除備份文件(文件åé¡žä¼¼xxx~ 或 xxx.orig),並確ä¿æ²’有失敗的補ä¸ï¼ˆæ–‡ä»¶å
é¡žä¼¼xxx# 或 xxx.rej)。如果有,ä¸æ˜¯ä½ å°±æ˜¯æˆ‘犯了錯誤。
- 與5.x內核的補ä¸ä¸åŒï¼Œ5.x.y內核(也稱爲穩定版內核)的補ä¸ä¸æ˜¯å¢žé‡çš„,而是
- 直接應用於基本的5.x內核。例如,如果您的基本內核是5.0,並且希望應用5.0.3
- 補ä¸ï¼Œå‰‡ä¸æ‡‰å…ˆæ‡‰ç”¨5.0.1å’Œ5.0.2的補ä¸ã€‚類似地,如果您é‹è¡Œçš„是5.0.2內核,
- 並且希望跳轉到5.0.3,那麼在應用5.0.3補ä¸ä¹‹å‰ï¼Œå¿…須首先撤銷5.0.2補ä¸
+ 與6.x內核的補ä¸ä¸åŒï¼Œ6.x.y內核(也稱爲穩定版內核)的補ä¸ä¸æ˜¯å¢žé‡çš„,而是
+ 直接應用於基本的6.x內核。例如,如果您的基本內核是6.0,並且希望應用6.0.3
+ 補ä¸ï¼Œå‰‡ä¸æ‡‰å…ˆæ‡‰ç”¨6.0.1å’Œ6.0.2的補ä¸ã€‚類似地,如果您é‹è¡Œçš„是6.0.2內核,
+ 並且希望跳轉到6.0.3,那麼在應用6.0.3補ä¸ä¹‹å‰ï¼Œå¿…須首先撤銷6.0.2補ä¸
(å³patch -R)。更多關於這方é¢çš„內容,請閱讀
:ref:`Documentation/process/applying-patches.rst <applying_patches>` 。
@@ -93,7 +93,7 @@ Linux內核5.x版本 <http://kernel.org/>
linux/scripts/patch-kernel linux
- 上é¢å‘½ä»¤ä¸­çš„第一個åƒæ•¸æ˜¯å…§æ ¸åŽŸå§‹ç¢¼çš„ä½ç½®ã€‚補ä¸æ˜¯åœ¨ç•¶å‰ç›®éŒ„應用的,但是
+ 上é¢å‘½ä»¤ä¸­çš„第一個åƒæ•¸æ˜¯å…§æ ¸æºä»£ç¢¼çš„ä½ç½®ã€‚補ä¸æ˜¯åœ¨ç•¶å‰ç›®éŒ„應用的,但是
å¯ä»¥å°‡å¦ä¸€å€‹ç›®éŒ„指定爲第二個åƒæ•¸ã€‚
- 確ä¿æ²’有éŽæ™‚çš„ .o 文件和ä¾è³´é …::
@@ -101,30 +101,30 @@ Linux內核5.x版本 <http://kernel.org/>
cd linux
make mrproper
- ç¾åœ¨æ‚¨æ‡‰è©²å·²ç¶“正確安è£äº†åŽŸå§‹ç¢¼ã€‚
+ ç¾åœ¨æ‚¨æ‡‰è©²å·²ç¶“正確安è£äº†æºä»£ç¢¼ã€‚
-軟體è¦æ±‚
+軟件è¦æ±‚
---------
- 編譯和é‹è¡Œ5.x內核需è¦å„種軟體包的最新版本。請åƒè€ƒ
+ 編譯和é‹è¡Œ6.x內核需è¦å„種軟件包的最新版本。請åƒè€ƒ
:ref:`Documentation/process/changes.rst <changes>`
- 來了解最低版本è¦æ±‚以åŠå¦‚何å‡ç´šè»Ÿé«”包。請注æ„,使用éŽèˆŠç‰ˆæœ¬çš„這些包å¯èƒ½æœƒ
+ 來了解最低版本è¦æ±‚以åŠå¦‚何å‡ç´šè»Ÿä»¶åŒ…。請注æ„,使用éŽèˆŠç‰ˆæœ¬çš„這些包å¯èƒ½æœƒ
導致很難追蹤的間接錯誤,因此ä¸è¦ä»¥çˆ²åœ¨ç”Ÿæˆæˆ–æ“作éŽç¨‹ä¸­å‡ºç¾æ˜Žé¡¯å•é¡Œæ™‚å¯ä»¥
åªæ›´æ–°åŒ…。
爲內核建立目錄
---------------
- 編譯內核時,默èªæƒ…æ³ä¸‹æ‰€æœ‰è¼¸å‡ºæ–‡ä»¶éƒ½å°‡èˆ‡å…§æ ¸åŽŸå§‹ç¢¼æ”¾åœ¨ä¸€èµ·ã€‚使用
+ 編譯內核時,默èªæƒ…æ³ä¸‹æ‰€æœ‰è¼¸å‡ºæ–‡ä»¶éƒ½å°‡èˆ‡å…§æ ¸æºä»£ç¢¼æ”¾åœ¨ä¸€èµ·ã€‚使用
``make O=output/dir`` é¸é …å¯ä»¥çˆ²è¼¸å‡ºæ–‡ä»¶ï¼ˆåŒ…括 .config)指定備用ä½ç½®ã€‚
例如::
- kernel source code: /usr/src/linux-5.x
+ kernel source code: /usr/src/linux-6.x
build directory: /home/name/build/kernel
è¦é…置和構建內核,請使用::
- cd /usr/src/linux-5.x
+ cd /usr/src/linux-6.x
make O=/home/name/build/kernel menuconfig
make O=/home/name/build/kernel
sudo make O=/home/name/build/kernel modules_install install
@@ -136,7 +136,7 @@ Linux內核5.x版本 <http://kernel.org/>
å³ä½¿åªå‡ç´šä¸€å€‹å°ç‰ˆæœ¬ï¼Œä¹Ÿä¸è¦è·³éŽæ­¤æ­¥é©Ÿã€‚æ¯å€‹ç‰ˆæœ¬ä¸­éƒ½æœƒæ·»åŠ æ–°çš„é…ç½®é¸é …,
如果é…置文件沒有按é å®šè¨­ç½®ï¼Œå°±æœƒå‡ºç¾å¥‡æ€ªçš„å•é¡Œã€‚如果您想以最少的工作é‡
- å°‡ç¾æœ‰é…ç½®å‡ç´šåˆ°æ–°ç‰ˆæœ¬ï¼Œè«‹ä½¿ç”¨ ``makeoldconfig`` ,它åªæœƒè©¢å•æ‚¨æ–°é…ç½®
+ å°‡ç¾æœ‰é…ç½®å‡ç´šåˆ°æ–°ç‰ˆæœ¬ï¼Œè«‹ä½¿ç”¨ ``make oldconfig`` ,它åªæœƒè©¢å•æ‚¨æ–°é…ç½®
é¸é …的答案。
- 其他é…置命令包括::
@@ -164,17 +164,17 @@ Linux內核5.x版本 <http://kernel.org/>
"make ${PLATFORM}_defconfig"
使用arch/$arch/configs/${PLATFORM}_defconfig中
的默èªé¸é …值創建一個./.config文件。
- 用「makehelpã€ä¾†ç²å–您體系架構中所有å¯ç”¨å¹³å°çš„列表。
+ 用“make helpâ€ä¾†ç²å–您體系架構中所有å¯ç”¨å¹³è‡ºçš„列表。
"make allyesconfig"
- 通éŽå„˜å¯èƒ½å°‡é¸é …值設置爲「yã€ï¼Œå‰µå»ºä¸€å€‹
+ 通éŽå„˜å¯èƒ½å°‡é¸é …值設置爲“yâ€ï¼Œå‰µå»ºä¸€å€‹
./.config文件。
"make allmodconfig"
- 通éŽå„˜å¯èƒ½å°‡é¸é …值設置爲「mã€ï¼Œå‰µå»ºä¸€å€‹
+ 通éŽå„˜å¯èƒ½å°‡é¸é …值設置爲“mâ€ï¼Œå‰µå»ºä¸€å€‹
./.config文件。
- "make allnoconfig" 通éŽå„˜å¯èƒ½å°‡é¸é …值設置爲「nã€ï¼Œå‰µå»ºä¸€å€‹
+ "make allnoconfig" 通éŽå„˜å¯èƒ½å°‡é¸é …值設置爲“nâ€ï¼Œå‰µå»ºä¸€å€‹
./.config文件。
"make randconfig" 通éŽéš¨æ©Ÿè¨­ç½®é¸é …值來創建./.config文件。
@@ -182,7 +182,7 @@ Linux內核5.x版本 <http://kernel.org/>
"make localmodconfig" 基於當å‰é…置和加載的模塊(lsmod)創建é…置。ç¦ç”¨
已加載的模塊ä¸éœ€è¦çš„任何模塊é¸é …。
- è¦çˆ²å¦ä¸€å°è¨ˆç®—機創建localmodconfig,請將該計算機
+ è¦çˆ²å¦ä¸€è‡ºè¨ˆç®—機創建localmodconfig,請將該計算機
çš„lsmod存儲到一個文件中,並將其作爲lsmodåƒæ•¸å‚³å…¥ã€‚
此外,通éŽåœ¨åƒæ•¸LMC_KEEP中指定模塊的路徑,å¯ä»¥å°‡
@@ -200,9 +200,10 @@ Linux內核5.x版本 <http://kernel.org/>
"make localyesconfig" 與localmodconfig類似,åªæ˜¯å®ƒæœƒå°‡æ‰€æœ‰æ¨¡å¡Šé¸é …轉æ›
爲內置(=y)。你å¯ä»¥åŒæ™‚通éŽLMC_KEEPä¿ç•™æ¨¡å¡Šã€‚
- "make kvmconfig" 爲kvm客體內核支æŒå•“用其他é¸é …。
+ "make kvm_guest.config"
+ 爲kvm客戶機內核支æŒå•“用其他é¸é …。
- "make xenconfig" 爲xen dom0客體內核支æŒå•“用其他é¸é …。
+ "make xen.config" 爲xen dom0客戶機內核支æŒå•“用其他é¸é …。
"make tinyconfig" é…置儘å¯èƒ½å°çš„內核。
@@ -218,10 +219,10 @@ Linux內核5.x版本 <http://kernel.org/>
這種情æ³ä¸‹ï¼Œæ•¸å­¸ä»¿çœŸæ°¸é ä¸æœƒè¢«ä½¿ç”¨ã€‚內核會ç¨å¾®å¤§ä¸€é»žï¼Œä½†ä¸ç®¡
是å¦æœ‰æ•¸å­¸å”處ç†å™¨ï¼Œéƒ½å¯ä»¥åœ¨ä¸åŒçš„機器上工作。
- - 「kernel hackingã€é…置細節通常會導致更大或更慢的內核(或兩者
+ - “kernel hackingâ€é…置細節通常會導致更大或更慢的內核(或兩者
兼而有之),甚至å¯ä»¥é€šéŽé…置一些例程來主動嘗試破壞壞代碼以發ç¾
內核å•é¡Œï¼Œå¾žè€Œé™ä½Žå…§æ ¸çš„穩定性(kmalloc())。因此,您å¯èƒ½æ‡‰è©²
- 用於研究「開發ã€ã€ã€Œå¯¦é©—ã€æˆ–「調試ã€ç‰¹æ€§ç›¸é—œå•é¡Œã€‚
+ 用於研究“開發â€ã€â€œå¯¦é©—â€æˆ–“調試â€ç‰¹æ€§ç›¸é—œå•é¡Œã€‚
編譯內核
---------
@@ -229,10 +230,8 @@ Linux內核5.x版本 <http://kernel.org/>
- 確ä¿æ‚¨è‡³å°‘有gcc 5.1å¯ç”¨ã€‚
有關更多信æ¯ï¼Œè«‹åƒé–± :ref:`Documentation/process/changes.rst <changes>` 。
- 請注æ„,您ä»ç„¶å¯ä»¥ä½¿ç”¨æ­¤å…§æ ¸é‹è¡Œa.out用戶程åºã€‚
-
- 執行 ``make`` 來創建壓縮內核映åƒã€‚如果您安è£äº†lilo以é©é…內核makefile,
- 那麼也å¯ä»¥é€²è¡Œ ``makeinstall`` ,但是您å¯èƒ½éœ€è¦å…ˆæª¢æŸ¥ç‰¹å®šçš„lilo設置。
+ 那麼也å¯ä»¥é€²è¡Œ ``make install`` ,但是您å¯èƒ½éœ€è¦å…ˆæª¢æŸ¥ç‰¹å®šçš„lilo設置。
實際安è£å¿…須以root身份執行,但任何正常構建都ä¸éœ€è¦ã€‚
無須徒然使用root身份。
@@ -242,8 +241,8 @@ Linux內核5.x版本 <http://kernel.org/>
- 詳細的內核編譯/生æˆè¼¸å‡ºï¼š
通常,內核構建系統在相當安éœçš„模å¼ä¸‹é‹è¡Œï¼ˆä½†ä¸æ˜¯å®Œå…¨å®‰éœï¼‰ã€‚但是有時您或
- 其他內核開發人員需è¦çœ‹åˆ°ç·¨è­¯ã€é€£çµæˆ–其他命令的執行éŽç¨‹ã€‚爲此,å¯ä½¿ç”¨
- 「verbose(詳細)ã€æ§‹å»ºæ¨¡å¼ã€‚
+ 其他內核開發人員需è¦çœ‹åˆ°ç·¨è­¯ã€éˆæŽ¥æˆ–其他命令的執行éŽç¨‹ã€‚爲此,å¯ä½¿ç”¨
+ “verbose(詳細)â€æ§‹å»ºæ¨¡å¼ã€‚
å‘ ``make`` å‘½ä»¤å‚³éž ``V=1`` 來實ç¾ï¼Œä¾‹å¦‚::
make V=1 all
@@ -255,15 +254,15 @@ Linux內核5.x版本 <http://kernel.org/>
與工作內核版本號相åŒçš„新內核,請在進行 ``make modules_install`` 安è£
之å‰å‚™ä»½modules目錄。
- 或者,在編譯之å‰ï¼Œä½¿ç”¨å…§æ ¸é…ç½®é¸é …「LOCALVERSIONã€å‘常è¦å…§æ ¸ç‰ˆæœ¬é™„加
- 一個唯一的後綴。LOCALVERSIONå¯ä»¥åœ¨ã€ŒGeneral Setupã€èœå–®ä¸­è¨­ç½®ã€‚
+ 或者,在編譯之å‰ï¼Œä½¿ç”¨å…§æ ¸é…ç½®é¸é …“LOCALVERSIONâ€å‘常è¦å…§æ ¸ç‰ˆæœ¬é™„加
+ 一個唯一的後綴。LOCALVERSIONå¯ä»¥åœ¨â€œGeneral Setupâ€èœå–®ä¸­è¨­ç½®ã€‚
- 爲了引導新內核,您需è¦å°‡å…§æ ¸æ˜ åƒï¼ˆä¾‹å¦‚編譯後的
.../linux/arch/x86/boot/bzImage)複製到常è¦å¯å¼•å°Žå…§æ ¸çš„ä½ç½®ã€‚
- ä¸å†æ”¯æŒåœ¨æ²’有LILO等啓動è£è¼‰ç¨‹åºå¹«åŠ©çš„情æ³ä¸‹ç›´æŽ¥å¾žè»Ÿç›¤å¼•å°Žå…§æ ¸ã€‚
- 如果從硬碟引導Linux,很å¯èƒ½ä½¿ç”¨LILO,它使用/etc/lilo.conf文件中
+ 如果從硬盤引導Linux,很å¯èƒ½ä½¿ç”¨LILO,它使用/etc/lilo.conf文件中
指定的內核映åƒæ–‡ä»¶ã€‚內核映åƒæ–‡ä»¶é€šå¸¸æ˜¯/vmlinuzã€/boot/vmlinuzã€
/bzImage或/boot/bzImage。使用新內核å‰ï¼Œè«‹ä¿å­˜èˆŠæ˜ åƒçš„副本,並複製
新映åƒè¦†è“‹èˆŠæ˜ åƒã€‚然後您ã€å¿…é ˆé‡æ–°é‹è¡ŒLILO】來更新加載映射ï¼å¦å‰‡ï¼Œ
@@ -284,68 +283,13 @@ Linux內核5.x版本 <http://kernel.org/>
è‹¥é‡åˆ°å•é¡Œ
-----------
- - 如果您發ç¾äº†ä¸€äº›å¯èƒ½ç”±æ–¼å…§æ ¸ç¼ºé™·æ‰€å°Žè‡´çš„å•é¡Œï¼Œè«‹æª¢æŸ¥MAINTAINERS(維護者)
- 文件看看是å¦æœ‰äººèˆ‡ä»¤æ‚¨é‡åˆ°éº»ç…©çš„內核部分相關。如果無人在此列出,那麼第二
- 個最好的方案就是把它們發給我(torvalds@linux-foundation.org),也å¯èƒ½ç™¼é€
- 到任何其他相關的郵件列表或新èžçµ„。
-
- - 在所有的缺陷報告中,ã€è«‹ã€‘告訴我們您在說什麼內核,如何復ç¾å•é¡Œï¼Œä»¥åŠæ‚¨çš„
- 設置是什麼的(使用您的常識)。如果å•é¡Œæ˜¯æ–°çš„,請告訴我;如果å•é¡Œæ˜¯èˆŠçš„,
- 請嘗試告訴我您什麼時候首次注æ„到它。
-
- - 如果缺陷導致如下消æ¯::
-
- unable to handle kernel paging request at address C0000010
- Oops: 0002
- EIP: 0010:XXXXXXXX
- eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx
- esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx
- ds: xxxx es: xxxx fs: xxxx gs: xxxx
- Pid: xx, process nr: xx
- xx xx xx xx xx xx xx xx xx xx
-
- 或者類似的內核調試信æ¯é¡¯ç¤ºåœ¨å±å¹•ä¸Šæˆ–在系統日誌里,請ã€å¦‚實】複製它。
- å¯èƒ½å°ä½ ä¾†èªªè½‰å„²ï¼ˆdump)看起來ä¸å¯ç†è§£ï¼Œä½†å®ƒç¢ºå¯¦åŒ…å«å¯èƒ½æœ‰åŠ©æ–¼èª¿è©¦å•é¡Œçš„
- ä¿¡æ¯ã€‚轉儲上方的文本也很é‡è¦ï¼šå®ƒèªªæ˜Žäº†å…§æ ¸è½‰å„²ä»£ç¢¼çš„原因(在上é¢çš„示例中,
- 是由於內核指é‡éŒ¯èª¤ï¼‰ã€‚更多關於如何ç†è§£è½‰å„²çš„ä¿¡æ¯ï¼Œè«‹åƒè¦‹
- Documentation/admin-guide/bug-hunting.rst。
-
- - 如果使用 CONFIG_KALLSYMS 編譯內核,則å¯ä»¥æŒ‰åŽŸæ¨£ç™¼é€è½‰å„²ï¼Œå¦å‰‡å¿…須使用
- ``ksymoops`` 程åºä¾†ç†è§£è½‰å„²ï¼ˆä½†é€šå¸¸é¦–é¸ä½¿ç”¨CONFIG_KALLSYMS編譯)。
- 此實用程åºå¯å¾ž
- https://www.kernel.org/pub/linux/utils/kernel/ksymoops/ 下載。
- 或者,您å¯ä»¥æ‰‹å‹•åŸ·è¡Œè½‰å„²æŸ¥æ‰¾ï¼š
-
- - 在調試åƒä¸Šé¢é€™æ¨£çš„轉儲時,如果您å¯ä»¥æŸ¥æ‰¾EIP值的å«ç¾©ï¼Œé€™å°‡éžå¸¸æœ‰å¹«åŠ©ã€‚
- å六進ä½å€¼æœ¬èº«å°æˆ‘或其他任何人都沒有太大幫助:它會å–決於特定的內核設置。
- 您應該åšçš„是從EIPè¡Œç²å–å六進ä½å€¼ï¼ˆå¿½ç•¥ ``0010:`` ),然後在內核å字列表
- 中查找它,以查看哪個內核函數包å«æœ‰å•é¡Œçš„地å€ã€‚
-
- è¦æ‰¾åˆ°å…§æ ¸å‡½æ•¸å,您需è¦æ‰¾åˆ°èˆ‡é¡¯ç¤ºç—‡ç‹€çš„內核相關è¯çš„系統二進ä½æ–‡ä»¶ã€‚就是
- 文件「linux/vmlinuxã€ã€‚è¦æå–å字列表並將其與內核崩潰中的EIP進行匹é…,
- 請執行::
-
- nm vmlinux | sort | less
-
- 這將爲您æ供一個按å‡åºæŽ’åºçš„內核地å€åˆ—表,從中很容易找到包å«æœ‰å•é¡Œçš„地å€
- 的函數。請注æ„,內核調試消æ¯æ供的地å€ä¸ä¸€å®šèˆ‡å‡½æ•¸åœ°å€å®Œå…¨åŒ¹é…(事實上,
- 這是ä¸å¯èƒ½çš„),因此您ä¸èƒ½åªã€Œgrepã€åˆ—表:ä¸éŽåˆ—表將爲您æä¾›æ¯å€‹å…§æ ¸å‡½æ•¸
- 的起點,因此通éŽæŸ¥æ‰¾èµ·å§‹åœ°å€ä½Žæ–¼ä½ æ­£åœ¨æœç´¢çš„地å€ï¼Œä½†å¾Œä¸€å€‹å‡½æ•¸çš„高於的
- 函數,你會找到您想è¦çš„。實際上,在您的å•é¡Œå ±å‘Šä¸­åŠ å…¥ä¸€äº›ã€Œä¸Šä¸‹æ–‡ã€å¯èƒ½æ˜¯
- 一個好主æ„,給出相關的上下幾行。
-
- 如果您由於æŸäº›åŽŸå› ç„¡æ³•å®Œæˆä¸Šè¿°æ“作(如您使用é ç·¨è­¯çš„內核映åƒæˆ–類似的映åƒï¼‰ï¼Œ
- 請儘å¯èƒ½å¤šåœ°å‘Šè¨´æˆ‘您的相關設置信æ¯ï¼Œé€™æœƒæœ‰æ‰€å¹«åŠ©ã€‚有關詳細信æ¯è«‹é–±è®€
- 『Documentation/admin-guide/reporting-issues.rstã€ã€‚
-
- - 或者,您å¯ä»¥åœ¨æ­£åœ¨é‹è¡Œçš„內核上使用gdb(åªè®€çš„ï¼›å³ä¸èƒ½æ›´æ”¹å€¼æˆ–設置斷點)。
- 爲此,請首先使用-g編譯內核;é©ç•¶åœ°ç·¨è¼¯arch/x86/Makefile,然後執行 ``make
- clean`` 。您還需è¦å•“用CONFIG_PROC_FSï¼ˆé€šéŽ ``make config`` )。
-
- 使用新內核é‡æ–°å•“動後,執行 ``gdb vmlinux /proc/kcore`` 。ç¾åœ¨å¯ä»¥ä½¿ç”¨æ‰€æœ‰
- 普通的gdb命令。查找系統崩潰點的命令是 ``l *0xXXXXXXXX`` (將xxx替æ›çˆ²EIP
- 值)。
-
- 用gdb無法調試一個當å‰æœªé‹è¡Œçš„內核是由於gdb(錯誤地)忽略了編譯內核的起始
- å移é‡ã€‚
+如果您發ç¾äº†ä¸€äº›å¯èƒ½ç”±æ–¼å…§æ ¸ç¼ºé™·æ‰€å°Žè‡´çš„å•é¡Œï¼Œè«‹åƒé–±ï¼š
+Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 。
+
+想è¦ç†è§£å…§æ ¸éŒ¯èª¤å ±å‘Šï¼Œè«‹åƒé–±ï¼š
+Documentation/translations/zh_CN/admin-guide/bug-hunting.rst 。
+
+更多用GDB調試內核的信æ¯ï¼Œè«‹åƒé–±ï¼š
+Documentation/translations/zh_CN/dev-tools/gdb-kernel-debugging.rst
+和 Documentation/dev-tools/kgdb.rst 。
diff --git a/Documentation/translations/zh_TW/admin-guide/bootconfig.rst b/Documentation/translations/zh_TW/admin-guide/bootconfig.rst
new file mode 100644
index 000000000000..abac5aa60f67
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/bootconfig.rst
@@ -0,0 +1,294 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/bootconfig.rst
+
+:譯者: å³æƒ³æˆ Wu XiangCheng <bobwxc@email.cn>
+
+========
+引導é…ç½®
+========
+
+:作者: Masami Hiramatsu <mhiramat@kernel.org>
+
+概述
+====
+
+引導é…置擴展了ç¾æœ‰çš„內核命令行,以一種更有效率的方å¼åœ¨å¼•å°Žå…§æ ¸æ™‚進一步支æŒ
+éµå€¼æ•¸æ“šã€‚這å…許管ç†å“¡å‚³éžä¸€ä»½çµæ§‹åŒ–é—œéµå­—çš„é…置文件。
+
+é…置文件語法
+============
+
+引導é…置文件的語法採用éžå¸¸ç°¡å–®çš„éµå€¼çµæ§‹ã€‚æ¯å€‹é—œéµå­—由點連接的單詞組æˆï¼Œéµ
+和值由 ``=`` 連接。值以分號( ``;`` )或æ›è¡Œç¬¦ï¼ˆ ``\n`` )çµå°¾ã€‚數組值中æ¯
+個元素由逗號( ``,`` )分隔。::
+
+ KEY[.WORD[...]] = VALUE[, VALUE2[...]][;]
+
+與內核命令行語法ä¸åŒï¼Œé€—號和 ``=`` 周åœå…許有空格。
+
+é—œéµå­—åªå…許包å«å­—æ¯ã€æ•¸å­—ã€é€£å­—符( ``-`` )和下劃線( ``_`` )。值å¯åŒ…å«
+å¯æ‰“å°å­—符和空格,但分號( ``;`` )ã€æ›è¡Œç¬¦ï¼ˆ ``\n`` )ã€é€—號( ``,`` )ã€
+井號( ``#`` )和å³å¤§æ‹¬è™Ÿï¼ˆ ``}`` )等分隔符除外。
+
+如果你需è¦åœ¨å€¼ä¸­ä½¿ç”¨é€™äº›åˆ†éš”符,å¯ä»¥ç”¨é›™å¼•è™Ÿï¼ˆ ``"VALUE"`` )或單引號
+( ``'VALUE'`` )括起來。注æ„,引號無法轉義。
+
+éµçš„值å¯ä»¥çˆ²ç©ºæˆ–ä¸å­˜åœ¨ã€‚這些éµç”¨æ–¼æª¢æŸ¥è©²éµæ˜¯å¦å­˜åœ¨ï¼ˆé¡žä¼¼å¸ƒçˆ¾å€¼ï¼‰ã€‚
+
+éµå€¼èªžæ³•
+--------
+
+引導é…置文件語法å…許用戶通éŽå¤§æ‹¬è™Ÿåˆä½µéµå部分相åŒçš„é—œéµå­—。例如::
+
+ foo.bar.baz = value1
+ foo.bar.qux.quux = value2
+
+也å¯ä»¥å¯«æˆ::
+
+ foo.bar {
+ baz = value1
+ qux.quux = value2
+ }
+
+或者更緊湊一些,寫æˆ::
+
+ foo.bar { baz = value1; qux.quux = value2 }
+
+在這兩種樣å¼ä¸­ï¼Œå¼•å°Žè§£æžæ™‚相åŒçš„é—œéµå­—都會自動åˆä½µã€‚å› æ­¤å¯ä»¥è¿½åŠ é¡žä¼¼çš„樹或
+éµå€¼ã€‚
+
+相åŒé—œéµå­—的值
+--------------
+
+ç¦æ­¢å…©å€‹æˆ–多個值或數組共享åŒä¸€å€‹é—œéµå­—。例如::
+
+ foo = bar, baz
+ foo = qux # !錯誤! 我們ä¸å¯ä»¥é‡å®šç¾©ç›¸åŒçš„é—œéµå­—
+
+如果你想è¦æ›´æ–°å€¼ï¼Œå¿…須顯å¼ä½¿ç”¨è¦†è“‹æ“作符 ``:=`` 。例如::
+
+ foo = bar, baz
+ foo := qux
+
+這樣 ``foo`` é—œéµå­—的值就變æˆäº† ``qux`` 。這å°æ–¼é€šéŽæ·»åŠ ï¼ˆéƒ¨åˆ†ï¼‰è‡ªå®šç¾©å¼•å°Ž
+é…置來覆蓋默èªå€¼éžå¸¸æœ‰ç”¨ï¼Œå…於解æžé»˜èªå¼•å°Žé…置。
+
+如果你想å°ç¾æœ‰é—œéµå­—追加值作爲數組æˆå“¡ï¼Œå¯ä»¥ä½¿ç”¨ ``+=`` æ“作符。例如::
+
+ foo = bar, baz
+ foo += qux
+
+這樣, ``foo`` é—œéµå­—å°±åŒæ™‚æ“有了 ``bar`` , ``baz`` å’Œ ``qux`` 。
+
+此外,父關éµå­—下å¯åŒæ™‚存在值和å­é—œéµå­—。
+例如,下列é…置是å¯è¡Œçš„。::
+
+ foo = value1
+ foo.bar = value2
+ foo := value3 # 這會更新foo的值。
+
+注æ„,裸值ä¸èƒ½ç›´æŽ¥æ”¾é€²çµæ§‹åŒ–é—œéµå­—中,必須在大括號外定義它。例如::
+
+ foo {
+ bar = value1
+ bar {
+ baz = value2
+ qux = value3
+ }
+ }
+
+åŒæ™‚,關éµå­—下值節點的順åºæ˜¯å›ºå®šçš„。如果值和å­é—œéµå­—åŒæ™‚存在,值永é æ˜¯è©²é—œ
+éµå­—的第一個å­ç¯€é»žã€‚因此如果用戶先指定å­é—œéµå­—,如::
+
+ foo.bar = value1
+ foo = value2
+
+則在程åºï¼ˆå’Œ/proc/bootconfig)中,它會按如下顯示::
+
+ foo = value2
+ foo.bar = value1
+
+註釋
+----
+
+é…置語法接å—shell腳本風格的註釋。註釋以井號( ``#`` )開始,到æ›è¡Œç¬¦
+( ``\n`` )çµæŸã€‚
+
+::
+
+ # comment line
+ foo = value # value is set to foo.
+ bar = 1, # 1st element
+ 2, # 2nd element
+ 3 # 3rd element
+
+會被解æžçˆ²::
+
+ foo = value
+ bar = 1, 2, 3
+
+注æ„ä½ ä¸èƒ½æŠŠè¨»é‡‹æ”¾åœ¨å€¼å’Œåˆ†éš”符( ``,`` 或 ``;`` )之間。如下é…置語法是錯誤的::
+
+ key = 1 # comment
+ ,2
+
+
+/proc/bootconfig
+================
+
+/proc/bootconfig是引導é…置的用戶空間接å£ã€‚與/proc/cmdlineä¸åŒï¼Œæ­¤æ–‡ä»¶å…§å®¹ä»¥
+éµå€¼åˆ—表樣å¼é¡¯ç¤ºã€‚
+æ¯å€‹éµå€¼å°ä¸€è¡Œï¼Œæ¨£å¼å¦‚下::
+
+ KEY[.WORDS...] = "[VALUE]"[,"VALUE2"...]
+
+
+用引導é…置引導內核
+==================
+
+用引導é…置引導內核有兩種方法:將引導é…置附加到initrdé¡åƒæˆ–直接嵌入內核中。
+
+*initrd: initial RAM disk,åˆå§‹å…§å­˜ç£ç›¤*
+
+將引導é…置附加到initrd
+----------------------
+
+由於默èªæƒ…æ³ä¸‹å¼•å°Žé…置文件是用initrd加載的,因此它將被添加到initrd(initramfs)
+é¡åƒæ–‡ä»¶çš„末尾,其中包å«å¡«å……ã€å¤§å°ã€æ ¡é©—值和12字節幻數,如下所示::
+
+ [initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n]
+
+大å°å’Œæ ¡é©—值爲å°ç«¯åºå­˜æ”¾çš„32ä½ç„¡ç¬¦è™Ÿå€¼ã€‚
+
+當引導é…置被加到initrdé¡åƒæ™‚,整個文件大å°æœƒå°é½Šåˆ°4字節。空字符( ``\0`` )
+會填補å°é½Šç©ºéš™ã€‚å› æ­¤ ``size`` 就是引導é…置文件的長度+填充的字節。
+
+Linux內核在內存中解碼initrdé¡åƒçš„最後部分以ç²å–引導é…置數據。由於這種“æ¹è² å¼â€
+的方法,åªè¦å¼•å°ŽåŠ è¼‰å™¨å‚³éžäº†æ­£ç¢ºçš„initrd文件大å°ï¼Œå°±ç„¡éœ€æ›´æ”¹æˆ–更新引導加載器
+和內核é¡åƒæœ¬èº«ã€‚如果引導加載器æ„外傳éžäº†æ›´é•·çš„大å°ï¼Œå…§æ ¸å°‡ç„¡æ³•æ‰¾åˆ°å¼•å°Žé…置數
+據。
+
+Linux內核在tools/bootconfig下æ供了 ``bootconfig`` 命令來完æˆæ­¤æ“作,管ç†å“¡
+å¯ä»¥ç”¨å®ƒå¾žinitrdé¡åƒä¸­åˆªé™¤æˆ–追加é…置文件。你å¯ä»¥ç”¨ä»¥ä¸‹å‘½ä»¤ä¾†æ§‹å»ºå®ƒ::
+
+ # make -C tools/bootconfig
+
+è¦å‘initrdé¡åƒæ·»åŠ ä½ çš„引導é…置文件,請按如下命令æ“作(舊數據會自動移除)::
+
+ # tools/bootconfig/bootconfig -a your-config /boot/initrd.img-X.Y.Z
+
+è¦å¾žé¡åƒä¸­ç§»é™¤é…置,å¯ä»¥ä½¿ç”¨-dé¸é …::
+
+ # tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z
+
+然後在內核命令行上添加 ``bootconfig`` 告訴內核去initrd文件末尾尋找內核é…置。
+
+將引導é…置嵌入內核
+------------------
+
+如果你ä¸èƒ½ä½¿ç”¨initrd,也å¯ä»¥é€šéŽKconfigé¸é …將引導é…置文件嵌入內核中。在此情
+æ³ä¸‹ï¼Œä½ éœ€è¦ç”¨ä»¥ä¸‹é¸é …é‡æ–°ç·¨è­¯å…§æ ¸::
+
+ CONFIG_BOOT_CONFIG_EMBED=y
+ CONFIG_BOOT_CONFIG_EMBED_FILE="/引導é…ç½®/文件/çš„/路徑"
+
+``CONFIG_BOOT_CONFIG_EMBED_FILE`` 需è¦å¾žæºç¢¼æ¨¹æˆ–å°è±¡æ¨¹é–‹å§‹çš„引導é…置文件的
+絕å°/相å°è·¯å¾‘。內核會將其嵌入作爲默èªå¼•å°Žé…置。
+
+與將引導é…置附加到initrd一樣,你也需è¦åœ¨å…§æ ¸å‘½ä»¤è¡Œä¸Šæ·»åŠ  ``bootconfig`` 告訴
+內核去啓用內嵌的引導é…置。
+
+注æ„,å³ä½¿ä½ å·²ç¶“設置了此é¸é …,ä»å¯ç”¨é™„加到initrd的其他引導é…置覆蓋內嵌的引導
+é…置。
+
+通éŽå¼•å°Žé…置傳éžå…§æ ¸åƒæ•¸
+========================
+
+除了內核命令行,引導é…置也å¯ä»¥ç”¨æ–¼å‚³éžå…§æ ¸åƒæ•¸ã€‚所有 ``kernel`` é—œéµå­—下的éµ
+值å°éƒ½å°‡ç›´æŽ¥å‚³éžçµ¦å…§æ ¸å‘½ä»¤è¡Œã€‚此外, ``init`` 下的éµå€¼å°å°‡é€šéŽå‘½ä»¤è¡Œå‚³éžçµ¦
+init進程。åƒæ•¸æŒ‰ä»¥ä¸‹é †åºèˆ‡ç”¨æˆ¶çµ¦å®šçš„內核命令行字符串相連,因此命令行åƒæ•¸å¯ä»¥
+覆蓋引導é…ç½®åƒæ•¸ï¼ˆé€™å–決於å­ç³»çµ±å¦‚何處ç†åƒæ•¸ï¼Œä½†é€šå¸¸å‰é¢çš„åƒæ•¸å°‡è¢«å¾Œé¢çš„åƒæ•¸
+覆蓋)::
+
+ [bootconfig params][cmdline params] -- [bootconfig init params][cmdline init params]
+
+如果引導é…置文件給出的kernel/initåƒæ•¸æ˜¯::
+
+ kernel {
+ root = 01234567-89ab-cdef-0123-456789abcd
+ }
+ init {
+ splash
+ }
+
+這將被複制到內核命令行字符串中,如下所示::
+
+ root="01234567-89ab-cdef-0123-456789abcd" -- splash
+
+如果用戶給出的其他命令行是::
+
+ ro bootconfig -- quiet
+
+則最後的內核命令行如下::
+
+ root="01234567-89ab-cdef-0123-456789abcd" ro bootconfig -- splash quiet
+
+
+é…置文件的é™åˆ¶
+==============
+
+當å‰æœ€å¤§çš„é…置大å°æ˜¯32KB,關éµå­—總數(ä¸æ˜¯éµå€¼æ¢ç›®ï¼‰å¿…須少於1024個節點。
+注æ„:這ä¸æ˜¯æ¢ç›®æ•¸è€Œæ˜¯ç¯€é»žæ•¸ï¼Œæ¢ç›®å¿…須消耗超éŽ2個節點(一個關éµå­—和一個值)。
+所以從ç†è«–上講最多512個éµå€¼å°ã€‚如果關éµå­—å¹³å‡åŒ…å«3個單詞,則å¯æœ‰256個éµå€¼å°ã€‚
+在大多數情æ³ä¸‹ï¼Œé…置項的數é‡å°‡å°‘æ–¼100個æ¢ç›®ï¼Œå°æ–¼8KB,因此這應該足夠了。如果
+節點數超éŽ1024,解æžå™¨å°‡è¿”回錯誤,å³ä½¿æ–‡ä»¶å¤§å°å°æ–¼32KB。(請注æ„,此最大尺寸
+ä¸åŒ…括填充的空字符。)
+無論如何,因爲 ``bootconfig`` 命令在附加啓動é…置到initrd映åƒæ™‚會驗證它,用戶
+å¯ä»¥åœ¨å¼•å°Žä¹‹å‰æ³¨æ„到它。
+
+
+引導é…ç½®API
+===========
+
+用戶å¯ä»¥æŸ¥è©¢æˆ–éæ­·éµå€¼å°ï¼Œä¹Ÿå¯ä»¥æŸ¥æ‰¾ï¼ˆå‰ç¶´ï¼‰æ ¹é—œéµå­—節點,並在查找該節點下的
+éµå€¼ã€‚
+
+如果您有一個關éµå­—字符串,則å¯ä»¥ç›´æŽ¥ä½¿ç”¨ xbc_find_value() 查詢該éµçš„值。如果
+你想知é“引導é…ç½®è£æœ‰å“ªäº›é—œéµå­—,å¯ä»¥ä½¿ç”¨ xbc_for_each_key_value() 迭代éµå€¼å°ã€‚
+請注æ„,您需è¦ä½¿ç”¨ xbc_array_for_each_value() 訪å•æ•¸çµ„的值,例如::
+
+ vnode = NULL;
+ xbc_find_value("key.word", &vnode);
+ if (vnode && xbc_node_is_array(vnode))
+ xbc_array_for_each_value(vnode, value) {
+ printk("%s ", value);
+ }
+
+如果您想查找具有å‰ç¶´å­—符串的éµï¼Œå¯ä»¥ä½¿ç”¨ xbc_find_node() 通éŽå‰ç¶´å­—符串查找
+節點,然後用 xbc_node_for_each_key_value() 迭代å‰ç¶´ç¯€é»žä¸‹çš„éµã€‚
+
+但最典型的用法是ç²å–å‰ç¶´ä¸‹çš„命å值或å‰ç¶´ä¸‹çš„命å數組,例如::
+
+ root = xbc_find_node("key.prefix");
+ value = xbc_node_find_value(root, "option", &vnode);
+ ...
+ xbc_node_for_each_array_value(root, "array-option", value, anode) {
+ ...
+ }
+
+這將訪å•å€¼â€œkey.prefix.optionâ€çš„值和“key.prefix.array-optionâ€çš„數組。
+
+鎖是ä¸éœ€è¦çš„,因爲在åˆå§‹åŒ–之後é…ç½®åªè®€ã€‚如果需è¦ä¿®æ”¹ï¼Œå¿…須複製所有數據和關éµå­—。
+
+
+函數與çµæ§‹é«”
+============
+
+相關定義的kernel-docåƒè¦‹ï¼š
+
+ - include/linux/bootconfig.h
+ - lib/bootconfig.c
+
diff --git a/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst b/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst
index b448dbf5ac87..3f10a9f8f223 100644
--- a/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst
+++ b/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst
@@ -17,14 +17,14 @@
引言
=====
-始終嘗試由來自kernel.org的原始碼構建的最新內核。如果您沒有信心這樣åšï¼Œè«‹å°‡
+始終嘗試由來自kernel.orgçš„æºä»£ç¢¼æ§‹å»ºçš„最新內核。如果您沒有信心這樣åšï¼Œè«‹å°‡
錯誤報告給您的發行版供應商,而ä¸æ˜¯å…§æ ¸é–‹ç™¼äººå“¡ã€‚
找到缺陷(bug)並ä¸ç¸½æ˜¯é‚£éº¼å®¹æ˜“,ä¸éŽä»ç„¶å¾—去找。如果你找ä¸åˆ°å®ƒï¼Œä¸è¦æ”¾æ£„。
-儘å¯èƒ½å¤šçš„å‘相關維護人員報告您發ç¾çš„ä¿¡æ¯ã€‚è«‹åƒé–±MAINTAINERS文件以了解您所
+儘å¯èƒ½å¤šçš„å‘相關維護人員報告您發ç¾çš„ä¿¡æ¯ã€‚è«‹åƒé–±MAINTAINERS文件以瞭解您所
關注的å­ç³»çµ±çš„維護人員。
-在æ交錯誤報告之å‰ï¼Œè«‹é–±è®€ã€ŒDocumentation/admin-guide/reporting-issues.rstã€ã€‚
+在æ交錯誤報告之å‰ï¼Œè«‹é–±è®€â€œDocumentation/admin-guide/reporting-issues.rstâ€ã€‚
設備未出ç¾ï¼ˆDevices not appearing)
====================================
@@ -38,7 +38,7 @@
æ“作步驟:
-- 從git原始碼構建內核
+- 從gitæºä»£ç¢¼æ§‹å»ºå…§æ ¸
- 以此開始二分 [#f1]_::
$ git bisect start
@@ -76,7 +76,7 @@
如需進一步åƒè€ƒï¼Œè«‹é–±è®€ï¼š
- ``git-bisect`` 的手冊é 
-- `Fighting regressions with git bisect(用git bisect解決回歸)
+- `Fighting regressions with git bisect(用git bisect解決迴歸)
<https://www.kernel.org/pub/software/scm/git/docs/git-bisect-lk2009.html>`_
- `Fully automated bisecting with "git bisect run"(使用git bisect run
來全自動二分) <https://lwn.net/Articles/317154>`_
diff --git a/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst b/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst
index 9a3de3bff5e7..631fd2650929 100644
--- a/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst
+++ b/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst
@@ -48,8 +48,8 @@
[<c1549f43>] ? sysenter_past_esp+0x40/0x6a
---[ end trace 6ebc60ef3981792f ]---
-這樣的堆棧跟蹤æ供了足夠的信æ¯ä¾†è­˜åˆ¥å…§æ ¸åŽŸå§‹ç¢¼ä¸­ç™¼ç”ŸéŒ¯èª¤çš„那一行。根據å•é¡Œçš„
-åš´é‡æ€§ï¼Œå®ƒé‚„å¯èƒ½åŒ…å« **「Oopsã€** 一詞,比如::
+這樣的堆棧跟蹤æ供了足夠的信æ¯ä¾†è­˜åˆ¥å…§æ ¸æºä»£ç¢¼ä¸­ç™¼ç”ŸéŒ¯èª¤çš„那一行。根據å•é¡Œçš„
+åš´é‡æ€§ï¼Œå®ƒé‚„å¯èƒ½åŒ…å« **“Oopsâ€** 一詞,比如::
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<c06969d4>] iret_exc+0x7d0/0xa59
@@ -58,17 +58,17 @@
...
儘管有 **Oops** 或其他類型的堆棧跟蹤,但通常需è¦æ‰¾åˆ°å‡ºå•é¡Œçš„行來識別和處ç†ç¼º
-陷。在本章中,我們將åƒè€ƒã€ŒOopsã€ä¾†äº†è§£éœ€è¦åˆ†æžçš„å„種堆棧跟蹤。
+陷。在本章中,我們將åƒè€ƒâ€œOopsâ€ä¾†äº†è§£éœ€è¦åˆ†æžçš„å„種堆棧跟蹤。
如果內核是用 ``CONFIG_DEBUG_INFO`` 編譯的,那麼å¯ä»¥ä½¿ç”¨æ–‡ä»¶ï¼š
`scripts/decode_stacktrace.sh` 。
-連çµçš„模塊
+éˆæŽ¥çš„模塊
-----------
-å—到汙染或正在加載/å¸è¼‰çš„模塊用「(…)ã€æ¨™è¨˜ï¼Œæ±™æŸ“標誌在
-`Documentation/admin-guide/tainted-kernels.rst` 文件中進行了æ述,「正在被加
-載ã€ç”¨ã€Œ+ã€æ¨™è¨»ï¼Œã€Œæ­£åœ¨è¢«å¸è¼‰ã€ç”¨ã€Œ-ã€æ¨™è¨»ã€‚
+å—到污染或正在加載/å¸è¼‰çš„模塊用“(…)â€æ¨™è¨˜ï¼Œæ±¡æŸ“標誌在
+`Documentation/admin-guide/tainted-kernels.rst` 文件中進行了æ述,“正在被加
+載â€ç”¨â€œ+â€æ¨™è¨»ï¼Œâ€œæ­£åœ¨è¢«å¸è¼‰â€ç”¨â€œ-â€æ¨™è¨»ã€‚
Oops消æ¯åœ¨å“ªï¼Ÿ
@@ -81,19 +81,19 @@ syslog文件,通常是 ``/var/log/messages`` (å–決於 ``/etc/syslog.conf``
有時 ``klogd`` 會掛掉,這種情æ³ä¸‹æ‚¨å¯ä»¥é‹è¡Œ ``dmesg > file`` 從內核緩è¡å€
讀å–數據並ä¿å­˜å®ƒã€‚或者您å¯ä»¥ ``cat /proc/kmsg > file`` ,但是您必須é©æ™‚
-中斷以åœæ­¢å‚³è¼¸ï¼Œå› çˆ² ``kmsg`` 是一個「永無止境的文件ã€ã€‚
+中斷以åœæ­¢å‚³è¼¸ï¼Œå› çˆ² ``kmsg`` 是一個“永無止境的文件â€ã€‚
-如果機器嚴é‡å´©æ½°ï¼Œç„¡æ³•è¼¸å…¥å‘½ä»¤æˆ–ç£ç¢Ÿä¸å¯ç”¨ï¼Œé‚£é‚„有三個é¸é …:
+如果機器嚴é‡å´©æ½°ï¼Œç„¡æ³•è¼¸å…¥å‘½ä»¤æˆ–ç£ç›¤ä¸å¯ç”¨ï¼Œé‚£é‚„有三個é¸é …:
(1) 手動複製å±å¹•ä¸Šçš„文本,並在機器é‡æ–°å•“動後輸入。很難å—,但這是çªç„¶å´©æ½°ä¸‹
- 唯一的é¸æ“‡ã€‚或者你å¯ä»¥ç”¨æ•¸ä½ç›¸æ©Ÿæ‹ä¸‹å±å¹•â€”—雖然ä¸é‚£éº¼å¥½ï¼Œä½†ç¸½æ¯”什麼都沒
- 有好。如果消æ¯æ»¾å‹•è¶…出控制å°é ‚部,使用更高解æžåº¦ï¼ˆä¾‹å¦‚ ``vga=791`` )
- 引導啓動將å…è¨±æ‚¨é–±è®€æ›´å¤šæ–‡æœ¬ã€‚ï¼ˆè­¦å‘Šï¼šé€™éœ€è¦ ``vesafb`` ,因此å°ã€Œæ—©æœŸã€
+ 唯一的é¸æ“‡ã€‚或者你å¯ä»¥ç”¨æ•¸ç¢¼ç›¸æ©Ÿæ‹ä¸‹å±å¹•â€”—雖然ä¸é‚£éº¼å¥½ï¼Œä½†ç¸½æ¯”什麼都沒
+ 有好。如果消æ¯æ»¾å‹•è¶…出控制檯頂部,使用更高分辨率(例如 ``vga=791`` )
+ 引導啓動將å…è¨±æ‚¨é–±è®€æ›´å¤šæ–‡æœ¬ã€‚ï¼ˆè­¦å‘Šï¼šé€™éœ€è¦ ``vesafb`` ,因此å°â€œæ—©æœŸâ€
的Oppses沒有幫助)
(2) 從串å£çµ‚端啓動(åƒè¦‹
:ref:`Documentation/admin-guide/serial-console.rst <serial_console>` ),
- 在å¦ä¸€å°æ©Ÿå™¨ä¸Šé‹è¡Œæ•¸æ“šæ©Ÿç„¶å¾Œç”¨ä½ å–œæ­¡çš„通信程åºæ•ç²è¼¸å‡ºã€‚
+ 在å¦ä¸€è‡ºæ©Ÿå™¨ä¸Šé‹è¡Œèª¿åˆ¶è§£èª¿å™¨ç„¶å¾Œç”¨ä½ å–œæ­¡çš„通信程åºæ•ç²è¼¸å‡ºã€‚
Minicomé‹è¡Œè‰¯å¥½ã€‚
(3) 使用Kdump(åƒé–± Documentation/admin-guide/kdump/kdump.rst ),使用
@@ -103,7 +103,7 @@ syslog文件,通常是 ``/var/log/messages`` (å–決於 ``/etc/syslog.conf``
找到缺陷ä½ç½®
-------------
-如果你能指出缺陷在內核原始碼中的ä½ç½®ï¼Œå‰‡å ±å‘Šç¼ºé™·çš„效果會éžå¸¸å¥½ã€‚這有兩種方法。
+如果你能指出缺陷在內核æºä»£ç¢¼ä¸­çš„ä½ç½®ï¼Œå‰‡å ±å‘Šç¼ºé™·çš„效果會éžå¸¸å¥½ã€‚這有兩種方法。
通常來說使用 ``gdb`` 會比較容易,ä¸éŽå…§æ ¸éœ€è¦ç”¨èª¿è©¦ä¿¡æ¯ä¾†é ç·¨è­¯ã€‚
gdb
@@ -187,7 +187,7 @@ GNU 調試器(GNU debugger, ``gdb`` )是從 ``vmlinux`` 文件中找出OOP
objdump
^^^^^^^^
-è¦èª¿è©¦å…§æ ¸ï¼Œè«‹ä½¿ç”¨objdump並從崩潰輸出中查找å六進ä½å移,以找到有效的代碼/匯
+è¦èª¿è©¦å…§æ ¸ï¼Œè«‹ä½¿ç”¨objdump並從崩潰輸出中查找å六進制å移,以找到有效的代碼/匯
編行。如果沒有調試符號,您將看到所示例程的彙編程åºä»£ç¢¼ï¼Œä½†æ˜¯å¦‚果內核有調試
符號,C代碼也將å¯è¦‹ï¼ˆèª¿è©¦ç¬¦è™Ÿå¯ä»¥åœ¨å…§æ ¸é…ç½®èœå–®çš„hacking項中啓用)。例如::
@@ -197,7 +197,7 @@ objdump
您需è¦è™•æ–¼å…§æ ¸æ¨¹çš„頂層以便此ç²å¾—您的C文件。
-如果您無法訪å•åŽŸå§‹ç¢¼ï¼Œä»ç„¶å¯ä»¥ä½¿ç”¨ä»¥ä¸‹æ–¹æ³•èª¿è©¦ä¸€äº›å´©æ½°è½‰å„²ï¼ˆå¦‚Dave Millerçš„
+如果您無法訪å•æºä»£ç¢¼ï¼Œä»ç„¶å¯ä»¥ä½¿ç”¨ä»¥ä¸‹æ–¹æ³•èª¿è©¦ä¸€äº›å´©æ½°è½‰å„²ï¼ˆå¦‚Dave Millerçš„
示例崩潰轉儲輸出所示)::
EIP is at +0x14/0x4c0
@@ -234,9 +234,9 @@ objdump
報告缺陷
---------
-一旦你通éŽå®šä½ç¼ºé™·æ‰¾åˆ°äº†å…¶ç™¼ç”Ÿçš„地方,你å¯ä»¥å˜—試自己修復它或者å‘上游報告它。
+一旦你通éŽå®šä½ç¼ºé™·æ‰¾åˆ°äº†å…¶ç™¼ç”Ÿçš„地方,你å¯ä»¥å˜—試自己修復它或者å‘上éŠå ±å‘Šå®ƒã€‚
-爲了å‘上游報告,您應該找出用於開發å—影響代碼的郵件列表。這å¯ä»¥ä½¿ç”¨ ``get_maintainer.pl`` 。
+爲了å‘上éŠå ±å‘Šï¼Œæ‚¨æ‡‰è©²æ‰¾å‡ºç”¨æ–¼é–‹ç™¼å—影響代碼的郵件列表。這å¯ä»¥ä½¿ç”¨ ``get_maintainer.pl`` 。
例如,您在gspcaçš„sonixj.c文件中發ç¾ä¸€å€‹ç¼ºé™·ï¼Œå‰‡å¯ä»¥é€šéŽä»¥ä¸‹æ–¹æ³•æ‰¾åˆ°å®ƒçš„維護者::
@@ -251,7 +251,7 @@ objdump
請注æ„它將指出:
-- 最後接觸原始碼的開發人員(如果這是在git樹中完æˆçš„)。在上é¢çš„例å­ä¸­æ˜¯Tejun
+- 最後接觸æºä»£ç¢¼çš„開發人員(如果這是在git樹中完æˆçš„)。在上é¢çš„例å­ä¸­æ˜¯Tejun
å’ŒBhaktipriya(在這個特定的案例中,沒有人真正åƒèˆ‡é€™å€‹æ–‡ä»¶çš„開發);
- 驅動維護人員(Hans Verkuil);
- å­ç³»çµ±ç¶­è­·äººå“¡ï¼ˆMauro Carvalho Chehab);
diff --git a/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst b/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst
index bd0c08aab8ea..6961006b4a2d 100644
--- a/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst
+++ b/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst
@@ -7,10 +7,10 @@
清除 WARN_ONCE
--------------
-WARN_ONCE / WARN_ON_ONCE / printk_once 僅僅列å°ä¸€æ¬¡æ¶ˆæ¯.
+WARN_ONCE / WARN_ON_ONCE / printk_once 僅僅打å°ä¸€æ¬¡æ¶ˆæ¯.
echo 1 > /sys/kernel/debug/clear_warn_once
-å¯ä»¥æ¸…除這種狀態並且å†æ¬¡å…許列å°ä¸€æ¬¡å‘Šè­¦ä¿¡æ¯ï¼Œé€™å°æ–¼é‹è¡Œæ¸¬è©¦é›†å¾Œé‡ç¾å•é¡Œ
+å¯ä»¥æ¸…除這種狀態並且å†æ¬¡å…許打å°ä¸€æ¬¡å‘Šè­¦ä¿¡æ¯ï¼Œé€™å°æ–¼é‹è¡Œæ¸¬è©¦é›†å¾Œé‡ç¾å•é¡Œ
很有用。
diff --git a/Documentation/translations/zh_TW/admin-guide/cpu-load.rst b/Documentation/translations/zh_TW/admin-guide/cpu-load.rst
index 9e04aeac1a5c..cc046f3b7ffa 100644
--- a/Documentation/translations/zh_TW/admin-guide/cpu-load.rst
+++ b/Documentation/translations/zh_TW/admin-guide/cpu-load.rst
@@ -20,13 +20,13 @@ Linux通éŽ``/proc/stat``å’Œ``/proc/uptime``導出å„種信æ¯ï¼Œç”¨æˆ¶ç©ºé–“å·¥
...
-這裡系統èªçˆ²åœ¨é»˜èªæŽ¡æ¨£å‘¨æœŸå…§æœ‰10.01%的時間工作在用戶空間,2.92%的時
+這è£ç³»çµ±èªçˆ²åœ¨é»˜èªæŽ¡æ¨£é€±æœŸå…§æœ‰10.01%的時間工作在用戶空間,2.92%的時
間用在系統空間,總體上有81.63%的時間是空閒的。
大多數情æ³ä¸‹``/proc/stat``çš„ä¿¡æ¯å¹¾ä¹ŽçœŸå¯¦å映了系統信æ¯ï¼Œç„¶è€Œï¼Œç”±æ–¼å…§
核採集這些數據的方å¼/時間的特點,有時這些信æ¯æ ¹æœ¬ä¸å¯é ã€‚
-那麼這些信æ¯æ˜¯å¦‚何被æœé›†çš„呢?æ¯ç•¶æ™‚間中斷觸發時,內核查看此刻é‹è¡Œçš„
+那麼這些信æ¯æ˜¯å¦‚何被è’集的呢?æ¯ç•¶æ™‚間中斷觸發時,內核查看此刻é‹è¡Œçš„
進程類型,並增加與此類型/狀態進程å°æ‡‰çš„計數器的值。這種方法的å•é¡Œæ˜¯
在兩次時間中斷之間系統(進程)能夠在多種狀態之間切æ›å¤šæ¬¡ï¼Œè€Œè¨ˆæ•¸å™¨åª
增加最後一種狀態下的計數。
@@ -34,7 +34,7 @@ Linux通éŽ``/proc/stat``å’Œ``/proc/uptime``導出å„種信æ¯ï¼Œç”¨æˆ¶ç©ºé–“å·¥
舉例
---
-å‡è¨­ç³»çµ±æœ‰ä¸€å€‹é€²ç¨‹ä»¥å¦‚下方å¼å‘¨æœŸæ€§åœ°å ç”¨cpu::
+å‡è¨­ç³»çµ±æœ‰ä¸€å€‹é€²ç¨‹ä»¥å¦‚下方å¼é€±æœŸæ€§åœ°ä½”用cpu::
兩個時é˜ä¸­æ–·ä¹‹é–“的時間線
|-----------------------|
@@ -46,7 +46,7 @@ Linux通éŽ``/proc/stat``å’Œ``/proc/uptime``導出å„種信æ¯ï¼Œç”¨æˆ¶ç©ºé–“å·¥
在上é¢çš„情æ³ä¸‹ï¼Œæ ¹æ“š``/proc/stat``çš„ä¿¡æ¯ï¼ˆç”±æ–¼ç•¶ç³»çµ±è™•æ–¼ç©ºé–’狀態時,
時間中斷經常會發生)系統的負載將會是0
-大家能夠想åƒå…§æ ¸çš„這種行爲會發生在許多情æ³ä¸‹ï¼Œé€™å°‡å°Žè‡´``/proc/stat``
+大家能夠想象內核的這種行爲會發生在許多情æ³ä¸‹ï¼Œé€™å°‡å°Žè‡´``/proc/stat``
中存在相當å¤æ€ªçš„ä¿¡æ¯::
/* gcc -o hog smallhog.c */
diff --git a/Documentation/translations/zh_TW/admin-guide/cputopology.rst b/Documentation/translations/zh_TW/admin-guide/cputopology.rst
new file mode 100644
index 000000000000..5c46d1b3b065
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/cputopology.rst
@@ -0,0 +1,97 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/cputopology.rst
+
+:翻譯:
+
+ å”è—舟 Tang Yizhou <tangyeechou@gmail.com>
+
+==========================
+如何通éŽsysfså°‡CPU拓撲導出
+==========================
+
+CPU拓撲信æ¯é€šéŽsysfs導出。顯示的項(屬性)和æŸäº›æž¶æ§‹çš„/proc/cpuinfo輸出相似。它們ä½æ–¼
+/sys/devices/system/cpu/cpuX/topology/。請閱讀ABI文件:
+Documentation/ABI/stable/sysfs-devices-system-cpu。
+
+drivers/base/topology.c是體系çµæ§‹ä¸­æ€§çš„,它導出了這些屬性。然而,dieã€clusterã€bookã€
+draw這些層次çµæ§‹ç›¸é—œçš„文件僅在體系çµæ§‹æ供了下文æè¿°çš„å®çš„æ¢ä»¶ä¸‹è¢«å‰µå»ºã€‚
+
+å°æ–¼æ”¯æŒé€™å€‹ç‰¹æ€§çš„體系çµæ§‹ï¼Œå®ƒå¿…須在include/asm-XXX/topology.h中定義這些å®ä¸­çš„一部分::
+
+ #define topology_physical_package_id(cpu)
+ #define topology_die_id(cpu)
+ #define topology_cluster_id(cpu)
+ #define topology_core_id(cpu)
+ #define topology_book_id(cpu)
+ #define topology_drawer_id(cpu)
+ #define topology_sibling_cpumask(cpu)
+ #define topology_core_cpumask(cpu)
+ #define topology_cluster_cpumask(cpu)
+ #define topology_die_cpumask(cpu)
+ #define topology_book_cpumask(cpu)
+ #define topology_drawer_cpumask(cpu)
+
+``**_id macros`` 的類型是int。
+``**_cpumask macros`` 的類型是 ``(const) struct cpumask *`` 。後者和æ°ç•¶çš„
+``**_siblings`` sysfs屬性å°æ‡‰ï¼ˆé™¤äº†topology_sibling_cpumask(),它和thread_siblings
+å°æ‡‰ï¼‰ã€‚
+
+爲了在所有體系çµæ§‹ä¸Šä¿æŒä¸€è‡´ï¼Œinclude/linux/topology.hæ供了上述所有å®çš„默èªå®šç¾©ï¼Œä»¥é˜²
+它們未在include/asm-XXX/topology.h中定義:
+
+1) topology_physical_package_id: -1
+2) topology_die_id: -1
+3) topology_cluster_id: -1
+4) topology_core_id: 0
+5) topology_book_id: -1
+6) topology_drawer_id: -1
+7) topology_sibling_cpumask: 僅入åƒCPU
+8) topology_core_cpumask: 僅入åƒCPU
+9) topology_cluster_cpumask: 僅入åƒCPU
+10) topology_die_cpumask: 僅入åƒCPU
+11) topology_book_cpumask: 僅入åƒCPU
+12) topology_drawer_cpumask: 僅入åƒCPU
+
+此外,CPU拓撲信æ¯ç”±/sys/devices/system/cpuæ供,包å«ä¸‹è¿°æ–‡ä»¶ã€‚輸出å°æ‡‰çš„內部數據æºæ”¾åœ¨
+方括號("[]")中。
+
+ =========== ==================================================================
+ kernel_max: 內核é…ç½®å…許的最大CPU下標值。[NR_CPUS-1]
+
+ offline: 由於熱æ’拔移除或者超éŽå…§æ ¸å…許的CPU上é™ï¼ˆä¸Šæ–‡æè¿°çš„kernel_max)
+ 導致未上線的CPU。[~cpu_online_mask + cpus >= NR_CPUS]
+
+ online: 在線的CPU,å¯ä¾›èª¿åº¦ä½¿ç”¨ã€‚[cpu_online_mask]
+
+ possible: 已被分é…資æºçš„CPU,如果它們CPU實際存在,å¯ä»¥ä¸Šç·šã€‚
+ [cpu_possible_mask]
+
+ present: 被系統識別實際存在的CPU。[cpu_present_mask]
+ =========== ==================================================================
+
+上述輸出的格å¼å’Œcpulist_parse()兼容[åƒè¦‹ <linux/cpumask.h>]。下é¢çµ¦äº›ä¾‹å­ã€‚
+
+在本例中,系統中有64個CPU,但是CPU 32-63超éŽäº†kernel_max值,因爲NR_CPUSé…置項是32,
+å–值範åœè¢«é™åˆ¶çˆ²0..31。此外注æ„CPU2å’Œ4-31未上線,但是å¯ä»¥ä¸Šç·šï¼Œå› çˆ²å®ƒå€‘åŒæ™‚存在於
+presentå’Œpossible::
+
+ kernel_max: 31
+ offline: 2,4-31,32-63
+ online: 0-1,3
+ possible: 0-31
+ present: 0-31
+
+在本例中,NR_CPUSé…置項是128,但內核啓動時設置possible_cpus=144。系統中有4個CPU,
+CPU2被手動設置下線(也是唯一一個å¯ä»¥ä¸Šç·šçš„CPU)::
+
+ kernel_max: 127
+ offline: 2,4-127,128-143
+ online: 0-1,3
+ possible: 0-127
+ present: 0-3
+
+閱讀Documentation/core-api/cpu_hotplug.rstå¯çž­è§£é–‹æ©Ÿåƒæ•¸possible_cpus=NUM,åŒæ™‚é‚„
+å¯ä»¥çž­è§£å„種cpumaskçš„ä¿¡æ¯ã€‚
+
diff --git a/Documentation/translations/zh_TW/admin-guide/index.rst b/Documentation/translations/zh_TW/admin-guide/index.rst
index 2804d619201d..aba8939351e0 100644
--- a/Documentation/translations/zh_TW/admin-guide/index.rst
+++ b/Documentation/translations/zh_TW/admin-guide/index.rst
@@ -3,13 +3,14 @@
.. include:: ../disclaimer-zh_TW.rst
:Original: :doc:`../../../admin-guide/index`
-:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
+:Translator: Alex Shi <alex.shi@linux.alibaba.com>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
Linux 內核用戶和管ç†å“¡æŒ‡å—
==========================
下é¢æ˜¯ä¸€çµ„隨時間添加到內核中的é¢å‘用戶的文檔的集åˆã€‚到目å‰çˆ²æ­¢ï¼Œé‚„沒有一個
-整體的順åºæˆ–組織 - 這些ææ–™ä¸æ˜¯ä¸€å€‹å–®ä¸€çš„,連貫的文件ï¼å¹¸é‹çš„話,情æ³æœƒéš¨è‘—
+整體的順åºæˆ–組織 - 這些ææ–™ä¸æ˜¯ä¸€å€‹å–®ä¸€çš„,連貫的文件ï¼å¹¸é‹çš„話,情æ³æœƒéš¨ç€
時間的推移而迅速改善。
這個åˆå§‹éƒ¨åˆ†åŒ…å«ç¸½é«”ä¿¡æ¯ï¼ŒåŒ…括æ述內核的README, 關於內核åƒæ•¸çš„文檔等。
@@ -21,15 +22,15 @@ Linux 內核用戶和管ç†å“¡æŒ‡å—
Todolist:
- kernel-parameters
- devices
- sysctl/index
+* kernel-parameters
+* devices
+* sysctl/index
本節介紹CPUæ¼æ´žåŠå…¶ç·©è§£æŽªæ–½ã€‚
Todolist:
- hw-vuln/index
+* hw-vuln/index
下é¢çš„一組文檔,é‡å°çš„是試圖跟蹤å•é¡Œå’Œbug的用戶。
@@ -37,6 +38,7 @@ Todolist:
:maxdepth: 1
reporting-issues
+ reporting-regressions
security-bugs
bug-hunting
bug-bisect
@@ -45,18 +47,17 @@ Todolist:
Todolist:
- reporting-bugs
- ramoops
- dynamic-debug-howto
- kdump/index
- perf/index
+* ramoops
+* dynamic-debug-howto
+* kdump/index
+* perf/index
-這是應用程å¼é–‹ç™¼äººå“¡æ„Ÿèˆˆè¶£çš„章節的開始。å¯ä»¥åœ¨é€™è£¡æ‰¾åˆ°æ¶µè“‹å…§æ ¸ABIå„個
+這是應用程åºé–‹ç™¼äººå“¡æ„Ÿèˆˆè¶£çš„章節的開始。å¯ä»¥åœ¨é€™è£æ‰¾åˆ°æ¶µè“‹å…§æ ¸ABIå„個
æ–¹é¢çš„文檔。
Todolist:
- sysfs-rules
+* sysfs-rules
本手冊的其餘部分包括å„種指å—,介紹如何根據您的喜好é…置內核的特定行爲。
@@ -64,67 +65,67 @@ Todolist:
.. toctree::
:maxdepth: 1
+ bootconfig
clearing-warn-once
cpu-load
+ cputopology
+ lockup-watchdogs
unicode
+ sysrq
+ mm/index
Todolist:
- acpi/index
- aoe/index
- auxdisplay/index
- bcache
- binderfs
- binfmt-misc
- blockdev/index
- bootconfig
- braille-console
- btmrvl
- cgroup-v1/index
- cgroup-v2
- cifs/index
- cputopology
- dell_rbu
- device-mapper/index
- edid
- efi-stub
- ext4
- nfs/index
- gpio/index
- highuid
- hw_random
- initrd
- iostats
- java
- jfs
- kernel-per-CPU-kthreads
- laptops/index
- lcd-panel-cgram
- ldm
- lockup-watchdogs
- LSM/index
- md
- media/index
- mm/index
- module-signing
- mono
- namespaces/index
- numastat
- parport
- perf-security
- pm/index
- pnp
- rapidio
- ras
- rtc
- serial-console
- svga
- sysrq
- thunderbolt
- ufs
- vga-softcursor
- video-output
- xfs
+* acpi/index
+* aoe/index
+* auxdisplay/index
+* bcache
+* binderfs
+* binfmt-misc
+* blockdev/index
+* braille-console
+* btmrvl
+* cgroup-v1/index
+* cgroup-v2
+* cifs/index
+* dell_rbu
+* device-mapper/index
+* edid
+* efi-stub
+* ext4
+* nfs/index
+* gpio/index
+* highuid
+* hw_random
+* initrd
+* iostats
+* java
+* jfs
+* kernel-per-CPU-kthreads
+* laptops/index
+* lcd-panel-cgram
+* ldm
+* LSM/index
+* md
+* media/index
+* module-signing
+* mono
+* namespaces/index
+* numastat
+* parport
+* perf-security
+* pm/index
+* pnp
+* rapidio
+* ras
+* rtc
+* serial-console
+* svga
+* thunderbolt
+* ufs
+* vga-softcursor
+* video-output
+* xfs
.. only:: subproject and html
diff --git a/Documentation/translations/zh_TW/admin-guide/init.rst b/Documentation/translations/zh_TW/admin-guide/init.rst
index db3fdf611080..be6e34f5f7fa 100644
--- a/Documentation/translations/zh_TW/admin-guide/init.rst
+++ b/Documentation/translations/zh_TW/admin-guide/init.rst
@@ -9,8 +9,8 @@
å³æƒ³æˆ Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com>
-解釋「No working init found.ã€å•“動掛起消æ¯
-==========================================
+解釋“No working init found.â€å•“動掛起消æ¯
+=========================================
:作者:
@@ -18,41 +18,41 @@
Cristian Souza <cristianmsbr at gmail period com>
-本文檔æ供了加載åˆå§‹åŒ–二進ä½ï¼ˆinit binary)失敗的一些高層級原因(大致按執行
+本文檔æ供了加載åˆå§‹åŒ–二進制(init binary)失敗的一些高層級原因(大致按執行
é †åºåˆ—出)。
-1) **無法掛載根文件系統Unable to mount root FS** :請設置「debugã€å…§æ ¸åƒæ•¸ï¼ˆåœ¨
+1) **無法掛載根文件系統Unable to mount root FS** :請設置“debugâ€å…§æ ¸åƒæ•¸ï¼ˆåœ¨
引導加載程åºbootloaderé…置文件或CONFIG_CMDLINE)以ç²å–更詳細的內核消æ¯ã€‚
-2) **åˆå§‹åŒ–二進ä½ä¸å­˜åœ¨æ–¼æ ¹æ–‡ä»¶ç³»çµ±ä¸Šinit binary doesn't exist on rootfs** :
+2) **åˆå§‹åŒ–二進制ä¸å­˜åœ¨æ–¼æ ¹æ–‡ä»¶ç³»çµ±ä¸Šinit binary doesn't exist on rootfs** :
確ä¿æ‚¨çš„根文件系統類型正確(並且 ``root=`` 內核åƒæ•¸æŒ‡å‘正確的分å€ï¼‰ï¼›æ“有
- 所需的驅動程åºï¼Œä¾‹å¦‚SCSI或USB等存儲硬體;文件系統(ext3ã€jffs2等)是內建的
+ 所需的驅動程åºï¼Œä¾‹å¦‚SCSI或USB等存儲硬件;文件系統(ext3ã€jffs2等)是內建的
(或者作爲模塊由initrdé åŠ è¼‰ï¼‰ã€‚
-3) **控制å°è¨­å‚™æ壞Broken console device** : ``console= setup`` 中å¯èƒ½å­˜åœ¨
- è¡çª --> åˆå§‹æŽ§åˆ¶å°ä¸å¯ç”¨ï¼ˆinitial console unavailable)。例如,由於串行
- IRQå•é¡Œï¼ˆå¦‚缺少基於中斷的é…置)導致的æŸäº›ä¸²è¡ŒæŽ§åˆ¶å°ä¸å¯é ã€‚嘗試使用ä¸åŒçš„
+3) **控制檯設備æ壞Broken console device** : ``console= setup`` 中å¯èƒ½å­˜åœ¨
+ è¡çª --> åˆå§‹æŽ§åˆ¶æª¯ä¸å¯ç”¨ï¼ˆinitial console unavailable)。例如,由於串行
+ IRQå•é¡Œï¼ˆå¦‚缺少基於中斷的é…置)導致的æŸäº›ä¸²è¡ŒæŽ§åˆ¶æª¯ä¸å¯é ã€‚嘗試使用ä¸åŒçš„
``console= device`` æˆ–åƒ ``netconsole=`` 。
-4) **二進ä½å­˜åœ¨ä½†ä¾è³´é …ä¸å¯ç”¨Binary exists but dependencies not available** :
- 例如åˆå§‹åŒ–二進ä½çš„必需庫ä¾è³´é …ï¼Œåƒ ``/lib/ld-linux.so.2`` 丟失或æ壞。使用
+4) **二進制存在但ä¾è³´é …ä¸å¯ç”¨Binary exists but dependencies not available** :
+ 例如åˆå§‹åŒ–二進制的必需庫ä¾è³´é …ï¼Œåƒ ``/lib/ld-linux.so.2`` 丟失或æ壞。使用
``readelf -d <INIT>|grep NEEDED`` 找出需è¦å“ªäº›åº«ã€‚
-5) **無法加載二進ä½Binary cannot be loaded** :請確ä¿äºŒé€²ä½çš„體系çµæ§‹èˆ‡æ‚¨çš„
- 硬體匹é…。例如i386ä¸åŒ¹é…x86_64,或者嘗試在ARM硬體上加載x86。如果您嘗試在
- 此處加載éžäºŒé€²ä½æ–‡ä»¶ï¼ˆshell腳本?),您應該確ä¿è…³æœ¬åœ¨å…¶å·¥ä½œé ­ï¼ˆshebang
+5) **無法加載二進制Binary cannot be loaded** :請確ä¿äºŒé€²åˆ¶çš„體系çµæ§‹èˆ‡æ‚¨çš„
+ 硬件匹é…。例如i386ä¸åŒ¹é…x86_64,或者嘗試在ARM硬件上加載x86。如果您嘗試在
+ 此處加載éžäºŒé€²åˆ¶æ–‡ä»¶ï¼ˆshell腳本?),您應該確ä¿è…³æœ¬åœ¨å…¶å·¥ä½œé ­ï¼ˆshebang
header)行 ``#!/...`` 中指定能正常工作的解釋器(包括其庫ä¾è³´é …)。在處ç†
- 腳本之å‰ï¼Œæœ€å¥½å…ˆæ¸¬è©¦ä¸€å€‹ç°¡å–®çš„éžè…³æœ¬äºŒé€²ä½æ–‡ä»¶ï¼Œæ¯”如 ``/bin/sh`` ,並確èª
+ 腳本之å‰ï¼Œæœ€å¥½å…ˆæ¸¬è©¦ä¸€å€‹ç°¡å–®çš„éžè…³æœ¬äºŒé€²åˆ¶æ–‡ä»¶ï¼Œæ¯”如 ``/bin/sh`` ,並確èª
它能æˆåŠŸåŸ·è¡Œã€‚è¦äº†è§£æ›´å¤šä¿¡æ¯ï¼Œè«‹å°‡ä»£ç¢¼æ·»åŠ åˆ° ``init/main.c`` 以顯示
kernel_execve()的返回值。
-當您發ç¾æ–°çš„失敗原因時,請擴展本解釋(畢竟加載åˆå§‹åŒ–二進ä½æ˜¯ä¸€å€‹ **é—œéµ** 且
+當您發ç¾æ–°çš„失敗原因時,請擴展本解釋(畢竟加載åˆå§‹åŒ–二進制是一個 **é—œéµ** 且
艱難的éŽæ¸¡æ­¥é©Ÿï¼Œéœ€è¦å„˜å¯èƒ½ç„¡ç—›åœ°é€²è¡Œï¼‰ï¼Œç„¶å¾Œå‘LKMLæ交一個補ä¸ã€‚
待辦事項:
- 通éŽä¸€å€‹å¯ä»¥å­˜å„² ``kernel_execve()`` çµæžœå€¼çš„çµæ§‹é«”數組實ç¾å„種
- ``run_init_process()`` 調用,並在失敗時通éŽç–Šä»£ **所有** çµæžœä¾†è¨˜éŒ„一切
+ ``run_init_process()`` 調用,並在失敗時通éŽè¿­ä»£ **所有** çµæžœä¾†è¨˜éŒ„一切
(éžå¸¸é‡è¦çš„å¯ç”¨æ€§ä¿®å¾©ï¼‰ã€‚
-- 試著使實ç¾æœ¬èº«åœ¨ä¸€èˆ¬æƒ…æ³ä¸‹æ›´æœ‰å¹«åŠ©ï¼Œä¾‹å¦‚在å—影響的地方æä¾›é¡å¤–的錯誤消æ¯ã€‚
+- 試ç€ä½¿å¯¦ç¾æœ¬èº«åœ¨ä¸€èˆ¬æƒ…æ³ä¸‹æ›´æœ‰å¹«åŠ©ï¼Œä¾‹å¦‚在å—影響的地方æä¾›é¡å¤–的錯誤消æ¯ã€‚
diff --git a/Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst b/Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst
new file mode 100644
index 000000000000..f65b0c96e8e3
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst
@@ -0,0 +1,67 @@
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/lockup-watchdogs.rst
+:Translator: Hailong Liu <liu.hailong6@zte.com.cn>
+
+.. _tw_lockup-watchdogs:
+
+
+=================================================
+Softlockup與hardlockup檢測機制(åˆå:nmi_watchdog)
+=================================================
+
+Linux中內核實ç¾äº†ä¸€ç¨®ç”¨ä»¥æª¢æ¸¬ç³»çµ±ç™¼ç”Ÿsoftlockupå’Œhardlockup的看門狗機制。
+
+Softlockup是一種會引發系統在內核態中一直循環超éŽ20秒(詳見下é¢â€œå¯¦ç¾â€å°ç¯€ï¼‰å°Žè‡´
+其他任務沒有機會得到é‹è¡Œçš„BUG。一旦檢測到'softlockup'發生,默èªæƒ…æ³ä¸‹ç³»çµ±æœƒæ‰“
+å°ç•¶å‰å †æ£§è·Ÿè¹¤ä¿¡æ¯ä¸¦é€²å…¥éŽ–定狀態。也å¯é…置使其在檢測到'softlockup'後進入panic
+狀態;通éŽsysctl命令設置“kernel.softlockup_panicâ€ã€ä½¿ç”¨å…§æ ¸å•“å‹•åƒæ•¸
+“softlockup_panicâ€ï¼ˆè©³è¦‹Documentation/admin-guide/kernel-parameters.rst)以åŠä½¿
+能內核編譯é¸é …“BOOTPARAM_SOFTLOCKUP_PANICâ€éƒ½å¯å¯¦ç¾é€™ç¨®é…置。
+
+而'hardlockup'是一種會引發系統在內核態一直循環超éŽ10秒é˜ï¼ˆè©³è¦‹"實ç¾"å°ç¯€ï¼‰å°Žè‡´å…¶
+他中斷沒有機會é‹è¡Œçš„缺陷。與'softlockup'情æ³é¡žä¼¼ï¼Œé™¤äº†ä½¿ç”¨sysctl命令設置
+'hardlockup_panic'ã€ä½¿èƒ½å…§æ ¸é¸é …“BOOTPARAM_HARDLOCKUP_PANICâ€ä»¥åŠä½¿ç”¨å…§æ ¸åƒæ•¸
+"nmi_watchdog"(詳見:â€Documentation/admin-guide/kernel-parameters.rst“)外,一旦檢
+測到'hardlockup'默èªæƒ…æ³ä¸‹ç³»çµ±æ‰“å°ç•¶å‰å †æ£§è·Ÿè¹¤ä¿¡æ¯ï¼Œç„¶å¾Œé€²å…¥éŽ–定狀態。
+
+這個panicé¸é …也å¯ä»¥èˆ‡panic_timeoutçµåˆä½¿ç”¨ï¼ˆé€™å€‹panic_timeout是通éŽç¨å…·è¿·æƒ‘性的
+sysctl命令"kernel.panic"來設置),使系統在panic指定時間後自動é‡å•“。
+
+實ç¾
+====
+
+Softlockupå’Œhardlockup分別建立在hrtimer(高精度定時器)å’Œperf兩個å­ç³»çµ±ä¸Šè€Œå¯¦ç¾ã€‚
+這也就æ„味ç€ç†è«–上任何架構åªè¦å¯¦ç¾äº†é€™å…©å€‹å­ç³»çµ±å°±æ”¯æŒé€™å…©ç¨®æª¢æ¸¬æ©Ÿåˆ¶ã€‚
+
+Hrtimer用於週期性產生中斷並喚醒watchdog線程;NMI perf事件則以â€watchdog_thresh“
+(編譯時默èªåˆå§‹åŒ–爲10秒,也å¯é€šéŽâ€watchdog_thresh“這個sysctl接å£ä¾†é€²è¡Œé…置修改)
+爲間隔週期產生以檢測 hardlockups。如果一個CPU在這個時間段內沒有檢測到hrtimer中
+斷髮生,'hardlockup 檢測器'(å³NMI perf事件處ç†å‡½æ•¸)將會視系統é…置而é¸æ“‡ç”¢ç”Ÿå…§æ ¸
+警告或者直接panic。
+
+而watchdog線程本質上是一個高優先級內核線程,æ¯èª¿åº¦ä¸€æ¬¡å°±å°æ™‚間戳進行一次更新。
+如果時間戳在2*watchdog_thresh(這個是softlockup的觸發門é™)這段時間都未更新,那麼
+"softlocup 檢測器"(內部hrtimer定時器回調函數)會將相關的調試信æ¯æ‰“å°åˆ°ç³»çµ±æ—¥èªŒä¸­ï¼Œ
+然後如果系統é…置了進入panicæµç¨‹å‰‡é€²å…¥panic,å¦å‰‡å…§æ ¸ç¹¼çºŒåŸ·è¡Œã€‚
+
+Hrtimer定時器的週期是2*watchdog_thresh/5,也就是說在hardlockup被觸發å‰hrtimer有
+2~3次機會產生時é˜ä¸­æ–·ã€‚
+
+如上所述,內核相當於爲系統管ç†å“¡æ供了一個å¯èª¿ç¯€hrtimer定時器和perf事件週期長度
+的調節旋鈕。如何通éŽé€™å€‹æ—‹éˆ•çˆ²ç‰¹å®šä½¿ç”¨å ´æ™¯é…置一個åˆç†çš„週期值è¦å°lockups檢測的
+響應速度和lockups檢測開銷這二者之間進行權衡。
+
+默èªæƒ…æ³ä¸‹æ‰€æœ‰åœ¨ç·šcpu上都會é‹è¡Œä¸€å€‹watchdog線程。ä¸éŽåœ¨å…§æ ¸é…置了â€NO_HZ_FULL“的
+情æ³ä¸‹watchdog線程默èªåªæœƒé‹è¡Œåœ¨ç®¡å®¶(housekeeping)cpu上,而â€nohz_full“啓動åƒæ•¸æŒ‡
+定的cpu上則ä¸æœƒæœ‰watchdog線程é‹è¡Œã€‚試想,如果我們å…許watchdog線程在â€nohz_full“指
+定的cpu上é‹è¡Œï¼Œé€™äº›cpu上必須得é‹è¡Œæ™‚é˜å®šæ™‚器來激發watchdog線程調度;這樣一來就會
+使â€nohz_full“ä¿è­·ç”¨æˆ¶ç¨‹åºå…å—內核干擾的功能失效。當然,副作用就是â€nohz_full“指定
+çš„cpuå³ä½¿åœ¨å…§æ ¸ç”¢ç”Ÿäº†lockupå•é¡Œæˆ‘們也無法檢測到。ä¸éŽï¼Œè‡³å°‘我們å¯ä»¥å…許watchdog
+線程在管家(non-tickless)核上繼續é‹è¡Œä»¥ä¾¿æˆ‘們能繼續正常的監測這些cpus上的lockups
+事件。
+
+ä¸è«–哪種情æ³éƒ½å¯ä»¥é€šéŽsysctl命令kernel.watchdog_cpumask來å°æ²’有é‹è¡Œwatchdog線程
+çš„cpu集åˆé€²è¡Œèª¿ç¯€ã€‚å°æ–¼nohz_full而言,如果nohz_full cpu上有異常掛ä½çš„情æ³ï¼Œé€šéŽ
+這種方å¼æ‰“開這些cpu上的watchdog進行調試å¯èƒ½æœƒæœ‰æ‰€ä½œç”¨ã€‚
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst
new file mode 100644
index 000000000000..a472eb3c708b
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst
@@ -0,0 +1,30 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/index.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+:æ ¡è­¯:
+
+============
+監測數據訪å•
+============
+
+:doc:`DAMON </mm/damon/index>` å…許輕é‡ç´šçš„數據訪å•ç›£æ¸¬ã€‚使用DAMON,
+用戶å¯ä»¥åˆ†æžä»–們系統的內存訪å•æ¨¡å¼ï¼Œä¸¦å„ªåŒ–它們。
+
+.. toctree::
+ :maxdepth: 2
+
+ start
+ usage
+ reclaim
+ lru_sort
+
+
+
+
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst
new file mode 100644
index 000000000000..1ffc4b6b1d12
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst
@@ -0,0 +1,264 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/lru_sort.rst
+
+:翻譯:
+
+ 臧雷剛 Leigang Zang <zangleigang@hisilicon.com>
+
+:æ ¡è­¯:
+
+==================
+基於DAMONçš„LRU排åº
+==================
+
+基於DAMONçš„LRU排åºæ˜¯ä¸€å€‹éœæ…‹çš„內核模塊,旨在用於以主動的ã€è¼•é‡ç´šçš„數據訪å•æ¨¡åž‹
+爲基礎的é é¢å„ªå…ˆç´šè™•ç†çš„LRUéˆè¡¨ä¸Šï¼Œä»¥ä½¿å¾—LRU上的數據訪å•æ¨¡åž‹æ›´çˆ²å¯ä¿¡ã€‚
+
+哪è£éœ€è¦ä¸»å‹•çš„LRU排åº
+=====================
+
+在一個大型系統中,以é çˆ²ç²’度的訪å•æª¢æ¸¬æœƒæœ‰æ¯”較顯著的開銷,LRU通常ä¸æœƒä¸»å‹•åŽ»æŽ’åºï¼Œ
+而是å°éƒ¨åˆ†ç‰¹æ®Šäº‹ä»¶é€²è¡Œéƒ¨åˆ†çš„ã€éŸ¿æ‡‰å¼çš„排åºï¼Œä¾‹å¦‚:特殊的用戶請求,系統調用或者
+內存壓力。這導致,在有些場景下,LRUä¸èƒ½å¤ å®Œç¾Žçš„作爲一個å¯ä¿¡çš„數據訪å•æ¨¡åž‹ï¼Œæ¯”如
+在內存壓力下å°ç›®æ¨™å…§å­˜é€²è¡Œå›žæ”¶ã€‚
+
+因爲DAMON能夠儘å¯èƒ½æº–確的識別數據訪å•æ¨¡åž‹ï¼ŒåŒæ™‚åªå¼•èµ·ç”¨æˆ¶æŒ‡å®šç¯„åœçš„開銷,主動的
+執行DAMON_LRU_SORT讓LRU變得更爲å¯ä¿¡æ˜¯æœ‰ç›Šçš„,而且這隻需è¦è¼ƒå°‘å’Œå¯æŽ§çš„開銷。
+
+這是如何工作的
+==============
+
+DAMON_LRU_SORT使用DAMON尋找熱é ï¼ˆç¯„åœå…§çš„é é¢è¨ªå•é »çŽ‡é«˜æ–¼ç”¨æˆ¶æŒ‡å®šçš„閾值)和冷é 
+(範åœå…§çš„é é¢åœ¨è¶…éŽç”¨æˆ¶æŒ‡å®šçš„時間無訪å•ï¼‰ï¼Œä¸¦æ高熱é å’Œé™ä½Žå†·é åœ¨LRU中的優先級。
+爲了é¿å…在排åºéŽç¨‹ä½”用更多的CPU計算資æºï¼Œå¯ä»¥è¨­ç½®ä¸€å€‹CPU佔用時間的約æŸå€¼ã€‚在約
+æŸä¸‹ï¼Œåˆ†åˆ¥æå‡æˆ–者é™ä½Žæ›´å¤šçš„熱é å’Œå†·é ã€‚系統管ç†å“¡ä¹Ÿå¯ä»¥é…置三個內存水ä½ä»¥æŽ§åˆ¶
+在何種æ¢ä»¶ä¸‹è‡ªå‹•æ¿€æ´»æˆ–者åœæ­¢é€™ç¨®æ©Ÿåˆ¶ã€‚
+
+冷熱閾值和CPUç´„æŸçš„默èªå€¼æ˜¯æ¯”較ä¿å®ˆçš„。這æ„味ç€ï¼Œåœ¨é»˜èªåƒæ•¸ä¸‹ï¼Œæ¨¡å¡Šå¯ä»¥å»£æ³›ä¸”ç„¡
+負作用的使用在常見環境中,åŒæ™‚在åªæ¶ˆè€—一å°éƒ¨åˆ†CPU時間的情æ³ä¸‹ï¼Œçµ¦æœ‰å…§å­˜å£“力的系
+çµ±æ供一定水平的冷熱識別。
+
+接å£ï¼šæ¨¡å¡Šåƒæ•¸
+==============
+
+使用此特性,你首先需è¦ç¢ºèªä½ çš„系統中é‹è¡Œçš„內核在編譯時啓用了
+``CONFIG_DAMON_LRU_SORT=y``.
+
+爲了讓系統管ç†å“¡æ‰“開或者關閉並且調節指定的系統,DAMON_LRU_SORT設計了模塊åƒæ•¸ã€‚
+這æ„味ç€ï¼Œä½ å¯ä»¥æ·»åŠ  ``damon_lru_sort.<parameter>=<value>`` 到內核的啓動命令行
+åƒæ•¸ï¼Œæˆ–者在 ``/sys/modules/damon_lru_sort/parameters/<parameter>`` 寫入正確的
+值。
+
+下邊是æ¯å€‹åƒæ•¸çš„æè¿°
+
+enabled
+-------
+
+打開或者關閉DAMON_LRU_SORT.
+
+ä½ å¯ä»¥é€šéŽè¨­ç½®é€™å€‹åƒæ•¸çˆ² ``Y`` 來打開DAMON_LRU_SORT。設置爲 ``N`` 關閉
+DAMON_LRU_SORT。注æ„,在基於水ä½çš„激活的情æ³ä¸‹ï¼ŒDAMON_LRU_SORT有å¯èƒ½ä¸æœƒçœŸæ­£åŽ»
+監測或者åšLRU排åºã€‚å°é€™ç¨®æƒ…æ³ï¼Œåƒè€ƒä¸‹æ–¹é—œæ–¼æ°´ä½çš„æ述。
+
+commit_inputs
+-------------
+
+讓DAMON_LRU_SORTå†æ¬¡è®€å–輸入åƒæ•¸ï¼Œé™¤äº† ``enabled`` 。
+
+在DAMON_LRU_SORTé‹è¡Œæ™‚,新的輸入åƒæ•¸é»˜èªä¸æœƒè¢«æ‡‰ç”¨ã€‚一旦這個åƒæ•¸è¢«è¨­ç½®çˆ² ``Y``
+,DAMON_LRU_SORT會å†æ¬¡è®€å–除了 ``enabled`` 之外的åƒæ•¸ã€‚讀å–完æˆå¾Œï¼Œé€™å€‹åƒæ•¸æœƒè¢«
+設置爲 ``N`` 。如果在讀å–時發ç¾æœ‰ç„¡æ•ˆåƒæ•¸ï¼ŒDAMON_LRU_SORT會被關閉。
+
+hot_thres_access_freq
+---------------------
+
+熱點內存å€åŸŸçš„訪å•é »çŽ‡é–¾å€¼ï¼Œåƒåˆ†æ¯”。
+
+如果一個內存å€åŸŸçš„訪å•é »çŽ‡å¤§æ–¼ç­‰æ–¼é€™å€‹å€¼ï¼ŒDAMON_LRU_SORT把這個å€åŸŸçœ‹ä½œç†±å€ï¼Œä¸¦
+在LRU上把這個å€åŸŸæ¨™è¨˜çˆ²å·²è¨ªå•ï¼Œå› äº›åœ¨å…§å­˜å£“力下這部分內存ä¸æœƒè¢«å›žæ”¶ã€‚默èªçˆ²50%。
+
+cold_min_age
+------------
+
+用於識別冷內存å€åŸŸçš„時間閾值,單ä½æ˜¯å¾®ç§’。
+
+如果一個內存å€åŸŸåœ¨é€™å€‹æ™‚間內未被訪å•éŽï¼ŒDAMON_LRU_SORT把這個å€åŸŸçœ‹ä½œå†·å€ï¼Œä¸¦åœ¨
+LRU上把這個å€åŸŸæ¨™è¨˜çˆ²æœªè¨ªå•ï¼Œå› æ­¤åœ¨å…§å­˜å£“力下這些內存會首先被回收。默èªå€¼çˆ²120
+秒。
+
+quota_ms
+--------
+
+嘗試LRUéˆè¡¨æŽ’åºçš„時間é™åˆ¶ï¼Œå–®ä½æ˜¯æ¯«ç§’。
+
+DAMON_LRU_SORT在一個時間窗å£å…§ï¼ˆquota_reset_interval_ms)內最多嘗試這麼長時間來
+å°LRU進行排åºã€‚這個å¯ä»¥ç”¨ä¾†ä½œçˆ²CPU計算資æºçš„ç´„æŸã€‚如果值爲0,則表示無é™åˆ¶ã€‚
+
+默èª10毫秒。
+
+quota_reset_interval_ms
+-----------------------
+
+é…é¡è¨ˆæ™‚é‡ç½®é€±æœŸï¼Œæ¯«ç§’。
+
+é…é¡è¨ˆæ™‚é‡ç½®é€±æœŸã€‚å³ï¼Œåœ¨quota_reset_interval_ms毫秒內,DAMON_LRU_SORTå°LRU進行
+排åºä¸æœƒè¶…éŽquota_ms或者quota_sz。
+
+默èª1秒。
+
+wmarks_interval
+---------------
+
+æ°´ä½çš„檢查週期,單ä½æ˜¯å¾®ç§’。
+
+當DAMON_LRU_SORT使能但是由於水ä½è€Œä¸æ´»èºæ™‚檢查水ä½å‰æœ€å°çš„等待時間。默èªå€¼5秒。
+
+wmarks_high
+-----------
+
+空閒內存高水ä½ï¼Œåƒåˆ†æ¯”。
+
+如果空閒內存水ä½é«˜æ–¼é€™å€‹å€¼ï¼ŒDAMON_LRU_SORTåœæ­¢å·¥ä½œï¼Œä¸åšä»»ä½•äº‹ï¼Œé™¤äº†é€±æœŸæ€§çš„檢
+查水ä½ã€‚默èª200(20%)。
+
+wmarks_mid
+----------
+
+空閒內存中間水ä½ï¼Œåƒåˆ†æ¯”。
+
+如果空閒內存水ä½åœ¨é€™å€‹å€¼èˆ‡ä½Žæ°´ä½ä¹‹é–“,DAMON_LRU_SORT開始工作,開始檢測並å°LRUéˆ
+表進行排åºã€‚默èª150(15%)。
+
+wmarks_low
+----------
+
+空閒內存低水ä½ï¼Œåƒåˆ†æ¯”。
+
+如果空閒內存å°æ–¼é€™å€‹å€¼ï¼ŒDAMON_LRU_SORTä¸å†å·¥ä½œï¼Œä¸åšä»»ä½•äº‹ï¼Œé™¤äº†é€±æœŸæ€§çš„檢查水
+線。默èª50(5%)。
+
+sample_interval
+---------------
+
+監測的採樣週期,微秒。
+
+DAMONå°å†·å…§å­˜ç›£æ¸¬çš„採樣週期。更多細節請åƒè€ƒDAMON文檔 (:doc:`usage`) 。默èª5
+毫秒。
+
+aggr_interval
+-------------
+
+監測的收集週期,微秒。
+
+DAMONå°å†·å…§å­˜é€²è¡Œæ”¶é›†çš„時間週期。更多細節請åƒè€ƒDAMON文檔 (:doc:`usage`) 。默èª
+100毫秒。
+
+min_nr_regions
+--------------
+
+最å°ç›£æ¸¬å€åŸŸæ•¸é‡ã€‚
+
+å°å†·å…§å­˜å€åŸŸç›£æ¸¬çš„最å°æ•¸é‡ã€‚這個值å¯ä»¥ä½œçˆ²ç›£æ¸¬è³ªé‡çš„下é™ã€‚ä¸éŽï¼Œé€™å€‹å€¼è¨­ç½®çš„éŽ
+大會增加開銷。更多細節請åƒè€ƒDAMON文檔 (:doc:`usage`) 。默èªå€¼çˆ²10。
+
+max_nr_regions
+--------------
+
+最大監測å€åŸŸæ•¸é‡ã€‚
+
+å°å†·å…§å­˜å€åŸŸç›£æ¸¬çš„最大數é‡ã€‚這個值å¯ä»¥ä½œçˆ²ç›£æ¸¬è³ªé‡çš„上é™ã€‚然而,這個值設置的éŽ
+低會導致監測çµæžœè®Šå·®ã€‚更多細節請åƒè€ƒDAMON文檔 (:doc:`usage`) 。默èªå€¼çˆ²1000。
+
+monitor_region_start
+--------------------
+
+目標內存å€åŸŸçš„起始物ç†åœ°å€ã€‚
+
+DAMON_LRU_SORTè¦è™•ç†çš„目標內存å€åŸŸçš„起始物ç†åœ°å€ã€‚默èªï¼Œä½¿ç”¨ç³»çµ±æœ€å¤§å…§å­˜ã€‚
+
+monitor_region_end
+------------------
+
+目標內存å€åŸŸçš„çµæŸç‰©ç†åœ°å€ã€‚
+
+DAMON_LRU_SORTè¦è™•ç†çš„目標內存å€åŸŸçš„çµæŸç‰©ç†åœ°å€ã€‚默èªï¼Œä½¿ç”¨ç³»çµ±æœ€å¤§å…§å­˜ã€‚
+
+kdamond_pid
+-----------
+
+DAMON線程的PID。
+
+如果DAMON_LRU_SORT是使能的,這個表示任務線程的PID。其它情æ³çˆ²-1。
+
+nr_lru_sort_tried_hot_regions
+-----------------------------
+
+被嘗試進行LRU排åºçš„熱內存å€åŸŸçš„數é‡ã€‚
+
+bytes_lru_sort_tried_hot_regions
+--------------------------------
+
+被嘗試進行LRU排åºçš„熱內存å€åŸŸçš„大å°ï¼ˆå­—節)。
+
+nr_lru_sorted_hot_regions
+-------------------------
+
+æˆåŠŸé€²è¡ŒLRU排åºçš„熱內存å€åŸŸçš„數é‡ã€‚
+
+bytes_lru_sorted_hot_regions
+----------------------------
+
+æˆåŠŸé€²è¡ŒLRU排åºçš„熱內存å€åŸŸçš„大å°ï¼ˆå­—節)。
+
+nr_hot_quota_exceeds
+--------------------
+
+熱å€åŸŸæ™‚é–“ç´„æŸè¶…éŽé™åˆ¶çš„次數。
+
+nr_lru_sort_tried_cold_regions
+------------------------------
+
+被嘗試進行LRU排åºçš„冷內存å€åŸŸçš„數é‡ã€‚
+
+bytes_lru_sort_tried_cold_regions
+---------------------------------
+
+被嘗試進行LRU排åºçš„冷內存å€åŸŸçš„大å°ï¼ˆå­—節)。
+
+nr_lru_sorted_cold_regions
+--------------------------
+
+æˆåŠŸé€²è¡ŒLRU排åºçš„冷內存å€åŸŸçš„數é‡ã€‚
+
+bytes_lru_sorted_cold_regions
+-----------------------------
+
+æˆåŠŸé€²è¡ŒLRU排åºçš„冷內存å€åŸŸçš„大å°ï¼ˆå­—節)。
+
+nr_cold_quota_exceeds
+---------------------
+
+冷å€åŸŸæ™‚é–“ç´„æŸè¶…éŽé™åˆ¶çš„次數。
+
+Example
+=======
+
+如下是一個é‹è¡Œæ™‚的命令示例,使DAMON_LRU_SORT查找訪å•é »çŽ‡è¶…éŽ50%çš„å€åŸŸä¸¦å°å…¶é€²è¡Œ
+LRU的優先級的æå‡ï¼ŒåŒæ™‚é™ä½Žé‚£äº›è¶…éŽ120秒無人訪å•çš„內存å€åŸŸçš„優先級。優先級的處
+ç†è¢«é™åˆ¶åœ¨æœ€å¤š1%çš„CPU以é¿å…DAMON_LRU_SORT消費éŽå¤šCPU時間。在系統空閒內存超éŽ50%
+時DAMON_LRU_SORTåœæ­¢å·¥ä½œï¼Œä¸¦åœ¨ä½Žæ–¼40%時é‡æ–°é–‹å§‹å·¥ä½œã€‚如果DAMON_RECLAIM沒有å–å¾—
+進展且空閒內存低於20%,å†æ¬¡è®“DAMON_LRU_SORTåœæ­¢å·¥ä½œï¼Œä»¥æ­¤å›žé€€åˆ°ä»¥LRUéˆè¡¨çˆ²åŸºç¤Ž
+以é é¢çˆ²å–®ä½çš„內存回收上。 ::
+
+ # cd /sys/modules/damon_lru_sort/parameters
+ # echo 500 > hot_thres_access_freq
+ # echo 120000000 > cold_min_age
+ # echo 10 > quota_ms
+ # echo 1000 > quota_reset_interval_ms
+ # echo 500 > wmarks_high
+ # echo 400 > wmarks_mid
+ # echo 200 > wmarks_low
+ # echo Y > enabled
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst
new file mode 100644
index 000000000000..efed29c40e44
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst
@@ -0,0 +1,229 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/reclaim.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+:æ ¡è­¯:
+
+===============
+基於DAMON的回收
+===============
+
+基於DAMON的回收(DAMON_RECLAIM)是一個éœæ…‹çš„內核模塊,旨在用於輕度內存壓力下的主動和輕
+é‡ç´šçš„回收。它的目的ä¸æ˜¯å–代基於LRU列表的é é¢å›žæ”¶ï¼Œè€Œæ˜¯æœ‰é¸æ“‡åœ°ç”¨æ–¼ä¸åŒç¨‹åº¦çš„內存壓力和è¦
+求。
+
+哪些地方需è¦ä¸»å‹•å›žæ”¶ï¼Ÿ
+======================
+
+在一般的內存超é‡ä½¿ç”¨ï¼ˆover-committed systems,虛擬化相關術語)的系統上,主動回收冷é 
+有助於節çœå…§å­˜å’Œæ¸›å°‘延é²é«˜å³¯ï¼Œé€™äº›å»¶é²æ˜¯ç”±ç›´æŽ¥å›žæ”¶é€²ç¨‹æˆ–kswapdçš„CPU消耗引起的,åŒæ™‚åªç”¢
+生最å°çš„æ€§èƒ½ä¸‹é™ [1]_ [2]_ 。
+
+基於空閒é å ±å‘Š [3]_ 的內存éŽåº¦æ‰¿è«¾çš„虛擬化系統就是很好的例å­ã€‚在這樣的系統中,客戶機
+å‘主機報告他們的空閒內存,而主機則將報告的內存é‡æ–°åˆ†é…給其他客戶。因此,系統的內存得到了充
+分的利用。然而,客戶å¯èƒ½ä¸é‚£éº¼ç¯€çœå…§å­˜ï¼Œä¸»è¦æ˜¯å› çˆ²ä¸€äº›å…§æ ¸å­ç³»çµ±å’Œç”¨æˆ¶ç©ºé–“應用程åºè¢«è¨­è¨ˆçˆ²
+使用盡å¯èƒ½å¤šçš„內存。然後,客戶機å¯èƒ½åªå‘主機報告少é‡çš„內存是空閒的,導致系統的內存利用率下é™ã€‚
+在客戶中é‹è¡Œä¸»å‹•å›žæ”¶å¯ä»¥ç·©è§£é€™å€‹å•é¡Œã€‚
+
+它是如何工作的?
+================
+
+DAMON_RECLAIM找到在特定時間內沒有被訪å•çš„內存å€åŸŸä¸¦åˆ†é ã€‚爲了é¿å…它在分é æ“作中消耗éŽå¤š
+çš„CPU,å¯ä»¥é…置一個速度é™åˆ¶ã€‚在這個速度é™åˆ¶ä¸‹ï¼Œå®ƒé¦–先分é å‡ºé‚£äº›æ²’有被訪å•éŽçš„內存å€åŸŸã€‚ç³»
+統管ç†å“¡é‚„å¯ä»¥é…置在什麼情æ³ä¸‹é€™å€‹æ–¹æ¡ˆæ‡‰è©²è‡ªå‹•æ¿€æ´»å’Œåœç”¨ä¸‰å€‹å…§å­˜å£“力水ä½ã€‚
+
+接å£: 模塊åƒæ•¸
+==============
+
+è¦ä½¿ç”¨é€™å€‹åŠŸèƒ½ï¼Œä½ é¦–å…ˆè¦ç¢ºä¿ä½ çš„系統é‹è¡Œåœ¨ä¸€å€‹ä»¥ ``CONFIG_DAMON_RECLAIM=y`` 構建的內
+核上。
+
+爲了讓系統管ç†å“¡å•“用或ç¦ç”¨å®ƒï¼Œä½µçˆ²çµ¦å®šçš„系統進行調整,DAMON_RECLAIM利用了模塊åƒæ•¸ã€‚也就
+是說,你å¯ä»¥æŠŠ ``damon_reclaim.<parameter>=<value>`` 放在內核啓動命令行上,或者把
+é©ç•¶çš„值寫入 ``/sys/module/damon_reclaim/parameters/<parameter>`` 文件。
+
+下é¢æ˜¯æ¯å€‹åƒæ•¸çš„æ述。
+
+enabled
+-------
+
+啓用或ç¦ç”¨DAMON_RECLAIM。
+
+ä½ å¯ä»¥é€šéŽæŠŠé€™å€‹åƒæ•¸çš„值設置爲 ``Y`` 來啓用DAMON_RCLAIM,把它設置爲 ``N`` å¯ä»¥ç¦ç”¨
+DAMON_RECLAIM。注æ„,由於基於水ä½çš„激活æ¢ä»¶ï¼ŒDAMON_RECLAIMä¸èƒ½é€²è¡ŒçœŸæ­£çš„監測和回收。
+這一點請åƒè€ƒä¸‹é¢é—œæ–¼æ°´ä½åƒæ•¸çš„æ述。
+
+min_age
+-------
+
+識別冷內存å€åŸŸçš„時間閾值,單ä½æ˜¯å¾®ç§’。
+
+如果一個內存å€åŸŸåœ¨é€™å€‹æ™‚間或更長的時間內沒有被訪å•ï¼ŒDAMON_RECLAIM會將該å€åŸŸè­˜åˆ¥çˆ²å†·çš„,
+並回收它。
+
+默èªçˆ²120秒。
+
+quota_ms
+--------
+
+回收的時間é™åˆ¶ï¼Œä»¥æ¯«ç§’爲單ä½ã€‚
+
+DAMON_RECLAIM 試圖在一個時間窗å£ï¼ˆquota_reset_interval_ms)內åªä½¿ç”¨åˆ°é€™å€‹æ™‚間,以
+嘗試回收冷é ã€‚這å¯ä»¥ç”¨ä¾†é™åˆ¶DAMON_RECLAIMçš„CPU消耗。如果該值爲零,則該é™åˆ¶è¢«ç¦ç”¨ã€‚
+
+默èªçˆ²10ms。
+
+quota_sz
+--------
+
+回收的內存大å°é™åˆ¶ï¼Œå–®ä½çˆ²å­—節。
+
+DAMON_RECLAIM 收å–在一個時間窗å£ï¼ˆquota_reset_interval_ms)內試圖回收的內存é‡ï¼Œä¸¦
+使其ä¸è¶…éŽé€™å€‹é™åˆ¶ã€‚這å¯ä»¥ç”¨ä¾†é™åˆ¶CPUå’ŒIO的消耗。如果該值爲零,則é™åˆ¶è¢«ç¦ç”¨ã€‚
+
+默èªæƒ…æ³ä¸‹æ˜¯128 MiB。
+
+quota_reset_interval_ms
+-----------------------
+
+時間/大å°é…é¡æ”¶å–é‡ç½®é–“隔,單ä½çˆ²æ¯«ç§’。
+
+時間(quota_ms)和大å°ï¼ˆquota_sz)的é…é¡çš„目標é‡ç½®é–“隔。也就是說,DAMON_RECLAIM在
+嘗試回收‘ä¸â€™è¶…éŽquota_ms毫秒或quota_sz字節的內存。
+
+默èªçˆ²1秒。
+
+wmarks_interval
+---------------
+
+當DAMON_RECLAIM被啓用但由於其水ä½è¦å‰‡è€Œä¸æ´»èºæ™‚,在檢查水ä½ä¹‹å‰çš„最å°ç­‰å¾…時間。
+
+wmarks_high
+-----------
+
+高水ä½çš„å¯ç”¨å…§å­˜çŽ‡ï¼ˆæ¯åƒå­—節)。
+
+如果系統的å¯ç”¨å…§å­˜ï¼ˆä»¥æ¯åƒå­—節爲單ä½ï¼‰é«˜æ–¼é€™å€‹æ•¸å€¼ï¼ŒDAMON_RECLAIM就會變得ä¸æ´»èºï¼Œæ‰€ä»¥
+它什麼也ä¸åšï¼Œåªæ˜¯å®šæœŸæª¢æŸ¥æ°´ä½ã€‚
+
+wmarks_mid
+----------
+
+中間水ä½çš„å¯ç”¨å…§å­˜çŽ‡ï¼ˆæ¯åƒå­—節)。
+
+如果系統的空閒內存(以æ¯åƒå­—節爲單ä½ï¼‰åœ¨é€™å€‹å’Œä½Žæ°´ä½ç·šä¹‹é–“,DAMON_RECLAIM就會被激活,
+因此開始監測和回收。
+
+wmarks_low
+----------
+
+低水ä½çš„å¯ç”¨å…§å­˜çŽ‡ï¼ˆæ¯åƒå­—節)。
+
+如果系統的空閒內存(以æ¯åƒå­—節爲單ä½ï¼‰ä½Žæ–¼é€™å€‹æ•¸å€¼ï¼ŒDAMON_RECLAIM就會變得ä¸æ´»èºï¼Œæ‰€ä»¥
+它除了定期檢查水ä½å¤–什麼都ä¸åšã€‚在這種情æ³ä¸‹ï¼Œç³»çµ±æœƒé€€å›žåˆ°åŸºæ–¼LRU列表的é é¢ç²’度回收é‚輯。
+
+sample_interval
+---------------
+
+監測的採樣間隔,單ä½æ˜¯å¾®ç§’。
+
+DAMON用於監測冷內存的採樣間隔。更多細節請åƒè€ƒDAMON文檔 (:doc:`usage`) 。
+
+aggr_interval
+-------------
+
+監測的èšé›†é–“隔,單ä½æ˜¯å¾®ç§’。
+
+DAMONå°å†·å…§å­˜ç›£æ¸¬çš„èšé›†é–“隔。更多細節請åƒè€ƒDAMON文檔 (:doc:`usage`)。
+
+min_nr_regions
+--------------
+
+監測å€åŸŸçš„最å°æ•¸é‡ã€‚
+
+DAMON用於冷內存監測的最å°ç›£æ¸¬å€åŸŸæ•¸ã€‚這å¯ä»¥ç”¨ä¾†è¨­ç½®ç›£æ¸¬è³ªé‡çš„下é™ã€‚但是,設
+置的太高å¯èƒ½æœƒå°Žè‡´ç›£æ¸¬é–‹éŠ·çš„增加。更多細節請åƒè€ƒDAMON文檔 (:doc:`usage`) 。
+
+max_nr_regions
+--------------
+
+監測å€åŸŸçš„最大數é‡ã€‚
+
+DAMON用於冷內存監測的最大監測å€åŸŸæ•¸ã€‚這å¯ä»¥ç”¨ä¾†è¨­ç½®ç›£æ¸¬é–‹éŠ·çš„上é™å€¼ã€‚但是,
+設置得太低å¯èƒ½æœƒå°Žè‡´ç›£æ¸¬è³ªé‡ä¸å¥½ã€‚更多細節請åƒè€ƒDAMON文檔 (:doc:`usage`) 。
+
+monitor_region_start
+--------------------
+
+目標內存å€åŸŸçš„物ç†åœ°å€èµ·é»žã€‚
+
+DAMON_RECLAIMå°‡å°å…¶é€²è¡Œå·¥ä½œçš„內存å€åŸŸçš„起始物ç†åœ°å€ã€‚也就是說,DAMON_RECLAIM
+將在這個å€åŸŸä¸­æ‰¾åˆ°å†·çš„內存å€åŸŸä¸¦é€²è¡Œå›žæ”¶ã€‚默èªæƒ…æ³ä¸‹ï¼Œè©²å€åŸŸä½¿ç”¨æœ€å¤§ç³»çµ±å…§å­˜å€ã€‚
+
+monitor_region_end
+------------------
+
+目標內存å€åŸŸçš„çµæŸç‰©ç†åœ°å€ã€‚
+
+DAMON_RECLAIMå°‡å°å…¶é€²è¡Œå·¥ä½œçš„內存å€åŸŸçš„末端物ç†åœ°å€ã€‚也就是說,DAMON_RECLAIMå°‡
+在這個å€åŸŸå…§æ‰¾åˆ°å†·çš„內存å€åŸŸä¸¦é€²è¡Œå›žæ”¶ã€‚默èªæƒ…æ³ä¸‹ï¼Œè©²å€åŸŸä½¿ç”¨æœ€å¤§ç³»çµ±å…§å­˜å€ã€‚
+
+kdamond_pid
+-----------
+
+DAMON線程的PID。
+
+如果DAMON_RECLAIM被啓用,這將æˆçˆ²å·¥ä½œç·šç¨‹çš„PID。å¦å‰‡ï¼Œçˆ²-1。
+
+nr_reclaim_tried_regions
+------------------------
+
+試圖通éŽDAMON_RECLAIM回收的內存å€åŸŸçš„數é‡ã€‚
+
+bytes_reclaim_tried_regions
+---------------------------
+
+試圖通éŽDAMON_RECLAIM回收的內存å€åŸŸçš„總字節數。
+
+nr_reclaimed_regions
+--------------------
+
+通éŽDAMON_RECLAIMæˆåŠŸå›žæ”¶çš„內存å€åŸŸçš„數é‡ã€‚
+
+bytes_reclaimed_regions
+-----------------------
+
+通éŽDAMON_RECLAIMæˆåŠŸå›žæ”¶çš„內存å€åŸŸçš„總字節數。
+
+nr_quota_exceeds
+----------------
+
+超éŽæ™‚é–“/空間é…é¡é™åˆ¶çš„次數。
+
+例å­
+====
+
+下é¢çš„é‹è¡Œç¤ºä¾‹å‘½ä»¤ä½¿DAMON_RECLAIM找到30秒或更長時間沒有訪å•çš„內存å€åŸŸä¸¦â€œå›žæ”¶â€ï¼Ÿ
+爲了é¿å…DAMON_RECLAIM在分é æ“作中消耗éŽå¤šçš„CPU時間,回收被é™åˆ¶åœ¨æ¯ç§’1GiB以內。
+它還è¦æ±‚DAMON_RECLAIM在系統的å¯ç”¨å…§å­˜çŽ‡è¶…éŽ50%時ä¸åšä»»ä½•äº‹æƒ…,但如果它低於40%時
+就開始真正的工作。如果DAMON_RECLAIM沒有å–得進展,因此空閒內存率低於20%,它會è¦æ±‚
+DAMON_RECLAIMå†æ¬¡ä»€éº¼éƒ½ä¸åšï¼Œé€™æ¨£æˆ‘們就å¯ä»¥é€€å›žåˆ°åŸºæ–¼LRU列表的é é¢ç²’度回收了::
+
+ # cd /sys/module/damon_reclaim/parameters
+ # echo 30000000 > min_age
+ # echo $((1 * 1024 * 1024 * 1024)) > quota_sz
+ # echo 1000 > quota_reset_interval_ms
+ # echo 500 > wmarks_high
+ # echo 400 > wmarks_mid
+ # echo 200 > wmarks_low
+ # echo Y > enabled
+
+.. [1] https://research.google/pubs/pub48551/
+.. [2] https://lwn.net/Articles/787611/
+.. [3] https://www.kernel.org/doc/html/latest/mm/free_page_reporting.html
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst
new file mode 100644
index 000000000000..1822956be0e0
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst
@@ -0,0 +1,125 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/start.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+:æ ¡è­¯:
+
+========
+入門指å—
+========
+
+本文通éŽæ¼”示DAMON的默èªç”¨æˆ¶ç©ºé–“工具,簡è¦åœ°ä»‹ç´¹çž­å¦‚何使用DAMON。請注æ„,爲了簡潔
+起見,本文檔åªæ述了它的部分功能。更多細節請åƒè€ƒè©²å·¥å…·çš„使用文檔。
+`doc <https://github.com/awslabs/damo/blob/next/USAGE.md>`_ .
+
+
+å‰ææ¢ä»¶
+========
+
+內核
+----
+
+首先,你è¦ç¢ºä¿ä½ ç•¶å‰ç³»çµ±ä¸­è·‘的內核構建時é¸å®šäº†é€™å€‹åŠŸèƒ½é¸é … ``CONFIG_DAMON_*=y``.
+
+
+用戶空間工具
+------------
+
+在演示中,我們將使用DAMON的默èªç”¨æˆ¶ç©ºé–“工具,稱爲DAMON Operator(DAMO)。它å¯ä»¥åœ¨
+https://github.com/awslabs/damo找到。下é¢çš„例å­å‡è¨­DAMO在你的$PATH上。當然,但
+這並ä¸æ˜¯å¼·åˆ¶æ€§çš„。
+
+因爲DAMO使用了DAMONçš„sysfs接å£ï¼ˆè©³æƒ…è«‹åƒè€ƒ:doc:`usage`),你應該確ä¿
+:doc:`sysfs </filesystems/sysfs>` 被掛載。
+
+記錄數據訪å•æ¨¡å¼
+================
+
+下é¢çš„命令記錄了一個程åºçš„內存訪å•æ¨¡å¼ï¼Œä¸¦å°‡ç›£æ¸¬çµæžœä¿å­˜åˆ°æ–‡ä»¶ä¸­ã€‚ ::
+
+ $ git clone https://github.com/sjp38/masim
+ $ cd masim; make; ./masim ./configs/zigzag.cfg &
+ $ sudo damo record -o damon.data $(pidof masim)
+
+命令的å‰å…©è¡Œä¸‹è¼‰äº†ä¸€å€‹äººå·¥å…§å­˜è¨ªå•ç”Ÿæˆå™¨ç¨‹åºä¸¦åœ¨å¾Œè‡ºé‹è¡Œã€‚生æˆå™¨å°‡é‡è¤‡åœ°é€ä¸€è¨ªå•å…©å€‹
+100 MiB大å°çš„內存å€åŸŸã€‚ä½ å¯ä»¥ç”¨ä½ çš„真實工作負載來代替它。最後一行è¦æ±‚ ``damo`` å°‡
+訪å•æ¨¡å¼è¨˜éŒ„在 ``damon.data`` 文件中。
+
+
+將記錄的模å¼å¯è¦–化
+==================
+
+ä½ å¯ä»¥åœ¨heatmap中直觀地看到這種模å¼ï¼Œé¡¯ç¤ºå“ªå€‹å…§å­˜å€åŸŸï¼ˆX軸)何時被訪å•ï¼ˆY軸)以åŠè¨ª
+å•çš„頻率(數字)。::
+
+ $ sudo damo report heats --heatmap stdout
+ 22222222222222222222222222222222222222211111111111111111111111111111111111111100
+ 44444444444444444444444444444444444444434444444444444444444444444444444444443200
+ 44444444444444444444444444444444444444433444444444444444444444444444444444444200
+ 33333333333333333333333333333333333333344555555555555555555555555555555555555200
+ 33333333333333333333333333333333333344444444444444444444444444444444444444444200
+ 22222222222222222222222222222222222223355555555555555555555555555555555555555200
+ 00000000000000000000000000000000000000288888888888888888888888888888888888888400
+ 00000000000000000000000000000000000000288888888888888888888888888888888888888400
+ 33333333333333333333333333333333333333355555555555555555555555555555555555555200
+ 88888888888888888888888888888888888888600000000000000000000000000000000000000000
+ 88888888888888888888888888888888888888600000000000000000000000000000000000000000
+ 33333333333333333333333333333333333333444444444444444444444444444444444444443200
+ 00000000000000000000000000000000000000288888888888888888888888888888888888888400
+ [...]
+ # access_frequency: 0 1 2 3 4 5 6 7 8 9
+ # x-axis: space (139728247021568-139728453431248: 196.848 MiB)
+ # y-axis: time (15256597248362-15326899978162: 1 m 10.303 s)
+ # resolution: 80x40 (2.461 MiB and 1.758 s for each character)
+
+你也å¯ä»¥ç›´è§€åœ°çœ‹åˆ°å·¥ä½œé›†çš„大å°åˆ†ä½ˆï¼ŒæŒ‰å¤§å°æŽ’åºã€‚::
+
+ $ sudo damo report wss --range 0 101 10
+ # <percentile> <wss>
+ # target_id 18446632103789443072
+ # avr: 107.708 MiB
+ 0 0 B | |
+ 10 95.328 MiB |**************************** |
+ 20 95.332 MiB |**************************** |
+ 30 95.340 MiB |**************************** |
+ 40 95.387 MiB |**************************** |
+ 50 95.387 MiB |**************************** |
+ 60 95.398 MiB |**************************** |
+ 70 95.398 MiB |**************************** |
+ 80 95.504 MiB |**************************** |
+ 90 190.703 MiB |********************************************************* |
+ 100 196.875 MiB |***********************************************************|
+
+在上述命令中使用 ``--sortby`` é¸é …,å¯ä»¥é¡¯ç¤ºå·¥ä½œé›†çš„大å°æ˜¯å¦‚何按時間順åºè®ŠåŒ–的。::
+
+ $ sudo damo report wss --range 0 101 10 --sortby time
+ # <percentile> <wss>
+ # target_id 18446632103789443072
+ # avr: 107.708 MiB
+ 0 3.051 MiB | |
+ 10 190.703 MiB |***********************************************************|
+ 20 95.336 MiB |***************************** |
+ 30 95.328 MiB |***************************** |
+ 40 95.387 MiB |***************************** |
+ 50 95.332 MiB |***************************** |
+ 60 95.320 MiB |***************************** |
+ 70 95.398 MiB |***************************** |
+ 80 95.398 MiB |***************************** |
+ 90 95.340 MiB |***************************** |
+ 100 95.398 MiB |***************************** |
+
+
+數據訪å•æ¨¡å¼æ„ŸçŸ¥çš„內存管ç†
+==========================
+
+以下三個命令使æ¯ä¸€å€‹å¤§å°>=4K的內存å€åŸŸåœ¨ä½ çš„工作負載中沒有被訪å•>=60秒,就會被æ›æŽ‰ã€‚ ::
+
+ $ echo "#min-size max-size min-acc max-acc min-age max-age action" > test_scheme
+ $ echo "4K max 0 0 60s max pageout" >> test_scheme
+ $ damo schemes -c test_scheme <pid of your workload>
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst
new file mode 100644
index 000000000000..6dee719a32ea
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst
@@ -0,0 +1,592 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/usage.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+:æ ¡è­¯:
+
+========
+詳細用法
+========
+
+DAMON 爲ä¸åŒçš„用戶æ供了下é¢é€™äº›æŽ¥å£ã€‚
+
+- *DAMON用戶空間工具。*
+ `這 <https://github.com/awslabs/damo>`_ 爲有這特權的人, 如系統管ç†å“¡ï¼Œå¸Œæœ›æœ‰ä¸€å€‹å‰›å¥½
+ å¯ä»¥å·¥ä½œçš„人性化界é¢ã€‚
+ 使用它,用戶å¯ä»¥ä»¥äººæ€§åŒ–çš„æ–¹å¼ä½¿ç”¨DAMON的主è¦åŠŸèƒ½ã€‚ä¸éŽï¼Œå®ƒå¯èƒ½ä¸æœƒçˆ²ç‰¹æ®Šæƒ…æ³é€²è¡Œé«˜åº¦èª¿æ•´ã€‚
+ 它åŒæ™‚支æŒè™›æ“¬å’Œç‰©ç†åœ°å€ç©ºé–“的監測。更多細節,請åƒè€ƒå®ƒçš„ `使用文檔
+ <https://github.com/awslabs/damo/blob/next/USAGE.md>`_。
+- *sysfs接å£ã€‚*
+ :ref:`這 <sysfs_interface>` 是爲那些希望更高級的使用DAMON的特權用戶空間程åºå“¡æº–備的。
+ 使用它,用戶å¯ä»¥é€šéŽè®€å–和寫入特殊的sysfs文件來使用DAMON的主è¦åŠŸèƒ½ã€‚因此,你å¯ä»¥ç·¨å¯«å’Œä½¿
+ 用你個性化的DAMON sysfs包è£ç¨‹åºï¼Œä»£æ›¿ä½ è®€/寫sysfs文件。 `DAMON用戶空間工具
+ <https://github.com/awslabs/damo>`_ 就是這種程åºçš„ä¸€å€‹ä¾‹å­ å®ƒåŒæ™‚支æŒè™›æ“¬å’Œç‰©ç†åœ°å€
+ 空間的監測。注æ„,這個界é¢åªæ供簡單的監測çµæžœ :ref:`統計 <damos_stats>`。å°æ–¼è©³ç´°çš„監測
+ çµæžœï¼ŒDAMONæ供了一個:ref:`跟蹤點 <tracepoint>`。
+- *debugfs interface.*
+ :ref:`這 <debugfs_interface>` 幾乎與:ref:`sysfs interface <sysfs_interface>` 接
+ å£ç›¸åŒã€‚這將在下一個LTS內核發佈後被移除,所以用戶應該轉移到
+ :ref:`sysfs interface <sysfs_interface>`。
+- *內核空間編程接å£ã€‚*
+ :doc:`這 </mm/damon/api>` 這是爲內核空間程åºå“¡æº–備的。使用它,用戶å¯ä»¥é€šéŽçˆ²ä½ ç·¨å¯«å…§
+ 核空間的DAMON應用程åºï¼Œæœ€éˆæ´»æœ‰æ•ˆåœ°åˆ©ç”¨DAMONçš„æ¯ä¸€å€‹åŠŸèƒ½ã€‚你甚至å¯ä»¥çˆ²å„種地å€ç©ºé–“擴展DAMON。
+ 詳細情æ³è«‹åƒè€ƒæŽ¥å£ :doc:`文件 </mm/damon/api>`。
+
+sysfs接å£
+=========
+DAMONçš„sysfs接å£æ˜¯åœ¨å®šç¾© ``CONFIG_DAMON_SYSFS`` 時建立的。它在其sysfs目錄下創建多
+個目錄和文件, ``<sysfs>/kernel/mm/damon/`` 。你å¯ä»¥é€šéŽå°è©²ç›®éŒ„下的文件進行寫入和
+讀å–來控制DAMON。
+
+å°æ–¼ä¸€å€‹ç°¡çŸ­çš„例å­ï¼Œç”¨æˆ¶å¯ä»¥ç›£æ¸¬ä¸€å€‹çµ¦å®šå·¥ä½œè² è¼‰çš„虛擬地å€ç©ºé–“,如下所示::
+
+ # cd /sys/kernel/mm/damon/admin/
+ # echo 1 > kdamonds/nr_kdamonds && echo 1 > kdamonds/0/contexts/nr_contexts
+ # echo vaddr > kdamonds/0/contexts/0/operations
+ # echo 1 > kdamonds/0/contexts/0/targets/nr_targets
+ # echo $(pidof <workload>) > kdamonds/0/contexts/0/targets/0/pid_target
+ # echo on > kdamonds/0/state
+
+文件層次çµæ§‹
+------------
+
+DAMON sysfs接å£çš„文件層次çµæ§‹å¦‚下圖所示。在下圖中,父å­é—œä¿‚用縮進表示,æ¯å€‹ç›®éŒ„有
+``/`` 後綴,æ¯å€‹ç›®éŒ„中的文件用逗號(",")分開。 ::
+
+ /sys/kernel/mm/damon/admin
+ │ kdamonds/nr_kdamonds
+ │ │ 0/state,pid
+ │ │ │ contexts/nr_contexts
+ │ │ │ │ 0/operations
+ │ │ │ │ │ monitoring_attrs/
+ │ │ │ │ │ │ intervals/sample_us,aggr_us,update_us
+ │ │ │ │ │ │ nr_regions/min,max
+ │ │ │ │ │ targets/nr_targets
+ │ │ │ │ │ │ 0/pid_target
+ │ │ │ │ │ │ │ regions/nr_regions
+ │ │ │ │ │ │ │ │ 0/start,end
+ │ │ │ │ │ │ │ │ ...
+ │ │ │ │ │ │ ...
+ │ │ │ │ │ schemes/nr_schemes
+ │ │ │ │ │ │ 0/action
+ │ │ │ │ │ │ │ access_pattern/
+ │ │ │ │ │ │ │ │ sz/min,max
+ │ │ │ │ │ │ │ │ nr_accesses/min,max
+ │ │ │ │ │ │ │ │ age/min,max
+ │ │ │ │ │ │ │ quotas/ms,bytes,reset_interval_ms
+ │ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil
+ │ │ │ │ │ │ │ watermarks/metric,interval_us,high,mid,low
+ │ │ │ │ │ │ │ stats/nr_tried,sz_tried,nr_applied,sz_applied,qt_exceeds
+ │ │ │ │ │ │ │ tried_regions/
+ │ │ │ │ │ │ │ │ 0/start,end,nr_accesses,age
+ │ │ │ │ │ │ │ │ ...
+ │ │ │ │ │ │ ...
+ │ │ │ │ ...
+ │ │ ...
+
+æ ¹
+--
+
+DAMON sysfs接å£çš„根是 ``<sysfs>/kernel/mm/damon/`` ,它有一個å爲 ``admin`` çš„
+目錄。該目錄包å«ç‰¹æ¬Šç”¨æˆ¶ç©ºé–“程åºæŽ§åˆ¶DAMON的文件。æ“有根權é™çš„用戶空間工具或deamonså¯ä»¥
+使用這個目錄。
+
+kdamonds/
+---------
+
+與監測相關的信æ¯åŒ…括請求è¦æ ¼å’Œçµæžœè¢«ç¨±çˆ²DAMON上下文。DAMON用一個å«åškdamond的內核線程
+執行æ¯å€‹ä¸Šä¸‹æ–‡ï¼Œå¤šå€‹kdamondså¯ä»¥ä¸¦è¡Œé‹è¡Œã€‚
+
+在 ``admin`` 目錄下,有一個目錄,å³``kdamonds``,它有控制kdamonds的文件存在。在開始
+時,這個目錄åªæœ‰ä¸€å€‹æ–‡ä»¶ï¼Œ``nr_kdamonds``。å‘該文件寫入一個數字(``N``),就會創建å爲
+``0`` 到 ``N-1`` çš„å­ç›®éŒ„數é‡ã€‚æ¯å€‹ç›®éŒ„代表æ¯å€‹kdamond。
+
+kdamonds/<N>/
+-------------
+
+在æ¯å€‹kdamond目錄中,存在兩個文件(``state`` å’Œ ``pid`` )和一個目錄( ``contexts`` )。
+
+è®€å– ``state`` 時,如果kdamond當å‰æ­£åœ¨é‹è¡Œï¼Œå‰‡è¿”回 ``on`` ,如果沒有é‹è¡Œå‰‡è¿”回 ``off`` 。
+寫入 ``on`` 或 ``off`` 使kdamondè™•æ–¼ç‹€æ…‹ã€‚å‘ ``state`` 文件寫 ``update_schemes_stats`` ,
+æ›´æ–°kdamondçš„æ¯å€‹åŸºæ–¼DAMONçš„æ“作方案的統計文件的內容。關於統計信æ¯çš„細節,請åƒè€ƒ
+:ref:`stats section <sysfs_schemes_stats>`. 將 ``update_schemes_tried_regions`` 寫到
+``state`` 文件,爲kdamondçš„æ¯å€‹åŸºæ–¼DAMONçš„æ“作方案,更新基於DAMONçš„æ“作方案動作的嘗試å€åŸŸç›®éŒ„。
+å°‡`clear_schemes_tried_regions`寫入`state`文件,清除kdamondçš„æ¯å€‹åŸºæ–¼DAMONçš„æ“作方案的動作
+嘗試å€åŸŸç›®éŒ„。 關於基於DAMONçš„æ“作方案動作嘗試å€åŸŸç›®éŒ„的細節,請åƒè€ƒ:ref:tried_regions 部分
+<sysfs_schemes_tried_regions>`。
+
+如果狀態爲 ``on``ï¼Œè®€å– ``pid`` 顯示kdamond線程的pid。
+
+``contexts`` 目錄包å«æŽ§åˆ¶é€™å€‹kdamondè¦åŸ·è¡Œçš„監測上下文的文件。
+
+kdamonds/<N>/contexts/
+----------------------
+
+在開始時,這個目錄åªæœ‰ä¸€å€‹æ–‡ä»¶ï¼Œå³ ``nr_contexts`` 。å‘該文件寫入一個數字( ``N`` ),就會創
+建å爲``0`` 到 ``N-1`` çš„å­ç›®éŒ„數é‡ã€‚æ¯å€‹ç›®éŒ„代表æ¯å€‹ç›£æ¸¬èƒŒæ™¯ã€‚ç›®å‰ï¼Œæ¯å€‹kdamondåªæ”¯æŒ
+一個上下文,所以åªæœ‰ ``0`` 或 ``1`` å¯ä»¥è¢«å¯«å…¥æ–‡ä»¶ã€‚
+
+contexts/<N>/
+-------------
+
+在æ¯å€‹ä¸Šä¸‹æ–‡ç›®éŒ„中,存在一個文件(``operations``)和三個目錄(``monitoring_attrs``,
+``targets``, 和 ``schemes``)。
+
+DAMON支æŒå¤šç¨®é¡žåž‹çš„監測æ“作,包括å°è™›æ“¬åœ°å€ç©ºé–“和物ç†åœ°å€ç©ºé–“的監測。你å¯ä»¥é€šéŽå‘文件
+中寫入以下關éµè©žä¹‹ä¸€ï¼Œä¸¦å¾žæ–‡ä»¶ä¸­è®€å–,來設置和ç²å–DAMON將爲上下文使用何種類型的監測æ“作。
+
+ - vaddr: 監測特定進程的虛擬地å€ç©ºé–“
+ - paddr: 監視系統的物ç†åœ°å€ç©ºé–“
+
+contexts/<N>/monitoring_attrs/
+------------------------------
+
+用於指定監測屬性的文件,包括所需的監測質é‡å’Œæ•ˆçŽ‡ï¼Œéƒ½åœ¨ ``monitoring_attrs`` 目錄中。
+å…·é«”ä¾†èªªï¼Œé€™å€‹ç›®éŒ„ä¸‹æœ‰å…©å€‹ç›®éŒ„ï¼Œå³ ``intervals`` å’Œ ``nr_regions`` 。
+
+在 ``intervals`` 目錄下,存在DAMON的採樣間隔(``sample_us``)ã€èšé›†é–“éš”(``aggr_us``)
+和更新間隔(``update_us``)三個文件。你å¯ä»¥é€šéŽå¯«å…¥å’Œè®€å‡ºé€™äº›æ–‡ä»¶ä¾†è¨­ç½®å’Œç²å–微秒級的值。
+
+在 ``nr_regions`` 目錄下,有兩個文件分別用於DAMON監測å€åŸŸçš„下é™å’Œä¸Šé™ï¼ˆ``min`` å’Œ ``max`` ),
+這兩個文件控制ç€ç›£æ¸¬çš„開銷。你å¯ä»¥é€šéŽå‘這些文件的寫入和讀出來設置和ç²å–這些值。
+
+關於間隔和監測å€åŸŸç¯„åœçš„更多細節,請åƒè€ƒè¨­è¨ˆæ–‡ä»¶ (:doc:`/mm/damon/design`)。
+
+contexts/<N>/targets/
+---------------------
+
+在開始時,這個目錄åªæœ‰ä¸€å€‹æ–‡ä»¶ ``nr_targets`` 。å‘該文件寫入一個數字(``N``),就å¯ä»¥å‰µå»º
+å爲 ``0`` 到 ``N-1`` çš„å­ç›®éŒ„的數é‡ã€‚æ¯å€‹ç›®éŒ„代表æ¯å€‹ç›£æ¸¬ç›®æ¨™ã€‚
+
+targets/<N>/
+------------
+
+在æ¯å€‹ç›®æ¨™ç›®éŒ„中,存在一個文件(``pid_target``)和一個目錄(``regions``)。
+
+如果你把 ``vaddr`` 寫到 ``contexts/<N>/operations`` 中,æ¯å€‹ç›®æ¨™æ‡‰è©²æ˜¯ä¸€å€‹é€²ç¨‹ã€‚ä½ 
+å¯ä»¥é€šéŽå°‡é€²ç¨‹çš„pid寫到 ``pid_target`` 文件中來指定DAMON的進程。
+
+targets/<N>/regions
+-------------------
+
+當使用 ``vaddr`` 監測æ“作集時( ``vaddr`` 被寫入 ``contexts/<N>/operations`` æ–‡
+件),DAMON自動設置和更新監測目標å€åŸŸï¼Œé€™æ¨£å°±å¯ä»¥è¦†è“‹ç›®æ¨™é€²ç¨‹çš„整個內存映射。然而,用戶å¯
+能希望將åˆå§‹ç›£æ¸¬å€åŸŸè¨­ç½®çˆ²ç‰¹å®šçš„地å€ç¯„åœã€‚
+
+相å,當使用 ``paddr`` 監測æ“作集時,DAMONä¸æœƒè‡ªå‹•è¨­ç½®å’Œæ›´æ–°ç›£æ¸¬ç›®æ¨™å€åŸŸï¼ˆ ``paddr``
+被寫入 ``contexts/<N>/operations`` 中)。因此,在這種情æ³ä¸‹ï¼Œç”¨æˆ¶æ‡‰è©²è‡ªå·±è¨­ç½®ç›£æ¸¬ç›®æ¨™
+å€åŸŸã€‚
+
+在這種情æ³ä¸‹ï¼Œç”¨æˆ¶å¯ä»¥æŒ‰ç…§è‡ªå·±çš„æ„願明確設置åˆå§‹ç›£æ¸¬ç›®æ¨™å€åŸŸï¼Œå°‡é©ç•¶çš„值寫入該目錄下的文件。
+
+開始時,這個目錄åªæœ‰ä¸€å€‹æ–‡ä»¶ï¼Œ ``nr_regions`` 。å‘該文件寫入一個數字(``N``),就å¯ä»¥å‰µ
+建å爲 ``0`` 到 ``N-1`` çš„å­ç›®éŒ„。æ¯å€‹ç›®éŒ„代表æ¯å€‹åˆå§‹ç›£æ¸¬ç›®æ¨™å€åŸŸã€‚
+
+regions/<N>/
+------------
+
+在æ¯å€‹å€åŸŸç›®éŒ„中,你會發ç¾å…©å€‹æ–‡ä»¶ï¼ˆ ``start`` å’Œ ``end`` )。你å¯ä»¥é€šéŽå‘文件寫入
+和從文件中讀出,分別設置和ç²å¾—åˆå§‹ç›£æ¸¬ç›®æ¨™å€åŸŸçš„起始和çµæŸåœ°å€ã€‚
+
+æ¯å€‹å€åŸŸä¸æ‡‰è©²èˆ‡å…¶ä»–å€åŸŸé‡ç–Šã€‚ 目錄“Nâ€çš„“çµæŸâ€æ‡‰ç­‰æ–¼æˆ–å°æ–¼ç›®éŒ„“N+1â€çš„“開始â€ã€‚
+
+contexts/<N>/schemes/
+---------------------
+
+å°æ–¼ä¸€ç‰ˆçš„基於DAMON的數據訪å•æ„ŸçŸ¥çš„內存管ç†å„ªåŒ–,用戶通常希望系統å°ç‰¹å®šè¨ªå•æ¨¡å¼çš„內存å€
+域應用內存管ç†æ“作。DAMON從用戶那è£æŽ¥æ”¶é€™ç¨®å½¢å¼åŒ–çš„æ“作方案,並將這些方案應用於目標內存
+å€åŸŸã€‚用戶å¯ä»¥é€šéŽè®€å–和寫入這個目錄下的文件來ç²å¾—和設置這些方案。
+
+在開始時,這個目錄åªæœ‰ä¸€å€‹æ–‡ä»¶ï¼Œ``nr_schemes``。å‘該文件寫入一個數字(``N``),就å¯ä»¥
+創建å爲``0``到``N-1``çš„å­ç›®éŒ„的數é‡ã€‚æ¯å€‹ç›®éŒ„代表æ¯å€‹åŸºæ–¼DAMONçš„æ“作方案。
+
+schemes/<N>/
+------------
+
+在æ¯å€‹æ–¹æ¡ˆç›®éŒ„中,存在五個目錄(``access_pattern``ã€``quotas``ã€``watermarks``ã€
+``stats`` 和 ``tried_regions``)和一個文件(``action``)。
+
+``action`` 文件用於設置和ç²å–你想應用於具有特定訪å•æ¨¡å¼çš„內存å€åŸŸçš„動作。å¯ä»¥å¯«å…¥æ–‡ä»¶
+和從文件中讀å–çš„é—œéµè©žåŠå…¶å«ç¾©å¦‚下。
+
+ - ``willneed``: å°æœ‰ ``MADV_WILLNEED`` çš„å€åŸŸèª¿ç”¨ ``madvise()`` 。
+ - ``cold``: å°å…·æœ‰ ``MADV_COLD`` çš„å€åŸŸèª¿ç”¨ ``madvise()`` 。
+ - ``pageout``: 爲具有 ``MADV_PAGEOUT`` çš„å€åŸŸèª¿ç”¨ ``madvise()`` 。
+ - ``hugepage``: 爲帶有 ``MADV_HUGEPAGE`` çš„å€åŸŸèª¿ç”¨ ``madvise()`` 。
+ - ``nohugepage``: 爲帶有 ``MADV_NOHUGEPAGE`` çš„å€åŸŸèª¿ç”¨ ``madvise()``。
+ - ``lru_prio``: 在其LRU列表上å°å€åŸŸé€²è¡Œå„ªå…ˆæŽ’åºã€‚
+ - ``lru_deprio``: å°å€åŸŸçš„LRU列表進行é™ä½Žå„ªå…ˆè™•ç†ã€‚
+ - ``stat``: 什麼都ä¸åšï¼Œåªè¨ˆç®—統計數據
+
+schemes/<N>/access_pattern/
+---------------------------
+
+æ¯å€‹åŸºæ–¼DAMONçš„æ“作方案的目標訪å•æ¨¡å¼ç”±ä¸‰å€‹ç¯„åœæ§‹æˆï¼ŒåŒ…括以字節爲單ä½çš„å€åŸŸå¤§å°ã€æ¯å€‹
+èšåˆå€é–“的監測訪å•æ¬¡æ•¸å’Œå€åŸŸå¹´é½¡çš„èšåˆå€é–“數。
+
+在 ``access_pattern`` 目錄下,存在三個目錄( ``sz``, ``nr_accesses``, 和 ``age`` ),
+æ¯å€‹ç›®éŒ„有兩個文件(``min`` å’Œ ``max`` )。你å¯ä»¥é€šéŽå‘ ``sz``, ``nr_accesses``, å’Œ
+``age`` 目錄下的 ``min`` å’Œ ``max`` 文件分別寫入和讀å–來設置和ç²å–給定方案的訪å•æ¨¡å¼ã€‚
+
+schemes/<N>/quotas/
+-------------------
+
+æ¯å€‹ ``動作`` 的最佳 ``目標訪å•æ¨¡å¼`` å–決於工作負載,所以ä¸å®¹æ˜“找到。更糟糕的是,將æŸäº›å‹•ä½œ
+的方案設置得éŽæ–¼æ¿€é€²æœƒé€ æˆåš´é‡çš„開銷。爲了é¿å…這種開銷,用戶å¯ä»¥çˆ²æ¯å€‹æ–¹æ¡ˆé™åˆ¶æ™‚間和大å°é…é¡ã€‚
+具體來說,用戶å¯ä»¥è¦æ±‚DAMON儘é‡åªä½¿ç”¨ç‰¹å®šçš„時間(``時間é…é¡``)來應用動作,並且在給定的時間間
+隔(``é‡ç½®é–“éš”``)內,åªå°å…·æœ‰ç›®æ¨™è¨ªå•æ¨¡å¼çš„內存å€åŸŸæ‡‰ç”¨å‹•ä½œï¼Œè€Œä¸ä½¿ç”¨ç‰¹å®šæ•¸é‡ï¼ˆ``大å°é…é¡``)。
+
+當é è¨ˆè¶…éŽé…é¡é™åˆ¶æ™‚,DAMON會根據 ``目標訪å•æ¨¡å¼`` 的大å°ã€è¨ªå•é »çŽ‡å’Œå¹´é½¡ï¼Œå°æ‰¾åˆ°çš„內存å€åŸŸ
+進行優先排åºã€‚爲了進行個性化的優先排åºï¼Œç”¨æˆ¶å¯ä»¥çˆ²é€™ä¸‰å€‹å±¬æ€§è¨­ç½®æ¬Šé‡ã€‚
+
+在 ``quotas`` 目錄下,存在三個文件(``ms``, ``bytes``, ``reset_interval_ms``)和一個
+目錄(``weights``),其中有三個文件(``sz_permil``, ``nr_accesses_permil``, 和
+``age_permil``)。
+
+ä½ å¯ä»¥è¨­ç½®ä»¥æ¯«ç§’爲單ä½çš„ ``時間é…é¡`` ,以字節爲單ä½çš„ ``大å°é…é¡`` ,以åŠä»¥æ¯«ç§’爲單ä½çš„ ``é‡
+置間隔`` ,分別å‘這三個文件寫入數值。你還å¯ä»¥é€šéŽå‘ ``weights`` 目錄下的三個文件寫入數值來設
+置大å°ã€è¨ªå•é »çŽ‡å’Œå¹´é½¡çš„優先權,單ä½çˆ²åƒåˆ†ä¹‹ä¸€ã€‚
+
+schemes/<N>/watermarks/
+-----------------------
+
+爲了便於根據系統狀態激活和åœç”¨æ¯å€‹æ–¹æ¡ˆï¼ŒDAMONæ供了一個稱爲水ä½çš„功能。該功能接收五個值,稱爲
+``度é‡`` ã€``é–“éš”`` ã€``高`` ã€``中`` ã€``低`` 。``度é‡å€¼`` 是指å¯ä»¥æ¸¬é‡çš„系統度é‡å€¼ï¼Œå¦‚
+自由內存比率。如果系統的度é‡å€¼ ``高`` æ–¼memoent的高值或 ``低`` 於低值,則該方案被åœç”¨ã€‚如果
+該值低於 ``中`` ,則該方案被激活。
+
+在水ä½ç›®éŒ„下,存在五個文件(``metric``, ``interval_us``,``high``, ``mid``, and ``low``)
+用於設置æ¯å€‹å€¼ã€‚ä½ å¯ä»¥é€šéŽå‘這些文件的寫入來分別設置和ç²å–這五個值。
+
+å¯ä»¥å¯«å…¥ ``metric`` 文件的關éµè©žå’Œå«ç¾©å¦‚下。
+
+ - none: 忽略水ä½
+ - free_mem_rate: 系統的自由內存率(åƒåˆ†æ¯”)。
+
+``interval`` 應以微秒爲單ä½å¯«å…¥ã€‚
+
+schemes/<N>/stats/
+------------------
+
+DAMON統計æ¯å€‹æ–¹æ¡ˆè¢«å˜—試應用的å€åŸŸçš„總數é‡å’Œå­—節數,æ¯å€‹æ–¹æ¡ˆè¢«æˆåŠŸæ‡‰ç”¨çš„å€åŸŸçš„兩個數字,以åŠ
+超éŽé…é¡é™åˆ¶çš„總數é‡ã€‚這些統計數據å¯ç”¨æ–¼åœ¨ç·šåˆ†æžæˆ–調整方案。
+
+å¯ä»¥é€šéŽè®€å– ``stats`` 目錄下的文件(``nr_tried``, ``sz_tried``, ``nr_applied``,
+``sz_applied``, å’Œ ``qt_exceeds``))分別檢索這些統計數據。這些文件ä¸æ˜¯å¯¦æ™‚更新的,所以
+你應該è¦æ±‚DAMON sysfs接å£é€šéŽåœ¨ç›¸é—œçš„ ``kdamonds/<N>/state`` 文件中寫入一個特殊的關éµå­—
+``update_schemes_stats`` 來更新統計信æ¯çš„文件內容。
+
+schemes/<N>/tried_regions/
+--------------------------
+
+當一個特殊的關éµå­— ``update_schemes_tried_regions`` 被寫入相關的 ``kdamonds/<N>/state``
+文件時,DAMON會在這個目錄下創建從 ``0`` 開始命å的整數目錄。æ¯å€‹ç›®éŒ„包å«çš„文件暴露了關於æ¯å€‹
+內存å€åŸŸçš„詳細信æ¯ï¼Œåœ¨ä¸‹ä¸€å€‹ :ref:`èšé›†å€é–“ <sysfs_monitoring_attrs>`,相應的方案的 ``動作``
+已經嘗試在這個目錄下應用。這些信æ¯åŒ…括地å€ç¯„åœã€``nr_accesses`` 以åŠå€åŸŸçš„ ``年齡`` 。
+
+當å¦ä¸€å€‹ç‰¹æ®Šçš„é—œéµå­— ``clear_schemes_tried_regions`` 被寫入相關的 ``kdamonds/<N>/state``
+文件時,這些目錄將被刪除。
+
+tried_regions/<N>/
+------------------
+
+在æ¯å€‹å€åŸŸç›®éŒ„中,你會發ç¾å››å€‹æ–‡ä»¶(``start``, ``end``, ``nr_accesses``, and ``age``)。
+讀å–這些文件將顯示相應的基於DAMONçš„æ“作方案 ``動作`` 試圖應用的å€åŸŸçš„開始和çµæŸåœ°å€ã€``nr_accesses``
+和 ``年齡`` 。
+
+用例
+~~~~
+
+下é¢çš„命令應用了一個方案:â€å¦‚果一個大å°çˆ²[4KiB, 8KiB]的內存å€åŸŸåœ¨[10, 20]çš„èšåˆæ™‚間間隔內
+顯示出æ¯ä¸€å€‹èšåˆæ™‚é–“é–“éš”[0, 5]的訪å•é‡ï¼Œè«‹åˆ†é è©²å€åŸŸã€‚å°æ–¼åˆ†é ï¼Œæ¯ç§’最多隻能使用10ms,而且æ¯
+秒分é ä¸èƒ½è¶…éŽ1GiB。在這一é™åˆ¶ä¸‹ï¼Œé¦–先分é å‡ºå…·æœ‰è¼ƒé•·å¹´é½¡çš„內存å€åŸŸã€‚å¦å¤–,æ¯5秒é˜æª¢æŸ¥ä¸€æ¬¡ç³»çµ±
+çš„å¯ç”¨å…§å­˜çŽ‡ï¼Œç•¶å¯ç”¨å…§å­˜çŽ‡ä½Žæ–¼50%時開始監測和分é ï¼Œä½†å¦‚æžœå¯ç”¨å…§å­˜çŽ‡å¤§æ–¼60%,或低於30%,則åœ
+止監測。“ ::
+
+ # cd <sysfs>/kernel/mm/damon/admin
+ # # populate directories
+ # echo 1 > kdamonds/nr_kdamonds; echo 1 > kdamonds/0/contexts/nr_contexts;
+ # echo 1 > kdamonds/0/contexts/0/schemes/nr_schemes
+ # cd kdamonds/0/contexts/0/schemes/0
+ # # set the basic access pattern and the action
+ # echo 4096 > access_pattern/sz/min
+ # echo 8192 > access_pattern/sz/max
+ # echo 0 > access_pattern/nr_accesses/min
+ # echo 5 > access_pattern/nr_accesses/max
+ # echo 10 > access_pattern/age/min
+ # echo 20 > access_pattern/age/max
+ # echo pageout > action
+ # # set quotas
+ # echo 10 > quotas/ms
+ # echo $((1024*1024*1024)) > quotas/bytes
+ # echo 1000 > quotas/reset_interval_ms
+ # # set watermark
+ # echo free_mem_rate > watermarks/metric
+ # echo 5000000 > watermarks/interval_us
+ # echo 600 > watermarks/high
+ # echo 500 > watermarks/mid
+ # echo 300 > watermarks/low
+
+請注æ„,我們強烈建議使用用戶空間的工具,如 `damo <https://github.com/awslabs/damo>`_ ,
+而ä¸æ˜¯åƒä¸Šé¢é‚£æ¨£æ‰‹å‹•è®€å¯«æ–‡ä»¶ã€‚以上åªæ˜¯ä¸€å€‹ä¾‹å­ã€‚
+
+debugfs接å£
+===========
+
+.. note::
+
+ DAMON debugfs接å£å°‡åœ¨ä¸‹ä¸€å€‹LTS內核發佈後被移除,所以用戶應該轉移到
+ :ref:`sysfs接å£<sysfs_interface>`。
+
+DAMON導出了八個文件, ``attrs``, ``target_ids``, ``init_regions``,
+``schemes``, ``monitor_on``, ``kdamond_pid``, ``mk_contexts`` 和
+``rm_contexts`` under its debugfs directory, ``<debugfs>/damon/``.
+
+
+屬性
+----
+
+用戶å¯ä»¥é€šéŽè®€å–和寫入 ``attrs`` 文件ç²å¾—和設置 ``採樣間隔`` 〠``èšé›†é–“éš”`` 〠``æ›´æ–°é–“éš”``
+以åŠç›£æ¸¬ç›®æ¨™å€åŸŸçš„最å°/最大數é‡ã€‚è¦è©³ç´°çž­è§£ç›£æ¸¬å±¬æ€§ï¼Œè«‹åƒè€ƒ `:doc:/mm/damon/design` 。例如,
+下é¢çš„命令將這些值設置爲5msã€100msã€1000msã€10å’Œ1000,然後å†æ¬¡æª¢æŸ¥::
+
+ # cd <debugfs>/damon
+ # echo 5000 100000 1000000 10 1000 > attrs
+ # cat attrs
+ 5000 100000 1000000 10 1000
+
+
+目標ID
+------
+
+一些類型的地å€ç©ºé–“支æŒå¤šå€‹ç›£æ¸¬ç›®æ¨™ã€‚例如,虛擬內存地å€ç©ºé–“的監測å¯ä»¥æœ‰å¤šå€‹é€²ç¨‹ä½œçˆ²ç›£æ¸¬ç›®æ¨™ã€‚用戶
+å¯ä»¥é€šéŽå¯«å…¥ç›®æ¨™çš„相關id值來設置目標,並通éŽè®€å– ``target_ids`` 文件來ç²å¾—當å‰ç›®æ¨™çš„id。在監
+測虛擬地å€ç©ºé–“的情æ³ä¸‹ï¼Œé€™äº›å€¼æ‡‰è©²æ˜¯ç›£æ¸¬ç›®æ¨™é€²ç¨‹çš„pid。例如,下é¢çš„命令將pid爲42å’Œ4242的進程設
+爲監測目標,並å†æ¬¡æª¢æŸ¥::
+
+ # cd <debugfs>/damon
+ # echo 42 4242 > target_ids
+ # cat target_ids
+ 42 4242
+
+用戶還å¯ä»¥é€šéŽåœ¨æ–‡ä»¶ä¸­å¯«å…¥ä¸€å€‹ç‰¹æ®Šçš„é—œéµå­— "paddr\n" 來監測系統的物ç†å…§å­˜åœ°å€ç©ºé–“。因爲物ç†åœ°
+å€ç©ºé–“監測ä¸æ”¯æŒå¤šå€‹ç›®æ¨™ï¼Œè®€å–文件會顯示一個å‡å€¼ï¼Œå³ ``42`` ,如下圖所示::
+
+ # cd <debugfs>/damon
+ # echo paddr > target_ids
+ # cat target_ids
+ 42
+
+請注æ„,設置目標ID並ä¸å•“動監測。
+
+
+åˆå§‹ç›£æ¸¬ç›®æ¨™å€åŸŸ
+----------------
+
+在虛擬地å€ç©ºé–“監測的情æ³ä¸‹ï¼ŒDAMON自動設置和更新監測的目標å€åŸŸï¼Œé€™æ¨£å°±å¯ä»¥è¦†è“‹ç›®æ¨™é€²ç¨‹çš„整個
+內存映射。然而,用戶å¯èƒ½å¸Œæœ›å°‡ç›£æ¸¬å€åŸŸé™åˆ¶åœ¨ç‰¹å®šçš„地å€ç¯„åœå…§ï¼Œå¦‚å †ã€æ£§æˆ–特定的文件映射å€åŸŸã€‚
+或者,一些用戶å¯ä»¥çŸ¥é“他們工作負載的åˆå§‹è¨ªå•æ¨¡å¼ï¼Œå› æ­¤å¸Œæœ›çˆ²â€œè‡ªé©æ‡‰å€åŸŸèª¿æ•´â€è¨­ç½®æœ€ä½³åˆå§‹å€åŸŸã€‚
+
+相比之下,DAMON在物ç†å…§å­˜ç›£æ¸¬çš„情æ³ä¸‹ä¸æœƒè‡ªå‹•è¨­ç½®å’Œæ›´æ–°ç›£æ¸¬ç›®æ¨™å€åŸŸã€‚因此,用戶應該自己設置
+監測目標å€åŸŸã€‚
+
+在這種情æ³ä¸‹ï¼Œç”¨æˆ¶å¯ä»¥é€šéŽåœ¨ ``init_regions`` 文件中寫入é©ç•¶çš„值,明確地設置他們想è¦çš„åˆ
+始監測目標å€åŸŸã€‚輸入應該是一個由三個整數組æˆçš„隊列,用空格隔開,代表一個å€åŸŸçš„å½¢å¼å¦‚下::
+
+ <target idx> <start address> <end address>
+
+目標idx應該是 ``target_ids`` 文件中目標的索引,從 ``0`` 開始,å€åŸŸæ‡‰è©²æŒ‰ç…§åœ°å€é †åºå‚³éžã€‚
+例如,下é¢çš„命令將設置幾個地å€ç¯„åœï¼Œ ``1-100`` å’Œ ``100-200`` 作爲pid 42çš„åˆå§‹ç›£æ¸¬ç›®æ¨™
+å€åŸŸï¼Œé€™æ˜¯ ``target_ids`` 中的第一個(索引 ``0`` ),å¦å¤–幾個地å€ç¯„åœï¼Œ ``20-40`` å’Œ
+``50-100`` 作爲pid 4242的地å€ï¼Œé€™æ˜¯ ``target_ids`` 中的第二個(索引 ``1`` )::
+
+ # cd <debugfs>/damon
+ # cat target_ids
+ 42 4242
+ # echo "0 1 100 \
+ 0 100 200 \
+ 1 20 40 \
+ 1 50 100" > init_regions
+
+請注æ„,這åªæ˜¯è¨­ç½®äº†åˆå§‹çš„監測目標å€åŸŸã€‚在虛擬內存監測的情æ³ä¸‹ï¼ŒDAMON會在一個 ``æ›´æ–°é–“éš”``
+後自動更新å€åŸŸçš„邊界。因此,在這種情æ³ä¸‹ï¼Œå¦‚果用戶ä¸å¸Œæœ›æ›´æ–°çš„話,應該把 ``æ›´æ–°é–“éš”`` 設
+置得足夠大。
+
+
+方案
+----
+
+å°æ–¼é€šå¸¸çš„基於DAMON的數據訪å•æ„ŸçŸ¥çš„內存管ç†å„ªåŒ–,用戶åªæ˜¯å¸Œæœ›ç³»çµ±å°ç‰¹å®šè¨ªå•æ¨¡å¼çš„內存å€åŸŸæ‡‰ç”¨å…§
+存管ç†æ“作。DAMON從用戶那è£æŽ¥æ”¶é€™ç¨®å½¢å¼åŒ–çš„æ“作方案,並將這些方案應用到目標進程中。
+
+用戶å¯ä»¥é€šéŽè®€å–和寫入 ``scheme`` debugfs文件來ç²å¾—和設置這些方案。讀å–該文件還å¯ä»¥é¡¯ç¤ºæ¯å€‹
+方案的統計數據。在文件中,æ¯ä¸€å€‹æ–¹æ¡ˆéƒ½æ‡‰è©²åœ¨æ¯ä¸€è¡Œä¸­ä»¥ä¸‹åˆ—å½¢å¼è¡¨ç¤ºå‡ºä¾†::
+
+ <target access pattern> <action> <quota> <watermarks>
+
+ä½ å¯ä»¥é€šéŽç°¡å–®åœ°åœ¨æ–‡ä»¶ä¸­å¯«å…¥ä¸€å€‹ç©ºå­—符串來ç¦ç”¨æ–¹æ¡ˆã€‚
+
+目標訪å•æ¨¡å¼
+~~~~~~~~~~~~
+
+``<目標訪å•æ¨¡å¼>`` 是由三個範åœæ§‹æˆçš„,形å¼å¦‚下::
+
+ min-size max-size min-acc max-acc min-age max-age
+
+具體來說,å€åŸŸå¤§å°çš„字節數( `min-size` å’Œ `max-size` ),訪å•é »çŽ‡çš„æ¯èšåˆå€é–“的監測訪å•æ¬¡
+數( `min-acc` å’Œ `max-acc` ),å€åŸŸå¹´é½¡çš„èšåˆå€é–“數( `min-age` å’Œ `max-age` )都被指定。
+請注æ„,這些範åœæ˜¯å°é–‰å€é–“。
+
+動作
+~~~~
+
+``<action>`` 是一個é å®šç¾©çš„內存管ç†å‹•ä½œçš„整數,DAMON將應用於具有目標訪å•æ¨¡å¼çš„å€åŸŸã€‚支æŒ
+的數字和它們的å«ç¾©å¦‚下::
+
+ - 0: Call ``madvise()`` for the region with ``MADV_WILLNEED``
+ - 1: Call ``madvise()`` for the region with ``MADV_COLD``
+ - 2: Call ``madvise()`` for the region with ``MADV_PAGEOUT``
+ - 3: Call ``madvise()`` for the region with ``MADV_HUGEPAGE``
+ - 4: Call ``madvise()`` for the region with ``MADV_NOHUGEPAGE``
+ - 5: Do nothing but count the statistics
+
+é…é¡
+~~~~
+
+æ¯å€‹ ``動作`` 的最佳 ``目標訪å•æ¨¡å¼`` å–決於工作負載,所以ä¸å®¹æ˜“找到。更糟糕的是,將æŸå€‹
+動作的方案設置得éŽæ–¼æ¿€é€²æœƒå°Žè‡´åš´é‡çš„開銷。爲了é¿å…這種開銷,用戶å¯ä»¥é€šéŽä¸‹é¢è¡¨æ ¼ä¸­çš„ ``<quota>``
+來é™åˆ¶æ–¹æ¡ˆçš„時間和大å°é…é¡::
+
+ <ms> <sz> <reset interval> <priority weights>
+
+這使得DAMON在 ``<reset interval>`` 毫秒內,儘é‡åªç”¨ ``<ms>`` æ¯«ç§’çš„æ™‚é–“å° ``目標訪
+å•æ¨¡å¼`` 的內存å€åŸŸæ‡‰ç”¨å‹•ä½œï¼Œä¸¦åœ¨ ``<reset interval>`` å…§åªå°æœ€å¤š<sz>字節的內存å€åŸŸæ‡‰
+用動作。將 ``<ms>`` å’Œ ``<sz>`` 都設置爲零,å¯ä»¥ç¦ç”¨é…é¡é™åˆ¶ã€‚
+
+當é è¨ˆè¶…éŽé…é¡é™åˆ¶æ™‚,DAMON會根據 ``目標訪å•æ¨¡å¼`` 的大å°ã€è¨ªå•é »çŽ‡å’Œå¹´é½¡ï¼Œå°ç™¼ç¾çš„內存
+å€åŸŸé€²è¡Œå„ªå…ˆæŽ’åºã€‚爲了實ç¾å€‹æ€§åŒ–的優先級,用戶å¯ä»¥åœ¨ ``<優先級權é‡>`` 中設置這三個屬性的
+權é‡ï¼Œå…·é«”å½¢å¼å¦‚下::
+
+ <size weight> <access frequency weight> <age weight>
+
+æ°´ä½
+~~~~
+
+有些方案需è¦æ ¹æ“šç³»çµ±ç‰¹å®šæŒ‡æ¨™çš„當å‰å€¼ä¾†é‹è¡Œï¼Œå¦‚自由內存比率。å°æ–¼é€™ç¨®æƒ…æ³ï¼Œç”¨æˆ¶å¯ä»¥çˆ²è©²æ¢
+件指定水ä½ã€‚::
+
+ <metric> <check interval> <high mark> <middle mark> <low mark>
+
+``<metric>`` 是一個é å®šç¾©çš„整數,用於è¦æª¢æŸ¥çš„度é‡ã€‚支æŒçš„數字和它們的å«ç¾©å¦‚下。
+
+ - 0: 忽視水ä½
+ - 1: 系統空閒內存率 (åƒåˆ†æ¯”)
+
+æ¯éš” ``<檢查間隔>`` 微秒檢查一次公制的值。
+
+如果該值高於 ``<高標>`` 或低於 ``<低標>`` ,該方案被åœç”¨ã€‚如果該值低於 ``<中標>`` ,
+該方案將被激活。
+
+統計數據
+~~~~~~~~
+
+它還統計æ¯å€‹æ–¹æ¡ˆè¢«å˜—試應用的å€åŸŸçš„總數é‡å’Œå­—節數,æ¯å€‹æ–¹æ¡ˆè¢«æˆåŠŸæ‡‰ç”¨çš„å€åŸŸçš„兩個數é‡ï¼Œä»¥
+åŠè¶…éŽé…é¡é™åˆ¶çš„總數é‡ã€‚這些統計數據å¯ç”¨æ–¼åœ¨ç·šåˆ†æžæˆ–調整方案。
+
+統計數據å¯ä»¥é€šéŽè®€å–方案文件來顯示。讀å–該文件將顯示你在æ¯ä¸€è¡Œä¸­è¼¸å…¥çš„æ¯å€‹ ``方案`` ,
+統計的五個數字將被加在æ¯ä¸€è¡Œçš„末尾。
+
+例å­
+~~~~
+
+下é¢çš„命令應用了一個方案:â€å¦‚果一個大å°çˆ²[4KiB, 8KiB]的內存å€åŸŸåœ¨[10, 20]çš„èšåˆæ™‚é–“
+間隔內顯示出æ¯ä¸€å€‹èšåˆæ™‚é–“é–“éš”[0, 5]的訪å•é‡ï¼Œè«‹åˆ†é å‡ºè©²å€åŸŸã€‚å°æ–¼åˆ†é ï¼Œæ¯ç§’最多隻能使
+用10ms,而且æ¯ç§’分é ä¸èƒ½è¶…éŽ1GiB。在這一é™åˆ¶ä¸‹ï¼Œé¦–先分é å‡ºå…·æœ‰è¼ƒé•·å¹´é½¡çš„內存å€åŸŸã€‚å¦å¤–,
+æ¯5秒é˜æª¢æŸ¥ä¸€æ¬¡ç³»çµ±çš„å¯ç”¨å…§å­˜çŽ‡ï¼Œç•¶å¯ç”¨å…§å­˜çŽ‡ä½Žæ–¼50%時開始監測和分é ï¼Œä½†å¦‚æžœå¯ç”¨å…§å­˜çŽ‡
+大於60%,或低於30%,則åœæ­¢ç›£æ¸¬â€œ::
+
+ # cd <debugfs>/damon
+ # scheme="4096 8192 0 5 10 20 2" # target access pattern and action
+ # scheme+=" 10 $((1024*1024*1024)) 1000" # quotas
+ # scheme+=" 0 0 100" # prioritization weights
+ # scheme+=" 1 5000000 600 500 300" # watermarks
+ # echo "$scheme" > schemes
+
+
+開關
+----
+
+除éžä½ æ˜Žç¢ºåœ°å•“動監測,å¦å‰‡å¦‚上所述的文件設置ä¸æœƒç”¢ç”Ÿæ•ˆæžœã€‚ä½ å¯ä»¥é€šéŽå¯«å…¥å’Œè®€å– ``monitor_on``
+文件來啓動ã€åœæ­¢å’Œæª¢æŸ¥ç›£æ¸¬çš„當å‰ç‹€æ…‹ã€‚寫入 ``on`` 該文件å¯ä»¥å•“å‹•å°æœ‰å±¬æ€§çš„目標的監測。寫入
+``off`` 該文件則åœæ­¢é€™äº›ç›®æ¨™ã€‚如果æ¯å€‹ç›®æ¨™é€²ç¨‹è¢«çµ‚止,DAMON也會åœæ­¢ã€‚下é¢çš„示例命令開啓ã€é—œ
+閉和檢查DAMON的狀態::
+
+ # cd <debugfs>/damon
+ # echo on > monitor_on
+ # echo off > monitor_on
+ # cat monitor_on
+ off
+
+請注æ„,當監測開啓時,你ä¸èƒ½å¯«åˆ°ä¸Šè¿°çš„debugfs文件。如果你在DAMONé‹è¡Œæ™‚寫到這些文件,將會返
+回一個錯誤代碼,如 ``-EBUSY`` 。
+
+
+監測線程PID
+-----------
+
+DAMON通éŽä¸€å€‹å«åškdamond的內核線程來進行請求監測。你å¯ä»¥é€šéŽè®€å– ``kdamond_pid`` 文件ç²
+得該線程的 ``pid`` 。當監測被 ``關閉`` 時,讀å–該文件ä¸æœƒè¿”回任何信æ¯::
+
+ # cd <debugfs>/damon
+ # cat monitor_on
+ off
+ # cat kdamond_pid
+ none
+ # echo on > monitor_on
+ # cat kdamond_pid
+ 18594
+
+
+使用多個監測線程
+----------------
+
+æ¯å€‹ç›£æ¸¬ä¸Šä¸‹æ–‡éƒ½æœƒå‰µå»ºä¸€å€‹ ``kdamond`` 線程。你å¯ä»¥ä½¿ç”¨ ``mk_contexts`` å’Œ ``rm_contexts``
+文件爲多個 ``kdamond`` 需è¦çš„用例創建和刪除監測上下文。
+
+將新上下文的å稱寫入 ``mk_contexts`` 文件,在 ``DAMON debugfs`` 目錄上創建一個該å稱的目錄。
+該目錄將有該上下文的 ``DAMON debugfs`` 文件::
+
+ # cd <debugfs>/damon
+ # ls foo
+ # ls: cannot access 'foo': No such file or directory
+ # echo foo > mk_contexts
+ # ls foo
+ # attrs init_regions kdamond_pid schemes target_ids
+
+如果ä¸å†éœ€è¦ä¸Šä¸‹æ–‡ï¼Œä½ å¯ä»¥é€šéŽæŠŠä¸Šä¸‹æ–‡çš„å字放到 ``rm_contexts`` 文件中來刪除它和相應的目錄::
+
+ # echo foo > rm_contexts
+ # ls foo
+ # ls: cannot access 'foo': No such file or directory
+
+注æ„, ``mk_contexts`` 〠``rm_contexts`` å’Œ ``monitor_on`` 文件åªåœ¨æ ¹ç›®éŒ„下。
+
+
+監測çµæžœçš„監測點
+================
+
+DAMON通éŽä¸€å€‹tracepoint ``damon:damon_aggregated`` æ供監測çµæžœ. 當監測開啓時,你å¯
+以記錄追蹤點事件,並使用追蹤點支æŒå·¥å…·å¦‚perf顯示çµæžœã€‚比如說::
+
+ # echo on > monitor_on
+ # perf record -e damon:damon_aggregated &
+ # sleep 5
+ # kill 9 $(pidof perf)
+ # echo off > monitor_on
+ # perf script
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/index.rst b/Documentation/translations/zh_TW/admin-guide/mm/index.rst
new file mode 100644
index 000000000000..0b04d925b68c
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/index.rst
@@ -0,0 +1,50 @@
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/index.rst
+
+:翻譯:
+
+ å¾é‘« xu xin <xu.xin16@zte.com.cn>
+
+
+========
+內存管ç†
+========
+
+Linux內存管ç†å­ç³»çµ±ï¼Œé¡§åæ€ç¾©ï¼Œæ˜¯è² è²¬ç³»çµ±ä¸­çš„內存管ç†ã€‚它包括了虛擬內存與請求
+分é çš„實ç¾ï¼Œå…§æ ¸å…§éƒ¨çµæ§‹å’Œç”¨æˆ¶ç©ºé–“程åºçš„內存分é…ã€å°‡æ–‡ä»¶æ˜ å°„到進程地å€ç©ºé–“以
+åŠè¨±å¤šå…¶ä»–很酷的事情。
+
+Linux內存管ç†æ˜¯ä¸€å€‹å…·æœ‰è¨±å¤šå¯é…置設置的複雜系統, 且這些設置中的大多數都å¯ä»¥é€š
+éŽ ``/proc`` 文件系統ç²å¾—,並且å¯ä»¥ä½¿ç”¨ ``sysctl`` 進行查詢和調整。這些API接
+å£è¢«æ述在Documentation/admin-guide/sysctl/vm.rst文件和 `man 5 proc`_ 中。
+
+.. _man 5 proc: http://man7.org/linux/man-pages/man5/proc.5.html
+
+Linux內存管ç†æœ‰å®ƒè‡ªå·±çš„術語,如果你還ä¸ç†Ÿæ‚‰å®ƒï¼Œè«‹è€ƒæ…®é–±è®€ä¸‹é¢åƒè€ƒï¼š
+Documentation/admin-guide/mm/concepts.rst.
+
+在此目錄下,我們詳細æ述瞭如何與Linux內存管ç†ä¸­çš„å„種機制交互。
+
+.. toctree::
+ :maxdepth: 1
+
+ damon/index
+ ksm
+
+Todolist:
+* concepts
+* cma_debugfs
+* hugetlbpage
+* idle_page_tracking
+* memory-hotplug
+* nommu-mmap
+* numa_memory_policy
+* numaperf
+* pagemap
+* soft-dirty
+* swap_numa
+* transhuge
+* userfaultfd
+* zswap
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/ksm.rst b/Documentation/translations/zh_TW/admin-guide/mm/ksm.rst
new file mode 100644
index 000000000000..1b4944b3cf61
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/ksm.rst
@@ -0,0 +1,199 @@
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/ksm.rst
+
+:翻譯:
+
+ å¾é‘« xu xin <xu.xin16@zte.com.cn>
+
+
+============
+內核åŒé åˆä½µ
+============
+
+
+概述
+====
+
+KSM是一種能節çœå…§å­˜çš„數據去é‡åŠŸèƒ½ï¼Œç”±CONFIG_KSM=y啓用,並在2.6.32版本時被添
+加到Linux內核。詳見 ``mm/ksm.c`` 的實ç¾ï¼Œä»¥åŠhttp://lwn.net/Articles/306704
+å’Œhttps://lwn.net/Articles/330589
+
+KSM最åˆç›®çš„是爲了與KVM(å³è‘—å的內核共享內存)一起使用而開發的,通éŽå…±äº«è™›æ“¬æ©Ÿ
+之間的公共數據,將更多虛擬機放入物ç†å…§å­˜ã€‚但它å°æ–¼ä»»ä½•æœƒç”Ÿæˆå¤šå€‹ç›¸åŒæ•¸æ“šå¯¦ä¾‹çš„
+應用程åºéƒ½æ˜¯å¾ˆæœ‰ç”¨çš„。
+
+KSM的守護進程ksmd會定期掃æ那些已註冊的用戶內存å€åŸŸï¼ŒæŸ¥æ‰¾å…§å®¹ç›¸åŒçš„é é¢ï¼Œé€™äº›
+é é¢å¯ä»¥è¢«å–®å€‹å¯«ä¿è­·é é¢æ›¿æ›ï¼ˆå¦‚果進程以後想è¦æ›´æ–°å…¶å…§å®¹ï¼Œå°‡è‡ªå‹•è¤‡è£½ï¼‰ã€‚使用:
+引用:`sysfs intraface <ksm_sysfs>` 接å£ä¾†é…ç½®KSM守護程åºåœ¨å–®å€‹éŽç¨‹ä¸­æ‰€æŽƒæçš„é 
+數以åŠå…©å€‹éŽç¨‹ä¹‹é–“的間隔時間。
+
+KSMåªåˆä¸¦åŒ¿å(ç§æœ‰ï¼‰é é¢ï¼Œå¾žä¸åˆä¸¦é ç·©å­˜ï¼ˆæ–‡ä»¶ï¼‰é é¢ã€‚KSMçš„åˆä½µé é¢æœ€åˆåªèƒ½è¢«
+鎖定在內核內存中,但ç¾åœ¨å¯ä»¥å°±åƒå…¶ä»–用戶é é¢ä¸€æ¨£è¢«æ›å‡ºï¼ˆä½†ç•¶å®ƒå€‘被交æ›å›žä¾†æ™‚å…±
+享會被破壞: ksmdå¿…é ˆé‡æ–°ç™¼ç¾å®ƒå€‘的身份並å†æ¬¡åˆä½µï¼‰ã€‚
+
+以madvise控制KSM
+================
+
+KSM僅在特定的地å€ç©ºé–“å€åŸŸæ™‚é‹è¡Œï¼Œå³æ‡‰ç”¨ç¨‹åºé€šéŽä½¿ç”¨å¦‚下所示的madvise(2)系統調
+用來請求æŸå¡Šåœ°å€æˆçˆ²å¯èƒ½çš„åˆä½µå€™é¸è€…的地å€ç©ºé–“::
+
+ int madvise(addr, length, MADV_MERGEABLE)
+
+應用程åºç•¶ç„¶ä¹Ÿå¯ä»¥é€šéŽèª¿ç”¨::
+
+ int madvise(addr, length, MADV_UNMERGEABLE)
+
+來å–消該請求,並æ¢å¾©çˆ²éžå…±äº«é é¢ï¼šæ­¤æ™‚KSM將去除åˆä½µåœ¨è©²ç¯„åœå…§çš„任何åˆä½µé ã€‚注æ„:
+這個去除åˆä½µçš„調用å¯èƒ½çªç„¶éœ€è¦çš„內存é‡è¶…éŽå¯¦éš›å¯ç”¨çš„內存é‡-那麼å¯èƒ½æœƒå‡ºç¾EAGAIN
+失敗,但更å¯èƒ½æœƒå–šé†’OOM killer。
+
+如果KSM未被é…置到正在é‹è¡Œçš„內核中,則madvise MADV_MERGEABLE å’Œ MADV_UNMERGEABLE
+的調用åªæœƒä»¥EINVAL 失敗。如果正在é‹è¡Œçš„內核是用CONFIG_KSM=yæ–¹å¼æ§‹å»ºçš„,那麼這些
+調用通常會æˆåŠŸï¼šå³ä½¿KSM守護程åºç•¶å‰æ²’有é‹è¡Œï¼ŒMADV_MERGEABLE ä»ç„¶æœƒåœ¨KSM守護程åº
+啓動時註冊範åœï¼Œå³ä½¿è©²ç¯„åœä¸èƒ½åŒ…å«KSM實際å¯ä»¥åˆä½µçš„任何é é¢ï¼Œå³ä½¿MADV_UNMERGEABLE
+應用於從未標記爲MADV_MERGEABLE的範åœã€‚
+
+如果一塊內存å€åŸŸå¿…須被拆分爲至少一個新的MADV_MERGEABLEå€åŸŸæˆ–MADV_UNMERGEABLEå€åŸŸï¼Œ
+ç•¶è©²é€²ç¨‹å°‡è¶…éŽ ``vm.max_map_count`` 的設定,則madviseå¯èƒ½è¿”回ENOMEM。(請åƒé–±æ–‡æª”
+Documentation/admin-guide/sysctl/vm.rst)。
+
+與其他madvise調用一樣,它們在用戶地å€ç©ºé–“的映射å€åŸŸä¸Šä½¿ç”¨ï¼šå¦‚果指定的範åœåŒ…å«æœª
+映射的間隙(儘管在中間的映射å€åŸŸå·¥ä½œï¼‰ï¼Œå®ƒå€‘將報告ENOMEM,如果沒有足夠的內存用於
+內部çµæ§‹ï¼Œå‰‡å¯èƒ½æœƒå› EAGAIN而失敗。
+
+KSM守護進程sysfs接å£
+====================
+
+KSM守護進程å¯ä»¥ç”±``/sys/kernel/mm/ksm/`` 中的sysfs文件控制,所有人都å¯ä»¥è®€å–,但
+åªèƒ½ç”±root用戶寫入。å„接å£è§£é‡‹å¦‚下:
+
+
+pages_to_scan
+ ksmd進程進入ç¡çœ å‰è¦æŽƒæçš„é æ•¸ã€‚
+ 例如, ``echo 100 > /sys/kernel/mm/ksm/pages_to_scan``
+
+ 默èªå€¼ï¼š100(該值被é¸æ“‡ç”¨æ–¼æ¼”示目的)
+
+sleep_millisecs
+ ksmd在下次掃æå‰æ‡‰ä¼‘眠多少毫秒
+ 例如, ``echo 20 > /sys/kernel/mm/ksm/sleep_millisecs``
+
+ 默èªå€¼ï¼š20(該值被é¸æ“‡ç”¨æ–¼æ¼”示目的)
+
+merge_across_nodes
+ 指定是å¦å¯ä»¥åˆä½µä¾†è‡ªä¸åŒNUMA節點的é é¢ã€‚當設置爲0時,ksm僅åˆä½µåœ¨ç‰©ç†ä¸Šä½
+ æ–¼åŒä¸€NUMA節點的內存å€åŸŸä¸­çš„é é¢ã€‚這é™ä½Žäº†è¨ªå•å…±äº«é é¢çš„延é²ã€‚在有明顯的
+ NUMAè·é›¢ä¸Šï¼Œå…·æœ‰æ›´å¤šç¯€é»žçš„系統å¯èƒ½å—益於設置該值爲0時的更低延é²ã€‚而å°æ–¼
+ 需è¦å°å…§å­˜ä½¿ç”¨é‡æœ€å°åŒ–的較å°ç³»çµ±ä¾†èªªï¼Œè¨­ç½®è©²å€¼çˆ²1(默èªè¨­ç½®ï¼‰å‰‡å¯èƒ½æœƒå—
+ 益於更大共享é é¢ã€‚在決定使用哪種設置之å‰ï¼Œæ‚¨å¯èƒ½å¸Œæœ›æ¯”較系統在æ¯ç¨®è¨­ç½®ä¸‹
+ 的性能。 ``merge_across_nodes`` 僅當系統中沒有ksm共享é é¢æ™‚,æ‰èƒ½è¢«æ›´æ”¹è¨­
+ 置:首先將接å£`run` 設置爲2從而å°é é€²è¡ŒåŽ»åˆä½µï¼Œç„¶å¾Œåœ¨ä¿®æ”¹
+ ``merge_across_nodes`` 後å†å°‡â€˜run’åˆè¨­ç½®çˆ²1,以根據新設置來é‡æ–°åˆä½µã€‚
+
+ 默èªå€¼ï¼š1(如早期的發佈版本一樣åˆä½µè·¨ç«™é»žï¼‰
+
+run
+ * 設置爲0å¯åœæ­¢ksmdé‹è¡Œï¼Œä½†ä¿ç•™åˆä½µé é¢ï¼Œ
+ * 設置爲1å¯é‹è¡Œksmd,例如, ``echo 1 > /sys/kernel/mm/ksm/run`` ,
+ * 設置爲2å¯åœæ­¢ksmdé‹è¡Œï¼Œä¸¦ä¸”å°æ‰€æœ‰ç›®å‰å·²åˆä½µçš„é é€²è¡ŒåŽ»åˆä½µï¼Œä½†ä¿ç•™å¯åˆä½µ
+ å€åŸŸä»¥ä¾›ä¸‹æ¬¡é‹è¡Œã€‚
+
+ 默èªå€¼ï¼š0(必須設置爲1æ‰èƒ½æ¿€æ´»KSM,除éžç¦ç”¨äº†CONFIG_SYSFS)
+
+use_zero_pages
+ 指定是å¦æ‡‰ç•¶ç‰¹æ®Šè™•ç†ç©ºé ï¼ˆå³é‚£äº›åƒ…å«zero的已分é…é ï¼‰ã€‚當該值設置爲1時,
+ 空é èˆ‡å…§æ ¸é›¶é åˆä½µï¼Œè€Œä¸æ˜¯åƒé€šå¸¸æƒ…æ³ä¸‹é‚£æ¨£ç©ºé è‡ªèº«å½¼æ­¤åˆä½µã€‚這å¯ä»¥æ ¹æ“š
+ 工作負載的ä¸åŒï¼Œåœ¨å…·æœ‰ç€è‰²é›¶é çš„架構上å¯ä»¥æ高性能。啓用此設置時應å°å¿ƒï¼Œ
+ 因爲它å¯èƒ½æœƒé™ä½ŽæŸäº›å·¥ä½œè² è¼‰çš„KSM性能,比如,當待åˆä½µçš„候é¸é é¢çš„æ ¡é©—å’Œ
+ 與空é é¢çš„æ ¡é©—å’Œæ°å¥½åŒ¹é…的時候。此設置å¯éš¨æ™‚更改,僅å°é‚£äº›æ›´æ”¹å¾Œå†åˆä½µ
+ çš„é é¢æœ‰æ•ˆã€‚
+
+ 默èªå€¼ï¼š0(如åŒæ—©æœŸç‰ˆæœ¬çš„KSM正常表ç¾ï¼‰
+
+max_page_sharing
+ 單個KSMé é¢å…許的最大共享站點數。這將強制執行é‡è¤‡æ•¸æ“šæ¶ˆé™¤é™åˆ¶ï¼Œä»¥é¿å…涉
+ åŠé歷共享KSMé é¢çš„虛擬映射的虛擬內存æ“作的高延é²ã€‚最å°å€¼çˆ²2,因爲新創
+ 建的KSMé é¢å°‡è‡³å°‘有兩個共享者。該值越高,KSMåˆä½µå…§å­˜çš„速度越快,去é‡
+ å› å­ä¹Ÿè¶Šé«˜ï¼Œä½†æ˜¯å°æ–¼ä»»ä½•çµ¦å®šçš„KSMé é¢ï¼Œè™›æ“¬æ˜ å°„的最壞情æ³é歷的速度也會
+ 越慢。減慢了這種é歷速度就æ„味ç€åœ¨äº¤æ›ã€å£“縮ã€NUMA平衡和é é¢é·ç§»æœŸé–“,
+ æŸäº›è™›æ“¬å…§å­˜æ“作將有更高的延é²ï¼Œå¾žè€Œé™ä½Žé€™äº›è™›æ“¬å…§å­˜æ“作調用者的響應能力。
+ 其他任務如果ä¸æ¶‰åŠåŸ·è¡Œè™›æ“¬æ˜ å°„éæ­·çš„VMæ“作,其任務調度延é²ä¸å—æ­¤åƒæ•¸çš„å½±
+ 響,因爲這些é歷本身是調度å‹å¥½çš„。
+
+stable_node_chains_prune_millisecs
+ 指定KSM檢查特定é é¢çš„元數據的頻率(å³é‚£äº›é”到éŽæ™‚ä¿¡æ¯æ•¸æ“šåŽ»é‡é™åˆ¶æ¨™æº–çš„
+ é é¢ï¼‰å–®ä½æ˜¯æ¯«ç§’。較å°çš„毫秒值將以更低的延é²ä¾†é‡‹æ”¾KSM元數據,但它們將使
+ ksmd在掃æ期間使用更多CPU。如果還沒有一個KSMé é¢é”到 ``max_page_sharing``
+ 標準,那就沒有什麼用。
+
+KSM與MADV_MERGEABLE的工作有效性體ç¾æ–¼ ``/sys/kernel/mm/ksm/`` 路徑下的接å£ï¼š
+
+pages_shared
+ 表示多少共享é æ­£åœ¨è¢«ä½¿ç”¨
+pages_sharing
+ 表示還有多少站點正在共享這些共享é ï¼Œå³ç¯€çœäº†å¤šå°‘
+pages_unshared
+ 表示有多少é æ˜¯å”¯ä¸€çš„,但被å覆檢查以進行åˆä½µ
+pages_volatile
+ 表示有多少é å› è®ŠåŒ–太快而無法放在tree中
+full_scans
+ 表示所有å¯åˆä½µå€åŸŸå·²æŽƒæ多少次
+stable_node_chains
+ é”到 ``max_page_sharing`` é™åˆ¶çš„KSMé æ•¸
+stable_node_dups
+ é‡è¤‡çš„KSMé æ•¸
+
+比值 ``pages_sharing/pages_shared`` 的最大值å—é™åˆ¶æ–¼ ``max_page_sharing``
+的設定。è¦æƒ³å¢žåŠ è©²æ¯”值,則相應地è¦å¢žåŠ  ``max_page_sharing`` 的值。
+
+監測KSM的收益
+=============
+
+KSMå¯ä»¥é€šéŽåˆä½µç›¸åŒçš„é é¢ä¾†ç¯€çœå…§å­˜ï¼Œä½†ä¹Ÿæœƒæ¶ˆè€—é¡å¤–的內存,因爲它需è¦ç”Ÿæˆä¸€äº›rmap_items
+來ä¿å­˜æ¯å€‹æŽƒæé é¢çš„ç°¡è¦rmapä¿¡æ¯ã€‚其中有些é é¢å¯èƒ½æœƒè¢«åˆä½µï¼Œä½†æœ‰äº›é é¢åœ¨è¢«æª¢æŸ¥å¹¾æ¬¡
+後å¯èƒ½ç„¡æ³•è¢«åˆä½µï¼Œé€™äº›éƒ½æ˜¯ç„¡ç›Šçš„內存消耗。
+
+1) 如何確定KSM在全系統範åœå…§æ˜¯ç¯€çœå…§å­˜é‚„是消耗內存?這è£æœ‰ä¸€å€‹ç°¡å–®çš„近似計算方法供åƒè€ƒ::
+
+ general_profit =~ pages_sharing * sizeof(page) - (all_rmap_items) *
+ sizeof(rmap_item);
+
+ 其中all_rmap_itemså¯ä»¥é€šéŽå° ``pages_sharing`` 〠``pages_shared`` 〠``pages_unshared``
+ å’Œ ``pages_volatile`` 的求和而輕鬆ç²å¾—。
+
+2) 單一進程中KSM的收益也å¯ä»¥é€šéŽä»¥ä¸‹è¿‘似的計算得到::
+
+ process_profit =~ ksm_merging_pages * sizeof(page) -
+ ksm_rmap_items * sizeof(rmap_item).
+
+ 其中ksm_merging_pages顯示在 ``/proc/<pid>/`` 目錄下,而ksm_rmap_items
+ 顯示在 ``/proc/<pid>/ksm_stat`` 。
+
+從應用的角度來看, ``ksm_rmap_items`` å’Œ ``ksm_merging_pages`` 的高比例æ„
+味ç€ä¸å¥½çš„madvise-applied策略,所以開發者或管ç†å“¡å¿…é ˆé‡æ–°è€ƒæ…®å¦‚何改變madvisç­–
+略。舉個例å­ä¾›åƒè€ƒï¼Œä¸€å€‹é é¢çš„大å°é€šå¸¸æ˜¯4K,而rmap_item的大å°åœ¨32ä½CPU架構上分
+別是32B,在64ä½CPU架構上是64B。所以如果 ``ksm_rmap_items/ksm_merging_pages``
+的比例在64ä½CPU上超éŽ64,或者在32ä½CPU上超éŽ128,那麼應用程åºçš„madvise策略應
+該被放棄,因爲ksm收益大約爲零或負值。
+
+監控KSM事件
+===========
+
+在/proc/vmstat中有一些計數器,å¯ä»¥ç”¨ä¾†ç›£æŽ§KSM事件。KSMå¯èƒ½æœ‰åŠ©æ–¼ç¯€çœå…§å­˜ï¼Œé€™æ˜¯
+一種權衡,因爲它å¯èƒ½æœƒåœ¨KSM COW或複製中的交æ›ä¸Šé­å—延é²ã€‚這些事件å¯ä»¥å¹«åŠ©ç”¨æˆ¶è©•ä¼°
+是å¦æˆ–如何使用KSM。例如,如果cow_ksm增加得太快,用戶å¯ä»¥æ¸›å°‘madvise(, , MADV_MERGEABLE)
+的範åœã€‚
+
+cow_ksm
+ 在æ¯æ¬¡KSMé é¢è§¸ç™¼å¯«æ™‚æ‹·è²ï¼ˆCOW)時都會被éžå¢žï¼Œç•¶ç”¨æˆ¶è©¦åœ–寫入KSMé é¢æ™‚,
+ 我們必須åšä¸€å€‹æ‹·è²ã€‚
+
+ksm_swpin_copy
+ 在æ›å…¥æ™‚,æ¯æ¬¡KSMé è¢«è¤‡åˆ¶æ™‚都會被éžå¢žã€‚請注æ„,KSMé åœ¨æ›å…¥æ™‚å¯èƒ½æœƒè¢«è¤‡
+ 制,因爲do_swap_page()ä¸èƒ½åšæ‰€æœ‰çš„鎖,而需è¦é‡çµ„一個跨anon_vmaçš„KSMé ã€‚
+
+--
+Izik Eidus,
+Hugh Dickins, 2009年11月17日。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst b/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst
index ea51342879c0..fe5a5a07d51a 100644
--- a/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst
+++ b/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst
@@ -1,13 +1,6 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
-..
- If you want to distribute this text under CC-BY-4.0 only, please use 'The
- Linux kernel developers' for author attribution and link this as source:
- https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst
-..
- Note: Only the content of this RST file as found in the Linux kernel sources
- is available under CC-BY-4.0, as versions of this text that were processed
- (for example by the kernel's build system) might contain content taken from
- files which use a more restrictive license.
+.. See the bottom of this file for additional redistribution information.
+
.. include:: ../disclaimer-zh_TW.rst
@@ -26,14 +19,16 @@
簡明指å—ï¼ˆäº¦å³ å¤ªé•·ä¸çœ‹ï¼‰
==========================
-您é¢è‡¨çš„是å¦çˆ²åŒç³»åˆ—穩定版或長期支æŒå…§æ ¸çš„普通內核的回歸?是å¦ä»ç„¶å—支æŒï¼Ÿ
+您é¢è‡¨çš„是å¦çˆ²åŒç³»åˆ—穩定版或長期支æŒå…§æ ¸çš„普通內核的迴歸?是å¦ä»ç„¶å—支æŒï¼Ÿ
è«‹æœç´¢ `LKML內核郵件列表 <https://lore.kernel.org/lkml/>`_ å’Œ
`Linux穩定版郵件列表 <https://lore.kernel.org/stable/>`_ 存檔中匹é…的報告並
加入討論。如果找ä¸åˆ°åŒ¹é…的報告,請安è£è©²ç³»åˆ—的最新版本。如果它ä»ç„¶å‡ºç¾å•é¡Œï¼Œ
-報告給穩定版郵件列表(stable@vger.kernel.org)。
+請報告給穩定版郵件列表(stable@vger.kernel.org)並抄é€å›žæ­¸éƒµä»¶åˆ—表
+(regressions@lists.linux.dev);ç†æƒ³æƒ…æ³ä¸‹ï¼Œé‚„å¯ä»¥æŠ„é€ç¶­è­·è€…和相關å­ç³»çµ±çš„
+郵件列表。
在所有其他情æ³ä¸‹ï¼Œè«‹å„˜å¯èƒ½çŒœæ¸¬æ˜¯å“ªå€‹å…§æ ¸éƒ¨åˆ†å°Žè‡´äº†å•é¡Œã€‚查看MAINTAINERS文件,
-了解開發人員希望如何得知å•é¡Œï¼Œå¤§å¤šæ•¸æƒ…æ³ä¸‹ï¼Œå ±å‘Šå•é¡Œéƒ½æ˜¯é€šéŽé›»å­éƒµä»¶å’ŒæŠ„é€
+瞭解開發人員希望如何得知å•é¡Œï¼Œå¤§å¤šæ•¸æƒ…æ³ä¸‹ï¼Œå ±å‘Šå•é¡Œéƒ½æ˜¯é€šéŽé›»å­éƒµä»¶å’ŒæŠ„é€
相關郵件列表進行的。檢查報告目的地的存檔中是å¦å·²æœ‰åŒ¹é…的報告;也請æœç´¢
`LKML <https://lore.kernel.org/lkml/>`_ 和網絡。如果找ä¸åˆ°å¯åŠ å…¥çš„討論,請
å®‰è£ `最新的主線內核 <https://kernel.org/>`_ 。如果ä»å­˜åœ¨å•é¡Œï¼Œè«‹ç™¼é€å ±å‘Šã€‚
@@ -45,21 +40,22 @@
**通用æ醒** :當安è£å’Œæ¸¬è©¦ä¸Šè¿°å…§æ ¸æ™‚,請確ä¿å®ƒæ˜¯æ™®é€šçš„(å³ï¼šæ²’有補ä¸ï¼Œä¹Ÿæ²’
有使用附加模塊)。還è¦ç¢ºä¿å®ƒæ˜¯åœ¨ä¸€å€‹æ­£å¸¸çš„環境中構建和é‹è¡Œï¼Œä¸¦ä¸”在å•é¡Œç™¼ç”Ÿ
-之å‰æ²’有被汙染(tainted)。
+之å‰æ²’有被污染(tainted)。
-在編寫報告時,è¦æ¶µè“‹èˆ‡å•é¡Œç›¸é—œçš„所有信æ¯ï¼Œå¦‚使用的內核和發行版。在碰見回歸時,
-嘗試給出引入它的更改的æ交ID,二分å¯ä»¥æ‰¾åˆ°å®ƒã€‚如果您åŒæ™‚é¢è‡¨Linux內核的多個
-å•é¡Œï¼Œè«‹åˆ†åˆ¥å ±å‘Šæ¯å€‹å•é¡Œã€‚
+當你åŒæ™‚é¢è‡¨Linux內核的多個å•é¡Œæ™‚,請分別報告。在編寫報告時,è¦æ¶µè“‹èˆ‡å•é¡Œ
+相關的所有信æ¯ï¼Œå¦‚使用的內核和發行版。如果碰見迴歸,請把報告抄é€å›žæ­¸éƒµä»¶åˆ—表
+(regressions@lists.linux.dev)。也請試試用二分法找出æºé ­ï¼›å¦‚æžœæˆåŠŸæ‰¾åˆ°ï¼Œè«‹
+在報告中寫上它的æ交ID並抄é€sign-off-byéˆä¸­çš„所有人。
一旦報告發出,請回答任何出ç¾çš„å•é¡Œï¼Œä¸¦å„˜å¯èƒ½åœ°æ供幫助。這包括通éŽä¸æ™‚é‡æ–°
-測試新版本並發é€ç‹€æ…‹æ›´æ–°ä¾†æŽ¨å‹•é€²å±•ã€‚
+測試新版本併發é€ç‹€æ…‹æ›´æ–°ä¾†æŽ¨å‹•é€²å±•ã€‚
如何å‘內核維護人員報告å•é¡Œçš„é€æ­¥æŒ‡å—
=====================================
-上é¢çš„簡明指å—概述了如何å‘Linux內核開發人員報告å•é¡Œã€‚å°æ–¼å·²ç¶“熟悉å‘自由和開
-æºè»Ÿé«”(FLOSS)項目報告å•é¡Œçš„人來說,這å¯èƒ½æ˜¯ä»–們所需è¦çš„全部內容。å°æ–¼å…¶ä»–
+上é¢çš„簡明指å—概述瞭如何å‘Linux內核開發人員報告å•é¡Œã€‚å°æ–¼å·²ç¶“熟悉å‘自由和開
+æºè»Ÿä»¶ï¼ˆFLOSS)項目報告å•é¡Œçš„人來說,這å¯èƒ½æ˜¯ä»–們所需è¦çš„全部內容。å°æ–¼å…¶ä»–
人,本部分更爲詳細,並一步一步地æ述。爲了便於閱讀,它ä»ç„¶å„˜é‡ç°¡æ½”,並çœç•¥
了許多細節;這些在é€æ­¥æŒ‡å—後的åƒè€ƒç« ç¯€ä¸­é€²è¡Œäº†æ述,該章節更詳細地解釋了æ¯
個步驟。
@@ -68,16 +64,16 @@
儘早æ„識到看起來åƒLinux內核毛病的å•é¡Œå¯èƒ½å¯¦éš›ä¸Šæ˜¯ç”±å…¶ä»–原因引起的。這些步驟
å¯ä»¥ç¢ºä¿ä½ æœ€çµ‚ä¸æœƒè¦ºå¾—在這一éŽç¨‹ä¸­æŠ•å…¥çš„時間是浪費:
- * 您是å¦é¢è‡¨ç¡¬é«”或軟體供應商æ供的Linux內核的å•é¡Œï¼Ÿé‚£éº¼åŸºæœ¬ä¸Šæ‚¨æœ€å¥½åœæ­¢é–±è®€
+ * 您是å¦é¢è‡¨ç¡¬ä»¶æˆ–軟件供應商æ供的Linux內核的å•é¡Œï¼Ÿé‚£éº¼åŸºæœ¬ä¸Šæ‚¨æœ€å¥½åœæ­¢é–±è®€
本文檔,轉而å‘您的供應商報告å•é¡Œï¼Œé™¤éžæ‚¨é¡˜æ„自己安è£æœ€æ–°çš„Linux版本。尋找
和解決å•é¡Œå¾€å¾€éœ€è¦å¾Œè€…。
- * 使用您喜愛的網絡æœå°‹å¼•æ“Žå°ç¾æœ‰å ±å‘Šé€²è¡Œç²—ç•¥æœç´¢ï¼›æ­¤å¤–,請檢查
+ * 使用您喜愛的網絡æœç´¢å¼•æ“Žå°ç¾æœ‰å ±å‘Šé€²è¡Œç²—ç•¥æœç´¢ï¼›æ­¤å¤–,請檢查
`Linux內核郵件列表(LKML) <https://lore.kernel.org/lkml/>`_ 的存檔。如果
找到匹é…的報告,請加入討論而ä¸æ˜¯ç™¼é€æ–°å ±å‘Šã€‚
- * 看看你正在處ç†çš„å•é¡Œæ˜¯å¦çˆ²å›žæ­¸å•é¡Œã€å®‰å…¨å•é¡Œæˆ–éžå¸¸åš´é‡çš„å•é¡Œï¼šé€™äº›éƒ½æ˜¯éœ€
- è¦åœ¨æŽ¥ä¸‹ä¾†çš„一些步驟中特別處ç†çš„「高優先級å•é¡Œã€ã€‚
+ * 看看你正在處ç†çš„å•é¡Œæ˜¯å¦çˆ²è¿´æ­¸å•é¡Œã€å®‰å…¨å•é¡Œæˆ–éžå¸¸åš´é‡çš„å•é¡Œï¼šé€™äº›éƒ½æ˜¯éœ€
+ è¦åœ¨æŽ¥ä¸‹ä¾†çš„一些步驟中特別處ç†çš„“高優先級å•é¡Œâ€ã€‚
* 確ä¿ä¸æ˜¯å…§æ ¸ç’°å¢ƒå°Žè‡´äº†æ‚¨é¢è‡¨çš„å•é¡Œã€‚
@@ -86,15 +82,15 @@
* 確ä¿æ‚¨çš„系統ä¸æœƒé€šéŽå‹•æ…‹æ§‹å»ºé¡å¤–的內核模塊來增強其內核,åƒDKMS這樣的解決
方案å¯èƒ½åœ¨æ‚¨ä¸çŸ¥æƒ…的情æ³ä¸‹å°±åœ¨æœ¬åœ°é€²è¡Œäº†é€™æ¨£çš„工作。
- * 當å•é¡Œç™¼ç”Ÿæ™‚,檢查您的內核是å¦è¢«ã€Œæ±™æŸ“ã€ï¼Œå› çˆ²ä½¿å…§æ ¸è¨­ç½®é€™å€‹æ¨™èªŒçš„事件å¯èƒ½
+ * 當å•é¡Œç™¼ç”Ÿæ™‚,檢查您的內核是å¦è¢«â€œæ±¡æŸ“â€ï¼Œå› çˆ²ä½¿å…§æ ¸è¨­ç½®é€™å€‹æ¨™èªŒçš„事件å¯èƒ½
會導致您é¢è‡¨çš„å•é¡Œã€‚
* 粗略地寫下如何é‡ç¾é€™å€‹å•é¡Œã€‚如果您åŒæ™‚處ç†å¤šå€‹å•é¡Œï¼Œè«‹çˆ²æ¯å€‹å•é¡Œå–®ç¨å¯«æ³¨
釋,並確ä¿å®ƒå€‘在新啓動的系統上ç¨ç«‹å‡ºç¾ã€‚這是必è¦çš„,因爲æ¯å€‹å•é¡Œéƒ½éœ€è¦åˆ†
別報告給內核開發人員,除éžå®ƒå€‘åš´é‡ç³¾çºåœ¨ä¸€èµ·ã€‚
- * 如果您正é¢è‡¨ç©©å®šç‰ˆæˆ–長期支æŒç‰ˆæœ¬ç·šçš„回歸(例如從5.10.4更新到5.10.5時出ç¾
- 故障),請查看後文「報告穩定版和長期支æŒå…§æ ¸ç·šçš„回歸ã€å°ç¯€ã€‚
+ * 如果您正é¢è‡¨ç©©å®šç‰ˆæˆ–長期支æŒç‰ˆæœ¬ç·šçš„迴歸(例如從5.10.4更新到5.10.5時出ç¾
+ 故障),請查看後文“報告穩定版和長期支æŒå…§æ ¸ç·šçš„è¿´æ­¸â€å°ç¯€ã€‚
* 定ä½å¯èƒ½å¼•èµ·å•é¡Œçš„驅動程åºæˆ–內核å­ç³»çµ±ã€‚找出其開發人員期望的報告的方å¼å’Œ
ä½ç½®ã€‚注æ„:大多數情æ³ä¸‹ä¸æœƒæ˜¯ bugzilla.kernel.org,因爲å•é¡Œé€šå¸¸éœ€è¦é€š
@@ -105,61 +101,62 @@
在完æˆé€™äº›æº–備之後,你將進入主è¦éƒ¨åˆ†ï¼š
- * 除éžæ‚¨å·²ç¶“在é‹è¡Œæœ€æ–°çš„「主線ã€Linux內核,å¦å‰‡æœ€å¥½åœ¨å ±å‘Šæµç¨‹å‰å®‰è£å®ƒã€‚在æŸäº›
- 情æ³ä¸‹ï¼Œä½¿ç”¨æœ€æ–°çš„「穩定版ã€Linux進行測試和報告也是å¯ä»¥æŽ¥å—的替代方案;在
+ * 除éžæ‚¨å·²ç¶“在é‹è¡Œæœ€æ–°çš„“主線â€Linux內核,å¦å‰‡æœ€å¥½åœ¨å ±å‘Šæµç¨‹å‰å®‰è£å®ƒã€‚在æŸäº›
+ 情æ³ä¸‹ï¼Œä½¿ç”¨æœ€æ–°çš„“穩定版â€Linux進行測試和報告也是å¯ä»¥æŽ¥å—的替代方案;在
åˆä½µçª—å£æœŸé–“,這實際上å¯èƒ½æ˜¯æœ€å¥½çš„方法,但在開發階段最好還是暫åœå¹¾å¤©ã€‚ç„¡è«–
- ä½ é¸æ“‡ä»€éº¼ç‰ˆæœ¬ï¼Œæœ€å¥½ä½¿ç”¨ã€Œæ™®é€šã€æ§‹å»ºã€‚忽略這些建議會大大增加您的報告被拒絕
+ ä½ é¸æ“‡ä»€éº¼ç‰ˆæœ¬ï¼Œæœ€å¥½ä½¿ç”¨â€œæ™®é€šâ€æ§‹å»ºã€‚忽略這些建議會大大增加您的報告被拒絕
或忽略的風險。
- * 確ä¿æ‚¨å‰›å‰›å®‰è£çš„內核在é‹è¡Œæ™‚ä¸æœƒã€Œæ±™æŸ“ã€è‡ªå·±ã€‚
+ * 確ä¿æ‚¨å‰›å‰›å®‰è£çš„內核在é‹è¡Œæ™‚ä¸æœƒâ€œæ±¡æŸ“â€è‡ªå·±ã€‚
* 在您剛剛安è£çš„內核中復ç¾é€™å€‹å•é¡Œã€‚如果它沒有出ç¾ï¼Œè«‹æŸ¥çœ‹ä¸‹æ–¹åªç™¼ç”Ÿåœ¨
穩定版和長期支æŒå…§æ ¸çš„å•é¡Œçš„說明。
- * 優化你的筆記:試著找到並寫出最直接的復ç¾å•é¡Œçš„方法。確ä¿æœ€çµ‚çµæžœåŒ…å«æ‰€æœ‰
+ * 優化你的筆記:試ç€æ‰¾åˆ°ä¸¦å¯«å‡ºæœ€ç›´æŽ¥çš„復ç¾å•é¡Œçš„方法。確ä¿æœ€çµ‚çµæžœåŒ…å«æ‰€æœ‰
é‡è¦çš„細節,åŒæ™‚讓第一次è½èªªçš„人容易閱讀和ç†è§£ã€‚如果您在此éŽç¨‹ä¸­å­¸åˆ°äº†ä¸€
些æ±è¥¿ï¼Œè«‹è€ƒæ…®å†æ¬¡æœç´¢é—œæ–¼è©²å•é¡Œçš„ç¾æœ‰å ±å‘Šã€‚
- * 如果失敗涉åŠã€Œpanicã€ã€ã€ŒOopsã€ã€ã€Œwarningã€æˆ–「BUGã€ï¼Œè«‹è€ƒæ…®è§£ç¢¼å…§æ ¸æ—¥èªŒä»¥æŸ¥æ‰¾è§¸
+ * 如果失敗涉åŠâ€œpanicâ€ã€â€œOopsâ€ã€â€œwarningâ€æˆ–“BUGâ€ï¼Œè«‹è€ƒæ…®è§£ç¢¼å…§æ ¸æ—¥èªŒä»¥æŸ¥æ‰¾è§¸
發錯誤的代碼行。
- * 如果您的å•é¡Œæ˜¯å›žæ­¸å•é¡Œï¼Œè«‹å„˜å¯èƒ½ç¸®å°å¼•å…¥å•é¡Œæ™‚的範åœã€‚
+ * 如果您的å•é¡Œæ˜¯è¿´æ­¸å•é¡Œï¼Œè«‹å„˜å¯èƒ½ç¸®å°å¼•å…¥å•é¡Œæ™‚的範åœã€‚
* 通éŽè©³ç´°æè¿°å•é¡Œä¾†é–‹å§‹ç·¨å¯«å ±å‘Šã€‚記得包括以下æ¢ç›®ï¼šæ‚¨çˆ²å¾©ç¾è€Œå®‰è£çš„最新內
核版本ã€ä½¿ç”¨çš„Linux發行版以åŠé—œæ–¼å¦‚何復ç¾è©²å•é¡Œçš„說明。如果å¯èƒ½ï¼Œå°‡å…§æ ¸
- 構建é…置(.config)和 ``dmesg`` 的輸出放在網上的æŸå€‹åœ°æ–¹ï¼Œä¸¦é€£çµåˆ°å®ƒã€‚包
+ 構建é…置(.config)和 ``dmesg`` 的輸出放在網上的æŸå€‹åœ°æ–¹ï¼Œä¸¦éˆæŽ¥åˆ°å®ƒã€‚包
å«æˆ–上傳所有其他å¯èƒ½ç›¸é—œçš„ä¿¡æ¯ï¼Œå¦‚Oops的輸出/截圖或來自 ``lspci`` 的輸出
。一旦你寫完了這個主è¦éƒ¨åˆ†ï¼Œè«‹åœ¨ä¸Šæ–¹æ’入一個正常長度的段è½å¿«é€Ÿæ¦‚è¿°å•é¡Œå’Œ
影響。å†åœ¨æ­¤ä¹‹ä¸Šæ·»åŠ ä¸€å€‹ç°¡å–®æè¿°å•é¡Œçš„å¥å­ï¼Œä»¥å¾—到人們的閱讀。ç¾åœ¨çµ¦å‡ºä¸€
個更短的æ述性標題或主題。然後就å¯ä»¥åƒMAINTAINERS文件告訴你的那樣發é€æˆ–
- æ交報告了,除éžä½ åœ¨è™•ç†ä¸€å€‹ã€Œé«˜å„ªå…ˆç´šå•é¡Œã€ï¼šå®ƒå€‘需è¦æŒ‰ç…§ä¸‹é¢ã€Œé«˜å„ªå…ˆç´šå•
- 題的特殊處ç†ã€æ‰€è¿°ç‰¹åˆ¥é—œç…§ã€‚
+ æ交報告了,除éžä½ åœ¨è™•ç†ä¸€å€‹â€œé«˜å„ªå…ˆç´šå•é¡Œâ€ï¼šå®ƒå€‘需è¦æŒ‰ç…§ä¸‹é¢â€œé«˜å„ªå…ˆç´šå•
+ 題的特殊處ç†â€æ‰€è¿°ç‰¹åˆ¥é—œç…§ã€‚
* 等待別人的å應,繼續推進事情,直到你能夠接å—這樣或那樣的çµæžœã€‚因此,請公
é–‹å’ŒåŠæ™‚地回應任何詢å•ã€‚測試æ出的修復。ç©æ¥µåœ°æ¸¬è©¦ï¼šè‡³å°‘é‡æ–°æ¸¬è©¦æ¯å€‹æ–°ä¸»
線版本的首個候é¸ç‰ˆæœ¬ï¼ˆRC),並報告你的çµæžœã€‚如果出ç¾æ‹–延,就å‹å¥½åœ°æ醒一
- 下。如果你沒有得到任何幫助或者未能滿æ„,請試著自己幫助自己。
+ 下。如果你沒有得到任何幫助或者未能滿æ„,請試ç€è‡ªå·±å¹«åŠ©è‡ªå·±ã€‚
-報告穩定版和長期支æŒå…§æ ¸ç·šçš„回歸
+報告穩定版和長期支æŒå…§æ ¸ç·šçš„è¿´æ­¸
----------------------------------
-如果您發ç¾äº†ç©©å®šç‰ˆæˆ–長期支æŒå…§æ ¸ç‰ˆæœ¬ç·šä¸­çš„回歸å•é¡Œä¸¦æŒ‰ä¸Šè¿°æµç¨‹è·³åˆ°é€™è£¡ï¼Œé‚£éº¼
+如果您發ç¾äº†ç©©å®šç‰ˆæˆ–長期支æŒå…§æ ¸ç‰ˆæœ¬ç·šä¸­çš„è¿´æ­¸å•é¡Œä¸¦æŒ‰ä¸Šè¿°æµç¨‹è·³åˆ°é€™è£ï¼Œé‚£éº¼
請閱讀本å°ç¯€ã€‚å³ä¾‹å¦‚您在從5.10.4更新到5.10.5時出ç¾äº†å•é¡Œï¼ˆå¾ž5.9.15到5.10.5則
-ä¸æ˜¯ï¼‰ã€‚開發人員希望儘快修復此類回歸,因此有一個簡化æµç¨‹ä¾†å ±å‘Šå®ƒå€‘:
+ä¸æ˜¯ï¼‰ã€‚開發人員希望儘快修復此類迴歸,因此有一個簡化æµç¨‹ä¾†å ±å‘Šå®ƒå€‘:
* 檢查內核開發人員是å¦ä»ç„¶ç¶­è­·ä½ é—œå¿ƒçš„Linux內核版本線:去 `kernel.org 的首é 
- <https://kernel.org/>`_ ,確ä¿æ­¤ç‰¹å®šç‰ˆæœ¬ç·šçš„最新版沒有「[EOL]ã€æ¨™è¨˜ã€‚
+ <https://kernel.org/>`_ ,確ä¿æ­¤ç‰¹å®šç‰ˆæœ¬ç·šçš„最新版沒有“[EOL]â€æ¨™è¨˜ã€‚
* 檢查 `Linux穩定版郵件列表 <https://lore.kernel.org/stable/>`_ 中的ç¾æœ‰å ±å‘Šã€‚
- * 從特定的版本線安è£æœ€æ–°ç‰ˆæœ¬ä½œçˆ²ç´”淨內核。確ä¿é€™å€‹å…§æ ¸æ²’有被汙染,並且ä»ç„¶
- 存在å•é¡Œï¼Œå› çˆ²å•é¡Œå¯èƒ½å·²ç¶“在那裡被修復了。如果您第一次發ç¾ä¾›æ‡‰å•†å…§æ ¸çš„å•é¡Œï¼Œ
+ * 從特定的版本線安è£æœ€æ–°ç‰ˆæœ¬ä½œçˆ²ç´”淨內核。確ä¿é€™å€‹å…§æ ¸æ²’有被污染,並且ä»ç„¶
+ 存在å•é¡Œï¼Œå› çˆ²å•é¡Œå¯èƒ½å·²ç¶“在那è£è¢«ä¿®å¾©äº†ã€‚如果您第一次發ç¾ä¾›æ‡‰å•†å…§æ ¸çš„å•é¡Œï¼Œ
請檢查已知最新版本的普通構建是å¦å¯ä»¥æ­£å¸¸é‹è¡Œã€‚
- * å‘Linux穩定版郵件列表發é€ä¸€å€‹ç°¡çŸ­çš„å•é¡Œå ±å‘Š(stable@vger.kernel.org)。大致
- æè¿°å•é¡Œï¼Œä¸¦è§£é‡‹å¦‚何復ç¾ã€‚講清楚首個出ç¾å•é¡Œçš„版本和最後一個工作正常的版本。
- 然後等待進一步的指示。
+ * å‘Linux穩定版郵件列表發é€ä¸€å€‹ç°¡çŸ­çš„å•é¡Œå ±å‘Šï¼ˆstable@vger.kernel.org)並抄é€
+ Linux迴歸郵件列表(regressions@lists.linux.dev);如果你懷疑是由æŸå­ç³»çµ±
+ 引起的,請抄é€å…¶ç¶­è­·äººå“¡å’Œå­ç³»çµ±éƒµä»¶åˆ—表。大致æè¿°å•é¡Œï¼Œä¸¦è§£é‡‹å¦‚何復ç¾ã€‚
+ 講清楚首個出ç¾å•é¡Œçš„版本和最後一個工作正常的版本。然後等待進一步的指示。
下é¢çš„åƒè€ƒç« ç¯€éƒ¨åˆ†è©³ç´°è§£é‡‹äº†é€™äº›æ­¥é©Ÿä¸­çš„æ¯ä¸€æ­¥ã€‚
@@ -167,14 +164,14 @@
報告åªç™¼ç”Ÿåœ¨è¼ƒèˆŠå…§æ ¸ç‰ˆæœ¬ç·šçš„å•é¡Œ
----------------------------------
-若您嘗試了上述的最新主線內核,但未能在那裡復ç¾å•é¡Œï¼Œé‚£éº¼æœ¬å°ç¯€é©ç”¨æ–¼æ‚¨ï¼›ä»¥ä¸‹
+若您嘗試了上述的最新主線內核,但未能在那è£å¾©ç¾å•é¡Œï¼Œé‚£éº¼æœ¬å°ç¯€é©ç”¨æ–¼æ‚¨ï¼›ä»¥ä¸‹
æµç¨‹æœ‰åŠ©æ–¼ä½¿å•é¡Œåœ¨ä»ç„¶æ”¯æŒçš„穩定版或長期支æŒç‰ˆæœ¬ç·šï¼Œæˆ–者定期基於最新穩定版或
長期支æŒå…§æ ¸çš„供應商內核中得到修復。如果是這種情æ³ï¼Œè«‹åŸ·è¡Œä»¥ä¸‹æ­¥é©Ÿï¼š
* è«‹åšå¥½æº–備,接下來的幾個步驟å¯èƒ½ç„¡æ³•åœ¨èˆŠç‰ˆæœ¬ä¸­è§£æ±ºå•é¡Œï¼šä¿®å¾©å¯èƒ½å¤ªå¤§æˆ–太
- 冒險,無法移æ¤åˆ°é‚£è£¡ã€‚
+ 冒險,無法移æ¤åˆ°é‚£è£ã€‚
- * 執行å‰ç¯€ã€Œå ±å‘Šç©©å®šç‰ˆå’Œé•·æœŸæ”¯æŒå…§æ ¸ç·šçš„回歸ã€ä¸­çš„å‰ä¸‰å€‹æ­¥é©Ÿã€‚
+ * 執行å‰ç¯€â€œå ±å‘Šç©©å®šç‰ˆå’Œé•·æœŸæ”¯æŒå…§æ ¸ç·šçš„è¿´æ­¸â€ä¸­çš„å‰ä¸‰å€‹æ­¥é©Ÿã€‚
* 在Linux內核版本控制系統中æœç´¢ä¿®å¾©ä¸»ç·šå•é¡Œçš„更改,因爲它的æ交消æ¯å¯èƒ½æœƒ
告訴你修復是å¦å·²ç¶“計劃好了支æŒã€‚如果你沒有找到,æœç´¢é©ç•¶çš„郵件列表,尋找
@@ -219,14 +216,14 @@
確ä¿æ‚¨ä½¿ç”¨çš„是上游Linux內核
----------------------------
- *您是å¦é¢è‡¨ç¡¬é«”或軟體供應商æ供的Linux內核的å•é¡Œï¼Ÿé‚£éº¼åŸºæœ¬ä¸Šæ‚¨æœ€å¥½åœæ­¢é–±
+ *您是å¦é¢è‡¨ç¡¬ä»¶æˆ–軟件供應商æ供的Linux內核的å•é¡Œï¼Ÿé‚£éº¼åŸºæœ¬ä¸Šæ‚¨æœ€å¥½åœæ­¢é–±
讀本文檔,轉而å‘您的供應商報告å•é¡Œï¼Œé™¤éžæ‚¨é¡˜æ„自己安è£æœ€æ–°çš„Linux版本。
尋找和解決å•é¡Œå¾€å¾€éœ€è¦å¾Œè€…。*
-與大多數程å¼è¨­è¨ˆå¸«ä¸€æ¨£ï¼ŒLinux內核開發人員ä¸å–œæ­¡èŠ±æ™‚間處ç†ä»–們維護的原始碼中根本
-ä¸æœƒç™¼ç”Ÿçš„å•é¡Œçš„報告。這åªæœƒæµªè²»æ¯å€‹äººçš„時間,尤其是你的時間。ä¸å¹¸çš„是,當
+與大多數程åºå“¡ä¸€æ¨£ï¼ŒLinux內核開發人員ä¸å–œæ­¡èŠ±æ™‚間處ç†ä»–們維護的æºä»£ç¢¼ä¸­æ ¹æœ¬
+ä¸æœƒç™¼ç”Ÿçš„å•é¡Œçš„報告。這隻會浪費æ¯å€‹äººçš„時間,尤其是你的時間。ä¸å¹¸çš„是,當
涉åŠåˆ°å…§æ ¸æ™‚,這樣的情æ³å¾ˆå®¹æ˜“發生,並且常常導致雙方氣餒。這是因爲幾乎所有é 
-è£åœ¨è¨­å‚™ï¼ˆå°å¼æ©Ÿã€ç­†è¨˜æœ¬é›»è…¦ã€æ™ºæ…§åž‹æ‰‹æ©Ÿã€è·¯ç”±å™¨ç­‰ï¼‰ä¸Šçš„Linux內核,以åŠå¤§å¤šæ•¸
+è£åœ¨è¨­å‚™ï¼ˆè‡ºå¼æ©Ÿã€ç­†è¨˜æœ¬é›»è…¦ã€æ™ºèƒ½æ‰‹æ©Ÿã€è·¯ç”±å™¨ç­‰ï¼‰ä¸Šçš„Linux內核,以åŠå¤§å¤šæ•¸
ç”±Linux發行商æ供的內核,都與由kernel.org發行的官方Linux內核相è·ç”šé ï¼šå¾žLinux
開發的角度來看,這些供應商æ供的內核通常是å¤è€çš„或者經éŽäº†å¤§é‡ä¿®æ”¹ï¼Œé€šå¸¸å…©é»ž
兼具。
@@ -235,19 +232,19 @@
å¯èƒ½å·²ç¶“ç”±Linux內核開發人員在數月或數年å‰ä¿®å¾©ï¼›æ­¤å¤–,供應商的修改和增強å¯èƒ½
會導致您é¢è‡¨çš„å•é¡Œï¼Œå³ä½¿å®ƒå€‘看起來很å°æˆ–者完全ä¸ç›¸é—œã€‚這就是爲什麼您應該å‘
供應商報告這些內核的å•é¡Œã€‚它的開發者應該查看報告,如果它是一個上游å•é¡Œï¼Œç›´æŽ¥
-於上游修復或將報告轉發到那裡。在實è¸ä¸­ï¼Œé€™æœ‰æ™‚è¡Œä¸é€šã€‚因此,您å¯èƒ½éœ€è¦è€ƒæ…®
+於上游修復或將報告轉發到那è£ã€‚在實è¸ä¸­ï¼Œé€™æœ‰æ™‚è¡Œä¸é€šã€‚因此,您å¯èƒ½éœ€è¦è€ƒæ…®
通éŽè‡ªå·±å®‰è£æœ€æ–°çš„Linux內核內核來繞éŽä¾›æ‡‰å•†ã€‚如果如果您é¸æ“‡æ­¤æ–¹æ³•ï¼Œé‚£éº¼æœ¬æŒ‡
å—後é¢çš„步驟將解釋如何在排除了其他å¯èƒ½å°Žè‡´æ‚¨çš„å•é¡Œçš„原因後執行此æ“作。
-注æ„å‰æ®µä½¿ç”¨çš„詞語是「大多數ã€ï¼Œå› çˆ²æœ‰æ™‚候開發人員實際上願æ„處ç†ä¾›æ‡‰å•†å…§æ ¸å‡ºç¾
+注æ„å‰æ®µä½¿ç”¨çš„詞語是“大多數â€ï¼Œå› çˆ²æœ‰æ™‚候開發人員實際上願æ„處ç†ä¾›æ‡‰å•†å…§æ ¸å‡ºç¾
çš„å•é¡Œå ±å‘Šã€‚他們是å¦é€™éº¼åšå¾ˆå¤§ç¨‹åº¦ä¸Šå–決於開發人員和相關å•é¡Œã€‚如果發行版åª
根據最近的Linux版本å°å…§æ ¸é€²è¡Œäº†è¼ƒå°ä¿®æ”¹ï¼Œé‚£éº¼æ©Ÿæœƒå°±æ¯”較大;例如å°æ–¼Debian
GNU/Linux Sid或Fedora Rawhide所æ供的主線內核。一些開發人員還將接å—基於最新
穩定內核的發行版內核å•é¡Œå ±å‘Šï¼Œåªè¦å®ƒæ”¹å‹•ä¸å¤§ï¼›ä¾‹å¦‚Arch Linuxã€å¸¸è¦Fedora版本
å’ŒopenSUSE Turboweed。但是請記ä½ï¼Œæ‚¨æœ€å¥½ä½¿ç”¨ä¸»ç·šLinux,並é¿å…在此æµç¨‹ä¸­ä½¿ç”¨
-穩定版內核,如「安è£ä¸€å€‹æ–°çš„內核進行測試ã€ä¸€ç¯€ä¸­æ‰€è©³è¿°ã€‚
+穩定版內核,如“安è£ä¸€å€‹æ–°çš„內核進行測試â€ä¸€ç¯€ä¸­æ‰€è©³è¿°ã€‚
-當然,您å¯ä»¥å¿½ç•¥æ‰€æœ‰é€™äº›å»ºè­°ï¼Œä¸¦å‘上游Linux開發人員報告舊的或經éŽå¤§é‡ä¿®æ”¹çš„
+當然,您å¯ä»¥å¿½ç•¥æ‰€æœ‰é€™äº›å»ºè­°ï¼Œä¸¦å‘上éŠLinux開發人員報告舊的或經éŽå¤§é‡ä¿®æ”¹çš„
供應商內核的å•é¡Œã€‚但是注æ„,這樣的報告經常被拒絕或忽視,所以自行å°å¿ƒè€ƒæ…®ä¸€ä¸‹ã€‚
ä¸éŽé€™é‚„是比根本ä¸å ±å‘Šå•é¡Œè¦å¥½ï¼šæœ‰æ™‚候這樣的報告會直接或間接地幫助解決之後的
å•é¡Œã€‚
@@ -256,64 +253,61 @@ GNU/Linux Sid或Fedora Rawhide所æ供的主線內核。一些開發人員還å°
æœç´¢ç¾æœ‰å ±å‘Šï¼ˆç¬¬ä¸€éƒ¨åˆ†ï¼‰
-------------------------
- *使用您喜愛的網絡æœå°‹å¼•æ“Žå°ç¾æœ‰å ±å‘Šé€²è¡Œç²—ç•¥æœç´¢ï¼›æ­¤å¤–,請檢查Linux內核
+ *使用您喜愛的網絡æœç´¢å¼•æ“Žå°ç¾æœ‰å ±å‘Šé€²è¡Œç²—ç•¥æœç´¢ï¼›æ­¤å¤–,請檢查Linux內核
郵件列表(LKML)的存檔。如果找到匹é…的報告,請加入討論而ä¸æ˜¯ç™¼é€æ–°å ±å‘Šã€‚*
報告一個別人已經æ出的å•é¡Œï¼Œå°æ¯å€‹äººä¾†èªªéƒ½æ˜¯æµªè²»æ™‚間,尤其是作爲報告人的你。
所以徹底檢查是å¦æœ‰äººå·²ç¶“報告了這個å•é¡Œï¼Œé€™å°ä½ è‡ªå·±æ˜¯æœ‰åˆ©çš„。在æµç¨‹ä¸­çš„這一步,
-å¯ä»¥åªåŸ·è¡Œä¸€å€‹ç²—略的æœç´¢ï¼šä¸€æ—¦æ‚¨çŸ¥é“您的å•é¡Œéœ€è¦å ±å‘Šåˆ°å“ªè£¡ï¼Œç¨å¾Œçš„步驟將告訴
+å¯ä»¥åªåŸ·è¡Œä¸€å€‹ç²—略的æœç´¢ï¼šä¸€æ—¦æ‚¨çŸ¥é“您的å•é¡Œéœ€è¦å ±å‘Šåˆ°å“ªè£ï¼Œç¨å¾Œçš„步驟將告訴
您如何詳細æœç´¢ã€‚儘管如此,ä¸è¦å€‰ä¿ƒå®Œæˆé€™ä¸€æ­¥ï¼Œå®ƒå¯ä»¥ç¯€çœæ‚¨çš„時間和減少麻煩。
-åªéœ€å…ˆç”¨ä½ æœ€å–œæ­¡çš„æœå°‹å¼•æ“Žåœ¨ç¶²éš›ç¶²è·¯ä¸Šæœç´¢ã€‚然後å†æœç´¢Linux內核郵件列表(LKML)
+åªéœ€å…ˆç”¨ä½ æœ€å–œæ­¡çš„æœç´¢å¼•æ“Žåœ¨äº’è¯ç¶²ä¸Šæœç´¢ã€‚然後å†æœç´¢Linux內核郵件列表(LKML)
存檔。
-如果æœç´¢çµæžœå¯¦åœ¨å¤ªå¤šï¼Œå¯ä»¥è€ƒæ…®è®“ä½ çš„æœå°‹å¼•æ“Žå°‡æœç´¢æ™‚間範åœé™åˆ¶åœ¨éŽåŽ»çš„一個
-月或一年。而且無論你在哪裡æœç´¢ï¼Œä¸€å®šè¦ç”¨æ°ç•¶çš„æœç´¢é—œéµè©žï¼›ä¹Ÿè¦è®ŠåŒ–幾次關éµ
-詞。åŒæ™‚,試著從別人的角度看å•é¡Œï¼šé€™å°‡å¹«åŠ©ä½ æƒ³å‡ºå…¶ä»–çš„é—œéµè©žã€‚å¦å¤–,一定ä¸
+如果æœç´¢çµæžœå¯¦åœ¨å¤ªå¤šï¼Œå¯ä»¥è€ƒæ…®è®“ä½ çš„æœç´¢å¼•æ“Žå°‡æœç´¢æ™‚間範åœé™åˆ¶åœ¨éŽåŽ»çš„一個
+月或一年。而且無論你在哪è£æœç´¢ï¼Œä¸€å®šè¦ç”¨æ°ç•¶çš„æœç´¢é—œéµè©žï¼›ä¹Ÿè¦è®ŠåŒ–幾次關éµ
+詞。åŒæ™‚,試ç€å¾žåˆ¥äººçš„角度看å•é¡Œï¼šé€™å°‡å¹«åŠ©ä½ æƒ³å‡ºå…¶ä»–çš„é—œéµè©žã€‚å¦å¤–,一定ä¸
è¦åŒæ™‚使用éŽå¤šçš„é—œéµè©žã€‚記ä½æœç´¢æ™‚è¦åŒæ™‚嘗試包å«å’Œä¸åŒ…å«å…§æ ¸é©…動程åºçš„å稱
-或å—影響的硬體組件的å稱等信æ¯ã€‚但其確切的å“牌å稱(比如說「è¯ç¢©ç´…é­” Radeon
-RX 5700 XT Gaming OCã€ï¼‰å¾€å¾€å¹«åŠ©ä¸å¤§ï¼Œå› çˆ²å®ƒå¤ªå…·é«”了。相å,嘗試æœç´¢è¡“語,如
-型號(Radeon 5700 或 Radeon 5000)和核心代號(「Naviã€æˆ–「Navi10ã€ï¼‰ï¼Œä»¥åŠåŒ…å«
-å’Œä¸åŒ…å«å…¶è£½é€ å•†ï¼ˆã€ŒAMDã€ï¼‰ã€‚
+或å—影響的硬件組件的å稱等信æ¯ã€‚但其確切的å“牌å稱(比如說“è¯ç¢©ç´…é­” Radeon
+RX 5700 XT Gaming OCâ€ï¼‰å¾€å¾€å¹«åŠ©ä¸å¤§ï¼Œå› çˆ²å®ƒå¤ªå…·é«”了。相å,嘗試æœç´¢è¡“語,如
+型號(Radeon 5700 或 Radeon 5000)和核心代號(“Naviâ€æˆ–“Navi10â€ï¼‰ï¼Œä»¥åŠåŒ…å«
+å’Œä¸åŒ…å«å…¶è£½é€ å•†ï¼ˆâ€œAMDâ€ï¼‰ã€‚
如果你發ç¾äº†é—œæ–¼ä½ çš„å•é¡Œçš„ç¾æœ‰å ±å‘Šï¼Œè«‹åŠ å…¥è¨Žè«–,因爲你å¯èƒ½æœƒæ供有價值的é¡
外信æ¯ã€‚這一點很é‡è¦ï¼Œå³ä½¿æ˜¯åœ¨ä¿®å¾©ç¨‹åºå·²ç¶“準備好或處於最後階段,因爲開發人
-å“¡å¯èƒ½æœƒå°‹æ‰¾èƒ½å¤ æä¾›é¡å¤–ä¿¡æ¯æˆ–測試建議修復程åºçš„人。跳到「發布報告後的責任ã€
-一節,了解有關如何正確åƒèˆ‡çš„細節。
+å“¡å¯èƒ½æœƒå°‹æ‰¾èƒ½å¤ æä¾›é¡å¤–ä¿¡æ¯æˆ–測試建議修復程åºçš„人。跳到“發佈報告後的責任â€
+一節,瞭解有關如何正確åƒèˆ‡çš„細節。
注æ„,æœç´¢ `bugzilla.kernel.org <https://bugzilla.kernel.org/>`_ 網站å¯èƒ½
也是一個好主æ„,因爲這å¯èƒ½æœƒæ供有價值的見解或找到匹é…的報告。如果您發ç¾å¾Œè€…,
-請記ä½ï¼šå¤§å¤šæ•¸å­ç³»çµ±éƒ½å¸Œæœ›åœ¨ä¸åŒçš„ä½ç½®å ±å‘Šï¼Œå¦‚下é¢ã€Œä½ éœ€è¦å°‡å•é¡Œå ±å‘Šåˆ°ä½•è™•ã€
+請記ä½ï¼šå¤§å¤šæ•¸å­ç³»çµ±éƒ½å¸Œæœ›åœ¨ä¸åŒçš„ä½ç½®å ±å‘Šï¼Œå¦‚下é¢â€œä½ éœ€è¦å°‡å•é¡Œå ±å‘Šåˆ°ä½•è™•â€
一節中所述。因此本應處ç†é€™å€‹å•é¡Œçš„開發人員甚至å¯èƒ½ä¸çŸ¥é“bugzilla的工單。所以
請檢查工單中的å•é¡Œæ˜¯å¦å·²ç¶“按照本文檔所述得到報告,如果沒有,請考慮這樣åšã€‚
高優先級的å•é¡Œï¼Ÿ
-----------------
- *看看你正在處ç†çš„å•é¡Œæ˜¯å¦æ˜¯å›žæ­¸å•é¡Œã€å®‰å…¨å•é¡Œæˆ–éžå¸¸åš´é‡çš„å•é¡Œï¼šé€™äº›éƒ½æ˜¯
- 需è¦åœ¨æŽ¥ä¸‹ä¾†çš„一些步驟中特別處ç†çš„「高優先級å•é¡Œã€ã€‚*
+ *看看你正在處ç†çš„å•é¡Œæ˜¯å¦æ˜¯è¿´æ­¸å•é¡Œã€å®‰å…¨å•é¡Œæˆ–éžå¸¸åš´é‡çš„å•é¡Œï¼šé€™äº›éƒ½æ˜¯
+ 需è¦åœ¨æŽ¥ä¸‹ä¾†çš„一些步驟中特別處ç†çš„“高優先級å•é¡Œâ€ã€‚*
Linus Torvalds和主è¦çš„Linux內核開發人員希望看到一些å•é¡Œå„˜å¿«å¾—到解決,因此在
-報告éŽç¨‹ä¸­æœ‰ä¸€äº›ã€Œé«˜å„ªå…ˆç´šå•é¡Œã€çš„處ç†ç•¥æœ‰ä¸åŒã€‚有三種情æ³ç¬¦åˆæ¢ä»¶:回歸ã€å®‰å…¨
+報告éŽç¨‹ä¸­æœ‰ä¸€äº›â€œé«˜å„ªå…ˆç´šå•é¡Œâ€çš„處ç†ç•¥æœ‰ä¸åŒã€‚有三種情æ³ç¬¦åˆæ¢ä»¶:è¿´æ­¸ã€å®‰å…¨
å•é¡Œå’Œéžå¸¸åš´é‡çš„å•é¡Œã€‚
-如果在舊版本的Linux內核中工作的æ±è¥¿ä¸èƒ½åœ¨æ–°ç‰ˆæœ¬çš„Linux內核中工作,或者æŸç¨®
-程度上在新版本的Linux內核中工作得更差,那麼你就需è¦è™•ç†ã€Œå›žæ­¸ã€ã€‚因此,當一個
-在Linux 5.7中表ç¾è‰¯å¥½çš„WiFi驅動程åºåœ¨5.8中表ç¾ä¸ä½³æˆ–根本ä¸èƒ½å·¥ä½œæ™‚,這是一
-種回歸。如果應用程å¼åœ¨æ–°çš„內核中出ç¾ä¸ç©©å®šçš„ç¾è±¡ï¼Œé€™ä¹Ÿæ˜¯ä¸€ç¨®å›žæ­¸ï¼Œé€™å¯èƒ½æ˜¯
-由於內核和用戶空間之間的接å£ï¼ˆå¦‚procfså’Œsysfs)發生ä¸å…¼å®¹çš„更改造æˆçš„。顯著
-的性能é™ä½Žæˆ–功耗增加也å¯ä»¥ç¨±çˆ²å›žæ­¸ã€‚但是請記ä½:新內核需è¦ä½¿ç”¨èˆ‡èˆŠå…§æ ¸ç›¸ä¼¼çš„
-é…置來構建(åƒè¦‹ä¸‹é¢å¦‚何實ç¾é€™ä¸€é»žï¼‰ã€‚這是因爲內核開發人員在實ç¾æ–°ç‰¹æ€§æ™‚有
-時無法é¿å…ä¸å…¼å®¹æ€§ï¼›ä½†æ˜¯çˆ²äº†é¿å…回歸,這些特性必須在構建é…置期間顯å¼åœ°å•“用。
+如果æŸå€‹æ‡‰ç”¨ç¨‹åºæˆ–實際用例在原先的Linux內核上é‹è¡Œè‰¯å¥½ï¼Œä½†åœ¨ä½¿ç”¨é¡žä¼¼é…置編譯的
+較新版本上效果更差ã€æˆ–者根本ä¸èƒ½ç”¨ï¼Œé‚£éº¼ä½ å°±éœ€è¦è™•ç†è¿´æ­¸å•é¡Œã€‚
+Documentation/admin-guide/reporting-regressions.rst å°æ­¤é€²è¡Œäº†æ›´è©³ç´°çš„解釋。
+它還æ供了很多你å¯èƒ½æƒ³çŸ¥é“的關於迴歸的其他信æ¯ï¼›ä¾‹å¦‚,它解釋瞭如何將您的å•é¡Œ
+添加到迴歸跟蹤列表中,以確ä¿å®ƒä¸æœƒè¢«å¿½ç•¥ã€‚
什麼是安全å•é¡Œç•™çµ¦æ‚¨è‡ªå·±åˆ¤æ–·ã€‚在繼續之å‰ï¼Œè«‹è€ƒæ…®é–±è®€
-「Documentation/translations/zh_TW/admin-guide/security-bugs.rstã€ï¼Œ
-因爲它æ供了如何最æ°ç•¶åœ°è™•ç†å®‰å…¨å•é¡Œçš„é¡å¤–細節。
+Documentation/translations/zh_CN/admin-guide/security-bugs.rst ,
+因爲它æ供瞭如何最æ°ç•¶åœ°è™•ç†å®‰å…¨å•é¡Œçš„é¡å¤–細節。
-當發生了完全無法接å—的糟糕事情時,此å•é¡Œå°±æ˜¯ä¸€å€‹ã€Œéžå¸¸åš´é‡çš„å•é¡Œã€ã€‚例如,
-Linux內核破壞了它處ç†çš„數據或æ壞了它é‹è¡Œçš„硬體。當內核çªç„¶é¡¯ç¤ºéŒ¯èª¤æ¶ˆæ¯
-(「kernel panicã€ï¼‰ä¸¦åœæ­¢å·¥ä½œï¼Œæˆ–者根本沒有任何åœæ­¢ä¿¡æ¯æ™‚,您也在處ç†ä¸€å€‹åš´é‡
-çš„å•é¡Œã€‚注æ„:ä¸è¦æ··æ·†ã€Œpanicã€ï¼ˆå…§æ ¸åœæ­¢è‡ªèº«çš„致命錯誤)和「Oopsã€ï¼ˆå¯æ¢å¾©éŒ¯èª¤ï¼‰ï¼Œ
+當發生了完全無法接å—的糟糕事情時,此å•é¡Œå°±æ˜¯ä¸€å€‹â€œéžå¸¸åš´é‡çš„å•é¡Œâ€ã€‚例如,
+Linux內核破壞了它處ç†çš„數據或æ壞了它é‹è¡Œçš„硬件。當內核çªç„¶é¡¯ç¤ºéŒ¯èª¤æ¶ˆæ¯
+(“kernel panicâ€ï¼‰ä¸¦åœæ­¢å·¥ä½œï¼Œæˆ–者根本沒有任何åœæ­¢ä¿¡æ¯æ™‚,您也在處ç†ä¸€å€‹åš´é‡
+çš„å•é¡Œã€‚注æ„:ä¸è¦æ··æ·†â€œpanicâ€ï¼ˆå…§æ ¸åœæ­¢è‡ªèº«çš„致命錯誤)和“Oopsâ€ï¼ˆå¯æ¢å¾©éŒ¯èª¤ï¼‰ï¼Œ
因爲顯示後者之後內核ä»ç„¶åœ¨é‹è¡Œã€‚
@@ -325,22 +319,22 @@ Linux內核破壞了它處ç†çš„數據或æ壞了它é‹è¡Œçš„硬體。當內核
看起來很åƒå…§æ ¸å•é¡Œçš„å•é¡Œæœ‰æ™‚是由構建或é‹è¡Œæ™‚環境引起的。很難完全排除這種å•
題,但你應該儘é‡æ¸›å°‘這種å•é¡Œï¼š
- * 構建內核時,請使用經éŽé©—證的工具,因爲編譯器或二進ä½æ–‡ä»¶ä¸­çš„錯誤å¯èƒ½æœƒå°Ž
+ * 構建內核時,請使用經éŽé©—證的工具,因爲編譯器或二進制文件中的錯誤å¯èƒ½æœƒå°Ž
致內核出ç¾éŒ¯èª¤è¡Œçˆ²ã€‚
* 確ä¿æ‚¨çš„計算機組件在其設計è¦ç¯„å…§é‹è¡Œï¼›é€™å°è™•ç†å™¨ã€å…§å­˜å’Œä¸»æ¿å°¤çˆ²é‡è¦ã€‚å› 
此,當é¢è‡¨æ½›åœ¨çš„內核å•é¡Œæ™‚,åœæ­¢ä½Žé›»å£“或超頻。
- * 儘é‡ç¢ºä¿ä¸æ˜¯ç¡¬é«”故障導致了你的å•é¡Œã€‚例如,內存æ壞會導致大é‡çš„å•é¡Œï¼Œé€™äº›
+ * 儘é‡ç¢ºä¿ä¸æ˜¯ç¡¬ä»¶æ•…障導致了你的å•é¡Œã€‚例如,內存æ壞會導致大é‡çš„å•é¡Œï¼Œé€™äº›
å•é¡Œæœƒè¡¨ç¾çˆ²çœ‹èµ·ä¾†åƒå…§æ ¸å•é¡Œã€‚
* 如果你正在處ç†ä¸€å€‹æ–‡ä»¶ç³»çµ±å•é¡Œï¼Œä½ å¯èƒ½éœ€è¦ç”¨ ``fsck`` 檢查一下文件系統,
因爲它å¯èƒ½æœƒä»¥æŸç¨®æ–¹å¼è¢«æ壞,從而導致無法é æœŸçš„內核行爲。
- * 在處ç†å›žæ­¸å•é¡Œæ™‚,è¦ç¢ºä¿æ²’有在更新內核的åŒæ™‚發生了其他變化。例如,這個å•
- é¡Œå¯èƒ½æ˜¯ç”±åŒæ™‚更新的其他軟體引起的。也有å¯èƒ½æ˜¯åœ¨ä½ ç¬¬ä¸€æ¬¡é‡å•“進入新內核時,
- æŸå€‹ç¡¬é«”å·§åˆåœ°å£žäº†ã€‚更新系統 BIOS 或改變 BIOS 設置中的æŸäº›å…§å®¹ä¹Ÿæœƒå°Žè‡´
- 一些看起來很åƒå…§æ ¸å›žæ­¸çš„å•é¡Œã€‚
+ * 在處ç†è¿´æ­¸å•é¡Œæ™‚,è¦ç¢ºä¿æ²’有在更新內核的åŒæ™‚發生了其他變化。例如,這個å•
+ é¡Œå¯èƒ½æ˜¯ç”±åŒæ™‚更新的其他軟件引起的。也有å¯èƒ½æ˜¯åœ¨ä½ ç¬¬ä¸€æ¬¡é‡å•“進入新內核時,
+ æŸå€‹ç¡¬ä»¶å·§åˆåœ°å£žäº†ã€‚更新系統 BIOS 或改變 BIOS 設置中的æŸäº›å…§å®¹ä¹Ÿæœƒå°Žè‡´
+ 一些看起來很åƒå…§æ ¸è¿´æ­¸çš„å•é¡Œã€‚
爲緊急情æ³åšå¥½æº–å‚™
@@ -349,8 +343,8 @@ Linux內核破壞了它處ç†çš„數據或æ壞了它é‹è¡Œçš„硬體。當內核
*創建一個全新的備份,並將系統修復和還原工具放在手邊*
我得æ醒您,您正在和計算機打交é“,計算機有時會出ç¾æ„想ä¸åˆ°çš„事情,尤其是當
-您折騰其作業系統的內核等關éµéƒ¨ä»¶æ™‚。而這就是你在這個éŽç¨‹ä¸­è¦åšçš„事情。因此,
-一定è¦å‰µå»ºä¸€å€‹å…¨æ–°çš„備份;還è¦ç¢ºä¿ä½ æ‰‹é ­æœ‰ä¿®å¾©æˆ–é‡è£ä½œæ¥­ç³»çµ±çš„所有工具,
+您折騰其æ“作系統的內核等關éµéƒ¨ä»¶æ™‚。而這就是你在這個éŽç¨‹ä¸­è¦åšçš„事情。因此,
+一定è¦å‰µå»ºä¸€å€‹å…¨æ–°çš„備份;還è¦ç¢ºä¿ä½ æ‰‹é ­æœ‰ä¿®å¾©æˆ–é‡è£æ“作系統的所有工具,
以åŠæ¢å¾©å‚™ä»½æ‰€éœ€çš„一切。
@@ -366,67 +360,67 @@ Linux內核破壞了它處ç†çš„數據或æ壞了它é‹è¡Œçš„硬體。當內核
的任何模塊。然後é‡æ–°å•“å‹•å†ç¹¼çºŒã€‚
注æ„,你å¯èƒ½ä¸çŸ¥é“ä½ çš„ç³»çµ±æ­£åœ¨ä½¿ç”¨é€™äº›è§£æ±ºæ–¹æ¡ˆä¹‹ä¸€ï¼šç•¶ä½ å®‰è£ Nvidia 專有圖
-形驅動程åºã€VirtualBox æˆ–å…¶ä»–éœ€è¦ Linux 內核以外的模塊支æŒçš„軟體時,它們通
-常會éœé»˜è¨­ç½®ã€‚這就是爲什麼你å¯èƒ½éœ€è¦å¸è¼‰é€™äº›è»Ÿé«”的軟體包,以擺脫任何第三方
+形驅動程åºã€VirtualBox æˆ–å…¶ä»–éœ€è¦ Linux 內核以外的模塊支æŒçš„軟件時,它們通
+常會éœé»˜è¨­ç½®ã€‚這就是爲什麼你å¯èƒ½éœ€è¦å¸è¼‰é€™äº›è»Ÿä»¶çš„軟件包,以擺脫任何第三方
內核模塊。
-檢測「汙染ã€æ¨™èªŒ
+檢查“污染â€æ¨™èªŒ
----------------
- *當å•é¡Œç™¼ç”Ÿæ™‚,檢查您的內核是å¦è¢«ã€Œæ±™æŸ“ã€ï¼Œå› çˆ²ä½¿å…§æ ¸è¨­ç½®é€™å€‹æ¨™èªŒçš„事件å¯
+ *當å•é¡Œç™¼ç”Ÿæ™‚,檢查您的內核是å¦è¢«â€œæ±¡æŸ“â€ï¼Œå› çˆ²ä½¿å…§æ ¸è¨­ç½®é€™å€‹æ¨™èªŒçš„事件å¯
能會導致您é¢è‡¨çš„å•é¡Œã€‚*
-當æŸäº›å¯èƒ½æœƒå°Žè‡´çœ‹èµ·ä¾†å®Œå…¨ä¸ç›¸é—œçš„後續錯誤的事情發生時,內核會用「汙染
-(taint)ã€æ¨™èªŒæ¨™è¨˜è‡ªå·±ã€‚如果您的內核å—到汙染,那麼您é¢è‡¨çš„å¯èƒ½æ˜¯é€™æ¨£çš„錯誤。
+當æŸäº›å¯èƒ½æœƒå°Žè‡´çœ‹èµ·ä¾†å®Œå…¨ä¸ç›¸é—œçš„後續錯誤的事情發生時,內核會用“污染
+(taint)â€æ¨™èªŒæ¨™è¨˜è‡ªå·±ã€‚如果您的內核å—到污染,那麼您é¢è‡¨çš„å¯èƒ½æ˜¯é€™æ¨£çš„錯誤。
因此在投入更多時間到這個éŽç¨‹ä¸­ä¹‹å‰ï¼Œå„˜æ—©æŽ’除此情æ³å¯èƒ½å°ä½ æœ‰å¥½è™•ã€‚這是這個
-步驟出ç¾åœ¨é€™è£¡çš„唯一原因,因爲這個éŽç¨‹ç¨å¾Œæœƒå‘Šè¨´æ‚¨å®‰è£æœ€æ–°çš„主線內核;然後
-您將需è¦å†æ¬¡æª¢æŸ¥æ±™æŸ“標誌,因爲當它出å•é¡Œçš„時候內核報告會關注它。
+步驟出ç¾åœ¨é€™è£çš„唯一原因,因爲這個éŽç¨‹ç¨å¾Œæœƒå‘Šè¨´æ‚¨å®‰è£æœ€æ–°çš„主線內核;然後
+您將需è¦å†æ¬¡æª¢æŸ¥æ±¡æŸ“標誌,因爲當它出å•é¡Œçš„時候內核報告會關注它。
-在正在é‹è¡Œçš„系統上檢查內核是å¦æ±™æŸ“éžå¸¸å®¹æ˜“:如果 ``cat /proc/sys/kernel/tainted``
-返回「0ã€ï¼Œé‚£éº¼å…§æ ¸æ²’有被汙染,一切正常。在æŸäº›æƒ…æ³ä¸‹ç„¡æ³•æª¢æŸ¥è©²æ–‡ä»¶ï¼›é€™å°±æ˜¯
-爲什麼當內核報告內部å•é¡Œï¼ˆã€Œkernel bugã€ï¼‰ã€å¯æ¢å¾©éŒ¯èª¤ï¼ˆã€Œkernel Oopsã€ï¼‰æˆ–åœæ­¢
-æ“作å‰ä¸å¯æ¢å¾©çš„錯誤(「kernel panicã€ï¼‰æ™‚,它也會æ到汙染狀態。當其中一個錯
-誤發生時,查看列å°çš„錯誤消æ¯çš„頂部,æœç´¢ä»¥ã€ŒCPU:ã€é–‹é ­çš„行。如果發ç¾å•é¡Œæ™‚å…§
-核未被汙染,那麼它應該以「Not infectedã€çµæŸï¼›å¦‚果你看到「Tainted:ã€ä¸”後跟一些
-空格和字æ¯ï¼Œé‚£å°±è¢«æ±™æŸ“了。
+在正在é‹è¡Œçš„系統上檢查內核是å¦æ±¡æŸ“éžå¸¸å®¹æ˜“:如果 ``cat /proc/sys/kernel/tainted``
+返回“0â€ï¼Œé‚£éº¼å…§æ ¸æ²’有被污染,一切正常。在æŸäº›æƒ…æ³ä¸‹ç„¡æ³•æª¢æŸ¥è©²æ–‡ä»¶ï¼›é€™å°±æ˜¯
+爲什麼當內核報告內部å•é¡Œï¼ˆâ€œkernel bugâ€ï¼‰ã€å¯æ¢å¾©éŒ¯èª¤ï¼ˆâ€œkernel Oopsâ€ï¼‰æˆ–åœæ­¢
+æ“作å‰ä¸å¯æ¢å¾©çš„錯誤(“kernel panicâ€ï¼‰æ™‚,它也會æ到污染狀態。當其中一個錯
+誤發生時,查看打å°çš„錯誤消æ¯çš„頂部,æœç´¢ä»¥â€œCPU:â€é–‹é ­çš„行。如果發ç¾å•é¡Œæ™‚å…§
+核未被污染,那麼它應該以“Not infectedâ€çµæŸï¼›å¦‚果你看到“Tainted:â€ä¸”後跟一些
+空格和字æ¯ï¼Œé‚£å°±è¢«æ±¡æŸ“了。
-如果你的內核被汙染了,請閱讀「Documentation/translations/zh_TW/admin-guide/tainted-kernels.rstã€
-以找出原因。設法消除汙染因素。通常是由以下三種因素之一引起的:
+如果你的內核被污染了,請閱讀 Documentation/translations/zh_CN/admin-guide/tainted-kernels.rst
+以找出原因。設法消除污染因素。通常是由以下三種因素之一引起的:
- 1. 發生了一個å¯æ¢å¾©çš„錯誤(「kernel Oopsã€ï¼‰ï¼Œå…§æ ¸æ±™æŸ“了自己,因爲內核知é“在
+ 1. 發生了一個å¯æ¢å¾©çš„錯誤(“kernel Oopsâ€ï¼‰ï¼Œå…§æ ¸æ±¡æŸ“了自己,因爲內核知é“在
此之後它å¯èƒ½æœƒå‡ºç¾å¥‡æ€ªçš„行爲錯亂。在這種情æ³ä¸‹ï¼Œæª¢æŸ¥æ‚¨çš„內核或系統日誌,
並尋找以下列文字開頭的部分::
Oops: 0000 [#1] SMP
- 如方括號中的「#1ã€æ‰€ç¤ºï¼Œé€™æ˜¯è‡ªå•“動以來的第一次Oops。æ¯å€‹Oops和此後發生的
+ 如方括號中的“#1â€æ‰€ç¤ºï¼Œé€™æ˜¯è‡ªå•“動以來的第一次Oops。æ¯å€‹Oops和此後發生的
任何其他å•é¡Œéƒ½å¯èƒ½æ˜¯é¦–個Oops的後續å•é¡Œï¼Œå³ä½¿é€™å…©å€‹å•é¡Œçœ‹èµ·ä¾†å®Œå…¨ä¸ç›¸é—œã€‚
通éŽæ¶ˆé™¤é¦–個Oops的原因並在之後復ç¾è©²å•é¡Œï¼Œå¯ä»¥æŽ’除這種情æ³ã€‚有時僅僅
é‡æ–°å•“動就足夠了,有時更改é…置後é‡æ–°å•“å‹•å¯ä»¥æ¶ˆé™¤Oops。但是在這個æµç¨‹ä¸­
ä¸è¦èŠ±è²»å¤ªå¤šæ™‚間在這一點上,因爲引起Oops的原因å¯èƒ½å·²ç¶“在您ç¨å¾Œå°‡æŒ‰æµç¨‹
安è£çš„æ–°Linux內核版本中修復了。
- 2. 您的系統使用的軟體安è£äº†è‡ªå·±çš„內核模塊,例如Nvidia的專有圖形驅動程åºæˆ–
- VirtualBox。當內核從外部æºï¼ˆå³ä½¿å®ƒå€‘是開æºçš„)加載此類模塊時,它會汙染
+ 2. 您的系統使用的軟件安è£äº†è‡ªå·±çš„內核模塊,例如Nvidia的專有圖形驅動程åºæˆ–
+ VirtualBox。當內核從外部æºï¼ˆå³ä½¿å®ƒå€‘是開æºçš„)加載此類模塊時,它會污染
自己:它們有時會在ä¸ç›¸é—œçš„內核å€åŸŸå°Žè‡´éŒ¯èª¤ï¼Œå¾žè€Œå¯èƒ½å°Žè‡´æ‚¨é¢è‡¨çš„å•é¡Œã€‚
因此,當您想è¦å‘Linux內核開發人員報告å•é¡Œæ™‚,您必須阻止這些模塊加載。
- 大多數情æ³ä¸‹æœ€ç°¡å–®çš„方法是:臨時å¸è¼‰é€™äº›è»Ÿé«”,包括它們å¯èƒ½å·²ç¶“安è£çš„ä»»
+ 大多數情æ³ä¸‹æœ€ç°¡å–®çš„方法是:臨時å¸è¼‰é€™äº›è»Ÿä»¶ï¼ŒåŒ…括它們å¯èƒ½å·²ç¶“安è£çš„ä»»
何模塊。之後é‡æ–°å•“動。
- 3. 當內核加載é§ç•™åœ¨Linux內核原始碼staging樹中的模塊時,它也會汙染自身。這
+ 3. 當內核加載é§ç•™åœ¨Linux內核æºä»£ç¢¼staging樹中的模塊時,它也會污染自身。這
是一個特殊的å€åŸŸï¼Œä»£ç¢¼ï¼ˆä¸»è¦æ˜¯é©…動程åºï¼‰é‚„沒有é”到正常Linux內核的質é‡
- 標準。當您報告此種模塊的å•é¡Œæ™‚,內核å—到汙染顯然是沒有å•é¡Œçš„ï¼›åªéœ€ç¢ºä¿
- å•é¡Œæ¨¡å¡Šæ˜¯é€ æˆæ±™æŸ“的唯一原因。如果å•é¡Œç™¼ç”Ÿåœ¨ä¸€å€‹ä¸ç›¸é—œçš„å€åŸŸï¼Œé‡æ–°å•“å‹•
+ 標準。當您報告此種模塊的å•é¡Œæ™‚,內核å—到污染顯然是沒有å•é¡Œçš„ï¼›åªéœ€ç¢ºä¿
+ å•é¡Œæ¨¡å¡Šæ˜¯é€ æˆæ±¡æŸ“的唯一原因。如果å•é¡Œç™¼ç”Ÿåœ¨ä¸€å€‹ä¸ç›¸é—œçš„å€åŸŸï¼Œé‡æ–°å•“å‹•
並通éŽæŒ‡å®š ``foo.blacklist=1`` 作爲內核åƒæ•¸è‡¨æ™‚阻止該模塊被加載(用有
- å•é¡Œçš„模塊å替æ›ã€Œfooã€ï¼‰ã€‚
+ å•é¡Œçš„模塊å替æ›â€œfooâ€ï¼‰ã€‚
記錄如何é‡ç¾å•é¡Œ
------------------
*粗略地寫下如何é‡ç¾é€™å€‹å•é¡Œã€‚如果您åŒæ™‚處ç†å¤šå€‹å•é¡Œï¼Œè«‹çˆ²æ¯å€‹å•é¡Œå–®ç¨å¯«
- 注釋,並確ä¿å®ƒå€‘在新啓動的系統上ç¨ç«‹å‡ºç¾ã€‚這是必è¦çš„,因爲æ¯å€‹å•é¡Œéƒ½éœ€
+ 註釋,並確ä¿å®ƒå€‘在新啓動的系統上ç¨ç«‹å‡ºç¾ã€‚這是必è¦çš„,因爲æ¯å€‹å•é¡Œéƒ½éœ€
è¦åˆ†åˆ¥å ±å‘Šçµ¦å…§æ ¸é–‹ç™¼äººå“¡ï¼Œé™¤éžå®ƒå€‘åš´é‡ç³¾çºåœ¨ä¸€èµ·ã€‚*
如果你åŒæ™‚處ç†å¤šå€‹å•é¡Œï¼Œå¿…須分別報告æ¯å€‹å•é¡Œï¼Œå› çˆ²å®ƒå€‘å¯èƒ½ç”±ä¸åŒçš„開發人員
@@ -438,20 +432,20 @@ Linux內核破壞了它處ç†çš„數據或æ壞了它é‹è¡Œçš„硬體。當內核
注æ„:報告åªç™¼ç”ŸéŽä¸€æ¬¡çš„å•é¡Œå¾€å¾€æ˜¯æ²’有çµæžœçš„,因爲它們å¯èƒ½æ˜¯ç”±æ–¼å®‡å®™è¼»å°„å°Ž
致的ä½ç¿»è½‰ã€‚所以你應該嘗試通éŽé‡ç¾å•é¡Œä¾†æŽ’除這種情æ³ï¼Œç„¶å¾Œå†ç¹¼çºŒã€‚如果你有
-足夠的經驗來å€åˆ†ç”±æ–¼ç¡¬é«”故障引起的一次性錯誤和難以é‡ç¾çš„罕見內核å•é¡Œï¼Œå¯ä»¥
+足夠的經驗來å€åˆ†ç”±æ–¼ç¡¬ä»¶æ•…障引起的一次性錯誤和難以é‡ç¾çš„罕見內核å•é¡Œï¼Œå¯ä»¥
忽略這個建議。
-穩定版或長期支æŒå…§æ ¸çš„回歸?
+穩定版或長期支æŒå…§æ ¸çš„迴歸?
-----------------------------
- *如果您正é¢è‡¨ç©©å®šç‰ˆæˆ–長期支æŒç‰ˆæœ¬ç·šçš„回歸(例如從5.10.4更新到5.10.5時出ç¾
- 故障),請查看後文「報告穩定版和長期支æŒå…§æ ¸ç·šçš„回歸ã€å°ç¯€ã€‚*
+ *如果您正é¢è‡¨ç©©å®šç‰ˆæˆ–長期支æŒç‰ˆæœ¬ç·šçš„迴歸(例如從5.10.4更新到5.10.5時出ç¾
+ 故障),請查看後文“報告穩定版和長期支æŒå…§æ ¸ç·šçš„è¿´æ­¸â€å°ç¯€ã€‚*
-穩定版和長期支æŒå…§æ ¸ç‰ˆæœ¬ç·šä¸­çš„回歸是Linux開發人員éžå¸¸å¸Œæœ›è§£æ±ºçš„å•é¡Œï¼Œé€™æ¨£çš„
-å•é¡Œç”šè‡³æ¯”主線開發分支中的回歸更ä¸æ‡‰å‡ºç¾ï¼Œå› çˆ²å®ƒå€‘會很快影響到很多人。開發人員
-希望儘快了解此類å•é¡Œï¼Œå› æ­¤æœ‰ä¸€å€‹ç°¡åŒ–æµç¨‹ä¾†å ±å‘Šé€™äº›å•é¡Œã€‚注æ„,使用更新內核版
-本線的回歸(比如從5.9.15切æ›åˆ°5.10.5時出ç¾æ•…障)ä¸ç¬¦åˆæ¢ä»¶ã€‚
+穩定版和長期支æŒå…§æ ¸ç‰ˆæœ¬ç·šä¸­çš„迴歸是Linux開發人員éžå¸¸å¸Œæœ›è§£æ±ºçš„å•é¡Œï¼Œé€™æ¨£çš„
+å•é¡Œç”šè‡³æ¯”主線開發分支中的迴歸更ä¸æ‡‰å‡ºç¾ï¼Œå› çˆ²å®ƒå€‘會很快影響到很多人。開發人員
+希望儘快瞭解此類å•é¡Œï¼Œå› æ­¤æœ‰ä¸€å€‹ç°¡åŒ–æµç¨‹ä¾†å ±å‘Šé€™äº›å•é¡Œã€‚注æ„,使用更新內核版
+本線的迴歸(比如從5.9.15切æ›åˆ°5.10.5時出ç¾æ•…障)ä¸ç¬¦åˆæ¢ä»¶ã€‚
你需è¦å°‡å•é¡Œå ±å‘Šåˆ°ä½•è™•
@@ -462,9 +456,9 @@ Linux內核破壞了它處ç†çš„數據或æ壞了它é‹è¡Œçš„硬體。當內核
éŽéƒµä»¶ç™¼é€çµ¦ç¶­è­·äººå“¡å’Œå…¬å…±éƒµä»¶åˆ—表。*
將報告發é€çµ¦åˆé©çš„人是至關é‡è¦çš„,因爲Linux內核是一個大項目,大多數開發人員
-åªç†Ÿæ‚‰å…¶ä¸­çš„一å°éƒ¨åˆ†ã€‚例如,相當多的程å¼è¨­è¨ˆå¸«åªé—œå¿ƒä¸€å€‹é©…動程åºï¼Œæ¯”如一個WiFi
-晶片驅動程åºï¼›å®ƒçš„開發人員å¯èƒ½å°ç–é çš„或ä¸ç›¸é—œçš„「å­ç³»çµ±ã€ï¼ˆå¦‚TCP堆棧ã€
-PCIe/PCIå­ç³»çµ±ã€å…§å­˜ç®¡ç†æˆ–文件系統)的內部知識了解很少或完全ä¸äº†è§£ã€‚
+åªç†Ÿæ‚‰å…¶ä¸­çš„一å°éƒ¨åˆ†ã€‚例如,相當多的程åºå“¡åªé—œå¿ƒä¸€å€‹é©…動程åºï¼Œæ¯”如一個WiFi
+芯片驅動程åºï¼›å®ƒçš„開發人員å¯èƒ½å°ç–é çš„或ä¸ç›¸é—œçš„“å­ç³»çµ±â€ï¼ˆå¦‚TCP堆棧ã€
+PCIe/PCIå­ç³»çµ±ã€å…§å­˜ç®¡ç†æˆ–文件系統)的內部知識瞭解很少或完全ä¸çž­è§£ã€‚
å•é¡Œåœ¨æ–¼ï¼šLinux內核缺少一個,å¯ä»¥ç°¡å–®åœ°å°‡å•é¡Œæ­¸æª”並讓需è¦äº†è§£å®ƒçš„開發人員了
解它的,中心化缺陷跟蹤器。這就是爲什麼你必須找到正確的途徑來自己報告å•é¡Œã€‚
@@ -476,10 +470,10 @@ PCIe/PCIå­ç³»çµ±ã€å…§å­˜ç®¡ç†æˆ–文件系統)的內部知識了解很少或
爲了說明如何使用 :ref:`MAINTAINERS <maintainers>` 文件,讓我們å‡è¨­æ‚¨çš„筆記
本電腦中的WiFi在更新內核後çªç„¶å‡ºç¾äº†éŒ¯èª¤è¡Œçˆ²ã€‚這種情æ³ä¸‹å¯èƒ½æ˜¯WiFié©…å‹•çš„å•
-題。顯然,它也å¯èƒ½ç”±æ–¼é©…動基於的æŸäº›ä»£ç¢¼ï¼Œä½†é™¤éžä½ æ‡·ç–‘有這樣的æ±è¥¿æœƒé™„著在
-驅動程åºä¸Šã€‚如果真的是其他的å•é¡Œï¼Œé©…動程åºçš„開發人員會讓åˆé©çš„人åƒèˆ‡é€²ä¾†ã€‚
+題。顯然,它也å¯èƒ½ç”±æ–¼é©…動基於的æŸäº›ä»£ç¢¼ï¼Œä½†é™¤éžä½ æ‡·ç–‘有這樣的æ±è¥¿æœƒé™„ç€åœ¨
+驅動程åºä¸Šã€‚如果真的是其他的å•é¡Œï¼Œé©…動程åºçš„開發人員會讓åˆé©çš„人蔘與進來。
-éºæ†¾çš„是,沒有通用且簡單的辦法來檢查哪個代碼驅動了特定硬體組件。
+éºæ†¾çš„是,沒有通用且簡單的辦法來檢查哪個代碼驅動了特定硬件組件。
在WiFi驅動出ç¾å•é¡Œçš„情æ³ä¸‹ï¼Œä½ å¯èƒ½æƒ³æŸ¥çœ‹ ``lspci -k`` 的輸出,因爲它列出了
PCI/PCIe總線上的設備和驅動它的內核模塊::
@@ -492,19 +486,19 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
Kernel modules: ath10k_pci
[...]
-但如果你的WiFi晶片通éŽUSB或其他內部總線連接,這種方法就行ä¸é€šäº†ã€‚在這種情æ³
+但如果你的WiFi芯片通éŽUSB或其他內部總線連接,這種方法就行ä¸é€šäº†ã€‚在這種情æ³
下,您å¯èƒ½éœ€è¦æª¢æŸ¥æ‚¨çš„WiFi管ç†å™¨æˆ– ``ip link`` 的輸出。尋找有å•é¡Œçš„網絡接å£
-çš„å稱,它å¯èƒ½é¡žä¼¼æ–¼ã€Œwlp58s0ã€ã€‚æ­¤å稱å¯ä»¥ç”¨ä¾†æ‰¾åˆ°é©…動它的模塊::
+çš„å稱,它å¯èƒ½é¡žä¼¼æ–¼â€œwlp58s0â€ã€‚æ­¤å稱å¯ä»¥ç”¨ä¾†æ‰¾åˆ°é©…動它的模塊::
[user@something ~]$ realpath --relative-to=/sys/module//sys/class/net/wlp58s0/device/driver/module
ath10k_pci
如果這些技巧ä¸èƒ½é€²ä¸€æ­¥å¹«åŠ©æ‚¨ï¼Œè«‹å˜—試在網上æœç´¢å¦‚何縮å°ç›¸é—œé©…動程åºæˆ–å­ç³»çµ±
-的範åœã€‚如果你ä¸ç¢ºå®šæ˜¯å“ªä¸€å€‹ï¼šè©¦è‘—猜一下,å³ä½¿ä½ çŒœå¾—ä¸å¥½ï¼Œä¹Ÿæœƒæœ‰äººæœƒå¹«åŠ©ä½ 
+的範åœã€‚如果你ä¸ç¢ºå®šæ˜¯å“ªä¸€å€‹ï¼šè©¦ç€çŒœä¸€ä¸‹ï¼Œå³ä½¿ä½ çŒœå¾—ä¸å¥½ï¼Œä¹Ÿæœƒæœ‰äººæœƒå¹«åŠ©ä½ 
的。
一旦您知é“了相應的驅動程åºæˆ–å­ç³»çµ±ï¼Œæ‚¨å°±å¸Œæœ›åœ¨MAINTAINERS文件中æœç´¢å®ƒã€‚如果
-是「ath10k_pciã€ï¼Œæ‚¨ä¸æœƒæ‰¾åˆ°ä»»ä½•æ±è¥¿ï¼Œå› çˆ²å稱太具體了。有時你需è¦åœ¨ç¶²ä¸Šå°‹æ‰¾
+是“ath10k_pciâ€ï¼Œæ‚¨ä¸æœƒæ‰¾åˆ°ä»»ä½•æ±è¥¿ï¼Œå› çˆ²å稱太具體了。有時你需è¦åœ¨ç¶²ä¸Šå°‹æ‰¾
幫助;但在此之å‰ï¼Œè«‹å˜—試使用一個ç¨çŸ­æˆ–修改éŽçš„å稱來æœç´¢MAINTAINERS文件,因
爲這樣你å¯èƒ½æœƒç™¼ç¾é¡žä¼¼é€™æ¨£çš„æ±è¥¿::
@@ -516,23 +510,23 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
SCM: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
Files: drivers/net/wireless/ath/ath10k/
-注æ„:如果您閱讀在Linux原始碼樹的根目錄中找到的原始維護者文件,則行æ述將是
-縮寫。例如,「Mail:(郵件)ã€å°‡æ˜¯ã€ŒM:ã€ï¼Œã€ŒMailing list:(郵件列表)ã€å°‡æ˜¯ã€ŒLã€ï¼Œ
-「Status:(狀態)ã€å°‡æ˜¯ã€ŒS:ã€ã€‚此文件頂部有一段解釋了這些和其他縮寫。
+注æ„:如果您閱讀在Linuxæºä»£ç¢¼æ¨¹çš„根目錄中找到的原始維護者文件,則行æ述將是
+縮寫。例如,“Mail:(郵件)â€å°‡æ˜¯â€œM:â€ï¼Œâ€œMailing list:(郵件列表)â€å°‡æ˜¯â€œLâ€ï¼Œ
+“Status:(狀態)â€å°‡æ˜¯â€œS:â€ã€‚此文件頂部有一段解釋了這些和其他縮寫。
-首先查看「Statusã€ç‹€æ…‹è¡Œã€‚ç†æƒ³æƒ…æ³ä¸‹ï¼Œå®ƒæ‡‰è©²å¾—到「Supported(支æŒï¼‰ã€æˆ–
-「Maintained(維護)ã€ã€‚如果狀態爲「Obsolete(éŽæ™‚的)ã€ï¼Œé‚£éº¼ä½ åœ¨ä½¿ç”¨ä¸€äº›éŽæ™‚çš„
-方法,需è¦è½‰æ›åˆ°æ–°çš„解決方案上。有時候,åªæœ‰åœ¨æ„Ÿåˆ°æœ‰å‹•åŠ›æ™‚,æ‰æœƒæœ‰äººçˆ²ä»£ç¢¼
-æ供「Odd Fixesã€ã€‚如果碰見「Orphanã€ï¼Œä½ å°±å®Œå…¨ä¸èµ°é‹äº†ï¼Œå› çˆ²å†ä¹Ÿæ²’有人關心代碼
-了,åªå‰©ä¸‹é€™äº›é¸é …:準備好與å•é¡Œå…±å­˜ï¼Œè‡ªå·±ä¿®å¾©å®ƒï¼Œæˆ–者找一個願æ„修復它的程å¼è¨­è¨ˆå¸«ã€‚
+首先查看“Statusâ€ç‹€æ…‹è¡Œã€‚ç†æƒ³æƒ…æ³ä¸‹ï¼Œå®ƒæ‡‰è©²å¾—到“Supported(支æŒï¼‰â€æˆ–
+“Maintained(維護)â€ã€‚如果狀態爲“Obsolete(éŽæ™‚的)â€ï¼Œé‚£éº¼ä½ åœ¨ä½¿ç”¨ä¸€äº›éŽæ™‚çš„
+方法,需è¦è½‰æ›åˆ°æ–°çš„解決方案上。有時候,åªæœ‰åœ¨æ„Ÿåˆ°æœ‰å‹•åŠ›æ™‚,纔會有人爲代碼
+æ供“Odd Fixesâ€ã€‚如果碰見“Orphanâ€ï¼Œä½ å°±å®Œå…¨ä¸èµ°é‹äº†ï¼Œå› çˆ²å†ä¹Ÿæ²’有人關心代碼
+了,åªå‰©ä¸‹é€™äº›é¸é …:準備好與å•é¡Œå…±å­˜ï¼Œè‡ªå·±ä¿®å¾©å®ƒï¼Œæˆ–者找一個願æ„修復它的程åºå“¡ã€‚
-檢查狀態後,尋找以「bug:ã€é–‹é ­çš„一行:它將告訴你在哪裡å¯ä»¥æ‰¾åˆ°å­ç³»çµ±ç‰¹å®šçš„缺
+檢查狀態後,尋找以“bug:â€é–‹é ­çš„一行:它將告訴你在哪è£å¯ä»¥æ‰¾åˆ°å­ç³»çµ±ç‰¹å®šçš„缺
陷跟蹤器來æ交你的å•é¡Œã€‚上é¢çš„例å­æ²’有此行。大多數部分都是這樣,因爲 Linux
內核的開發完全是由郵件驅動的。很少有å­ç³»çµ±ä½¿ç”¨ç¼ºé™·è·Ÿè¹¤å™¨ï¼Œä¸”其中åªæœ‰ä¸€éƒ¨åˆ†
ä¾è³´æ–¼ bugzilla.kernel.org。
-在這種以åŠå…¶ä»–很多情æ³ä¸‹ï¼Œä½ å¿…須尋找以「Mail:ã€é–‹é ­çš„行。這些行æ到了特定代碼
-的維護者的å字和電å­éƒµä»¶åœ°å€ã€‚也å¯ä»¥æŸ¥æ‰¾ä»¥ã€ŒMailing list:ã€é–‹é ­çš„行,它告訴你
+在這種以åŠå…¶ä»–很多情æ³ä¸‹ï¼Œä½ å¿…須尋找以“Mail:â€é–‹é ­çš„行。這些行æ到了特定代碼
+的維護者的å字和電å­éƒµä»¶åœ°å€ã€‚也å¯ä»¥æŸ¥æ‰¾ä»¥â€œMailing list:â€é–‹é ­çš„行,它告訴你
開發代碼的公共郵件列表。你的報告之後需è¦é€šéŽéƒµä»¶ç™¼åˆ°é€™äº›åœ°å€ã€‚å¦å¤–,å°æ–¼æ‰€æœ‰
通éŽé›»å­éƒµä»¶ç™¼é€çš„å•é¡Œå ±å‘Šï¼Œä¸€å®šè¦æŠ„é€ Linux Kernel Mailing List(LKML)
<linux-kernel@vger.kernel.org>。在以後通éŽéƒµä»¶ç™¼é€å•é¡Œå ±å‘Šæ™‚,ä¸è¦éºæ¼ä»»ä½•
@@ -544,8 +538,8 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
~~~~~~~~~~~~~~~~~~~~
å°æ–¼æ‰‹é ­æœ‰Linuxæºç¢¼çš„人來說,有第二個å¯ä»¥æ‰¾åˆ°åˆé©çš„報告地點的é¸æ“‡ï¼šè…³æœ¬
-「scripts/get_maintainer.plã€ï¼Œå®ƒå˜—試找到所有è¦è¯ç¹«çš„人。它會查詢MAINTAINERS
-文件,並需è¦ç”¨ç›¸é—œåŽŸå§‹ç¢¼çš„路徑來調用。å°æ–¼ç·¨è­¯æˆæ¨¡å¡Šçš„驅動程åºï¼Œç¶“常å¯ä»¥ç”¨
+“scripts/get_maintainer.plâ€ï¼Œå®ƒå˜—試找到所有è¦è¯ç¹«çš„人。它會查詢MAINTAINERS
+文件,並需è¦ç”¨ç›¸é—œæºä»£ç¢¼çš„路徑來調用。å°æ–¼ç·¨è­¯æˆæ¨¡å¡Šçš„驅動程åºï¼Œç¶“常å¯ä»¥ç”¨
這樣的命令找到::
$ modinfo ath10k_pci | grep filename | sed 's!/lib/modules/.*/kernel/!!; s!filename:!!; s!\.ko\(\|\.xz\)!!'
@@ -561,13 +555,13 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
netdev@vger.kernel.org (open list:NETWORKING DRIVERS)
linux-kernel@vger.kernel.org (open list)
-ä¸è¦æŠŠä½ çš„報告發給所有的人。發é€çµ¦ç¶­è­·è€…,腳本稱之爲「supporter:ã€ï¼›å¦å¤–抄é€
+ä¸è¦æŠŠä½ çš„報告發給所有的人。發é€çµ¦ç¶­è­·è€…,腳本稱之爲“supporter:â€ï¼›å¦å¤–抄é€
ä»£ç¢¼æœ€ç›¸é—œçš„éƒµä»¶åˆ—è¡¨ï¼Œä»¥åŠ Linux 內核郵件列表(LKML)。在此例中,你需è¦å°‡å ±
-告發é€çµ¦ 「Some Human <shuman@example.com>〠,並抄é€
-「ath10k@lists.infradead.orgã€å’Œã€Œlinux-kernel@vger.kernel.orgã€ã€‚
+告發é€çµ¦ “Some Human <shuman@example.com>†,並抄é€
+“ath10k@lists.infradead.orgâ€å’Œâ€œlinux-kernel@vger.kernel.orgâ€ã€‚
-注æ„:如果你用 git 克隆了 Linux 原始碼,你å¯èƒ½éœ€è¦ç”¨--git å†æ¬¡èª¿ç”¨
-get_maintainer.pl。腳本會查看æ交歷å²ï¼Œä»¥æ‰¾åˆ°æœ€è¿‘哪些人åƒèˆ‡äº†ç›¸é—œä»£ç¢¼çš„編寫,
+注æ„:如果你用 git 克隆了 Linux æºä»£ç¢¼ï¼Œä½ å¯èƒ½éœ€è¦ç”¨--git å†æ¬¡èª¿ç”¨
+get_maintainer.pl。腳本會查看æ交歷å²ï¼Œä»¥æ‰¾åˆ°æœ€è¿‘哪些人蔘與了相關代碼的編寫,
因爲他們å¯èƒ½æœƒæ供幫助。但è¦å°å¿ƒä½¿ç”¨é€™äº›çµæžœï¼Œå› çˆ²å®ƒå¾ˆå®¹æ˜“讓你誤入歧途。
例如,這種情æ³å¸¸å¸¸æœƒç™¼ç”Ÿåœ¨å¾ˆå°‘被修改的地方(比如è€èˆŠçš„或未維護的驅動程åºï¼‰ï¼š
有時這樣的代碼會在樹級清ç†æœŸé–“被根本ä¸é—œå¿ƒæ­¤é©…動程åºçš„開發者修改。
@@ -580,73 +574,74 @@ get_maintainer.pl。腳本會查看æ交歷å²ï¼Œä»¥æ‰¾åˆ°æœ€è¿‘哪些人åƒèˆ‡
如果找到匹é…的報告,請加入討論而ä¸æ˜¯ç™¼é€æ–°å ±å‘Šã€‚*
如å‰æ‰€è¿°ï¼šå ±å‘Šä¸€å€‹åˆ¥äººå·²ç¶“æ出的å•é¡Œï¼Œå°æ¯å€‹äººä¾†èªªéƒ½æ˜¯æµªè²»æ™‚間,尤其是作爲報告
-人的你。這就是爲什麼你應該å†æ¬¡æœç´¢ç¾æœ‰çš„報告。ç¾åœ¨ä½ å·²ç¶“知é“å•é¡Œéœ€è¦å ±å‘Šåˆ°å“ªè£¡ã€‚
+人的你。這就是爲什麼你應該å†æ¬¡æœç´¢ç¾æœ‰çš„報告。ç¾åœ¨ä½ å·²ç¶“知é“å•é¡Œéœ€è¦å ±å‘Šåˆ°å“ªè£ã€‚
如果是郵件列表,那麼一般在 `lore.kernel.org <https://lore.kernel.org/>`_ å¯ä»¥
找到相應存檔。
但有些列表é‹è¡Œåœ¨å…¶ä»–地方。例如å‰é¢æ­¥é©Ÿä¸­ç•¶ä¾‹å­çš„ath10k WiFi驅動程åºå°±æ˜¯é€™ç¨®
-情æ³ã€‚但是你通常å¯ä»¥åœ¨ç¶²ä¸Šå¾ˆå®¹æ˜“地找到這些列表的檔案。例如æœç´¢ã€Œarchive
-ath10k@lists.infradead.orgã€ï¼Œå°‡å¼•å°Žæ‚¨åˆ°ath10k郵件列表的信æ¯é ï¼Œè©²é é¢é ‚部連çµ
+情æ³ã€‚但是你通常å¯ä»¥åœ¨ç¶²ä¸Šå¾ˆå®¹æ˜“地找到這些列表的檔案。例如æœç´¢â€œarchive
+ath10k@lists.infradead.orgâ€ï¼Œå°‡å¼•å°Žæ‚¨åˆ°ath10k郵件列表的信æ¯é ï¼Œè©²é é¢é ‚部éˆæŽ¥
到其 `列表存檔 <https://lists.infradead.org/pipermail/ath10k/>`_ 。éºæ†¾çš„是,
-這個列表和其他一些列表缺ä¹æœç´¢å…¶å­˜æª”的功能。在這種情æ³ä¸‹å¯ä»¥ä½¿ç”¨å¸¸è¦çš„網際網路
-æœå°‹å¼•æ“Žï¼Œä¸¦æ·»åŠ é¡žä¼¼ã€Œsite:lists.infadead.org/pipermail/ath10k/ã€é€™
-樣的æœç´¢æ¢ä»¶ï¼Œé€™æœƒæŠŠçµæžœé™åˆ¶åœ¨è©²é€£çµä¸­çš„檔案。
+這個列表和其他一些列表缺ä¹æœç´¢å…¶å­˜æª”的功能。在這種情æ³ä¸‹å¯ä»¥ä½¿ç”¨å¸¸è¦çš„互è¯ç¶²
+æœç´¢å¼•æ“Žï¼Œä¸¦æ·»åŠ é¡žä¼¼â€œsite:lists.infadead.org/pipermail/ath10k/â€é€™
+樣的æœç´¢æ¢ä»¶ï¼Œé€™æœƒæŠŠçµæžœé™åˆ¶åœ¨è©²éˆæŽ¥ä¸­çš„檔案。
-也請進一步æœç´¢ç¶²çµ¡ã€LKMLå’Œbugzilla.kernel.org網站。
+也請進一步æœç´¢ç¶²çµ¡ã€LKMLå’Œbugzilla.kernel.org網站。如果你的報告需è¦ç™¼é€åˆ°ç¼ºé™·
+跟蹤器中,那麼您å¯èƒ½é‚„需è¦æª¢æŸ¥å­ç³»çµ±çš„郵件列表存檔,因爲å¯èƒ½æœ‰äººåªåœ¨é‚£è£å ±å‘Šäº†å®ƒã€‚
-有關如何æœç´¢ä»¥åŠåœ¨æ‰¾åˆ°åŒ¹é…報告時如何æ“作的詳細信æ¯ï¼Œè«‹åƒé–±ä¸Šé¢çš„「æœç´¢ç¾æœ‰å ±å‘Š
-(第一部分)ã€ã€‚
+有關如何æœç´¢ä»¥åŠåœ¨æ‰¾åˆ°åŒ¹é…報告時如何æ“作的詳細信æ¯ï¼Œè«‹åƒé–±ä¸Šé¢çš„“æœç´¢ç¾æœ‰å ±å‘Š
+(第一部分)â€ã€‚
-ä¸è¦æ€¥è‘—完æˆå ±å‘ŠéŽç¨‹çš„這一步:花30到60分é˜ç”šè‡³æ›´å¤šçš„時間å¯ä»¥çˆ²ä½ å’Œå…¶ä»–äººç¯€çœ /
+ä¸è¦æ€¥ç€å®Œæˆå ±å‘ŠéŽç¨‹çš„這一步:花30到60分é˜ç”šè‡³æ›´å¤šçš„時間å¯ä»¥çˆ²ä½ å’Œå…¶ä»–äººç¯€çœ /
減少相當多的時間和麻煩。
安è£ä¸€å€‹æ–°çš„內核進行測試
--------------------------
- *除éžæ‚¨å·²ç¶“在é‹è¡Œæœ€æ–°çš„「主線ã€Linux內核,å¦å‰‡æœ€å¥½åœ¨å ±å‘Šæµç¨‹å‰å®‰è£å®ƒã€‚在
- æŸäº›æƒ…æ³ä¸‹ï¼Œä½¿ç”¨æœ€æ–°çš„「穩定版ã€Linux進行測試和報告也是å¯ä»¥æŽ¥å—的替代方案;
+ *除éžæ‚¨å·²ç¶“在é‹è¡Œæœ€æ–°çš„“主線â€Linux內核,å¦å‰‡æœ€å¥½åœ¨å ±å‘Šæµç¨‹å‰å®‰è£å®ƒã€‚在
+ æŸäº›æƒ…æ³ä¸‹ï¼Œä½¿ç”¨æœ€æ–°çš„“穩定版â€Linux進行測試和報告也是å¯ä»¥æŽ¥å—的替代方案;
在åˆä½µçª—å£æœŸé–“,這實際上å¯èƒ½æ˜¯æœ€å¥½çš„方法,但在開發階段最好還是暫åœå¹¾å¤©ã€‚
- ç„¡è«–ä½ é¸æ“‡ä»€éº¼ç‰ˆæœ¬ï¼Œæœ€å¥½ä½¿ç”¨ã€Œæ™®é€šã€æ§‹å»ºã€‚忽略這些建議會大大增加您的報告
+ ç„¡è«–ä½ é¸æ“‡ä»€éº¼ç‰ˆæœ¬ï¼Œæœ€å¥½ä½¿ç”¨â€œæ™®é€šâ€æ§‹å»ºã€‚忽略這些建議會大大增加您的報告
被拒絕或忽略的風險。*
-正如第一步的詳細解釋中所æ到的:與大多數程å¼è¨­è¨ˆå¸«ä¸€æ¨£ï¼Œèˆ‡å¤§å¤šæ•¸ç¨‹å¼è¨­è¨ˆå¸«ä¸€æ¨£ï¼ŒLinux
-內核開發人員ä¸å–œæ­¡èŠ±æ™‚間處ç†ä»–們維護的原始碼中根本ä¸æœƒç™¼ç”Ÿçš„å•é¡Œçš„報告。這隻
+正如第一步的詳細解釋中所æ到的:與大多數程åºå“¡ä¸€æ¨£ï¼Œèˆ‡å¤§å¤šæ•¸ç¨‹åºå“¡ä¸€æ¨£ï¼ŒLinux
+內核開發人員ä¸å–œæ­¡èŠ±æ™‚間處ç†ä»–們維護的æºä»£ç¢¼ä¸­æ ¹æœ¬ä¸æœƒç™¼ç”Ÿçš„å•é¡Œçš„報告。這隻
會浪費æ¯å€‹äººçš„時間,尤其是你的時間。這就是爲什麼在報告å•é¡Œä¹‹å‰ï¼Œæ‚¨å¿…須先確èª
å•é¡Œä»ç„¶å­˜åœ¨æ–¼æœ€æ–°çš„上游代碼中,這符åˆæ¯å€‹äººçš„利益。您å¯ä»¥å¿½ç•¥æ­¤å»ºè­°ï¼Œä½†å¦‚å‰
所述:這樣åšæœƒæ¥µå¤§åœ°å¢žåŠ å•é¡Œå ±å‘Šè¢«æ‹’絕或被忽略的風險。
-內核「最新上游ã€çš„範åœé€šå¸¸æŒ‡ï¼š
+內核“最新上游â€çš„範åœé€šå¸¸æŒ‡ï¼š
* 安è£ä¸€å€‹ä¸»ç·šå…§æ ¸ï¼›æœ€æ–°çš„穩定版內核也å¯ä»¥æ˜¯ä¸€å€‹é¸æ“‡ï¼Œä½†å¤§å¤šæ•¸æ™‚候都最好é¿å…。
- 長期支æŒå…§æ ¸ï¼ˆæœ‰æ™‚稱爲「LTS內核ã€ï¼‰ä¸é©åˆæ­¤æµç¨‹ã€‚下一å°ç¯€å°‡æ›´è©³ç´°åœ°è§£é‡‹æ‰€æœ‰
+ 長期支æŒå…§æ ¸ï¼ˆæœ‰æ™‚稱爲“LTS內核â€ï¼‰ä¸é©åˆæ­¤æµç¨‹ã€‚下一å°ç¯€å°‡æ›´è©³ç´°åœ°è§£é‡‹æ‰€æœ‰
這些。
* 下一å°ç¯€æè¿°ç²å–和安è£é€™æ¨£ä¸€å€‹å…§æ ¸çš„方法。它還指出了使用é ç·¨è­¯å…§æ ¸æ˜¯å¯ä»¥çš„,
- 但普通的內核更好,這æ„味著:它是直接使用從 `kernel.org <https://kernel.org/>`_
- ç²å¾—çš„Linux原始碼構建並且沒有任何方å¼ä¿®æ”¹æˆ–增強。
+ 但普通的內核更好,這æ„味ç€ï¼šå®ƒæ˜¯ç›´æŽ¥ä½¿ç”¨å¾ž `kernel.org <https://kernel.org/>`_
+ ç²å¾—çš„Linuxæºä»£ç¢¼æ§‹å»ºä¸¦ä¸”沒有任何方å¼ä¿®æ”¹æˆ–增強。
é¸æ“‡é©åˆæ¸¬è©¦çš„版本
~~~~~~~~~~~~~~~~~~~~
-å‰å¾€ `kernel.org <https://kernel.org/>`_ 來決定使用哪個版本。忽略那個寫著
-「Latest release最新版本ã€çš„巨大黃色按鈕,往下看有一個表格。在表格的頂部,你會
-看到一行以「mainlineã€é–‹é ­çš„字樣,大多數情æ³ä¸‹å®ƒæœƒæŒ‡å‘一個版本號類似「5.8-rc2ã€
-çš„é ç™¼å¸ƒç‰ˆæœ¬ã€‚如果是這樣的話,你將需è¦ä½¿ç”¨é€™å€‹ä¸»ç·šå…§æ ¸é€²è¡Œæ¸¬è©¦ã€‚ä¸è¦è®“「rcã€
-嚇到你,這些「開發版內核ã€å¯¦éš›ä¸Šéžå¸¸å¯é â€”—而且你已經按照上é¢çš„指示åšäº†å‚™ä»½ï¼Œ
+å‰å¾€ `kernel.org <https://kernel.org/>`_ 來決定使用哪個版本。忽略那個寫ç€
+“Latest release最新版本â€çš„巨大黃色按鈕,往下看有一個表格。在表格的頂部,你會
+看到一行以“mainlineâ€é–‹é ­çš„字樣,大多數情æ³ä¸‹å®ƒæœƒæŒ‡å‘一個版本號類似“5.8-rc2â€
+çš„é ç™¼ä½ˆç‰ˆæœ¬ã€‚如果是這樣的話,你將需è¦ä½¿ç”¨é€™å€‹ä¸»ç·šå…§æ ¸é€²è¡Œæ¸¬è©¦ã€‚ä¸è¦è®““rcâ€
+嚇到你,這些“開發版內核â€å¯¦éš›ä¸Šéžå¸¸å¯é â€”—而且你已經按照上é¢çš„指示åšäº†å‚™ä»½ï¼Œ
ä¸æ˜¯å—Žï¼Ÿ
-大概æ¯ä¹åˆ°å周,「mainlineã€å¯èƒ½æœƒçµ¦ä½ æŒ‡å‡ºä¸€å€‹ç‰ˆæœ¬è™Ÿé¡žä¼¼ã€Œ5.7ã€çš„æ­£å¼ç‰ˆæœ¬ã€‚如果
-碰見這種情æ³ï¼Œè«‹è€ƒæ…®æš«åœå ±å‘ŠéŽç¨‹ï¼Œç›´åˆ°ä¸‹ä¸€å€‹ç‰ˆæœ¬çš„第一個é ç™¼å¸ƒï¼ˆ5.8-rc1)出
-ç¾åœ¨ `kernel.org <https://kernel.org/>`_ 上。這是因爲 Linux 的開發周期正在
-兩周的「åˆä½µçª—å£ã€å…§ã€‚大部分的改動和所有干擾性的改動都會在這段時間內被åˆä½µåˆ°
+大概æ¯ä¹åˆ°å週,“mainlineâ€å¯èƒ½æœƒçµ¦ä½ æŒ‡å‡ºä¸€å€‹ç‰ˆæœ¬è™Ÿé¡žä¼¼â€œ5.7â€çš„æ­£å¼ç‰ˆæœ¬ã€‚如果
+碰見這種情æ³ï¼Œè«‹è€ƒæ…®æš«åœå ±å‘ŠéŽç¨‹ï¼Œç›´åˆ°ä¸‹ä¸€å€‹ç‰ˆæœ¬çš„第一個é ç™¼ä½ˆï¼ˆ5.8-rc1)出
+ç¾åœ¨ `kernel.org <https://kernel.org/>`_ 上。這是因爲 Linux 的開發週期正在
+兩週的“åˆä½µçª—å£â€å…§ã€‚大部分的改動和所有干擾性的改動都會在這段時間內被åˆä½µåˆ°
下一個版本中。在此期間使用主線是比較å±éšªçš„。內核開發者通常也很忙,å¯èƒ½æ²’有
多餘的時間來處ç†å•é¡Œå ±å‘Šã€‚這也是很有å¯èƒ½åœ¨åˆä½µçª—å£ä¸­æ‡‰ç”¨äº†è¨±å¤šä¿®æ”¹ä¾†ä¿®å¾©ä½ 
-所é¢è‡¨çš„å•é¡Œï¼›é€™å°±æ˜¯çˆ²ä»€éº¼ä½ å¾ˆå¿«å°±å¾—用一個新的內核版本é‡æ–°æ¸¬è©¦ï¼Œå°±åƒä¸‹é¢ã€Œç™¼
-布報告後的責任ã€ä¸€ç¯€ä¸­æ‰€è¿°çš„那樣。
+所é¢è‡¨çš„å•é¡Œï¼›é€™å°±æ˜¯çˆ²ä»€éº¼ä½ å¾ˆå¿«å°±å¾—用一個新的內核版本é‡æ–°æ¸¬è©¦ï¼Œå°±åƒä¸‹é¢â€œç™¼
+布報告後的責任â€ä¸€ç¯€ä¸­æ‰€è¿°çš„那樣。
-這就是爲什麼è¦ç­‰åˆ°åˆä½µçª—å£çµæŸå¾Œæ‰åŽ»åšã€‚但是如果你處ç†çš„是一些ä¸æ‡‰è©²ç­‰å¾…çš„
+這就是爲什麼è¦ç­‰åˆ°åˆä½µçª—å£çµæŸå¾Œçº”去åšã€‚但是如果你處ç†çš„是一些ä¸æ‡‰è©²ç­‰å¾…çš„
æ±è¥¿ï¼Œå‰‡ç„¡éœ€é€™æ¨£åšã€‚在這種情æ³ä¸‹ï¼Œå¯ä»¥è€ƒæ…®é€šéŽ git ç²å–最新的主線內核(見下
文),或者使用 kernel.org 上æ供的最新穩定版本。如果 mainline 因爲æŸäº›åŽŸå› 
ä¸ç„¡æ³•æ­£å¸¸å·¥ä½œï¼Œé‚£éº¼ä½¿ç”¨å®ƒä¹Ÿæ˜¯å¯ä»¥æŽ¥å—的。總的來說:用它來é‡ç¾å•é¡Œä¹Ÿæ¯”完全
@@ -657,7 +652,7 @@ ath10k@lists.infradead.orgã€ï¼Œå°‡å¼•å°Žæ‚¨åˆ°ath10k郵件列表的信æ¯é ï¼Œ
需è¦å…ˆåœ¨ä¸»ç·šä¿®å¾©ï¼Œç„¶å¾Œæ‰èƒ½å¾—到回傳,這å¯èƒ½éœ€è¦å¹¾å¤©æˆ–幾周。å¦ä¸€å€‹åŽŸå› æ˜¯ï¼šæ‚¨
希望的修復å°æ–¼å›žå‚³ä¾†èªªå¯èƒ½å¤ªé›£æˆ–太冒險;因此å†æ¬¡å ±å‘Šå•é¡Œä¸å¤ªå¯èƒ½æ”¹è®Šä»»ä½•äº‹æƒ…。
-這些方é¢ä¹Ÿéƒ¨åˆ†è¡¨æ˜Žäº†çˆ²ä»€éº¼é•·æœŸæ”¯æŒå…§æ ¸ï¼ˆæœ‰æ™‚稱爲「LTS內核ã€ï¼‰ä¸é©åˆå ±å‘Šæµç¨‹ï¼š
+這些方é¢ä¹Ÿéƒ¨åˆ†è¡¨æ˜Žäº†çˆ²ä»€éº¼é•·æœŸæ”¯æŒå…§æ ¸ï¼ˆæœ‰æ™‚稱爲“LTS內核â€ï¼‰ä¸é©åˆå ±å‘Šæµç¨‹ï¼š
它們與當å‰ä»£ç¢¼çš„è·é›¢å¤ªé ã€‚因此,先去測試主線,然後å†æŒ‰æµç¨‹èµ°ï¼šå¦‚果主線沒有
出ç¾å•é¡Œï¼Œæµç¨‹å°‡æŒ‡å°Žæ‚¨å¦‚何在舊版本線中修復它。
@@ -669,31 +664,31 @@ ath10k@lists.infradead.orgã€ï¼Œå°‡å¼•å°Žæ‚¨åˆ°ath10k郵件列表的信æ¯é ï¼Œ
**使用é ç·¨è­¯çš„內核** :這往往是最快速ã€æœ€ç°¡å–®ã€æœ€å®‰å…¨çš„方法——尤其是在你ä¸ç†Ÿ
悉 Linux 內核的情æ³ä¸‹ã€‚å•é¡Œæ˜¯ï¼šç™¼è¡Œå•†æˆ–附加存儲庫æ供的大多數版本都是從修改
-éŽçš„Linux原始碼構建的。因此它們ä¸æ˜¯æ™®é€šçš„,通常ä¸é©åˆæ–¼æ¸¬è©¦å’Œå•é¡Œå ±å‘Šï¼šé€™äº›
+éŽçš„Linuxæºä»£ç¢¼æ§‹å»ºçš„。因此它們ä¸æ˜¯æ™®é€šçš„,通常ä¸é©åˆæ–¼æ¸¬è©¦å’Œå•é¡Œå ±å‘Šï¼šé€™äº›
更改å¯èƒ½æœƒå°Žè‡´æ‚¨é¢è‡¨çš„å•é¡Œæˆ–以æŸç¨®æ–¹å¼å½±éŸ¿å•é¡Œã€‚
但是如果您使用的是æµè¡Œçš„Linux發行版,那麼您就很幸é‹äº†ï¼šå°æ–¼å¤§éƒ¨åˆ†çš„發行版,
您å¯ä»¥åœ¨ç¶²ä¸Šæ‰¾åˆ°åŒ…å«æœ€æ–°ä¸»ç·šæˆ–穩定版本Linux內核包的存儲庫。使用這些是完全å¯
-以的,åªè¦å¾žå­˜å„²åº«çš„æ述中確èªå®ƒå€‘是普通的或者至少接近普通。此外,請確ä¿è»Ÿé«”
-包包å«kernel.org上æ供的最新版本內核。如果這些軟體包的時間超éŽä¸€å‘¨ï¼Œé‚£éº¼å®ƒå€‘
-å¯èƒ½å°±ä¸åˆé©äº†ï¼Œå› çˆ²æ–°çš„主線和穩定版內核通常至少æ¯å‘¨ç™¼å¸ƒä¸€æ¬¡ã€‚
+以的,åªè¦å¾žå­˜å„²åº«çš„æ述中確èªå®ƒå€‘是普通的或者至少接近普通。此外,請確ä¿è»Ÿä»¶
+包包å«kernel.org上æ供的最新版本內核。如果這些軟件包的時間超éŽä¸€é€±ï¼Œé‚£éº¼å®ƒå€‘
+å¯èƒ½å°±ä¸åˆé©äº†ï¼Œå› çˆ²æ–°çš„主線和穩定版內核通常至少æ¯é€±ç™¼ä½ˆä¸€æ¬¡ã€‚
請注æ„,您以後å¯èƒ½éœ€è¦æ‰‹å‹•æ§‹å»ºè‡ªå·±çš„內核:有時這是調試或測試修復程åºæ‰€å¿…需的,
如後文所述。還è¦æ³¨æ„,é ç·¨è­¯çš„內核å¯èƒ½ç¼ºå°‘在出ç¾panicã€Oopsã€warning或BUG時
-解碼內核列å°çš„消æ¯æ‰€éœ€çš„調試符號;如果您計劃解碼這些消æ¯ï¼Œæœ€å¥½è‡ªå·±ç·¨è­¯å…§æ ¸
-(有關詳細信æ¯ï¼Œè«‹åƒé–±æœ¬å°ç¯€çµå°¾å’Œã€Œè§£ç¢¼å¤±æ•—ä¿¡æ¯ã€å°ç¯€ï¼‰ã€‚
+解碼內核打å°çš„消æ¯æ‰€éœ€çš„調試符號;如果您計劃解碼這些消æ¯ï¼Œæœ€å¥½è‡ªå·±ç·¨è­¯å…§æ ¸
+(有關詳細信æ¯ï¼Œè«‹åƒé–±æœ¬å°ç¯€çµå°¾å’Œâ€œè§£ç¢¼å¤±æ•—ä¿¡æ¯â€å°ç¯€ï¼‰ã€‚
**使用git** :熟悉 git 的開發者和有經驗的 Linux 用戶通常最好直接從
`kernel.org 上的官方開發倉庫
<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/>`_
-中ç²å–最新的 Linux 內核原始碼。這些很å¯èƒ½æ¯”最新的主線é ç™¼å¸ƒç‰ˆæœ¬æ›´æ–°ä¸€äº›ã€‚ä¸
-用擔心:它們和正å¼çš„é ç™¼å¸ƒç‰ˆæœ¬ä¸€æ¨£å¯é ï¼Œé™¤éžå…§æ ¸çš„開發周期目å‰æ­£è™•æ–¼åˆä½µçª—
+中ç²å–最新的 Linux 內核æºä»£ç¢¼ã€‚這些很å¯èƒ½æ¯”最新的主線é ç™¼ä½ˆç‰ˆæœ¬æ›´æ–°ä¸€äº›ã€‚ä¸
+用擔心:它們和正å¼çš„é ç™¼ä½ˆç‰ˆæœ¬ä¸€æ¨£å¯é ï¼Œé™¤éžå…§æ ¸çš„開發週期目å‰æ­£è™•æ–¼åˆä½µçª—
å£ä¸­ã€‚ä¸éŽå³ä¾¿å¦‚此,它們也是相當å¯é çš„。
**常è¦æ–¹æ³•** :ä¸ç†Ÿæ‚‰ git 的人通常最好從 `kernel.org <https://kernel.org/>`_
下載æºç¢¼çš„tar 存檔包。
-如何實際構建一個內核並ä¸åœ¨é€™è£¡æ述,因爲許多網站已經解釋了必è¦çš„步驟。如果
+如何實際構建一個內核並ä¸åœ¨é€™è£æ述,因爲許多網站已經解釋了必è¦çš„步驟。如果
你是新手,å¯ä»¥è€ƒæ…®æŒ‰ç…§é‚£äº›å»ºè­°ä½¿ç”¨ ``make localmodconfig`` 來åšï¼Œå®ƒå°‡å˜—試ç²
å–你當å‰å…§æ ¸çš„é…置,然後根據你的系統進行一些調整。這樣åšä¸¦ä¸èƒ½ä½¿ç·¨è­¯å‡ºä¾†çš„
內核更好,但å¯ä»¥æ›´å¿«åœ°ç·¨è­¯ã€‚
@@ -702,19 +697,19 @@ ath10k@lists.infradead.orgã€ï¼Œå°‡å¼•å°Žæ‚¨åˆ°ath10k郵件列表的信æ¯é ï¼Œ
啓用 CONFIG_KALLSYMS é¸é …。此外,還å¯ä»¥å•“用 CONFIG_DEBUG_KERNEL å’Œ
CONFIG_DEBUG_INFO;後者是相關é¸é …,但åªæœ‰å•“用å‰è€…æ‰èƒ½é–‹å•“。請注æ„,
CONFIG_DEBUG_INFO 會需è¦æ›´å¤šå„²å­˜ç©ºé–“來構建內核。但這是值得的,因爲這些é¸é …å°‡
-å…許您ç¨å¾Œç²¾ç¢ºå®šä½è§¸ç™¼å•é¡Œçš„確切代碼行。下é¢çš„「解碼失敗信æ¯ã€ä¸€ç¯€å°æ­¤é€²è¡Œäº†æ›´
+å…許您ç¨å¾Œç²¾ç¢ºå®šä½è§¸ç™¼å•é¡Œçš„確切代碼行。下é¢çš„“解碼失敗信æ¯â€ä¸€ç¯€å°æ­¤é€²è¡Œäº†æ›´
詳細的解釋。
但請記ä½ï¼šå§‹çµ‚記錄é‡åˆ°çš„å•é¡Œï¼Œä»¥é˜²é›£ä»¥é‡ç¾ã€‚發é€æœªè§£ç¢¼çš„報告總比ä¸å ±å‘Šè¦å¥½ã€‚
-檢查「汙染ã€æ¨™èªŒ
+檢查“污染â€æ¨™èªŒ
----------------
- *確ä¿æ‚¨å‰›å‰›å®‰è£çš„內核在é‹è¡Œæ™‚ä¸æœƒã€Œæ±™æŸ“ã€è‡ªå·±ã€‚*
+ *確ä¿æ‚¨å‰›å‰›å®‰è£çš„內核在é‹è¡Œæ™‚ä¸æœƒâ€œæ±¡æŸ“â€è‡ªå·±ã€‚*
正如上é¢å·²ç¶“詳細介紹éŽçš„:當發生一些å¯èƒ½æœƒå°Žè‡´ä¸€äº›çœ‹èµ·ä¾†å®Œå…¨ä¸ç›¸é—œçš„後續錯
-誤的事情時,內核會設置一個「汙染ã€æ¨™èªŒã€‚這就是爲什麼你需è¦æª¢æŸ¥ä½ å‰›å‰›å®‰è£çš„å…§
+誤的事情時,內核會設置一個“污染â€æ¨™èªŒã€‚這就是爲什麼你需è¦æª¢æŸ¥ä½ å‰›å‰›å®‰è£çš„å…§
核是å¦æœ‰è¨­ç½®æ­¤æ¨™èªŒã€‚如果有的話,幾乎在任何情æ³ä¸‹ä½ éƒ½éœ€è¦åœ¨å ±å‘Šå•é¡Œä¹‹å‰å…ˆæ¶ˆ
除它。詳細的æ“作方法請看上é¢çš„章節。
@@ -729,43 +724,43 @@ CONFIG_DEBUG_INFO 會需è¦æ›´å¤šå„²å­˜ç©ºé–“來構建內核。但這是值得çš
å¯ä»¥è€ƒæ…®ä½¿ç”¨æ­¤ç‰ˆæœ¬ç·šï¼Œæ”¾æ£„報告å•é¡Œã€‚但是請記ä½ï¼Œåªè¦å®ƒæ²’有在 `kernel.org
<https://kernel.org/>`_ 的穩定版和長期版(以åŠç”±é€™äº›ç‰ˆæœ¬è¡ç”Ÿå‡ºä¾†çš„廠商內核)
中得到修復,其他用戶å¯èƒ½ä»ç„¶æœƒå—到它的困擾。如果你喜歡使用其中的一個,或
-者åªæ˜¯æƒ³å¹«åŠ©å®ƒå€‘的用戶,請å‰å¾€ä¸‹é¢çš„「報告åªç™¼ç”Ÿåœ¨è¼ƒèˆŠå…§æ ¸ç‰ˆæœ¬ç·šçš„å•é¡Œã€ä¸€ç¯€ã€‚
+者åªæ˜¯æƒ³å¹«åŠ©å®ƒå€‘的用戶,請å‰å¾€ä¸‹é¢çš„“報告åªç™¼ç”Ÿåœ¨è¼ƒèˆŠå…§æ ¸ç‰ˆæœ¬ç·šçš„å•é¡Œâ€ä¸€ç¯€ã€‚
優化復ç¾å•é¡Œçš„æè¿°
--------------------
- *優化你的筆記:試著找到並寫出最直接的復ç¾å•é¡Œçš„方法。確ä¿æœ€çµ‚çµæžœåŒ…å«æ‰€
+ *優化你的筆記:試ç€æ‰¾åˆ°ä¸¦å¯«å‡ºæœ€ç›´æŽ¥çš„復ç¾å•é¡Œçš„方法。確ä¿æœ€çµ‚çµæžœåŒ…å«æ‰€
有é‡è¦çš„細節,åŒæ™‚讓第一次è½èªªçš„人容易閱讀和ç†è§£ã€‚如果您在此éŽç¨‹ä¸­å­¸åˆ°
了一些æ±è¥¿ï¼Œè«‹è€ƒæ…®å†æ¬¡æœç´¢é—œæ–¼è©²å•é¡Œçš„ç¾æœ‰å ±å‘Šã€‚*
éŽæ–¼è¤‡é›œçš„報告會讓別人很難ç†è§£ã€‚因此請儘é‡æ‰¾åˆ°ä¸€å€‹å¯ä»¥ç›´æŽ¥æè¿°ã€æ˜“於以書é¢
å½¢å¼ç†è§£çš„å†ç¾æ–¹æ³•ã€‚包å«æ‰€æœ‰é‡è¦çš„細節,但åŒæ™‚也è¦å„˜é‡ä¿æŒç°¡çŸ­ã€‚
-在這在å‰é¢çš„步驟中,你很å¯èƒ½å·²ç¶“了解了一些關於你所é¢è‡¨çš„å•é¡Œçš„點。利用這些
+在這在å‰é¢çš„步驟中,你很å¯èƒ½å·²ç¶“瞭解了一些關於你所é¢è‡¨çš„å•é¡Œçš„點。利用這些
知識,å†æ¬¡æœç´¢å¯ä»¥è½‰è€ŒåŠ å…¥çš„ç¾æœ‰å ±å‘Šã€‚
解碼失敗信æ¯
-------------
- *如果失敗涉åŠã€Œpanicã€ã€ã€ŒOopsã€ã€ã€Œwarningã€æˆ–「BUGã€ï¼Œè«‹è€ƒæ…®è§£ç¢¼å…§æ ¸æ—¥èªŒä»¥æŸ¥æ‰¾
+ *如果失敗涉åŠâ€œpanicâ€ã€â€œOopsâ€ã€â€œwarningâ€æˆ–“BUGâ€ï¼Œè«‹è€ƒæ…®è§£ç¢¼å…§æ ¸æ—¥èªŒä»¥æŸ¥æ‰¾
觸發錯誤的代碼行。*
-當內核檢測到內部å•é¡Œæ™‚,它會記錄一些有關已執行代碼的信æ¯ã€‚這使得在原始碼中精
+當內核檢測到內部å•é¡Œæ™‚,它會記錄一些有關已執行代碼的信æ¯ã€‚這使得在æºä»£ç¢¼ä¸­ç²¾
確定ä½è§¸ç™¼å•é¡Œçš„行並顯示如何調用它æˆçˆ²å¯èƒ½ã€‚但åªæœ‰åœ¨é…置內核時啓用了
CONFIG_DEBUG_INFO å’Œ CONFIG_KALLSYMSé¸é …時,這種方法æ‰èµ·æ•ˆã€‚如果已啓用此é¸é …,
-請考慮解碼內核日誌中的信æ¯ã€‚這將使我們更容易ç†è§£æ˜¯ä»€éº¼å°Žè‡´äº†ã€Œpanicã€ã€ã€ŒOopsã€ã€
-「warningã€æˆ–「BUGã€ï¼Œå¾žè€Œå¢žåŠ äº†æœ‰äººæ供修復的機率。
+請考慮解碼內核日誌中的信æ¯ã€‚這將使我們更容易ç†è§£æ˜¯ä»€éº¼å°Žè‡´äº†â€œpanicâ€ã€â€œOopsâ€ã€
+“warningâ€æˆ–“BUGâ€ï¼Œå¾žè€Œå¢žåŠ äº†æœ‰äººæ供修復的幾率。
-解碼å¯ä»¥é€šéŽLinux原始碼樹中的腳本來完æˆã€‚如果您é‹è¡Œçš„內核是之å‰è‡ªå·±ç·¨è­¯çš„,
+解碼å¯ä»¥é€šéŽLinuxæºä»£ç¢¼æ¨¹ä¸­çš„腳本來完æˆã€‚如果您é‹è¡Œçš„內核是之å‰è‡ªå·±ç·¨è­¯çš„,
這樣這樣調用它::
[user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh ./linux-5.10.5/vmlinux
/usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/
如果您é‹è¡Œçš„是打包好的普通內核,則å¯èƒ½éœ€è¦å®‰è£å¸¶æœ‰èª¿è©¦ç¬¦è™Ÿçš„相應包。然後按以下
-æ–¹å¼èª¿ç”¨è…³æœ¬ï¼ˆå¦‚果發行版未打包,則å¯èƒ½éœ€è¦å¾žLinux原始碼ç²å–)::
+æ–¹å¼èª¿ç”¨è…³æœ¬ï¼ˆå¦‚果發行版未打包,則å¯èƒ½éœ€è¦å¾žLinuxæºä»£ç¢¼ç²å–)::
[user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh \
/usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/
@@ -778,10 +773,10 @@ CONFIG_DEBUG_INFO å’Œ CONFIG_KALLSYMSé¸é …時,這種方法æ‰èµ·æ•ˆã€‚如果å
[ 68.387301] RIP: 0010:test_module_init (/home/username/linux-5.10.5/test-module/test-module.c:16) test_module
-在本例中,執行的代碼是從文件「~/linux-5.10.5/test-module/test-module.cã€æ§‹å»ºçš„,
+在本例中,執行的代碼是從文件“~/linux-5.10.5/test-module/test-module.câ€æ§‹å»ºçš„,
錯誤出ç¾åœ¨ç¬¬16行的指令中。
-該腳本也會如此解碼以「Call traceã€é–‹é ­çš„部分中æ到的地å€ï¼Œè©²éƒ¨åˆ†é¡¯ç¤ºå‡ºç¾å•é¡Œçš„
+該腳本也會如此解碼以“Call traceâ€é–‹é ­çš„部分中æ到的地å€ï¼Œè©²éƒ¨åˆ†é¡¯ç¤ºå‡ºç¾å•é¡Œçš„
函數的路徑。此外,腳本還會顯示內核正在執行的代碼部分的彙編輸出。
注æ„,如果你沒法åšåˆ°é€™ä¸€é»žï¼Œåªéœ€è·³éŽé€™ä¸€æ­¥ï¼Œä¸¦åœ¨å ±å‘Šä¸­èªªæ˜ŽåŽŸå› ã€‚如果你幸é‹çš„
@@ -790,60 +785,60 @@ CONFIG_DEBUG_INFO å’Œ CONFIG_KALLSYMSé¸é …時,這種方法æ‰èµ·æ•ˆã€‚如果å
別擔心,如果您碰到的情æ³éœ€è¦é€™æ¨£åšï¼Œé–‹ç™¼äººå“¡æœƒå‘Šè¨´æ‚¨è©²æ€Žéº¼åšã€‚
-å°å›žæ­¸çš„特別關照
+å°è¿´æ­¸çš„特別關照
-----------------
- *如果您的å•é¡Œæ˜¯å›žæ­¸å•é¡Œï¼Œè«‹å„˜å¯èƒ½ç¸®å°å¼•å…¥å•é¡Œæ™‚的範åœã€‚*
+ *如果您的å•é¡Œæ˜¯è¿´æ­¸å•é¡Œï¼Œè«‹å„˜å¯èƒ½ç¸®å°å¼•å…¥å•é¡Œæ™‚的範åœã€‚*
Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這就是爲什麼他
-èªçˆ²å›žæ­¸æ˜¯ä¸å¯æŽ¥å—的,並希望看到它們被迅速修復。這就是爲什麼引入了回歸的改
-動導致的å•é¡Œè‹¥ç„¡æ³•é€šéŽå…¶ä»–æ–¹å¼å¿«é€Ÿè§£æ±ºï¼Œé€šå¸¸æœƒè¢«è¿…速撤銷。因此,報告回歸有
-點åƒã€ŒçŽ‹ç‚¸ã€ï¼Œæœƒè¿…速得到修復。但è¦åšåˆ°é€™ä¸€é»žï¼Œéœ€è¦çŸ¥é“導致回歸的變化。通常情
+èªçˆ²è¿´æ­¸æ˜¯ä¸å¯æŽ¥å—的,並希望看到它們被迅速修復。這就是爲什麼引入了迴歸的改
+動導致的å•é¡Œè‹¥ç„¡æ³•é€šéŽå…¶ä»–æ–¹å¼å¿«é€Ÿè§£æ±ºï¼Œé€šå¸¸æœƒè¢«è¿…速撤銷。因此,報告迴歸有
+點åƒâ€œçŽ‹ç‚¸â€ï¼Œæœƒè¿…速得到修復。但è¦åšåˆ°é€™ä¸€é»žï¼Œéœ€è¦çŸ¥é“導致迴歸的變化。通常情
æ³ä¸‹ï¼Œè¦ç”±å ±å‘Šè€…來追查罪é­ç¦é¦–,因爲維護者往往沒有時間或手頭設置ä¸ä¾¿ä¾†è‡ªè¡Œ
é‡ç¾å®ƒã€‚
-有一個å«åšã€ŒäºŒåˆ†ã€çš„éŽç¨‹å¯ä»¥ä¾†å°‹æ‰¾è®ŠåŒ–,這在
-「Documentation/translations/zh_TW/admin-guide/bug-bisect.rstã€æ–‡æª”中進行了詳細
+有一個å«åšâ€œäºŒåˆ†â€çš„éŽç¨‹å¯ä»¥ä¾†å°‹æ‰¾è®ŠåŒ–,這在
+Documentation/translations/zh_CN/admin-guide/bug-bisect.rst 文檔中進行了詳細
çš„æ述,這個éŽç¨‹é€šå¸¸éœ€è¦ä½ æ§‹å»ºå到二å個內核é¡åƒï¼Œæ¯æ¬¡éƒ½å˜—試在構建下一個é¡åƒ
-之å‰é‡ç¾å•é¡Œã€‚是的,這需è¦èŠ±è²»ä¸€äº›æ™‚間,但ä¸ç”¨æ“”心,它比大多數人想åƒçš„è¦å¿«å¾—多。
-多虧了「binary search二進ä½æœç´¢ã€ï¼Œé€™å°‡å¼•å°Žä½ åœ¨åŽŸå§‹ç¢¼ç®¡ç†ç³»çµ±ä¸­æ‰¾åˆ°å°Žè‡´å›žæ­¸çš„æ交。
+之å‰é‡ç¾å•é¡Œã€‚是的,這需è¦èŠ±è²»ä¸€äº›æ™‚間,但ä¸ç”¨æ“”心,它比大多數人想象的è¦å¿«å¾—多。
+多虧了“binary search二分æœç´¢â€ï¼Œé€™å°‡å¼•å°Žä½ åœ¨æºä»£ç¢¼ç®¡ç†ç³»çµ±ä¸­æ‰¾åˆ°å°Žè‡´è¿´æ­¸çš„æ交。
一旦你找到它,就在網上æœç´¢å…¶ä¸»é¡Œã€æ交ID和縮短的æ交ID(æ交IDçš„å‰12個字符)。
如果有的話,這將引導您找到關於它的ç¾æœ‰å ±å‘Šã€‚
需è¦æ³¨æ„的是,二分法需è¦ä¸€é»žç«…門,ä¸æ˜¯æ¯å€‹äººéƒ½æ‡‚得訣竅,也需è¦ç›¸ç•¶å¤šçš„努力,
ä¸æ˜¯æ¯å€‹äººéƒ½é¡˜æ„投入。儘管如此,還是強烈建議自己進行一次二分。如果你真的
-ä¸èƒ½æˆ–者ä¸æƒ³èµ°é€™æ¢è·¯ï¼Œè‡³å°‘è¦æ‰¾å‡ºæ˜¯å“ªå€‹ä¸»ç·šå…§æ ¸å¼•å…¥çš„回歸。比如說從 5.5.15
+ä¸èƒ½æˆ–者ä¸æƒ³èµ°é€™æ¢è·¯ï¼Œè‡³å°‘è¦æ‰¾å‡ºæ˜¯å“ªå€‹ä¸»ç·šå…§æ ¸å¼•å…¥çš„迴歸。比如說從 5.5.15
切æ›åˆ° 5.8.4 的時候出ç¾äº†ä¸€äº›å•é¡Œï¼Œé‚£éº¼è‡³å°‘å¯ä»¥å˜—試一下相近的所有的主線版本
(5.6ã€5.7 å’Œ 5.8)來檢查它是什麼時候出ç¾çš„。除éžä½ æƒ³åœ¨ä¸€å€‹ç©©å®šç‰ˆæˆ–長期支æŒ
-內核中找到一個回歸,å¦å‰‡è¦é¿å…測試那些編號有三段的版本(5.6.12ã€5.7.8),因
-爲那會使çµæžœé›£ä»¥è§£é‡‹ï¼Œå¯èƒ½æœƒè®“你的測試變得無用。一旦你找到了引入回歸的主è¦
+內核中找到一個迴歸,å¦å‰‡è¦é¿å…測試那些編號有三段的版本(5.6.12ã€5.7.8),因
+爲那會使çµæžœé›£ä»¥è§£é‡‹ï¼Œå¯èƒ½æœƒè®“你的測試變得無用。一旦你找到了引入迴歸的主è¦
版本,就å¯ä»¥æ”¾å¿ƒåœ°ç¹¼çºŒå ±å‘Šäº†ã€‚但請記ä½ï¼šåœ¨ä¸çŸ¥é“罪é­ç¦é¦–的情æ³ä¸‹ï¼Œé–‹ç™¼äººå“¡
是å¦èƒ½å¤ æ供幫助å–決於手頭的å•é¡Œã€‚有時他們å¯èƒ½æœƒå¾žå ±å‘Šä¸­ç¢ºèªæ˜¯ä»€éº¼å‡ºç¾äº†å•
題,並能修復它;有時他們å¯èƒ½ç„¡æ³•æ供幫助,除éžä½ é€²è¡ŒäºŒåˆ†ã€‚
-當處ç†å›žæ­¸å•é¡Œæ™‚,請確ä¿ä½ æ‰€é¢è‡¨çš„å•é¡ŒçœŸçš„是由內核引起的,而ä¸æ˜¯ç”±å…¶ä»–æ±è¥¿
+當處ç†è¿´æ­¸å•é¡Œæ™‚,請確ä¿ä½ æ‰€é¢è‡¨çš„å•é¡ŒçœŸçš„是由內核引起的,而ä¸æ˜¯ç”±å…¶ä»–æ±è¥¿
引起的,如上文所述。
-在整個éŽç¨‹ä¸­ï¼Œè«‹è¨˜ä½ï¼šåªæœ‰ç•¶èˆŠå…§æ ¸å’Œæ–°å…§æ ¸çš„é…置相似時,å•é¡Œæ‰ç®—回歸。最好
-的方法是:把é…置文件(``.config``)從舊的工作內核直接複製到你嘗試的æ¯å€‹æ–°å…§
-核版本。之後é‹è¡Œ ``make oldnoconfig`` 來調整它以é©æ‡‰æ–°ç‰ˆæœ¬çš„需è¦ï¼Œè€Œä¸å•“用
-任何新的功能,因爲那些功能也å¯èƒ½å°Žè‡´å›žæ­¸ã€‚
+在整個éŽç¨‹ä¸­ï¼Œè«‹è¨˜ä½ï¼šåªæœ‰ç•¶èˆŠå…§æ ¸å’Œæ–°å…§æ ¸çš„é…置相似時,å•é¡Œçº”算迴歸。這å¯ä»¥
+é€šéŽ ``make olddefconfig`` 來實ç¾ï¼Œè©³ç´°è§£é‡‹åƒè¦‹
+Documentation/admin-guide/reporting-regressions.rst ;它還æ供了大é‡å…¶ä»–您
+å¯èƒ½å¸Œæœ›çž­è§£çš„有關回歸的信æ¯ã€‚
-撰寫並發é€å ±å‘Š
+撰寫併發é€å ±å‘Š
---------------
*通éŽè©³ç´°æè¿°å•é¡Œä¾†é–‹å§‹ç·¨å¯«å ±å‘Šã€‚記得包括以下æ¢ç›®ï¼šæ‚¨çˆ²å¾©ç¾è€Œå®‰è£çš„最新
內核版本ã€ä½¿ç”¨çš„Linux發行版以åŠé—œæ–¼å¦‚何復ç¾è©²å•é¡Œçš„說明。如果å¯èƒ½ï¼Œå°‡å…§
- 核構建é…置(.config)和 ``dmesg`` 的輸出放在網上的æŸå€‹åœ°æ–¹ï¼Œä¸¦é€£çµåˆ°å®ƒã€‚
+ 核構建é…置(.config)和 ``dmesg`` 的輸出放在網上的æŸå€‹åœ°æ–¹ï¼Œä¸¦éˆæŽ¥åˆ°å®ƒã€‚
包å«æˆ–上傳所有其他å¯èƒ½ç›¸é—œçš„ä¿¡æ¯ï¼Œå¦‚Oops的輸出/截圖或來自 ``lspci``
的輸出。一旦你寫完了這個主è¦éƒ¨åˆ†ï¼Œè«‹åœ¨ä¸Šæ–¹æ’入一個正常長度的段è½å¿«é€Ÿæ¦‚
è¿°å•é¡Œå’Œå½±éŸ¿ã€‚å†åœ¨æ­¤ä¹‹ä¸Šæ·»åŠ ä¸€å€‹ç°¡å–®æè¿°å•é¡Œçš„å¥å­ï¼Œä»¥å¾—到人們的閱讀。
ç¾åœ¨çµ¦å‡ºä¸€å€‹æ›´çŸ­çš„æ述性標題或主題。然後就å¯ä»¥åƒMAINTAINERS文件告訴你的
- 那樣發é€æˆ–æ交報告了,除éžä½ åœ¨è™•ç†ä¸€å€‹ã€Œé«˜å„ªå…ˆç´šå•é¡Œã€ï¼šå®ƒå€‘需è¦æŒ‰ç…§ä¸‹é¢
- 「高優先級å•é¡Œçš„特殊處ç†ã€æ‰€è¿°ç‰¹åˆ¥é—œç…§ã€‚*
+ 那樣發é€æˆ–æ交報告了,除éžä½ åœ¨è™•ç†ä¸€å€‹â€œé«˜å„ªå…ˆç´šå•é¡Œâ€ï¼šå®ƒå€‘需è¦æŒ‰ç…§ä¸‹é¢
+ “高優先級å•é¡Œçš„特殊處ç†â€æ‰€è¿°ç‰¹åˆ¥é—œç…§ã€‚*
-ç¾åœ¨ä½ å·²ç¶“準備好了一切,是時候寫你的報告了。上文å‰è¨€ä¸­é€£çµçš„三篇文檔å°å¦‚何
+ç¾åœ¨ä½ å·²ç¶“準備好了一切,是時候寫你的報告了。上文å‰è¨€ä¸­éˆæŽ¥çš„三篇文檔å°å¦‚何
寫報告åšäº†éƒ¨åˆ†è§£é‡‹ã€‚這就是爲什麼本文將åªæåˆ°ä¸€äº›åŸºæœ¬çš„å…§å®¹ä»¥åŠ Linux 內核特
有的æ±è¥¿ã€‚
@@ -855,7 +850,7 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
æ¯ä»½å ±å‘Šéƒ½æ‡‰æåŠçš„事項
~~~~~~~~~~~~~~~~~~~~~~~~
-詳細æè¿°ä½ çš„å•é¡Œæ˜¯å¦‚何發生在你安è£çš„新純淨內核上的。試著包å«ä½ ä¹‹å‰å¯«çš„和優
+詳細æè¿°ä½ çš„å•é¡Œæ˜¯å¦‚何發生在你安è£çš„新純淨內核上的。試ç€åŒ…å«ä½ ä¹‹å‰å¯«çš„和優
化éŽçš„分步說明,概述你和其他人如何é‡ç¾é€™å€‹å•é¡Œï¼›åœ¨æ¥µå°‘數無法é‡ç¾çš„情æ³ä¸‹ï¼Œ
儘é‡æè¿°ä½ åšäº†ä»€éº¼ä¾†è§¸ç™¼å®ƒã€‚
@@ -864,19 +859,19 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
* ``cat /proc/version`` çš„è¼¸å‡ºï¼Œå…¶ä¸­åŒ…å« Linux 內核版本號和構建時的編譯器。
- * 機器正在é‹è¡Œçš„ Linux 發行版( ``hostnamectl | grep 「Operating System「`` )
+ * 機器正在é‹è¡Œçš„ Linux 發行版( ``hostnamectl | grep “Operating System“`` )
- * CPU 和作業系統的架構( ``uname -mi`` )
+ * CPU å’Œæ“作系統的架構( ``uname -mi`` )
- * 如果您正在處ç†å›žæ­¸ï¼Œä¸¦é€²è¡Œäº†äºŒåˆ†ï¼Œè«‹æåŠå°Žè‡´å›žæ­¸çš„變更的主題和æ交ID。
+ * 如果您正在處ç†è¿´æ­¸ï¼Œä¸¦é€²è¡Œäº†äºŒåˆ†ï¼Œè«‹æåŠå°Žè‡´è¿´æ­¸çš„變更的主題和æ交ID。
-許多情æ³ä¸‹ï¼Œè®“讀你報告的人多了解兩件事也是明智之舉:
+許多情æ³ä¸‹ï¼Œè®“讀你報告的人多瞭解兩件事也是明智之舉:
- * 用於構建 Linux 內核的é…置(「.configã€æ–‡ä»¶ï¼‰
+ * 用於構建 Linux 內核的é…置(“.configâ€æ–‡ä»¶ï¼‰
- * 內核的信æ¯ï¼Œä½ å¾ž ``dmesg`` 得到的信æ¯å¯«åˆ°ä¸€å€‹æ–‡ä»¶é‡Œã€‚確ä¿å®ƒä»¥åƒã€ŒLinux
+ * 內核的信æ¯ï¼Œä½ å¾ž ``dmesg`` 得到的信æ¯å¯«åˆ°ä¸€å€‹æ–‡ä»¶è£ã€‚確ä¿å®ƒä»¥åƒâ€œLinux
version 5.8-1 (foobar@example.com) (gcc (GCC) 10.2.1, GNU ld version
- 2.34) #1 SMP Mon Aug 3 14:54:37 UTC 2020ã€é€™æ¨£çš„行開始,如果沒有,那麼第
+ 2.34) #1 SMP Mon Aug 3 14:54:37 UTC 2020â€é€™æ¨£çš„行開始,如果沒有,那麼第
一次啓動階段的é‡è¦ä¿¡æ¯å·²ç¶“被丟棄了。在這種情æ³ä¸‹ï¼Œå¯ä»¥è€ƒæ…®ä½¿ç”¨
``journalctl -b 0 -k`` ;或者你也å¯ä»¥é‡å•“,é‡ç¾é€™å€‹å•é¡Œï¼Œç„¶å¾Œèª¿ç”¨
``dmesg`` 。
@@ -887,39 +882,39 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
* 將文件上傳到æŸå€‹å…¬é–‹çš„地方(你的網站,公共文件粘貼æœå‹™ï¼Œåœ¨
`bugzilla.kernel.org <https://bugzilla.kernel.org/>`_ 上創建的工單……),
- 並在你的報告中放上連çµã€‚ç†æƒ³æƒ…æ³ä¸‹è«‹ä½¿ç”¨å…許這些文件ä¿å­˜å¾ˆå¤šå¹´çš„地方,因
+ 並在你的報告中放上éŠæŽ¥ã€‚ç†æƒ³æƒ…æ³ä¸‹è«‹ä½¿ç”¨å…許這些文件ä¿å­˜å¾ˆå¤šå¹´çš„地方,因
爲它們å¯èƒ½åœ¨å¾ˆå¤šå¹´å¾Œå°åˆ¥äººæœ‰ç”¨ï¼›ä¾‹å¦‚ 5 年或 10 年後,一個開發者正在修改
一些代碼,而這些代碼正是爲了修復你的å•é¡Œã€‚
- * 把文件放在一邊,然後說明你會在他人回復時å†å–®ç¨ç™¼é€ã€‚åªè¦è¨˜å¾—報告發出去後,
+ * 把文件放在一邊,然後說明你會在他人回覆時å†å–®ç¨ç™¼é€ã€‚åªè¦è¨˜å¾—報告發出去後,
真正åšåˆ°é€™ä¸€é»žå°±å¯ä»¥äº†ã€‚;-)
æ供這些æ±è¥¿å¯èƒ½æ˜¯æ˜Žæ™ºçš„
~~~~~~~~~~~~~~~~~~~~~~~~~~
-根據å•é¡Œçš„ä¸åŒï¼Œä½ å¯èƒ½éœ€è¦æ供更多的背景數據。這裡有一些關於æ供什麼比較好
+根據å•é¡Œçš„ä¸åŒï¼Œä½ å¯èƒ½éœ€è¦æ供更多的背景數據。這è£æœ‰ä¸€äº›é—œæ–¼æ供什麼比較好
的建議:
- * 如果你處ç†çš„是內核的「warningã€ã€ã€ŒOOPSã€æˆ–「panicã€ï¼Œè«‹åŒ…å«å®ƒã€‚如果你ä¸èƒ½è¤‡è£½
- 粘貼它,試著用netconsole網絡終端é ç¨‹è·Ÿè¹¤æˆ–者至少æ‹ä¸€å¼µå±å¹•çš„照片。
+ * 如果你處ç†çš„是內核的“warningâ€ã€â€œOOPSâ€æˆ–“panicâ€ï¼Œè«‹åŒ…å«å®ƒã€‚如果你ä¸èƒ½è¤‡è£½
+ 粘貼它,試ç€ç”¨netconsole網絡終端é ç¨‹è·Ÿè¹¤æˆ–者至少æ‹ä¸€å¼µå±å¹•çš„照片。
- * 如果å•é¡Œå¯èƒ½èˆ‡ä½ çš„電腦硬體有關,請說明你使用的是什麼系統。例如,如果你的
- 顯å¡æœ‰å•é¡Œï¼Œè«‹æåŠå®ƒçš„製造商,顯å¡çš„型號,以åŠä½¿ç”¨çš„晶片。如果是筆記本電
- 腦,請æåŠå®ƒçš„型號å稱,但儘é‡ç¢ºä¿æ„義明確。例如「戴爾 XPS 13ã€å°±ä¸å¾ˆæ˜Žç¢ºï¼Œ
+ * 如果å•é¡Œå¯èƒ½èˆ‡ä½ çš„電腦硬件有關,請說明你使用的是什麼系統。例如,如果你的
+ 顯å¡æœ‰å•é¡Œï¼Œè«‹æåŠå®ƒçš„製造商,顯å¡çš„型號,以åŠä½¿ç”¨çš„芯片。如果是筆記本電
+ 腦,請æåŠå®ƒçš„型號å稱,但儘é‡ç¢ºä¿æ„義明確。例如“戴爾 XPS 13â€å°±ä¸å¾ˆæ˜Žç¢ºï¼Œ
因爲它å¯èƒ½æ˜¯ 2012 年的那款,那款除了看起來和ç¾åœ¨éŠ·å”®çš„沒有什麼ä¸åŒä¹‹å¤–,
兩者沒有任何共åŒä¹‹è™•ã€‚因此,在這種情æ³ä¸‹ï¼Œè¦åŠ ä¸Šæº–確的型號,例如 2019
- 年內推出的 XPS 13 型號爲「9380ã€æˆ–「7390ã€ã€‚åƒã€Œè¯æƒ³ Thinkpad T590ã€é€™æ¨£çš„åå­—
+ 年內推出的 XPS 13 型號爲“9380â€æˆ–“7390â€ã€‚åƒâ€œè¯æƒ³ Thinkpad T590â€é€™æ¨£çš„åå­—
也有些å«ç³Šä¸æ¸…:這款筆記本有帶ç¨ç«‹é¡¯å¡å’Œä¸å¸¶çš„å­åž‹è™Ÿï¼Œæ‰€ä»¥è¦å„˜é‡æ‰¾åˆ°æº–確
的型號å稱或註明主è¦éƒ¨ä»¶ã€‚
- * 說明正在使用的相關軟體。如果你在加載模塊時é‡åˆ°äº†å•é¡Œï¼Œä½ è¦èªªæ˜Žæ­£åœ¨ä½¿ç”¨çš„
+ * 說明正在使用的相關軟件。如果你在加載模塊時é‡åˆ°äº†å•é¡Œï¼Œä½ è¦èªªæ˜Žæ­£åœ¨ä½¿ç”¨çš„
kmodã€systemd å’Œ udev 的版本。如果其中一個 DRM 驅動出ç¾å•é¡Œï¼Œä½ è¦èªªæ˜Ž
libdrm å’Œ Mesa 的版本;還è¦èªªæ˜Žä½ çš„ Wayland åˆæˆå™¨æˆ– X-Server åŠå…¶é©…動。
如果你有文件系統å•é¡Œï¼Œè«‹è¨»æ˜Žç›¸æ‡‰çš„文件系統實用程åºçš„版本(e2fsprogs,
btrfs-progs, xfsprogs……)。
* 從內核中收集å¯èƒ½æœ‰ç”¨çš„é¡å¤–ä¿¡æ¯ã€‚例如, ``lspci -nn`` 的輸出å¯ä»¥å¹«åŠ©åˆ¥äºº
- 識別你使用的硬體。如果你的硬體有å•é¡Œï¼Œä½ ç”šè‡³å¯ä»¥çµ¦å‡º ``sudo lspci -vvv``
+ 識別你使用的硬件。如果你的硬件有å•é¡Œï¼Œä½ ç”šè‡³å¯ä»¥çµ¦å‡º ``sudo lspci -vvv``
çš„çµæžœï¼Œå› çˆ²å®ƒæ供了組件是如何é…置的信æ¯ã€‚å°æ–¼ä¸€äº›å•é¡Œï¼Œå¯èƒ½æœ€å¥½åŒ…å«
``/proc/cpuinfo`` , ``/proc/ioports`` , ``/proc/iomem`` ,
``/proc/modules`` 或 ``/proc/scsi/scsi`` 等文件的內容。一些å­ç³»çµ±é‚„æ
@@ -936,7 +931,7 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
~~~~~~~~~~~~~~~~~~~~~~
ç¾åœ¨ä½ å·²ç¶“準備好了報告的詳細部分,讓我們進入最é‡è¦çš„部分:開頭幾å¥ã€‚ç¾åœ¨åˆ°
-報告的最å‰é¢ï¼Œåœ¨ä½ å‰›æ‰å¯«çš„部分之å‰åŠ ä¸Šé¡žä¼¼ã€ŒThe detailed description:ã€ï¼ˆè©³ç´°
+報告的最å‰é¢ï¼Œåœ¨ä½ å‰›çº”寫的部分之å‰åŠ ä¸Šé¡žä¼¼â€œThe detailed description:â€ï¼ˆè©³ç´°
æ述)這樣的內容,並在最å‰é¢æ’入兩個新行。ç¾åœ¨å¯«ä¸€å€‹æ­£å¸¸é•·åº¦çš„段è½ï¼Œå¤§è‡´æ¦‚
述這個å•é¡Œã€‚去掉所有枯燥的細節,把é‡é»žæ”¾åœ¨è®€è€…需è¦çŸ¥é“çš„é—œéµéƒ¨åˆ†ï¼Œä»¥è®“人了
解這是怎麼回事;如果你èªçˆ²é€™å€‹ç¼ºé™·å½±éŸ¿äº†å¾ˆå¤šç”¨æˆ¶ï¼Œå°±æ一下這點來å¸å¼•å¤§å®¶é—œ
@@ -946,10 +941,10 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
è¦æ›´åŠ æŠ½è±¡ï¼Œçˆ²å ±å‘Šå¯«ä¸€å€‹æ›´çŸ­çš„主題/標題。
ç¾åœ¨ä½ å·²ç¶“寫好了這部分,請花點時間來優化它,因爲它是你的報告中最é‡è¦çš„部分:
-很多人會先讀這部分,然後æ‰æœƒæ±ºå®šæ˜¯å¦å€¼å¾—花時間閱讀其他部分。
+很多人會先讀這部分,然後纔會決定是å¦å€¼å¾—花時間閱讀其他部分。
ç¾åœ¨å°±åƒ :ref:`MAINTAINERS <maintainers>` 維護者文件告訴你的那樣發é€æˆ–æ交
-報告,除éžå®ƒæ˜¯å‰é¢æ¦‚述的那些「高優先級å•é¡Œã€ä¹‹ä¸€ï¼šåœ¨é€™ç¨®æƒ…æ³ä¸‹ï¼Œè«‹å…ˆé–±è®€ä¸‹ä¸€
+報告,除éžå®ƒæ˜¯å‰é¢æ¦‚述的那些“高優先級å•é¡Œâ€ä¹‹ä¸€ï¼šåœ¨é€™ç¨®æƒ…æ³ä¸‹ï¼Œè«‹å…ˆé–±è®€ä¸‹ä¸€
å°ç¯€ï¼Œç„¶å¾Œå†ç™¼é€å ±å‘Šã€‚
高優先級å•é¡Œçš„特殊處ç†
@@ -960,11 +955,19 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
**éžå¸¸åš´é‡çš„缺陷** :確ä¿åœ¨ä¸»é¡Œæˆ–工單標題以åŠç¬¬ä¸€æ®µä¸­æ˜Žé¡¯æ¨™å‡º severeness
(éžå¸¸åš´é‡çš„)。
-**回歸** :如果å•é¡Œæ˜¯ä¸€å€‹å›žæ­¸ï¼Œè«‹åœ¨éƒµä»¶çš„主題或缺陷跟蹤器的標題中添加
-[REGRESSION]。如果您沒有進行二分,請至少註明您測試的最新主線版本(比如 5.7)
-和出ç¾å•é¡Œçš„最新版本(比如 5.8)。如果您æˆåŠŸåœ°é€²è¡Œäº†äºŒåˆ†ï¼Œè«‹è¨»æ˜Žå°Žè‡´å›žæ­¸
-çš„æ交ID和主題。也請添加該變更的作者到你的報告中;如果您需è¦å°‡æ‚¨çš„缺陷æ交
-到缺陷跟蹤器中,請將報告以ç§äººéƒµä»¶çš„å½¢å¼è½‰ç™¼çµ¦ä»–,並註明報告æ交地點。
+**è¿´æ­¸** :報告的主題應以“[REGRESSION]â€é–‹é ­ã€‚
+
+如果您æˆåŠŸç”¨äºŒåˆ†æ³•å®šä½äº†å•é¡Œï¼Œè«‹ä½¿ç”¨å¼•å…¥è¿´æ­¸ä¹‹æ›´æ”¹çš„標題作爲主題的第二部分。
+請在報告中寫明“罪é­ç¦é¦–â€çš„æ交ID。如果未能æˆåŠŸäºŒåˆ†ï¼Œè«‹åœ¨å ±å‘Šä¸­è¬›æ˜Žæœ€å¾Œä¸€å€‹
+正常工作的版本(例如5.7)和最先發生å•é¡Œçš„版本(例如5.8-rc1)。
+
+通éŽéƒµä»¶ç™¼é€å ±å‘Šæ™‚,請抄é€Linux迴歸郵件列表(regressions@lists.linux.dev)。
+如果報告需è¦æ交到æŸå€‹web追蹤器,請繼續æ交;並在æ交後,通éŽéƒµä»¶å°‡å ±å‘Šè½‰ç™¼
+至迴歸列表;抄é€ç›¸é—œå­ç³»çµ±çš„維護人員和郵件列表。請確ä¿å ±å‘Šæ˜¯å…§è¯è½‰ç™¼çš„,ä¸è¦
+把它作爲附件。å¦å¤–請在頂部添加一個簡短的說明,在那è£å¯«ä¸Šå·¥å–®çš„網å€ã€‚
+
+在郵寄或轉發報告時,如果æˆåŠŸäºŒåˆ†ï¼Œéœ€è¦å°‡â€œç½ªé­ç¦é¦–â€çš„作者添加到收件人中;åŒæ™‚
+抄é€signed-off-byéˆä¸­çš„æ¯å€‹äººï¼Œæ‚¨å¯ä»¥åœ¨æ交消æ¯çš„末尾找到。
**安全å•é¡Œ** :å°æ–¼é€™ç¨®å•é¡Œï¼Œä½ å°‡å¿…須評估:如果細節被公開披露,是å¦æœƒå°å…¶ä»–
用戶產生短期風險。如果ä¸æœƒï¼Œåªéœ€æŒ‰ç…§æ‰€è¿°ç¹¼çºŒå ±å‘Šå•é¡Œã€‚如果有此風險,你需è¦
@@ -972,47 +975,47 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
* 如果 MAINTAINERS 文件指示您通éŽéƒµä»¶å ±å‘Šå•é¡Œï¼Œè«‹ä¸è¦æŠ„é€ä»»ä½•å…¬å…±éƒµä»¶åˆ—表。
- * 如果你應該在缺陷跟蹤器中æ交å•é¡Œï¼Œè«‹ç¢ºä¿å°‡å·¥å–®æ¨™è¨˜çˆ²ã€Œç§æœ‰ã€æˆ–「安全å•é¡Œã€ã€‚
+ * 如果你應該在缺陷跟蹤器中æ交å•é¡Œï¼Œè«‹ç¢ºä¿å°‡å·¥å–®æ¨™è¨˜çˆ²â€œç§æœ‰â€æˆ–“安全å•é¡Œâ€ã€‚
如果缺陷跟蹤器沒有æä¾›ä¿æŒå ±å‘Šç§å¯†æ€§çš„方法,那就別想了,把你的報告以ç§äºº
郵件的形å¼ç™¼é€çµ¦ç¶­è­·è€…å§ã€‚
-在這兩種情æ³ä¸‹ï¼Œéƒ½ä¸€å®šè¦å°‡å ±å‘Šç™¼åˆ° MAINTAINERS 文件中「安全è¯çµ¡ã€éƒ¨åˆ†åˆ—出的
+在這兩種情æ³ä¸‹ï¼Œéƒ½ä¸€å®šè¦å°‡å ±å‘Šç™¼åˆ° MAINTAINERS 文件中“安全è¯çµ¡â€éƒ¨åˆ†åˆ—出的
地å€ã€‚ç†æƒ³çš„情æ³æ˜¯åœ¨ç™¼é€å ±å‘Šçš„時候直接抄é€ä»–們。如果您在缺陷跟蹤器中æ交了
-報告,請將報告的文本轉發到這些地å€ï¼›ä½†è«‹åœ¨å ±å‘Šçš„頂部加上注釋,表明您æ交了
-報告,並附上工單連çµã€‚
+報告,請將報告的文本轉發到這些地å€ï¼›ä½†è«‹åœ¨å ±å‘Šçš„頂部加上註釋,表明您æ交了
+報告,並附上工單éˆæŽ¥ã€‚
-更多信æ¯è«‹åƒè¦‹ã€ŒDocumentation/translations/zh_TW/admin-guide/security-bugs.rstã€ã€‚
+更多信æ¯è«‹åƒè¦‹ Documentation/translations/zh_CN/admin-guide/security-bugs.rst 。
-發布報告後的責任
+發佈報告後的責任
------------------
*等待別人的å應,繼續推進事情,直到你能夠接å—這樣或那樣的çµæžœã€‚因此,請
公開和åŠæ™‚地回應任何詢å•ã€‚測試æ出的修復。ç©æ¥µåœ°æ¸¬è©¦ï¼šè‡³å°‘é‡æ–°æ¸¬è©¦æ¯å€‹
新主線版本的首個候é¸ç‰ˆæœ¬ï¼ˆRC),並報告你的çµæžœã€‚如果出ç¾æ‹–延,就å‹å¥½åœ°
- æ醒一下。如果你沒有得到任何幫助或者未能滿æ„,請試著自己幫助自己。*
+ æ醒一下。如果你沒有得到任何幫助或者未能滿æ„,請試ç€è‡ªå·±å¹«åŠ©è‡ªå·±ã€‚*
如果你的報告éžå¸¸å„ªç§€ï¼Œè€Œä¸”你真的很幸é‹ï¼Œé‚£éº¼æŸå€‹é–‹ç™¼è€…å¯èƒ½æœƒç«‹å³ç™¼ç¾å°Žè‡´å•
題的原因;然後他們å¯èƒ½æœƒå¯«ä¸€å€‹è£œä¸ä¾†ä¿®å¾©ã€æ¸¬è©¦å®ƒï¼Œä¸¦ç›´æŽ¥ç™¼é€çµ¦ä¸»ç·šé›†æˆï¼ŒåŒ
-時標記它以便以後回溯到需è¦å®ƒçš„穩定版和長期支æŒå…§æ ¸ã€‚那麼你需è¦åšçš„就是回復
-一å¥ã€ŒThank you very muchã€ï¼ˆéžå¸¸æ„Ÿè¬ï¼‰ï¼Œç„¶å¾Œåœ¨ç™¼å¸ƒå¾Œæ›ä¸Šä¿®å¾©å¥½çš„版本。
+時標記它以便以後回溯到需è¦å®ƒçš„穩定版和長期支æŒå…§æ ¸ã€‚那麼你需è¦åšçš„就是回覆
+一å¥â€œThank you very muchâ€ï¼ˆéžå¸¸æ„Ÿè¬ï¼‰ï¼Œç„¶å¾Œåœ¨ç™¼ä½ˆå¾Œæ›ä¸Šä¿®å¾©å¥½çš„版本。
-但這種ç†æƒ³ç‹€æ³å¾ˆå°‘發生。這就是爲什麼你把報告拿出來之後工作æ‰é–‹å§‹ã€‚ä½ è¦åšçš„
-事情è¦è¦–情æ³è€Œå®šï¼Œä½†é€šå¸¸æœƒæ˜¯ä¸‹é¢åˆ—出的事情。但在深入研究細節之å‰ï¼Œé€™è£¡æœ‰å¹¾
+但這種ç†æƒ³ç‹€æ³å¾ˆå°‘發生。這就是爲什麼你把報告拿出來之後工作纔開始。你è¦åšçš„
+事情è¦è¦–情æ³è€Œå®šï¼Œä½†é€šå¸¸æœƒæ˜¯ä¸‹é¢åˆ—出的事情。但在深入研究細節之å‰ï¼Œé€™è£æœ‰å¹¾
件é‡è¦çš„事情,你需è¦è¨˜ä½é€™éƒ¨åˆ†çš„éŽç¨‹ã€‚
關於進一步互動的一般建議
~~~~~~~~~~~~~~~~~~~~~~~~~~
-**總是公開回復** :當你在缺陷跟蹤器中æ交å•é¡Œæ™‚,一定è¦åœ¨é‚£è£¡å›žå¾©ï¼Œä¸è¦ç§ä¸‹
-è¯ç¹«ä»»ä½•é–‹ç™¼è€…。å°æ–¼éƒµä»¶å ±å‘Šï¼Œåœ¨å›žå¾©æ‚¨æ”¶åˆ°çš„任何郵件時,總是使用「全部回復ã€
+**總是公開回復** :當你在缺陷跟蹤器中æ交å•é¡Œæ™‚,一定è¦åœ¨é‚£è£å›žè¦†ï¼Œä¸è¦ç§ä¸‹
+è¯ç¹«ä»»ä½•é–‹ç™¼è€…。å°æ–¼éƒµä»¶å ±å‘Šï¼Œåœ¨å›žè¦†æ‚¨æ”¶åˆ°çš„任何郵件時,總是使用“全部回覆â€
功能。這包括帶有任何你å¯èƒ½æƒ³è¦æ·»åŠ åˆ°ä½ çš„報告中的é¡å¤–數據的郵件:進入郵件應
-用程åºã€Œå·²ç™¼é€ã€æ–‡ä»¶å¤¾ï¼Œä¸¦åœ¨éƒµä»¶ä¸Šä½¿ç”¨ã€Œå…¨éƒ¨å›žå¾©ã€ä¾†å›žå¾©å ±å‘Šã€‚這種方法å¯ä»¥ç¢ºä¿
-公共郵件列表和其他所有åƒèˆ‡è€…都能åŠæ™‚了解情æ³ï¼›å®ƒé‚„能ä¿æŒéƒµä»¶ç·šç¨‹çš„完整性,
+用程åºâ€œå·²ç™¼é€â€æ–‡ä»¶å¤¾ï¼Œä¸¦åœ¨éƒµä»¶ä¸Šä½¿ç”¨â€œå…¨éƒ¨å›žè¦†â€ä¾†å›žå¾©å ±å‘Šã€‚這種方法å¯ä»¥ç¢ºä¿
+公共郵件列表和其他所有åƒèˆ‡è€…都能åŠæ™‚瞭解情æ³ï¼›å®ƒé‚„能ä¿æŒéƒµä»¶ç·šç¨‹çš„完整性,
這å°æ–¼éƒµä»¶åˆ—表將所有相關郵件歸爲一類是éžå¸¸é‡è¦çš„。
-åªæœ‰å…©ç¨®æƒ…æ³ä¸é©åˆåœ¨ç¼ºé™·è·Ÿè¹¤å™¨æˆ–「全部回復ã€ä¸­ç™¼è¡¨è©•è«–:
+åªæœ‰å…©ç¨®æƒ…æ³ä¸é©åˆåœ¨ç¼ºé™·è·Ÿè¹¤å™¨æˆ–“全部回覆â€ä¸­ç™¼è¡¨è©•è«–:
* 有人讓你ç§ä¸‹ç™¼æ±è¥¿ã€‚
@@ -1022,32 +1025,32 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
**在請求解釋或幫助之å‰å…ˆç ”究一下** :在這部分éŽç¨‹ä¸­ï¼Œæœ‰äººå¯èƒ½æœƒå‘Šè¨´ä½ ç”¨å°šæœª
掌æ¡çš„技能åšä¸€äº›äº‹æƒ…。例如你å¯èƒ½æœƒè¢«è¦æ±‚使用一些你從未è½èªªéŽçš„測試工具;或
-者你å¯èƒ½æœƒè¢«è¦æ±‚在 Linux 內核原始碼上應用一個補ä¸ä¾†æ¸¬è©¦å®ƒæ˜¯å¦æœ‰å¹«åŠ©ã€‚在æŸäº›
-情æ³ä¸‹ï¼Œç™¼å€‹å›žå¾©è©¢å•å¦‚何åšå°±å¯ä»¥äº†ã€‚但在走這æ¢è·¯ä¹‹å‰ï¼Œå„˜é‡é€šéŽåœ¨ç¶²éš›ç¶²è·¯ä¸Šæœ
+者你å¯èƒ½æœƒè¢«è¦æ±‚在 Linux 內核æºä»£ç¢¼ä¸Šæ‡‰ç”¨ä¸€å€‹è£œä¸ä¾†æ¸¬è©¦å®ƒæ˜¯å¦æœ‰å¹«åŠ©ã€‚在æŸäº›
+情æ³ä¸‹ï¼Œç™¼å€‹å›žè¦†è©¢å•å¦‚何åšå°±å¯ä»¥äº†ã€‚但在走這æ¢è·¯ä¹‹å‰ï¼Œå„˜é‡é€šéŽåœ¨äº’è¯ç¶²ä¸Šæœ
索自行找到答案;或者考慮在其他地方詢å•å»ºè­°ã€‚比如詢å•æœ‹å‹ï¼Œæˆ–者到你平時常去
çš„èŠå¤©å®¤æˆ–論壇發帖諮詢。
**è¦æœ‰è€å¿ƒ** :如果你真的很幸é‹ï¼Œä½ å¯èƒ½æœƒåœ¨å¹¾å€‹å°æ™‚內收到å°ä½ çš„報告的答覆。
但大多數情æ³ä¸‹æœƒèŠ±è²»æ›´å¤šçš„時間,因爲維護者分散在全çƒå„地,因此å¯èƒ½åœ¨ä¸åŒçš„
-時å€â€”—在那裡他們已經享å—è‘—é é›¢éµç›¤çš„夜晚。
+時å€â€”—在那è£ä»–們已經享å—ç€é é›¢éµç›¤çš„夜晚。
一般來說,內核開發者需è¦ä¸€åˆ°äº”個工作日來回復報告。有時會花費更長的時間,因
爲他們å¯èƒ½æ­£å¿™æ–¼åˆä½µçª—å£ã€å…¶ä»–工作ã€åƒåŠ é–‹ç™¼è€…會議,或者åªæ˜¯åœ¨äº«å—一個漫長
çš„æš‘å‡ã€‚
-「高優先級的å•é¡Œã€ï¼ˆè¦‹ä¸Šé¢çš„解釋)例外:維護者應該儘快解決這些å•é¡Œï¼›é€™å°±æ˜¯çˆ²
+“高優先級的å•é¡Œâ€ï¼ˆè¦‹ä¸Šé¢çš„解釋)例外:維護者應該儘快解決這些å•é¡Œï¼›é€™å°±æ˜¯çˆ²
什麼你應該最多等待一個星期(如果是緊急的事情,則åªéœ€å…©å¤©ï¼‰ï¼Œç„¶å¾Œå†ç™¼é€å‹å¥½
çš„æ醒。
-有時維護者å¯èƒ½æ²’有åŠæ™‚回復;有時候å¯èƒ½æœƒå‡ºç¾åˆ†æ­§ï¼Œä¾‹å¦‚一個å•é¡Œæ˜¯å¦ç¬¦åˆå›žæ­¸
+有時維護者å¯èƒ½æ²’有åŠæ™‚回覆;有時候å¯èƒ½æœƒå‡ºç¾åˆ†æ­§ï¼Œä¾‹å¦‚一個å•é¡Œæ˜¯å¦ç¬¦åˆè¿´æ­¸
çš„æ¢ä»¶ã€‚在這種情æ³ä¸‹ï¼Œåœ¨éƒµä»¶åˆ—表上æ出你的顧慮,並請求其他人公開或ç§ä¸‹å›žå¾©
如何繼續推進。如果失敗了,å¯èƒ½æ‡‰è©²è®“更高級別的維護者介入。如果是 WiFi 驅動,
那就是無線維護者;如果沒有更高級別的維護者,或者其他一切努力都失敗了,那
這å¯èƒ½æ˜¯ä¸€ç¨®ç½•è¦‹çš„ã€å¯ä»¥è®“ Linus Torvalds åƒèˆ‡é€²ä¾†çš„情æ³ã€‚
-**主動測試** :æ¯ç•¶ä¸€å€‹æ–°çš„主線內核版本的第一個é ç™¼å¸ƒç‰ˆæœ¬ï¼ˆrc1)發布的時候,
+**主動測試** :æ¯ç•¶ä¸€å€‹æ–°çš„主線內核版本的第一個é ç™¼ä½ˆç‰ˆæœ¬ï¼ˆrc1)發佈的時候,
去檢查一下這個å•é¡Œæ˜¯å¦å¾—到了解決,或者是å¦æœ‰ä»€éº¼é‡è¦çš„變化。在工單中或在
-回復報告的郵件中æåŠçµæžœï¼ˆç¢ºä¿æ‰€æœ‰åƒèˆ‡è¨Žè«–的人都被抄é€ï¼‰ã€‚這將表明你的承諾
+回覆報告的郵件中æåŠçµæžœï¼ˆç¢ºä¿æ‰€æœ‰åƒèˆ‡è¨Žè«–的人都被抄é€ï¼‰ã€‚這將表明你的承諾
和你願æ„幫忙。如果å•é¡ŒæŒçºŒå­˜åœ¨ï¼Œå®ƒä¹Ÿæœƒæ醒開發者確ä¿ä»–們ä¸æœƒå¿˜è¨˜å®ƒã€‚其他一
些ä¸å®šæœŸçš„é‡æ–°æ¸¬è©¦ï¼ˆä¾‹å¦‚用rc3ã€rc5 和最終版本)也是一個好主æ„,但åªæœ‰åœ¨ç›¸é—œ
çš„æ±è¥¿ç™¼ç”Ÿè®ŠåŒ–或者你正在寫什麼æ±è¥¿çš„時候æ‰å ±å‘Šä½ çš„çµæžœã€‚
@@ -1057,10 +1060,10 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
查詢和測試請求
~~~~~~~~~~~~~~~
-如果你的報告得到了回復則需履行以下責任:
+如果你的報告得到了回覆則需履行以下責任:
**檢查與你打交é“的人** :大多數情æ³ä¸‹ï¼Œæœƒæ˜¯ç¶­è­·è€…或特定代碼å€åŸŸçš„開發人員å°
-你的報告åšå‡ºå›žæ‡‰ã€‚但由於å•é¡Œé€šå¸¸æ˜¯å…¬é–‹å ±å‘Šçš„,所以回復的å¯èƒ½æ˜¯ä»»ä½•äººâ€”—包括
+你的報告åšå‡ºå›žæ‡‰ã€‚但由於å•é¡Œé€šå¸¸æ˜¯å…¬é–‹å ±å‘Šçš„,所以回覆的å¯èƒ½æ˜¯ä»»ä½•äººâ€”—包括
那些想è¦å¹«å¿™çš„人,但最後å¯èƒ½æœƒç”¨ä»–們的å•é¡Œæˆ–請求引導你完全å離軌é“。這很少
發生,但這是快速上網æœæœçœ‹ä½ æ­£åœ¨èˆ‡èª°äº’動是明智之舉的許多原因之一。通éŽé€™æ¨£
åšï¼Œä½ ä¹Ÿå¯ä»¥çŸ¥é“你的報告是å¦è¢«æ­£ç¢ºçš„人è½åˆ°ï¼Œå› çˆ²å¦‚果討論沒有導致滿æ„çš„å•é¡Œ
@@ -1086,63 +1089,63 @@ Linux 首席開發者 Linus Torvalds èªçˆ² Linux 內核永é ä¸æ‡‰æƒ¡åŒ–,這
報告到é”時,維護者剛剛離開éµç›¤ä¸€æ®µæ™‚間,或者有更é‡è¦çš„事情è¦è™•ç†ã€‚在寫æ醒
信的時候,è¦å–„æ„地å•ä¸€ä¸‹ï¼Œæ˜¯å¦é‚„需è¦ä½ é€™é‚Šæ供什麼來讓事情推進下去。如果報
告是通éŽéƒµä»¶ç™¼å‡ºä¾†çš„,那就在郵件的第一行回覆你的åˆå§‹éƒµä»¶ï¼ˆè¦‹ä¸Šæ–‡ï¼‰ï¼Œå…¶ä¸­åŒ…
-括下方的原始報告的完整引用:這是少數幾種情æ³ä¸‹ï¼Œé€™æ¨£çš„「TOFUã€ï¼ˆText Over,
+括下方的原始報告的完整引用:這是少數幾種情æ³ä¸‹ï¼Œé€™æ¨£çš„“TOFUâ€ï¼ˆText Over,
Fullquote Under文字在上,完整引用在下)是正確的åšæ³•ï¼Œå› çˆ²é€™æ¨£æ‰€æœ‰çš„收件人都
會以é©ç•¶çš„é †åºç«‹å³è®“細節到手頭上來。
-在æ醒之後,å†ç­‰ä¸‰å‘¨çš„回覆。如果你ä»ç„¶æ²’有得到é©ç•¶çš„å饋,你首先應該é‡æ–°è€ƒ
+在æ醒之後,å†ç­‰ä¸‰é€±çš„回覆。如果你ä»ç„¶æ²’有得到é©ç•¶çš„å饋,你首先應該é‡æ–°è€ƒ
慮你的方法。你是å¦å¯èƒ½å˜—試接觸了錯誤的人?是ä¸æ˜¯å ±å‘Šä¹Ÿè¨±ä»¤äººå感或者太混亂,
以至於人們決定完全é é›¢å®ƒï¼ŸæŽ’除這些因素的最好方法是:把報告給一兩個熟悉
FLOSS å•é¡Œå ±å‘Šçš„人看,詢å•ä»–們的æ„見。åŒæ™‚徵求他們關於如何繼續推進的建議。
-這å¯èƒ½æ„味著:準備一份更好的報告,讓這些人在你發出去之å‰å°å®ƒé€²è¡Œå¯©æŸ¥ã€‚這樣
+這å¯èƒ½æ„味ç€ï¼šæº–備一份更好的報告,讓這些人在你發出去之å‰å°å®ƒé€²è¡Œå¯©æŸ¥ã€‚這樣
的方法完全å¯ä»¥ï¼›åªéœ€èªªæ˜Žé€™æ˜¯é—œæ–¼é€™å€‹å•é¡Œçš„第二份改進的報告,並附上第一份報
-告的連çµã€‚
+å‘Šçš„éˆæŽ¥ã€‚
如果報告是æ°ç•¶çš„,你å¯ä»¥ç™¼é€ç¬¬äºŒå°æ醒信;在其中詢å•çˆ²ä»€éº¼å ±å‘Šæ²’有得到任何
-回復。第二å°æ醒郵件的好時機是在新 Linux 內核版本的首個é ç™¼å¸ƒç‰ˆæœ¬ï¼ˆ'rc1')
-發布後ä¸ä¹…,因爲無論如何你都應該在那個時候é‡æ–°æ¸¬è©¦ä¸¦æ供狀態更新(見上文)。
+回覆。第二å°æ醒郵件的好時機是在新 Linux 內核版本的首個é ç™¼ä½ˆç‰ˆæœ¬ï¼ˆ'rc1')
+發佈後ä¸ä¹…,因爲無論如何你都應該在那個時候é‡æ–°æ¸¬è©¦ä¸¦æ供狀態更新(見上文)。
-如果第二次æ醒的çµæžœåˆåœ¨ä¸€å‘¨å…§æ²’有任何å應,å¯ä»¥å˜—試è¯ç¹«ä¸Šç´šç¶­è­·è€…è©¢å•æ„見:
+如果第二次æ醒的çµæžœåˆåœ¨ä¸€é€±å…§æ²’有任何å應,å¯ä»¥å˜—試è¯ç¹«ä¸Šç´šç¶­è­·è€…è©¢å•æ„見:
å³ä½¿å†å¿™çš„維護者在這時候也至少應該發éŽæŸç¨®ç¢ºèªã€‚
記ä½è¦åšå¥½å¤±æœ›çš„準備:ç†æƒ³ç‹€æ³ä¸‹ç¶­è­·è€…最好å°æ¯ä¸€å€‹å•é¡Œå ±å‘Šåšå‡ºå›žæ‡‰ï¼Œä½†ä»–們
-åªæœ‰ç¾©å‹™è§£æ±ºä¹‹å‰åˆ—出的「高優先級å•é¡Œã€ã€‚所以,如果你得到的回覆是「è¬è¬ä½ çš„報告,
-我目å‰æœ‰æ›´é‡è¦çš„å•é¡Œè¦è™•ç†ï¼Œåœ¨å¯é è¦‹çš„未來沒有時間去研究這個å•é¡Œã€ï¼Œé‚£è«‹ä¸
+åªæœ‰ç¾©å‹™è§£æ±ºä¹‹å‰åˆ—出的“高優先級å•é¡Œâ€ã€‚所以,如果你得到的回覆是“è¬è¬ä½ çš„報告,
+我目å‰æœ‰æ›´é‡è¦çš„å•é¡Œè¦è™•ç†ï¼Œåœ¨å¯é è¦‹çš„未來沒有時間去研究這個å•é¡Œâ€ï¼Œé‚£è«‹ä¸
è¦å¤ªæ²®å–ªã€‚
也有å¯èƒ½åœ¨ç¼ºé™·è·Ÿè¹¤å™¨æˆ–列表中進行了一些討論之後,什麼都沒有發生,æ醒也無助
於激勵大家進行修復。這種情æ³å¯èƒ½æ˜¯æ¯€æ»…性的,但在 Linux 內核開發中確實會發生。
-這些和其他得ä¸åˆ°å¹«åŠ©çš„原因在本文çµå°¾è™•çš„「爲什麼有些å•é¡Œåœ¨è¢«å ±å‘Šå¾Œæ²’有得到
-任何回應或者ä»ç„¶æ²’有修復ã€ä¸­é€²è¡Œäº†è§£é‡‹ã€‚
+這些和其他得ä¸åˆ°å¹«åŠ©çš„原因在本文çµå°¾è™•çš„“爲什麼有些å•é¡Œåœ¨è¢«å ±å‘Šå¾Œæ²’有得到
+任何回應或者ä»ç„¶æ²’有修復â€ä¸­é€²è¡Œäº†è§£é‡‹ã€‚
如果你沒有得到任何幫助或å•é¡Œæœ€çµ‚沒有得到解決,ä¸è¦æ²®å–ªï¼šLinux 內核是 FLOSS,
-因此你ä»ç„¶å¯ä»¥è‡ªå·±å¹«åŠ©è‡ªå·±ã€‚例如,你å¯ä»¥è©¦è‘—找到其他å—影響的人,和他們一
+因此你ä»ç„¶å¯ä»¥è‡ªå·±å¹«åŠ©è‡ªå·±ã€‚例如,你å¯ä»¥è©¦ç€æ‰¾åˆ°å…¶ä»–å—影響的人,和他們一
èµ·åˆä½œä¾†è§£æ±ºé€™å€‹å•é¡Œã€‚這樣的團隊å¯ä»¥ä¸€èµ·æº–備一份新的報告,æ到團隊有多少人,
爲什麼你們èªçˆ²é€™æ˜¯æ‡‰è©²å¾—到解決的事情。也許你們還å¯ä»¥ä¸€èµ·ç¸®å°ç¢ºåˆ‡åŽŸå› æˆ–引
-入回歸的變化,這往往會使修復更容易。而且如果é‹æ°£å¥½çš„話,團隊中å¯èƒ½æœƒæœ‰æ‡‚點
-編程的人,也許能寫出一個修複方案。
+入迴歸的變化,這往往會使修復更容易。而且如果é‹æ°£å¥½çš„話,團隊中å¯èƒ½æœƒæœ‰æ‡‚點
+編程的人,也許能寫出一個修復方案。
-「報告穩定版和長期支æŒå…§æ ¸ç·šçš„回歸ã€çš„åƒè€ƒ
+“報告穩定版和長期支æŒå…§æ ¸ç·šçš„è¿´æ­¸â€çš„åƒè€ƒ
------------------------------------------
-本å°ç¯€æ供了在穩定版和長期支æŒå…§æ ¸ç·šä¸­é¢å°å›žæ­¸æ™‚需è¦åŸ·è¡Œçš„步驟的詳細信æ¯ã€‚
+本å°ç¯€æ供了在穩定版和長期支æŒå…§æ ¸ç·šä¸­é¢å°è¿´æ­¸æ™‚需è¦åŸ·è¡Œçš„步驟的詳細信æ¯ã€‚
確ä¿ç‰¹å®šç‰ˆæœ¬ç·šä»ç„¶å—支æŒ
~~~~~~~~~~~~~~~~~~~~~~~~~
*檢查內核開發人員是å¦ä»ç„¶ç¶­è­·ä½ é—œå¿ƒçš„Linux內核版本線:去 kernel.org çš„
- 首é ï¼Œç¢ºä¿æ­¤ç‰¹å®šç‰ˆæœ¬ç·šçš„最新版沒有「[EOL]ã€æ¨™è¨˜ã€‚*
+ 首é ï¼Œç¢ºä¿æ­¤ç‰¹å®šç‰ˆæœ¬ç·šçš„最新版沒有“[EOL]â€æ¨™è¨˜ã€‚*
大多數內核版本線åªæ”¯æŒä¸‰å€‹æœˆå·¦å³ï¼Œå› çˆ²å»¶é•·ç¶­è­·æ™‚間會帶來相當多的工作。因此,
æ¯å¹´åªæœƒé¸æ“‡ä¸€å€‹ç‰ˆæœ¬ä¾†æ”¯æŒè‡³å°‘兩年(通常是六年)。這就是爲什麼你需è¦æª¢æŸ¥
內核開發者是å¦é‚„支æŒä½ é—œå¿ƒçš„版本線。
-注æ„,如果 `kernel.org <https://kernel.org/>`_ 在首é ä¸Šåˆ—出了兩個「穩定ã€ç‰ˆæœ¬ï¼Œ
+注æ„,如果 `kernel.org <https://kernel.org/>`_ 在首é ä¸Šåˆ—出了兩個“穩定â€ç‰ˆæœ¬ï¼Œ
你應該考慮切æ›åˆ°è¼ƒæ–°çš„版本,而忘掉較舊的版本:å°å®ƒçš„支æŒå¯èƒ½å¾ˆå¿«å°±æœƒçµæŸã€‚
-然後,它將被標記爲「生命周期çµæŸã€ï¼ˆEOL)。é”到這個程度的版本線ä»ç„¶æœƒåœ¨
-`kernel.org <https://kernel.org/>`_ 首é ä¸Šè¢«é¡¯ç¤ºä¸€å…©å‘¨ï¼Œä½†ä¸é©åˆç”¨æ–¼æ¸¬è©¦å’Œ
+然後,它將被標記爲“生命週期çµæŸâ€ï¼ˆEOL)。é”到這個程度的版本線ä»ç„¶æœƒåœ¨
+`kernel.org <https://kernel.org/>`_ 首é ä¸Šè¢«é¡¯ç¤ºä¸€å…©é€±ï¼Œä½†ä¸é©åˆç”¨æ–¼æ¸¬è©¦å’Œ
報告。
æœç´¢ç©©å®šç‰ˆéƒµä»¶åˆ—表
@@ -1158,57 +1161,63 @@ FLOSS å•é¡Œå ±å‘Šçš„人看,詢å•ä»–們的æ„見。åŒæ™‚徵求他們關於å¦
用最新版本復ç¾å•é¡Œ
~~~~~~~~~~~~~~~~~~~
- *從特定的版本線安è£æœ€æ–°ç‰ˆæœ¬ä½œçˆ²ç´”淨內核。確ä¿é€™å€‹å…§æ ¸æ²’有被汙染,並且ä»
- 然存在å•é¡Œï¼Œå› çˆ²å•é¡Œå¯èƒ½å·²ç¶“在那裡被修復了。*
+ *從特定的版本線安è£æœ€æ–°ç‰ˆæœ¬ä½œçˆ²ç´”淨內核。確ä¿é€™å€‹å…§æ ¸æ²’有被污染,並且ä»
+ 然存在å•é¡Œï¼Œå› çˆ²å•é¡Œå¯èƒ½å·²ç¶“在那è£è¢«ä¿®å¾©äº†ã€‚*
在投入更多時間到這個éŽç¨‹ä¸­ä¹‹å‰ï¼Œä½ è¦æª¢æŸ¥é€™å€‹å•é¡Œæ˜¯å¦åœ¨ä½ é—œæ³¨çš„版本線的最新
-版本中已經得到了修復。這個內核需è¦æ˜¯ç´”淨的,在å•é¡Œç™¼ç”Ÿä¹‹å‰ä¸æ‡‰è©²è¢«æ±™æŸ“,正
+版本中已經得到了修復。這個內核需è¦æ˜¯ç´”淨的,在å•é¡Œç™¼ç”Ÿä¹‹å‰ä¸æ‡‰è©²è¢«æ±¡æŸ“,正
如上é¢å·²ç¶“在測試主線的éŽç¨‹ä¸­è©³ç´°ä»‹ç´¹éŽçš„一樣。
-您是å¦æ˜¯ç¬¬ä¸€æ¬¡æ³¨æ„到供應商內核的回歸?供應商的更改å¯èƒ½æœƒç™¼ç”Ÿè®ŠåŒ–。你需è¦é‡æ–°
+您是å¦æ˜¯ç¬¬ä¸€æ¬¡æ³¨æ„到供應商內核的迴歸?供應商的更改å¯èƒ½æœƒç™¼ç”Ÿè®ŠåŒ–。你需è¦é‡æ–°
檢查排除來這個å•é¡Œã€‚當您從5.10.4-vendor.42更新到5.10.5-vendor.43時,記錄æ壞
çš„ä¿¡æ¯ã€‚然後在測試了å‰ä¸€æ®µä¸­æ‰€è¿°çš„最新5.10版本之後,檢查Linux 5.10.4的普通版本
-是å¦ä¹Ÿå¯ä»¥æ­£å¸¸å·¥ä½œã€‚如果å•é¡Œåœ¨é‚£è£¡å‡ºç¾ï¼Œé‚£å°±ä¸ç¬¦åˆä¸Šæ¸¸å›žæ­¸çš„æ¢ä»¶ï¼Œæ‚¨éœ€è¦åˆ‡æ›
+是å¦ä¹Ÿå¯ä»¥æ­£å¸¸å·¥ä½œã€‚如果å•é¡Œåœ¨é‚£è£å‡ºç¾ï¼Œé‚£å°±ä¸ç¬¦åˆä¸Šæ¸¸è¿´æ­¸çš„æ¢ä»¶ï¼Œæ‚¨éœ€è¦åˆ‡æ›
回主é€æ­¥æŒ‡å—來報告å•é¡Œã€‚
-報告回歸
+報告迴歸
~~~~~~~~~~
- *å‘Linux穩定版郵件列表發é€ä¸€å€‹ç°¡çŸ­çš„å•é¡Œå ±å‘Š(stable@vger.kernel.org)。
- 大致æè¿°å•é¡Œï¼Œä¸¦è§£é‡‹å¦‚何復ç¾ã€‚講清楚首個出ç¾å•é¡Œçš„版本和最後一個工作正常
- 的版本。然後等待進一步的指示。*
+ *å‘Linux穩定版郵件列表發é€ä¸€å€‹ç°¡çŸ­çš„å•é¡Œå ±å‘Š(stable@vger.kernel.org)並
+ 抄é€Linux迴歸郵件列表(regressions@lists.linux.dev);如果你懷疑是由æŸ
+ å­ç³»çµ±å¼•èµ·çš„,請抄é€å…¶ç¶­è­·äººå“¡å’Œå­ç³»çµ±éƒµä»¶åˆ—表。大致æè¿°å•é¡Œï¼Œä¸¦è§£é‡‹å¦‚
+ 何復ç¾ã€‚講清楚首個出ç¾å•é¡Œçš„版本和最後一個工作正常的版本。然後等待進一
+ 步的指示。*
-當報告在穩定版或長期支æŒå…§æ ¸ç·šå…§ç™¼ç”Ÿçš„回歸(例如在從5.10.4更新到5.10.5時),
-一份簡短的報告足以快速報告å•é¡Œã€‚å› æ­¤åªéœ€è¦ç²—略的æ述。
+當報告在穩定版或長期支æŒå…§æ ¸ç·šå…§ç™¼ç”Ÿçš„迴歸(例如在從5.10.4更新到5.10.5時),
+一份簡短的報告足以快速報告å•é¡Œã€‚å› æ­¤åªéœ€å‘穩定版和迴歸郵件列表發é€ç²—略的æè¿°ï¼›
+ä¸éŽå¦‚果你懷疑æŸå­ç³»çµ±å°Žè‡´æ­¤å•é¡Œçš„話,請一併抄é€å…¶ç¶­è­·äººå“¡å’Œå­ç³»çµ±éƒµä»¶åˆ—表,
+這會加快進程。
-但是請注æ„,如果您能夠指明引入å•é¡Œçš„確切版本,這將å°é–‹ç™¼äººå“¡æœ‰å¾ˆå¤§å¹«åŠ©ã€‚å› æ­¤
-如果有時間的話,請嘗試使用普通內核找到該版本。讓我們å‡è¨­ç™¼è¡Œç‰ˆç™¼å¸ƒLinux內核
+請注æ„,如果您能夠指明引入å•é¡Œçš„確切版本,這將å°é–‹ç™¼äººå“¡æœ‰å¾ˆå¤§å¹«åŠ©ã€‚å› æ­¤
+如果有時間的話,請嘗試使用普通內核找到該版本。讓我們å‡è¨­ç™¼è¡Œç‰ˆç™¼ä½ˆLinux內核
5.10.5到5.10.8的更新時發生了故障。那麼按照上é¢çš„指示,去檢查該版本線中的最新
內核,比如5.10.9。如果å•é¡Œå‡ºç¾ï¼Œè«‹å˜—試普通5.10.5,以確ä¿ä¾›æ‡‰å•†æ‡‰ç”¨çš„補ä¸ä¸æœƒ
干擾。如果å•é¡Œæ²’有出ç¾ï¼Œé‚£éº¼å˜—試5.10.7,然後直到5.10.8或5.10.6(å–決於çµæžœï¼‰
找到第一個引入å•é¡Œçš„版本。在報告中寫明這一點,並指出5.10.9ä»ç„¶å­˜åœ¨æ•…障。
-å‰ä¸€æ®µåŸºæœ¬ç²—略地概述了「二分ã€æ–¹æ³•ã€‚一旦報告出來,您å¯èƒ½æœƒè¢«è¦æ±‚åšä¸€å€‹æ­£ç¢ºçš„
+å‰ä¸€æ®µåŸºæœ¬ç²—略地概述了“二分â€æ–¹æ³•ã€‚一旦報告出來,您å¯èƒ½æœƒè¢«è¦æ±‚åšä¸€å€‹æ­£ç¢ºçš„
報告,因爲它å…許精確地定ä½å°Žè‡´å•é¡Œçš„確切更改(然後很容易被æ¢å¾©ä»¥å¿«é€Ÿä¿®å¾©å•é¡Œï¼‰ã€‚
-因此如果時間å…許,考慮立å³é€²è¡Œé©ç•¶çš„二分。有關如何詳細信æ¯ï¼Œè«‹åƒé–±ã€Œå°å›žæ­¸çš„
-特別關照ã€éƒ¨åˆ†å’Œæ–‡æª”「Documentation/translations/zh_TW/admin-guide/bug-bisect.rstã€ã€‚
+因此如果時間å…許,考慮立å³é€²è¡Œé©ç•¶çš„二分。有關如何詳細信æ¯ï¼Œè«‹åƒé–±â€œå°è¿´æ­¸çš„
+特別關照â€éƒ¨åˆ†å’Œæ–‡æª” Documentation/translations/zh_CN/admin-guide/bug-bisect.rst 。
+如果æˆåŠŸäºŒåˆ†çš„話,請將“罪é­ç¦é¦–â€çš„作者添加到收件人中;åŒæ™‚抄é€æ‰€æœ‰åœ¨
+signed-off-byéˆä¸­çš„人,您å¯ä»¥åœ¨æ交消æ¯çš„末尾找到。
-「報告僅在舊內核版本線中發生的å•é¡Œã€çš„åƒè€ƒ
-------------------------------------------
+“報告僅在舊內核版本線中發生的å•é¡Œâ€çš„åƒè€ƒ
+----------------------------------------
-本節詳細介紹了如果無法用主線內核é‡ç¾å•é¡Œï¼Œä½†å¸Œæœ›åœ¨èˆŠç‰ˆæœ¬ç·šï¼ˆåˆç¨±ç©©å®šç‰ˆå…§æ ¸å’Œ
+本節詳細介紹瞭如果無法用主線內核é‡ç¾å•é¡Œï¼Œä½†å¸Œæœ›åœ¨èˆŠç‰ˆæœ¬ç·šï¼ˆåˆç¨±ç©©å®šç‰ˆå…§æ ¸å’Œ
長期支æŒå…§æ ¸ï¼‰ä¸­ä¿®å¾©å•é¡Œæ™‚需è¦æŽ¡å–的步驟。
有些修復太複雜
~~~~~~~~~~~~~~~
*è«‹åšå¥½æº–備,接下來的幾個步驟å¯èƒ½ç„¡æ³•åœ¨èˆŠç‰ˆæœ¬ä¸­è§£æ±ºå•é¡Œï¼šä¿®å¾©å¯èƒ½å¤ªå¤§æˆ–
- 太冒險,無法移æ¤åˆ°é‚£è£¡ã€‚*
+ 太冒險,無法移æ¤åˆ°é‚£è£ã€‚*
å³ä½¿æ˜¯å¾®å°çš„ã€çœ‹ä¼¼æ˜Žé¡¯çš„代碼變化,有時也會帶來新的ã€å®Œå…¨æ„想ä¸åˆ°çš„å•é¡Œã€‚ç©©
定版和長期支æŒå…§æ ¸çš„維護者éžå¸¸æ¸…楚這一點,因此他們åªå°é€™äº›å…§æ ¸é€²è¡Œç¬¦åˆ
-「Documentation/translations/zh_TW/process/stable-kernel-rules.rstã€ä¸­æ‰€åˆ—出的
+Documentation/translations/zh_CN/process/stable-kernel-rules.rst 中所列出的
è¦å‰‡çš„修改。
複雜或有風險的修改ä¸ç¬¦åˆæ¢ä»¶ï¼Œå› æ­¤åªèƒ½æ‡‰ç”¨æ–¼ä¸»ç·šã€‚其他的修復很容易被回溯到
@@ -1220,7 +1229,7 @@ FLOSS å•é¡Œå ±å‘Šçš„人看,詢å•ä»–們的æ„見。åŒæ™‚徵求他們關於å¦
通用準備
~~~~~~~~~~
- *執行上é¢ã€Œå ±å‘Šåƒ…在舊內核版本線中發生的å•é¡Œã€ä¸€ç¯€ä¸­çš„å‰ä¸‰å€‹æ­¥é©Ÿã€‚*
+ *執行上é¢â€œå ±å‘Šåƒ…在舊內核版本線中發生的å•é¡Œâ€ä¸€ç¯€ä¸­çš„å‰ä¸‰å€‹æ­¥é©Ÿã€‚*
您需è¦åŸ·è¡Œæœ¬æŒ‡å—å¦ä¸€ç¯€ä¸­å·²ç¶“æ述的幾個步驟。這些步驟將讓您:
@@ -1242,21 +1251,21 @@ FLOSS å•é¡Œå ±å‘Šçš„人看,詢å•ä»–們的æ„見。åŒæ™‚徵求他們關於å¦
在許多情æ³ä¸‹ï¼Œä½ æ‰€è™•ç†çš„å•é¡Œæœƒç™¼ç”Ÿåœ¨ä¸»ç·šä¸Šï¼Œä½†å·²åœ¨ä¸»ç·šä¸Šå¾—到了解決。修正它
çš„æ交也需è¦è¢«å›žæº¯æ‰èƒ½è§£æ±ºé€™å€‹å•é¡Œã€‚這就是爲什麼你è¦æœç´¢å®ƒæˆ–任何相關討論。
- * 首先嘗試在存放 Linux 內核原始碼的 Git 倉庫中找到修復。你å¯ä»¥é€šéŽ
+ * 首先åšè©¦åœ¨å­˜æ”¾ Linux 內核æºä»£ç¢¼çš„ Git 倉庫中找到修復。你å¯ä»¥é€šéŽ
`kernel.org 上的網é 
<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/>`_
或 `GitHub 上的é¡åƒ <https://github.com/torvalds/linux>`_ 來實ç¾ï¼›å¦‚果你
有一個本地克隆,你也å¯ä»¥åœ¨å‘½ä»¤è¡Œç”¨ ``git log --grep=<pattern>`` 來æœç´¢ã€‚
- 如果你找到了修復,請查看æ交消æ¯çš„尾部是å¦åŒ…å«äº†é¡žä¼¼é€™æ¨£çš„「穩定版標籤ã€ï¼š
+ 如果你找到了修復,請查看æ交消æ¯çš„尾部是å¦åŒ…å«äº†é¡žä¼¼é€™æ¨£çš„“穩定版標籤â€ï¼š
Cc: <stable@vger.kernel.org> # 5.4+
åƒä¸Šé¢é€™è¡Œï¼Œé–‹ç™¼è€…標記了安全修復å¯ä»¥å›žå‚³åˆ° 5.4 åŠä»¥å¾Œçš„版本。大多數情æ³
- 下,它會在兩周內被應用到那裡,但有時需è¦æ›´é•·çš„時間。
+ 下,它會在兩週內被應用到那è£ï¼Œä½†æœ‰æ™‚需è¦æ›´é•·çš„時間。
* 如果æ交沒有告訴你任何æ±è¥¿ï¼Œæˆ–者你找ä¸åˆ°ä¿®å¾©ï¼Œè«‹å†æ‰¾æ‰¾é—œæ–¼é€™å€‹å•é¡Œçš„討論。
- 用你最喜歡的æœå°‹å¼•æ“Žæœç´¢ç¶²çµ¡ï¼Œä»¥åŠ `Linux kernel developers mailing
+ 用你最喜歡的æœç´¢å¼•æ“Žæœç´¢ç¶²çµ¡ï¼Œä»¥åŠ `Linux kernel developers mailing
list 內核開發者郵件列表 <https://lore.kernel.org/lkml/>`_ 的檔案。也å¯ä»¥
閱讀上é¢çš„ `定ä½å°Žè‡´å•é¡Œçš„內核å€åŸŸ` 一節,然後按照說明找到導致å•é¡Œçš„å­ç³»
統:它的缺陷跟蹤器或郵件列表存檔中å¯èƒ½æœ‰ä½ è¦æ‰¾çš„答案。
@@ -1286,41 +1295,41 @@ FLOSS å•é¡Œå ±å‘Šçš„人看,詢å•ä»–們的æ„見。åŒæ™‚徵求他們關於å¦
爲什麼有些å•é¡Œåœ¨å ±å‘Šå¾Œæ²’有任何回應或ä»æœªè§£æ±ºï¼Ÿ
===============================================
-ç•¶å‘ Linux 開發者報告å•é¡Œæ™‚,è¦æ³¨æ„åªæœ‰ã€Œé«˜å„ªå…ˆç´šçš„å•é¡Œã€ï¼ˆå›žæ­¸ã€å®‰å…¨å•é¡Œã€åš´
+ç•¶å‘ Linux 開發者報告å•é¡Œæ™‚,è¦æ³¨æ„åªæœ‰â€œé«˜å„ªå…ˆç´šçš„å•é¡Œâ€ï¼ˆè¿´æ­¸ã€å®‰å…¨å•é¡Œã€åš´
é‡å•é¡Œï¼‰æ‰ä¸€å®šæœƒå¾—到解決。如果維護者或其他人都失敗了,Linus Torvalds 他自己
會確ä¿é€™ä¸€é»žã€‚他們和其他內核開發者也會解決很多其他å•é¡Œã€‚但是è¦çŸ¥é“,有時他
們也會ä¸èƒ½æˆ–ä¸é¡˜å¹«å¿™ï¼›æœ‰æ™‚甚至沒有人發報告給他們。
最好的解釋就是那些內核開發者常常是在業餘時間爲 Linux 內核åšå‡ºè²¢ç»ã€‚內核中的
-ä¸å°‘驅動程åºéƒ½æ˜¯ç”±é€™æ¨£çš„程å¼è¨­è¨ˆå¸«ç·¨å¯«çš„,往往åªæ˜¯å› çˆ²ä»–們想讓自己的硬體å¯ä»¥åœ¨
-自己喜歡的作業系統上使用。
+ä¸å°‘驅動程åºéƒ½æ˜¯ç”±é€™æ¨£çš„程åºå“¡ç·¨å¯«çš„,往往åªæ˜¯å› çˆ²ä»–們想讓自己的硬件å¯ä»¥åœ¨
+自己喜歡的æ“作系統上使用。
-這些程å¼è¨­è¨ˆå¸«å¤§å¤šæ•¸æ™‚候會很樂æ„修復別人報告的å•é¡Œã€‚但是沒有人å¯ä»¥å¼·è¿«ä»–們這樣
+這些程åºå“¡å¤§å¤šæ•¸æ™‚候會很樂æ„修復別人報告的å•é¡Œã€‚但是沒有人å¯ä»¥å¼·è¿«ä»–們這樣
åšï¼Œå› çˆ²ä»–們是自願貢ç»çš„。
還有一些情æ³ä¸‹ï¼Œé€™äº›é–‹ç™¼è€…真的很想解決一個å•é¡Œï¼Œä½†å»ä¸èƒ½è§£æ±ºï¼šæœ‰æ™‚他們缺ä¹
-硬體編程文檔來解決å•é¡Œã€‚這種情æ³å¾€å¾€ç”±æ–¼å…¬é–‹çš„文檔太簡陋,或者驅動程åºæ˜¯é€š
+硬件編程文檔來解決å•é¡Œã€‚這種情æ³å¾€å¾€ç”±æ–¼å…¬é–‹çš„文檔太簡陋,或者驅動程åºæ˜¯é€š
éŽé€†å‘工程編寫的。
-業餘開發者é²æ—©ä¹Ÿæœƒä¸å†é—œå¿ƒæŸé©…動。也許他們的測試硬體壞了,被更高級的玩æ„å–
-代了,或者是太è€äº†ä»¥è‡³æ–¼åªèƒ½åœ¨è¨ˆç®—æ©Ÿåšç‰©é¤¨è£¡æ‰¾åˆ°ã€‚有時開發者根本就ä¸é—œå¿ƒä»–
+業餘開發者é²æ—©ä¹Ÿæœƒä¸å†é—œå¿ƒæŸé©…動。也許他們的測試硬件壞了,被更高級的玩æ„å–
+代了,或者是太è€äº†ä»¥è‡³æ–¼åªèƒ½åœ¨è¨ˆç®—æ©Ÿåšç‰©é¤¨è£æ‰¾åˆ°ã€‚有時開發者根本就ä¸é—œå¿ƒä»–
們的代碼和 Linux 了,因爲在他們的生活中一些ä¸åŒçš„æ±è¥¿è®Šå¾—æ›´é‡è¦äº†ã€‚在æŸäº›æƒ…
æ³ä¸‹ï¼Œæ²’有人願æ„接手維護者的工作——也沒有人å¯ä»¥è¢«å¼·è¿«ï¼Œå› çˆ²å° Linux 內核的貢
ç»æ˜¯è‡ªé¡˜çš„。然而被éºæ£„的驅動程åºä»ç„¶å­˜åœ¨æ–¼å…§æ ¸ä¸­ï¼šå®ƒå€‘å°äººå€‘ä»ç„¶æœ‰ç”¨ï¼Œåˆªé™¤
-它們å¯èƒ½å°Žè‡´å›žæ­¸ã€‚
+它們å¯èƒ½å°Žè‡´è¿´æ­¸ã€‚
å°æ–¼é‚£äº›çˆ² Linux 內核工作而ç²å¾—報酬的開發者來說,情æ³ä¸¦æ²’有什麼ä¸åŒã€‚這些人
ç¾åœ¨è²¢ç»äº†å¤§éƒ¨åˆ†çš„變更。但是他們的僱主é²æ—©ä¹Ÿæœƒåœæ­¢é—œæ³¨ä»–們的代碼或者讓程åº
-員專注於其他事情。例如,硬體廠商主è¦é€šéŽéŠ·å”®æ–°ç¡¬é«”來賺錢;因此,他們中的ä¸
+員專注於其他事情。例如,硬件廠商主è¦é€šéŽéŠ·å”®æ–°ç¡¬ä»¶ä¾†è³ºéŒ¢ï¼›å› æ­¤ï¼Œä»–們中的ä¸
少人並沒有投入太多時間和精力來維護他們多年å‰å°±åœæ­¢éŠ·å”®çš„æ±è¥¿çš„ Linux 內核驅
動。ä¼æ¥­ç´š Linux 發行商往往æŒçºŒç¶­è­·çš„時間比較長,但在新版本中往往會把å°è€èˆŠ
-和稀有硬體的支æŒæ”¾åœ¨ä¸€é‚Šï¼Œä»¥é™åˆ¶ç¯„åœã€‚一旦公å¸æ‹‹æ£„了一些代碼,往往由業餘貢
+和稀有硬件的支æŒæ”¾åœ¨ä¸€é‚Šï¼Œä»¥é™åˆ¶ç¯„åœã€‚一旦公å¸æ‹‹æ£„了一些代碼,往往由業餘貢
ç»è€…接手,但正如上é¢æ到的:他們é²æ—©ä¹Ÿæœƒæ”¾ä¸‹ä»£ç¢¼ã€‚
優先級是一些å•é¡Œæ²’有被修復的å¦ä¸€å€‹åŽŸå› ï¼Œå› çˆ²ç¶­è­·è€…相當多的時候是被迫設置這
些優先級的,因爲在 Linux 上工作的時間是有é™çš„。å°æ–¼æ¥­é¤˜æ™‚間或者僱主給予他們
的開發人員用於上游內核維護工作的時間也是如此。有時維護人員也會被報告淹沒,
-å³ä½¿ä¸€å€‹é©…動程åºå¹¾ä¹Žå®Œç¾Žåœ°å·¥ä½œã€‚爲了ä¸è¢«å®Œå…¨çºä½ï¼Œç¨‹å¼è¨­è¨ˆå¸«å¯èƒ½åˆ¥ç„¡é¸æ“‡ï¼Œåªèƒ½
+å³ä½¿ä¸€å€‹é©…動程åºå¹¾ä¹Žå®Œç¾Žåœ°å·¥ä½œã€‚爲了ä¸è¢«å®Œå…¨çºä½ï¼Œç¨‹åºå“¡å¯èƒ½åˆ¥ç„¡é¸æ“‡ï¼Œåªèƒ½
å°å•é¡Œå ±å‘Šé€²è¡Œå„ªå…ˆç´šæŽ’åºè€Œæ‹’絕其中的一些報告。
ä¸éŽé€™äº›éƒ½ä¸ç”¨å¤ªéŽæ“”心,很多驅動都有ç©æ¥µçš„維護者,他們å°å„˜å¯èƒ½å¤šçš„解決å•é¡Œ
@@ -1330,8 +1339,32 @@ FLOSS å•é¡Œå ±å‘Šçš„人看,詢å•ä»–們的æ„見。åŒæ™‚徵求他們關於å¦
çµæŸèªž
=======
-與其他å…è²»/自由&é–‹æºè»Ÿé«”(Free/Libre & Open Source Software,FLOSS)相比,
-å‘ Linux 內核開發者報告å•é¡Œæ˜¯å¾ˆé›£çš„:這個文檔的長度和複雜性以åŠå­—裡行間的內
+與其他å…è²»/自由&é–‹æºè»Ÿä»¶ï¼ˆFree/Libre & Open Source Software,FLOSS)相比,
+å‘ Linux 內核開發者報告å•é¡Œæ˜¯å¾ˆé›£çš„:這個文檔的長度和複雜性以åŠå­—è£è¡Œé–“çš„å…§
涵都說明了這一點。但目å‰å°±æ˜¯é€™æ¨£äº†ã€‚這篇文字的主è¦ä½œè€…希望通éŽè¨˜éŒ„ç¾ç‹€ä¾†çˆ²
以後改善這種狀æ³æ‰“下一些基礎。
+
+..
+ end-of-content
+..
+ This English version of this document is maintained by Thorsten Leemhuis
+ <linux@leemhuis.info>. If you spot a typo or small mistake, feel free to
+ let him know directly and he'll fix it. For translation problems, please
+ contact with translators. You are free to do the same in a mostly informal
+ way if you want to contribute changes to the text, but for copyright
+ reasons please CC linux-doc@vger.kernel.org and "sign-off" your
+ contribution as Documentation/process/submitting-patches.rst outlines in
+ the section "Sign your work - the Developer's Certificate of Origin".
+..
+ This text is available under GPL-2.0+ or CC-BY-4.0, as stated at the top
+ of the file. If you want to distribute this text under CC-BY-4.0 only,
+ please use "The Linux kernel developers" for author attribution and link
+ this as source:
+ https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst
+..
+ Note: Only the content of this RST file as found in the Linux kernel sources
+ is available under CC-BY-4.0, as versions of this text that were processed
+ (for example by the kernel's build system) might contain content taken from
+ files which use a more restrictive license.
+
diff --git a/Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst b/Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst
new file mode 100644
index 000000000000..d7dcb2a26564
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst
@@ -0,0 +1,371 @@
+.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
+.. ã€é‡åˆ†ç™¼ä¿¡æ¯åƒè¦‹æœ¬æ–‡ä»¶çµå°¾ã€‘
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/reporting-regressions.rst
+
+:譯者:
+
+ å³æƒ³æˆ Wu XiangCheng <bobwxc@email.cn>
+
+
+============
+報告迴歸å•é¡Œ
+============
+
+“*我們拒絕出ç¾è¿´æ­¸*â€æ˜¯Linux內核開發的首è¦è¦å‰‡ï¼›Linux的發起者和領è»é–‹ç™¼è€…Linus
+Torvalds立下了此è¦å‰‡ä¸¦ç¢ºä¿å®ƒè¢«è½å¯¦ã€‚
+
+本文檔æ述了這æ¢è¦å‰‡å°ç”¨æˆ¶çš„æ„義,以åŠLinux內核開發模型如何確ä¿è§£æ±ºæ‰€æœ‰è¢«å ±å‘Š
+的迴歸;關於內核開發者如何處ç†çš„æ–¹é¢åƒè¦‹ Documentation/process/handling-regressions.rst 。
+
+
+本文é‡é»žï¼ˆäº¦å³â€œå¤ªé•·ä¸çœ‹â€ï¼‰
+==========================
+
+#. 如果æŸç¨‹åºåœ¨åŽŸå…ˆçš„Linux內核上é‹è¡Œè‰¯å¥½ï¼Œä½†åœ¨è¼ƒæ–°ç‰ˆæœ¬ä¸Šæ•ˆæžœæ›´å·®ã€æˆ–者根本ä¸
+ 能用,那麼你就碰見迴歸å•é¡Œäº†ã€‚注æ„,新內核需è¦ä½¿ç”¨é¡žä¼¼é…置編譯;更多相關細
+ 節åƒè¦‹ä¸‹æ–¹ã€‚
+
+#. 按照 Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 中
+ 所說的報告你的å•é¡Œï¼Œè©²æ–‡æª”已經包å«äº†æ‰€æœ‰é—œæ–¼è¿´æ­¸çš„é‡è¦æ–¹é¢ï¼Œçˆ²äº†æ–¹ä¾¿èµ·è¦‹ä¹Ÿ
+ 複製到了下é¢ã€‚兩個é‡é»žï¼šåœ¨å ±å‘Šä¸»é¡Œä¸­ä½¿ç”¨â€œ[REGRESSION]â€é–‹é ­ä¸¦æŠ„é€æˆ–轉發到
+ `迴歸郵件列表 <https://lore.kernel.org/regressions/>`_
+ (regressions@lists.linux.dev)。
+
+#. å¯é¸ä½†æ˜¯å»ºè­°ï¼šåœ¨ç™¼é€æˆ–轉發報告時,指明該回歸發生的起點,以便Linux內核迴歸
+ 追蹤機器人“regzbotâ€å¯ä»¥è¿½è¹¤æ­¤å•é¡Œ::
+
+ #regzbot introduced v5.13..v5.14-rc1
+
+
+與用戶相關的所有Linux內核迴歸細節
+=================================
+
+
+基本é‡é»ž
+--------
+
+
+什麼是“迴歸â€ä»¥åŠä»€éº¼æ˜¯â€œç„¡è¿´æ­¸è¦å‰‡â€ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+如果æŸç¨‹åº/實例在原先的Linux內核上é‹è¡Œè‰¯å¥½ï¼Œä½†åœ¨è¼ƒæ–°ç‰ˆæœ¬ä¸Šæ•ˆæžœæ›´å·®ã€æˆ–者根本
+ä¸èƒ½ç”¨ï¼Œé‚£éº¼ä½ å°±ç¢°è¦‹è¿´æ­¸å•é¡Œäº†ã€‚“無迴歸è¦å‰‡â€ä¸å…許出ç¾é€™ç¨®æƒ…æ³ã€‚如果å¶ç„¶ç™¼
+生了,導致å•é¡Œçš„開發者應當迅速修復å•é¡Œã€‚
+
+也就是說,若Linux 5.13中的WiFi驅動程åºé‹è¡Œè‰¯å¥½ï¼Œä½†æ˜¯åœ¨5.14版本上å»ä¸èƒ½ç”¨ã€é€Ÿ
+度明顯變慢或出ç¾éŒ¯èª¤ï¼Œé‚£å°±å‡ºç¾äº†è¿´æ­¸ã€‚如果æŸæ­£å¸¸å·¥ä½œçš„應用程åºçªç„¶åœ¨æ–°å…§æ ¸ä¸Š
+出ç¾ä¸ç©©å®šï¼Œé€™ä¹Ÿæ˜¯è¿´æ­¸ï¼›é€™äº›å•é¡Œå¯èƒ½æ˜¯ç”±æ–¼procfsã€sysfs或Linuxæ供給用戶空間
+軟件的許多其他接å£ä¹‹ä¸€çš„變化。但請記ä½ï¼Œå‰è¿°ä¾‹å­ä¸­çš„5.14需è¦ä½¿ç”¨é¡žä¼¼æ–¼5.13çš„
+é…置構建。這å¯ä»¥ç”¨ ``make olddefconfig`` 實ç¾ï¼Œè©³ç´°è§£é‡‹è¦‹ä¸‹ã€‚
+
+注æ„本節第一å¥è©±ä¸­çš„“實例â€ï¼šå³ä½¿é–‹ç™¼è€…需è¦éµå¾ªâ€œç„¡è¿´æ­¸â€è¦å‰‡ï¼Œä½†ä»å¯è‡ªç”±åœ°æ”¹
+變內核的任何方é¢ï¼Œç”šè‡³æ˜¯å°Žå‡ºåˆ°ç”¨æˆ¶ç©ºé–“çš„API或ABI,åªè¦åˆ¥ç ´å£žç¾æœ‰çš„應用程åºæˆ–
+用例。
+
+還需注æ„,“無迴歸â€è¦å‰‡åªé™åˆ¶å…§æ ¸æ供給用戶空間的接å£ã€‚它ä¸é©ç”¨æ–¼å…§æ ¸å…§éƒ¨æŽ¥
+å£ï¼Œæ¯”如一些外部開發的驅動程åºç”¨ä¾†æ’入鉤å­åˆ°å…§æ ¸çš„模塊API。
+
+如何報告迴歸?
+~~~~~~~~~~~~~~
+
+åªéœ€æŒ‰ç…§ Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 中
+所說的報告你的å•é¡Œï¼Œè©²æ–‡æª”已經包å«äº†è¦é»žã€‚下é¢å¹¾é»žæ¦‚述了一下åªåœ¨è¿´æ­¸ä¸­é‡è¦çš„
+æ–¹é¢ï¼š
+
+ * 在檢查å¯åŠ å…¥è¨Žè«–çš„ç¾æœ‰å ±å‘Šæ™‚,別忘了æœç´¢ `Linux迴歸郵件列表
+ <https://lore.kernel.org/regressions/>`_ å’Œ `regzbot網é ç•Œé¢
+ <https://linux-regtracking.leemhuis.info/regzbot/>`_ 。
+
+ * 在報告主題的開頭加上“[REGRESSION]â€ã€‚
+
+ * 在你的報告中明確最後一個正常工作的內核版本和首個出å•é¡Œçš„版本。如若å¯èƒ½ï¼Œ
+ 用二分法嘗試找出導致迴歸的變更,更多細節見下。
+
+ * 記得把報告發到Linux迴歸郵件列表(regressions@lists.linux.dev)。
+
+ * 如果通éŽéƒµä»¶å ±å‘Šè¿´æ­¸ï¼Œè«‹æŠ„é€å›žæ­¸åˆ—表。
+
+ * 如果你使用æŸäº›ç¼ºé™·è¿½è¹¤å™¨å ±å‘Šè¿´æ­¸ï¼Œè«‹é€šéŽéƒµä»¶è½‰ç™¼å·²æ交的報告到迴歸列表,
+ 並抄é€ç¶­è­·è€…以åŠå‡ºå•é¡Œçš„相關å­ç³»çµ±çš„郵件列表。
+
+ 如果是穩定版或長期支æŒç‰ˆç³»åˆ—(如v5.15.3…v5.15.5)的迴歸,請記得抄é€
+ `Linux穩定版郵件列表 <https://lore.kernel.org/stable/>`_ (stable@vger.kernel.org)。
+
+ 如果你æˆåŠŸåœ°åŸ·è¡Œäº†äºŒåˆ†ï¼Œè«‹æŠ„é€è‚‡äº‹æ交的信æ¯ä¸­æ‰€æœ‰ç°½äº†â€œSigned-off-by:â€çš„人。
+
+在抄é€ä½ çš„報告到列表時,也請記得通知å‰è¿°çš„Linux內核迴歸追蹤機器人。åªéœ€åœ¨éƒµä»¶
+中包å«å¦‚下片段::
+
+ #regzbot introduced: v5.13..v5.14-rc1
+
+Regzbot會就將你的郵件視爲在æŸå€‹ç‰¹å®šç‰ˆæœ¬å€é–“的迴歸報告。上例中å³linux v5.13ä»
+然正常,而Linux 5.14-rc1是首個您é‡åˆ°å•é¡Œçš„版本。如果你執行了二分以查找導致回
+歸的æ交,請使用指定肇事æ交的id代替::
+
+ #regzbot introduced: 1f2e3d4c5d
+
+添加這樣的“regzbot命令â€å°ä½ æ˜¯æœ‰å¥½è™•çš„,它會確ä¿å ±å‘Šä¸æœƒè¢«å¿½ç•¥ã€‚如果你çœç•¥äº†
+它,Linux內核的迴歸跟蹤者會把你的迴歸告訴regzbot,åªè¦ä½ ç™¼é€äº†ä¸€å€‹å‰¯æœ¬åˆ°è¿´æ­¸
+郵件列表。但是迴歸跟蹤者åªæœ‰ä¸€å€‹äººï¼Œæœ‰æ™‚ä¸å¾—ä¸ä¼‘æ¯æˆ–甚至å¶çˆ¾äº«å—å¯ä»¥é é›¢é›»è…¦
+的時光(è½èµ·ä¾†å¾ˆç˜‹ç‹‚)。因此,ä¾è³´æ­¤äººæ‰‹å‹•å°‡å›žæ­¸æ·»åŠ åˆ° `已追蹤且尚未解決的
+Linux內核迴歸列表 <https://linux-regtracking.leemhuis.info/regzbot/>`_ 和
+regzbot發é€çš„æ¯é€±è¿´æ­¸å ±å‘Šï¼Œå¯èƒ½æœƒå‡ºç¾å»¶é²ã€‚ 這樣的延誤會導致Linus Torvalds
+在決定“繼續開發還是發佈新版本?â€æ™‚忽略嚴é‡çš„迴歸。
+
+真的修復了所有的迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+幾乎所有都是,åªè¦å¼•èµ·å•é¡Œçš„變更(肇事æ交)被å¯é å®šä½ã€‚也有些迴歸å¯ä»¥ä¸ç”¨é€™
+樣,但通常是必須的。
+
+誰需è¦æ‰¾å‡ºè¿´æ­¸çš„根本原因?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+å—影響代碼å€åŸŸçš„開發者應該自行嘗試定ä½å•é¡Œæ‰€åœ¨ã€‚但僅é ä»–們的努力往往是ä¸å¯
+能åšåˆ°çš„,很多å•é¡Œåªç™¼ç”Ÿåœ¨é–‹ç™¼è€…的無法接觸的其他特定外部環境中——例如特定的
+硬件平臺ã€å›ºä»¶ã€Linux發行版ã€ç³»çµ±çš„é…置或應用程åºã€‚這就是爲什麼最終往往是報
+告者定ä½è‚‡äº‹æ交;有時用戶甚至需è¦å†é‹è¡Œé¡å¤–測試以查明確切的根本原因。開發
+者應該æ供建議和å¯èƒ½çš„幫助,以使普通用戶更容易完æˆè©²æµç¨‹ã€‚
+
+如何找到罪é­ç¦é¦–?
+~~~~~~~~~~~~~~~~~~
+
+如 Documentation/translations/zh_CN/admin-guide/reporting-issues.rst (簡è¦ï¼‰
+和 Documentation/translations/zh_CN/admin-guide/bug-bisect.rst (詳細)中所
+述,執行二分。è½èµ·ä¾†å·¥ä½œé‡å¾ˆå¤§ï¼Œä½†å¤§éƒ¨åˆ†æƒ…æ³ä¸‹å¾ˆå¿«å°±èƒ½æ‰¾åˆ°ç½ªé­ç¦é¦–。如果這很
+困難或å¯é åœ°é‡ç¾å•é¡Œå¾ˆè€—時,請考慮與其他å—影響的用戶åˆä½œï¼Œä¸€èµ·ç¸®å°æœç´¢ç¯„åœã€‚
+
+當出ç¾è¿´æ­¸æ™‚我å¯ä»¥å‘誰尋求建議?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+發é€éƒµä»¶åˆ°è¿´æ­¸éƒµä»¶åˆ—表(regressions@lists.linux.dev)åŒæ™‚抄é€Linux內核的迴歸
+跟蹤者(regressions@leemhuis.info);如果å•é¡Œéœ€è¦ä¿å¯†è™•ç†ï¼Œå¯ä»¥çœç•¥åˆ—表。
+
+
+關於迴歸的更多細節
+------------------
+
+
+“無迴歸è¦å‰‡â€çš„目標是什麼?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+用戶應該放心å‡ç´šå…§æ ¸ç‰ˆæœ¬ï¼Œè€Œä¸å¿…擔心有程åºå¯èƒ½å´©æ½°ã€‚這符åˆå…§æ ¸é–‹ç™¼è€…的利益,
+å¯ä»¥ä½¿æ›´æ–°æœ‰å¸å¼•åŠ›ï¼šä»–們ä¸å¸Œæœ›ç”¨æˆ¶åœç•™åœ¨åœæ­¢ç¶­è­·æˆ–超éŽä¸€å¹´åŠçš„穩定/長期Linux
+版本系列上。這也符åˆæ‰€æœ‰äººçš„利益,因爲 `那些系列å¯èƒ½å«æœ‰å·²çŸ¥çš„缺陷ã€å®‰å…¨å•é¡Œ
+或其他後續版本已經修復的å•é¡Œ
+<http://www.kroah.com/log/blog/2018/08/24/what-stable-kernel-should-i-use/>`_ 。
+此外,內核開發者希望使用戶測試最新的é ç™¼è¡Œç‰ˆæˆ–常è¦ç™¼è¡Œç‰ˆè®Šå¾—簡單而有å¸å¼•åŠ›ã€‚
+這åŒæ¨£ç¬¦åˆæ‰€æœ‰äººçš„利益,如果新版本出來後很快就有相關報告,會使追蹤和修復å•é¡Œ
+更容易。
+
+實際中“無迴歸â€è¦å‰‡çœŸçš„å¯è¡Œå—Žï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+這ä¸æ˜¯å¥çŽ©ç¬‘話,請見Linux創建者和主è¦é–‹ç™¼äººå“¡Linus Torvalds在郵件列表中的許
+多發言,其中一些在 Documentation/process/handling-regressions.rst 中被引用。
+
+æ­¤è¦å‰‡çš„例外情æ³æ¥µçˆ²ç½•è¦‹ï¼›ä¹‹å‰ç•¶é–‹ç™¼è€…èªçˆ²æŸå€‹ç‰¹å®šçš„情æ³æœ‰å¿…è¦æ´å¼•ä¾‹å¤–時,
+基本都被證明錯了。
+
+誰來確ä¿â€œç„¡è¿´æ­¸â€è¢«è½å¯¦ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+照看和支æ’樹的å­ç³»çµ±ç¶­è­·è€…應該關心這一點——例如,Linus Torvalds之於主線,
+Greg Kroah-Hartman等人之於å„種穩定/長期系列。
+
+他們都得到了別人的幫助,以確ä¿è¿´æ­¸å ±å‘Šä¸æœƒè¢«éºæ¼ã€‚其中之一是Thorsten
+Leemhuis,他目å‰æ“”ä»»Linux內核的“迴歸跟蹤者â€ï¼›çˆ²äº†åšå¥½é€™é …工作,他使用了
+regzbot——Linux內核迴歸跟蹤機器人。所以這就是爲什麼è¦æŠ„é€æˆ–轉發你的報告到
+迴歸郵件列表來通知這些人,已經最好在你的郵件中包å«â€œregzbot命令â€ä¾†ç«‹å³è¿½è¹¤å®ƒã€‚
+
+迴歸通常多久能修復?
+~~~~~~~~~~~~~~~~~~~~
+
+開發者應該儘快修復任何被報告的迴歸,以æä¾›åŠæ™‚爲å—影響的用戶æ供解決方案,並
+防止更多用戶é‡åˆ°å•é¡Œï¼›ç„¶è€Œï¼Œé–‹ç™¼äººå“¡éœ€è¦èŠ±è¶³å¤ çš„時間和注æ„力確ä¿è¿´æ­¸ä¿®å¾©ä¸æœƒ
+造æˆé¡å¤–çš„æ害。
+
+因此,答案å–決於å„種因素,如迴歸的影響ã€å­˜åœ¨æ™‚長或出ç¾æ–¼å“ªå€‹Linux版本系列。
+但最終,大多數的迴歸應該在兩週內修復。
+
+當å•é¡Œå¯ä»¥é€šéŽå‡ç´šæŸäº›è»Ÿä»¶è§£æ±ºæ™‚,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+基本都是。如果開發人員告訴您其他情æ³ï¼Œè«‹è«®è©¢ä¸Šè¿°è¿´æ­¸è·Ÿè¹¤è€…。
+
+當新內核變慢或能耗增加,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+是的,但有一些差別。在微型基準測試中變慢5%ä¸å¤ªå¯èƒ½è¢«è¦–爲迴歸,除éžå®ƒä¹Ÿæœƒå°
+廣泛基準測試的çµæžœç”¢ç”Ÿè¶…éŽ1%的影響。如果有疑å•ï¼Œè«‹å°‹æ±‚建議。
+
+當更新Linux時外部內核模塊崩潰了,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ä¸ï¼Œå› çˆ²â€œç„¡è¿´æ­¸â€è¦å‰‡åƒ…é™æ–¼Linux內核æ供給用戶空間的接å£å’Œæœå‹™ã€‚因此,它ä¸åŒ…括
+構建或é‹è¡Œå¤–部開發的內核模塊,因爲它們在內核空間中é‹è¡Œèˆ‡æŽ›é€²å…§æ ¸ä½¿ç”¨çš„內部接
+å£å¶çˆ¾æœƒè®ŠåŒ–。
+
+如何處ç†å®‰å…¨ä¿®å¾©å¼•èµ·çš„迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+在極爲罕見的情æ³ä¸‹ï¼Œå®‰å…¨å•é¡Œç„¡æ³•åœ¨ä¸å¼•èµ·è¿´æ­¸çš„情æ³ä¸‹ä¿®å¾©ï¼›é€™äº›ä¿®å¾©éƒ½è¢«æ”¾æ£„了,
+因爲它們終究會引起å•é¡Œã€‚幸é‹çš„是這種兩難境地基本都å¯ä»¥é¿å…,å—影響å€åŸŸçš„主è¦
+開發者以åŠLinus Torvalds本人通常都會努力在ä¸å¼•å…¥è¿´æ­¸çš„情æ³ä¸‹è§£æ±ºå®‰å…¨å•é¡Œã€‚
+
+如果你ä»ç„¶é¢è‡¨æ­¤ç¨®æƒ…æ³ï¼Œè«‹æŸ¥çœ‹éƒµä»¶åˆ—表檔案是å¦æœ‰äººç›¡åŠ›é¿å…éŽè¿´æ­¸ã€‚如果沒有,
+請報告它;如有疑å•ï¼Œè«‹å¦‚上所述尋求建議。
+
+當修復迴歸時ä¸å¯é¿å…會引入å¦ä¸€å€‹ï¼Œå¦‚何處ç†ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+很éºæ†¾é€™ç¨®äº‹ç¢ºå¯¦æœƒå‡ºç¾ï¼Œä½†å¹¸é‹çš„是並ä¸ç¶“常出ç¾ï¼›å¦‚果發生了,å—影響代碼å€çš„資
+深開發者應當調查該å•é¡Œä»¥æ‰¾åˆ°é¿å…迴歸的解決方法,至少é¿å…它們的影響。如果你é‡
+到這樣的情æ³ï¼Œå¦‚上所述:檢查之å‰çš„討論是å¦æœ‰äººå·²ç¶“盡了最大努力,如有疑å•è«‹å°‹
+求建議。
+
+å°æ示:如果人們在æ¯å€‹é–‹ç™¼é€±æœŸä¸­å®šæœŸçµ¦å‡ºä¸»ç·šé ç™¼ä½ˆï¼ˆå³v5.15-rc1或-rc3)以供
+測試,則å¯ä»¥é¿å…這種情æ³ã€‚爲了更好地解釋,å¯ä»¥è¨­æƒ³ä¸€å€‹åœ¨Linux v5.14å’Œv5.15-rc1
+之間集æˆçš„更改,該更改導致了迴歸,但åŒæ™‚是應用於5.15-rc1的其他改進的強ä¾è³´ã€‚
+如果有人在5.15發佈之å‰å°±ç™¼ç¾ä¸¦å ±å‘Šäº†é€™å€‹å•é¡Œï¼Œé‚£éº¼æ‰€æœ‰æ›´æ”¹éƒ½å¯ä»¥ç›´æŽ¥æ’¤éŠ·ï¼Œå¾ž
+而解決迴歸å•é¡Œã€‚而就在幾天或幾周後,此解決方案變æˆäº†ä¸å¯èƒ½ï¼Œå› çˆ²ä¸€äº›è»Ÿä»¶å¯èƒ½
+已經開始ä¾è³´æ–¼å¾ŒçºŒæ›´æ”¹ä¹‹ä¸€ï¼šæ’¤éŠ·æ‰€æœ‰æ›´æ”¹å°‡å°Žè‡´ä¸Šè¿°ç”¨æˆ¶è»Ÿä»¶å‡ºç¾è¿´æ­¸ï¼Œé€™æ˜¯ä¸å¯
+接å—的。
+
+若我所ä¾è³´çš„功能在數月å‰è¢«ç§»é™¤äº†ï¼Œæ˜¯è¿´æ­¸å—Žï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+是的,但如å‰ç¯€æ‰€è¿°ï¼Œé€šå¸¸å¾ˆé›£ä¿®å¾©æ­¤é¡žè¿´æ­¸ã€‚因此需è¦é€æ¡ˆè™•ç†ã€‚這也是定期測試主
+ç·šé ç™¼ä½ˆå°æ‰€æœ‰äººæœ‰å¥½è™•çš„å¦ä¸€å€‹åŽŸå› ã€‚
+
+如果我似乎是唯一å—影響的人,是å¦ä»é©ç”¨â€œç„¡è¿´æ­¸â€è¦å‰‡ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+é©ç”¨ï¼Œä½†åƒ…é™æ–¼å¯¦éš›ä½¿ç”¨ï¼šLinux開發人員希望能夠自由地å–消那些åªèƒ½åœ¨é–£æ¨“å’Œåšç‰©
+館中找到的硬件的支æŒã€‚
+
+請注æ„,有時爲了å–得進展,ä¸å¾—ä¸å‡ºç¾è¿´æ­¸â€”—後者也是防止Linuxåœæ»¯ä¸å‰æ‰€å¿…需
+的。因此如果迴歸所影響的用戶很少,那麼爲了他們和其他人更大的利益,還是讓事情
+éŽåŽ»å§ã€‚尤其是存在æŸç¨®è¦é¿è¿´æ­¸çš„簡單方法,例如更新一些軟件或者使用專門爲此目
+的創建的內核åƒæ•¸ã€‚
+
+è¿´æ­¸è¦å‰‡æ˜¯å¦ä¹Ÿé©ç”¨æ–¼staging樹中的代碼?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ä¸ï¼Œåƒè¦‹ `é©ç”¨æ–¼æ‰€æœ‰staging代碼é…ç½®é¸é …的幫助文本
+<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/staging/Kconfig>`_ ,
+其早已è²æ˜Ž::
+
+ 請注æ„:這些驅動正在ç©æ¥µé–‹ç™¼ä¸­ï¼Œå¯èƒ½ç„¡æ³•æ­£å¸¸å·¥ä½œï¼Œä¸¦å¯èƒ½åŒ…å«æœƒåœ¨ä¸ä¹…çš„
+ 將來發生變化的用戶接å£ã€‚
+
+雖然staging開發人員通常堅æŒâ€œç„¡è¿´æ­¸â€çš„原則,但有時爲了å–得進展也會é•èƒŒå®ƒã€‚這就
+是爲什麼當staging樹的WiFi驅動被基本推倒é‡ä¾†æ™‚,有些用戶ä¸å¾—ä¸è™•ç†è¿´æ­¸ï¼ˆé€šå¸¸å¯
+以忽略)。
+
+爲什麼較新版本必須“使用相似é…置編譯â€ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+因爲Linux內核開發人員有時會集æˆå·²çŸ¥çš„會導致迴歸的變更,但使它們æˆçˆ²å¯é¸çš„,並
+在內核的默èªé…置下ç¦ç”¨å®ƒå€‘。這一技巧å…許進步,å¦å‰‡â€œç„¡è¿´æ­¸â€è¦å‰‡å°‡å°Žè‡´åœæ»¯ã€‚
+
+例如,試想一個新的å¯ä»¥é˜»æ­¢æƒ¡æ„軟件濫用æŸå€‹å…§æ ¸çš„接å£çš„安全特性,åŒæ™‚åˆéœ€è¦æ»¿è¶³
+å¦ä¸€å€‹å¾ˆç½•è¦‹çš„應用程åºã€‚上述的方法å¯ä½¿å…©æ–¹éƒ½æ»¿æ„:使用這些應用程åºçš„人å¯ä»¥é—œé–‰
+新的安全功能,而其他ä¸æœƒé‡åˆ°éº»ç…©çš„人å¯ä»¥å•“用它。
+
+如何創建與舊內核相似的é…置?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+用一個已知良好的內核啓動機器,並用 ``make olddefconfig`` é…置新版的Linux。這
+會讓內核的構建腳本從正在é‹è¡Œçš„內核中摘錄é…置文件(“.configâ€æ–‡ä»¶ï¼‰ï¼Œä½œçˆ²å³å°‡ç·¨
+譯的新版本的基礎é…置;åŒæ™‚將所有新的é…ç½®é¸é …設爲默èªå€¼ï¼Œä»¥ç¦ç”¨å¯èƒ½å°Žè‡´è¿´æ­¸çš„
+新功能。
+
+如何報告在é ç·¨è­¯çš„普通內核中發ç¾çš„迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+您需è¦ç¢ºä¿æ–°çš„內核是用與舊版相似的é…置編譯(見上文),因爲那些構建它們的人å¯
+能啓用了一些已知的與新內核ä¸å…¼å®¹çš„特性。如有疑å•ï¼Œè«‹å‘內核的æ供者報告å•é¡Œä¸¦
+尋求建議。
+
+
+用“regzbotâ€è¿½è¹¤è¿´æ­¸çš„更多信æ¯
+-----------------------------
+
+什麼是迴歸追蹤?爲啥我需è¦é—œå¿ƒå®ƒï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+åƒâ€œç„¡è¿´æ­¸â€é€™æ¨£çš„è¦å‰‡éœ€è¦æœ‰äººä¾†ç¢ºä¿å®ƒå€‘被éµå®ˆï¼Œå¦å‰‡æœƒè¢«æœ‰æ„/ç„¡æ„打破。歷å²è­‰
+明瞭這一點å°æ–¼Linux內核開發也é©ç”¨ã€‚這就是爲什麼Linux內核的迴歸跟蹤者Thorsten
+Leemhuis,,和å¦ä¸€äº›äººç›¡åŠ›é—œæ³¨æ‰€æœ‰çš„迴歸直到他們解決。他們從未爲此ç²å¾—報酬,
+因此這項工作是在盡最大努力的基礎上完æˆçš„。
+
+爲什麼/如何使用機器人追蹤Linux內核迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+由於Linux內核開發éŽç¨‹çš„分佈å¼å’Œé¬†æ•£çµæ§‹ï¼Œå®Œå…¨æ‰‹å‹•è·Ÿè¹¤è¿´æ­¸å·²ç¶“被證明是相當困難
+的。因此Linux內核的迴歸跟蹤者開發了regzbot來促進這項工作,其長期目標是儘å¯èƒ½çˆ²
+所有相關人員自動化迴歸跟蹤。
+
+Regzbot通éŽç›£è¦–跟蹤的迴歸報告的回覆來工作。此外,它還查找用“Link:â€æ¨™ç±¤å¼•ç”¨é€™
+些報告的補ä¸ï¼›å°é€™äº›è£œä¸çš„回覆也會被跟蹤。çµåˆé€™äº›æ•¸æ“šï¼Œå¯ä»¥å¾ˆå¥½åœ°çž­è§£ç•¶å‰ä¿®
+復éŽç¨‹çš„狀態。
+
+如何查看regzbot當å‰è¿½è¹¤çš„迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+åƒè¦‹ `regzbot在線 <https://linux-regtracking.leemhuis.info/regzbot/>`_ 。
+
+何種å•é¡Œå¯ä»¥ç”±regzbot追蹤?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+該機器人åªçˆ²äº†è·Ÿè¹¤è¿´æ­¸ï¼Œå› æ­¤è«‹ä¸è¦è®“regzbot涉åŠå¸¸è¦å•é¡Œã€‚但是å°æ–¼Linux內核的
+迴歸跟蹤者來說,讓regzbot跟蹤嚴é‡å•é¡Œä¹Ÿå¯ä»¥ï¼Œå¦‚有關掛起ã€æ壞數據或內部錯誤
+(Panicã€Oopsã€BUG()ã€warning…)的報告。
+
+如何修改被追蹤迴歸的相關信æ¯ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+在直接或間接回復報告郵件時使用“regzbot命令â€å³å¯ã€‚最簡單的方法是:在“已發é€â€æ–‡
+件夾或郵件列表存檔中找到報告,然後使用郵件客戶端的“全部回覆â€åŠŸèƒ½å°å…¶é€²è¡Œå›žè¦†ã€‚
+在該郵件中的ç¨ç«‹æ®µè½ä¸­å¯ä½¿ç”¨ä»¥ä¸‹å‘½ä»¤ä¹‹ä¸€ï¼ˆå³ä½¿ç”¨ç©ºè¡Œå°‡é€™äº›å‘½ä»¤ä¸­çš„一個或多個與
+其餘郵件文本分隔開)。
+
+ * 更新迴歸引入起點,例如在執行二分之後::
+
+ #regzbot introduced: 1f2e3d4c5d
+
+ * 設置或更新標題::
+
+ #regzbot title: foo
+
+ * 監視討論或bugzilla.kernel.org上有關討論或修復的工單::
+
+ #regzbot monitor: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
+ #regzbot monitor: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
+
+ * 標記一個有更多相關細節的地方,例如有關但主題ä¸åŒçš„郵件列表帖å­æˆ–缺陷追蹤器中的工單::
+
+ #regzbot link: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
+
+ * 標記迴歸已失效::
+
+ #regzbot invalid: wasn't a regression, problem has always existed
+
+Regzbot還支æŒå…¶ä»–一些主è¦ç”±é–‹ç™¼äººå“¡æˆ–迴歸追蹤人員使用的命令。命令的更多細節請
+åƒè€ƒ `å…¥é–€æŒ‡å— <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/getting_started.md>`_
+å’Œ `åƒè€ƒæ‰‹å†Š <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/reference.md>`_ 。
+
+..
+ 正文çµæŸ
+..
+ 如本文件開頭所述,本文以GPL-2.0+或CC-BY-4.0許å¯ç™¼è¡Œã€‚如您想僅在CC-BY-4.0許
+ å¯ä¸‹é‡åˆ†ç™¼æœ¬æ–‡ï¼Œè«‹ç”¨â€œLinux內核開發者â€ä½œçˆ²ä½œè€…,並用如下éˆæŽ¥ä½œçˆ²ä¾†æºï¼š
+ https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/translations/zh_CN/admin-guide/reporting-regressions.rst
+..
+ 注æ„:本RST文件內容åªæœ‰åœ¨ä¾†è‡ªLinux內核æºä»£ç¢¼æ™‚是使用CC-BY-4.0許å¯çš„,因爲經
+ éŽè™•ç†çš„版本(如經內核的構建系統)å¯èƒ½åŒ…å«ä¾†è‡ªä½¿ç”¨æ›´åš´æ ¼è¨±å¯è­‰çš„文件的內容。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/security-bugs.rst b/Documentation/translations/zh_TW/admin-guide/security-bugs.rst
index 65c8dd24c96d..c0e9fc247695 100644
--- a/Documentation/translations/zh_TW/admin-guide/security-bugs.rst
+++ b/Documentation/translations/zh_TW/admin-guide/security-bugs.rst
@@ -19,17 +19,17 @@ Linux內核開發人員éžå¸¸é‡è¦–安全性。因此我們想知é“何時發ç¾
-----
å¯ä»¥é€šéŽé›»å­éƒµä»¶<security@kernel.org>è¯ç¹«Linux內核安全團隊。這是一個安全人員
-çš„ç§æœ‰åˆ—表,他們將幫助驗證錯誤報告並開發和發布修復程åºã€‚如果您已經有了一個
+çš„ç§æœ‰åˆ—表,他們將幫助驗證錯誤報告並開發和發佈修復程åºã€‚如果您已經有了一個
修復,請將其包å«åœ¨æ‚¨çš„報告中,這樣å¯ä»¥å¤§å¤§åŠ å¿«é€²ç¨‹ã€‚安全團隊å¯èƒ½æœƒå¾žå€åŸŸç¶­è­·
-人員那裡ç²å¾—é¡å¤–的幫助,以ç†è§£å’Œä¿®å¾©å®‰å…¨æ¼æ´žã€‚
+人員那è£ç²å¾—é¡å¤–的幫助,以ç†è§£å’Œä¿®å¾©å®‰å…¨æ¼æ´žã€‚
與任何缺陷一樣,æ供的信æ¯è¶Šå¤šï¼Œè¨ºæ–·å’Œä¿®å¾©å°±è¶Šå®¹æ˜“。如果您ä¸æ¸…楚哪些信æ¯æœ‰ç”¨ï¼Œ
-請查看「Documentation/translations/zh_TW/admin-guide/reporting-issues.rstã€ä¸­
+請查看“Documentation/translations/zh_CN/admin-guide/reporting-issues.rstâ€ä¸­
概述的步驟。任何利用æ¼æ´žçš„攻擊代碼都éžå¸¸æœ‰ç”¨ï¼Œæœªç¶“報告者åŒæ„ä¸æœƒå°å¤–發布,除
éžå·²ç¶“公開。
-請儘å¯èƒ½ç™¼é€ç„¡é™„件的純文本電å­éƒµä»¶ã€‚如果所有的細節都è—在附件里,那麼就很難å°
-一個複雜的å•é¡Œé€²è¡Œä¸Šä¸‹æ–‡å¼•ç”¨çš„討論。把它想åƒæˆä¸€å€‹
+請儘å¯èƒ½ç™¼é€ç„¡é™„件的純文本電å­éƒµä»¶ã€‚如果所有的細節都è—在附件è£ï¼Œé‚£éº¼å°±å¾ˆé›£å°
+一個複雜的å•é¡Œé€²è¡Œä¸Šä¸‹æ–‡å¼•ç”¨çš„討論。把它想象æˆä¸€å€‹
:doc:`常è¦çš„補ä¸æ交 <../process/submitting-patches>` (å³ä½¿ä½ é‚„沒有補ä¸ï¼‰ï¼š
æè¿°å•é¡Œå’Œå½±éŸ¿ï¼Œåˆ—出復ç¾æ­¥é©Ÿï¼Œç„¶å¾Œçµ¦å‡ºä¸€å€‹å»ºè­°çš„解決方案,所有這些都是純文本的。
@@ -38,15 +38,15 @@ Linux內核開發人員éžå¸¸é‡è¦–安全性。因此我們想知é“何時發ç¾
安全列表ä¸æ˜¯å…¬é–‹æ¸ é“。爲此,請åƒè¦‹ä¸‹é¢çš„å”作。
-一旦開發出了å¥å£¯çš„補ä¸ï¼Œç™¼å¸ƒéŽç¨‹å°±é–‹å§‹äº†ã€‚å°å…¬é–‹çš„缺陷的修復會立å³ç™¼å¸ƒã€‚
+一旦開發出了å¥å£¯çš„補ä¸ï¼Œç™¼ä½ˆéŽç¨‹å°±é–‹å§‹äº†ã€‚å°å…¬é–‹çš„缺陷的修復會立å³ç™¼ä½ˆã€‚
-儘管我們傾å‘於在未公開缺陷的修復å¯ç”¨æ™‚å³ç™¼å¸ƒè£œä¸ï¼Œä½†æ‡‰å ±å‘Šè€…或å—影響方的請求,
-這å¯èƒ½æœƒè¢«æŽ¨é²åˆ°ç™¼å¸ƒéŽç¨‹é–‹å§‹å¾Œçš„7日內,如果根據缺陷的嚴é‡æ€§éœ€è¦æ›´å¤šçš„時間,
-則å¯é¡å¤–延長到14天。推é²ç™¼å¸ƒä¿®å¾©çš„唯一有效原因是爲了é©æ‡‰QAçš„é‚輯和需è¦ç™¼å¸ƒ
+儘管我們傾å‘於在未公開缺陷的修復å¯ç”¨æ™‚å³ç™¼ä½ˆè£œä¸ï¼Œä½†æ‡‰å ±å‘Šè€…或å—影響方的請求,
+這å¯èƒ½æœƒè¢«æŽ¨é²åˆ°ç™¼ä½ˆéŽç¨‹é–‹å§‹å¾Œçš„7日內,如果根據缺陷的嚴é‡æ€§éœ€è¦æ›´å¤šçš„時間,
+則å¯é¡å¤–延長到14天。推é²ç™¼ä½ˆä¿®å¾©çš„唯一有效原因是爲了é©æ‡‰QAçš„é‚輯和需è¦ç™¼ä½ˆ
å”調的大è¦æ¨¡éƒ¨ç½²ã€‚
雖然å¯èƒ½èˆ‡å—信任的個人共享å—é™ä¿¡æ¯ä»¥é–‹ç™¼ä¿®å¾©ï¼Œä½†æœªç¶“報告者許å¯ï¼Œæ­¤é¡žä¿¡æ¯ä¸æœƒ
-與修復程åºä¸€èµ·ç™¼å¸ƒæˆ–發布在任何其他披露渠é“上。這包括但ä¸é™æ–¼åŽŸå§‹éŒ¯èª¤å ±å‘Šå’Œ
+與修復程åºä¸€èµ·ç™¼ä½ˆæˆ–發佈在任何其他披露渠é“上。這包括但ä¸é™æ–¼åŽŸå§‹éŒ¯èª¤å ±å‘Šå’Œ
後續討論(如有)ã€æ¼æ´žã€CVEä¿¡æ¯æˆ–報告者的身份。
æ›å¥è©±èªªï¼Œæˆ‘們唯一感興趣的是修復缺陷。æ交給安全列表的所有其他資料以åŠå°å ±å‘Š
@@ -57,10 +57,10 @@ Linux內核開發人員éžå¸¸é‡è¦–安全性。因此我們想知é“何時發ç¾
å°æ•æ„Ÿç¼ºé™·ï¼ˆä¾‹å¦‚那些å¯èƒ½å°Žè‡´æ¬Šé™æå‡çš„缺陷)的修復å¯èƒ½éœ€è¦èˆ‡ç§æœ‰éƒµä»¶åˆ—表
<linux-distros@vs.openwall.org>進行å”調,以便分發供應商åšå¥½æº–備,在公開披露
-上游補ä¸æ™‚發布一個已修復的內核。發行版將需è¦ä¸€äº›æ™‚間來測試建議的補ä¸ï¼Œé€šå¸¸
-會è¦æ±‚至少幾天的é™åˆ¶ï¼Œè€Œä¾›æ‡‰å•†æ›´æ–°ç™¼å¸ƒæ›´å‚¾å‘於周二至周四。若åˆé©ï¼Œå®‰å…¨åœ˜éšŠ
+上游補ä¸æ™‚發佈一個已修復的內核。發行版將需è¦ä¸€äº›æ™‚間來測試建議的補ä¸ï¼Œé€šå¸¸
+會è¦æ±‚至少幾天的é™åˆ¶ï¼Œè€Œä¾›æ‡‰å•†æ›´æ–°ç™¼å¸ƒæ›´å‚¾å‘於週二至週四。若åˆé©ï¼Œå®‰å…¨åœ˜éšŠ
å¯ä»¥å”助這種å”調,或者報告者å¯ä»¥å¾žä¸€é–‹å§‹å°±åŒ…括linux發行版。在這種情æ³ä¸‹ï¼Œè«‹
-記ä½åœ¨é›»å­éƒµä»¶ä¸»é¡Œè¡Œå‰é¢åŠ ä¸Šã€Œ[vs]ã€ï¼Œå¦‚linux發行版wiki中所述:
+記ä½åœ¨é›»å­éƒµä»¶ä¸»é¡Œè¡Œå‰é¢åŠ ä¸Šâ€œ[vs]â€ï¼Œå¦‚linux發行版wiki中所述:
<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists>。
CVE分é…
diff --git a/Documentation/translations/zh_TW/admin-guide/sysrq.rst b/Documentation/translations/zh_TW/admin-guide/sysrq.rst
new file mode 100644
index 000000000000..4a08db00a495
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/sysrq.rst
@@ -0,0 +1,281 @@
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/sysrq.rst
+
+:翻譯:
+
+ 黃è»è¯ Junhua Huang <huang.junhua@zte.com.cn>
+
+:æ ¡è­¯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_admin-guide_sysrq:
+
+Linux 魔法系統請求éµé§­å®¢
+========================
+
+é‡å° sysrq.c 的文檔說明
+
+什麼是魔法 SysRq éµï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~
+
+它是一個你å¯ä»¥è¼¸å…¥çš„具有魔法般的組åˆéµã€‚
+無論內核在åšä»€éº¼ï¼Œå…§æ ¸éƒ½æœƒéŸ¿æ‡‰ SysRq éµçš„輸入,除éžå…§æ ¸å®Œå…¨å¡æ­»ã€‚
+
+如何使能魔法 SysRq éµï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~
+
+在é…置內核時,我們需è¦è¨­ç½® 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' 爲 'Y'。
+當é‹è¡Œä¸€å€‹ç·¨è­¯é€² sysrq 功能的內核時,/proc/sys/kernel/sysrq 控制ç€è¢«
+SysRq éµèª¿ç”¨çš„功能許å¯ã€‚這個文件的默èªå€¼ç”± CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE
+é…置符號設定,文件本身默èªè¨­ç½®çˆ² 1。以下是 /proc/sys/kernel/sysrq 中å¯èƒ½çš„
+值列表:
+
+ - 0 - 完全ä¸ä½¿èƒ½ SysRq éµ
+ - 1 - 使能 SysRq éµçš„全部功能
+ - >1 - å°æ–¼å…許的 SysRq éµåŠŸèƒ½çš„比特掩碼(åƒè¦‹ä¸‹é¢æ›´è©³ç´°çš„功能æ述)::
+
+ 2 = 0x2 - 使能å°æŽ§åˆ¶æª¯æ—¥èªŒè¨˜éŒ„級別的控制
+ 4 = 0x4 - 使能å°éµç›¤çš„控制 (SAK, unraw)
+ 8 = 0x8 - 使能å°é€²ç¨‹çš„調試導出等
+ 16 = 0x10 - 使能åŒæ­¥å‘½ä»¤
+ 32 = 0x20 - 使能é‡æ–°æŽ›è¼‰åªè®€
+ 64 = 0x40 - 使能å°é€²ç¨‹çš„信號æ“作 (term, kill, oom-kill)
+ 128 = 0x80 - å…許é‡å•“ã€æ–·é›»
+ 256 = 0x100 - å…許讓所有實時任務變普通任務
+
+ä½ å¯ä»¥é€šéŽå¦‚下命令把值設置到這個文件中::
+
+ echo "number" >/proc/sys/kernel/sysrq
+
+這è£è¢«å¯«å…¥çš„ number å¯ä»¥æ˜¯ 10 é€²åˆ¶æ•¸ï¼Œæˆ–è€…æ˜¯å¸¶ç€ 0x å‰ç¶´çš„ 16 進制數。
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE 必須是以 16 進制數寫入。
+
+注æ„,``/proc/sys/kernel/sysrq`` 的值隻影響通éŽéµç›¤è§¸ç™¼ SySRq 的調用,å°æ–¼
+é€šéŽ ``/proc/sysrq-trigger`` 的任何æ“作調用都是å…許的
+(通éŽå…·æœ‰ç³»çµ±æ¬Šé™çš„用戶)。
+
+如何使用魔法 SysRq éµï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~
+
+在 x86 架構上
+ ä½ å¯ä»¥æŒ‰ä¸‹éµç›¤çµ„åˆéµ :kbd:`ALT-SysRq-<command key>`。
+
+ .. note::
+ 一些éµç›¤å¯èƒ½æ²’有標識 'SySRq' éµã€‚'SySRq' éµä¹Ÿè¢«ç•¶åš 'Print Screen'éµã€‚
+ åŒæ™‚有些éµç›¤ç„¡æ³•è™•ç†åŒæ™‚按下這麼多éµï¼Œå› æ­¤ä½ å¯ä»¥å…ˆæŒ‰ä¸‹éµç›¤ :kbd:`Alt` éµï¼Œ
+ 然後按下éµç›¤ :kbd:`SysRq` éµï¼Œå†é‡‹æ”¾éµç›¤ :kbd:`SysRq` éµï¼Œä¹‹å¾ŒæŒ‰ä¸‹éµç›¤ä¸Šå‘½ä»¤éµ
+ :kbd:`<command key>`,最後釋放所有éµã€‚
+
+在 SPARC 架構上
+ ä½ å¯ä»¥æŒ‰ä¸‹éµç›¤çµ„åˆéµ :kbd:`ALT-STOP-<command key>` 。
+
+在串行控制檯(åªé‡å° PC 類型的標準串å£ï¼‰
+ ä½ å¯ä»¥ç™¼ä¸€å€‹ ``BREAK`` ,然後在 5 秒內發é€ä¸€å€‹å‘½ä»¤éµï¼Œ
+ ç™¼é€ ``BREAK`` 兩次將被翻譯爲一個正常的 BREAK æ“作。
+
+在 PowerPC 架構上
+ 按下éµç›¤çµ„åˆéµ :kbd:`ALT - Print Screen` (或者 :kbd:`F13`) - :kbd:`<命令éµ>` 。
+ :kbd:`Print Screen` (或者 :kbd:`F13`) - :kbd:`<命令éµ>` 或許也能實ç¾ã€‚
+
+在其他架構上
+ 如果你知é“其他架構的組åˆéµï¼Œè«‹å‘Šè¨´æˆ‘,我å¯ä»¥æŠŠå®ƒå€‘添加到這部分。
+
+在所有架構上
+ 寫一個字符到 /proc/sysrq-trigger 文件,例如::
+
+ echo t > /proc/sysrq-trigger
+
+é€™å€‹å‘½ä»¤éµ :kbd:`<command key>` 是å€åˆ†å¤§å°å¯«çš„。
+
+什麼是命令éµï¼Ÿ
+~~~~~~~~~~~~~~
+
+=========== ================================================================
+å‘½ä»¤éµ åŠŸèƒ½
+=========== ================================================================
+``b`` 將立å³é‡å•“系統,ä¸æœƒåŒæ­¥æˆ–者å¸è¼‰ç£ç›¤ã€‚
+
+``c`` 將執行系統 crash,如果é…置了系統 crashdump,將執行 crashdump。
+
+``d`` 顯示所有æŒæœ‰çš„鎖。
+
+``e`` ç™¼é€ SIGTERM 信號給所有進程,除了 init 進程。
+
+``f`` 將調用 oom killer 殺掉一個éŽåº¦ä½”用內存的進程,如果什麼任務都沒殺,
+ 也ä¸æœƒ panic。
+
+``g`` kgdb 使用(內核調試器)。
+
+``h`` 將會顯示幫助。(實際上除了這è£åˆ—舉的éµï¼Œå…¶ä»–的都將顯示幫助,
+ 但是 ``h`` 容易記ä½ï¼‰:-)
+
+``i`` ç™¼é€ SIGKILL 給所有進程,除了 init 進程。
+
+``j`` 強制性的 “解å‡å®ƒâ€ - 用於被 FIFREEZE ioctl æ“作å‡ä½çš„文件系統。
+
+``k`` 安全訪å•ç¥•é‘°(SAK)殺掉在當å‰è™›æ“¬æŽ§åˆ¶æª¯çš„所有程åºï¼Œæ³¨æ„:åƒè€ƒ
+ ä¸‹é¢ SAK 節é‡è¦è«–述。
+
+``l`` 顯示所有活動 cpu 的棧回溯。
+
+``m`` 將導出當å‰å…§å­˜ä¿¡æ¯åˆ°ä½ çš„控制檯。
+
+``n`` 用於使所有實時任務變æˆæ™®é€šä»»å‹™ã€‚
+
+``o`` 將關閉系統(如果é…置和支æŒçš„話)。
+
+``p`` 將導出當å‰å¯„存器和標誌ä½åˆ°æŽ§åˆ¶æª¯ã€‚
+
+``q`` 將導出æ¯å€‹ cpu 上所有已è£å‚™çš„高精度定時器(ä¸æ˜¯å®Œæ•´çš„
+ time_list 文件顯示的 timers)和所有時é˜äº‹ä»¶è¨­å‚™çš„詳細信æ¯ã€‚
+
+``r`` 關閉éµç›¤çš„原始模å¼ï¼Œè¨­ç½®çˆ²è½‰æ›æ¨¡å¼ã€‚
+
+``s`` 將嘗試åŒæ­¥æ‰€æœ‰çš„已掛載文件系統。
+
+``t`` 將導出當å‰æ‰€æœ‰ä»»å‹™åˆ—表和它們的信æ¯åˆ°æŽ§åˆ¶æª¯ã€‚
+
+``u`` 將嘗試é‡æ–°æŽ›è¼‰å·²æŽ›è¼‰æ–‡ä»¶ç³»çµ±çˆ²åªè®€ã€‚
+
+``v`` 強制æ¢å¾©å¹€ç·©å­˜æŽ§åˆ¶æª¯ã€‚
+``v`` 觸發 ETM 緩存導出 [ARM 架構特有]
+
+``w`` 導出處於ä¸å¯ä¸­æ–·ç‹€æ…‹ï¼ˆé˜»å¡žï¼‰çš„任務。
+
+``x`` 在 ppc/powerpc 架構上用於 xmon 接å£ã€‚
+ 在 sparc64 架構上用於顯示全局的 PMU(性能監控單元)寄存器。
+ 在 MIPS 架構上導出所有的 tlb æ¢ç›®ã€‚
+
+``y`` 顯示全局 cpu 寄存器 [SPARC-64 架構特有]
+
+``z`` 導出 ftrace 緩存信æ¯
+
+``0``-``9`` 設置控制檯日誌級別,該級別控制什麼樣的內核信æ¯å°‡è¢«æ‰“å°åˆ°ä½ çš„
+ 控制檯。(比如 ``0`` ,將使得åªæœ‰ç·Šæ€¥ä¿¡æ¯ï¼Œåƒ PANICs or OOPSes
+ æ‰èƒ½åˆ°ä½ çš„控制檯。)
+=========== ================================================================
+
+好了,我能用他們åšä»€éº¼å‘¢ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+嗯,當你的 X æœå‹™ç«¯æˆ–者 svgalib 程åºå´©æ½°ï¼Œunraw(r) éžåŽŸå§‹æ¨¡å¼å‘½ä»¤éµæ˜¯éžå¸¸
+方便的。
+
+sak(k)(安全訪å•ç¥•é‘°ï¼‰åœ¨ä½ å˜—試登陸的åŒæ™‚,åˆæƒ³ç¢ºä¿ç•¶å‰æŽ§åˆ¶æª¯æ²’有å¯ä»¥ç²å–ä½ çš„
+密碼的特洛伊木馬程åºé‹è¡Œæ™‚是有用的。它會殺掉給定控制檯的所有程åºï¼Œé€™æ¨£ä½ 
+å°±å¯ä»¥ç¢ºèªç•¶å‰çš„登陸æ示程åºæ˜¯å¯¦éš›ä¾†è‡ª init 進程的程åºï¼Œè€Œä¸æ˜¯æŸäº›ç‰¹æ´›ä¼Š
+木馬程åºã€‚
+
+.. important::
+
+ 在其實際的形å¼ä¸­ï¼Œåœ¨å…¼å®¹ C2 安全標準的系統上,它ä¸æ˜¯ä¸€å€‹çœŸæ­£çš„ SAK,
+ 它也ä¸æ‡‰è©²èª¤èªçˆ²æ­¤ã€‚
+
+似乎其他人發ç¾å…¶å¯ä»¥ä½œçˆ²ï¼ˆç³»çµ±çµ‚端è¯æ©Ÿéµï¼‰ç•¶ä½ æƒ³é€€å‡ºä¸€å€‹ç¨‹åºï¼Œ
+åŒæ™‚ä¸æœƒè®“你切æ›æŽ§åˆ¶æª¯çš„方法。(比如,X æœå‹™ç«¯æˆ–者 svgalib 程åºï¼‰
+
+``reboot(b)`` 是個好方法,當你ä¸èƒ½é—œé–‰æ©Ÿå™¨æ™‚,它等åŒæ–¼æŒ‰ä¸‹"復ä½"按鈕。
+
+``crash(c)`` å¯ä»¥ç”¨æ–¼æ‰‹å‹•è§¸ç™¼ä¸€å€‹ crashdump,當系統å¡ä½æ™‚。
+注æ„當 crashdump 機制ä¸å¯ç”¨æ™‚,這個åªæ˜¯è§¸ç™¼ä¸€å€‹å…§æ ¸ crash。
+
+``sync(s)`` 在拔掉å¯ç§»å‹•ä»‹è³ªä¹‹å‰ï¼Œæˆ–者在使用ä¸æ供優雅關機的
+æ•‘æ´ shell 之後很方便 -- 它將確ä¿ä½ çš„數據被安全地寫入ç£ç›¤ã€‚注æ„,在你看到
+å±å¹•ä¸Šå‡ºç¾ "OK" å’Œ "Done" 之å‰ï¼ŒåŒæ­¥é‚„沒有發生。
+
+``umount(u)`` å¯ä»¥ç”¨ä¾†æ¨™è¨˜æ–‡ä»¶ç³»çµ±æ­£å¸¸å¸è¼‰ï¼Œå¾žæ­£åœ¨é‹è¡Œçš„系統角度來看,它們將
+被é‡æ–°æŽ›è¼‰çˆ²åªè®€ã€‚這個é‡æ–°æŽ›è¼‰å‹•ä½œç›´åˆ°ä½ çœ‹åˆ° "OK" å’Œ "Done" ä¿¡æ¯å‡ºç¾åœ¨å±å¹•ä¸Š
+纔算完æˆã€‚
+
+日誌級別 ``0`` - ``9`` 用於當你的控制檯被大é‡çš„內核信æ¯è¡æ“Šï¼Œä½ ä¸æƒ³çœ‹è¦‹çš„時候。
+é¸æ“‡ ``0`` å°‡ç¦æ­¢é™¤äº†æœ€ç·Šæ€¥çš„內核信æ¯å¤–的所有的內核信æ¯è¼¸å‡ºåˆ°æŽ§åˆ¶æª¯ã€‚(但是如果
+syslogd/klogd 進程是é‹è¡Œçš„,它們ä»å°‡è¢«è¨˜éŒ„。)
+
+``term(e)`` å’Œ ``kill(i)`` 用於當你有些有點失控的進程,你無法通éŽå…¶ä»–æ–¹å¼æ®ºæŽ‰
+它們的時候,特別是它正在創建其他進程。
+
+"just thaw ``it(j)`` " 用於當你的系統由於一個 FIFREEZE ioctl 調用而產生的文件
+系統å‡çµï¼Œè€Œå°Žè‡´çš„ä¸éŸ¿æ‡‰æ™‚。
+
+有的時候 SysRq éµåœ¨ä½¿ç”¨å®ƒä¹‹å¾Œï¼Œçœ‹èµ·ä¾†åƒæ˜¯â€œå¡ä½â€äº†ï¼Œæˆ‘能åšäº›ä»€éº¼ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+這也會發生在我這,我發ç¾è¼•æ•²éµç›¤å…©å´çš„ shiftã€alt å’Œ control éµï¼Œç„¶å¾Œå†æ¬¡æ•²æ“Š
+一個無效的 SysRq éµåºåˆ—å¯ä»¥è§£æ±ºå•é¡Œã€‚(比如,åƒéµç›¤çµ„åˆéµ :kbd:`alt-sysrq-z` )
+切æ›åˆ°å¦ä¸€å€‹è™›æ“¬æŽ§åˆ¶æª¯ï¼ˆéµç›¤æ“作 :kbd:`ALT+Fn` ),然後å†åˆ‡å›žä¾†æ‡‰è©²ä¹Ÿæœ‰å¹«åŠ©ã€‚
+
+我敲擊了 SysRq éµï¼Œä½†åƒæ˜¯ä»€éº¼éƒ½æ²’發生,發生了什麼錯誤?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+有一些éµç›¤å°æ–¼ SysRq éµè¨­ç½®äº†ä¸åŒçš„éµå€¼ï¼Œè€Œä¸æ˜¯æå‰å®šç¾©çš„ 99
+(查看在 ``include/uapi/linux/input-event-codes.h`` 文件中 ``KEY_SYSRQ`` 的定義)
+或者就根本沒有 SysRq éµã€‚在這些場景下,執行 ``showkey -s`` 命令來找到一個åˆé©
+的掃æ碼åºåˆ—,然後使用 ``setkeycodes <sequence> 99`` 命令映射這個åºåˆ—值到通用
+çš„ SysRq éµç·¨ç¢¼ä¸Šï¼ˆæ¯”如 ``setkeycodes e05b 99`` )。最好將這個命令放在啓動腳本
+中。
+哦,順便說一å¥ï¼Œä½ å秒é˜ä¸è¼¸å…¥ä»»ä½•æ±è¥¿å°±å°‡é€€å‡º “showkeyâ€ã€‚
+
+我想添加一個 SysRq éµäº‹ä»¶åˆ°ä¸€å€‹æ¨¡å¡Šä¸­ï¼Œå¦‚何去åšå‘¢ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+çˆ²äº†è¨»å†Šä¸€å€‹åŸºç¤Žå‡½æ•¸åˆ°é€™å€‹è¡¨ä¸­ï¼Œé¦–å…ˆä½ å¿…é ˆåŒ…å« ``include/linux/sysrq.h`` é ­
+文件,這個頭文件定義了你所需è¦çš„所有æ±è¥¿ã€‚然後你必須創建一個 ``sysrq_key_op``
+çµæ§‹é«”,然後åˆå§‹åŒ–它,使用如下內容,A) 你將使用的這個éµçš„處ç†å‡½æ•¸ï¼Œ B) 一個
+help_msg 字符串,在 SysRq éµæ‰“å°å¹«åŠ©ä¿¡æ¯æ™‚將打å°å‡ºä¾†ï¼ŒC) 一個 action_msg å­—
+符串,就在你的處ç†å‡½æ•¸èª¿ç”¨å‰æ‰“å°å‡ºä¾†ã€‚你的處ç†å‡½æ•¸å¿…須符åˆåœ¨ 'sysrq.h' 文件中
+的函數原型。
+
+在 ``sysrq_key_op`` çµæ§‹é«”被創建後,你å¯ä»¥èª¿ç”¨å…§æ ¸å‡½æ•¸
+``register_sysrq_key(int key, const struct sysrq_key_op *op_p);``,
+該函數在表中的 'key' å°æ‡‰ä½ç½®å…§å®¹æ˜¯ç©ºçš„情æ³ä¸‹ï¼Œå°‡é€šéŽ ``op_p`` 指é‡è¨»å†Šé€™å€‹æ“作
+函數到表中 'key' å°æ‡‰ä½ç½®ä¸Šã€‚在模塊å¸è¼‰çš„時候,你必須調用
+``unregister_sysrq_key(int key, const struct sysrq_key_op *op_p)`` 函數,該函數
+åªæœ‰åœ¨ç•¶å‰è©²éµå°æ‡‰çš„處ç†å‡½æ•¸è¢«è¨»å†Šåˆ°äº† 'key' å°æ‡‰ä½ç½®æ™‚,纔會移除 'op_p' 指é‡
+å°æ‡‰çš„éµå€¼æ“作函數。這是爲了防止在你註冊之後,該ä½ç½®è¢«æ”¹å¯«çš„情æ³ã€‚
+
+魔法 SysRq éµç³»çµ±çš„工作原ç†æ˜¯å°‡éµå°æ‡‰æ“作函數註冊到éµçš„æ“作查找表,
+該表定義在 'drivers/tty/sysrq.c' 文件中。
+該éµè¡¨æœ‰è¨±å¤šåœ¨ç·¨è­¯æ™‚候就註冊進去的æ“作函數,但是是å¯è®Šçš„。
+並且有兩個函數作爲æ“作該表的接å£è¢«å°Žå‡º::
+
+ register_sysrq_key 和 unregister_sysrq_key.
+
+當然,永é ä¸è¦åœ¨è¡¨ä¸­ç•™ä¸‹ç„¡æ•ˆæŒ‡é‡ï¼Œå³ï¼Œç•¶ä½ çš„模塊存在調用 register_sysrq_key()
+函數,它一定è¦èª¿ç”¨ unregister_sysrq_key() 來清除它使用éŽçš„ SysRq éµè¡¨æ¢ç›®ã€‚
+表中的空指é‡æ˜¯å®‰å…¨çš„。:)
+
+如果å°æ–¼æŸç¨®åŽŸå› ï¼Œåœ¨ handle_sysrq 調用的處ç†å‡½æ•¸ä¸­ï¼Œä½ èªçˆ²æœ‰å¿…è¦èª¿ç”¨
+handle_sysrq 函數時,你必須æ„識到當å‰ä½ è™•æ–¼ä¸€å€‹éŽ–中(你åŒæ™‚也處於一箇中斷處ç†
+函數中,這æ„味ç€ä¸èƒ½ç¡çœ ï¼‰ã€‚所以這時你必須使用 ``__handle_sysrq_nolock`` 替代。
+
+當我敲擊一個 SysRq 組åˆéµæ™‚,åªæœ‰æ¨™é¡Œæ‰“å°å‡ºç¾åœ¨æŽ§åˆ¶æª¯ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SysRq éµçš„輸出和所有其他控制檯輸出一樣,å—制於控制檯日誌級別控制。
+這æ„味ç€ï¼Œå¦‚果內核以發行版內核中常見的 "quiet" æ–¹å¼å•“動,則輸出å¯èƒ½ä¸æœƒå‡ºç¾åœ¨å¯¦éš›
+的控制檯上,å³ä½¿å®ƒæœƒå‡ºç¾åœ¨ dmesg 緩存中,也å¯ä»¥é€šéŽ dmesg 命令和 ``/proc/kmsg``
+文件的消費訪å•åˆ°ã€‚作爲一個特例,來自 sysrq 命令的標題行將被傳éžçµ¦æ‰€æœ‰æŽ§åˆ¶æª¯
+使用者,就好åƒç•¶å‰æ—¥èªŒç´šåˆ¥æ˜¯æœ€å¤§çš„一樣。如果åªç™¼å‡ºæ¨™é¡Œé ­ï¼Œå‰‡å¹¾ä¹Žå¯ä»¥è‚¯å®šå…§æ ¸æ—¥èªŒ
+級別太低。如果你需è¦æŽ§åˆ¶æª¯ä¸Šçš„輸出,那麼你將需è¦è‡¨æ™‚æ高控制檯日誌級別,通éŽä½¿ç”¨
+éµç›¤çµ„åˆéµ :kbd:`alt-sysrq-8` 或者::
+
+ echo 8 > /proc/sysrq-trigger
+
+在觸發了你感興趣的 SysRq éµå‘½ä»¤å¾Œï¼Œè¨˜å¾—æ¢å¾©æ—¥èªŒç´šåˆ¥åˆ°æ­£å¸¸æƒ…æ³ã€‚
+
+我有很多å•é¡Œæ™‚,å¯ä»¥è«‹æ•™èª°ï¼Ÿ
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+請教在內核郵件列表上的人,郵箱:
+ linux-kernel@vger.kernel.org
+
+致è¬
+~~~~
+
+- Mydraal <vulpyne@vulpyne.net> 撰寫了該文件
+- Adam Sulmicki <adam@cfar.umd.edu> 進行了更新
+- Jeremy M. Dolan <jmd@turbogeek.org> 在 2001/01/28 10:15:59 進行了更新
+- Crutcher Dunnavant <crutcher+kernel@datastacks.com> 添加éµè¨»å†Šéƒ¨åˆ†
+
diff --git a/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst b/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst
index ebe3812ead82..47629f6b05de 100644
--- a/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst
+++ b/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst
@@ -9,27 +9,27 @@
å³æƒ³æˆ Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com>
-å—汙染的內核
+å—污染的內核
-------------
-當發生一些在ç¨å¾Œèª¿æŸ¥å•é¡Œæ™‚å¯èƒ½ç›¸é—œçš„事件時,內核會將自己標記爲「å—汙染
-(tainted)ã€çš„。ä¸ç”¨å¤ªéŽæ“”心,大多數情æ³ä¸‹é‹è¡Œå—汙染的內核沒有å•é¡Œï¼›é€™äº›ä¿¡æ¯
-主è¦åœ¨æœ‰äººæƒ³èª¿æŸ¥æŸå€‹å•é¡Œæ™‚æ‰æœ‰æ„義的,因爲å•é¡Œçš„真正原因å¯èƒ½æ˜¯å°Žè‡´å…§æ ¸å—汙染
-的事件。這就是爲什麼來自å—汙染內核的缺陷報告常常被開發人員忽略,因此請嘗試用
-未å—汙染的內核é‡ç¾å•é¡Œã€‚
+當發生一些在ç¨å¾Œèª¿æŸ¥å•é¡Œæ™‚å¯èƒ½ç›¸é—œçš„事件時,內核會將自己標記爲“å—污染
+(tainted)â€çš„。ä¸ç”¨å¤ªéŽæ“”心,大多數情æ³ä¸‹é‹è¡Œå—污染的內核沒有å•é¡Œï¼›é€™äº›ä¿¡æ¯
+主è¦åœ¨æœ‰äººæƒ³èª¿æŸ¥æŸå€‹å•é¡Œæ™‚纔有æ„義的,因爲å•é¡Œçš„真正原因å¯èƒ½æ˜¯å°Žè‡´å…§æ ¸å—污染
+的事件。這就是爲什麼來自å—污染內核的缺陷報告常常被開發人員忽略,因此請嘗試用
+未å—污染的內核é‡ç¾å•é¡Œã€‚
-請注æ„,å³ä½¿åœ¨æ‚¨æ¶ˆé™¤å°Žè‡´æ±™æŸ“的原因(亦å³å¸è¼‰å°ˆæœ‰å…§æ ¸æ¨¡å¡Šï¼‰ä¹‹å¾Œï¼Œå…§æ ¸ä»å°‡ä¿æŒ
-汙染狀態,以表示內核ä»ç„¶ä¸å¯ä¿¡ã€‚這也是爲什麼內核在注æ„到內部å•é¡Œï¼ˆã€Œkernel
-bugã€ï¼‰ã€å¯æ¢å¾©éŒ¯èª¤ï¼ˆã€Œkernel oopsã€ï¼‰æˆ–ä¸å¯æ¢å¾©éŒ¯èª¤ï¼ˆã€Œkernel panicã€ï¼‰æ™‚會列å°
-å—汙染狀態,並將有關此的調試信æ¯å¯«å…¥æ—¥èªŒ ``dmesg`` 輸出。也å¯ä»¥é€šéŽ
-``/proc/`` 中的文件在é‹è¡Œæ™‚檢查å—汙染的狀態。
+請注æ„,å³ä½¿åœ¨æ‚¨æ¶ˆé™¤å°Žè‡´æ±¡æŸ“的原因(亦å³å¸è¼‰å°ˆæœ‰å…§æ ¸æ¨¡å¡Šï¼‰ä¹‹å¾Œï¼Œå…§æ ¸ä»å°‡ä¿æŒ
+污染狀態,以表示內核ä»ç„¶ä¸å¯ä¿¡ã€‚這也是爲什麼內核在注æ„到內部å•é¡Œï¼ˆâ€œkernel
+bugâ€ï¼‰ã€å¯æ¢å¾©éŒ¯èª¤ï¼ˆâ€œkernel oopsâ€ï¼‰æˆ–ä¸å¯æ¢å¾©éŒ¯èª¤ï¼ˆâ€œkernel panicâ€ï¼‰æ™‚會打å°
+å—污染狀態,並將有關此的調試信æ¯å¯«å…¥æ—¥èªŒ ``dmesg`` 輸出。也å¯ä»¥é€šéŽ
+``/proc/`` 中的文件在é‹è¡Œæ™‚檢查å—污染的狀態。
-BUGã€Oops或Panics消æ¯ä¸­çš„汙染標誌
+BUGã€Oops或Panics消æ¯ä¸­çš„污染標誌
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-在頂部以「CPU:ã€é–‹é ­çš„一行中å¯ä»¥æ‰¾åˆ°å—汙染的狀態;內核是å¦å—到汙染和原因會顯示
-在進程ID(「PID:ã€ï¼‰å’Œè§¸ç™¼äº‹ä»¶å‘½ä»¤çš„縮寫å稱(「Comm:ã€ï¼‰ä¹‹å¾Œ::
+在頂部以“CPU:â€é–‹é ­çš„一行中å¯ä»¥æ‰¾åˆ°å—污染的狀態;內核是å¦å—到污染和原因會顯示
+在進程ID(“PID:â€ï¼‰å’Œè§¸ç™¼äº‹ä»¶å‘½ä»¤çš„縮寫å稱(“Comm:â€ï¼‰ä¹‹å¾Œ::
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
Oops: 0002 [#1] SMP PTI
@@ -38,27 +38,27 @@ BUGã€Oops或Panics消æ¯ä¸­çš„汙染標誌
RIP: 0010:my_oops_init+0x13/0x1000 [kpanic]
[...]
-如果內核在事件發生時沒有被汙染,您將在那裡看到「Not-tainted:ã€ï¼›å¦‚果被汙染,那
-麼它將是「Tainted:ã€ä»¥åŠå­—æ¯æˆ–空格。在上é¢çš„例å­ä¸­ï¼Œå®ƒçœ‹èµ·ä¾†æ˜¯é€™æ¨£çš„::
+如果內核在事件發生時沒有被污染,您將在那è£çœ‹åˆ°â€œNot-tainted:â€ï¼›å¦‚果被污染,那
+麼它將是“Tainted:â€ä»¥åŠå­—æ¯æˆ–空格。在上é¢çš„例å­ä¸­ï¼Œå®ƒçœ‹èµ·ä¾†æ˜¯é€™æ¨£çš„::
Tainted: P W O
下表解釋了這些字符的å«ç¾©ã€‚在本例中,由於加載了專有模塊( ``P`` ),出ç¾äº†
警告( ``W`` ),並且加載了外部構建的模塊( ``O`` ),所以內核早些時候å—到
-了汙染。è¦è§£ç¢¼å…¶ä»–字符,請使用下表。
+了污染。è¦è§£ç¢¼å…¶ä»–字符,請使用下表。
-解碼é‹è¡Œæ™‚的汙染狀態
+解碼é‹è¡Œæ™‚的污染狀態
~~~~~~~~~~~~~~~~~~~~~
-在é‹è¡Œæ™‚,您å¯ä»¥é€šéŽè®€å– ``cat /proc/sys/kernel/tainted`` 來查詢å—汙染狀態。
-如果返回 ``0`` ,則內核沒有å—到汙染;任何其他數字都表示å—到汙染的原因。解碼
+在é‹è¡Œæ™‚,您å¯ä»¥é€šéŽè®€å– ``cat /proc/sys/kernel/tainted`` 來查詢å—污染狀態。
+如果返回 ``0`` ,則內核沒有å—到污染;任何其他數字都表示å—到污染的原因。解碼
這個數字的最簡單方法是使用腳本 ``tools/debugging/kernel-chktaint`` ,您的
發行版å¯èƒ½æœƒå°‡å…¶ä½œçˆ²å爲 ``linux-tools`` 或 ``kernel-tools`` 的包的一部分æ
供;如果沒有,您å¯ä»¥å¾ž
`git.kernel.org <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/tools/debugging/kernel-chktaint>`_
網站下載此腳本並用 ``sh kernel-chktaint`` 執行,它會在上é¢å¼•ç”¨çš„日誌中有類似
-語å¥çš„機器上列å°é€™æ¨£çš„內容::
+語å¥çš„機器上打å°é€™æ¨£çš„內容::
Kernel is Tainted for following reasons:
* Proprietary module was loaded (#0)
@@ -69,19 +69,19 @@ BUGã€Oops或Panics消æ¯ä¸­çš„汙染標誌
a more details explanation of the various taint flags.
Raw taint value as int/string: 4609/'P W O '
-你也å¯ä»¥è©¦è‘—自己解碼這個數字。如果內核被汙染的原因åªæœ‰ä¸€å€‹ï¼Œé‚£éº¼é€™å¾ˆç°¡å–®ï¼Œ
+你也å¯ä»¥è©¦ç€è‡ªå·±è§£ç¢¼é€™å€‹æ•¸å­—。如果內核被污染的原因åªæœ‰ä¸€å€‹ï¼Œé‚£éº¼é€™å¾ˆç°¡å–®ï¼Œ
在本例中您å¯ä»¥é€šéŽä¸‹è¡¨æ‰¾åˆ°æ•¸å­—。如果你需è¦è§£ç¢¼æœ‰å¤šå€‹åŽŸå› çš„數字,因爲它是一
-個ä½åŸŸï¼ˆbitfield),其中æ¯å€‹ä½è¡¨ç¤ºä¸€å€‹ç‰¹å®šé¡žåž‹çš„汙染的存在或ä¸å­˜åœ¨ï¼Œæœ€å¥½è®“
+個ä½åŸŸï¼ˆbitfield),其中æ¯å€‹ä½è¡¨ç¤ºä¸€å€‹ç‰¹å®šé¡žåž‹çš„污染的存在或ä¸å­˜åœ¨ï¼Œæœ€å¥½è®“
å‰é¢æ到的腳本來處ç†ã€‚但是如果您需è¦å¿«é€Ÿçœ‹ä¸€ä¸‹ï¼Œå¯ä»¥ä½¿ç”¨é€™å€‹shell命令來檢查
設置了哪些ä½::
$ for i in $(seq 18); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done
-汙染狀態代碼表
+污染狀態代碼表
~~~~~~~~~~~~~~~
=== ===== ====== ========================================================
- ä½ æ—¥èªŒ 數字 內核被汙染的原因
+ ä½ æ—¥èªŒ 數字 內核被污染的原因
=== ===== ====== ========================================================
0 G/P 1 已加載專用模塊
1 _/F 2 模塊被強制加載
@@ -89,23 +89,23 @@ BUGã€Oops或Panics消æ¯ä¸­çš„汙染標誌
3 _/R 8 模塊被強制å¸è¼‰
4 _/M 16 處ç†å™¨å ±å‘Šäº†æ©Ÿå™¨æª¢æ¸¬ç•°å¸¸ï¼ˆMCE)
5 _/B 32 引用了錯誤的é æˆ–æŸäº›æ„外的é æ¨™èªŒ
- 6 _/U 64 用戶空間應用程å¼è«‹æ±‚的汙染
+ 6 _/U 64 用戶空間應用程åºè«‹æ±‚的污染
7 _/D 128 內核最近死機了,å³æ›¾å‡ºç¾OOPS或BUG
8 _/A 256 ACPI表被用戶覆蓋
9 _/W 512 內核發出警告
10 _/C 1024 已加載staging驅動程åº
- 11 _/I 2048 已應用平å°å›ºä»¶ç¼ºé™·çš„解決方案
- 12 _/O 4096 已加載外部構建(「樹外ã€ï¼‰æ¨¡å¡Š
+ 11 _/I 2048 已應用平臺固件缺陷的解決方案
+ 12 _/O 4096 已加載外部構建(“樹外â€ï¼‰æ¨¡å¡Š
13 _/E 8192 已加載未簽å的模塊
14 _/L 16384 發生軟鎖定
15 _/K 32768 內核已實時打補ä¸
- 16 _/X 65536 備用汙染,爲發行版定義並使用
+ 16 _/X 65536 備用污染,爲發行版定義並使用
17 _/T 131072 內核是用çµæ§‹éš¨æ©ŸåŒ–æ’件構建的
=== ===== ====== ========================================================
-註:字符 ``_`` 表示空白,以便於閱讀表。
+注:字符 ``_`` 表示空白,以便於閱讀表。
-汙染的更詳細解釋
+污染的更詳細解釋
~~~~~~~~~~~~~~~~~
0) ``G`` 加載的所有模塊都有GPL或兼容許å¯è­‰ï¼Œ ``P`` 加載了任何專有模塊。
@@ -115,14 +115,14 @@ BUGã€Oops或Panics消æ¯ä¸­çš„汙染標誌
1) ``F`` 任何模塊被 ``insmod -f`` 強制加載, ``' '`` 所有模塊正常加載。
- 2) ``S`` 內核é‹è¡Œåœ¨ä¸åˆè¦ç¯„的處ç†å™¨æˆ–系統上:硬體已é‹è¡Œåœ¨ä¸å—支æŒçš„é…置中,
- 因此無法ä¿è­‰æ­£ç¢ºåŸ·è¡Œã€‚內核將被汙染,例如:
+ 2) ``S`` 內核é‹è¡Œåœ¨ä¸åˆè¦ç¯„的處ç†å™¨æˆ–系統上:硬件已é‹è¡Œåœ¨ä¸å—支æŒçš„é…置中,
+ 因此無法ä¿è­‰æ­£ç¢ºåŸ·è¡Œã€‚內核將被污染,例如:
- 在x86上:PAE是通éŽintel CPU(如Pentium M)上的forcepae強制執行的,這些
CPUä¸å ±å‘ŠPAE,但å¯èƒ½æœ‰åŠŸèƒ½å¯¦ç¾ï¼ŒSMP內核在éžå®˜æ–¹æ”¯æŒçš„SMP Athlon CPU上
é‹è¡Œï¼ŒMSR被暴露到用戶空間中。
- 在arm上:在æŸäº›CPU(如Keystone 2)上é‹è¡Œçš„內核,沒有啓用æŸäº›å…§æ ¸ç‰¹æ€§ã€‚
- - 在arm64上:CPU之間存在ä¸åŒ¹é…的硬體特性,引導加載程åºä»¥ä¸åŒçš„模å¼å¼•å°ŽCPU。
+ - 在arm64上:CPU之間存在ä¸åŒ¹é…的硬件特性,引導加載程åºä»¥ä¸åŒçš„模å¼å¼•å°ŽCPU。
- æŸäº›é©…動程åºæ­£åœ¨è¢«ç”¨åœ¨ä¸å—支æŒçš„體系çµæ§‹ä¸Šï¼ˆä¾‹å¦‚x86_64以外的其他系統
上的scsi/snic,éžx86/x86_64/itanium上的scsi/ips,已經æ壞了arm64上
irqchip/irq-gic的固件設置…)。
@@ -131,22 +131,22 @@ BUGã€Oops或Panics消æ¯ä¸­çš„汙染標誌
4) ``M`` 任何處ç†å™¨å ±å‘Šäº†æ©Ÿå™¨æª¢æ¸¬ç•°å¸¸ï¼Œ ``' '`` 未發生機器檢測異常。
- 5) ``B`` é é¢é‡‹æ”¾å‡½æ•¸ç™¼ç¾éŒ¯èª¤çš„é é¢å¼•ç”¨æˆ–æŸäº›æ„外的é é¢æ¨™èªŒã€‚這表示硬體å•é¡Œ
- 或內核錯誤;日誌中應該有其他信æ¯æŒ‡ç¤ºç™¼ç”Ÿæ­¤æ±™æŸ“的原因。
+ 5) ``B`` é é¢é‡‹æ”¾å‡½æ•¸ç™¼ç¾éŒ¯èª¤çš„é é¢å¼•ç”¨æˆ–æŸäº›æ„外的é é¢æ¨™èªŒã€‚這表示硬件å•é¡Œ
+ 或內核錯誤;日誌中應該有其他信æ¯æŒ‡ç¤ºç™¼ç”Ÿæ­¤æ±¡æŸ“的原因。
- 6) ``U`` 用戶或用戶應用程å¼ç‰¹æ„請求設置å—汙染標誌,å¦å‰‡æ‡‰çˆ² ``' '`` 。
+ 6) ``U`` 用戶或用戶應用程åºç‰¹æ„請求設置å—污染標誌,å¦å‰‡æ‡‰çˆ² ``' '`` 。
7) ``D`` 內核最近死機了,å³å‡ºç¾äº†OOPS或BUG。
8) ``A`` ACPI表被é‡å¯«ã€‚
- 9) ``W`` 內核之å‰å·²ç™¼å‡ºéŽè­¦å‘Šï¼ˆå„˜ç®¡æœ‰äº›è­¦å‘Šå¯èƒ½æœƒè¨­ç½®æ›´å…·é«”的汙染標誌)。
+ 9) ``W`` 內核之å‰å·²ç™¼å‡ºéŽè­¦å‘Šï¼ˆå„˜ç®¡æœ‰äº›è­¦å‘Šå¯èƒ½æœƒè¨­ç½®æ›´å…·é«”的污染標誌)。
10) ``C`` 已加載staging驅動程åºã€‚
- 11) ``I`` 內核正在處ç†å¹³å°å›ºä»¶ï¼ˆBIOS或類似軟體)中的嚴é‡éŒ¯èª¤ã€‚
+ 11) ``I`` 內核正在處ç†å¹³è‡ºå›ºä»¶ï¼ˆBIOS或類似軟件)中的嚴é‡éŒ¯èª¤ã€‚
- 12) ``O`` 已加載外部構建(「樹外ã€ï¼‰æ¨¡å¡Šã€‚
+ 12) ``O`` 已加載外部構建(“樹外â€ï¼‰æ¨¡å¡Šã€‚
13) ``E`` 在支æŒæ¨¡å¡Šç°½å的內核中加載了未簽å的模塊。
@@ -154,8 +154,8 @@ BUGã€Oops或Panics消æ¯ä¸­çš„汙染標誌
15) ``K`` 內核已經實時打了補ä¸ã€‚
- 16) ``X`` 備用汙染,由Linux發行版定義和使用。
+ 16) ``X`` 備用污染,由Linux發行版定義和使用。
17) ``T`` 內核構建時使用了randstructæ’件,它å¯ä»¥æœ‰æ„生æˆéžå¸¸ä¸å°‹å¸¸çš„內核çµæ§‹
- 布局(甚至是性能病態的布局),這在調試時éžå¸¸æœ‰ç”¨ã€‚於構建時設置。
+ 佈局(甚至是性能病態的佈局),這在調試時éžå¸¸æœ‰ç”¨ã€‚於構建時設置。
diff --git a/Documentation/translations/zh_TW/admin-guide/unicode.rst b/Documentation/translations/zh_TW/admin-guide/unicode.rst
index 7908b369b85b..a2b48b5d0a64 100644
--- a/Documentation/translations/zh_TW/admin-guide/unicode.rst
+++ b/Documentation/translations/zh_TW/admin-guide/unicode.rst
@@ -37,15 +37,15 @@ IBMPC_MAP IBM code page 437 ESC ( U
USER_MAP User defined ESC ( K
=============== =============================== ================
-特別是 ESC ( U ä¸å†æ˜¯ã€Œç›´é€šå­—é«”ã€ï¼Œå› çˆ²å­—é«”å¯èƒ½èˆ‡IBM字符集完全ä¸åŒã€‚
+特別是 ESC ( U ä¸å†æ˜¯â€œç›´é€šå­—é«”â€ï¼Œå› çˆ²å­—é«”å¯èƒ½èˆ‡IBM字符集完全ä¸åŒã€‚
例如,å³ä½¿åŠ è¼‰äº†ä¸€å€‹Latin-1字體,也å…許使用塊圖形(block graphics)。
請注æ„,儘管這些代碼與ISO 2022類似,但這些代碼åŠå…¶ç”¨é€”都與ISO 2022ä¸åŒ¹é…ï¼›
Linux有兩個八ä½ä»£ç¢¼ï¼ˆG0å’ŒG1),而ISO 2022有四個七ä½ä»£ç¢¼ï¼ˆG0-G3)。
-根據Unicode標準/ISO 10646,U+F000到U+F8FF被ä¿ç•™ç”¨æ–¼ä½œæ¥­ç³»çµ±ç¯„åœå…§çš„分é…
-(Unicode標準將其稱爲「團體å€åŸŸï¼ˆCorporate Zone)ã€ï¼Œå› çˆ²é€™å°æ–¼Linux是ä¸æº–確
-的,所以我們稱之爲「Linuxå€åŸŸã€ï¼‰ã€‚é¸æ“‡U+F000作爲起點,因爲它å…許直接映射
+根據Unicode標準/ISO 10646,U+F000到U+F8FF被ä¿ç•™ç”¨æ–¼æ“作系統範åœå…§çš„分é…
+(Unicode標準將其稱爲“團體å€åŸŸï¼ˆCorporate Zone)â€ï¼Œå› çˆ²é€™å°æ–¼Linux是ä¸æº–確
+的,所以我們稱之爲“Linuxå€åŸŸâ€ï¼‰ã€‚é¸æ“‡U+F000作爲起點,因爲它å…許直接映射
å€åŸŸä»¥2的大å€æ•¸é–‹å§‹ï¼ˆä»¥é˜²éœ€è¦1024或2048個字符的字體)。這就留下U+E000到
U+EFFF作爲最終用戶å€ã€‚
@@ -87,7 +87,7 @@ U+F813 KEYBOARD SYMBOL SOLID APPLE
克林貢(Klingon)語支æŒ
------------------------
-1996年,Linux是世界上第一個添加å°äººå·¥èªžè¨€å…‹æž—貢支æŒçš„作業系統,克林貢是由
+1996年,Linux是世界上第一個添加å°äººå·¥èªžè¨€å…‹æž—貢支æŒçš„æ“作系統,克林貢是由
Marc Okrand爲《星際迷航》電視連續劇創造的。這種編碼後來被徵募Unicode註冊表
(ConScript Unicode Registry,CSUR)採用,並建議(但最終被拒絕)ç´å…¥Unicode
å¹³é¢ä¸€ã€‚ä¸éŽï¼Œå®ƒä»ç„¶æ˜¯Linuxå€åŸŸä¸­çš„Linux/CSURç§æœ‰åˆ†é…。
diff --git a/Documentation/translations/zh_TW/arch/arm/Booting b/Documentation/translations/zh_TW/arch/arm/Booting
new file mode 100644
index 000000000000..a5375f262de2
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/arm/Booting
@@ -0,0 +1,176 @@
+Chinese translated version of Documentation/arch/arm/booting.rst
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly. However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help. Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Maintainer: Russell King <linux@arm.linux.org.uk>
+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
+---------------------------------------------------------------------
+Documentation/arch/arm/booting.rst 的中文翻譯
+
+如果想評論或更新本文的內容,請直接è¯ç¹«åŽŸæ–‡æª”的維護者。如果你使用英文
+交æµæœ‰å›°é›£çš„話,也å¯ä»¥å‘中文版維護者求助。如果本翻譯更新ä¸åŠæ™‚或者翻
+譯存在å•é¡Œï¼Œè«‹è¯ç¹«ä¸­æ–‡ç‰ˆç¶­è­·è€…。
+
+英文版維護者: Russell King <linux@arm.linux.org.uk>
+中文版維護者: 傅煒 Fu Wei <tekkamanninja@gmail.com>
+中文版翻譯者: 傅煒 Fu Wei <tekkamanninja@gmail.com>
+中文版校譯者: 傅煒 Fu Wei <tekkamanninja@gmail.com>
+
+以下爲正文
+---------------------------------------------------------------------
+
+ å•“å‹• ARM Linux
+ ==============
+
+作者:Russell King
+日期:2002年5月18日
+
+以下文檔é©ç”¨æ–¼ 2.4.18-rmk6 åŠä»¥ä¸Šç‰ˆæœ¬ã€‚
+
+爲了啓動 ARM Linux,你需è¦ä¸€å€‹å¼•å°Žè£è¼‰ç¨‹åºï¼ˆboot loader),
+它是一個在主內核啓動å‰é‹è¡Œçš„一個å°ç¨‹åºã€‚引導è£è¼‰ç¨‹åºéœ€è¦åˆå§‹åŒ–å„種
+設備,並最終調用 Linux 內核,將信æ¯å‚³éžçµ¦å…§æ ¸ã€‚
+
+從本質上講,引導è£è¼‰ç¨‹åºæ‡‰æ供(至少)以下功能:
+
+1ã€è¨­ç½®å’Œåˆå§‹åŒ– RAM。
+2ã€åˆå§‹åŒ–一個串å£ã€‚
+3ã€æª¢æ¸¬æ©Ÿå™¨çš„類型(machine type)。
+4ã€è¨­ç½®å…§æ ¸æ¨™ç±¤åˆ—表(tagged list)。
+5ã€èª¿ç”¨å…§æ ¸æ˜ åƒã€‚
+
+
+1ã€è¨­ç½®å’Œåˆå§‹åŒ– RAM
+-------------------
+
+ç¾æœ‰çš„引導加載程åº: 強制
+新開發的引導加載程åº: 強制
+
+引導è£è¼‰ç¨‹åºæ‡‰è©²æ‰¾åˆ°ä¸¦åˆå§‹åŒ–系統中所有內核用於ä¿æŒç³»çµ±è®Šé‡æ•¸æ“šçš„ RAM。
+這個æ“作的執行是設備ä¾è³´çš„。(它å¯èƒ½ä½¿ç”¨å…§éƒ¨ç®—法來自動定ä½å’Œè¨ˆç®—所有
+RAM,或å¯èƒ½ä½¿ç”¨å°é€™å€‹è¨­å‚™å·²çŸ¥çš„ RAM ä¿¡æ¯ï¼Œé‚„å¯èƒ½ä½¿ç”¨ä»»ä½•å¼•å°Žè£è¼‰ç¨‹åº
+設計者想到的匹é…方法。)
+
+
+2ã€åˆå§‹åŒ–一個串å£
+-----------------------------
+
+ç¾æœ‰çš„引導加載程åº: å¯é¸ã€å»ºè­°
+新開發的引導加載程åº: å¯é¸ã€å»ºè­°
+
+引導加載程åºæ‡‰è©²åˆå§‹åŒ–並使能一個目標æ¿ä¸Šçš„串å£ã€‚這å…許內核串å£é©…å‹•
+自動檢測哪個串å£ç”¨æ–¼å…§æ ¸æŽ§åˆ¶æª¯ã€‚(一般用於調試或與目標æ¿é€šä¿¡ã€‚)
+
+作爲替代方案,引導加載程åºä¹Ÿå¯ä»¥é€šéŽæ¨™ç±¤åˆ—表傳éžç›¸é—œçš„'console='
+é¸é …給內核以指定æŸå€‹ä¸²å£ï¼Œè€Œä¸²å£æ•¸æ“šæ ¼å¼çš„é¸é …在以下文檔中æ述:
+
+ Documentation/admin-guide/kernel-parameters.rst。
+
+
+3ã€æª¢æ¸¬æ©Ÿå™¨é¡žåž‹
+--------------------------
+
+ç¾æœ‰çš„引導加載程åº: å¯é¸
+新開發的引導加載程åº: 強制
+
+引導加載程åºæ‡‰è©²é€šéŽæŸäº›æ–¹å¼æª¢æ¸¬è‡ªèº«æ‰€è™•çš„機器類型。這是一個硬件
+代碼或通éŽæŸ¥çœ‹æ‰€é€£æŽ¥çš„硬件用æŸäº›ç®—法得到,這些超出了本文檔的範åœã€‚
+引導加載程åºæœ€çµ‚必須能æ供一個 MACH_TYPE_xxx 值給內核。
+(詳見 linux/arch/arm/tools/mach-types )。
+
+4ã€è¨­ç½®å•“動數據
+------------------
+
+ç¾æœ‰çš„引導加載程åº: å¯é¸ã€å¼·çƒˆå»ºè­°
+新開發的引導加載程åº: 強制
+
+引導加載程åºå¿…é ˆæ供標籤列表或者 dtb 映åƒä»¥å‚³éžé…置數據給內核。啓動
+數據的物ç†åœ°å€é€šéŽå¯„存器 r2 傳éžçµ¦å…§æ ¸ã€‚
+
+4aã€è¨­ç½®å…§æ ¸æ¨™ç±¤åˆ—表
+--------------------------------
+
+bootloader 必須創建和åˆå§‹åŒ–內核標籤列表。一個有效的標籤列表以
+ATAG_CORE 標籤開始,並以 ATAG_NONE 標籤çµæŸã€‚ATAG_CORE 標籤å¯ä»¥æ˜¯
+空的,也å¯ä»¥æ˜¯éžç©ºã€‚一個空 ATAG_CORE 標籤其 size 域設置爲
+‘2’(0x00000002)。ATAG_NONE 標籤的 size 域必須設置爲零。
+
+在列表中å¯ä»¥ä¿å­˜ä»»æ„數é‡çš„標籤。å°æ–¼ä¸€å€‹é‡è¤‡çš„標籤是追加到之å‰æ¨™ç±¤
+所攜帶的信æ¯ä¹‹å¾Œï¼Œé‚„是會覆蓋原來的信æ¯ï¼Œæ˜¯æœªå®šç¾©çš„。æŸäº›æ¨™ç±¤çš„行爲
+是å‰è€…,其他是後者。
+
+bootloader 必須傳éžä¸€å€‹ç³»çµ±å…§å­˜çš„ä½ç½®å’Œæœ€å°å€¼ï¼Œä»¥åŠæ ¹æ–‡ä»¶ç³»çµ±ä½ç½®ã€‚
+因此,最å°çš„標籤列表如下所示:
+
+ +-----------+
+åŸºåœ°å€ -> | ATAG_CORE | |
+ +-----------+ |
+ | ATAG_MEM | | 地å€å¢žé•·æ–¹å‘
+ +-----------+ |
+ | ATAG_NONE | |
+ +-----------+ v
+
+標籤列表應該ä¿å­˜åœ¨ç³»çµ±çš„ RAM 中。
+
+標籤列表必須置於內核自解壓和 initrd'bootp' 程åºéƒ½ä¸æœƒè¦†è“‹çš„內存å€ã€‚
+建議放在 RAM 的頭 16KiB 中。
+
+4bã€è¨­ç½®è¨­å‚™æ¨¹
+-------------------------
+
+bootloader 必須以 64bit 地å€å°é½Šçš„å½¢å¼åŠ è¼‰ä¸€å€‹è¨­å‚™æ¨¹æ˜ åƒ(dtb)到系統
+RAM 中,並用啓動數據åˆå§‹åŒ–它。dtb æ ¼å¼åœ¨æ–‡æª”
+https://www.devicetree.org/specifications/ 中。內核將會在
+dtb 物ç†åœ°å€è™•æŸ¥æ‰¾ dtb 魔數值(0xd00dfeed),以確定 dtb 是å¦å·²ç¶“代替
+標籤列表被傳éžé€²ä¾†ã€‚
+
+bootloader 必須傳éžä¸€å€‹ç³»çµ±å…§å­˜çš„ä½ç½®å’Œæœ€å°å€¼ï¼Œä»¥åŠæ ¹æ–‡ä»¶ç³»çµ±ä½ç½®ã€‚
+dtb 必須置於內核自解壓ä¸æœƒè¦†è“‹çš„內存å€ã€‚建議將其放置於 RAM çš„é ­ 16KiB
+中。但是ä¸å¯å°‡å…¶æ”¾ç½®æ–¼â€œ0â€ç‰©ç†åœ°å€è™•ï¼Œå› çˆ²å…§æ ¸èªçˆ²ï¼šr2 中爲 0,æ„味ç€
+沒有標籤列表和 dtb 傳éžéŽä¾†ã€‚
+
+5ã€èª¿ç”¨å…§æ ¸æ˜ åƒ
+---------------------------
+
+ç¾æœ‰çš„引導加載程åº: 強制
+新開發的引導加載程åº: 強制
+
+èª¿ç”¨å…§æ ¸æ˜ åƒ zImage 有兩個é¸æ“‡ã€‚如果 zImge ä¿å­˜åœ¨ flash 中,且是爲了
+在 flash 中直接é‹è¡Œè€Œè¢«æ­£ç¢ºéˆæŽ¥çš„。這樣引導加載程åºå°±å¯ä»¥åœ¨ flash 中
+直接調用 zImage。
+
+zImage 也å¯ä»¥è¢«æ”¾åœ¨ç³»çµ± RAM(任æ„ä½ç½®ï¼‰ä¸­è¢«èª¿ç”¨ã€‚注æ„:內核使用映åƒ
+基地å€çš„å‰ 16KB RAM 空間來ä¿å­˜é è¡¨ã€‚建議將映åƒç½®æ–¼ RAM çš„ 32KB 處。
+
+å°æ–¼ä»¥ä¸Šä»»æ„一種情æ³ï¼Œéƒ½å¿…須符åˆä»¥ä¸‹å•“動狀態:
+
+- åœæ­¢æ‰€æœ‰ DMA 設備,這樣內存數據就ä¸æœƒå› çˆ²è™›å‡ç¶²çµ¡åŒ…或ç£ç›¤æ•¸æ“šè€Œè¢«ç ´å£žã€‚
+ 這å¯èƒ½å¯ä»¥ç¯€çœä½ è¨±å¤šçš„調試時間。
+
+- CPU 寄存器é…ç½®
+ r0 = 0,
+ r1 = ï¼ˆåœ¨ä¸Šé¢ 3 中ç²å–的)機器類型碼。
+ r2 = 標籤列表在系統 RAM 中的物ç†åœ°å€ï¼Œæˆ–
+ 設備樹塊(dtb)在系統 RAM 中的物ç†åœ°å€
+
+- CPU 模å¼
+ 所有形å¼çš„中斷必須被ç¦æ­¢ (IRQs å’Œ FIQs)
+ CPU 必須處於 SVC 模å¼ã€‚(å°æ–¼ Angel 調試有特例存在)
+
+- 緩存,MMUs
+ MMU 必須關閉。
+ 指令緩存開啓或關閉都å¯ä»¥ã€‚
+ 數據緩存必須關閉。
+
+- 引導加載程åºæ‡‰è©²é€šéŽç›´æŽ¥è·³è½‰åˆ°å…§æ ¸æ˜ åƒçš„第一æ¢æŒ‡ä»¤ä¾†èª¿ç”¨å…§æ ¸æ˜ åƒã€‚
+
+ å°æ–¼æ”¯æŒ ARM 指令集的 CPU,跳入內核入å£æ™‚必須處在 ARM 狀態,å³ä½¿
+ å°æ–¼ Thumb-2 內核也是如此。
+
+ å°æ–¼åƒ…æ”¯æŒ Thumb 指令集的 CPU,比如 Cortex-M 系列的 CPU,跳入
+ 內核入å£æ™‚必須處於 Thumb 狀態。
+
diff --git a/Documentation/translations/zh_TW/arch/arm/kernel_user_helpers.txt b/Documentation/translations/zh_TW/arch/arm/kernel_user_helpers.txt
new file mode 100644
index 000000000000..4c0bff97af31
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/arm/kernel_user_helpers.txt
@@ -0,0 +1,285 @@
+Chinese translated version of Documentation/arch/arm/kernel_user_helpers.rst
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly. However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help. Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Maintainer: Nicolas Pitre <nicolas.pitre@linaro.org>
+ Dave Martin <dave.martin@linaro.org>
+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
+---------------------------------------------------------------------
+Documentation/arch/arm/kernel_user_helpers.rst 的中文翻譯
+
+如果想評論或更新本文的內容,請直接è¯ç¹«åŽŸæ–‡æª”的維護者。如果你使用英文
+交æµæœ‰å›°é›£çš„話,也å¯ä»¥å‘中文版維護者求助。如果本翻譯更新ä¸åŠæ™‚或者翻
+譯存在å•é¡Œï¼Œè«‹è¯ç¹«ä¸­æ–‡ç‰ˆç¶­è­·è€…。
+英文版維護者: Nicolas Pitre <nicolas.pitre@linaro.org>
+ Dave Martin <dave.martin@linaro.org>
+中文版維護者: 傅煒 Fu Wei <tekkamanninja@gmail.com>
+中文版翻譯者: 傅煒 Fu Wei <tekkamanninja@gmail.com>
+中文版校譯者: 宋冬生 Dongsheng Song <dongshneg.song@gmail.com>
+ å‚…ç…’ Fu Wei <tekkamanninja@gmail.com>
+
+
+以下爲正文
+---------------------------------------------------------------------
+內核æ供的用戶空間輔助代碼
+=========================
+
+在內核內存空間的固定地å€è™•ï¼Œæœ‰ä¸€å€‹ç”±å…§æ ¸æ供並å¯å¾žç”¨æˆ¶ç©ºé–“訪å•çš„代碼
+段。它用於å‘用戶空間æ供因在許多 ARM CPU 中未實ç¾çš„特性和/或指令而需
+內核æ供幫助的æŸäº›æ“作。這些代碼直接在用戶模å¼ä¸‹åŸ·è¡Œçš„想法是爲了ç²å¾—
+最佳效率,但那些與內核計數器è¯ç¹«éŽæ–¼ç·Šå¯†çš„部分,則被留給了用戶庫實ç¾ã€‚
+事實上,此代碼甚至å¯èƒ½å› ä¸åŒçš„ CPU 而異,這å–決於其å¯ç”¨çš„指令集或它
+是å¦çˆ² SMP 系統。æ›å¥è©±èªªï¼Œå…§æ ¸ä¿ç•™åœ¨ä¸ä½œå‡ºè­¦å‘Šçš„情æ³ä¸‹æ ¹æ“šéœ€è¦æ›´æ”¹
+這些代碼的權利。åªæœ‰æœ¬æ–‡æª”æè¿°çš„å…¥å£åŠå…¶çµæžœæ˜¯ä¿è­‰ç©©å®šçš„。
+
+這與完全æˆç†Ÿçš„ VDSO 實ç¾ä¸åŒï¼ˆä½†å…©è€…並ä¸è¡çªï¼‰ï¼Œå„˜ç®¡å¦‚此,VDSO å¯é˜»æ­¢
+æŸäº›é€šéŽå¸¸é‡é«˜æ•ˆè·³è½‰åˆ°é‚£äº›ä»£ç¢¼æ®µçš„彙編技巧。且由於那些代碼段在返回用戶
+代碼å‰åƒ…使用少é‡çš„代碼週期,則一個 VDSO 間接é ç¨‹èª¿ç”¨å°‡æœƒåœ¨é€™äº›ç°¡å–®çš„
+æ“作上增加一個å¯æ¸¬é‡çš„開銷。
+
+在å°é‚£äº›æ“有原生支æŒçš„新型處ç†å™¨é€²è¡Œä»£ç¢¼å„ªåŒ–時,僅在已爲其他æ“作使用
+了類似的新增指令,而導致二進制çµæžœå·²èˆ‡æ—©æœŸ ARM 處ç†å™¨ä¸å…¼å®¹çš„情æ³ä¸‹ï¼Œ
+用戶空間æ‰æ‡‰ç¹žéŽé€™äº›è¼”助代碼,並在內è¯å‡½æ•¸ä¸­å¯¦ç¾é€™äº›æ“作(無論是通éŽ
+編譯器在代碼中直接放置,還是作爲庫函數調用實ç¾çš„一部分)。也就是說,
+如果你編譯的代碼ä¸æœƒçˆ²äº†å…¶ä»–目的使用新指令,則ä¸è¦åƒ…爲了é¿å…使用這些
+內核輔助代碼,導致二進制程åºç„¡æ³•åœ¨æ—©æœŸè™•ç†å™¨ä¸Šé‹è¡Œã€‚
+
+新的輔助代碼å¯èƒ½éš¨ç€æ™‚間的推移而增加,所以新內核中的æŸäº›è¼”助代碼在舊
+內核中å¯èƒ½ä¸å­˜åœ¨ã€‚因此,程åºå¿…須在å°ä»»ä½•è¼”助代碼調用å‡è¨­æ˜¯å®‰å…¨ä¹‹å‰ï¼Œ
+檢測 __kuser_helper_version 的值(見下文)。ç†æƒ³æƒ…æ³ä¸‹ï¼Œé€™ç¨®æª¢æ¸¬æ‡‰è©²
+åªåœ¨é€²ç¨‹å•“動時執行一次;如果內核版本ä¸æ”¯æŒæ‰€éœ€è¼”助代碼,則該進程å¯å„˜æ—©
+中止執行。
+
+kuser_helper_version
+--------------------
+
+ä½ç½®: 0xffff0ffc
+
+åƒè€ƒè²æ˜Ž:
+
+ extern int32_t __kuser_helper_version;
+
+定義:
+
+ 這個å€åŸŸåŒ…å«äº†ç•¶å‰é‹è¡Œå…§æ ¸å¯¦ç¾çš„輔助代碼版本號。用戶空間å¯ä»¥é€šéŽè®€
+ å–此版本號以確定特定的輔助代碼是å¦å­˜åœ¨ã€‚
+
+使用範例:
+
+#define __kuser_helper_version (*(int32_t *)0xffff0ffc)
+
+void check_kuser_version(void)
+{
+ if (__kuser_helper_version < 2) {
+ fprintf(stderr, "can't do atomic operations, kernel too old\n");
+ abort();
+ }
+}
+
+注æ„:
+
+ 用戶空間å¯ä»¥å‡è¨­é€™å€‹åŸŸçš„值ä¸æœƒåœ¨ä»»ä½•å–®å€‹é€²ç¨‹çš„生存期內改變。也就
+ 是說,這個域å¯ä»¥åƒ…在庫的åˆå§‹åŒ–階段或進程啓動階段讀å–一次。
+
+kuser_get_tls
+-------------
+
+ä½ç½®: 0xffff0fe0
+
+åƒè€ƒåŽŸåž‹:
+
+ void * __kuser_get_tls(void);
+
+輸入:
+
+ lr = 返回地å€
+
+輸出:
+
+ r0 = TLS 值
+
+被篡改的寄存器:
+
+ ç„¡
+
+定義:
+
+ ç²å–之å‰é€šéŽ __ARM_NR_set_tls 系統調用設置的 TLS 值。
+
+使用範例:
+
+typedef void * (__kuser_get_tls_t)(void);
+#define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0)
+
+void foo()
+{
+ void *tls = __kuser_get_tls();
+ printf("TLS = %p\n", tls);
+}
+
+注æ„:
+
+ - 僅在 __kuser_helper_version >= 1 時,此輔助代碼存在
+ (從內核版本 2.6.12 開始)。
+
+kuser_cmpxchg
+-------------
+
+ä½ç½®: 0xffff0fc0
+
+åƒè€ƒåŽŸåž‹:
+
+ int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr);
+
+輸入:
+
+ r0 = oldval
+ r1 = newval
+ r2 = ptr
+ lr = 返回地å€
+
+輸出:
+
+ r0 = æˆåŠŸä»£ç¢¼ (零或éžé›¶)
+ C flag = 如果 r0 == 0 則置 1,如果 r0 != 0 則清零。
+
+被篡改的寄存器:
+
+ r3, ip, flags
+
+定義:
+
+ 僅在 *ptr 爲 oldval 時原å­ä¿å­˜ newval æ–¼ *ptr 中。
+ 如果 *ptr 被改變,則返回值爲零,å¦å‰‡çˆ²éžé›¶å€¼ã€‚
+ 如果 *ptr 被改變,則 C flag 也會被置 1,以實ç¾èª¿ç”¨ä»£ç¢¼ä¸­çš„彙編
+ 優化。
+
+使用範例:
+
+typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
+#define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0)
+
+int atomic_add(volatile int *ptr, int val)
+{
+ int old, new;
+
+ do {
+ old = *ptr;
+ new = old + val;
+ } while(__kuser_cmpxchg(old, new, ptr));
+
+ return new;
+}
+
+注æ„:
+
+ - 這個例程已根據需è¦åŒ…å«äº†å…§å­˜å±éšœã€‚
+
+ - 僅在 __kuser_helper_version >= 2 時,此輔助代碼存在
+ (從內核版本 2.6.12 開始)。
+
+kuser_memory_barrier
+--------------------
+
+ä½ç½®: 0xffff0fa0
+
+åƒè€ƒåŽŸåž‹:
+
+ void __kuser_memory_barrier(void);
+
+輸入:
+
+ lr = 返回地å€
+
+輸出:
+
+ ç„¡
+
+被篡改的寄存器:
+
+ ç„¡
+
+定義:
+
+ 應用於任何需è¦å…§å­˜å±éšœä»¥é˜²æ­¢æ‰‹å‹•æ•¸æ“šä¿®æ”¹å¸¶ä¾†çš„一致性å•é¡Œï¼Œä»¥åŠ
+ __kuser_cmpxchg 中。
+
+使用範例:
+
+typedef void (__kuser_dmb_t)(void);
+#define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0)
+
+注æ„:
+
+ - 僅在 __kuser_helper_version >= 3 時,此輔助代碼存在
+ (從內核版本 2.6.15 開始)。
+
+kuser_cmpxchg64
+---------------
+
+ä½ç½®: 0xffff0f60
+
+åƒè€ƒåŽŸåž‹:
+
+ int __kuser_cmpxchg64(const int64_t *oldval,
+ const int64_t *newval,
+ volatile int64_t *ptr);
+
+輸入:
+
+ r0 = æŒ‡å‘ oldval
+ r1 = æŒ‡å‘ newval
+ r2 = 指å‘目標值
+ lr = 返回地å€
+
+輸出:
+
+ r0 = æˆåŠŸä»£ç¢¼ (零或éžé›¶)
+ C flag = 如果 r0 == 0 則置 1,如果 r0 != 0 則清零。
+
+被篡改的寄存器:
+
+ r3, lr, flags
+
+定義:
+
+ 僅在 *ptr 等於 *oldval 指å‘çš„ 64 ä½å€¼æ™‚,原å­ä¿å­˜ *newval
+ 指å‘çš„ 64 ä½å€¼æ–¼ *ptr 中。如果 *ptr 被改變,則返回值爲零,
+ å¦å‰‡çˆ²éžé›¶å€¼ã€‚
+
+ 如果 *ptr 被改變,則 C flag 也會被置 1,以實ç¾èª¿ç”¨ä»£ç¢¼ä¸­çš„彙編
+ 優化。
+
+使用範例:
+
+typedef int (__kuser_cmpxchg64_t)(const int64_t *oldval,
+ const int64_t *newval,
+ volatile int64_t *ptr);
+#define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t *)0xffff0f60)
+
+int64_t atomic_add64(volatile int64_t *ptr, int64_t val)
+{
+ int64_t old, new;
+
+ do {
+ old = *ptr;
+ new = old + val;
+ } while(__kuser_cmpxchg64(&old, &new, ptr));
+
+ return new;
+}
+
+注æ„:
+
+ - 這個例程已根據需è¦åŒ…å«äº†å…§å­˜å±éšœã€‚
+
+ - 由於這個éŽç¨‹çš„代碼長度(此輔助代碼跨越 2 個常è¦çš„ kuser “槽â€ï¼‰ï¼Œ
+ å› æ­¤ 0xffff0f80 ä¸è¢«ä½œçˆ²æœ‰æ•ˆçš„å…¥å£é»žã€‚
+
+ - 僅在 __kuser_helper_version >= 5 時,此輔助代碼存在
+ (從內核版本 3.1 開始)。
+
diff --git a/Documentation/translations/zh_TW/arch/arm64/amu.rst b/Documentation/translations/zh_TW/arch/arm64/amu.rst
index 21ac0db63889..1b451eae2bee 100644
--- a/Documentation/translations/zh_TW/arch/arm64/amu.rst
+++ b/Documentation/translations/zh_TW/arch/arm64/amu.rst
@@ -28,11 +28,11 @@ AArch64 Linux 中擴展的活動監控單元
AMUv1 架構實ç¾äº†ä¸€å€‹ç”±4個固定的64ä½äº‹ä»¶è¨ˆæ•¸å™¨çµ„æˆçš„計數器組。
- - CPU å‘¨æœŸè¨ˆæ•¸å™¨ï¼šåŒ CPU 的頻率增長
+ - CPU é€±æœŸè¨ˆæ•¸å™¨ï¼šåŒ CPU 的頻率增長
- 常é‡è¨ˆæ•¸å™¨ï¼šåŒå›ºå®šçš„系統時é˜é »çŽ‡å¢žé•·
- 淘汰指令計數器: åŒæ¯æ¬¡æž¶æ§‹æŒ‡ä»¤åŸ·è¡Œå¢žé•·
- - 內存åœé “周期計數器:計算由在時é˜åŸŸå…§çš„最後一級緩存中未命中而引起
- 的指令調度åœé “周期數
+ - 內存åœé “週期計數器:計算由在時é˜åŸŸå…§çš„最後一級緩存中未命中而引起
+ 的指令調度åœé “週期數
當處於 WFI 或者 WFE 狀態時,計數器ä¸æœƒå¢žé•·ã€‚
diff --git a/Documentation/translations/zh_TW/arch/arm64/booting.txt b/Documentation/translations/zh_TW/arch/arm64/booting.txt
index 3cc8f593e006..be0de91ecebd 100644
--- a/Documentation/translations/zh_TW/arch/arm64/booting.txt
+++ b/Documentation/translations/zh_TW/arch/arm64/booting.txt
@@ -41,8 +41,8 @@ AArch64 異常模型由多個異常級(EL0 - EL3)組æˆï¼Œå°æ–¼ EL0 å’Œ EL1
有å°æ‡‰çš„安全和éžå®‰å…¨æ¨¡å¼ã€‚EL2 是系統管ç†ç´šï¼Œä¸”僅存在於éžå®‰å…¨æ¨¡å¼ä¸‹ã€‚
EL3 是最高特權級,且僅存在於安全模å¼ä¸‹ã€‚
-基於本文檔的目的,我們將簡單地使用『引導è£è¼‰ç¨‹åºã€ï¼ˆã€Žboot loaderã€ï¼‰
-這個術語來定義在將控制權交給 Linux å…§æ ¸å‰ CPU 上執行的所有軟體。
+基於本文檔的目的,我們將簡單地使用‘引導è£è¼‰ç¨‹åºâ€™ï¼ˆâ€˜boot loader’)
+這個術語來定義在將控制權交給 Linux å…§æ ¸å‰ CPU 上執行的所有軟件。
這å¯èƒ½åŒ…å«å®‰å…¨ç›£æŽ§å’Œç³»çµ±ç®¡ç†ä»£ç¢¼ï¼Œæˆ–者它å¯èƒ½åªæ˜¯ä¸€äº›ç”¨æ–¼æº–備最å°å•“å‹•
環境的指令。
@@ -74,7 +74,7 @@ RAM,或å¯èƒ½ä½¿ç”¨å°é€™å€‹è¨­å‚™å·²çŸ¥çš„ RAM ä¿¡æ¯ï¼Œé‚„å¯èƒ½æ˜¯å¼•å°Žè£
數據塊將在使能緩存的情æ³ä¸‹ä»¥ 2MB 粒度被映射,故其ä¸èƒ½è¢«ç½®æ–¼å¿…須以特定
屬性映射的2Må€åŸŸå…§ã€‚
-註: v4.2 之å‰çš„版本åŒæ™‚è¦æ±‚設備樹數據塊被置於從內核映åƒä»¥ä¸‹
+注: v4.2 之å‰çš„版本åŒæ™‚è¦æ±‚設備樹數據塊被置於從內核映åƒä»¥ä¸‹
text_offset 字節處算起第一個 512MB 內。
3ã€è§£å£“內核映åƒ
@@ -106,7 +106,7 @@ AArch64 內核當å‰æ²’有æ供自解壓代碼,因此如果使用了壓縮內
u32 res5; /* ä¿ç•™ (用於 PE COFF å移) */
-映åƒé ­æ³¨é‡‹ï¼š
+映åƒé ­è¨»é‡‹ï¼š
- 自 v3.17 起,除éžå¦æœ‰èªªæ˜Žï¼Œæ‰€æœ‰åŸŸéƒ½æ˜¯å°ç«¯æ¨¡å¼ã€‚
@@ -143,7 +143,7 @@ AArch64 內核當å‰æ²’有æ供自解壓代碼,因此如果使用了壓縮內
字節處,並從該處被調用。2MB å°é½ŠåŸºå€å’Œå…§æ ¸æ˜ åƒèµ·å§‹åœ°å€ä¹‹é–“çš„å€åŸŸå°æ–¼
內核來說沒有特殊æ„義,且å¯èƒ½è¢«ç”¨æ–¼å…¶ä»–目的。
從映åƒèµ·å§‹åœ°å€ç®—起,最少必須準備 image_size 字節的空閒內存供內核使用。
-註: v4.6 之å‰çš„版本無法使用內核映åƒç‰©ç†å移以下的內存,所以當時建議
+注: v4.6 之å‰çš„版本無法使用內核映åƒç‰©ç†å移以下的內存,所以當時建議
將映åƒå„˜é‡æ”¾ç½®åœ¨é è¿‘系統內存起始的地方。
任何æ供給內核的內存(甚至在映åƒèµ·å§‹åœ°å€ä¹‹å‰ï¼‰ï¼Œè‹¥æœªå¾žå…§æ ¸ä¸­æ¨™è¨˜çˆ²ä¿ç•™
@@ -151,7 +151,7 @@ AArch64 內核當å‰æ²’有æ供自解壓代碼,因此如果使用了壓縮內
在跳轉入內核å‰ï¼Œå¿…須符åˆä»¥ä¸‹ç‹€æ…‹ï¼š
-- åœæ­¢æ‰€æœ‰ DMA 設備,這樣內存數據就ä¸æœƒå› çˆ²è™›å‡ç¶²çµ¡åŒ…或ç£ç¢Ÿæ•¸æ“šè€Œ
+- åœæ­¢æ‰€æœ‰ DMA 設備,這樣內存數據就ä¸æœƒå› çˆ²è™›å‡ç¶²çµ¡åŒ…或ç£ç›¤æ•¸æ“šè€Œ
被破壞。這å¯èƒ½å¯ä»¥ç¯€çœä½ è¨±å¤šçš„調試時間。
- 主 CPU 通用寄存器設置
@@ -175,7 +175,7 @@ AArch64 內核當å‰æ²’有æ供自解壓代碼,因此如果使用了壓縮內
而ä¸é€šéŽè™›æ“¬åœ°å€æ“作維護構架緩存的系統緩存(ä¸æŽ¨è–¦ï¼‰ï¼Œå¿…須被é…置且
ç¦ç”¨ã€‚
- *譯者註:å°æ–¼ PoC 以åŠç·©å­˜ç›¸é—œå…§å®¹ï¼Œè«‹åƒè€ƒ ARMv8 構架åƒè€ƒæ‰‹å†Š
+ *譯者注:å°æ–¼ PoC 以åŠç·©å­˜ç›¸é—œå…§å®¹ï¼Œè«‹åƒè€ƒ ARMv8 構架åƒè€ƒæ‰‹å†Š
ARM DDI 0487A
- 架構計時器
@@ -189,7 +189,7 @@ AArch64 內核當å‰æ²’有æ供自解壓代碼,因此如果使用了壓縮內
接收。
- 系統寄存器
- 在進入內核映åƒçš„異常級中,所有構架中å¯å¯«çš„系統寄存器必須通éŽè»Ÿé«”
+ 在進入內核映åƒçš„異常級中,所有構架中å¯å¯«çš„系統寄存器必須通éŽè»Ÿä»¶
在一個更高的異常級別下åˆå§‹åŒ–,以防止在 未知 狀態下é‹è¡Œã€‚
å°æ–¼æ“有 GICv3 中斷控制器並以 v3 模å¼é‹è¡Œçš„系統:
@@ -214,14 +214,14 @@ AArch64 內核當å‰æ²’有æ供自解壓代碼,因此如果使用了壓縮內
引導è£è¼‰ç¨‹åºå¿…須在æ¯å€‹ CPU 處於以下狀態時跳入內核入å£ï¼š
- 主 CPU 必須直接跳入內核映åƒçš„第一æ¢æŒ‡ä»¤ã€‚通éŽæ­¤ CPU 傳éžçš„設備樹
- 數據塊必須在æ¯å€‹ CPU 節點中包å«ä¸€å€‹ 『enable-method〠屬性,所
+ 數據塊必須在æ¯å€‹ CPU 節點中包å«ä¸€å€‹ ‘enable-method’ 屬性,所
支æŒçš„ enable-method 請見下文。
引導è£è¼‰ç¨‹åºå¿…須生æˆé€™äº›è¨­å‚™æ¨¹å±¬æ€§ï¼Œä¸¦åœ¨è·³å…¥å…§æ ¸å…¥å£ä¹‹å‰å°‡å…¶æ’å…¥
數據塊。
-- enable-method 爲 「spin-table〠的 CPU 必須在它們的 CPU
- 節點中包å«ä¸€å€‹ 『cpu-release-addr〠屬性。這個屬性標識了一個
+- enable-method 爲 “spin-table†的 CPU 必須在它們的 CPU
+ 節點中包å«ä¸€å€‹ ‘cpu-release-addr’ 屬性。這個屬性標識了一個
64 ä½è‡ªç„¶å°é½Šä¸”åˆå§‹åŒ–爲零的內存ä½ç½®ã€‚
這些 CPU 必須在內存ä¿ç•™å€ï¼ˆé€šéŽè¨­å‚™æ¨¹ä¸­çš„ /memreserve/ 域傳éž
@@ -231,15 +231,15 @@ AArch64 內核當å‰æ²’有æ供自解壓代碼,因此如果使用了壓縮內
時,CPU 必須跳入此值所指å‘的地å€ã€‚此值爲一個單ç¨çš„ 64 ä½å°ç«¯å€¼ï¼Œ
å› æ­¤ CPU 須在跳轉å‰å°‡æ‰€è®€å–的值轉æ›çˆ²å…¶æœ¬èº«çš„端模å¼ã€‚
-- enable-method 爲 「psci〠的 CPU ä¿æŒåœ¨å…§æ ¸å¤–(比如,在
+- enable-method 爲 “psci†的 CPU ä¿æŒåœ¨å…§æ ¸å¤–(比如,在
memory 節點中æ述爲內核空間的內存å€å¤–,或在通éŽè¨­å‚™æ¨¹ /memreserve/
域中æ述爲內核ä¿ç•™å€çš„空間中)。內核將會發起在 ARM 文檔(編號
- ARM DEN 0022A:用於 ARM 上的電æºç‹€æ…‹å”調接å£ç³»çµ±è»Ÿé«”)中æè¿°çš„
+ ARM DEN 0022A:用於 ARM 上的電æºç‹€æ…‹å”調接å£ç³»çµ±è»Ÿä»¶ï¼‰ä¸­æè¿°çš„
CPU_ON 調用來將 CPU 帶入內核。
*譯者注: ARM DEN 0022A 已更新到 ARM DEN 0022C。
- 設備樹必須包å«ä¸€å€‹ 『psci〠節點,請åƒè€ƒä»¥ä¸‹æ–‡æª”:
+ 設備樹必須包å«ä¸€å€‹ ‘psci’ 節點,請åƒè€ƒä»¥ä¸‹æ–‡æª”:
Documentation/devicetree/bindings/arm/psci.yaml
diff --git a/Documentation/translations/zh_TW/arch/arm64/elf_hwcaps.rst b/Documentation/translations/zh_TW/arch/arm64/elf_hwcaps.rst
index ca7ff749a67b..d2c1c2f23812 100644
--- a/Documentation/translations/zh_TW/arch/arm64/elf_hwcaps.rst
+++ b/Documentation/translations/zh_TW/arch/arm64/elf_hwcaps.rst
@@ -17,11 +17,11 @@ ARM64 ELF hwcaps
1. 簡介
-------
-有些硬體或軟體功能僅在æŸäº› CPU 實ç¾ä¸Šå’Œ/或在具體æŸå€‹å…§æ ¸é…置上å¯ç”¨ï¼Œä½†
+有些硬件或軟件功能僅在æŸäº› CPU 實ç¾ä¸Šå’Œ/或在具體æŸå€‹å…§æ ¸é…置上å¯ç”¨ï¼Œä½†
å°æ–¼è™•æ–¼ EL0 的用戶空間代碼沒有å¯ç”¨çš„架構發ç¾æ©Ÿåˆ¶ã€‚內核通éŽåœ¨è¼”助å‘é‡è¡¨
公開一組稱爲 hwcaps 的標誌而把這些功能暴露給用戶空間。
-用戶空間軟體å¯ä»¥é€šéŽç²å–輔助å‘é‡çš„ AT_HWCAP 或 AT_HWCAP2 æ¢ç›®ä¾†æ¸¬è©¦åŠŸèƒ½ï¼Œ
+用戶空間軟件å¯ä»¥é€šéŽç²å–輔助å‘é‡çš„ AT_HWCAP 或 AT_HWCAP2 æ¢ç›®ä¾†æ¸¬è©¦åŠŸèƒ½ï¼Œ
並測試是å¦è¨­ç½®äº†ç›¸é—œæ¨™èªŒï¼Œä¾‹å¦‚::
bool floating_point_is_present(void)
@@ -33,7 +33,7 @@ ARM64 ELF hwcaps
return false;
}
-如果軟體ä¾è³´æ–¼ hwcap æ述的功能,在嘗試使用該功能å‰å‰‡æ‡‰æª¢æŸ¥ç›¸é—œçš„ hwcap
+如果軟件ä¾è³´æ–¼ hwcap æ述的功能,在嘗試使用該功能å‰å‰‡æ‡‰æª¢æŸ¥ç›¸é—œçš„ hwcap
標誌以驗證該功能是å¦å­˜åœ¨ã€‚
ä¸èƒ½é€šéŽå…¶ä»–æ–¹å¼æŽ¢æŸ¥é€™äº›åŠŸèƒ½ã€‚當一個功能ä¸å¯ç”¨æ™‚,嘗試使用它å¯èƒ½å°Žè‡´ä¸å¯
@@ -44,8 +44,8 @@ ARM64 ELF hwcaps
----------------
大多數 hwcaps 旨在說明通éŽæž¶æ§‹ ID 寄存器(處於 EL0 的用戶空間代碼無法訪å•)
-æ述的功能的存在。這些 hwcap é€šéŽ ID 寄存器欄ä½å®šç¾©ï¼Œä¸¦ä¸”應根據 ARM 體系
-çµæ§‹åƒè€ƒæ‰‹å†Šï¼ˆARM ARM)中定義的欄ä½ä¾†è§£é‡‹èªªæ˜Žã€‚
+æ述的功能的存在。這些 hwcap é€šéŽ ID 寄存器字段定義,並且應根據 ARM 體系
+çµæ§‹åƒè€ƒæ‰‹å†Šï¼ˆARM ARM)中定義的字段來解釋說明。
這些 hwcaps 以下é¢çš„å½¢å¼æè¿°::
diff --git a/Documentation/translations/zh_TW/arch/arm64/legacy_instructions.txt b/Documentation/translations/zh_TW/arch/arm64/legacy_instructions.txt
index c2d02cd5017d..7d1f0593d7ca 100644
--- a/Documentation/translations/zh_TW/arch/arm64/legacy_instructions.txt
+++ b/Documentation/translations/zh_TW/arch/arm64/legacy_instructions.txt
@@ -31,7 +31,7 @@ Documentation/arch/arm64/legacy_instructions.rst 的中文翻譯
以下爲正文
---------------------------------------------------------------------
Linux 內核在 arm64 上的移æ¤æ供了一個基礎框架,以支æŒæ§‹æž¶ä¸­æ­£åœ¨è¢«æ·˜æ±°æˆ–已廢棄指令的模擬執行。
-這個基礎框架的代碼使用未定義指令鉤å­ï¼ˆhooks)來支æŒæ¨¡æ“¬ã€‚如果指令存在,它也å…許在硬體中啓用該指令。
+這個基礎框架的代碼使用未定義指令鉤å­ï¼ˆhooks)來支æŒæ¨¡æ“¬ã€‚如果指令存在,它也å…許在硬件中啓用該指令。
模擬模å¼å¯é€šéŽå¯« sysctl 節點(/proc/sys/abi)來控制。
ä¸åŒçš„執行方å¼åŠ sysctl 節點的相應值,解釋如下:
@@ -42,18 +42,18 @@ Linux 內核在 arm64 上的移æ¤æ供了一個基礎框架,以支æŒæ§‹æž¶ä
* Emulate(模擬)
值: 1
- 使用軟體模擬方å¼ã€‚爲解決軟體é·ç§»å•é¡Œï¼Œé€™ç¨®æ¨¡æ“¬æŒ‡ä»¤æ¨¡å¼çš„使用是被跟蹤的,並會發出速率é™åˆ¶è­¦å‘Šã€‚
+ 使用軟件模擬方å¼ã€‚爲解決軟件é·ç§»å•é¡Œï¼Œé€™ç¨®æ¨¡æ“¬æŒ‡ä»¤æ¨¡å¼çš„使用是被跟蹤的,並會發出速率é™åˆ¶è­¦å‘Šã€‚
它是那些構架中正在被淘汰的指令,如 CP15 barriers(隔離指令),的默èªè™•ç†æ–¹å¼ã€‚
-* Hardware Execution(硬體執行)
+* Hardware Execution(硬件執行)
值: 2
- 雖然標記爲正在被淘汰,但一些實ç¾å¯èƒ½æ供硬體執行這些指令的使能/ç¦ç”¨æ“作。
- 使用硬體執行一般會有更好的性能,但將無法收集é‹è¡Œæ™‚å°æ­£è¢«æ·˜æ±°æŒ‡ä»¤çš„使用統計數據。
+ 雖然標記爲正在被淘汰,但一些實ç¾å¯èƒ½æ供硬件執行這些指令的使能/ç¦ç”¨æ“作。
+ 使用硬件執行一般會有更好的性能,但將無法收集é‹è¡Œæ™‚å°æ­£è¢«æ·˜æ±°æŒ‡ä»¤çš„使用統計數據。
默èªåŸ·è¡Œæ¨¡å¼ä¾è³´æ–¼æŒ‡ä»¤åœ¨æ§‹æž¶ä¸­ç‹€æ…‹ã€‚正在被淘汰的指令應該以模擬(Emulate)作爲默èªæ¨¡å¼ï¼Œ
而已廢棄的指令必須默èªä½¿ç”¨æœªå®šç¾©ï¼ˆUndef)模å¼
-注æ„:指令模擬å¯èƒ½ç„¡æ³•æ‡‰å°æ‰€æœ‰æƒ…æ³ã€‚更多詳情請åƒè€ƒå–®ç¨çš„指令注釋。
+注æ„:指令模擬å¯èƒ½ç„¡æ³•æ‡‰å°æ‰€æœ‰æƒ…æ³ã€‚更多詳情請åƒè€ƒå–®ç¨çš„指令註釋。
å—支æŒçš„éºç•™æŒ‡ä»¤
-------------
@@ -71,7 +71,7 @@ Linux 內核在 arm64 上的移æ¤æ供了一個基礎框架,以支æŒæ§‹æž¶ä
節點: /proc/sys/abi/setend
狀態: 正被淘汰,ä¸æŽ¨è–¦ä½¿ç”¨
默èªåŸ·è¡Œæ–¹å¼: Emulate (1)*
-註:爲了使能這個特性,系統中的所有 CPU 必須在 EL0 支æŒæ··åˆå­—節åºã€‚
+注:爲了使能這個特性,系統中的所有 CPU 必須在 EL0 支æŒæ··åˆå­—節åºã€‚
如果一個新的 CPU (ä¸æ”¯æŒæ··åˆå­—節åºï¼‰ 在使能這個特性後被熱æ’入系統,
在應用中å¯èƒ½æœƒå‡ºç¾ä¸å¯é æœŸçš„çµæžœã€‚
diff --git a/Documentation/translations/zh_TW/arch/arm64/memory.txt b/Documentation/translations/zh_TW/arch/arm64/memory.txt
index 0280200e791f..e41c518e71c6 100644
--- a/Documentation/translations/zh_TW/arch/arm64/memory.txt
+++ b/Documentation/translations/zh_TW/arch/arm64/memory.txt
@@ -28,17 +28,17 @@ Documentation/arch/arm64/memory.rst 的中文翻譯
以下爲正文
---------------------------------------------------------------------
- Linux 在 AArch64 中的內存布局
+ Linux 在 AArch64 中的內存佈局
===========================
作者: Catalin Marinas <catalin.marinas@arm.com>
-本文檔æè¿° AArch64 Linux 內核所使用的虛擬內存布局。此構架å¯ä»¥å¯¦ç¾
+本文檔æè¿° AArch64 Linux 內核所使用的虛擬內存佈局。此構架å¯ä»¥å¯¦ç¾
é å¤§å°çˆ² 4KB çš„ 4 級轉æ›è¡¨å’Œé å¤§å°çˆ² 64KB çš„ 3 級轉æ›è¡¨ã€‚
AArch64 Linux 使用 3 級或 4 級轉æ›è¡¨ï¼Œå…¶é å¤§å°é…置爲 4KB,å°æ–¼ç”¨æˆ¶å’Œå…§æ ¸
分別都有 39-bit (512GB) 或 48-bit (256TB) 的虛擬地å€ç©ºé–“。
-å°æ–¼é å¤§å°çˆ² 64KBçš„é…置,僅使用 2 級轉æ›è¡¨ï¼Œæœ‰ 42-bit (4TB) 的虛擬地å€ç©ºé–“,但內存布局相åŒã€‚
+å°æ–¼é å¤§å°çˆ² 64KBçš„é…置,僅使用 2 級轉æ›è¡¨ï¼Œæœ‰ 42-bit (4TB) 的虛擬地å€ç©ºé–“,但內存佈局相åŒã€‚
用戶地å€ç©ºé–“çš„ 63:48 ä½çˆ² 0,而內核地å€ç©ºé–“的相應ä½çˆ² 1。TTBRx çš„
é¸æ“‡ç”±è™›æ“¬åœ°å€çš„ 63 ä½çµ¦å‡ºã€‚swapper_pg_dir 僅包å«å…§æ ¸ï¼ˆå…¨å±€ï¼‰æ˜ å°„,
@@ -46,7 +46,7 @@ AArch64 Linux 使用 3 級或 4 級轉æ›è¡¨ï¼Œå…¶é å¤§å°é…置爲 4KB,å°æ–
TTBR1 中,且從ä¸å¯«å…¥ TTBR0。
-AArch64 Linux 在é å¤§å°çˆ² 4KB,並使用 3 級轉æ›è¡¨æ™‚的內存布局:
+AArch64 Linux 在é å¤§å°çˆ² 4KB,並使用 3 級轉æ›è¡¨æ™‚的內存佈局:
èµ·å§‹åœ°å€ çµæŸåœ°å€ å¤§å° ç”¨é€”
-----------------------------------------------------------------------
@@ -54,7 +54,7 @@ AArch64 Linux 在é å¤§å°çˆ² 4KB,並使用 3 級轉æ›è¡¨æ™‚的內存布局ï¼
ffffff8000000000 ffffffffffffffff 512GB 內核空間
-AArch64 Linux 在é å¤§å°çˆ² 4KB,並使用 4 級轉æ›è¡¨æ™‚的內存布局:
+AArch64 Linux 在é å¤§å°çˆ² 4KB,並使用 4 級轉æ›è¡¨æ™‚的內存佈局:
èµ·å§‹åœ°å€ çµæŸåœ°å€ å¤§å° ç”¨é€”
-----------------------------------------------------------------------
@@ -62,7 +62,7 @@ AArch64 Linux 在é å¤§å°çˆ² 4KB,並使用 4 級轉æ›è¡¨æ™‚的內存布局ï¼
ffff000000000000 ffffffffffffffff 256TB 內核空間
-AArch64 Linux 在é å¤§å°çˆ² 64KB,並使用 2 級轉æ›è¡¨æ™‚的內存布局:
+AArch64 Linux 在é å¤§å°çˆ² 64KB,並使用 2 級轉æ›è¡¨æ™‚的內存佈局:
èµ·å§‹åœ°å€ çµæŸåœ°å€ å¤§å° ç”¨é€”
-----------------------------------------------------------------------
@@ -70,7 +70,7 @@ AArch64 Linux 在é å¤§å°çˆ² 64KB,並使用 2 級轉æ›è¡¨æ™‚的內存布局ï
fffffc0000000000 ffffffffffffffff 4TB 內核空間
-AArch64 Linux 在é å¤§å°çˆ² 64KB,並使用 3 級轉æ›è¡¨æ™‚的內存布局:
+AArch64 Linux 在é å¤§å°çˆ² 64KB,並使用 3 級轉æ›è¡¨æ™‚的內存佈局:
èµ·å§‹åœ°å€ çµæŸåœ°å€ å¤§å° ç”¨é€”
-----------------------------------------------------------------------
@@ -78,7 +78,7 @@ AArch64 Linux 在é å¤§å°çˆ² 64KB,並使用 3 級轉æ›è¡¨æ™‚的內存布局ï
ffff000000000000 ffffffffffffffff 256TB 內核空間
-更詳細的內核虛擬內存布局,請åƒé–±å…§æ ¸å•“å‹•ä¿¡æ¯ã€‚
+更詳細的內核虛擬內存佈局,請åƒé–±å…§æ ¸å•“å‹•ä¿¡æ¯ã€‚
4KB é å¤§å°çš„轉æ›è¡¨æŸ¥æ‰¾ï¼š
diff --git a/Documentation/translations/zh_TW/arch/arm64/perf.rst b/Documentation/translations/zh_TW/arch/arm64/perf.rst
index 645f3944a0f4..405d5f66964f 100644
--- a/Documentation/translations/zh_TW/arch/arm64/perf.rst
+++ b/Documentation/translations/zh_TW/arch/arm64/perf.rst
@@ -59,7 +59,7 @@ EL2(VHE 內核 或 non-VHE 虛擬機監控器)。
KVM 客戶機å¯èƒ½é‹è¡Œåœ¨ EL0(用戶空間)和 EL1(內核)。
-由於宿主機和客戶機之間é‡ç–Šçš„異常級別,我們ä¸èƒ½åƒ…僅ä¾é  PMU 的硬體異
+由於宿主機和客戶機之間é‡ç–Šçš„異常級別,我們ä¸èƒ½åƒ…僅ä¾é  PMU 的硬件異
常éŽæ¿¾æ©Ÿåˆ¶-因此我們必須啓用/ç¦ç”¨å°æ–¼å®¢æˆ¶æ©Ÿé€²å…¥å’Œé€€å‡ºçš„計數。而這在
VHE å’Œ non-VHE 系統上表ç¾ä¸åŒã€‚
diff --git a/Documentation/translations/zh_TW/arch/arm64/silicon-errata.txt b/Documentation/translations/zh_TW/arch/arm64/silicon-errata.txt
index f6f41835a54a..70371807ca83 100644
--- a/Documentation/translations/zh_TW/arch/arm64/silicon-errata.txt
+++ b/Documentation/translations/zh_TW/arch/arm64/silicon-errata.txt
@@ -28,39 +28,39 @@ Documentation/arch/arm64/silicon-errata.rst 的中文翻譯
以下爲正文
---------------------------------------------------------------------
- 晶片勘誤和軟體補救措施
+ 芯片勘誤和軟件補救措施
==================
作者: Will Deacon <will.deacon@arm.com>
日期: 2015年11月27日
-一個ä¸å¹¸çš„ç¾å¯¦ï¼šç¡¬é«”經常帶有一些所謂的「瑕疵(errata)ã€ï¼Œå°Žè‡´å…¶åœ¨
-æŸäº›ç‰¹å®šæƒ…æ³ä¸‹æœƒé•èƒŒæ§‹æž¶å®šç¾©çš„行爲。就基於 ARM 的硬體而言,這些瑕疵
+一個ä¸å¹¸çš„ç¾å¯¦ï¼šç¡¬ä»¶ç¶“常帶有一些所謂的“瑕疵(errata)â€ï¼Œå°Žè‡´å…¶åœ¨
+æŸäº›ç‰¹å®šæƒ…æ³ä¸‹æœƒé•èƒŒæ§‹æž¶å®šç¾©çš„行爲。就基於 ARM 的硬件而言,這些瑕疵
大體å¯åˆ†çˆ²ä»¥ä¸‹å¹¾é¡žï¼š
A 類:無å¯è¡Œè£œæ•‘措施的嚴é‡ç¼ºé™·ã€‚
B 類:有å¯æŽ¥å—的補救措施的é‡å¤§æˆ–åš´é‡ç¼ºé™·ã€‚
C 類:在正常æ“作中ä¸æœƒé¡¯ç¾çš„å°ç‘•ç–µã€‚
-更多資訊,請在 infocenter.arm.com (需註冊)中查閱「軟體開發者勘誤
-筆記ã€ï¼ˆã€ŒSoftware Developers Errata Noticeã€ï¼‰æ–‡æª”。
+更多資訊,請在 infocenter.arm.com (需註冊)中查閱“軟件開發者勘誤
+筆記â€ï¼ˆâ€œSoftware Developers Errata Noticeâ€ï¼‰æ–‡æª”。
-å°æ–¼ Linux 而言,B 類缺陷å¯èƒ½éœ€è¦ä½œæ¥­ç³»çµ±çš„æŸäº›ç‰¹åˆ¥è™•ç†ã€‚例如,é¿å…
+å°æ–¼ Linux 而言,B 類缺陷å¯èƒ½éœ€è¦æ“作系統的æŸäº›ç‰¹åˆ¥è™•ç†ã€‚例如,é¿å…
一個特殊的代碼åºåˆ—,或是以一種特定的方å¼é…置處ç†å™¨ã€‚在æŸç¨®ä¸å¤ªå¸¸è¦‹çš„
情æ³ä¸‹ï¼Œçˆ²å°‡ A 類缺陷當作 C 類處ç†ï¼Œå¯èƒ½éœ€è¦ç”¨é¡žä¼¼çš„手段。這些手段被
-統稱爲「軟體補救措施ã€ï¼Œä¸”僅在少數情æ³éœ€è¦ï¼ˆä¾‹å¦‚,那些需è¦ä¸€å€‹é‹è¡Œåœ¨
+統稱爲“軟件補救措施â€ï¼Œä¸”僅在少數情æ³éœ€è¦ï¼ˆä¾‹å¦‚,那些需è¦ä¸€å€‹é‹è¡Œåœ¨
éžå®‰å…¨ç•°å¸¸ç´šçš„補救措施 *並且* 能被 Linux 觸發的情æ³ï¼‰ã€‚
-å°æ–¼å°šåœ¨è¨Žè«–中的å¯èƒ½å°æœªå—瑕疵影響的系統產生干擾的軟體補救措施,有一個
-相應的內核é…置(Kconfig)é¸é …被加在 「內核特性(Kernel Features)ã€->
-「基於å¯é¸æ–¹æ³•æ¡†æž¶çš„ ARM 瑕疵補救措施(ARM errata workarounds via
+å°æ–¼å°šåœ¨è¨Žè«–中的å¯èƒ½å°æœªå—瑕疵影響的系統產生干擾的軟件補救措施,有一個
+相應的內核é…置(Kconfig)é¸é …被加在 “內核特性(Kernel Features)â€->
+“基於å¯é¸æ–¹æ³•æ¡†æž¶çš„ ARM 瑕疵補救措施(ARM errata workarounds via
the alternatives framework)"。這些é¸é …被默èªé–‹å•“,若探測到å—影響的CPU,
補ä¸å°‡åœ¨é‹è¡Œæ™‚被使用。至於å°ç³»çµ±é‹è¡Œå½±éŸ¿è¼ƒå°çš„補救措施,內核é…ç½®é¸é …
-並ä¸å­˜åœ¨ï¼Œä¸”代碼以æŸç¨®è¦é¿ç‘•ç–µçš„æ–¹å¼è¢«æ§‹é€ ï¼ˆå¸¶æ³¨é‡‹çˆ²å®œï¼‰ã€‚
+並ä¸å­˜åœ¨ï¼Œä¸”代碼以æŸç¨®è¦é¿ç‘•ç–µçš„æ–¹å¼è¢«æ§‹é€ ï¼ˆå¸¶è¨»é‡‹çˆ²å®œï¼‰ã€‚
-這種åšæ³•å°æ–¼åœ¨ä»»æ„內核原始碼樹中準確地判斷出哪個瑕疵已被軟體方法所補救
-ç¨å¾®æœ‰é»žéº»ç…©ï¼Œæ‰€ä»¥åœ¨ Linux 內核中此文件作爲軟體補救措施的註冊表,
-並將在新的軟體補救措施被æ交和å‘後移æ¤ï¼ˆbackported)到穩定內核時被更新。
+這種åšæ³•å°æ–¼åœ¨ä»»æ„內核æºä»£ç¢¼æ¨¹ä¸­æº–確地判斷出哪個瑕疵已被軟件方法所補救
+ç¨å¾®æœ‰é»žéº»ç…©ï¼Œæ‰€ä»¥åœ¨ Linux 內核中此文件作爲軟件補救措施的註冊表,
+並將在新的軟件補救措施被æ交和å‘後移æ¤ï¼ˆbackported)到穩定內核時被更新。
| 實ç¾è€… | å—影響的組件 | 勘誤編號 | 內核é…ç½® |
+----------------+-----------------+-----------------+-------------------------+
diff --git a/Documentation/translations/zh_TW/arch/arm64/tagged-pointers.txt b/Documentation/translations/zh_TW/arch/arm64/tagged-pointers.txt
index c0be1d1e0d01..9812d99549ba 100644
--- a/Documentation/translations/zh_TW/arch/arm64/tagged-pointers.txt
+++ b/Documentation/translations/zh_TW/arch/arm64/tagged-pointers.txt
@@ -36,14 +36,14 @@ Documentation/arch/arm64/tagged-pointers.rst 的中文翻譯
AArch64 Linux 中的潛在用途。
內核æ供的地å€è½‰æ›è¡¨é…ç½®ä½¿é€šéŽ TTBR0 完æˆçš„虛擬地å€è½‰æ›ï¼ˆå³ç”¨æˆ¶ç©ºé–“
-映射),其虛擬地å€çš„最高 8 ä½ï¼ˆ63:56)會被轉æ›ç¡¬é«”所忽略。這種機制
-讓這些ä½å¯ä¾›æ‡‰ç”¨ç¨‹å¼è‡ªç”±ä½¿ç”¨ï¼Œå…¶æ³¨æ„事項如下:
+映射),其虛擬地å€çš„最高 8 ä½ï¼ˆ63:56)會被轉æ›ç¡¬ä»¶æ‰€å¿½ç•¥ã€‚這種機制
+讓這些ä½å¯ä¾›æ‡‰ç”¨ç¨‹åºè‡ªç”±ä½¿ç”¨ï¼Œå…¶æ³¨æ„事項如下:
(1) 內核è¦æ±‚所有傳éžåˆ° EL1 的用戶空間地å€å¸¶æœ‰ 0x00 標記。
- 這æ„味著任何攜帶用戶空間虛擬地å€çš„系統調用(syscall)
+ 這æ„味ç€ä»»ä½•æ”œå¸¶ç”¨æˆ¶ç©ºé–“虛擬地å€çš„系統調用(syscall)
åƒæ•¸ *å¿…é ˆ* 在陷入內核å‰ä½¿å®ƒå€‘的最高字節被清零。
- (2) éžé›¶æ¨™è¨˜åœ¨å‚³éžä¿¡è™Ÿæ™‚ä¸è¢«ä¿å­˜ã€‚這æ„味著在應用程å¼ä¸­åˆ©ç”¨äº†
+ (2) éžé›¶æ¨™è¨˜åœ¨å‚³éžä¿¡è™Ÿæ™‚ä¸è¢«ä¿å­˜ã€‚這æ„味ç€åœ¨æ‡‰ç”¨ç¨‹åºä¸­åˆ©ç”¨äº†
標記的信號處ç†å‡½æ•¸ç„¡æ³•ä¾è³´ siginfo_t 的用戶空間虛擬
地å€æ‰€æ”œå¸¶çš„包å«å…¶å…§éƒ¨åŸŸä¿¡æ¯çš„標記。此è¦å‰‡çš„一個例外是
當信號是在調試觀察點的異常處ç†ç¨‹åºä¸­ç”¢ç”Ÿçš„,此時標記的
@@ -53,5 +53,5 @@ AArch64 Linux 中的潛在用途。
的高字節,C 編譯器很å¯èƒ½ç„¡æ³•åˆ¤æ–·å®ƒå€‘是ä¸åŒçš„。
此構架會阻止å°å¸¶æ¨™è¨˜çš„ PC 指é‡çš„利用,因此在異常返回時,其高字節
-將被設置æˆä¸€å€‹çˆ² 「55〠的擴展符。
+將被設置æˆä¸€å€‹çˆ² “55†的擴展符。
diff --git a/Documentation/translations/zh_TW/arch/index.rst b/Documentation/translations/zh_TW/arch/index.rst
new file mode 100644
index 000000000000..7c0490589465
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/index.rst
@@ -0,0 +1,29 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+處ç†å™¨é«”ç³»çµæ§‹
+==============
+
+以下文檔æ供了具體架構實ç¾çš„編程細節。
+
+.. toctree::
+ :maxdepth: 2
+
+ mips/index
+ arm64/index
+ openrisc/index
+ parisc/index
+ loongarch/index
+
+TODOList:
+
+* arm/index
+* m68k/index
+* nios2/index
+* powerpc/index
+* s390/index
+* sh/index
+* sparc/index
+* x86/index
+* xtensa/index
+* ../riscv/index
+
diff --git a/Documentation/translations/zh_TW/arch/loongarch/booting.rst b/Documentation/translations/zh_TW/arch/loongarch/booting.rst
new file mode 100644
index 000000000000..88291090cea1
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/loongarch/booting.rst
@@ -0,0 +1,49 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/loongarch/booting.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+====================
+å•“å‹• Linux/LoongArch
+====================
+
+:作者: å¸å»¶é¨° <siyanteng@loongson.cn>
+:日期: 2022年11月18日
+
+BootLoader傳éžçµ¦å…§æ ¸çš„ä¿¡æ¯
+==========================
+
+LoongArch支æŒACPIå’ŒFDT啓動,需è¦å‚³éžçµ¦å…§æ ¸çš„ä¿¡æ¯åŒ…括memmapã€initrdã€cmdlineã€å¯
+é¸çš„ACPI/FDT表等。
+
+內核在 `kernel_entry` å…¥å£è™•è¢«å‚³éžä»¥ä¸‹åƒæ•¸:
+
+ - a0 = efi_boot: `efi_boot` 是一個標誌,表示這個啓動環境是å¦å®Œå…¨ç¬¦åˆUEFI
+ çš„è¦æ±‚。
+
+ - a1 = cmdline: `cmdline` 是一個指å‘內核命令行的指é‡ã€‚
+
+ - a2 = systemtable: `systemtable` 指å‘EFI的系統表,在這個階段涉åŠçš„所有
+ 指é‡éƒ½æ˜¯ç‰©ç†åœ°å€ã€‚
+
+Linux/LoongArch內核é¡åƒæ–‡ä»¶é ­
+=============================
+
+內核é¡åƒæ˜¯EFIé¡åƒã€‚作爲PE文件,它們有一個64字節的頭部çµæ§‹é«”,如下所示::
+
+ u32 MZ_MAGIC /* "MZ", MS-DOS é ­ */
+ u32 res0 = 0 /* ä¿ç•™ */
+ u64 kernel_entry /* 內核入å£é»ž */
+ u64 _end - _text /* 內核é¡åƒæœ‰æ•ˆå¤§å° */
+ u64 load_offset /* 加載內核é¡åƒç›¸å°å…§å­˜èµ·å§‹åœ°å€çš„åç§»é‡ */
+ u64 res1 = 0 /* ä¿ç•™ */
+ u64 res2 = 0 /* ä¿ç•™ */
+ u64 res3 = 0 /* ä¿ç•™ */
+ u32 LINUX_PE_MAGIC /* 魔術數 */
+ u32 pe_header - _head /* 到PEé ­çš„åç§»é‡ */
+
diff --git a/Documentation/translations/zh_TW/arch/loongarch/features.rst b/Documentation/translations/zh_TW/arch/loongarch/features.rst
new file mode 100644
index 000000000000..b64e430f55ae
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/loongarch/features.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/loongarch/features.rst
+:Translator: Huacai Chen <chenhuacai@loongson.cn>
+
+.. kernel-feat:: $srctree/Documentation/features loongarch
+
diff --git a/Documentation/translations/zh_TW/arch/loongarch/index.rst b/Documentation/translations/zh_TW/arch/loongarch/index.rst
new file mode 100644
index 000000000000..7281e050fe1c
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/loongarch/index.rst
@@ -0,0 +1,28 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/loongarch/index.rst
+:Translator: Huacai Chen <chenhuacai@loongson.cn>
+
+=================
+LoongArch體系çµæ§‹
+=================
+
+.. toctree::
+ :maxdepth: 2
+ :numbered:
+
+ introduction
+ booting
+ irq-chip-model
+
+ features
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
+
diff --git a/Documentation/translations/zh_TW/arch/loongarch/introduction.rst b/Documentation/translations/zh_TW/arch/loongarch/introduction.rst
new file mode 100644
index 000000000000..a5603f9b0a1b
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/loongarch/introduction.rst
@@ -0,0 +1,354 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/loongarch/introduction.rst
+:Translator: Huacai Chen <chenhuacai@loongson.cn>
+
+=============
+LoongArch介紹
+=============
+
+LoongArch是一種新的RISC ISA,在一定程度上類似於MIPS和RISC-V。LoongArch指令集
+包括一個精簡32ä½ç‰ˆï¼ˆLA32R)ã€ä¸€å€‹æ¨™æº–32ä½ç‰ˆï¼ˆLA32S)ã€ä¸€å€‹64ä½ç‰ˆï¼ˆLA64)。
+LoongArch定義了四個特權級(PLV0~PLV3),其中PLV0是最高特權級,用於內核;而PLV3
+是最低特權級,用於應用程åºã€‚本文檔介紹了LoongArch的寄存器ã€åŸºç¤ŽæŒ‡ä»¤é›†ã€è™›æ“¬å…§
+存以åŠå…¶ä»–一些主題。
+
+寄存器
+======
+
+LoongArch的寄存器包括通用寄存器(GPRs)ã€æµ®é»žå¯„存器(FPRs)ã€å‘é‡å¯„存器(VRs)
+和用於特權模å¼ï¼ˆPLV0)的控制狀態寄存器(CSRs)。
+
+通用寄存器
+----------
+
+LoongArch包括32個通用寄存器( ``$r0`` ~ ``$r31`` ),LA32中æ¯å€‹å¯„存器爲32ä½å¯¬ï¼Œ
+LA64中æ¯å€‹å¯„存器爲64ä½å¯¬ã€‚ ``$r0`` 的內容總是固定爲0,而其他寄存器在體系çµæ§‹å±¤é¢
+沒有特殊功能。( ``$r1`` 算是一個例外,在BL指令中固定用作éˆæŽ¥è¿”回寄存器。)
+
+內核使用了一套LoongArch寄存器約定,定義在LoongArch ELF psABIè¦ç¯„中,詳細æè¿°åƒè¦‹
+:ref:`åƒè€ƒæ–‡ç» <loongarch-references-zh_TW>`:
+
+================= =============== =================== ==========
+寄存器å 別å 用途 跨調用ä¿æŒ
+================= =============== =================== ==========
+``$r0`` ``$zero`` 常é‡0 ä¸ä½¿ç”¨
+``$r1`` ``$ra`` è¿”å›žåœ°å€ å¦
+``$r2`` ``$tp`` TLS/線程信æ¯æŒ‡é‡ ä¸ä½¿ç”¨
+``$r3`` ``$sp`` æ£§æŒ‡é‡ æ˜¯
+``$r4``-``$r11`` ``$a0``-``$a7`` åƒæ•¸å¯„存器 å¦
+``$r4``-``$r5`` ``$v0``-``$v1`` 返回值 å¦
+``$r12``-``$r20`` ``$t0``-``$t8`` 臨時寄存器 å¦
+``$r21`` ``$u0`` æ¯CPU變é‡åŸºåœ°å€ ä¸ä½¿ç”¨
+``$r22`` ``$fp`` å¹€æŒ‡é‡ æ˜¯
+``$r23``-``$r31`` ``$s0``-``$s8`` éœæ…‹å¯„存器 是
+================= =============== =================== ==========
+
+.. note::
+ 注æ„: ``$r21`` 寄存器在ELF psABI中ä¿ç•™æœªä½¿ç”¨ï¼Œä½†æ˜¯åœ¨Linux內核用於ä¿
+ å­˜æ¯CPU變é‡åŸºåœ°å€ã€‚該寄存器沒有ABI命å,ä¸éŽåœ¨å…§æ ¸ä¸­ç¨±çˆ² ``$u0`` 。在
+ 一些éºç•™ä»£ç¢¼ä¸­æœ‰æ™‚å¯èƒ½è¦‹åˆ° ``$v0`` å’Œ ``$v1`` ,它們是 ``$a0`` å’Œ
+ ``$a1`` 的別å,屬於已經廢棄的用法。
+
+浮點寄存器
+----------
+
+當系統中存在FPU時,LoongArch有32個浮點寄存器( ``$f0`` ~ ``$f31`` )。在LA64
+çš„CPU核上,æ¯å€‹å¯„存器å‡çˆ²64ä½å¯¬ã€‚
+
+浮點寄存器的使用約定與LoongArch ELF psABIè¦ç¯„çš„æ述相åŒï¼š
+
+================= ================== =================== ==========
+寄存器å 別å 用途 跨調用ä¿æŒ
+================= ================== =================== ==========
+``$f0``-``$f7`` ``$fa0``-``$fa7`` åƒæ•¸å¯„存器 å¦
+``$f0``-``$f1`` ``$fv0``-``$fv1`` 返回值 å¦
+``$f8``-``$f23`` ``$ft0``-``$ft15`` 臨時寄存器 å¦
+``$f24``-``$f31`` ``$fs0``-``$fs7`` éœæ…‹å¯„存器 是
+================= ================== =================== ==========
+
+.. note::
+ 注æ„:在一些éºç•™ä»£ç¢¼ä¸­æœ‰æ™‚å¯èƒ½è¦‹åˆ° ``$fv0`` å’Œ ``$fv1`` ,它們是
+ ``$fa0`` å’Œ ``$fa1`` 的別å,屬於已經廢棄的用法。
+
+
+å‘é‡å¯„存器
+----------
+
+LoongArchç¾æœ‰å…©ç¨®å‘é‡æ“´å±•ï¼š
+
+- 128ä½å‘é‡æ“´å±•LSX(全稱Loongson SIMD eXtention),
+- 256ä½å‘é‡æ“´å±•LASX(全稱Loongson Advanced SIMD eXtention)。
+
+LSX使用 ``$v0`` ~ ``$v31`` å‘é‡å¯„存器,而LASX則使用 ``$x0`` ~ ``$x31`` 。
+
+浮點寄存器和å‘é‡å¯„存器是複用的,比如:在一個實ç¾äº†LSXå’ŒLASX的核上, ``$x0`` çš„
+低128ä½èˆ‡ ``$v0`` 共用, ``$v0`` 的低64ä½èˆ‡ ``$f0`` 共用,其他寄存器ä¾æ­¤é¡žæŽ¨ã€‚
+
+控制狀態寄存器
+--------------
+
+控制狀態寄存器åªèƒ½åœ¨ç‰¹æ¬Šæ¨¡å¼ï¼ˆPLV0)下訪å•:
+
+================= ==================================== ==========
+åœ°å€ å…¨ç¨±æè¿° 簡稱
+================= ==================================== ==========
+0x0 當å‰æ¨¡å¼ä¿¡æ¯ CRMD
+0x1 異常å‰æ¨¡å¼ä¿¡æ¯ PRMD
+0x2 擴展部件使能 EUEN
+0x3 雜項控制 MISC
+0x4 異常é…ç½® ECFG
+0x5 異常狀態 ESTAT
+0x6 ç•°å¸¸è¿”å›žåœ°å€ ERA
+0x7 出錯(Faulting)è™›æ“¬åœ°å€ BADV
+0x8 出錯(Faulting)指令字 BADI
+0xC 異常入å£åœ°å€ EENTRY
+0x10 TLB索引 TLBIDX
+0x11 TLBè¡¨é …é«˜ä½ TLBEHI
+0x12 TLB表項低ä½0 TLBELO0
+0x13 TLB表項低ä½1 TLBELO1
+0x18 地å€ç©ºé–“標識符 ASID
+0x19 低åŠåœ°å€ç©ºé–“é å…¨å±€ç›®éŒ„åŸºå€ PGDL
+0x1A 高åŠåœ°å€ç©ºé–“é å…¨å±€ç›®éŒ„åŸºå€ PGDH
+0x1B é å…¨å±€ç›®éŒ„åŸºå€ PGD
+0x1C é è¡¨é歷控制低åŠéƒ¨åˆ† PWCL
+0x1D é è¡¨é歷控制高åŠéƒ¨åˆ† PWCH
+0x1E STLBé å¤§å° STLBPS
+0x1F 縮減虛地å€é…ç½® RVACFG
+0x20 CPU編號 CPUID
+0x21 特權資æºé…置信æ¯1 PRCFG1
+0x22 特權資æºé…置信æ¯2 PRCFG2
+0x23 特權資æºé…置信æ¯3 PRCFG3
+0x30+n (0≤n≤15) 數據ä¿å­˜å¯„存器 SAVEn
+0x40 定時器編號 TID
+0x41 定時器é…ç½® TCFG
+0x42 定時器值 TVAL
+0x43 計時器補償 CNTC
+0x44 定時器中斷清除 TICLR
+0x60 LLBit相關控制 LLBCTL
+0x80 實ç¾ç›¸é—œæŽ§åˆ¶1 IMPCTL1
+0x81 實ç¾ç›¸é—œæŽ§åˆ¶2 IMPCTL2
+0x88 TLBé‡å¡«ç•°å¸¸å…¥å£åœ°å€ TLBRENTRY
+0x89 TLBé‡å¡«ç•°å¸¸å‡ºéŒ¯(Faulting)è™›åœ°å€ TLBRBADV
+0x8A TLBé‡å¡«ç•°å¸¸è¿”å›žåœ°å€ TLBRERA
+0x8B TLBé‡å¡«ç•°å¸¸æ•¸æ“šä¿å­˜ TLBRSAVE
+0x8C TLBé‡å¡«ç•°å¸¸è¡¨é …低ä½0 TLBRELO0
+0x8D TLBé‡å¡«ç•°å¸¸è¡¨é …低ä½1 TLBRELO1
+0x8E TLBé‡å¡«ç•°å¸¸è¡¨é …é«˜ä½ TLBEHI
+0x8F TLBé‡å¡«ç•°å¸¸å‰æ¨¡å¼ä¿¡æ¯ TLBRPRMD
+0x90 機器錯誤控制 MERRCTL
+0x91 機器錯誤信æ¯1 MERRINFO1
+0x92 機器錯誤信æ¯2 MERRINFO2
+0x93 機器錯誤異常入å£åœ°å€ MERRENTRY
+0x94 æ©Ÿå™¨éŒ¯èª¤ç•°å¸¸è¿”å›žåœ°å€ MERRERA
+0x95 機器錯誤異常數據ä¿å­˜ MERRSAVE
+0x98 高速緩存標籤 CTAG
+0x180+n (0≤n≤3) 直接映射é…置窗å£n DMWn
+0x200+2n (0≤n≤31) 性能監測é…ç½®n PMCFGn
+0x201+2n (0≤n≤31) 性能監測計數器n PMCNTn
+0x300 內存讀寫監視點整體控制 MWPC
+0x301 內存讀寫監視點整體狀態 MWPS
+0x310+8n (0≤n≤7) 內存讀寫監視點né…ç½®1 MWPnCFG1
+0x311+8n (0≤n≤7) 內存讀寫監視點né…ç½®2 MWPnCFG2
+0x312+8n (0≤n≤7) 內存讀寫監視點né…ç½®3 MWPnCFG3
+0x313+8n (0≤n≤7) 內存讀寫監視點né…ç½®4 MWPnCFG4
+0x380 å–指監視點整體控制 FWPC
+0x381 å–指監視點整體狀態 FWPS
+0x390+8n (0≤n≤7) å–指監視點né…ç½®1 FWPnCFG1
+0x391+8n (0≤n≤7) å–指監視點né…ç½®2 FWPnCFG2
+0x392+8n (0≤n≤7) å–指監視點né…ç½®3 FWPnCFG3
+0x393+8n (0≤n≤7) å–指監視點né…ç½®4 FWPnCFG4
+0x500 調試寄存器 DBG
+0x501 èª¿è©¦ç•°å¸¸è¿”å›žåœ°å€ DERA
+0x502 調試數據ä¿å­˜ DSAVE
+================= ==================================== ==========
+
+ERA,TLBRERA,MERRERA和DERA有時也分別稱爲EPC,TLBREPC,MERREPC和DEPC。
+
+基礎指令集
+==========
+
+指令格å¼
+--------
+
+LoongArch的指令字長爲32ä½ï¼Œä¸€å…±æœ‰9種基本指令格å¼ï¼ˆä»¥åŠä¸€äº›è®Šé«”):
+
+=========== ==========================
+æ ¼å¼å稱 指令構æˆ
+=========== ==========================
+2R Opcode + Rj + Rd
+3R Opcode + Rk + Rj + Rd
+4R Opcode + Ra + Rk + Rj + Rd
+2RI8 Opcode + I8 + Rj + Rd
+2RI12 Opcode + I12 + Rj + Rd
+2RI14 Opcode + I14 + Rj + Rd
+2RI16 Opcode + I16 + Rj + Rd
+1RI21 Opcode + I21L + Rj + I21H
+I26 Opcode + I26L + I26H
+=========== ==========================
+
+Opcode是指令æ“作碼,Rjå’ŒRk是æºæ“作數(寄存器),Rd是目標æ“作數(寄存器),Ra是
+4R-typeæ ¼å¼ç‰¹æœ‰çš„附加æ“作數(寄存器)。I8/I12/I14/I16/I21/I26分別是8ä½/12ä½/14ä½/
+16ä½/21ä½/26ä½çš„ç«‹å³æ•¸ã€‚其中較長的21ä½å’Œ26ä½ç«‹å³æ•¸åœ¨æŒ‡ä»¤å­—中被分割爲高ä½éƒ¨åˆ†èˆ‡ä½Žä½
+部分,所以你們在這è£çš„æ ¼å¼æ述中能夠看到I21L/I21Hå’ŒI26L/I26H這樣帶後綴的表述。
+
+指令列表
+--------
+
+爲了簡便起見,我們在此åªç¾…列一下指令å稱(助記符),需è¦è©³ç´°ä¿¡æ¯è«‹é–±è®€
+:ref:`åƒè€ƒæ–‡ç» <loongarch-references-zh_TW>` 中的文檔。
+
+1. ç®—è¡“é‹ç®—指令::
+
+ ADD.W SUB.W ADDI.W ADD.D SUB.D ADDI.D
+ SLT SLTU SLTI SLTUI
+ AND OR NOR XOR ANDN ORN ANDI ORI XORI
+ MUL.W MULH.W MULH.WU DIV.W DIV.WU MOD.W MOD.WU
+ MUL.D MULH.D MULH.DU DIV.D DIV.DU MOD.D MOD.DU
+ PCADDI PCADDU12I PCADDU18I
+ LU12I.W LU32I.D LU52I.D ADDU16I.D
+
+2. 移ä½é‹ç®—指令::
+
+ SLL.W SRL.W SRA.W ROTR.W SLLI.W SRLI.W SRAI.W ROTRI.W
+ SLL.D SRL.D SRA.D ROTR.D SLLI.D SRLI.D SRAI.D ROTRI.D
+
+3. ä½åŸŸæ“作指令::
+
+ EXT.W.B EXT.W.H CLO.W CLO.D SLZ.W CLZ.D CTO.W CTO.D CTZ.W CTZ.D
+ BYTEPICK.W BYTEPICK.D BSTRINS.W BSTRINS.D BSTRPICK.W BSTRPICK.D
+ REVB.2H REVB.4H REVB.2W REVB.D REVH.2W REVH.D BITREV.4B BITREV.8B BITREV.W BITREV.D
+ MASKEQZ MASKNEZ
+
+4. 分支轉移指令::
+
+ BEQ BNE BLT BGE BLTU BGEU BEQZ BNEZ B BL JIRL
+
+5. 訪存讀寫指令::
+
+ LD.B LD.BU LD.H LD.HU LD.W LD.WU LD.D ST.B ST.H ST.W ST.D
+ LDX.B LDX.BU LDX.H LDX.HU LDX.W LDX.WU LDX.D STX.B STX.H STX.W STX.D
+ LDPTR.W LDPTR.D STPTR.W STPTR.D
+ PRELD PRELDX
+
+6. 原å­æ“作指令::
+
+ LL.W SC.W LL.D SC.D
+ AMSWAP.W AMSWAP.D AMADD.W AMADD.D AMAND.W AMAND.D AMOR.W AMOR.D AMXOR.W AMXOR.D
+ AMMAX.W AMMAX.D AMMIN.W AMMIN.D
+
+7. 柵障指令::
+
+ IBAR DBAR
+
+8. 特殊指令::
+
+ SYSCALL BREAK CPUCFG NOP IDLE ERTN(ERET) DBCL(DBGCALL) RDTIMEL.W RDTIMEH.W RDTIME.D
+ ASRTLE.D ASRTGT.D
+
+9. 特權指令::
+
+ CSRRD CSRWR CSRXCHG
+ IOCSRRD.B IOCSRRD.H IOCSRRD.W IOCSRRD.D IOCSRWR.B IOCSRWR.H IOCSRWR.W IOCSRWR.D
+ CACOP TLBP(TLBSRCH) TLBRD TLBWR TLBFILL TLBCLR TLBFLUSH INVTLB LDDIR LDPTE
+
+虛擬內存
+========
+
+LoongArchå¯ä»¥ä½¿ç”¨ç›´æŽ¥æ˜ å°„虛擬內存和分é æ˜ å°„虛擬內存。
+
+直接映射虛擬內存通éŽCSR.DMWn(n=0~3)來進行é…置,虛擬地å€ï¼ˆVA)和物ç†åœ°å€ï¼ˆPA)
+之間有簡單的映射關係::
+
+ VA = PA + 固定å移
+
+分é æ˜ å°„的虛擬地å€ï¼ˆVA)和物ç†åœ°å€ï¼ˆPA)有任æ„的映射關係,這種關係記錄在TLBå’Œé 
+表中。LoongArchçš„TLB包括一個全相è¯çš„MTLB(Multiple Page Size TLB,多樣é å¤§å°TLB)
+和一個組相è¯çš„STLB(Single Page Size TLB,單一é å¤§å°TLB)。
+
+缺çœç‹€æ…‹ä¸‹ï¼ŒLA32的整個虛擬地å€ç©ºé–“é…置如下:
+
+============ =========================== ===========================
+å€æ®µå 地å€ç¯„åœ å±¬æ€§
+============ =========================== ===========================
+``UVRANGE`` ``0x00000000 - 0x7FFFFFFF`` 分é æ˜ å°„, å¯ç·©å­˜, PLV0~3
+``KPRANGE0`` ``0x80000000 - 0x9FFFFFFF`` 直接映射, éžç·©å­˜, PLV0
+``KPRANGE1`` ``0xA0000000 - 0xBFFFFFFF`` 直接映射, å¯ç·©å­˜, PLV0
+``KVRANGE`` ``0xC0000000 - 0xFFFFFFFF`` 分é æ˜ å°„, å¯ç·©å­˜, PLV0
+============ =========================== ===========================
+
+用戶態(PLV3)åªèƒ½è¨ªå•UVRANGE,å°æ–¼ç›´æŽ¥æ˜ å°„çš„KPRANGE0å’ŒKPRANGE1,將虛擬地å€çš„第
+30~31ä½æ¸…零就等於物ç†åœ°å€ã€‚例如:物ç†åœ°å€0x00001000å°æ‡‰çš„éžç·©å­˜ç›´æŽ¥æ˜ å°„虛擬地å€
+是0x80001000,而其å¯ç·©å­˜ç›´æŽ¥æ˜ å°„虛擬地å€æ˜¯0xA0001000。
+
+缺çœç‹€æ…‹ä¸‹ï¼ŒLA64的整個虛擬地å€ç©ºé–“é…置如下:
+
+============ ====================== ==================================
+å€æ®µå 地å€ç¯„åœ å±¬æ€§
+============ ====================== ==================================
+``XUVRANGE`` ``0x0000000000000000 - 分é æ˜ å°„, å¯ç·©å­˜, PLV0~3
+ 0x3FFFFFFFFFFFFFFF``
+``XSPRANGE`` ``0x4000000000000000 - 直接映射, å¯ç·©å­˜ / éžç·©å­˜, PLV0
+ 0x7FFFFFFFFFFFFFFF``
+``XKPRANGE`` ``0x8000000000000000 - 直接映射, å¯ç·©å­˜ / éžç·©å­˜, PLV0
+ 0xBFFFFFFFFFFFFFFF``
+``XKVRANGE`` ``0xC000000000000000 - 分é æ˜ å°„, å¯ç·©å­˜, PLV0
+ 0xFFFFFFFFFFFFFFFF``
+============ ====================== ==================================
+
+用戶態(PLV3)åªèƒ½è¨ªå•XUVRANGE,å°æ–¼ç›´æŽ¥æ˜ å°„çš„XSPRANGEå’ŒXKPRANGE,將虛擬地å€çš„第
+60~63ä½æ¸…零就等於物ç†åœ°å€ï¼Œè€Œå…¶ç·©å­˜å±¬æ€§æ˜¯é€šéŽè™›æ“¬åœ°å€çš„第60~61ä½é…置的(0表示強åº
+éžç·©å­˜ï¼Œ1表示一致å¯ç·©å­˜ï¼Œ2表示弱åºéžç·©å­˜ï¼‰ã€‚
+
+ç›®å‰ï¼Œæˆ‘們僅用XKPRANGE來進行直接映射,XSPRANGEä¿ç•™çµ¦ä»¥å¾Œç”¨ã€‚
+
+此處給出一個直接映射的例å­ï¼šç‰©ç†åœ°å€0x00000000_00001000çš„å¼·åºéžç·©å­˜ç›´æŽ¥æ˜ å°„虛擬地å€
+(在XKPRANGE中)是0x80000000_00001000,其一致å¯ç·©å­˜ç›´æŽ¥æ˜ å°„虛擬地å€ï¼ˆåœ¨XKPRANGE中)
+是0x90000000_00001000,而其弱åºéžç·©å­˜ç›´æŽ¥æ˜ å°„虛擬地å€ï¼ˆåœ¨XKPRANGE中)是0xA0000000_
+00001000。
+
+Loongson與LoongArch的關係
+=========================
+
+LoongArch是一種RISC指令集架構(ISA),ä¸åŒæ–¼ç¾å­˜çš„任何一種ISA,而Loongson(å³é¾
+芯)是一個處ç†å™¨å®¶æ—。é¾èŠ¯åŒ…括三個系列:Loongson-1(é¾èŠ¯1號)是32ä½è™•ç†å™¨ç³»åˆ—,
+Loongson-2(é¾èŠ¯2號)是低端64ä½è™•ç†å™¨ç³»åˆ—,而Loongson-3(é¾èŠ¯3號)是高端64ä½è™•ç†
+器系列。舊的é¾èŠ¯è™•ç†å™¨åŸºæ–¼MIPS架構,而新的é¾èŠ¯è™•ç†å™¨åŸºæ–¼LoongArch架構。以é¾èŠ¯3號
+爲例:é¾èŠ¯3A1000/3B1500/3A2000/3A3000/3A4000都是兼容MIPS的,而é¾èŠ¯3A5000(以åŠå°‡
+來的型號)都是基於LoongArch的。
+
+.. _loongarch-references-zh_TW:
+
+åƒè€ƒæ–‡ç»
+========
+
+Loongson官方網站(é¾èŠ¯ä¸­ç§‘技術股份有é™å…¬å¸ï¼‰ï¼š
+
+ http://www.loongson.cn/
+
+Loongson與LoongArch的開發者網站(軟件與文檔資æºï¼‰ï¼š
+
+ http://www.loongnix.cn/
+
+ https://github.com/loongson/
+
+ https://loongson.github.io/LoongArch-Documentation/
+
+LoongArch指令集架構的文檔:
+
+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-CN.pdf (中文版)
+
+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-EN.pdf (英文版)
+
+LoongArch的ELF psABI文檔:
+
+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-CN.pdf (中文版)
+
+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-EN.pdf (英文版)
+
+Loongson與LoongArchçš„Linux內核æºç¢¼å€‰åº«ï¼š
+
+ https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git
+
diff --git a/Documentation/translations/zh_TW/arch/loongarch/irq-chip-model.rst b/Documentation/translations/zh_TW/arch/loongarch/irq-chip-model.rst
new file mode 100644
index 000000000000..dbe9595bbf16
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/loongarch/irq-chip-model.rst
@@ -0,0 +1,158 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/loongarch/irq-chip-model.rst
+:Translator: Huacai Chen <chenhuacai@loongson.cn>
+
+==================================
+LoongArch的IRQ芯片模型(層級關係)
+==================================
+
+ç›®å‰ï¼ŒåŸºæ–¼LoongArch的處ç†å™¨ï¼ˆå¦‚é¾èŠ¯3A5000)åªèƒ½èˆ‡LS7A芯片組é…åˆå·¥ä½œã€‚LoongArch計算機
+中的中斷控制器(å³IRQ芯片)包括CPUINTC(CPU Core Interrupt Controller)ã€LIOINTC(
+Legacy I/O Interrupt Controller)ã€EIOINTC(Extended I/O Interrupt Controller)ã€
+HTVECINTC(Hyper-Transport Vector Interrupt Controller)ã€PCH-PIC(LS7A芯片組的主中
+斷控制器)ã€PCH-LPC(LS7A芯片組的LPC中斷控制器)和PCH-MSI(MSI中斷控制器)。
+
+CPUINTC是一種CPU內部的æ¯å€‹æ ¸æœ¬åœ°çš„中斷控制器,LIOINTC/EIOINTC/HTVECINTC是CPU內部的
+全局中斷控制器(æ¯å€‹èŠ¯ç‰‡ä¸€å€‹ï¼Œæ‰€æœ‰æ ¸å…±äº«ï¼‰ï¼Œè€ŒPCH-PIC/PCH-LPC/PCH-MSI是CPU外部的中
+斷控制器(在é…套芯片組è£é¢ï¼‰ã€‚這些中斷控制器(或者說IRQ芯片)以一種層次樹的組織形å¼
+ç´šè¯åœ¨ä¸€èµ·ï¼Œä¸€å…±æœ‰å…©ç¨®å±¤ç´šé—œä¿‚模型(傳統IRQ模型和擴展IRQ模型)。
+
+傳統IRQ模型
+===========
+
+在這種模型è£é¢ï¼ŒIPI(Inter-Processor Interrupt)和CPU本地時é˜ä¸­æ–·ç›´æŽ¥ç™¼é€åˆ°CPUINTC,
+CPU串å£ï¼ˆUARTs)中斷髮é€åˆ°LIOINTC,而其他所有設備的中斷則分別發é€åˆ°æ‰€é€£æŽ¥çš„PCH-PIC/
+PCH-LPC/PCH-MSI,然後被HTVECINTC統一收集,å†ç™¼é€åˆ°LIOINTC,最後到é”CPUINTC::
+
+ +-----+ +---------+ +-------+
+ | IPI | --> | CPUINTC | <-- | Timer |
+ +-----+ +---------+ +-------+
+ ^
+ |
+ +---------+ +-------+
+ | LIOINTC | <-- | UARTs |
+ +---------+ +-------+
+ ^
+ |
+ +-----------+
+ | HTVECINTC |
+ +-----------+
+ ^ ^
+ | |
+ +---------+ +---------+
+ | PCH-PIC | | PCH-MSI |
+ +---------+ +---------+
+ ^ ^ ^
+ | | |
+ +---------+ +---------+ +---------+
+ | PCH-LPC | | Devices | | Devices |
+ +---------+ +---------+ +---------+
+ ^
+ |
+ +---------+
+ | Devices |
+ +---------+
+
+擴展IRQ模型
+===========
+
+在這種模型è£é¢ï¼ŒIPI(Inter-Processor Interrupt)和CPU本地時é˜ä¸­æ–·ç›´æŽ¥ç™¼é€åˆ°CPUINTC,
+CPU串å£ï¼ˆUARTs)中斷髮é€åˆ°LIOINTC,而其他所有設備的中斷則分別發é€åˆ°æ‰€é€£æŽ¥çš„PCH-PIC/
+PCH-LPC/PCH-MSI,然後被EIOINTC統一收集,å†ç›´æŽ¥åˆ°é”CPUINTC::
+
+ +-----+ +---------+ +-------+
+ | IPI | --> | CPUINTC | <-- | Timer |
+ +-----+ +---------+ +-------+
+ ^ ^
+ | |
+ +---------+ +---------+ +-------+
+ | EIOINTC | | LIOINTC | <-- | UARTs |
+ +---------+ +---------+ +-------+
+ ^ ^
+ | |
+ +---------+ +---------+
+ | PCH-PIC | | PCH-MSI |
+ +---------+ +---------+
+ ^ ^ ^
+ | | |
+ +---------+ +---------+ +---------+
+ | PCH-LPC | | Devices | | Devices |
+ +---------+ +---------+ +---------+
+ ^
+ |
+ +---------+
+ | Devices |
+ +---------+
+
+ACPI相關的定義
+==============
+
+CPUINTC::
+
+ ACPI_MADT_TYPE_CORE_PIC;
+ struct acpi_madt_core_pic;
+ enum acpi_madt_core_pic_version;
+
+LIOINTC::
+
+ ACPI_MADT_TYPE_LIO_PIC;
+ struct acpi_madt_lio_pic;
+ enum acpi_madt_lio_pic_version;
+
+EIOINTC::
+
+ ACPI_MADT_TYPE_EIO_PIC;
+ struct acpi_madt_eio_pic;
+ enum acpi_madt_eio_pic_version;
+
+HTVECINTC::
+
+ ACPI_MADT_TYPE_HT_PIC;
+ struct acpi_madt_ht_pic;
+ enum acpi_madt_ht_pic_version;
+
+PCH-PIC::
+
+ ACPI_MADT_TYPE_BIO_PIC;
+ struct acpi_madt_bio_pic;
+ enum acpi_madt_bio_pic_version;
+
+PCH-MSI::
+
+ ACPI_MADT_TYPE_MSI_PIC;
+ struct acpi_madt_msi_pic;
+ enum acpi_madt_msi_pic_version;
+
+PCH-LPC::
+
+ ACPI_MADT_TYPE_LPC_PIC;
+ struct acpi_madt_lpc_pic;
+ enum acpi_madt_lpc_pic_version;
+
+åƒè€ƒæ–‡ç»
+========
+
+é¾èŠ¯3A5000的文檔:
+
+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-3A5000-usermanual-1.02-CN.pdf (中文版)
+
+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-3A5000-usermanual-1.02-EN.pdf (英文版)
+
+é¾èŠ¯LS7A芯片組的文檔:
+
+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-CN.pdf (中文版)
+
+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-EN.pdf (英文版)
+
+.. note::
+ - CPUINTC:å³ã€Šé¾èŠ¯æž¶æ§‹åƒè€ƒæ‰‹å†Šå·ä¸€ã€‹ç¬¬7.4節所æè¿°çš„CSR.ECFG/CSR.ESTAT寄存器åŠå…¶
+ 中斷控制é‚輯;
+ - LIOINTC:å³ã€Šé¾èŠ¯3A5000處ç†å™¨ä½¿ç”¨æ‰‹å†Šã€‹ç¬¬11.1節所æ述的“傳統I/O中斷â€ï¼›
+ - EIOINTC:å³ã€Šé¾èŠ¯3A5000處ç†å™¨ä½¿ç”¨æ‰‹å†Šã€‹ç¬¬11.2節所æ述的“擴展I/O中斷â€ï¼›
+ - HTVECINTC:å³ã€Šé¾èŠ¯3A5000處ç†å™¨ä½¿ç”¨æ‰‹å†Šã€‹ç¬¬14.3節所æ述的“HyperTransport中斷â€ï¼›
+ - PCH-PIC/PCH-MSI:å³ã€Šé¾èŠ¯7A1000橋片用戶手冊》第5章所æ述的“中斷控制器â€ï¼›
+ - PCH-LPC:å³ã€Šé¾èŠ¯7A1000橋片用戶手冊》第24.3節所æ述的“LPC中斷â€ã€‚
+
diff --git a/Documentation/translations/zh_TW/arch/mips/booting.rst b/Documentation/translations/zh_TW/arch/mips/booting.rst
new file mode 100644
index 000000000000..7e104abf5a51
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/mips/booting.rst
@@ -0,0 +1,35 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/mips/booting.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_booting:
+
+BMIPS設備樹引導
+------------------------
+
+ 一些bootloadersåªæ”¯æŒåœ¨å…§æ ¸é¡åƒé–‹å§‹åœ°å€è™•çš„單一入å£é»žã€‚而其它
+ bootloaders將跳轉到ELF的開始地å€è™•ã€‚兩種方案都支æŒçš„;因爲
+ CONFIG_BOOT_RAW=y and CONFIG_NO_EXCEPT_FILL=y, 所以第一æ¢æŒ‡ä»¤
+ 會立å³è·³è½‰åˆ°kernel_entry()å…¥å£è™•åŸ·è¡Œã€‚
+
+ 與arch/arm情æ³(b)類似,dt感知的引導加載程åºéœ€è¦è¨­ç½®ä»¥ä¸‹å¯„存器:
+
+ a0 : 0
+
+ a1 : 0xffffffff
+
+ a2 : RAM中指å‘設備樹塊的物ç†æŒ‡é‡(在chapterII中定義)。
+ 設備樹å¯ä»¥ä½æ–¼å‰512MB物ç†åœ°å€ç©ºé–“(0x00000000 -
+ 0x1fffffff)的任何ä½ç½®ï¼Œä»¥64ä½é‚Šç•Œå°é½Šã€‚
+
+ 傳統bootloadersä¸æœƒä½¿ç”¨é€™æ¨£çš„約定,並且它們ä¸å‚³å…¥DT塊。
+ 在這種情æ³ä¸‹ï¼ŒLinux將通éŽé¸ä¸­CONFIG_DT_*查找DTB。
+
+ 以上約定åªåœ¨32ä½ç³»çµ±ä¸­å®šç¾©ï¼Œå› çˆ²ç›®å‰æ²’有任何64ä½çš„BMIPS實ç¾ã€‚
+
diff --git a/Documentation/translations/zh_TW/arch/mips/features.rst b/Documentation/translations/zh_TW/arch/mips/features.rst
new file mode 100644
index 000000000000..f69410420035
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/mips/features.rst
@@ -0,0 +1,14 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/mips/features.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_features:
+
+.. kernel-feat:: $srctree/Documentation/features mips
+
diff --git a/Documentation/translations/zh_TW/arch/mips/index.rst b/Documentation/translations/zh_TW/arch/mips/index.rst
new file mode 100644
index 000000000000..4b7d28806489
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/mips/index.rst
@@ -0,0 +1,30 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/mips/index.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+===========================
+MIPS特性文檔
+===========================
+
+.. toctree::
+ :maxdepth: 2
+ :numbered:
+
+ booting
+ ingenic-tcu
+
+ features
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
+
diff --git a/Documentation/translations/zh_TW/arch/mips/ingenic-tcu.rst b/Documentation/translations/zh_TW/arch/mips/ingenic-tcu.rst
new file mode 100644
index 000000000000..4385c0f3e9cd
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/mips/ingenic-tcu.rst
@@ -0,0 +1,73 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/mips/ingenic-tcu.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_ingenic-tcu:
+
+===============================================
+å›æ­£ JZ47xx SoC定時器/計數器硬件單元
+===============================================
+
+å›æ­£ JZ47xx SoC中的定時器/計數器單元(TCU)是一個多功能硬件塊。它有多é”
+8個通é“,å¯ä»¥ç”¨ä½œè¨ˆæ•¸å™¨ï¼Œè¨ˆæ™‚器,或脈è¡å¯¬åº¦èª¿è£½å™¨ã€‚
+
+- JZ4725B, JZ4750, JZ4755 åªæœ‰ï¼–個TCU通é“。其它SoC都有8個通é“。
+
+- JZ4725B引入了一個ç¨ç«‹çš„通é“,稱爲æ“作系統計時器(OST)。這是一個32ä½å¯
+ 編程定時器。在JZ4760BåŠä»¥ä¸Šåž‹è™Ÿä¸Šï¼Œå®ƒæ˜¯64ä½çš„。
+
+- æ¯å€‹TCU通é“都有自己的時é˜æºï¼Œå¯ä»¥é€šéŽ TCSR 寄存器設置通é“的父級時é˜
+ æºï¼ˆpclkã€extã€rtc)ã€é–‹é—œä»¥åŠåˆ†é »ã€‚
+
+ - 看門狗和OST硬件模塊在它們的寄存器空間中也有相åŒå½¢å¼çš„TCSR寄存器。
+ - 用於關閉/é–‹å•“çš„ TCU 寄存器也å¯ä»¥é—œé–‰/開啓看門狗和 OST 時é˜ã€‚
+
+- æ¯å€‹TCU通é“在兩種模å¼çš„其中一種模å¼ä¸‹é‹è¡Œï¼š
+
+ - æ¨¡å¼ TCU1:通é“無法在ç¡çœ æ¨¡å¼ä¸‹é‹è¡Œï¼Œä½†æ›´æ˜“æ–¼æ“作。
+ - æ¨¡å¼ TCU2:通é“å¯ä»¥åœ¨ç¡çœ æ¨¡å¼ä¸‹é‹è¡Œï¼Œä½†æ“作比 TCU1 通é“複雜一些。
+
+- æ¯å€‹ TCU 通é“的模å¼å–決於使用的SoC:
+
+ - 在最è€çš„SoC(高於JZ4740),八個通é“都é‹è¡Œåœ¨TCU1模å¼ã€‚
+ - 在 JZ4725B,通é“5é‹è¡Œåœ¨TCU2,其它通é“則é‹è¡Œåœ¨TCU1。
+ - 在最新的SoC(JZ4750åŠä¹‹å¾Œï¼‰ï¼Œé€šé“1-2é‹è¡Œåœ¨TCU2,其它通é“則é‹è¡Œ
+ 在TCU1。
+
+- æ¯å€‹é€šé“都å¯ä»¥ç”Ÿæˆä¸­æ–·ã€‚有些通é“共享一æ¢ä¸­æ–·ç·šï¼Œè€Œæœ‰äº›æ²’有,其在SoCåž‹
+ 號之間的變更:
+
+ - 在很è€çš„SoC(JZ4740åŠæ›´ä½Žï¼‰ï¼Œé€šé“0和通é“1有它們自己的中斷線;通
+ é“2-7共享最後一æ¢ä¸­æ–·ç·šã€‚
+ - 在 JZ4725B,通é“0有它自己的中斷線;通é“1-5共享一æ¢ä¸­æ–·ç·šï¼›OST
+ 使用最後一æ¢ä¸­æ–·ç·šã€‚
+ - 在比較新的SoC(JZ4750åŠä»¥å¾Œï¼‰ï¼Œé€šé“5有它自己的中斷線;通
+ é“0-4和(如果是8通é“)6-7全部共享一æ¢ä¸­æ–·ç·šï¼›OST使用最後一æ¢ä¸­
+ 斷線。
+
+實ç¾
+====
+
+TCU硬件的功能分佈在多個驅動程åºï¼š
+
+============== ===================================
+æ™‚é˜ drivers/clk/ingenic/tcu.c
+中斷 drivers/irqchip/irq-ingenic-tcu.c
+定時器 drivers/clocksource/ingenic-timer.c
+OST drivers/clocksource/ingenic-ost.c
+脈è¡å¯¬åº¦èª¿è£½å™¨ drivers/pwm/pwm-jz4740.c
+看門狗 drivers/watchdog/jz4740_wdt.c
+============== ===================================
+
+因爲å¯ä»¥å¾žç›¸åŒçš„寄存器控制屬於ä¸åŒé©…動程åºå’Œæ¡†æž¶çš„TCUçš„å„種功能,所以
+所有這些驅動程åºéƒ½é€šéŽç›¸åŒçš„控制總線通用接å£è¨ªå•å®ƒå€‘的寄存器。
+
+有關TCU驅動程åºçš„設備樹ç¶å®šçš„更多信æ¯ï¼Œè«‹åƒé–±:
+Documentation/devicetree/bindings/timer/ingenic,tcu.yaml.
+
diff --git a/Documentation/translations/zh_TW/arch/openrisc/index.rst b/Documentation/translations/zh_TW/arch/openrisc/index.rst
new file mode 100644
index 000000000000..7585960783fc
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/openrisc/index.rst
@@ -0,0 +1,33 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/openrisc/index.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_openrisc_index:
+
+=================
+OpenRISC 體系架構
+=================
+
+.. toctree::
+ :maxdepth: 2
+
+ openrisc_port
+ todo
+
+Todolist:
+ features
+
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
+
diff --git a/Documentation/translations/zh_TW/arch/openrisc/openrisc_port.rst b/Documentation/translations/zh_TW/arch/openrisc/openrisc_port.rst
new file mode 100644
index 000000000000..422fe9f7a3f2
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/openrisc/openrisc_port.rst
@@ -0,0 +1,128 @@
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/openrisc/openrisc_port.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_openrisc_port:
+
+==============
+OpenRISC Linux
+==============
+
+這是Linuxå°OpenRISC類微處ç†å™¨çš„移æ¤ï¼›å…·é«”來說,最早移æ¤ç›®æ¨™æ˜¯32ä½
+OpenRISC 1000系列(或1k)。
+
+關於OpenRISC處ç†å™¨å’Œæ­£åœ¨é€²è¡Œä¸­çš„開發的信æ¯:
+
+ ======= =============================
+ 網站 https://openrisc.io
+ 郵箱 openrisc@lists.librecores.org
+ ======= =============================
+
+---------------------------------------------------------------------
+
+OpenRISC工具éˆå’ŒLinux的構建指å—
+===============================
+
+爲了構建和é‹è¡ŒLinux for OpenRISC,你至少需è¦ä¸€å€‹åŸºæœ¬çš„工具éˆï¼Œæˆ–許
+還需è¦æž¶æ§‹æ¨¡æ“¬å™¨ã€‚ 這è£æ¦‚述了準備就ä½é€™äº›éƒ¨åˆ†çš„步驟。
+
+1) 工具éˆ
+
+工具éˆäºŒé€²åˆ¶æ–‡ä»¶å¯ä»¥å¾žopenrisc.io或我們的github發佈é é¢ç²å¾—。ä¸åŒ
+工具éˆçš„構建指å—å¯ä»¥åœ¨openrisc.io或Stafford的工具éˆæ§‹å»ºå’Œç™¼ä½ˆè…³æœ¬
+中找到。
+
+ ====== =================================================
+ 二進制 https://github.com/openrisc/or1k-gcc/releases
+ å·¥å…·éˆ https://openrisc.io/software
+ 構建 https://github.com/stffrdhrn/or1k-toolchain-build
+ ====== =================================================
+
+2) 構建
+
+åƒå¾€å¸¸ä¸€æ¨£æ§‹å»ºLinux內核::
+
+ make ARCH=openrisc CROSS_COMPILE="or1k-linux-" defconfig
+ make ARCH=openrisc CROSS_COMPILE="or1k-linux-"
+
+3) 在FPGA上é‹è¡Œï¼ˆå¯é¸)
+
+OpenRISC社å€é€šå¸¸ä½¿ç”¨FuseSoC來管ç†æ§‹å»ºå’Œç·¨ç¨‹SoC到FPGA中。 下é¢æ˜¯ç”¨
+OpenRISC SoCå°De0 Nano開發æ¿é€²è¡Œç·¨ç¨‹çš„一個例å­ã€‚ 在構建éŽç¨‹ä¸­ï¼Œ
+FPGA RTL是從FuseSoC IP核庫中下載的代碼,並使用FPGA供應商工具構建。
+二進制文件用openocd加載到電路æ¿ä¸Šã€‚
+
+::
+
+ git clone https://github.com/olofk/fusesoc
+ cd fusesoc
+ sudo pip install -e .
+
+ fusesoc init
+ fusesoc build de0_nano
+ fusesoc pgm de0_nano
+
+ openocd -f interface/altera-usb-blaster.cfg \
+ -f board/or1k_generic.cfg
+
+ telnet localhost 4444
+ > init
+ > halt; load_image vmlinux ; reset
+
+4) 在模擬器上é‹è¡Œï¼ˆå¯é¸ï¼‰
+
+QEMU是一個處ç†å™¨ä»¿çœŸå™¨ï¼Œæˆ‘們推薦它來模擬OpenRISC平臺。 請按照QEMU網
+站上的OpenRISC說明,讓Linux在QEMU上é‹è¡Œã€‚ ä½ å¯ä»¥è‡ªå·±æ§‹å»ºQEMU,但你的
+Linux發行版å¯èƒ½æ供了支æŒOpenRISC的二進制包。
+
+ ============= ======================================================
+ qemu openrisc https://wiki.qemu.org/Documentation/Platforms/OpenRISC
+ ============= ======================================================
+
+---------------------------------------------------------------------
+
+術語表
+======
+
+代碼中使用了以下符號約定以將範åœé™åˆ¶åœ¨å¹¾å€‹ç‰¹å®šè™•ç†å™¨å¯¦ç¾ä¸Šï¼š
+
+========= =======================
+openrisc: OpenRISC類型處ç†å™¨
+or1k: OpenRISC 1000系列處ç†å™¨
+or1200: OpenRISC 1200處ç†å™¨
+========= =======================
+
+---------------------------------------------------------------------
+
+æ­·å²
+====
+
+2003-11-18 Matjaz Breskvar (phoenix@bsemi.com)
+ å°‡linuxåˆæ­¥ç§»æ¤åˆ°OpenRISC或32架構。
+ 所有的核心功能都實ç¾äº†ï¼Œä¸¦ä¸”å¯ä»¥ä½¿ç”¨ã€‚
+
+2003-12-08 Matjaz Breskvar (phoenix@bsemi.com)
+ 徹底改變TLB失誤處ç†ã€‚
+ é‡å¯«ç•°å¸¸è™•ç†ã€‚
+ 在默èªçš„initrd中實ç¾äº†sash-3.6的所有功能。
+ 大幅改進的版本。
+
+2004-04-10 Matjaz Breskvar (phoenix@bsemi.com)
+ 大é‡çš„bug修復。
+ 支æŒä»¥å¤ªç¶²ï¼Œhttpå’Œtelnetæœå‹™å™¨åŠŸèƒ½ã€‚
+ å¯ä»¥é‹è¡Œè¨±å¤šæ¨™æº–çš„linux應用程åºã€‚
+
+2004-06-26 Matjaz Breskvar (phoenix@bsemi.com)
+ 移æ¤åˆ°2.6.x。
+
+2004-11-30 Matjaz Breskvar (phoenix@bsemi.com)
+ 大é‡çš„bug修復和增強功能。
+ 增加了opencores framebuffer驅動。
+
+2010-10-09 Jonas Bonn (jonas@southpole.se)
+ é‡å¤§é‡å¯«ï¼Œä½¿å…¶èˆ‡ä¸Šæ¸¸çš„Linux 2.6.36看齊。
+
diff --git a/Documentation/translations/zh_TW/arch/openrisc/todo.rst b/Documentation/translations/zh_TW/arch/openrisc/todo.rst
new file mode 100644
index 000000000000..df261b9e3002
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/openrisc/todo.rst
@@ -0,0 +1,24 @@
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/openrisc/todo.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_openrisc_todo.rst:
+
+========
+待辦事項
+========
+
+OpenRISC Linux的移æ¤å·²ç¶“完全投入使用,並且從 2.6.35 開始就一直在上游åŒæ­¥ã€‚
+然而,還有一些剩餘的項目需è¦åœ¨æœªä¾†å¹¾å€‹æœˆå…§å®Œæˆã€‚ 下é¢æ˜¯ä¸€å€‹å³å°‡é€²è¡Œèª¿æŸ¥çš„已知
+ä¸ç›¡å®Œç¾Žçš„項目列表,å³æˆ‘們的待辦事項列表。
+
+- 實ç¾å…¶é¤˜çš„DMA API……dma_map_sg等。
+
+- 完æˆé‡å‘½å清ç†å·¥ä½œâ€¦â€¦ä»£ç¢¼ä¸­æ到了or32,這是架構的一個è€å字。 我們
+ 已經確定的å字是or1k,這個改變正在以緩慢ç©ç´¯çš„æ–¹å¼é€²è¡Œã€‚ ç›®å‰ï¼Œor32相當
+ 於or1k。
+
diff --git a/Documentation/translations/zh_TW/arch/parisc/debugging.rst b/Documentation/translations/zh_TW/arch/parisc/debugging.rst
new file mode 100644
index 000000000000..c9ee804aebbd
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/parisc/debugging.rst
@@ -0,0 +1,46 @@
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/parisc/debugging.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_parisc_debugging:
+
+=================
+調試PA-RISC
+=================
+
+好å§ï¼Œé€™è£æœ‰ä¸€äº›é—œæ–¼èª¿è©¦linux/parisc的較底層部分的信æ¯ã€‚
+
+
+1. 絕å°åœ°å€
+=====================
+
+很多彙編代碼目å‰é‹è¡Œåœ¨å¯¦æ¨¡å¼ä¸‹ï¼Œé€™æ„味ç€æœƒä½¿ç”¨çµ•å°åœ°å€ï¼Œè€Œä¸æ˜¯åƒå…§æ ¸å…¶ä»–
+部分那樣使用虛擬地å€ã€‚è¦å°‡çµ•å°åœ°å€è½‰æ›çˆ²è™›æ“¬åœ°å€ï¼Œä½ å¯ä»¥åœ¨System.map中查
+找,添加__PAGE_OFFSET(目å‰æ˜¯0x10000000)。
+
+
+2. HPMCs
+========
+
+當實模å¼çš„代碼試圖訪å•ä¸å­˜åœ¨çš„內存時,會出ç¾HPMC(high priority machine
+check)而ä¸æ˜¯å…§æ ¸oops。若è¦èª¿è©¦HPMC,請嘗試找到系統響應程åº/請求程åºåœ°å€ã€‚
+系統請求程åºåœ°å€æ‡‰è©²èˆ‡ï¼ˆæŸï¼‰è™•ç†å™¨çš„HPA(I/O範åœå…§çš„高地å€ï¼‰ç›¸åŒ¹é…;系統響應程
+åºåœ°å€æ˜¯å¯¦æ¨¡å¼ä»£ç¢¼è©¦åœ–訪å•çš„地å€ã€‚
+
+系統響應程åºåœ°å€çš„典型值是大於__PAGE_OFFSET (0x10000000)的地å€ï¼Œé€™æ„味ç€
+在實模å¼è©¦åœ–訪å•å®ƒä¹‹å‰ï¼Œè™›æ“¬åœ°å€æ²’有被翻譯æˆç‰©ç†åœ°å€ã€‚
+
+
+3. 有趣的Qä½
+============
+
+æŸäº›éžå¸¸é—œéµçš„代碼必須清除PSW中的Qä½ã€‚當Qä½è¢«æ¸…除時,CPUä¸æœƒæ›´æ–°ä¸­æ–·è™•ç†
+程åºæ‰€è®€å–的寄存器,以找出機器被中斷的ä½ç½®â€”—所以如果你在清除Qä½çš„指令和å†
+次設置Qä½çš„RFI之間é‡åˆ°ä¸­æ–·ï¼Œä½ ä¸çŸ¥é“它到底發生在哪è£ã€‚如果你幸é‹çš„話,IAOQ
+會指å‘清除Qä½çš„指令,如果你ä¸å¹¸é‹çš„話,它會指å‘任何地方。通常Qä½çš„å•é¡Œæœƒ
+表ç¾çˆ²ç„¡æ³•è§£é‡‹çš„系統掛起或物ç†å…§å­˜è¶Šç•Œã€‚
+
diff --git a/Documentation/translations/zh_TW/arch/parisc/index.rst b/Documentation/translations/zh_TW/arch/parisc/index.rst
new file mode 100644
index 000000000000..35941bf68c88
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/parisc/index.rst
@@ -0,0 +1,32 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/parisc/index.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_parisc_index:
+
+====================
+PA-RISC體系架構
+====================
+
+.. toctree::
+ :maxdepth: 2
+
+ debugging
+ registers
+
+Todolist:
+
+ features
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
+
diff --git a/Documentation/translations/zh_TW/arch/parisc/registers.rst b/Documentation/translations/zh_TW/arch/parisc/registers.rst
new file mode 100644
index 000000000000..695acb21134a
--- /dev/null
+++ b/Documentation/translations/zh_TW/arch/parisc/registers.rst
@@ -0,0 +1,157 @@
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/arch/parisc/registers.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_parisc_registers:
+
+=========================
+Linux/PA-RISC的寄存器用法
+=========================
+
+[ 用星號表示目å‰å°šæœªå¯¦ç¾çš„計劃用途。 ]
+
+ABI約定的通用寄存器
+===================
+
+控制寄存器
+----------
+
+============================ =================================
+CR 0 (æ¢å¾©è¨ˆæ•¸å™¨) 用於ptrace
+CR 1-CR 7(無定義) 未使用
+CR 8 (Protection ID) æ¯é€²ç¨‹å€¼*
+CR 9, 12, 13 (PIDS) 未使用
+CR10 (CCR) FPU延é²ä¿å­˜*
+CR11 按照ABIçš„è¦å®šï¼ˆSAR)
+CR14 (中斷å‘é‡) åˆå§‹åŒ–爲 fault_vector
+CR15 (EIEM) 所有ä½åˆå§‹åŒ–爲1*
+CR16 (間隔計時器) 讀å–週期數/寫入開始時間間隔計時器
+CR17-CR22 中斷åƒæ•¸
+CR19 中斷指令寄存器
+CR20 中斷空間寄存器
+CR21 中斷å移é‡å¯„存器
+CR22 中斷 PSW
+CR23 (EIRR) 讀å–未決中斷/寫入清除ä½
+CR24 (TR 0) 內核空間é ç›®éŒ„指é‡
+CR25 (TR 1) 用戶空間é ç›®éŒ„指é‡
+CR26 (TR 2) ä¸ä½¿ç”¨
+CR27 (TR 3) 線程æ述符指é‡
+CR28 (TR 4) ä¸ä½¿ç”¨
+CR29 (TR 5) ä¸ä½¿ç”¨
+CR30 (TR 6) ç•¶å‰ / 0
+CR31 (TR 7) 臨時寄存器,在ä¸åŒåœ°æ–¹ä½¿ç”¨
+============================ =================================
+
+空間寄存器(內核模å¼ï¼‰
+----------------------
+
+======== ==============================
+SR0 臨時空間寄存器
+SR4-SR7 設置爲0
+SR1 臨時空間寄存器
+SR2 內核ä¸æ‡‰è©²ç ´å£žå®ƒ
+SR3 用於用戶空間訪å•ï¼ˆç•¶å‰é€²ç¨‹ï¼‰
+======== ==============================
+
+空間寄存器(用戶模å¼ï¼‰
+----------------------
+
+======== ============================
+SR0 臨時空間寄存器
+SR1 臨時空間寄存器
+SR2 ä¿å­˜Linux gateway page的空間
+SR3 在內核中ä¿å­˜ç”¨æˆ¶åœ°å€ç©ºé–“的值
+SR4-SR7 定義了用戶/內核的短地å€ç©ºé–“
+======== ============================
+
+
+處ç†å™¨ç‹€æ…‹å­—
+------------
+
+====================== ================================================
+W (64ä½åœ°å€ï¼‰ 0
+E (å°å°¾ç«¯ï¼‰ 0
+S (安全間隔計時器) 0
+T (產生分支陷阱) 0
+H (高特權級陷阱) 0
+L (低特權級陷阱) 0
+N (撤銷下一æ¢æŒ‡ä»¤ï¼‰ 被C代碼使用
+X (數據存儲中斷ç¦ç”¨ï¼‰ 0
+B (產生分支) 被C代碼使用
+C (代碼地å€è½‰è­¯ï¼‰ 1, 在執行實模å¼ä»£ç¢¼æ™‚爲0
+V (除法步長校正) 被C代碼使用
+M (HPMC 掩碼) 0, 在執行HPMCæ“作*時爲1
+C/B (進/借 ä½ï¼‰ 被C代碼使用
+O (有åºå¼•ç”¨ï¼‰ 1*
+F (性能監視器) 0
+R (回收計數器陷阱) 0
+Q (收集中斷狀態) 1 (在rfi之å‰çš„代碼中爲0)
+P (ä¿è­·æ¨™è­˜ç¬¦ï¼‰ 1*
+D (數據地å€è½‰è­¯ï¼‰ 1, 在執行實模å¼ä»£ç¢¼æ™‚爲0
+I (外部中斷掩碼) ç”±cli()/sti()å®ä½¿ç”¨ã€‚
+====================== ================================================
+
+“隱形â€å¯„存器(影å­å¯„存器)
+---------------------------
+
+============= ===================
+PSW W 默èªå€¼ 0
+PSW E 默èªå€¼ 0
+å½±å­å¯„存器 被中斷處ç†ä»£ç¢¼ä½¿ç”¨
+TOCå•“ç”¨ä½ 1
+============= ===================
+
+----------------------------------------------------------
+
+PA-RISC架構定義了7個寄存器作爲“影å­å¯„存器â€ã€‚這些寄存器在
+RETURN FROM INTERRUPTION AND RESTORE指令中使用,通éŽæ¶ˆ
+除中斷處ç†ç¨‹åºä¸­å°ä¸€èˆ¬å¯„存器(GR)的ä¿å­˜å’Œæ¢å¾©çš„需è¦ä¾†æ¸›
+少狀態ä¿å­˜å’Œæ¢å¾©æ™‚間。影å­å¯„存器是GRs 1, 8, 9, 16, 17,
+24和25。
+
+-------------------------------------------------------------------------
+
+寄存器使用說明,最åˆç”±John Marvinæ供,並由Randolph Chungæ供一些補充說明。
+
+å°æ–¼é€šç”¨å¯„存器:
+
+r1,r2,r19-r26,r28,r29 & r31å¯ä»¥åœ¨ä¸ä¿å­˜å®ƒå€‘的情æ³ä¸‹è¢«ä½¿ç”¨ã€‚當然,如果你
+關心它們,在調用å¦ä¸€å€‹ç¨‹åºä¹‹å‰ï¼Œä½ ä¹Ÿéœ€è¦ä¿å­˜å®ƒå€‘。上é¢çš„一些寄存器確實
+有特殊的å«ç¾©ï¼Œä½ æ‡‰è©²æ³¨æ„一下:
+
+ r1:
+ addil指令是硬性è¦å®šå°‡å…¶çµæžœæ”¾åœ¨r1中,所以如果你使用這æ¢æŒ‡ä»¤è¦
+ 注æ„這點。
+
+ r2:
+ 這就是返回指é‡ã€‚一般來說,你ä¸æƒ³ä½¿ç”¨å®ƒï¼Œå› çˆ²ä½ éœ€è¦é€™å€‹æŒ‡é‡ä¾†è¿”
+ 回給你的調用者。然而,它與這組寄存器組åˆåœ¨ä¸€èµ·ï¼Œå› çˆ²èª¿ç”¨è€…ä¸èƒ½
+ ä¾è³´ä½ è¿”回時的值是相åŒçš„,也就是說,你å¯ä»¥å°‡r2複製到å¦ä¸€å€‹å¯„å­˜
+ 器,並在作廢r2後通éŽè©²å¯„存器返回,這應該ä¸æœƒçµ¦èª¿ç”¨ç¨‹åºå¸¶ä¾†å•é¡Œã€‚
+
+ r19-r22:
+ 這些通常被èªçˆ²æ˜¯è‡¨æ™‚寄存器。
+ 請注æ„,在64ä½ä¸­å®ƒå€‘是arg7-arg4。
+
+ r23-r26:
+ 這些是arg3-arg0,也就是說,如果你ä¸å†é—œå¿ƒå‚³å…¥çš„值,你å¯ä»¥ä½¿ç”¨
+ 它們。
+
+ r28,r29:
+ 這倆是ret0和ret1。它們是你傳入返回值的地方。r28是主返回值。當返回
+ å°çµæ§‹é«”時,r29也å¯ä»¥ç”¨ä¾†å°‡æ•¸æ“šå‚³å›žçµ¦èª¿ç”¨ç¨‹åºã€‚
+
+ r30:
+ 棧指é‡
+
+ r31:
+ ble指令將返回指é‡æ”¾åœ¨é€™è£ã€‚
+
+
+ r3-r18,r27,r30需è¦è¢«ä¿å­˜å’Œæ¢å¾©ã€‚r3-r18åªæ˜¯ä¸€èˆ¬ç”¨é€”的寄存器。
+ r27是數據指é‡ï¼Œç”¨ä¾†ä½¿å°å…¨å±€è®Šé‡çš„引用更容易。r30是棧指é‡ã€‚
+
diff --git a/Documentation/translations/zh_TW/cpu-freq/core.rst b/Documentation/translations/zh_TW/cpu-freq/core.rst
index f1951e1b23bb..4f98d1e9f34b 100644
--- a/Documentation/translations/zh_TW/cpu-freq/core.rst
+++ b/Documentation/translations/zh_TW/cpu-freq/core.rst
@@ -1,13 +1,15 @@
.. SPDX-License-Identifier: GPL-2.0
-
.. include:: ../disclaimer-zh_TW.rst
-:Original: :doc:`../../../cpu-freq/core`
-:Translator: Yanteng Si <siyanteng@loongson.cn>
- Hu Haowen <src.res.211@gmail.com>
+:Original: Documentation/cpu-freq/core.rst
+
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
-.. _tw_core.rst:
+:æ ¡è­¯:
+ å”è—舟 Tang Yizhou <tangyeechou@gmail.com>
====================================
CPUFreq核心和CPUFreq通知器的通用說明
@@ -29,10 +31,10 @@ CPUFreq核心和CPUFreq通知器的通用說明
======================
cpufreq核心代碼ä½æ–¼drivers/cpufreq/cpufreq.c中。這些cpufreq代碼爲CPUFreq架構的驅
-動程åºï¼ˆé‚£äº›æ“作硬體切æ›é »çŽ‡çš„ä»£ç¢¼ï¼‰ä»¥åŠ "通知器 "æ供了一個標準化的接å£ã€‚
-這些是設備驅動程åºæˆ–需è¦äº†è§£ç­–略變化的其它內核部分(如 ACPI 熱é‡ç®¡ç†ï¼‰æˆ–所有頻率更改(除
-計時代碼外),甚至需è¦å¼·åˆ¶ç¢ºå®šé€Ÿåº¦é™åˆ¶çš„通知器(如 ARM 架構上的 LCD 驅動程åºï¼‰ã€‚
-此外, 內核 "常數" loops_per_jiffy會根據頻率變化而更新。
+動程åºï¼ˆé‚£äº›åŸ·è¡Œç¡¬ä»¶é »çŽ‡åˆ‡æ›çš„ä»£ç¢¼ï¼‰ä»¥åŠ "通知器" æ供了一個標準化的接å£ã€‚
+包括設備驅動程åºï¼›éœ€è¦äº†è§£ç­–略變化(如 ACPI 熱é‡ç®¡ç†ï¼‰ï¼Œæˆ–所有頻率變化(如計時代碼),
+甚至需è¦å¼·åˆ¶é™åˆ¶çˆ²æŒ‡å®šé »çŽ‡ï¼ˆå¦‚ ARM 架構上的 LCD 驅動程åºï¼‰çš„其它內核組件。
+此外,內核 "常數" loops_per_jiffy 會根據頻率變化而更新。
cpufreq策略的引用計數由 cpufreq_cpu_get å’Œ cpufreq_cpu_put 來完æˆï¼Œä»¥ç¢ºä¿ cpufreq é©…
動程åºè¢«æ­£ç¢ºåœ°è¨»å†Šåˆ°æ ¸å¿ƒä¸­ï¼Œä¸¦ä¸”驅動程åºåœ¨ cpufreq_put_cpu 被調用之å‰ä¸æœƒè¢«å¸è¼‰ã€‚這也ä¿è­‰
@@ -41,10 +43,10 @@ cpufreq策略的引用計數由 cpufreq_cpu_get å’Œ cpufreq_cpu_put 來完æˆï¼Œ
2. CPUFreq 通知器
====================
-CPUFreq通知器符åˆæ¨™æº–的內核通知器接å£ã€‚
+CPUFreq通知器éµå¾ªæ¨™æº–的內核通知器接å£ã€‚
關於通知器的細節請åƒé–± linux/include/linux/notifier.h。
-這裡有兩個ä¸åŒçš„CPUfreq通知器 - 策略通知器和轉æ›é€šçŸ¥å™¨ã€‚
+這è£æœ‰å…©å€‹ä¸åŒçš„CPUfreq通知器 - 策略通知器和轉æ›é€šçŸ¥å™¨ã€‚
2.1 CPUFreq策略通知器
@@ -62,27 +64,27 @@ CPUFreq通知器符åˆæ¨™æº–的內核通知器接å£ã€‚
2.2 CPUFreq轉æ›é€šçŸ¥å™¨
--------------------------------
-當CPUfreq驅動切æ›CPU核心頻率時,策略中的æ¯å€‹åœ¨ç·šCPU都會收到兩次通知,這些變化沒有任何外部干
+當CPUfreq驅動切æ›CPU核心頻率時,策略中的æ¯å€‹åœ¨ç·šCPU都會收到兩次通知,這些變化沒有任何外部幹
é ã€‚
第二個åƒæ•¸æŒ‡å®šéšŽæ®µ - CPUFREQ_PRECHANGE or CPUFREQ_POSTCHANGE.
第三個åƒæ•¸æ˜¯ä¸€å€‹åŒ…å«å¦‚下值的çµæ§‹é«”cpufreq_freqs:
-===== ====================
-cpu å—影響cpu的編號
+====== ===============================
+policy 指å‘struct cpufreq_policy的指é‡
old 舊頻率
new 新頻率
flags cpufreq驅動的標誌
-===== ====================
+====== ===============================
3. å«æœ‰Operating Performance Point (OPP)çš„CPUFreq表的生æˆ
==================================================================
關於OPP的細節請åƒé–± Documentation/power/opp.rst
dev_pm_opp_init_cpufreq_table -
- 這個功能æ供了一個隨時å¯ç”¨çš„轉æ›ç¨‹åºï¼Œç”¨ä¾†å°‡OPP層關於å¯ç”¨é »çŽ‡çš„內部信æ¯ç¿»è­¯æˆä¸€ç¨®å®¹æ˜“æ供給
- cpufreqçš„æ ¼å¼ã€‚
+ 這個函數æ供了一個隨時å¯ç”¨çš„轉æ›ä¾‹ç¨‹ï¼Œç”¨ä¾†å°‡OPP層關於å¯ç”¨é »çŽ‡çš„內部信æ¯ç¿»è­¯æˆä¸€ç¨®
+ cpufreq易於處ç†çš„æ ¼å¼ã€‚
.. Warning::
@@ -101,7 +103,7 @@ dev_pm_opp_init_cpufreq_table -
.. note::
- 該函數åªæœ‰åœ¨CONFIG_PM_OPP之外還啓用了CONFIG_CPU_FREQ時æ‰å¯ç”¨ã€‚
+ 該函數åªæœ‰åœ¨CONFIG_PM_OPP之外還啓用了CONFIG_CPU_FREQ時纔å¯ç”¨ã€‚
dev_pm_opp_free_cpufreq_table
釋放dev_pm_opp_init_cpufreq_table分é…的表。
diff --git a/Documentation/translations/zh_TW/cpu-freq/cpu-drivers.rst b/Documentation/translations/zh_TW/cpu-freq/cpu-drivers.rst
index 671b1bf0e2c5..add3de2d4523 100644
--- a/Documentation/translations/zh_TW/cpu-freq/cpu-drivers.rst
+++ b/Documentation/translations/zh_TW/cpu-freq/cpu-drivers.rst
@@ -2,12 +2,15 @@
.. include:: ../disclaimer-zh_TW.rst
-:Original: :doc:`../../../cpu-freq/cpu-drivers`
-:Translator: Yanteng Si <siyanteng@loongson.cn>
- Hu Haowen <src.res.211@gmail.com>
+:Original: Documentation/cpu-freq/cpu-drivers.rst
-.. _tw_cpu-drivers.rst:
+:翻譯:
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+:æ ¡è­¯:
+
+ å”è—舟 Tang Yizhou <tangyeechou@gmail.com>
=======================================
如何實ç¾ä¸€å€‹æ–°çš„CPUFreq處ç†å™¨é©…動程åºï¼Ÿ
@@ -37,15 +40,15 @@
1. 怎麼åšï¼Ÿ
===========
-如此,你剛剛得到了一個全新的CPU/晶片組åŠå…¶æ•¸æ“šæ‰‹å†Šï¼Œä¸¦å¸Œæœ›çˆ²é€™å€‹CPU/晶片組添加cpufreq
-支æŒï¼Ÿå¾ˆå¥½ï¼Œé€™è£¡æœ‰ä¸€äº›è‡³é—œé‡è¦çš„æ示:
+如果,你剛剛得到了一個全新的CPU/芯片組åŠå…¶æ•¸æ“šæ‰‹å†Šï¼Œä¸¦å¸Œæœ›çˆ²é€™å€‹CPU/芯片組添加cpufreq
+支æŒï¼Ÿå¾ˆå¥½ï¼Œé€™è£æœ‰ä¸€äº›è‡³é—œé‡è¦çš„æ示:
1.1 åˆå§‹åŒ–
----------
-首先,在__initcall_level_7 (module_init())或更é å¾Œçš„函數中檢查這個內核是å¦
-é‹è¡Œåœ¨æ­£ç¢ºçš„CPU和正確的晶片組上。如果是,則使用cpufreq_register_driver()å‘
+首先,在 __initcall level 7 (module_init())或更é å¾Œçš„函數中檢查這個內核是å¦
+é‹è¡Œåœ¨æ­£ç¢ºçš„CPU和正確的芯片組上。如果是,則使用cpufreq_register_driver()å‘
CPUfreq核心層註冊一個cpufreq_driverçµæ§‹é«”。
çµæ§‹é«”cpufreq_driver應該包å«ä»€éº¼æˆå“¡?
@@ -59,11 +62,11 @@ CPUfreq核心層註冊一個cpufreq_driverçµæ§‹é«”。
.setpolicy 或 .fast_switch 或 .target 或 .target_index - 差異見
下文。
-並且å¯é¸æ“‡
+其它å¯é¸æˆå“¡
- .flags - cpufreq核的æ示。
+ .flags - 給cpufreq核心的æ示。
- .driver_data - cpufreq驅動程åºçš„特定數據。
+ .driver_data - cpufreq驅動程åºçš„特有數據。
.get_intermediate å’Œ target_intermediate - 用於在改變CPU頻率時切æ›åˆ°ç©©å®š
的頻率。
@@ -72,18 +75,18 @@ CPUfreq核心層註冊一個cpufreq_driverçµæ§‹é«”。
.bios_limit - 返回HW/BIOSå°CPU的最大頻率é™åˆ¶å€¼ã€‚
- .exit - 一個指å‘per-policy清ç†å‡½æ•¸çš„指é‡ï¼Œè©²å‡½æ•¸åœ¨cpu熱æ’æ‹”éŽç¨‹çš„CPU_POST_DEAD
+ .exit - 一個指å‘per-policy清ç†å‡½æ•¸çš„指é‡ï¼Œè©²å‡½æ•¸åœ¨CPU熱æ’æ‹”éŽç¨‹çš„CPU_POST_DEAD
階段被調用。
.suspend - 一個指å‘per-policyæš«åœå‡½æ•¸çš„指é‡ï¼Œè©²å‡½æ•¸åœ¨é—œä¸­æ–·ä¸”在該策略的調節器åœæ­¢
後被調用。
- .resume - 一個指å‘per-policyæ¢å¾©å‡½æ•¸çš„指é‡ï¼Œè©²å‡½æ•¸åœ¨é—œä¸­æ–·ä¸”在調節器å†ä¸€æ¬¡é–‹å§‹å‰è¢«
+ .resume - 一個指å‘per-policyæ¢å¾©å‡½æ•¸çš„指é‡ï¼Œè©²å‡½æ•¸åœ¨é—œä¸­æ–·ä¸”在調節器å†ä¸€æ¬¡å•“å‹•å‰è¢«
調用。
.ready - 一個指å‘per-policy準備函數的指é‡ï¼Œè©²å‡½æ•¸åœ¨ç­–略完全åˆå§‹åŒ–之後被調用。
- .attr - 一個指å‘NULLçµå°¾çš„"struct freq_attr"列表的指é‡ï¼Œè©²å‡½æ•¸å…許導出值到
+ .attr - 一個指å‘NULLçµå°¾çš„"struct freq_attr"列表的指é‡ï¼Œè©²åˆ—表å…許導出值到
sysfs。
.boost_enabled - 如果設置,則啓用æå‡(boost)頻率。
@@ -94,95 +97,93 @@ CPUfreq核心層註冊一個cpufreq_driverçµæ§‹é«”。
1.2 Per-CPU åˆå§‹åŒ–
------------------
-æ¯ç•¶ä¸€å€‹æ–°çš„CPU被註冊到設備模型中,或者在cpufreq驅動註冊自己之後,如果此CPUçš„cpufreqç­–
-ç•¥ä¸å­˜åœ¨ï¼Œå‰‡æœƒèª¿ç”¨per-policyçš„åˆå§‹åŒ–函數cpufreq_driver.init。請注æ„,.init()å’Œ.exit()程åº
-åªå°ç­–略調用一次,而ä¸æ˜¯å°ç­–略管ç†çš„æ¯å€‹CPU調用一次。它需è¦ä¸€å€‹ ``struct cpufreq_policy
+æ¯ç•¶ä¸€å€‹æ–°çš„CPU被註冊到設備模型中,或者當cpufreq驅動註冊自身之後,如果此CPUçš„cpufreqç­–
+ç•¥ä¸å­˜åœ¨ï¼Œå‰‡æœƒèª¿ç”¨per-policyçš„åˆå§‹åŒ–函數cpufreq_driver.init。請注æ„,.init()å’Œ.exit()例程
+åªçˆ²æŸå€‹ç­–略調用一次,而ä¸æ˜¯å°è©²ç­–略管ç†çš„æ¯å€‹CPU調用一次。它需è¦ä¸€å€‹ ``struct cpufreq_policy
*policy`` 作爲åƒæ•¸ã€‚ç¾åœ¨è©²æ€Žéº¼åšå‘¢ï¼Ÿ
如果有必è¦ï¼Œè«‹åœ¨ä½ çš„CPU上激活CPUfreq功能支æŒã€‚
-然後,驅動程åºå¿…須填寫以下數值:
+然後,驅動程åºå¿…須填寫以下值:
+-----------------------------------+--------------------------------------+
-|policy->cpuinfo.min_freq 和 | |
-|policy->cpuinfo.max_freq | 該CPU支æŒçš„最低和最高頻率(kHz) |
-| | |
-| | |
+|policy->cpuinfo.min_freqå’Œ | 該CPU支æŒçš„最低和最高頻率(kHz) |
+|policy->cpuinfo.max_freq | |
+| | |
+-----------------------------------+--------------------------------------+
-|policy->cpuinfo.transition_latency | |
-| | CPU在兩個頻率之間切æ›æ‰€éœ€çš„時間,以 |
-| | ç´ç§’爲單ä½ï¼ˆå¦‚é©ç”¨ï¼Œå¦å‰‡æŒ‡å®š |
-| | CPUFREQ_ETERNAL) |
+|policy->cpuinfo.transition_latency | CPU在兩個頻率之間切æ›æ‰€éœ€çš„時間,以 |
+| | ç´ç§’爲單ä½ï¼ˆå¦‚ä¸é©ç”¨ï¼Œè¨­å®šçˆ² |
+| | CPUFREQ_ETERNAL) |
+| | |
+-----------------------------------+--------------------------------------+
-|policy->cur | 該CPU當å‰çš„工作頻率(如é©ç”¨) |
-| | |
+|policy->cur | 該CPU當å‰çš„工作頻率(如é©ç”¨) |
+| | |
+-----------------------------------+--------------------------------------+
-|policy->min, | |
-|policy->max, | |
-|policy->policy and, if necessary, | |
-|policy->governor | 必須包å«è©²cpuçš„ 「默èªç­–ç•¥ã€ã€‚ç¨å¾Œ |
-| | 會用這些值調用 |
-| | cpufreq_driver.verify and either |
-| | cpufreq_driver.setpolicy or |
-| | cpufreq_driver.target/target_index |
-| | |
+|policy->min, | 必須包å«è©²CPUçš„"默èªç­–ç•¥"。ç¨å¾Œ |
+|policy->max, | 會用這些值調用 |
+|policy->policy and, if necessary, | cpufreq_driver.verify和下é¢å‡½æ•¸ |
+|policy->governor | 之一:cpufreq_driver.setpolicy或 |
+| | cpufreq_driver.target/target_index |
+| | |
+-----------------------------------+--------------------------------------+
-|policy->cpus | 用與這個CPU一起åšDVFSçš„(在線+離線) |
-| | CPU(å³èˆ‡å®ƒå…±äº«æ™‚é˜/電壓軌)的掩碼更新 |
-| | 這個 |
-| | |
+|policy->cpus | 該policy通éŽDVFS框架影響的全部CPU |
+| | (å³èˆ‡æœ¬CPU共享"時é˜/電壓"å°)æ§‹æˆ |
+| | 掩碼(åŒæ™‚包å«åœ¨ç·šå’Œé›¢ç·šCPU),用掩碼 |
+| | 更新本字段 |
+| | |
+-----------------------------------+--------------------------------------+
-å°æ–¼è¨­ç½®å…¶ä¸­çš„一些值(cpuinfo.min[max]_freq, policy->min[max]),頻率表助手å¯èƒ½æœƒæœ‰å¹«
+å°æ–¼è¨­ç½®å…¶ä¸­çš„一些值(cpuinfo.min[max]_freq, policy->min[max]),頻率表輔助函數å¯èƒ½æœƒæœ‰å¹«
助。關於它們的更多信æ¯ï¼Œè«‹åƒè¦‹ç¬¬2節。
1.3 é©—è­‰
--------
-當用戶決定設置一個新的策略(ç”± 「policy,governor,min,max組æˆã€)時,必須å°é€™å€‹ç­–略進行驗證,
+當用戶決定設置一個新的策略(ç”±"policy,governor,min,max組æˆ")時,必須å°é€™å€‹ç­–略進行驗證,
以便糾正ä¸å…¼å®¹çš„值。爲了驗證這些值,cpufreq_verify_within_limits(``struct cpufreq_policy
*policy``, ``unsigned int min_freq``, ``unsigned int max_freq``)函數å¯èƒ½æœƒæœ‰å¹«åŠ©ã€‚
-關於頻率表助手的詳細內容請åƒè¦‹ç¬¬2節。
+關於頻率表輔助函數的詳細內容請åƒè¦‹ç¬¬2節。
您需è¦ç¢ºä¿è‡³å°‘有一個有效頻率(或工作範åœï¼‰åœ¨ policy->min å’Œ policy->max 範åœå…§ã€‚如果有必
-è¦ï¼Œå…ˆå¢žåŠ policy->max,åªæœ‰åœ¨æ²’有辦法的情æ³ä¸‹ï¼Œæ‰æ¸›å°‘policy->min。
+è¦ï¼Œå…ˆå¢žå¤§policy->max,åªæœ‰åœ¨æ²’有解決方案的情æ³ä¸‹ï¼Œæ‰æ¸›å°policy->min。
1.4 target 或 target_index 或 setpolicy 或 fast_switch?
-------------------------------------------------------
-大多數cpufreq驅動甚至大多數cpu頻率å‡é™ç®—法åªå…許將CPU頻率設置爲é å®šç¾©çš„固定值。å°æ–¼é€™äº›ï¼Œä½ 
+大多數cpufreq驅動甚至大多數CPU頻率å‡é™ç®—法åªå…許將CPU頻率設置爲é å®šç¾©çš„固定值。å°æ–¼é€™äº›ï¼Œä½ 
å¯ä»¥ä½¿ç”¨->target(),->target_index()或->fast_switch()回調。
-有些cpufreq功能的處ç†å™¨å¯ä»¥è‡ªå·±åœ¨æŸäº›é™åˆ¶ä¹‹é–“切æ›é »çŽ‡ã€‚這些應使用->setpolicy()回調。
+有些具有硬件調頻能力的處ç†å™¨å¯ä»¥è‡ªè¡Œä¾æ“šæŸäº›é™åˆ¶ä¾†åˆ‡æ›CPU頻率。它們應使用->setpolicy()回調。
1.5. target/target_index
------------------------
-target_index調用有兩個åƒæ•¸ï¼š``struct cpufreq_policy * policy``å’Œ``unsigned int``
-索引(於列出的頻率表)。
+target_index調用有兩個åƒæ•¸ï¼š ``struct cpufreq_policy * policy`` å’Œ ``unsigned int``
+索引(用於索引頻率表項)。
-當調用這裡時,CPUfreq驅動必須設置新的頻率。實際頻率必須由freq_table[index].frequency決定。
+當調用這è£æ™‚,CPUfreq驅動必須設置新的頻率。實際頻率必須由freq_table[index].frequency決定。
-它應該總是在錯誤的情æ³ä¸‹æ¢å¾©åˆ°ä¹‹å‰çš„頻率(å³policy->restore_freq),å³ä½¿æˆ‘們之å‰åˆ‡æ›åˆ°ä¸­é–“頻率。
+在發生錯誤的情æ³ä¸‹ç¸½æ˜¯æ‡‰è©²æ¢å¾©åˆ°ä¹‹å‰çš„頻率(å³policy->restore_freq),å³ä½¿æˆ‘們已經切æ›åˆ°äº†
+中間頻率。
已棄用
----------
-目標調用有三個åƒæ•¸ã€‚``struct cpufreq_policy * policy``, unsigned int target_frequency,
+target調用有三個åƒæ•¸ã€‚``struct cpufreq_policy * policy``, unsigned int target_frequency,
unsigned int relation.
-CPUfreq驅動在調用這裡時必須設置新的頻率。實際的頻率必須使用以下è¦å‰‡ä¾†ç¢ºå®šã€‚
+CPUfreq驅動在調用這è£æ™‚必須設置新的頻率。實際的頻率必須使用以下è¦å‰‡ä¾†ç¢ºå®šã€‚
-- 緊跟 "目標頻率"。
+- 儘é‡è²¼è¿‘"目標頻率"。
- policy->min <= new_freq <= policy->max (這必須是有效的!!!)
- 如果 relation==CPUFREQ_REL_L,嘗試é¸æ“‡ä¸€å€‹é«˜æ–¼æˆ–等於 target_freq çš„ new_freq。("L代表
最低,但ä¸èƒ½ä½Žæ–¼")
- 如果 relation==CPUFREQ_REL_H,嘗試é¸æ“‡ä¸€å€‹ä½Žæ–¼æˆ–等於 target_freq çš„ new_freq。("H代表
最高,但ä¸èƒ½é«˜æ–¼")
-這裡,頻率表助手å¯èƒ½æœƒå¹«åŠ©ä½ --詳見第2節。
+這è£ï¼Œé »çŽ‡è¡¨è¼”助函數å¯èƒ½æœƒå¹«åŠ©ä½  -- 詳見第2節。
1.6. fast_switch
----------------
@@ -196,51 +197,52 @@ CPUfreq驅動在調用這裡時必須設置新的頻率。實際的頻率必須ä
1.7 setpolicy
-------------
-setpolicy調用åªéœ€è¦ä¸€å€‹``struct cpufreq_policy * policy``作爲åƒæ•¸ã€‚需è¦å°‡è™•ç†å™¨å…§æˆ–晶片組內動態頻
+setpolicy調用åªéœ€è¦ä¸€å€‹ ``struct cpufreq_policy * policy`` 作爲åƒæ•¸ã€‚需è¦å°‡è™•ç†å™¨å…§æˆ–芯片組內動態頻
率切æ›çš„下é™è¨­ç½®çˆ²policy->min,上é™è¨­ç½®çˆ²policy->max,如果支æŒçš„話,當policy->policy爲
-CPUFREQ_POLICY_PERFORMANCE時é¸æ“‡é¢å‘性能的設置,當CPUFREQ_POLICY_POWERSAVE時é¸æ“‡é¢å‘çœé›»çš„設置。
+CPUFREQ_POLICY_PERFORMANCE時é¸æ“‡é¢å‘性能的設置,爲CPUFREQ_POLICY_POWERSAVE時é¸æ“‡é¢å‘çœé›»çš„設置。
也å¯ä»¥æŸ¥çœ‹drivers/cpufreq/longrun.c中的åƒè€ƒå¯¦ç¾ã€‚
1.8 get_intermediate 和 target_intermediate
--------------------------------------------
-僅é©ç”¨æ–¼ target_index() å’Œ CPUFREQ_ASYNC_NOTIFICATION 未設置的驅動。
+僅é©ç”¨æ–¼æœªè¨­ç½® target_index() å’Œ CPUFREQ_ASYNC_NOTIFICATION 的驅動。
-get_intermediate應該返回一個平å°æƒ³è¦åˆ‡æ›åˆ°çš„穩定的中間頻率,target_intermediate()應該將CPU設置爲
-該頻率,然後å†è·³è½‰åˆ°'index'å°æ‡‰çš„頻率。核心會負責發é€é€šçŸ¥ï¼Œé©…å‹•ä¸å¿…在target_intermediate()或
-target_index()中處ç†ã€‚
+get_intermediate應該返回一個平臺想è¦åˆ‡æ›åˆ°çš„穩定的中間頻率,target_intermediate()應該將CPU設置爲
+該頻率,然後å†è·³è½‰åˆ°'index'å°æ‡‰çš„頻率。cpufreq核心會負責發é€é€šçŸ¥ï¼Œé©…å‹•ä¸å¿…在
+target_intermediate()或target_index()中處ç†å®ƒå€‘。
-在驅動程åºä¸æƒ³å› çˆ²æŸå€‹ç›®æ¨™é »çŽ‡åˆ‡æ›åˆ°ä¸­é–“頻率的情æ³ä¸‹ï¼Œå®ƒå€‘å¯ä»¥å¾žget_intermediate()中返回'0'。在這種情æ³
-下,核心將直接調用->target_index()。
+在驅動程åºä¸æƒ³çˆ²æŸå€‹ç›®æ¨™é »çŽ‡åˆ‡æ›åˆ°ä¸­é–“頻率的情æ³ä¸‹ï¼Œå®ƒå€‘å¯ä»¥è®“get_intermediate()返回'0'。
+在這種情æ³ä¸‹ï¼Œcpufreq核心將直接調用->target_index()。
-注æ„:->target_index()應該在失敗的情æ³ä¸‹æ¢å¾©åˆ°policy->restore_freq,因爲core會爲此發é€é€šçŸ¥ã€‚
+注æ„:->target_index()應該在發生失敗的情æ³ä¸‹å°‡é »çŽ‡æ¢å¾©åˆ°policy->restore_freq,
+因爲cpufreq核心會爲此發é€é€šçŸ¥ã€‚
-2. 頻率表助手
-=============
+2. 頻率表輔助函數
+=================
-由於大多數cpufreq處ç†å™¨åªå…許被設置爲幾個特定的頻率,因此,一個帶有一些函數的 「頻率表ã€å¯èƒ½æœƒè¼”助處ç†å™¨é©…å‹•
-程åºçš„一些工作。這樣的 "頻率表" 由一個cpufreq_frequency_tableæ¢ç›®æ§‹æˆçš„數組組æˆï¼Œ"driver_data" 中包
-å«äº†é©…動程åºçš„具體數值,"frequency" 中包å«äº†ç›¸æ‡‰çš„頻率,並設置了標誌。在表的最後,需è¦æ·»åŠ ä¸€å€‹
-cpufreq_frequency_tableæ¢ç›®ï¼Œé »çŽ‡è¨­ç½®çˆ²CPUFREQ_TABLE_END。而如果想跳éŽè¡¨ä¸­çš„一個æ¢ç›®ï¼Œå‰‡å°‡é »çŽ‡è¨­ç½®çˆ²
-CPUFREQ_ENTRY_INVALID。這些æ¢ç›®ä¸éœ€è¦æŒ‰ç…§ä»»ä½•ç‰¹å®šçš„é †åºæŽ’åºï¼Œä½†å¦‚果它們是cpufreq 核心會å°å®ƒå€‘進行快速的DVFS,
+由於大多數支æŒcpufreq的處ç†å™¨åªå…許被設置爲幾個特定的頻率,因此,"頻率表"和一些相關函數å¯èƒ½æœƒè¼”助處ç†å™¨é©…å‹•
+程åºçš„一些工作。這樣的"頻率表"是一個由struct cpufreq_frequency_tableçš„æ¢ç›®æ§‹æˆçš„數組,"driver_data"æˆå“¡åŒ…
+å«é©…動程åºçš„專用值,"frequency"æˆå“¡åŒ…å«äº†ç›¸æ‡‰çš„頻率,此外還有標誌æˆå“¡ã€‚在表的最後,需è¦æ·»åŠ ä¸€å€‹
+cpufreq_frequency_tableæ¢ç›®ï¼Œé »çŽ‡è¨­ç½®çˆ²CPUFREQ_TABLE_END。如果想跳éŽè¡¨ä¸­çš„一個æ¢ç›®ï¼Œå‰‡å°‡é »çŽ‡è¨­ç½®çˆ²
+CPUFREQ_ENTRY_INVALID。這些æ¢ç›®ä¸éœ€è¦æŒ‰ç…§ä»»ä½•ç‰¹å®šçš„é †åºæŽ’åºï¼Œå¦‚果排åºäº†ï¼Œcpufreq核心執行DVFS會更快一點,
因爲æœç´¢æœ€ä½³åŒ¹é…會更快。
-如果策略在其policy->freq_table欄ä½ä¸­åŒ…å«ä¸€å€‹æœ‰æ•ˆçš„指é‡ï¼Œcpufreq表就會被核心自動驗證。
+如果在policy->freq_table字段中包å«ä¸€å€‹æœ‰æ•ˆçš„頻率表指é‡ï¼Œé »çŽ‡è¡¨å°±æœƒè¢«cpufreq核心自動驗證。
cpufreq_frequency_table_verify()ä¿è­‰è‡³å°‘有一個有效的頻率在policy->minå’Œpolicy->max範åœå…§ï¼Œä¸¦ä¸”所有其他
-標準都被滿足。這å°->verify調用很有幫助。
+準則都被滿足。這å°->verify調用很有幫助。
-cpufreq_frequency_table_target()是å°æ‡‰æ–¼->target階段的頻率表助手。åªè¦æŠŠæ•¸å€¼å‚³éžçµ¦é€™å€‹å‡½æ•¸ï¼Œé€™å€‹å‡½æ•¸å°±æœƒè¿”
+cpufreq_frequency_table_target()是å°æ‡‰æ–¼->target階段的頻率表輔助函數。åªè¦æŠŠå€¼å‚³éžçµ¦é€™å€‹å‡½æ•¸ï¼Œé€™å€‹å‡½æ•¸å°±æœƒè¿”
回包å«CPUè¦è¨­ç½®çš„頻率的頻率表æ¢ç›®ã€‚
-以下å®å¯ä»¥ä½œçˆ²cpufreq_frequency_table的疊代器。
+以下å®å¯ä»¥ä½œçˆ²cpufreq_frequency_table的迭代器。
cpufreq_for_each_entry(pos, table) - é歷頻率表的所有æ¢ç›®ã€‚
cpufreq_for_each_valid_entry(pos, table) - 該函數é歷所有æ¢ç›®ï¼Œä¸åŒ…括CPUFREQ_ENTRY_INVALID頻率。
-使用åƒæ•¸ "pos"-一個``cpufreq_frequency_table * `` 作爲循環變é‡ï¼Œä½¿ç”¨åƒæ•¸ "table"-作爲你想疊代
-的``cpufreq_frequency_table * `` 。
+使用åƒæ•¸"pos" -- 一個 ``cpufreq_frequency_table *`` 作爲循環指é‡ï¼Œä½¿ç”¨åƒæ•¸"table" -- 作爲你想迭代
+的 ``cpufreq_frequency_table *`` 。
例如::
@@ -251,6 +253,6 @@ cpufreq_for_each_valid_entry(pos, table) - 該函數é歷所有æ¢ç›®ï¼Œä¸åŒ…æ
pos->frequency = ...
}
-如果你需è¦åœ¨driver_freq_table中處ç†posçš„ä½ç½®ï¼Œä¸è¦æ¸›åŽ»æŒ‡é‡ï¼Œå› çˆ²å®ƒçš„代價相當高。相å,使用å®
+如果你需è¦åœ¨driver_freq_table中處ç†posçš„ä½ç½®ï¼Œä¸è¦åšæŒ‡é‡æ¸›æ³•ï¼Œå› çˆ²å®ƒçš„代價相當高。作爲替代,使用å®
cpufreq_for_each_entry_idx() 和 cpufreq_for_each_valid_entry_idx() 。
diff --git a/Documentation/translations/zh_TW/cpu-freq/cpufreq-stats.rst b/Documentation/translations/zh_TW/cpu-freq/cpufreq-stats.rst
index 49088becd5fa..01ec8c837fe9 100644
--- a/Documentation/translations/zh_TW/cpu-freq/cpufreq-stats.rst
+++ b/Documentation/translations/zh_TW/cpu-freq/cpufreq-stats.rst
@@ -2,18 +2,21 @@
.. include:: ../disclaimer-zh_TW.rst
-:Original: :doc:`../../../cpu-freq/cpufreq-stats`
-:Translator: Yanteng Si <siyanteng@loongson.cn>
- Hu Haowen <src.res.211@gmail.com>
+:Original: Documentation/cpu-freq/cpufreq-stats.rst
-.. _tw_cpufreq-stats.rst:
+:翻譯:
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+
+:æ ¡è­¯:
+
+ å”è—舟 Tang Yizhou <tangyeechou@gmail.com>
==========================================
sysfs CPUFreq Stats的一般說明
==========================================
-用戶信æ¯
+爲使用者準備的信æ¯
作者: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
@@ -28,17 +31,16 @@ sysfs CPUFreq Stats的一般說明
1. 簡介
===============
-cpufreq-stats是一個爲æ¯å€‹CPUæä¾›CPU頻率統計的驅動。
-這些統計數據在/sysfs中以一堆åªè®€æŽ¥å£çš„å½¢å¼æ供。這個接å£ï¼ˆåœ¨é…置好後)將出ç¾åœ¨
-/sysfs(<sysfs root>/devices/system/cpu/cpuX/cpufreq/stats/)中cpufreq下的一個單
-ç¨çš„目錄中,æ供給æ¯å€‹CPU。
-å„種統計數據將在此目錄下形æˆåªè®€æ–‡ä»¶ã€‚
+cpufreq-stats是一種爲æ¯å€‹CPUæä¾›CPU頻率統計的驅動。
+這些統計數據以/sysfs中一系列åªè®€æŽ¥å£çš„å½¢å¼å‘ˆç¾ã€‚cpufreq-stats接å£ï¼ˆè‹¥å·²é…置)將爲æ¯å€‹CPU生æˆ
+/sysfs(<sysfs root>/devices/system/cpu/cpuX/cpufreq/stats/)中cpufreq目錄下的stats目錄。
+å„項統計數據將在stats目錄下形æˆå°æ‡‰çš„åªè®€æ–‡ä»¶ã€‚
-此驅動是ç¨ç«‹æ–¼ä»»ä½•å¯èƒ½é‹è¡Œåœ¨ä½ æ‰€ç”¨CPU上的特定cpufreq_driver而設計的。因此,它將與所有
-cpufreq_driver一起工作。
+此驅動是以ç¨ç«‹æ–¼ä»»ä½•å¯èƒ½é‹è¡Œåœ¨ä½ æ‰€ç”¨CPU上的特定cpufreq_driverçš„æ–¹å¼è¨­è¨ˆçš„。因此,它將能和任何
+cpufreq_driverå”åŒå·¥ä½œã€‚
-2. æ供的統計數據(舉例說明)
+2. å·²æ供的統計數據(有例å­)
=====================================
cpufreq statsæ供了以下統計數據(在下é¢è©³ç´°è§£é‡‹ï¼‰ã€‚
@@ -47,8 +49,8 @@ cpufreq statsæ供了以下統計數據(在下é¢è©³ç´°è§£é‡‹ï¼‰ã€‚
- total_trans
- trans_table
-所有的統計數據將從統計驅動被載入的時間(或統計被é‡ç½®çš„時間)開始,到æŸä¸€çµ±è¨ˆæ•¸æ“šè¢«è®€å–的時間爲止。
-顯然,統計驅動ä¸æœƒæœ‰ä»»ä½•é—œæ–¼çµ±è¨ˆé©…動載入之å‰çš„頻率轉æ›ä¿¡æ¯ã€‚
+所有統計數據來自以下時間範åœï¼šå¾žçµ±è¨ˆé©…動被加載的時間(或統計數據被é‡ç½®çš„時間)開始,到æŸä¸€çµ±è¨ˆæ•¸æ“šè¢«è®€å–的時間爲止。
+顯然,統計驅動ä¸æœƒä¿å­˜å®ƒè¢«åŠ è¼‰ä¹‹å‰çš„任何頻率轉æ›ä¿¡æ¯ã€‚
::
@@ -63,14 +65,14 @@ cpufreq statsæ供了以下統計數據(在下é¢è©³ç´°è§£é‡‹ï¼‰ã€‚
- **reset**
-åªå¯«å±¬æ€§ï¼Œå¯ç”¨æ–¼é‡ç½®çµ±è¨ˆè¨ˆæ•¸å™¨ã€‚這å°æ–¼è©•ä¼°ä¸åŒèª¿ç¯€å™¨ä¸‹çš„系統行爲éžå¸¸æœ‰ç”¨ï¼Œä¸”無需é‡å•“。
+åªå¯«å±¬æ€§ï¼Œå¯ç”¨æ–¼é‡ç½®çµ±è¨ˆè¨ˆæ•¸å™¨ã€‚這å°æ–¼è©•ä¼°ä¸åŒèª¿ç¯€å™¨çš„系統行爲éžå¸¸æœ‰ç”¨ï¼Œä¸”無需é‡å•“。
- **time_in_state**
-此項給出了這個CPU所支æŒçš„æ¯å€‹é »çŽ‡æ‰€èŠ±è²»çš„時間。cat輸出的æ¯ä¸€è¡Œéƒ½æœƒæœ‰"<frequency>
-<time>"å°ï¼Œè¡¨ç¤ºé€™å€‹CPU在<frequency>上花費了<time>個usertimeå–®ä½çš„時間。這裡的
-usertimeå–®ä½æ˜¯10mS(類似於/proc中輸出的其他時間)。
+此文件給出了在本CPU支æŒçš„æ¯å€‹é »çŽ‡ä¸Šåˆ†åˆ¥èŠ±è²»çš„時間。cat輸出的æ¯ä¸€è¡Œéƒ½æ˜¯ä¸€å€‹"<frequency>
+<time>"å°ï¼Œè¡¨ç¤ºé€™å€‹CPU在<frequency>上花費了<time>個usertimeå–®ä½çš„時間。輸出的æ¯ä¸€è¡Œå°æ‡‰
+一個CPU支æŒçš„頻率。這è£usertimeå–®ä½æ˜¯10mS(類似於/proc導出的其它時間)。
::
@@ -84,7 +86,7 @@ usertimeå–®ä½æ˜¯10mS(類似於/proc中輸出的其他時間)。
- **total_trans**
-給出了這個CPU上頻率轉æ›çš„總次數。cat的輸出將有一個單一的計數,這就是頻率轉æ›çš„總數。
+此文件給出了這個CPU頻率轉æ›çš„總次數。cat的輸出是一個計數值,它就是頻率轉æ›çš„總次數。
::
@@ -93,10 +95,10 @@ usertimeå–®ä½æ˜¯10mS(類似於/proc中輸出的其他時間)。
- **trans_table**
-這將æ供所有CPU頻率轉æ›çš„細粒度信æ¯ã€‚這裡的cat輸出是一個二維矩陣,其中一個æ¢ç›®<i, j>(第
+本文件æ供所有CPU頻率轉æ›çš„細粒度信æ¯ã€‚這è£çš„cat輸出是一個二維矩陣,其中一個æ¢ç›®<i, j>(第
i行,第j列)代表從Freq_i到Freq_j的轉æ›æ¬¡æ•¸ã€‚Freq_i行和Freq_j列éµå¾ªé©…動最åˆæ供給cpufreq
-核的頻率表的排åºé †åºï¼Œå› æ­¤å¯ä»¥æŽ’åºï¼ˆå‡åºæˆ–é™åºï¼‰æˆ–ä¸æŽ’åºã€‚ 這裡的輸出也包å«äº†æ¯è¡Œæ¯åˆ—的實際
-頻率值,以便更好地閱讀。
+核心的頻率表的排列順åºï¼Œå› æ­¤å¯ä»¥å·²æŽ’åºï¼ˆå‡åºæˆ–é™åºï¼‰æˆ–未排åºã€‚這è£çš„輸出也包å«äº†å¯¦éš›
+頻率值,分別按行和按列顯示,以便更好地閱讀。
如果轉æ›è¡¨å¤§æ–¼PAGE_SIZE,讀å–時將返回一個-EFBIG錯誤。
@@ -114,7 +116,7 @@ i行,第j列)代表從Freq_i到Freq_j的轉æ›æ¬¡æ•¸ã€‚Freq_i行和Freq_j列
3. é…ç½®cpufreq-stats
============================
-è¦åœ¨ä½ çš„內核中é…ç½®cpufreq-stats::
+按以下方å¼åœ¨ä½ çš„內核中é…ç½®cpufreq-stats::
Config Main Menu
Power management options (ACPI, APM) --->
@@ -123,7 +125,7 @@ i行,第j列)代表從Freq_i到Freq_j的轉æ›æ¬¡æ•¸ã€‚Freq_i行和Freq_j列
[*] CPU frequency translation statistics
-"CPU Frequency scaling" (CONFIG_CPU_FREQ) 應該被啓用以é…ç½®cpufreq-stats。
+"CPU Frequency scaling" (CONFIG_CPU_FREQ) 應該被啓用,以支æŒé…ç½®cpufreq-stats。
"CPU frequency translation statistics" (CONFIG_CPU_FREQ_STAT)æ供了包括
time_in_stateã€total_transå’Œtrans_table的統計數據。
diff --git a/Documentation/translations/zh_TW/cpu-freq/index.rst b/Documentation/translations/zh_TW/cpu-freq/index.rst
index c6cf825b57a5..a9df16870b21 100644
--- a/Documentation/translations/zh_TW/cpu-freq/index.rst
+++ b/Documentation/translations/zh_TW/cpu-freq/index.rst
@@ -2,12 +2,13 @@
.. include:: ../disclaimer-zh_TW.rst
-:Original: :doc:`../../../cpu-freq/index`
-:Translator: Yanteng Si <siyanteng@loongson.cn>
- Hu Haowen <src.res.211@gmail.com>
+:Original: Documentation/cpu-freq/index.rst
-.. _tw_index.rst:
+:翻譯:
+
+ å¸å»¶é¨° Yanteng Si <siyanteng@loongson.cn>
+.. _tw_index.rst:
=======================================================
Linux CPUFreq - Linux(TM)內核中的CPU頻率和電壓å‡é™ä»£ç¢¼
@@ -28,10 +29,10 @@ Author: Dominik Brodowski <linux@brodo.de>
郵件列表
------------
-這裡有一個 CPU 頻率變化的 CVS æ交和通用列表,您å¯ä»¥åœ¨é€™è£¡å ±å‘Šbugã€å•é¡Œæˆ–æ交補ä¸ã€‚è¦ç™¼
+這è£æœ‰ä¸€å€‹ CPU 頻率變化的 CVS æ交和通用列表,您å¯ä»¥åœ¨é€™è£å ±å‘Šbugã€å•é¡Œæˆ–æ交補ä¸ã€‚è¦ç™¼
布消æ¯ï¼Œè«‹ç™¼é€é›»å­éƒµä»¶åˆ° linux-pm@vger.kernel.org。
-連çµ
+éˆæŽ¥
-----
FTP檔案:
* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
diff --git a/Documentation/translations/zh_TW/dev-tools/gcov.rst b/Documentation/translations/zh_TW/dev-tools/gcov.rst
new file mode 100644
index 000000000000..ce1c9a97de16
--- /dev/null
+++ b/Documentation/translations/zh_TW/dev-tools/gcov.rst
@@ -0,0 +1,265 @@
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/dev-tools/gcov.rst
+:Translator: 趙è»å¥Ž Bernard Zhao <bernard@vivo.com>
+
+在Linux內核è£ä½¿ç”¨gcovåšä»£ç¢¼è¦†è“‹çŽ‡æª¢æŸ¥
+=====================================
+
+gcov分æžæ ¸å¿ƒæ”¯æŒåœ¨Linux內核中啓用GCC的覆蓋率測試工具 gcov_ ,Linux內核
+é‹è¡Œæ™‚的代碼覆蓋率數據會以gcov兼容的格å¼å°Žå‡ºåˆ°â€œgcovâ€debugfs目錄中,å¯
+以通éŽgcovçš„ ``-o`` é¸é …(如下示例)ç²å¾—指定文件的代碼é‹è¡Œè¦†è“‹çŽ‡çµ±è¨ˆæ•¸æ“š
+(需è¦è·³è½‰åˆ°å…§æ ¸ç·¨è­¯è·¯å¾‘下並且è¦æœ‰root權é™ï¼‰::
+
+ # cd /tmp/linux-out
+ # gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c
+
+這將在當å‰ç›®éŒ„中創建帶有執行計數註釋的æºä»£ç¢¼æ–‡ä»¶ã€‚
+在ç²å¾—這些統計文件後,å¯ä»¥ä½¿ç”¨åœ–形化的gcovå‰ç«¯å·¥å…·ï¼ˆæ¯”如 lcov_ ),來實ç¾
+自動化處ç†Linux內核的覆蓋率é‹è¡Œæ•¸æ“šï¼ŒåŒæ™‚生æˆæ˜“於閱讀的HTMLæ ¼å¼æ–‡ä»¶ã€‚
+
+å¯èƒ½çš„用途:
+
+* 調試(用來判斷æ¯ä¸€è¡Œçš„代碼是å¦å·²ç¶“é‹è¡ŒéŽï¼‰
+* 測試改進(如何修改測試代碼,儘å¯èƒ½åœ°è¦†è“‹åˆ°æ²’有é‹è¡ŒéŽçš„代碼)
+* 內核最å°åŒ–é…置(å°æ–¼æŸä¸€å€‹é¸é …é…置,如果關è¯çš„代碼從來沒有é‹è¡ŒéŽï¼Œ
+ 是å¦é‚„需è¦é€™å€‹é…置)
+
+.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html
+.. _lcov: http://ltp.sourceforge.net/coverage/lcov.php
+
+
+準備
+----
+
+內核打開如下é…ç½®::
+
+ CONFIG_DEBUG_FS=y
+ CONFIG_GCOV_KERNEL=y
+
+ç²å–整個內核的覆蓋率數據,還需è¦æ‰“é–‹::
+
+ CONFIG_GCOV_PROFILE_ALL=y
+
+需è¦æ³¨æ„的是,整個內核開啓覆蓋率統計會造æˆå…§æ ¸é¡åƒæ–‡ä»¶å°ºå¯¸çš„增大,
+åŒæ™‚內核é‹è¡Œä¹Ÿæœƒè®Šæ…¢ä¸€äº›ã€‚
+å¦å¤–,並ä¸æ˜¯æ‰€æœ‰çš„架構都支æŒæ•´å€‹å…§æ ¸é–‹å•“覆蓋率統計。
+
+代碼é‹è¡Œè¦†è“‹çŽ‡æ•¸æ“šåªåœ¨debugfs掛載完æˆå¾Œçº”å¯ä»¥è¨ªå•::
+
+ mount -t debugfs none /sys/kernel/debug
+
+
+定製化
+------
+
+如果è¦å–®ç¨é‡å°æŸä¸€å€‹è·¯å¾‘或者文件進行代碼覆蓋率統計,å¯ä»¥åœ¨å…§æ ¸ç›¸æ‡‰è·¯
+徑的Makefile中增加如下的é…ç½®:
+
+- å–®ç¨çµ±è¨ˆå–®å€‹æ–‡ä»¶ï¼ˆä¾‹å¦‚main.o)::
+
+ GCOV_PROFILE_main.o := y
+
+- å–®ç¨çµ±è¨ˆæŸä¸€å€‹è·¯å¾‘::
+
+ GCOV_PROFILE := y
+
+如果è¦åœ¨æ•´å€‹å…§æ ¸çš„覆蓋率統計(開啓CONFIG_GCOV_PROFILE_ALL)中單ç¨æŽ’除
+æŸä¸€å€‹æ–‡ä»¶æˆ–者路徑,å¯ä»¥ä½¿ç”¨å¦‚下的方法::
+
+ GCOV_PROFILE_main.o := n
+
+和::
+
+ GCOV_PROFILE := n
+
+此機制僅支æŒéˆæŽ¥åˆ°å…§æ ¸é¡åƒæˆ–編譯爲內核模塊的文件。
+
+
+相關文件
+--------
+
+gcov功能需è¦åœ¨debugfs中創建如下文件:
+
+``/sys/kernel/debug/gcov``
+ gcov相關功能的根路徑
+
+``/sys/kernel/debug/gcov/reset``
+ 全局復ä½æ–‡ä»¶:å‘該文件寫入數據後會將所有的gcov統計數據清0
+
+``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda``
+ gcov工具å¯ä»¥è­˜åˆ¥çš„覆蓋率統計數據文件,å‘該文件寫入數據後
+ 會將本文件的gcov統計數據清0
+
+``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno``
+ gcov工具需è¦çš„軟連接文件(指å‘編譯時生æˆçš„ä¿¡æ¯çµ±è¨ˆæ–‡ä»¶ï¼‰ï¼Œé€™å€‹æ–‡ä»¶æ˜¯
+ 在gcc編譯時如果é…置了é¸é … ``-ftest-coverage`` 時生æˆçš„。
+
+
+é‡å°æ¨¡å¡Šçš„統計
+--------------
+
+內核中的模塊會動態的加載和å¸è¼‰ï¼Œæ¨¡å¡Šå¸è¼‰æ™‚å°æ‡‰çš„數據會被清除掉。
+gcovæ供了一種機制,通éŽä¿ç•™ç›¸é—œæ•¸æ“šçš„副本來收集這部分å¸è¼‰æ¨¡å¡Šçš„覆蓋率數據。
+模塊å¸è¼‰å¾Œé€™äº›å‚™ä»½æ•¸æ“šåœ¨debugfs中會繼續存在。
+一旦這個模塊é‡æ–°åŠ è¼‰ï¼Œæ¨¡å¡Šé—œè¯çš„é‹è¡Œçµ±è¨ˆæœƒè¢«åˆå§‹åŒ–æˆdebugfs中備份的數據。
+
+å¯ä»¥é€šéŽå°å…§æ ¸åƒæ•¸gcov_persist的修改來åœç”¨gcovå°æ¨¡å¡Šçš„備份機制::
+
+ gcov_persist = 0
+
+在é‹è¡Œæ™‚,用戶還å¯ä»¥é€šéŽå¯«å…¥æ¨¡å¡Šçš„數據文件或者寫入gcov復ä½æ–‡ä»¶ä¾†ä¸Ÿæ£„å·²å¸
+載模塊的數據。
+
+
+編譯機和測試機分離
+------------------
+
+gcov的內核分æžæ’æ¨æ”¯æŒå…§æ ¸çš„編譯和é‹è¡Œæ˜¯åœ¨åŒä¸€è‡ºæ©Ÿå™¨ä¸Šï¼Œä¹Ÿå¯ä»¥ç·¨è­¯å’Œé‹
+行是在ä¸åŒçš„機器上。
+如果內核編譯和é‹è¡Œæ˜¯ä¸åŒçš„機器,那麼需è¦é¡å¤–的準備工作,這å–決於gcov工具
+是在哪è£ä½¿ç”¨çš„:
+
+.. _gcov-test_zh:
+
+a) è‹¥gcové‹è¡Œåœ¨æ¸¬è©¦æ©Ÿä¸Š
+
+ 測試機上é¢gcov工具的版本必須è¦è·Ÿå…§æ ¸ç·¨è­¯æ©Ÿå™¨ä½¿ç”¨çš„gcc版本相兼容,
+ åŒæ™‚下é¢çš„文件è¦å¾žç·¨è­¯æ©Ÿæ‹·è²åˆ°æ¸¬è©¦æ©Ÿä¸Š:
+
+ 從æºä»£ç¢¼ä¸­:
+ - 所有的C文件和頭文件
+
+ 從編譯目錄中:
+ - 所有的C文件和頭文件
+ - 所有的.gcda文件和.gcno文件
+ - 所有目錄的éˆæŽ¥
+
+ 特別需è¦æ³¨æ„,測試機器上é¢çš„目錄çµæ§‹è·Ÿç·¨è­¯æ©Ÿå™¨ä¸Šé¢çš„目錄機構必須
+ 完全一致。
+ 如果文件是軟éˆæŽ¥ï¼Œéœ€è¦æ›¿æ›æˆçœŸæ­£çš„目錄文件(這是由make的當å‰å·¥ä½œ
+ 目錄變é‡CURDIR引起的)。
+
+.. _gcov-build_zh:
+
+b) è‹¥gcové‹è¡Œåœ¨ç·¨è­¯æ©Ÿä¸Š
+
+ 測試用例é‹è¡ŒçµæŸå¾Œï¼Œå¦‚下的文件需è¦å¾žæ¸¬è©¦æ©Ÿä¸­æ‹·è²åˆ°ç·¨è­¯æ©Ÿä¸Š:
+
+ 從sysfs中的gcov目錄中:
+ - 所有的.gcda文件
+ - 所有的.gcno文件軟éˆæŽ¥
+
+ 這些文件å¯ä»¥æ‹·è²åˆ°ç·¨è­¯æ©Ÿçš„ä»»æ„目錄下,gcov使用-oé¸é …指定拷è²çš„
+ 目錄。
+
+ 比如一個是示例的目錄çµæ§‹å¦‚下::
+
+ /tmp/linux: 內核æºç¢¼ç›®éŒ„
+ /tmp/out: 內核編譯文件路徑(make O=指定)
+ /tmp/coverage: 從測試機器上é¢æ‹·è²çš„數據文件路徑
+
+ [user@build] cd /tmp/out
+ [user@build] gcov -o /tmp/coverage/tmp/out/init main.c
+
+
+關於編譯器的注æ„事項
+--------------------
+
+GCCå’ŒLLVM gcov工具ä¸ä¸€å®šå…¼å®¹ã€‚
+如果編譯器是GCC,使用 gcov_ 來處ç†.gcnoå’Œ.gcda文件,如果是Clang編譯器,
+則使用 llvm-cov_ 。
+
+.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html
+.. _llvm-cov: https://llvm.org/docs/CommandGuide/llvm-cov.html
+
+GCCå’ŒClang gcov之間的版本差異由Kconfig處ç†çš„。
+kconfig會根據編譯工具éˆçš„檢查自動é¸æ“‡åˆé©çš„gcovæ ¼å¼ã€‚
+
+å•é¡Œå®šä½
+--------
+
+å¯èƒ½å‡ºç¾çš„å•é¡Œ1
+ 編譯到éˆæŽ¥éšŽæ®µå ±éŒ¯çµ‚æ­¢
+
+å•é¡ŒåŽŸå› 
+ 分æžæ¨™èªŒæŒ‡å®šåœ¨äº†æºæ–‡ä»¶ä½†æ˜¯æ²’有éˆæŽ¥åˆ°ä¸»å…§æ ¸ï¼Œæˆ–者客製化了éˆæŽ¥ç¨‹åº
+
+解決方法
+ 通éŽåœ¨ç›¸æ‡‰çš„Makefile中使用 ``GCOV_PROFILE := n``
+ 或者 ``GCOV_PROFILE_basename.o := n`` 來將éˆæŽ¥å ±éŒ¯çš„文件排除掉
+
+å¯èƒ½å‡ºç¾çš„å•é¡Œ2
+ 從sysfs複製的文件顯示爲空或ä¸å®Œæ•´
+
+å•é¡ŒåŽŸå› 
+ 由於seq_file的工作方å¼ï¼ŒæŸäº›å·¥å…·ï¼ˆä¾‹å¦‚cp或tar)å¯èƒ½ç„¡æ³•æ­£ç¢ºåœ°å¾ž
+ sysfs複製文件。
+
+解決方法
+ 使用 ``cat`` è®€å– ``.gcda`` 文件,使用 ``cp -d`` 複製éˆæŽ¥ï¼Œæˆ–者使用附錄B
+ 中所示的機制。
+
+
+附錄A:collect_on_build.sh
+--------------------------
+
+用於在編譯機上收集覆蓋率元文件的示例腳本
+(見 :ref:`編譯機和測試機分離 a. <gcov-test_zh>` )
+
+.. code-block:: sh
+
+ #!/bin/bash
+
+ KSRC=$1
+ KOBJ=$2
+ DEST=$3
+
+ if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then
+ echo "Usage: $0 <ksrc directory> <kobj directory> <output.tar.gz>" >&2
+ exit 1
+ fi
+
+ KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
+ KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
+
+ find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \
+ -perm /u+r,g+r | tar cfz $DEST -P -T -
+
+ if [ $? -eq 0 ] ; then
+ echo "$DEST successfully created, copy to test system and unpack with:"
+ echo " tar xfz $DEST -P"
+ else
+ echo "Could not create file $DEST"
+ fi
+
+
+附錄B:collect_on_test.sh
+-------------------------
+
+用於在測試機上收集覆蓋率數據文件的示例腳本
+(見 :ref:`編譯機和測試機分離 b. <gcov-build_zh>` )
+
+.. code-block:: sh
+
+ #!/bin/bash -e
+
+ DEST=$1
+ GCDA=/sys/kernel/debug/gcov
+
+ if [ -z "$DEST" ] ; then
+ echo "Usage: $0 <output.tar.gz>" >&2
+ exit 1
+ fi
+
+ TEMPDIR=$(mktemp -d)
+ echo Collecting data..
+ find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
+ find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
+ find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
+ tar czf $DEST -C $TEMPDIR sys
+ rm -rf $TEMPDIR
+
+ echo "$DEST successfully created, copy to build system and unpack with:"
+ echo " tar xfz $DEST"
+
diff --git a/Documentation/translations/zh_TW/dev-tools/gdb-kernel-debugging.rst b/Documentation/translations/zh_TW/dev-tools/gdb-kernel-debugging.rst
new file mode 100644
index 000000000000..c881e8872b19
--- /dev/null
+++ b/Documentation/translations/zh_TW/dev-tools/gdb-kernel-debugging.rst
@@ -0,0 +1,168 @@
+.. highlight:: none
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/dev-tools/gdb-kernel-debugging.rst
+:Translator: 高超 gao chao <gaochao49@huawei.com>
+
+通éŽgdb調試內核和模塊
+=====================
+
+Kgdb內核調試器ã€QEMU等虛擬機管ç†ç¨‹åºæˆ–基於JTAG的硬件接å£ï¼Œæ”¯æŒåœ¨é‹è¡Œæ™‚使用gdb
+調試Linux內核åŠå…¶æ¨¡å¡Šã€‚Gdbæ供了一個強大的python腳本接å£ï¼Œå…§æ ¸ä¹Ÿæ供了一套
+輔助腳本以簡化典型的內核調試步驟。本文檔爲如何啓用和使用這些腳本æ供了一個簡è¦çš„教程。
+此教程基於QEMU/KVM虛擬機,但文中示例也é©ç”¨æ–¼å…¶ä»–gdb stub。
+
+
+環境é…ç½®è¦æ±‚
+------------
+
+- gdb 7.2+ (推薦版本: 7.4+) 且開啓pythonæ”¯æŒ (通常發行版上都已支æŒ)
+
+設置
+----
+
+- 創建一個QEMU/KVMçš„linux虛擬機(詳情請åƒè€ƒ www.linux-kvm.org å’Œ www.qemu.org )。
+ å°æ–¼äº¤å‰é–‹ç™¼ï¼Œhttps://landley.net/aboriginal/bin æ供了一些é¡åƒå’Œå·¥å…·éˆï¼Œ
+ å¯ä»¥å¹«åŠ©æ­å»ºäº¤å‰é–‹ç™¼ç’°å¢ƒã€‚
+
+- 編譯內核時開啓CONFIG_GDB_SCRIPTS,關閉CONFIG_DEBUG_INFO_REDUCED。
+ 如果架構支æŒCONFIG_FRAME_POINTER,請ä¿æŒé–‹å•“。
+
+- 在guest環境上安è£è©²å…§æ ¸ã€‚如有必è¦ï¼Œé€šéŽåœ¨å…§æ ¸command line中添加“nokaslrâ€ä¾†é—œé–‰KASLR。
+ 此外,QEMUå…許通éŽ-kernelã€-appendã€-initrd這些命令行é¸é …直接啓動內核。
+ 但這通常僅在ä¸ä¾è³´å…§æ ¸æ¨¡å¡Šæ™‚纔有效。有關此模å¼çš„更多詳細信æ¯ï¼Œè«‹åƒé–±QEMU文檔。
+ 在這種情æ³ä¸‹ï¼Œå¦‚果架構支æŒKASLR,應該在ç¦ç”¨CONFIG_RANDOMIZE_BASE的情æ³ä¸‹æ§‹å»ºå…§æ ¸ã€‚
+
+- 啓用QEMU/KVMçš„gdb stub,å¯ä»¥é€šéŽå¦‚下方å¼å¯¦ç¾
+
+ - 在VM啓動時,通éŽåœ¨QEMU命令行中添加“-sâ€åƒæ•¸
+
+ 或
+
+ - 在é‹è¡Œæ™‚通éŽå¾žQEMU監視控制檯發é€â€œgdbserverâ€
+
+- 切æ›åˆ°/path/to/linux-build(內核æºç¢¼ç·¨è­¯)目錄
+
+- 啓動gdb:gdb vmlinux
+
+ 注æ„:æŸäº›ç™¼è¡Œç‰ˆå¯èƒ½æœƒå°‡gdb腳本的自動加載é™åˆ¶åœ¨å·²çŸ¥çš„安全目錄中。
+ 如果gdb報告拒絕加載vmlinux-gdb.py(相關命令找ä¸åˆ°ï¼‰ï¼Œè«‹å°‡::
+
+ add-auto-load-safe-path /path/to/linux-build
+
+ 添加到~/.gdbinit。更多詳細信æ¯ï¼Œè«‹åƒé–±gdb幫助信æ¯ã€‚
+
+- 連接到已啓動的guest環境::
+
+ (gdb) target remote :1234
+
+
+使用Linuxæ供的gdb腳本的示例
+----------------------------
+
+- 加載模塊(以åŠä¸»å…§æ ¸ï¼‰ç¬¦è™Ÿ::
+
+ (gdb) lx-symbols
+ loading vmlinux
+ scanning for modules in /home/user/linux/build
+ loading @0xffffffffa0020000: /home/user/linux/build/net/netfilter/xt_tcpudp.ko
+ loading @0xffffffffa0016000: /home/user/linux/build/net/netfilter/xt_pkttype.ko
+ loading @0xffffffffa0002000: /home/user/linux/build/net/netfilter/xt_limit.ko
+ loading @0xffffffffa00ca000: /home/user/linux/build/net/packet/af_packet.ko
+ loading @0xffffffffa003c000: /home/user/linux/build/fs/fuse/fuse.ko
+ ...
+ loading @0xffffffffa0000000: /home/user/linux/build/drivers/ata/ata_generic.ko
+
+- å°ä¸€äº›å°šæœªåŠ è¼‰çš„模塊中的函數函數設置斷點,例如::
+
+ (gdb) b btrfs_init_sysfs
+ Function "btrfs_init_sysfs" not defined.
+ Make breakpoint pending on future shared library load? (y or [n]) y
+ Breakpoint 1 (btrfs_init_sysfs) pending.
+
+- 繼續執行::
+
+ (gdb) c
+
+- 加載模塊並且能觀察到正在加載的符號以åŠæ–·é»žå‘½ä¸­::
+
+ loading @0xffffffffa0034000: /home/user/linux/build/lib/libcrc32c.ko
+ loading @0xffffffffa0050000: /home/user/linux/build/lib/lzo/lzo_compress.ko
+ loading @0xffffffffa006e000: /home/user/linux/build/lib/zlib_deflate/zlib_deflate.ko
+ loading @0xffffffffa01b1000: /home/user/linux/build/fs/btrfs/btrfs.ko
+
+ Breakpoint 1, btrfs_init_sysfs () at /home/user/linux/fs/btrfs/sysfs.c:36
+ 36 btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj);
+
+- 查看內核的日誌緩è¡å€::
+
+ (gdb) lx-dmesg
+ [ 0.000000] Initializing cgroup subsys cpuset
+ [ 0.000000] Initializing cgroup subsys cpu
+ [ 0.000000] Linux version 3.8.0-rc4-dbg+ (...
+ [ 0.000000] Command line: root=/dev/sda2 resume=/dev/sda1 vga=0x314
+ [ 0.000000] e820: BIOS-provided physical RAM map:
+ [ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
+ [ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
+ ....
+
+- 查看當å‰task structçµæ§‹é«”的字段(僅x86å’Œarm64支æŒï¼‰::
+
+ (gdb) p $lx_current().pid
+ $1 = 4998
+ (gdb) p $lx_current().comm
+ $2 = "modprobe\000\000\000\000\000\000\000"
+
+- å°ç•¶å‰æˆ–指定的CPU使用per-cpu函數::
+
+ (gdb) p $lx_per_cpu("runqueues").nr_running
+ $3 = 1
+ (gdb) p $lx_per_cpu("runqueues", 2).nr_running
+ $4 = 0
+
+- 使用container_of查看更多hrtimersä¿¡æ¯::
+
+ (gdb) set $next = $lx_per_cpu("hrtimer_bases").clock_base[0].active.next
+ (gdb) p *$container_of($next, "struct hrtimer", "node")
+ $5 = {
+ node = {
+ node = {
+ __rb_parent_color = 18446612133355256072,
+ rb_right = 0x0 <irq_stack_union>,
+ rb_left = 0x0 <irq_stack_union>
+ },
+ expires = {
+ tv64 = 1835268000000
+ }
+ },
+ _softexpires = {
+ tv64 = 1835268000000
+ },
+ function = 0xffffffff81078232 <tick_sched_timer>,
+ base = 0xffff88003fd0d6f0,
+ state = 1,
+ start_pid = 0,
+ start_site = 0xffffffff81055c1f <hrtimer_start_range_ns+20>,
+ start_comm = "swapper/2\000\000\000\000\000\000"
+ }
+
+
+命令和輔助調試功能列表
+----------------------
+
+命令和輔助調試功能å¯èƒ½æœƒéš¨ç€æ™‚間的推移而改進,此文顯示的是åˆå§‹ç‰ˆæœ¬çš„部分示例::
+
+ (gdb) apropos lx
+ function lx_current -- Return current task
+ function lx_module -- Find module by name and return the module variable
+ function lx_per_cpu -- Return per-cpu variable
+ function lx_task_by_pid -- Find Linux task by PID and return the task_struct variable
+ function lx_thread_info -- Calculate Linux thread_info from task variable
+ lx-dmesg -- Print Linux kernel log buffer
+ lx-lsmod -- List currently loaded modules
+ lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules
+
+å¯ä»¥é€šéŽâ€œhelp <command-name>â€æˆ–“help function <function-name>â€å‘½ä»¤
+ç²å–指定命令或指定調試功能的更多詳細信æ¯ã€‚
+
diff --git a/Documentation/translations/zh_TW/dev-tools/index.rst b/Documentation/translations/zh_TW/dev-tools/index.rst
new file mode 100644
index 000000000000..0d38e5f80e54
--- /dev/null
+++ b/Documentation/translations/zh_TW/dev-tools/index.rst
@@ -0,0 +1,43 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/dev-tools/index.rst
+:Translator: 趙è»å¥Ž Bernard Zhao <bernard@vivo.com>
+
+============
+內核開發工具
+============
+
+本文檔是有關內核開發工具文檔的åˆé›†ã€‚
+ç›®å‰é€™äº›æ–‡æª”已經整ç†åœ¨ä¸€èµ·ï¼Œä¸éœ€è¦å†èŠ±è²»é¡å¤–的精力。
+歡迎任何補ä¸ã€‚
+
+有關測試專用工具的簡è¦æ¦‚述,åƒè¦‹
+Documentation/translations/zh_TW/dev-tools/testing-overview.rst
+
+.. class:: toc-title
+
+ 目錄
+
+.. toctree::
+ :maxdepth: 2
+
+ testing-overview
+ sparse
+ gcov
+ kasan
+ gdb-kernel-debugging
+
+Todolist:
+
+ - coccinelle
+ - kcov
+ - ubsan
+ - kmemleak
+ - kcsan
+ - kfence
+ - kgdb
+ - kselftest
+ - kunit/index
+
diff --git a/Documentation/translations/zh_TW/dev-tools/kasan.rst b/Documentation/translations/zh_TW/dev-tools/kasan.rst
new file mode 100644
index 000000000000..979eb84bc58f
--- /dev/null
+++ b/Documentation/translations/zh_TW/dev-tools/kasan.rst
@@ -0,0 +1,463 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/dev-tools/kasan.rst
+:Translator: è¬å®¶å…µ Wan Jiabing <wanjiabing@vivo.com>
+
+內核地å€æ¶ˆæ¯’劑(KASAN)
+=====================
+
+概述
+----
+
+Kernel Address SANitizer(KASAN)是一種動態內存安全錯誤檢測工具,主è¦åŠŸèƒ½æ˜¯
+檢查內存越界訪å•å’Œä½¿ç”¨å·²é‡‹æ”¾å…§å­˜çš„å•é¡Œã€‚
+
+KASAN有三種模å¼:
+
+1. 通用KASAN
+2. 基於軟件標籤的KASAN
+3. 基於硬件標籤的KASAN
+
+用CONFIG_KASAN_GENERIC啓用的通用KASAN,是用於調試的模å¼ï¼Œé¡žä¼¼æ–¼ç”¨æˆ¶ç©º
+é–“çš„ASan。這種模å¼åœ¨è¨±å¤šCPU架構上都被支æŒï¼Œä½†å®ƒæœ‰æ˜Žé¡¯çš„性能和內存開銷。
+
+基於軟件標籤的KASAN或SW_TAGS KASAN,通éŽCONFIG_KASAN_SW_TAGS啓用,
+å¯ä»¥ç”¨æ–¼èª¿è©¦å’Œè‡ªæˆ‘測試,類似於用戶空間HWASan。這種模å¼åªæ”¯æŒarm64,但其
+é©åº¦çš„內存開銷å…許在內存å—é™çš„設備上用真實的工作負載進行測試。
+
+基於硬件標籤的KASAN或HW_TAGS KASAN,用CONFIG_KASAN_HW_TAGS啓用,被
+用作ç¾å ´å…§å­˜éŒ¯èª¤æª¢æ¸¬å™¨æˆ–作爲安全緩解的模å¼ã€‚這種模å¼åªåœ¨æ”¯æŒMTE(內存標籤
+擴展)的arm64 CPU上工作,但它的內存和性能開銷很低,因此å¯ä»¥åœ¨ç”Ÿç”¢ä¸­ä½¿ç”¨ã€‚
+
+關於æ¯ç¨®KASAN模å¼çš„內存和性能影響的細節,請åƒè¦‹ç›¸æ‡‰çš„Kconfigé¸é …çš„æ述。
+
+通用模å¼å’ŒåŸºæ–¼è»Ÿä»¶æ¨™ç±¤çš„模å¼é€šå¸¸è¢«ç¨±çˆ²è»Ÿä»¶æ¨¡å¼ã€‚基於軟件標籤的模å¼å’ŒåŸºæ–¼
+硬件標籤的模å¼è¢«ç¨±çˆ²åŸºæ–¼æ¨™ç±¤çš„模å¼ã€‚
+
+支æŒ
+----
+
+體系架構
+~~~~~~~~
+
+在x86_64ã€armã€arm64ã€powerpcã€riscvã€s390ã€xtensaå’Œloongarch上支æŒé€šç”¨KASAN,
+而基於標籤的KASAN模å¼åªåœ¨arm64上支æŒã€‚
+
+編譯器
+~~~~~~
+
+軟件KASAN模å¼ä½¿ç”¨ç·¨è­¯æ™‚工具在æ¯å€‹å…§å­˜è¨ªå•ä¹‹å‰æ’入有效性檢查,因此需è¦ä¸€å€‹
+æ供支æŒçš„編譯器版本。基於硬件標籤的模å¼ä¾é ç¡¬ä»¶ä¾†åŸ·è¡Œé€™äº›æª¢æŸ¥ï¼Œä½†ä»ç„¶éœ€è¦
+一個支æŒå…§å­˜æ¨™ç±¤æŒ‡ä»¤çš„編譯器版本。
+
+通用KASAN需è¦GCC 8.3.0版本或更高版本,或者內核支æŒçš„任何Clang版本。
+
+基於軟件標籤的KASAN需è¦GCC 11+或者內核支æŒçš„任何Clang版本。
+
+基於硬件標籤的KASAN需è¦GCC 10+或Clang 12+。
+
+內存類型
+~~~~~~~~
+
+通用KASAN支æŒåœ¨æ‰€æœ‰çš„slabã€page_allocã€vmapã€vmallocã€å †æ£§å’Œå…¨å±€å…§å­˜
+中查找錯誤。
+
+基於軟件標籤的KASAN支æŒslabã€page_allocã€vmalloc和堆棧內存。
+
+基於硬件標籤的KASAN支æŒslabã€page_allocå’Œä¸å¯åŸ·è¡Œçš„vmalloc內存。
+
+å°æ–¼slab,兩種軟件KASAN模å¼éƒ½æ”¯æŒSLUBå’ŒSLAB分é…器,而基於硬件標籤的
+KASANåªæ”¯æŒSLUB。
+
+用法
+----
+
+è¦å•“用KASAN,請使用以下命令é…置內核::
+
+ CONFIG_KASAN=y
+
+åŒæ™‚在 ``CONFIG_KASAN_GENERIC`` (啓用通用KASAN模å¼), ``CONFIG_KASAN_SW_TAGS``
+(啓用基於硬件標籤的KASAN模å¼),和 ``CONFIG_KASAN_HW_TAGS`` (啓用基於硬件標籤
+çš„KASAN模å¼)之間進行é¸æ“‡ã€‚
+
+å°æ–¼è»Ÿä»¶æ¨¡å¼ï¼Œé‚„å¯ä»¥åœ¨ ``CONFIG_KASAN_OUTLINE`` å’Œ ``CONFIG_KASAN_INLINE``
+之間進行é¸æ“‡ã€‚outlineå’Œinline是編譯器æ’æ¨é¡žåž‹ã€‚å‰è€…產生較å°çš„二進制文件,
+而後者快2å€ã€‚
+
+è¦å°‡å—影響的slabå°è±¡çš„allocå’Œfree堆棧跟蹤包å«åˆ°å ±å‘Šä¸­ï¼Œè«‹å•“用
+``CONFIG_STACKTRACE`` 。è¦åŒ…括å—影響物ç†é é¢çš„分é…和釋放堆棧跟蹤的話,
+請啓用 ``CONFIG_PAGE_OWNER`` 並使用 ``page_owner=on`` 進行引導。
+
+å•“å‹•åƒæ•¸
+~~~~~~~~
+
+KASANå—到通用 ``panic_on_warn`` 命令行åƒæ•¸çš„影響。當它被啓用時,KASAN
+在打å°å‡ºéŒ¯èª¤å ±å‘Šå¾Œæœƒä½¿å…§æ ¸æ慌。
+
+默èªæƒ…æ³ä¸‹ï¼ŒKASANåªå°ç¬¬ä¸€å€‹ç„¡æ•ˆçš„內存訪å•æ‰“å°éŒ¯èª¤å ±å‘Šã€‚使用
+``kasan_multi_shot``,KASANå°æ¯ä¸€å€‹ç„¡æ•ˆçš„訪å•éƒ½æ‰“å°ä¸€ä»½å ±å‘Šã€‚這會ç¦ç”¨
+了KASAN報告的 ``panic_on_warn``。
+
+å¦å¤–,ç¨ç«‹æ–¼ ``panic_on_warn`` 〠``kasan.fault=`` bootåƒæ•¸å¯ä»¥ç”¨
+來控制æ慌和報告行爲。
+
+- ``kasan.fault=report`` 或 ``=panic`` 控制是å¦åªæ‰“å°KASAN report或
+ åŒæ™‚使內核æ慌(默èªï¼š ``report`` )。å³ä½¿ ``kasan_multi_shot`` 被
+ 啓用,æ慌也會發生。
+
+基於軟件和硬件標籤的KASAN模å¼ï¼ˆè¦‹ä¸‹é¢é—œæ–¼å„種模å¼çš„部分)支æŒæ”¹è®Šå †æ£§è·Ÿ
+蹤收集行爲:
+
+- ``kasan.stacktrace=off`` 或 ``=on`` ç¦ç”¨æˆ–啓用分é…和釋放堆棧痕
+ 跡的收集(默èªï¼š ``on`` )。
+
+- ``kasan.stack_ring_size=<number of entries>`` 指定堆棧環的æ¢
+ 目數(默èªï¼š ``32768`` )。
+
+基於硬件標籤的KASAN模å¼æ˜¯çˆ²äº†åœ¨ç”Ÿç”¢ä¸­ä½œçˆ²ä¸€ç¨®å®‰å…¨ç·©è§£æŽªæ–½ä½¿ç”¨ã€‚因此,它
+支æŒé¡å¤–çš„å•“å‹•åƒæ•¸ï¼Œå…許完全ç¦ç”¨KASAN或控制其功能。
+
+- ``kasan=off`` 或 ``=on`` 控制KASAN是å¦è¢«å•“用(默èªï¼š ``on`` )。
+
+- ``kasan.mode=sync``, ``=async`` or ``=asymm`` 控制KASAN是å¦
+ 被é…置爲åŒæ­¥ã€ç•°æ­¥æˆ–éžå°ç¨±çš„執行模å¼ï¼ˆé»˜èªï¼š ``åŒæ­¥`` )。
+ åŒæ­¥æ¨¡å¼ï¼šç•¶æ¨™ç±¤æª¢æŸ¥ç•°å¸¸ç™¼ç”Ÿæ™‚,會立å³æª¢æ¸¬åˆ°ä¸è‰¯è¨ªå•ã€‚
+ 異步模å¼ï¼šä¸è‰¯è¨ªå•çš„檢測是延é²çš„。當標籤檢查異常發生時,信æ¯è¢«å­˜å„²åœ¨ç¡¬
+ 件中(å°æ–¼arm64來說是在TFSR_EL1寄存器中)。內核週期性地檢查硬件,並\
+ 且åªåœ¨é€™äº›æª¢æŸ¥ä¸­å ±å‘Šæ¨™ç±¤ç•°å¸¸ã€‚
+ éžå°ç¨±æ¨¡å¼ï¼šè®€å–時åŒæ­¥æª¢æ¸¬ä¸è‰¯è¨ªå•ï¼Œå¯«å…¥æ™‚異步檢測。
+
+- ``kasan.vmalloc=off`` or ``=on`` ç¦ç”¨æˆ–啓用vmalloc分é…的標記(默èªï¼š ``on`` )。
+
+錯誤報告
+~~~~~~~~
+
+典型的KASAN報告如下所示::
+
+ ==================================================================
+ BUG: KASAN: slab-out-of-bounds in kmalloc_oob_right+0xa8/0xbc [test_kasan]
+ Write of size 1 at addr ffff8801f44ec37b by task insmod/2760
+
+ CPU: 1 PID: 2760 Comm: insmod Not tainted 4.19.0-rc3+ #698
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
+ Call Trace:
+ dump_stack+0x94/0xd8
+ print_address_description+0x73/0x280
+ kasan_report+0x144/0x187
+ __asan_report_store1_noabort+0x17/0x20
+ kmalloc_oob_right+0xa8/0xbc [test_kasan]
+ kmalloc_tests_init+0x16/0x700 [test_kasan]
+ do_one_initcall+0xa5/0x3ae
+ do_init_module+0x1b6/0x547
+ load_module+0x75df/0x8070
+ __do_sys_init_module+0x1c6/0x200
+ __x64_sys_init_module+0x6e/0xb0
+ do_syscall_64+0x9f/0x2c0
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+ RIP: 0033:0x7f96443109da
+ RSP: 002b:00007ffcf0b51b08 EFLAGS: 00000202 ORIG_RAX: 00000000000000af
+ RAX: ffffffffffffffda RBX: 000055dc3ee521a0 RCX: 00007f96443109da
+ RDX: 00007f96445cff88 RSI: 0000000000057a50 RDI: 00007f9644992000
+ RBP: 000055dc3ee510b0 R08: 0000000000000003 R09: 0000000000000000
+ R10: 00007f964430cd0a R11: 0000000000000202 R12: 00007f96445cff88
+ R13: 000055dc3ee51090 R14: 0000000000000000 R15: 0000000000000000
+
+ Allocated by task 2760:
+ save_stack+0x43/0xd0
+ kasan_kmalloc+0xa7/0xd0
+ kmem_cache_alloc_trace+0xe1/0x1b0
+ kmalloc_oob_right+0x56/0xbc [test_kasan]
+ kmalloc_tests_init+0x16/0x700 [test_kasan]
+ do_one_initcall+0xa5/0x3ae
+ do_init_module+0x1b6/0x547
+ load_module+0x75df/0x8070
+ __do_sys_init_module+0x1c6/0x200
+ __x64_sys_init_module+0x6e/0xb0
+ do_syscall_64+0x9f/0x2c0
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ Freed by task 815:
+ save_stack+0x43/0xd0
+ __kasan_slab_free+0x135/0x190
+ kasan_slab_free+0xe/0x10
+ kfree+0x93/0x1a0
+ umh_complete+0x6a/0xa0
+ call_usermodehelper_exec_async+0x4c3/0x640
+ ret_from_fork+0x35/0x40
+
+ The buggy address belongs to the object at ffff8801f44ec300
+ which belongs to the cache kmalloc-128 of size 128
+ The buggy address is located 123 bytes inside of
+ 128-byte region [ffff8801f44ec300, ffff8801f44ec380)
+ The buggy address belongs to the page:
+ page:ffffea0007d13b00 count:1 mapcount:0 mapping:ffff8801f7001640 index:0x0
+ flags: 0x200000000000100(slab)
+ raw: 0200000000000100 ffffea0007d11dc0 0000001a0000001a ffff8801f7001640
+ raw: 0000000000000000 0000000080150015 00000001ffffffff 0000000000000000
+ page dumped because: kasan: bad access detected
+
+ Memory state around the buggy address:
+ ffff8801f44ec200: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
+ ffff8801f44ec280: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
+ >ffff8801f44ec300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
+ ^
+ ffff8801f44ec380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
+ ffff8801f44ec400: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
+ ==================================================================
+
+報告標題總çµäº†ç™¼ç”Ÿçš„錯誤類型以åŠå°Žè‡´è©²éŒ¯èª¤çš„訪å•é¡žåž‹ã€‚緊隨其後的是錯誤訪å•çš„
+堆棧跟蹤ã€æ‰€è¨ªå•å…§å­˜åˆ†é…ä½ç½®çš„堆棧跟蹤(å°æ–¼è¨ªå•äº†slabå°è±¡çš„情æ³ï¼‰ä»¥åŠå°è±¡
+被釋放的ä½ç½®çš„堆棧跟蹤(å°æ–¼è¨ªå•å·²é‡‹æ”¾å…§å­˜çš„å•é¡Œå ±å‘Šï¼‰ã€‚接下來是å°è¨ªå•çš„
+slabå°è±¡çš„æ述以åŠé—œæ–¼è¨ªå•çš„內存é çš„ä¿¡æ¯ã€‚
+
+最後,報告展示了訪å•åœ°å€å‘¨åœçš„內存狀態。在內部,KASANå–®ç¨è·Ÿè¹¤æ¯å€‹å…§å­˜é¡†ç²’çš„
+內存狀態,根據KASAN模å¼åˆ†çˆ²8或16個å°é½Šå­—節。報告的內存狀態部分中的æ¯å€‹æ•¸å­—
+都顯示了åœç¹žè¨ªå•åœ°å€çš„其中一個內存顆粒的狀態。
+
+å°æ–¼é€šç”¨KASAN,æ¯å€‹å…§å­˜é¡†ç²’的大å°çˆ²8個字節。æ¯å€‹é¡†ç²’的狀態被編碼在一個影å­å­—節
+中。這8個字節å¯ä»¥æ˜¯å¯è¨ªå•çš„,部分訪å•çš„,已釋放的或æˆçˆ²Redzone的一部分。KASAN
+å°æ¯å€‹å½±å­å­—節使用以下編碼:00表示å°æ‡‰å…§å­˜å€åŸŸçš„所有8個字節都å¯ä»¥è¨ªå•ï¼›æ•¸å­—N
+(1 <= N <= 7)表示å‰N個字節å¯è¨ªå•ï¼Œå…¶ä»–(8 - N)個字節ä¸å¯è¨ªå•ï¼›ä»»ä½•è² å€¼éƒ½è¡¨ç¤º
+無法訪å•æ•´å€‹8字節。KASAN使用ä¸åŒçš„負值來å€åˆ†ä¸åŒé¡žåž‹çš„ä¸å¯è¨ªå•å…§å­˜ï¼Œå¦‚redzones
+或已釋放的內存(åƒè¦‹ mm/kasan/kasan.h)。
+
+在上é¢çš„報告中,箭頭指å‘å½±å­å­—節 ``03`` ,表示訪å•çš„地å€æ˜¯éƒ¨åˆ†å¯è¨ªå•çš„。
+
+å°æ–¼åŸºæ–¼æ¨™ç±¤çš„KASAN模å¼ï¼Œå ±å‘Šæœ€å¾Œçš„部分顯示了訪å•åœ°å€å‘¨åœçš„內存標籤
+(åƒè€ƒ `實施細則`_ 章節)。
+
+請注æ„,KASAN錯誤標題(如 ``slab-out-of-bounds`` 或 ``use-after-free`` )
+是儘é‡æŽ¥è¿‘çš„:KASAN根據其æ“有的有é™ä¿¡æ¯æ‰“å°å‡ºæœ€å¯èƒ½çš„錯誤類型。錯誤的實際類型
+å¯èƒ½æœƒæœ‰æ‰€ä¸åŒã€‚
+
+通用KASAN還報告兩個輔助調用堆棧跟蹤。這些堆棧跟蹤指å‘代碼中與å°è±¡äº¤äº’但ä¸ç›´æŽ¥
+出ç¾åœ¨éŒ¯èª¤è¨ªå•å †æ£§è·Ÿè¹¤ä¸­çš„ä½ç½®ã€‚ç›®å‰ï¼Œé€™åŒ…括 call_rcu() 和排隊的工作隊列。
+
+實施細則
+--------
+
+通用KASAN
+~~~~~~~~~
+
+軟件KASAN模å¼ä½¿ç”¨å½±å­å…§å­˜ä¾†è¨˜éŒ„æ¯å€‹å…§å­˜å­—節是å¦å¯ä»¥å®‰å…¨è¨ªå•ï¼Œä¸¦ä½¿ç”¨ç·¨è­¯æ™‚工具
+在æ¯æ¬¡å…§å­˜è¨ªå•ä¹‹å‰æ’入影å­å…§å­˜æª¢æŸ¥ã€‚
+
+通用KASANå°‡1/8的內核內存專用於其影å­å…§å­˜ï¼ˆ16TB以覆蓋x86_64上的128TB),並使用
+具有比例和å移é‡çš„直接映射將內存地å€è½‰æ›çˆ²å…¶ç›¸æ‡‰çš„å½±å­åœ°å€ã€‚
+
+這是將地å€è½‰æ›çˆ²å…¶ç›¸æ‡‰å½±å­åœ°å€çš„函數::
+
+ static inline void *kasan_mem_to_shadow(const void *addr)
+ {
+ return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
+ + KASAN_SHADOW_OFFSET;
+ }
+
+åœ¨é€™è£ ``KASAN_SHADOW_SCALE_SHIFT = 3`` 。
+
+編譯時工具用於æ’入內存訪å•æª¢æŸ¥ã€‚編譯器在æ¯æ¬¡è¨ªå•å¤§å°çˆ²1ã€2ã€4ã€8或16的內存之å‰
+æ’入函數調用( ``__asan_load*(addr)`` , ``__asan_store*(addr)``)。這些函數通éŽ
+檢查相應的影å­å…§å­˜ä¾†æª¢æŸ¥å…§å­˜è¨ªå•æ˜¯å¦æœ‰æ•ˆã€‚
+
+使用inlineæ’æ¨ï¼Œç·¨è­¯å™¨ä¸é€²è¡Œå‡½æ•¸èª¿ç”¨ï¼Œè€Œæ˜¯ç›´æŽ¥æ’入代碼來檢查影å­å…§å­˜ã€‚æ­¤é¸é …
+顯著地增大了內核體ç©ï¼Œä½†èˆ‡outlineæ’æ¨å…§æ ¸ç›¸æ¯”,它æ供了x1.1-x2的性能æå‡ã€‚
+
+通用KASAN是唯一一種通éŽéš”離延é²é‡æ–°ä½¿ç”¨å·²é‡‹æ”¾å°è±¡çš„模å¼
+(åƒè¦‹ mm/kasan/quarantine.c 以瞭解實ç¾ï¼‰ã€‚
+
+基於軟件標籤的KASAN模å¼
+~~~~~~~~~~~~~~~~~~~~~~~
+
+基於軟件標籤的KASAN使用軟件內存標籤方法來檢查訪å•æœ‰æ•ˆæ€§ã€‚ç›®å‰åƒ…é‡å°arm64架構實ç¾ã€‚
+
+基於軟件標籤的KASAN使用arm64 CPU的頂部字節忽略(TBI)特性在內核指é‡çš„頂部字節中
+存儲一個指é‡æ¨™ç±¤ã€‚它使用影å­å…§å­˜ä¾†å­˜å„²èˆ‡æ¯å€‹16字節內存單元相關的內存標籤(因此,
+它將內核內存的1/16專用於影å­å…§å­˜)。
+
+在æ¯æ¬¡å…§å­˜åˆ†é…時,基於軟件標籤的KASAN都會生æˆä¸€å€‹éš¨æ©Ÿæ¨™ç±¤ï¼Œç”¨é€™å€‹æ¨™ç±¤æ¨™è¨˜åˆ†é…
+的內存,並將相åŒçš„標籤嵌入到返回的指é‡ä¸­ã€‚
+
+基於軟件標籤的KASAN使用編譯時工具在æ¯æ¬¡å…§å­˜è¨ªå•ä¹‹å‰æ’入檢查。這些檢查確ä¿æ­£åœ¨
+訪å•çš„內存的標籤等於用於訪å•è©²å…§å­˜çš„指é‡çš„標籤。如果標籤ä¸åŒ¹é…,基於軟件標籤
+çš„KASAN會打å°éŒ¯èª¤å ±å‘Šã€‚
+
+基於軟件標籤的KASAN也有兩種æ’æ¨æ¨¡å¼ï¼ˆoutline,發出回調來檢查內存訪å•ï¼›inline,
+執行內è¯çš„å½±å­å…§å­˜æª¢æŸ¥ï¼‰ã€‚使用outlineæ’æ¨æ¨¡å¼ï¼Œæœƒå¾žåŸ·è¡Œè¨ªå•æª¢æŸ¥çš„函數打å°éŒ¯èª¤
+報告。使用inlineæ’æ¨ï¼Œç·¨è­¯å™¨æœƒç™¼å‡º ``brk`` 指令,並使用專用的 ``brk`` 處ç†ç¨‹åº
+來打å°éŒ¯èª¤å ±å‘Šã€‚
+
+基於軟件標籤的KASAN使用0xFF作爲匹é…所有指é‡æ¨™ç±¤ï¼ˆä¸æª¢æŸ¥é€šéŽå¸¶æœ‰0xFF指é‡æ¨™ç±¤
+的指é‡é€²è¡Œçš„訪å•ï¼‰ã€‚值0xFE當å‰ä¿ç•™ç”¨æ–¼æ¨™è¨˜å·²é‡‹æ”¾çš„內存å€åŸŸã€‚
+
+
+基於硬件標籤的KASAN模å¼
+~~~~~~~~~~~~~~~~~~~~~~~
+
+基於硬件標籤的KASAN在概念上類似於軟件模å¼ï¼Œä½†å®ƒæ˜¯ä½¿ç”¨ç¡¬ä»¶å…§å­˜æ¨™ç±¤ä½œçˆ²æ”¯æŒè€Œ
+ä¸æ˜¯ç·¨è­¯å™¨æ’æ¨å’Œå½±å­å…§å­˜ã€‚
+
+基於硬件標籤的KASANç›®å‰åƒ…é‡å°arm64架構實ç¾ï¼Œä¸¦ä¸”基於ARMv8.5指令集架構中引入
+的arm64內存標記擴展(MTE)和最高字節忽略(TBI)。
+
+特殊的arm64指令用於爲æ¯æ¬¡å…§å­˜åˆ†é…指定內存標籤。相åŒçš„標籤被指定給指å‘這些分é…
+的指é‡ã€‚在æ¯æ¬¡å…§å­˜è¨ªå•æ™‚,硬件確ä¿æ­£åœ¨è¨ªå•çš„內存的標籤等於用於訪å•è©²å…§å­˜çš„指é‡
+的標籤。如果標籤ä¸åŒ¹é…,則會生æˆæ•…障並打å°å ±å‘Šã€‚
+
+基於硬件標籤的KASAN使用0xFF作爲匹é…所有指é‡æ¨™ç±¤ï¼ˆä¸æª¢æŸ¥é€šéŽå¸¶æœ‰0xFF指é‡æ¨™ç±¤çš„
+指é‡é€²è¡Œçš„訪å•ï¼‰ã€‚值0xFE當å‰ä¿ç•™ç”¨æ–¼æ¨™è¨˜å·²é‡‹æ”¾çš„內存å€åŸŸã€‚
+
+如果硬件ä¸æ”¯æŒMTE(ARMv8.5之å‰ï¼‰ï¼Œå‰‡ä¸æœƒå•“用基於硬件標籤的KASAN。在這種情æ³ä¸‹ï¼Œ
+所有KASAN引導åƒæ•¸éƒ½å°‡è¢«å¿½ç•¥ã€‚
+
+請注æ„,啓用CONFIG_KASAN_HW_TAGS始終會導致啓用內核中的TBI。å³ä½¿æ供了
+``kasan.mode=off`` 或硬件ä¸æ”¯æŒMTE(但支æŒTBI)。
+
+基於硬件標籤的KASANåªå ±å‘Šç¬¬ä¸€å€‹ç™¼ç¾çš„錯誤。之後,MTE標籤檢查將被ç¦ç”¨ã€‚
+
+å½±å­å…§å­˜
+--------
+
+本節的內容åªé©ç”¨æ–¼è»Ÿä»¶KASAN模å¼ã€‚
+
+內核將內存映射到地å€ç©ºé–“的幾個ä¸åŒéƒ¨åˆ†ã€‚內核虛擬地å€çš„範åœå¾ˆå¤§ï¼šæ²’有足夠的真實
+內存來支æŒå…§æ ¸å¯ä»¥è¨ªå•çš„æ¯å€‹åœ°å€çš„真實影å­å€åŸŸã€‚因此,KASANåªçˆ²åœ°å€ç©ºé–“çš„æŸäº›
+部分映射真實的影å­ã€‚
+
+默èªè¡Œçˆ²
+~~~~~~~~
+
+默èªæƒ…æ³ä¸‹ï¼Œé«”ç³»çµæ§‹åƒ…將實際內存映射到用於線性映射的陰影å€åŸŸï¼ˆä»¥åŠå¯èƒ½çš„其他
+å°å€åŸŸï¼‰ã€‚å°æ–¼æ‰€æœ‰å…¶ä»–å€åŸŸ —— 例如vmallocå’Œvmemmap空間 —— 一個åªè®€é é¢è¢«æ˜ å°„
+到陰影å€åŸŸä¸Šã€‚這個åªè®€çš„å½±å­é é¢è²æ˜Žæ‰€æœ‰å…§å­˜è¨ªå•éƒ½æ˜¯å…許的。
+
+這給模塊帶來了一個å•é¡Œï¼šå®ƒå€‘ä¸å­˜åœ¨æ–¼ç·šæ€§æ˜ å°„中,而是存在於專用的模塊空間中。
+通éŽé€£æŽ¥æ¨¡å¡Šåˆ†é…器,KASAN臨時映射真實的影å­å…§å­˜ä»¥è¦†è“‹å®ƒå€‘。例如,這å…許檢測
+å°æ¨¡å¡Šå…¨å±€è®Šé‡çš„無效訪å•ã€‚
+
+這也造æˆäº†èˆ‡ ``VMAP_STACK`` çš„ä¸å…¼å®¹ï¼šå¦‚果堆棧ä½æ–¼vmalloc空間中,它將被分é…
+åªè®€é é¢çš„å½±å­å…§å­˜ï¼Œä¸¦ä¸”內核在嘗試爲堆棧變é‡è¨­ç½®å½±å­æ•¸æ“šæ™‚會出錯。
+
+CONFIG_KASAN_VMALLOC
+~~~~~~~~~~~~~~~~~~~~
+
+使用 ``CONFIG_KASAN_VMALLOC`` ,KASANå¯ä»¥ä»¥æ›´å¤§çš„內存使用爲代價覆蓋vmalloc
+空間。目å‰ï¼Œé€™åœ¨arm64ã€x86ã€riscvã€s390å’Œpowerpc上å—支æŒã€‚
+
+這通éŽé€£æŽ¥åˆ°vmallocå’Œvmap並動態分é…真實的影å­å…§å­˜ä¾†æ”¯æŒæ˜ å°„。
+
+vmalloc空間中的大多數映射都很å°ï¼Œéœ€è¦ä¸åˆ°ä¸€æ•´é çš„陰影空間。因此,爲æ¯å€‹æ˜ å°„
+分é…一個完整的影å­é é¢å°‡æ˜¯ä¸€ç¨®æµªè²»ã€‚此外,爲了確ä¿ä¸åŒçš„映射使用ä¸åŒçš„å½±å­
+é é¢ï¼Œæ˜ å°„必須與 ``KASAN_GRANULE_SIZE * PAGE_SIZE`` å°é½Šã€‚
+
+相å,KASAN跨多個映射共享後備空間。當vmalloc空間中的映射使用影å­å€åŸŸçš„特定
+é é¢æ™‚,它會分é…一個後備é é¢ã€‚æ­¤é é¢ç¨å¾Œå¯ä»¥ç”±å…¶ä»–vmalloc映射共享。
+
+KASAN連接到vmap基礎架構以懶清ç†æœªä½¿ç”¨çš„å½±å­å…§å­˜ã€‚
+
+爲了é¿å…交æ›æ˜ å°„的困難,KASANé æ¸¬è¦†è“‹vmalloc空間的陰影å€åŸŸéƒ¨åˆ†å°‡ä¸æœƒè¢«æ—©æœŸ
+çš„é™°å½±é é¢è¦†è“‹ï¼Œä½†æ˜¯å°‡ä¸æœƒè¢«æ˜ å°„。這將需è¦æ›´æ”¹ç‰¹å®šæ–¼arch的代碼。
+
+這å…許在x86ä¸Šæ”¯æŒ ``VMAP_STACK`` ,並且å¯ä»¥ç°¡åŒ–å°æ²’有固定模塊å€åŸŸçš„架構的支æŒã€‚
+
+å°æ–¼é–‹ç™¼è€…
+----------
+
+忽略訪å•
+~~~~~~~~
+
+軟件KASAN模å¼ä½¿ç”¨ç·¨è­¯å™¨æ’æ¨ä¾†æ’入有效性檢查。此類檢測å¯èƒ½èˆ‡å…§æ ¸çš„æŸäº›éƒ¨åˆ†
+ä¸å…¼å®¹ï¼Œå› æ­¤éœ€è¦ç¦ç”¨ã€‚
+
+內核的其他部分å¯èƒ½æœƒè¨ªå•å·²åˆ†é…å°è±¡çš„元數據。通常,KASAN會檢測並報告此類訪å•ï¼Œ
+但在æŸäº›æƒ…æ³ä¸‹ï¼ˆä¾‹å¦‚,在內存分é…器中),這些訪å•æ˜¯æœ‰æ•ˆçš„。
+
+å°æ–¼è»Ÿä»¶KASAN模å¼ï¼Œè¦ç¦ç”¨ç‰¹å®šæ–‡ä»¶æˆ–目錄的檢測,請將 ``KASAN_SANITIZE`` 添加
+到相應的內核Makefile中:
+
+- å°æ–¼å–®å€‹æ–‡ä»¶(例如,main.o)::
+
+ KASAN_SANITIZE_main.o := n
+
+- å°æ–¼ä¸€å€‹ç›®éŒ„下的所有文件::
+
+ KASAN_SANITIZE := n
+
+å°æ–¼è»Ÿä»¶KASAN模å¼ï¼Œè¦åœ¨æ¯å€‹å‡½æ•¸çš„基礎上ç¦ç”¨æª¢æ¸¬ï¼Œè«‹ä½¿ç”¨KASAN特定的
+``__no_sanitize_address`` 函數屬性或通用的 ``noinstr`` 。
+
+請注æ„,ç¦ç”¨ç·¨è­¯å™¨æ’æ¨ï¼ˆåŸºæ–¼æ¯å€‹æ–‡ä»¶æˆ–æ¯å€‹å‡½æ•¸ï¼‰æœƒä½¿KASAN忽略在軟件KASAN模å¼
+的代碼中直接發生的訪å•ã€‚當訪å•æ˜¯é–“接發生的(通éŽèª¿ç”¨æª¢æ¸¬å‡½æ•¸ï¼‰æˆ–使用沒有編譯器
+æ’æ¨çš„基於硬件標籤的模å¼æ™‚,它沒有幫助。
+
+å°æ–¼è»Ÿä»¶KASAN模å¼ï¼Œè¦åœ¨ç•¶å‰ä»»å‹™çš„一部分內核代碼中ç¦ç”¨KASAN報告,請使用
+``kasan_disable_current()``/``kasan_enable_current()`` 部分註釋這部分代碼。
+這也會ç¦ç”¨é€šéŽå‡½æ•¸èª¿ç”¨ç™¼ç”Ÿçš„間接訪å•çš„報告。
+
+å°æ–¼åŸºæ–¼æ¨™ç±¤çš„KASAN模å¼ï¼Œè¦ç¦ç”¨è¨ªå•æª¢æŸ¥ï¼Œè«‹ä½¿ç”¨ ``kasan_reset_tag()`` 或
+``page_kasan_tag_reset()`` 。請注æ„ï¼Œé€šéŽ ``page_kasan_tag_reset()``
+臨時ç¦ç”¨è¨ªå•æª¢æŸ¥éœ€è¦é€šéŽ ``page_kasan_tag`` / ``page_kasan_tag_set`` ä¿
+存和æ¢å¾©æ¯é KASAN標籤。
+
+測試
+~~~~
+
+有一些KASAN測試å¯ä»¥é©—è­‰KASAN是å¦æ­£å¸¸å·¥ä½œä¸¦å¯ä»¥æª¢æ¸¬æŸäº›é¡žåž‹çš„內存æ壞。
+測試由兩部分組æˆ:
+
+1. 與KUnit測試框架集æˆçš„測試。使用 ``CONFIG_KASAN_KUNIT_TEST`` 啓用。
+這些測試å¯ä»¥é€šéŽå¹¾ç¨®ä¸åŒçš„æ–¹å¼è‡ªå‹•é‹è¡Œå’Œéƒ¨åˆ†é©—證;請åƒé–±ä¸‹é¢çš„說明。
+
+2. 與KUnitä¸å…¼å®¹çš„測試。使用 ``CONFIG_KASAN_MODULE_TEST`` 啓用並且åªèƒ½ä½œçˆ²æ¨¡å¡Š
+é‹è¡Œã€‚這些測試åªèƒ½é€šéŽåŠ è¼‰å…§æ ¸æ¨¡å¡Šä¸¦æª¢æŸ¥å…§æ ¸æ—¥èªŒä»¥ç²å–KASAN報告來手動驗證。
+
+如果檢測到錯誤,æ¯å€‹KUnit兼容的KASAN測試都會打å°å¤šå€‹KASAN報告之一,然後測試打å°
+其編號和狀態。
+
+當測試通éŽ::
+
+ ok 28 - kmalloc_double_kzfree
+
+當由於 ``kmalloc`` 失敗而導致測試失敗時::
+
+ # kmalloc_large_oob_right: ASSERTION FAILED at lib/test_kasan.c:163
+ Expected ptr is not null, but is
+ not ok 4 - kmalloc_large_oob_right
+
+當由於缺少KASAN報告而導致測試失敗時::
+
+ # kmalloc_double_kzfree: EXPECTATION FAILED at lib/test_kasan.c:974
+ KASAN failure expected in "kfree_sensitive(ptr)", but none occurred
+ not ok 44 - kmalloc_double_kzfree
+
+
+最後打å°æ‰€æœ‰KASAN測試的累ç©ç‹€æ…‹ã€‚æˆåŠŸ::
+
+ ok 1 - kasan
+
+或者,如果其中一項測試失敗::
+
+ not ok 1 - kasan
+
+有幾種方法å¯ä»¥é‹è¡Œèˆ‡KUnit兼容的KASAN測試。
+
+1. å¯åŠ è¼‰æ¨¡å¡Š
+
+ 啓用 ``CONFIG_KUNIT`` 後,KASAN-KUnit測試å¯ä»¥æ§‹å»ºçˆ²å¯åŠ è¼‰æ¨¡å¡Šï¼Œä¸¦é€šéŽä½¿ç”¨
+ ``insmod`` 或 ``modprobe`` 加載 ``test_kasan.ko`` 來é‹è¡Œã€‚
+
+2. 內置
+
+ 通éŽå…§ç½® ``CONFIG_KUNIT`` ,也å¯ä»¥å…§ç½®KASAN-KUnit測試。在這種情æ³ä¸‹ï¼Œ
+ 測試將在啓動時作爲後期åˆå§‹åŒ–調用é‹è¡Œã€‚
+
+3. 使用kunit_tool
+
+ 通éŽå…§ç½® ``CONFIG_KUNIT`` å’Œ ``CONFIG_KASAN_KUNIT_TEST`` ,還å¯ä»¥ä½¿ç”¨
+ ``kunit_tool`` 以更易讀的方å¼æŸ¥çœ‹KUnit測試çµæžœã€‚這ä¸æœƒæ‰“å°é€šéŽæ¸¬è©¦
+ çš„KASAN報告。有關 ``kunit_tool`` 更多最新信æ¯ï¼Œè«‹åƒé–±
+ `KUnit文檔 <https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html>`_ 。
+
+.. _KUnit: https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html
+
diff --git a/Documentation/translations/zh_TW/sparse.txt b/Documentation/translations/zh_TW/dev-tools/sparse.rst
index 35d3d1d748e6..11d64709d6a4 100644
--- a/Documentation/translations/zh_TW/sparse.txt
+++ b/Documentation/translations/zh_TW/dev-tools/sparse.rst
@@ -27,7 +27,7 @@ Copyright 2006 Bob Copeland <me@bobcopeland.com>
使用 sparse 工具åšé¡žåž‹æª¢æŸ¥
~~~~~~~~~~~~~~~~~~~~~~~~~~
-"__bitwise" 是一種類型屬性,所以你應該這樣使用它:
+"__bitwise" 是一種類型屬性,所以你應該這樣使用它::
typedef int __bitwise pm_request_t;
@@ -47,7 +47,7 @@ Copyright 2006 Bob Copeland <me@bobcopeland.com>
å¦ç™½ä¾†èªªï¼Œä½ ä¸¦ä¸éœ€è¦ä½¿ç”¨æžšèˆ‰é¡žåž‹ã€‚上é¢é‚£äº›å¯¦éš›éƒ½å¯ä»¥æ¿ƒç¸®æˆä¸€å€‹ç‰¹æ®Šçš„"int
__bitwise"類型。
-所以更簡單的辦法åªè¦é€™æ¨£åšï¼š
+所以更簡單的辦法åªè¦é€™æ¨£åš::
typedef int __bitwise pm_request_t;
diff --git a/Documentation/translations/zh_TW/dev-tools/testing-overview.rst b/Documentation/translations/zh_TW/dev-tools/testing-overview.rst
new file mode 100644
index 000000000000..fb3f691f46c3
--- /dev/null
+++ b/Documentation/translations/zh_TW/dev-tools/testing-overview.rst
@@ -0,0 +1,162 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/dev-tools/testing-overview.rst
+:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
+
+============
+內核測試指å—
+============
+
+有許多ä¸åŒçš„工具å¯ä»¥ç”¨æ–¼æ¸¬è©¦Linux內核,因此瞭解什麼時候使用它們å¯èƒ½
+很困難。本文檔粗略概述了它們之間的å€åˆ¥ï¼Œä¸¦é—¡é‡‹äº†å®ƒå€‘是怎樣糅åˆåœ¨ä¸€èµ·
+的。
+
+編寫和é‹è¡Œæ¸¬è©¦
+==============
+
+大多數內核測試都是用kselftest或KUnit框架之一編寫的。它們都讓é‹è¡Œæ¸¬è©¦
+更加簡化,併爲編寫新測試æ供幫助。
+
+如果你想驗證內核的行爲——尤其是內核的特定部分——那你就è¦ä½¿ç”¨kUnit或
+kselftest。
+
+KUnitå’Œkselftestçš„å€åˆ¥
+----------------------
+
+.. note::
+ 由於本文段中部分術語尚無較好的å°æ‡‰ä¸­æ–‡é‡‹ç¾©ï¼Œå¯èƒ½å°Žè‡´èˆ‡åŽŸæ–‡å«ç¾©
+ 存在些許差異,因此建議讀者çµåˆåŽŸæ–‡
+ (Documentation/dev-tools/testing-overview.rst)輔助閱讀。
+ 如å°éƒ¨åˆ†ç¿»è­¯æœ‰ç•°è­°æˆ–有更好的翻譯æ„見,歡迎è¯ç¹«è­¯è€…進行修訂。
+
+KUnit(Documentation/dev-tools/kunit/index.rst)是用於“白箱â€æ¸¬
+試的一個完整的內核內部系統:因爲測試代碼是內核的一部分,所以它能夠訪
+å•ç”¨æˆ¶ç©ºé–“ä¸èƒ½è¨ªå•åˆ°çš„內部çµæ§‹å’ŒåŠŸèƒ½ã€‚
+
+因此,KUnit測試最好é‡å°å…§æ ¸ä¸­è¼ƒå°çš„ã€è‡ªåŒ…å«çš„部分,以便能夠ç¨ç«‹åœ°æ¸¬
+試。“單元â€æ¸¬è©¦çš„概念亦是如此。
+
+比如,一個KUnit測試å¯èƒ½æ¸¬è©¦ä¸€å€‹å–®ç¨çš„內核功能(甚至通éŽä¸€å€‹å‡½æ•¸æ¸¬è©¦
+一個單一的代碼路徑,例如一個錯誤處ç†æ¡ˆä¾‹ï¼‰ï¼Œè€Œä¸æ˜¯æ•´å€‹åœ°æ¸¬è©¦ä¸€å€‹ç‰¹æ€§ã€‚
+
+這也使得KUnit測試構建和é‹è¡Œéžå¸¸åœ°å¿«ï¼Œå¾žè€Œèƒ½å¤ ä½œçˆ²é–‹ç™¼æµç¨‹çš„一部分被
+é »ç¹åœ°é‹è¡Œã€‚
+
+有關更詳細的介紹,請åƒé–±KUnit測試代碼風格指å—
+Documentation/dev-tools/kunit/style.rst
+
+kselftest(Documentation/dev-tools/kselftest.rst),相å°ä¾†èªªï¼Œå¤§é‡ç”¨
+於用戶空間,並且通常測試用戶空間的腳本或程åºã€‚
+
+這使得編寫複雜的測試,或者需è¦æ“作更多全局系統狀態的測試更加容易(諸
+如生æˆé€²ç¨‹ä¹‹é¡žï¼‰ã€‚然而,從kselftest直接調用內核函數是ä¸è¡Œçš„。這也就
+æ„味ç€åªæœ‰é€šéŽæŸç¨®æ–¹å¼ï¼ˆå¦‚系統調用ã€é©…動設備ã€æ–‡ä»¶ç³»çµ±ç­‰ï¼‰å°Žå‡ºåˆ°äº†ç”¨
+戶空間的內核功能æ‰èƒ½ä½¿ç”¨kselftest來測試。爲此,有些測試包å«äº†ä¸€å€‹ä¼´
+生的內核模塊用於導出更多的信æ¯å’ŒåŠŸèƒ½ã€‚ä¸éŽï¼Œå°æ–¼åŸºæœ¬ä¸Šæˆ–者完全在內核
+中é‹è¡Œçš„測試,KUnitå¯èƒ½æ˜¯æ›´ä½³å·¥å…·ã€‚
+
+kselftest也因此éžå¸¸é©åˆæ–¼å…¨éƒ¨åŠŸèƒ½çš„測試,因爲這些功能會將接å£æš´éœ²åˆ°
+用戶空間,從而能夠被測試,而ä¸æ˜¯å±•ç¾å¯¦ç¾ç´°ç¯€ã€‚“systemâ€æ¸¬è©¦å’Œ
+“end-to-endâ€æ¸¬è©¦äº¦æ˜¯å¦‚此。
+
+比如,一個新的系統調用應該伴隨有新的kselftest測試。
+
+代碼覆蓋率工具
+==============
+
+支æŒå…©ç¨®ä¸åŒä»£ç¢¼ä¹‹é–“的覆蓋率測é‡å·¥å…·ã€‚它們å¯ä»¥ç”¨ä¾†é©—證一項測試執行的
+確切函數或代碼行。這有助於決定內核被測試了多少,或用來查找åˆé©çš„測試
+中沒有覆蓋到的極端情æ³ã€‚
+
+Documentation/translations/zh_CN/dev-tools/gcov.rst 是GCC的覆蓋率測試
+工具,能用於ç²å–內核的全局或æ¯å€‹æ¨¡å¡Šçš„覆蓋率。與KCOVä¸åŒçš„是,這個工具
+ä¸è¨˜éŒ„æ¯å€‹ä»»å‹™çš„覆蓋率。覆蓋率數據å¯ä»¥é€šéŽdebugfs讀å–,並通éŽå¸¸è¦çš„
+gcov工具進行解釋。
+
+Documentation/dev-tools/kcov.rst 是能夠構建在內核之中,用於在æ¯å€‹ä»»å‹™
+的層é¢æ•æ‰è¦†è“‹çŽ‡çš„一個功能。因此,它å°æ–¼æ¨¡ç³Šæ¸¬è©¦å’Œé—œæ–¼ä»£ç¢¼åŸ·è¡ŒæœŸé–“ä¿¡
+æ¯çš„其它情æ³éžå¸¸æœ‰ç”¨ï¼Œæ¯”如在一個單一系統調用è£ä½¿ç”¨å®ƒå°±å¾ˆæœ‰ç”¨ã€‚
+
+動態分æžå·¥å…·
+============
+
+內核也支æŒè¨±å¤šå‹•æ…‹åˆ†æžå·¥å…·ï¼Œç”¨ä»¥æª¢æ¸¬æ­£åœ¨é‹è¡Œçš„內核中出ç¾çš„多種類型的
+å•é¡Œã€‚這些工具通常æ¯å€‹åŽ»å°‹æ‰¾ä¸€é¡žä¸åŒçš„缺陷,比如éžæ³•å…§å­˜è¨ªå•ï¼Œæ•¸æ“šç«¶
+爭等併發å•é¡Œï¼Œæˆ–整型溢出等其他未定義行爲。
+
+如下所示:
+
+* kmemleak檢測å¯èƒ½çš„內存泄æ¼ã€‚åƒé–±
+ Documentation/dev-tools/kmemleak.rst
+* KASAN檢測éžæ³•å…§å­˜è¨ªå•ï¼Œå¦‚數組越界和釋放後é‡ç”¨ï¼ˆUAF)。åƒé–±
+ Documentation/dev-tools/kasan.rst
+* UBSAN檢測C標準中未定義的行爲,如整型溢出。åƒé–±
+ Documentation/dev-tools/ubsan.rst
+* KCSAN檢測數據競爭。åƒé–± Documentation/dev-tools/kcsan.rst
+* KFENCE是一個低開銷的內存å•é¡Œæª¢æ¸¬å™¨ï¼Œæ¯”KASAN更快且能被用於批é‡æ§‹å»ºã€‚
+ åƒé–± Documentation/dev-tools/kfence.rst
+* lockdep是一個鎖定正確性檢測器。åƒé–±
+ Documentation/locking/lockdep-design.rst
+* 除此以外,在內核中還有一些其它的調試工具,大多數能在
+ lib/Kconfig.debug 中找到。
+
+這些工具傾å‘æ–¼å°å…§æ ¸é€²è¡Œæ•´é«”測試,並且ä¸åƒkselftestå’ŒKUnit一樣“傳éžâ€ã€‚
+它們å¯ä»¥é€šéŽåœ¨å•“用這些工具時é‹è¡Œå…§æ ¸æ¸¬è©¦ä»¥èˆ‡kselftest或KUnitçµåˆèµ·ä¾†ï¼š
+之後你就能確ä¿é€™äº›éŒ¯èª¤åœ¨æ¸¬è©¦éŽç¨‹ä¸­éƒ½ä¸æœƒç™¼ç”Ÿäº†ã€‚
+
+一些工具與KUnitå’Œkselftest集æˆï¼Œä¸¦ä¸”在檢測到å•é¡Œæ™‚會自動打斷測試。
+
+éœæ…‹åˆ†æžå·¥å…·
+============
+
+除了測試é‹è¡Œä¸­çš„內核,我們還å¯ä»¥ä½¿ç”¨**éœæ…‹åˆ†æž**工具直接分æžå…§æ ¸çš„æºä»£
+碼(**在編譯時**)。內核中常用的工具å…許人們檢查整個æºä»£ç¢¼æ¨¹æˆ–其中的特
+定文件。它們使得在開發éŽç¨‹ä¸­æ›´å®¹æ˜“發ç¾å’Œä¿®å¾©å•é¡Œã€‚
+
+ Sparseå¯ä»¥é€šéŽåŸ·è¡Œé¡žåž‹æª¢æŸ¥ã€éŽ–檢查ã€å€¼ç¯„åœæª¢æŸ¥ä¾†å¹«åŠ©æ¸¬è©¦å…§æ ¸ï¼Œæ­¤å¤–é‚„
+ å¯ä»¥åœ¨æª¢æŸ¥ä»£ç¢¼æ™‚報告å„種錯誤和警告。關於如何使用它的細節,請åƒé–±
+ Documentation/translations/zh_CN/dev-tools/sparse.rst。
+
+ Smatch擴展了Sparse,並æ供了å°ç·¨ç¨‹é‚輯錯誤的é¡å¤–檢查,如開關語å¥ä¸­
+ 缺少斷點,錯誤檢查中未使用的返回值,忘記在錯誤路徑的返回中設置錯誤代
+ 碼等。Smatch也有é‡å°æ›´åš´é‡å•é¡Œçš„測試,如整數溢出ã€ç©ºæŒ‡é‡è§£é™¤å¼•ç”¨å’Œå…§
+ 存泄æ¼ã€‚見項目é é¢http://smatch.sourceforge.net/。
+
+ Coccinelle是我們å¯ä»¥ä½¿ç”¨çš„å¦ä¸€å€‹éœæ…‹åˆ†æžå™¨ã€‚Coccinelle經常被用來
+ 幫助æºä»£ç¢¼çš„é‡æ§‹å’Œä¸¦è¡Œæ¼”化,但它也å¯ä»¥å¹«åŠ©é¿å…常見代碼模å¼ä¸­å‡ºç¾çš„æŸ
+ 些錯誤。å¯ç”¨çš„測試類型包括API測試ã€å…§æ ¸è¿­ä»£å™¨çš„正確使用測試ã€è‡ªç”±æ“
+ 作的åˆç†æ€§æª¢æŸ¥ã€éŽ–定行爲的分æžï¼Œä»¥åŠå·²çŸ¥çš„有助於ä¿æŒå…§æ ¸ä½¿ç”¨ä¸€è‡´æ€§çš„
+ 進一步測試。詳情請見Documentation/dev-tools/coccinelle.rst。
+
+ ä¸éŽè¦æ³¨æ„的是,éœæ…‹åˆ†æžå·¥å…·å­˜åœ¨**å‡é™½æ€§**çš„å•é¡Œã€‚在試圖修復錯誤和警
+ 告之å‰ï¼Œéœ€è¦ä»”細評估它們。
+
+何時使用Sparse和Smatch
+----------------------
+
+Sparseåšé¡žåž‹æª¢æŸ¥ï¼Œä¾‹å¦‚驗證註釋的變é‡ä¸æœƒå°Žè‡´ç„¡ç¬¦è™Ÿçš„錯誤,檢測
+``__user`` 指é‡ä½¿ç”¨ä¸ç•¶çš„地方,以åŠåˆ†æžç¬¦è™Ÿåˆå§‹åŒ–器的兼容性。
+
+Smatch進行æµç¨‹åˆ†æžï¼Œå¦‚æžœå…許建立函數數據庫,它還會進行跨函數分æžã€‚
+Smatch試圖回答一些å•é¡Œï¼Œæ¯”如這個緩è¡å€æ˜¯åœ¨å“ªè£åˆ†é…的?它有多大?這
+個索引å¯ä»¥ç”±ç”¨æˆ¶æŽ§åˆ¶å—Žï¼Ÿé€™å€‹è®Šé‡æ¯”那個變é‡å¤§å—Žï¼Ÿ
+
+一般來說,在Smatch中寫檢查比在Sparse中寫檢查è¦å®¹æ˜“。儘管如此,
+Sparseå’ŒSmatch的檢查還是有一些é‡ç–Šçš„地方。
+
+Smatchå’ŒCoccinelleçš„å¼·é …
+------------------------
+
+Coccinelleå¯èƒ½æ˜¯æœ€å®¹æ˜“寫檢查的。它在é è™•ç†å™¨ä¹‹å‰å·¥ä½œï¼Œæ‰€ä»¥ç”¨Coccinelle
+檢查å®ä¸­çš„錯誤更容易。Coccinelle還能爲你創建補ä¸ï¼Œé€™æ˜¯å…¶ä»–工具無法åšåˆ°çš„。
+
+例如,用Coccinelleä½ å¯ä»¥å¾ž ``kmalloc_array(x, size, GFP_KERNEL)``
+到 ``kmalloc_array(x, size, GFP_KERNEL)`` 進行大è¦æ¨¡è½‰æ›ï¼Œé€™çœŸçš„很
+有用。如果你åªæ˜¯å‰µå»ºä¸€å€‹Smatch警告,並試圖把轉æ›çš„工作推給維護者,他們會很
+惱ç«ã€‚ä½ å°‡ä¸å¾—ä¸çˆ²æ¯å€‹è­¦å‘Šçˆ­è«–是å¦çœŸçš„å¯ä»¥æº¢å‡ºã€‚
+
+Coccinelleä¸å°è®Šé‡å€¼é€²è¡Œåˆ†æžï¼Œè€Œé€™æ­£æ˜¯Smatch的強項。å¦ä¸€æ–¹é¢ï¼ŒCoccinelle
+å…許你用簡單的方法åšç°¡å–®çš„事情。
+
diff --git a/Documentation/translations/zh_TW/filesystems/debugfs.rst b/Documentation/translations/zh_TW/filesystems/debugfs.rst
index ddf801943c92..78e2e08af95e 100644
--- a/Documentation/translations/zh_TW/filesystems/debugfs.rst
+++ b/Documentation/translations/zh_TW/filesystems/debugfs.rst
@@ -2,7 +2,7 @@
.. include:: ../disclaimer-zh_TW.rst
-:Original: :doc:`../../../filesystems/debugfs`
+:Original: Documentation/filesystems/debugfs.rst
=======
Debugfs
@@ -11,20 +11,19 @@ Debugfs
譯者
::
- ä¸­æ–‡ç‰ˆç¶­è­·è€…ï¼šç¾…æ¥šæˆ Chucheng Luo <luochucheng@vivo.com>
- ä¸­æ–‡ç‰ˆç¿»è­¯è€…ï¼šç¾…æ¥šæˆ Chucheng Luo <luochucheng@vivo.com>
- 中文版校譯者: ç¾…æ¥šæˆ Chucheng Luo <luochucheng@vivo.com>
+ 中文版維護者: ç¾…æ¥šæˆ Chucheng Luo <luochucheng@vivo.com>
+ 中文版翻譯者: ç¾…æ¥šæˆ Chucheng Luo <luochucheng@vivo.com>
+ 中文版校譯者: ç¾…æ¥šæˆ Chucheng Luo <luochucheng@vivo.com>
ç¹é«”中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com>
版權所有2020 ç¾…æ¥šæˆ <luochucheng@vivo.com>
-版權所有2021 胡皓文 Hu Haowen <src.res.211@gmail.com>
Debugfs是內核開發人員在用戶空間ç²å–ä¿¡æ¯çš„簡單方法。與/procä¸åŒï¼Œprocåªæ供進程
-ä¿¡æ¯ã€‚也ä¸åƒsysfs,具有嚴格的「æ¯å€‹æ–‡ä»¶ä¸€å€‹å€¼ã€Œçš„è¦å‰‡ã€‚debugfs根本沒有è¦å‰‡,開發
-人員å¯ä»¥åœ¨é€™è£¡æ”¾ç½®ä»–們想è¦çš„任何信æ¯ã€‚debugfs文件系統也ä¸èƒ½ç”¨ä½œç©©å®šçš„ABI接å£ã€‚
+ä¿¡æ¯ã€‚也ä¸åƒsysfs,具有嚴格的“æ¯å€‹æ–‡ä»¶ä¸€å€‹å€¼â€œçš„è¦å‰‡ã€‚debugfs根本沒有è¦å‰‡,開發
+人員å¯ä»¥åœ¨é€™è£æ”¾ç½®ä»–們想è¦çš„任何信æ¯ã€‚debugfs文件系統也ä¸èƒ½ç”¨ä½œç©©å®šçš„ABI接å£ã€‚
從ç†è«–上講,debugfs導出文件的時候沒有任何約æŸã€‚但是[1]實際情æ³ä¸¦ä¸ç¸½æ˜¯é‚£éº¼
簡單。å³ä½¿æ˜¯debugfs接å£ï¼Œä¹Ÿæœ€å¥½æ ¹æ“šéœ€è¦é€²è¡Œè¨­è¨ˆ,並儘é‡ä¿æŒæŽ¥å£ä¸è®Šã€‚
@@ -34,8 +33,8 @@ Debugfs通常使用以下命令安è£::
mount -t debugfs none /sys/kernel/debug
(或等效的/etc/fstab行)。
-debugfs根目錄默èªåƒ…å¯ç”±root用戶訪å•ã€‚è¦æ›´æ”¹å°æ–‡ä»¶æ¨¹çš„訪å•ï¼Œè«‹ä½¿ç”¨ã€Œ uidã€ï¼Œã€Œ gidã€
-和「 modeã€æŽ›è¼‰é¸é …。請注æ„,debugfs API僅按照GPLå”議導出到模塊。
+debugfs根目錄默èªåƒ…å¯ç”±root用戶訪å•ã€‚è¦æ›´æ”¹å°æ–‡ä»¶æ¨¹çš„訪å•ï¼Œè«‹ä½¿ç”¨â€œ uidâ€ï¼Œâ€œ gidâ€
+和“ modeâ€æŽ›è¼‰é¸é …。請注æ„,debugfs API僅按照GPLå”議導出到模塊。
使用debugfs的代碼應包å«<linux/debugfs.h>。然後,首先是創建至少一個目錄來ä¿å­˜
一組debugfs文件::
@@ -54,8 +53,8 @@ debugfs根目錄默èªåƒ…å¯ç”±root用戶訪å•ã€‚è¦æ›´æ”¹å°æ–‡ä»¶æ¨¹çš„訪å•
struct dentry *parent, void *data,
const struct file_operations *fops);
-在這裡,name是è¦å‰µå»ºçš„文件的å稱,modeæ述了訪å•æ–‡ä»¶æ‡‰å…·æœ‰çš„權é™ï¼Œparent指å‘
-應該ä¿å­˜æ–‡ä»¶çš„目錄,data將存儲在產生的inodeçµæ§‹é«”çš„i_private欄ä½ä¸­ï¼Œè€Œfops是
+在這è£ï¼Œname是è¦å‰µå»ºçš„文件的å稱,modeæ述了訪å•æ–‡ä»¶æ‡‰å…·æœ‰çš„權é™ï¼Œparent指å‘
+應該ä¿å­˜æ–‡ä»¶çš„目錄,data將存儲在產生的inodeçµæ§‹é«”çš„i_private字段中,而fops是
一組文件æ“作函數,這些函數中實ç¾æ–‡ä»¶æ“作的具體行爲。至少,read()和/或
write()æ“作應æ供;其他å¯ä»¥æ ¹æ“šéœ€è¦åŒ…括在內。åŒæ¨£çš„,返回值將是指å‘創建文件
çš„dentry指é‡ï¼ŒéŒ¯èª¤æ™‚返回ERR_PTR(-ERROR),系統ä¸æ”¯æŒdebugfs時返回值爲ERR_PTR
@@ -81,7 +80,7 @@ file_size是åˆå§‹æ–‡ä»¶å¤§å°ã€‚其他åƒæ•¸è·Ÿå‡½æ•¸debugfs_create_file的相å
struct dentry *parent, u64 *value);
這些文件支æŒè®€å–和寫入給定值。如果æŸå€‹æ–‡ä»¶ä¸æ”¯æŒå¯«å…¥ï¼Œåªéœ€æ ¹æ“šéœ€è¦è¨­ç½®mode
-åƒæ•¸ä½ã€‚這些文件中的值以å進ä½è¡¨ç¤ºï¼›å¦‚果需è¦ä½¿ç”¨å六進ä½ï¼Œå¯ä»¥ä½¿ç”¨ä»¥ä¸‹å‡½æ•¸
+åƒæ•¸ä½ã€‚這些文件中的值以å進制表示;如果需è¦ä½¿ç”¨å六進制,å¯ä»¥ä½¿ç”¨ä»¥ä¸‹å‡½æ•¸
替代::
void debugfs_create_x8(const char *name, umode_t mode,
@@ -93,7 +92,7 @@ file_size是åˆå§‹æ–‡ä»¶å¤§å°ã€‚其他åƒæ•¸è·Ÿå‡½æ•¸debugfs_create_file的相å
void debugfs_create_x64(const char *name, umode_t mode,
struct dentry *parent, u64 *value);
-這些功能åªæœ‰åœ¨é–‹ç™¼äººå“¡çŸ¥é“導出值的大å°çš„時候æ‰æœ‰ç”¨ã€‚æŸäº›æ•¸æ“šé¡žåž‹åœ¨ä¸åŒçš„架構上
+這些功能åªæœ‰åœ¨é–‹ç™¼äººå“¡çŸ¥é“導出值的大å°çš„時候纔有用。æŸäº›æ•¸æ“šé¡žåž‹åœ¨ä¸åŒçš„架構上
有ä¸åŒçš„寬度,這樣會使情æ³è®Šå¾—有些複雜。在這種特殊情æ³ä¸‹å¯ä»¥ä½¿ç”¨ä»¥ä¸‹å‡½æ•¸::
void debugfs_create_size_t(const char *name, umode_t mode,
@@ -101,7 +100,7 @@ file_size是åˆå§‹æ–‡ä»¶å¤§å°ã€‚其他åƒæ•¸è·Ÿå‡½æ•¸debugfs_create_file的相å
ä¸å‡ºæ‰€æ–™ï¼Œæ­¤å‡½æ•¸å°‡å‰µå»ºä¸€å€‹debugfs文件來表示類型爲size_t的變é‡ã€‚
-åŒæ¨£åœ°ï¼Œä¹Ÿæœ‰å°Žå‡ºç„¡ç¬¦è™Ÿé•·æ•´åž‹è®Šé‡çš„函數,分別以å進ä½å’Œå六進ä½è¡¨ç¤ºå¦‚下::
+åŒæ¨£åœ°ï¼Œä¹Ÿæœ‰å°Žå‡ºç„¡ç¬¦è™Ÿé•·æ•´åž‹è®Šé‡çš„函數,分別以å進制和å六進制表示如下::
struct dentry *debugfs_create_ulong(const char *name, umode_t mode,
struct dentry *parent,
@@ -125,7 +124,7 @@ file_size是åˆå§‹æ–‡ä»¶å¤§å°ã€‚其他åƒæ•¸è·Ÿå‡½æ•¸debugfs_create_file的相å
讀å–此文件將ç²å¾—atomic_t值,寫入此文件將設置atomic_t值。
-å¦ä¸€å€‹é¸æ“‡æ˜¯é€šéŽä»¥ä¸‹çµæ§‹é«”和函數導出一個任æ„二進ä½æ•¸æ“šå¡Š::
+å¦ä¸€å€‹é¸æ“‡æ˜¯é€šéŽä»¥ä¸‹çµæ§‹é«”和函數導出一個任æ„二進制數據塊::
struct debugfs_blob_wrapper {
void *data;
@@ -136,10 +135,10 @@ file_size是åˆå§‹æ–‡ä»¶å¤§å°ã€‚其他åƒæ•¸è·Ÿå‡½æ•¸debugfs_create_file的相å
struct dentry *parent,
struct debugfs_blob_wrapper *blob);
-讀å–此文件將返回由指é‡æŒ‡å‘debugfs_blob_wrapperçµæ§‹é«”的數據。一些驅動使用「blobsã€
-作爲一種返回幾行(éœæ…‹ï¼‰æ ¼å¼åŒ–文本的簡單方法。這個函數å¯ç”¨æ–¼å°Žå‡ºäºŒé€²ä½ä¿¡æ¯ï¼Œä½†
+讀å–此文件將返回由指é‡æŒ‡å‘debugfs_blob_wrapperçµæ§‹é«”的數據。一些驅動使用“blobsâ€
+作爲一種返回幾行(éœæ…‹ï¼‰æ ¼å¼åŒ–文本的簡單方法。這個函數å¯ç”¨æ–¼å°Žå‡ºäºŒé€²åˆ¶ä¿¡æ¯ï¼Œä½†
似乎在主線中沒有任何代碼這樣åšã€‚請注æ„,使用debugfs_create_blob()命令創建的
-所有文件是åªè®€çš„。
+所有文件是隻讀的。
如果您è¦è½‰å„²ä¸€å€‹å¯„存器塊(在開發éŽç¨‹ä¸­ç¶“常會這麼åšï¼Œä½†æ˜¯é€™æ¨£çš„調試代碼很少上傳
到主線中。Debugfsæ供兩個函數:一個用於創建僅寄存器文件,å¦ä¸€å€‹æŠŠä¸€å€‹å¯„存器塊
@@ -163,7 +162,7 @@ file_size是åˆå§‹æ–‡ä»¶å¤§å°ã€‚其他åƒæ•¸è·Ÿå‡½æ•¸debugfs_create_file的相å
void debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs,
int nregs, void __iomem *base, char *prefix);
-「baseã€åƒæ•¸å¯èƒ½çˆ²0,但您å¯èƒ½éœ€è¦ä½¿ç”¨__stringify構建reg32數組,實際上有許多寄存器
+“baseâ€åƒæ•¸å¯èƒ½çˆ²0,但您å¯èƒ½éœ€è¦ä½¿ç”¨__stringify構建reg32數組,實際上有許多寄存器
å稱(å®ï¼‰æ˜¯å¯„存器塊在基å€ä¸Šçš„字節å移é‡ã€‚
如果è¦åœ¨debugfs中轉儲u32數組,å¯ä»¥ä½¿ç”¨ä»¥ä¸‹å‡½æ•¸å‰µå»ºæ–‡ä»¶::
@@ -172,7 +171,7 @@ file_size是åˆå§‹æ–‡ä»¶å¤§å°ã€‚其他åƒæ•¸è·Ÿå‡½æ•¸debugfs_create_file的相å
struct dentry *parent,
u32 *array, u32 elements);
-「arrayã€åƒæ•¸æ供數據,而「elementsã€åƒæ•¸çˆ²æ•¸çµ„中元素的數é‡ã€‚注æ„:數組創建後,數組
+“arrayâ€åƒæ•¸æ供數據,而“elementsâ€åƒæ•¸çˆ²æ•¸çµ„中元素的數é‡ã€‚注æ„:數組創建後,數組
大å°ç„¡æ³•æ›´æ”¹ã€‚
有一個函數來創建與設備相關的seq_file::
@@ -183,8 +182,8 @@ file_size是åˆå§‹æ–‡ä»¶å¤§å°ã€‚其他åƒæ•¸è·Ÿå‡½æ•¸debugfs_create_file的相å
int (*read_fn)(struct seq_file *s,
void *data));
-「devã€åƒæ•¸æ˜¯èˆ‡æ­¤debugfs文件相關的設備,並且「read_fnã€æ˜¯ä¸€å€‹å‡½æ•¸æŒ‡é‡ï¼Œé€™å€‹å‡½æ•¸åœ¨
-列å°seq_file內容的時候被回調。
+“devâ€åƒæ•¸æ˜¯èˆ‡æ­¤debugfs文件相關的設備,並且“read_fnâ€æ˜¯ä¸€å€‹å‡½æ•¸æŒ‡é‡ï¼Œé€™å€‹å‡½æ•¸åœ¨
+打å°seq_file內容的時候被回調。
還有一些其他的é¢å‘目錄的函數::
@@ -199,7 +198,7 @@ file_size是åˆå§‹æ–‡ä»¶å¤§å°ã€‚其他åƒæ•¸è·Ÿå‡½æ•¸debugfs_create_file的相å
調用debugfs_rename()將爲ç¾æœ‰çš„debugfs文件é‡å‘½å,å¯èƒ½åŒæ™‚切æ›ç›®éŒ„。 new_name
函數調用之å‰ä¸èƒ½å­˜åœ¨ï¼›è¿”回值爲old_dentry,其中包å«æ›´æ–°çš„ä¿¡æ¯ã€‚å¯ä»¥ä½¿ç”¨
-debugfs_create_symlink()創建符號連çµã€‚
+debugfs_create_symlink()創建符號éˆæŽ¥ã€‚
所有debugfs用戶必須考慮的一件事是:
@@ -219,6 +218,6 @@ dentry值å¯ä»¥çˆ²NULL或錯誤值,在這種情æ³ä¸‹ï¼Œä¸æœƒæœ‰ä»»ä½•æ–‡ä»¶è
如果將å°æ‡‰é ‚層目錄的dentry傳éžçµ¦ä»¥ä¸Šå‡½æ•¸ï¼Œå‰‡è©²ç›®éŒ„下的整個層次çµæ§‹å°‡æœƒè¢«åˆªé™¤ã€‚
-注釋:
+註釋:
[1] http://lwn.net/Articles/309298/
diff --git a/Documentation/translations/zh_TW/filesystems/index.rst b/Documentation/translations/zh_TW/filesystems/index.rst
index 789e742fa3c5..d7f9d61f654c 100644
--- a/Documentation/translations/zh_TW/filesystems/index.rst
+++ b/Documentation/translations/zh_TW/filesystems/index.rst
@@ -12,7 +12,7 @@
Linux Kernel中的文件系統
========================
-這份正在開發的手冊或許在未來æŸå€‹è¼ç…Œçš„æ—¥å­è£¡ä»¥æ˜“懂的形å¼å°‡Linux虛擬\
+這份正在開發的手冊或許在未來æŸå€‹è¼ç…Œçš„æ—¥å­è£ä»¥æ˜“懂的形å¼å°‡Linux虛擬\
文件系統(VFS)層以åŠåŸºæ–¼å…¶ä¸Šçš„å„種文件系統如何工作呈ç¾çµ¦å¤§å®¶ã€‚當å‰\
å¯ä»¥çœ‹åˆ°ä¸‹é¢çš„內容。
diff --git a/Documentation/translations/zh_TW/filesystems/sysfs.txt b/Documentation/translations/zh_TW/filesystems/sysfs.txt
index a84eba2af9d3..ebe90651fc3b 100644
--- a/Documentation/translations/zh_TW/filesystems/sysfs.txt
+++ b/Documentation/translations/zh_TW/filesystems/sysfs.txt
@@ -61,7 +61,7 @@ Documentation/core-api/kobject.rst 文檔以ç²å¾—更多關於 kobject 接å£çš„
任何 kobject 在系統中註冊,就會有一個目錄在 sysfs 中被創建。這個
目錄是作爲該 kobject 的父å°è±¡æ‰€åœ¨ç›®éŒ„çš„å­ç›®éŒ„創建的,以準確地傳éž
-內核的å°è±¡å±¤æ¬¡åˆ°ç”¨æˆ¶ç©ºé–“。sysfs 中的頂層目錄代表著內核å°è±¡å±¤æ¬¡çš„
+內核的å°è±¡å±¤æ¬¡åˆ°ç”¨æˆ¶ç©ºé–“。sysfs 中的頂層目錄代表ç€å…§æ ¸å°è±¡å±¤æ¬¡çš„
å…±åŒç¥–先;例如:æŸäº›å°è±¡å±¬æ–¼æŸå€‹å­ç³»çµ±ã€‚
Sysfs 在與其目錄關è¯çš„ kernfs_node å°è±¡ä¸­å…§éƒ¨ä¿å­˜ä¸€å€‹æŒ‡å‘實ç¾
@@ -198,7 +198,7 @@ Sysfs 將會爲æ¯æ¬¡è®€å¯«æ“作調用一次這個方法。這使得這些方æ³
ä¸æœƒä¸å¤ªé«˜ã€‚
這使得用戶空間å¯ä»¥å±€éƒ¨åœ°è®€å’Œä»»æ„çš„å‘å‰æœç´¢æ•´å€‹æ–‡ä»¶ã€‚如果用戶空間
- å‘後æœç´¢åˆ°é›¶æˆ–使用『0ã€å移執行一個pread(2)æ“作,show()方法將
+ å‘後æœç´¢åˆ°é›¶æˆ–使用‘0’å移執行一個pread(2)æ“作,show()方法將
å†æ¬¡è¢«èª¿ç”¨ï¼Œä»¥é‡æ–°å¡«å……緩存。
- 在寫方é¢ï¼ˆwrite(2)),sysfs 希望在第一次寫æ“作時得到整個緩è¡å€ã€‚
@@ -253,7 +253,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);
(注æ„:真正的實ç¾ä¸å…許用戶空間設置設備å。)
-頂層目錄布局
+頂層目錄佈局
~~~~~~~~~~~~
sysfs 目錄的安排顯示了內核數據çµæ§‹ä¹‹é–“的關係。
@@ -272,23 +272,23 @@ fs/
devices/ 包å«äº†ä¸€å€‹è¨­å‚™æ¨¹çš„文件系統表示。他直接映射了內部的內核
設備樹,å映了設備的層次çµæ§‹ã€‚
-bus/ 包å«äº†å…§æ ¸ä¸­å„種總線類型的平é¢ç›®éŒ„布局。æ¯å€‹ç¸½ç·šç›®éŒ„包å«å…©å€‹
+bus/ 包å«äº†å…§æ ¸ä¸­å„種總線類型的平é¢ç›®éŒ„佈局。æ¯å€‹ç¸½ç·šç›®éŒ„包å«å…©å€‹
å­ç›®éŒ„:
devices/
drivers/
-devices/ 包å«äº†ç³»çµ±ä¸­å‡ºç¾çš„æ¯å€‹è¨­å‚™çš„符號連çµï¼Œä»–å€‘æŒ‡å‘ root/ 下的
+devices/ 包å«äº†ç³»çµ±ä¸­å‡ºç¾çš„æ¯å€‹è¨­å‚™çš„符號éˆæŽ¥ï¼Œä»–å€‘æŒ‡å‘ root/ 下的
設備目錄。
-drivers/ 包å«äº†æ¯å€‹å·²çˆ²ç‰¹å®šç¸½ç·šä¸Šçš„設備而掛載的驅動程åºçš„目錄(這裡
+drivers/ 包å«äº†æ¯å€‹å·²çˆ²ç‰¹å®šç¸½ç·šä¸Šçš„設備而掛載的驅動程åºçš„目錄(這è£
å‡å®šé©…動沒有跨越多個總線類型)。
fs/ 包å«äº†ä¸€å€‹çˆ²æ–‡ä»¶ç³»çµ±è¨­ç«‹çš„目錄。ç¾åœ¨æ¯å€‹æƒ³è¦å°Žå‡ºå±¬æ€§çš„文件系統必須
在 fs/ 下創建自己的層次çµæ§‹(åƒè¦‹Documentation/filesystems/fuse.rst)。
dev/ 包å«å…©å€‹å­ç›®éŒ„: char/ å’Œ block/。在這兩個å­ç›®éŒ„中,有以
-<major>:<minor> æ ¼å¼å‘½å的符號連çµã€‚這些符號連çµæŒ‡å‘ sysfs 目錄
+<major>:<minor> æ ¼å¼å‘½å的符號éˆæŽ¥ã€‚這些符號éˆæŽ¥æŒ‡å‘ sysfs 目錄
中相應的設備。/sys/dev æ供一個通éŽä¸€å€‹ stat(2) æ“作çµæžœï¼ŒæŸ¥æ‰¾
設備 sysfs 接å£å¿«æ·çš„方法。
diff --git a/Documentation/translations/zh_TW/filesystems/tmpfs.rst b/Documentation/translations/zh_TW/filesystems/tmpfs.rst
index 2c8439b2b77e..aed61cc3064d 100644
--- a/Documentation/translations/zh_TW/filesystems/tmpfs.rst
+++ b/Documentation/translations/zh_TW/filesystems/tmpfs.rst
@@ -4,8 +4,7 @@
:Original: Documentation/filesystems/tmpfs.rst
-Translated by Wang Qing <wangqing@vivo.com>
-and Hu Haowen <src.res.211@gmail.com>
+translated by Wang Qing<wangqing@vivo.com>
=====
Tmpfs
@@ -13,18 +12,18 @@ Tmpfs
Tmpfs是一個將所有文件都ä¿å­˜åœ¨è™›æ“¬å…§å­˜ä¸­çš„文件系統。
-tmpfs中的所有內容都是臨時的,也就是說沒有任何文件會在硬碟上創建。
+tmpfs中的所有內容都是臨時的,也就是說沒有任何文件會在硬盤上創建。
如果å¸è¼‰tmpfs實例,所有ä¿å­˜åœ¨å…¶ä¸­çš„文件都會丟失。
-tmpfs將所有文件ä¿å­˜åœ¨å…§æ ¸ç·©å­˜ä¸­ï¼Œéš¨è‘—文件內容增長或縮å°å¯ä»¥å°‡ä¸éœ€è¦çš„
-é é¢swap出去。它具有最大é™åˆ¶ï¼Œå¯ä»¥é€šéŽã€Œmount -o remount ...ã€èª¿æ•´ã€‚
+tmpfs將所有文件ä¿å­˜åœ¨å…§æ ¸ç·©å­˜ä¸­ï¼Œéš¨ç€æ–‡ä»¶å…§å®¹å¢žé•·æˆ–縮å°å¯ä»¥å°‡ä¸éœ€è¦çš„
+é é¢swap出去。它具有最大é™åˆ¶ï¼Œå¯ä»¥é€šéŽâ€œmount -o remount ...â€èª¿æ•´ã€‚
å’Œramfs(創建tmpfs的模æ¿ï¼‰ç›¸æ¯”,tmpfs包å«äº¤æ›å’Œé™åˆ¶æª¢æŸ¥ã€‚å’Œtmpfs相似的å¦
-一個æ±è¥¿æ˜¯RAMç£ç¢Ÿï¼ˆ/dev/ram*),å¯ä»¥åœ¨ç‰©ç†RAM中模擬固定大å°çš„硬碟,並在
+一個æ±è¥¿æ˜¯RAMç£ç›¤ï¼ˆ/dev/ram*),å¯ä»¥åœ¨ç‰©ç†RAM中模擬固定大å°çš„硬盤,並在
此之上創建一個普通的文件系統。Ramdisks無法swap,因此無法調整它們的大å°ã€‚
由於tmpfs完全ä¿å­˜æ–¼é é¢ç·©å­˜å’Œswap中,因此所有tmpfsé é¢å°‡åœ¨/proc/meminfo
-中顯示爲「Shmemã€ï¼Œè€Œåœ¨free(1)中顯示爲「Sharedã€ã€‚請注æ„,這些計數還包括
+中顯示爲“Shmemâ€ï¼Œè€Œåœ¨free(1)中顯示爲“Sharedâ€ã€‚請注æ„,這些計數還包括
共享內存(shmem,請åƒé–±ipcs(1))。ç²å¾—計數的最å¯é æ–¹æ³•æ˜¯ä½¿ç”¨df(1)å’Œdu(1)。
tmpfs具有以下用途:
@@ -45,7 +44,7 @@ tmpfs具有以下用途:
tmpfsçš„å‰èº«(shm fs)æ‰èƒ½ä½¿ç”¨SYSV共享內存)
3) 很多人(包括我)都覺的在/tmpå’Œ/var/tmp上掛載éžå¸¸æ–¹ä¾¿ï¼Œä¸¦å…·æœ‰è¼ƒå¤§çš„
- swap分å€ã€‚ç›®å‰å¾ªç’°æŽ›è¼‰tmpfså¯ä»¥æ­£å¸¸å·¥ä½œï¼Œæ‰€ä»¥å¤§å¤šæ•¸ç™¼å¸ƒéƒ½æ‡‰ç•¶å¯ä»¥
+ swap分å€ã€‚ç›®å‰å¾ªç’°æŽ›è¼‰tmpfså¯ä»¥æ­£å¸¸å·¥ä½œï¼Œæ‰€ä»¥å¤§å¤šæ•¸ç™¼ä½ˆéƒ½æ‡‰ç•¶å¯ä»¥
使用mkinitrd通éŽ/tmp訪å•/tmp。
4) 也許還有更多我ä¸çŸ¥é“的地方:-)
@@ -58,11 +57,11 @@ size tmpfs實例分é…的字節數é™åˆ¶ã€‚默èªå€¼æ˜¯ä¸swap時物ç†RAM
如果tmpfs實例éŽå¤§ï¼Œæ©Ÿå™¨å°‡æ­»éŽ–,因爲OOM處ç†å°‡ç„¡æ³•é‡‹æ”¾è©²å…§å­˜ã€‚
nr_blocks 與size相åŒï¼Œä½†ä»¥PAGE_SIZE爲單ä½ã€‚
nr_inodes tmpfs實例的最大inode個數。默èªå€¼æ˜¯ç‰©ç†å…§å­˜é æ•¸çš„一åŠï¼Œæˆ–者
- (有高端內存的機器)低端內存RAMçš„é æ•¸ï¼ŒäºŒè€…以較低者為準。
+ (有高端內存的機器)低端內存RAMçš„é æ•¸ï¼ŒäºŒè€…以較低者爲準。
========= ===========================================================
這些åƒæ•¸æŽ¥å—後綴k,m或g表示åƒï¼Œå…†å’Œåƒå…†å­—節,å¯ä»¥åœ¨remount時更改。
-sizeåƒæ•¸ä¹ŸæŽ¥å—後綴%用來é™åˆ¶tmpfs實例å ç”¨ç‰©ç†RAM的百分比:
+sizeåƒæ•¸ä¹ŸæŽ¥å—後綴%用來é™åˆ¶tmpfs實例佔用物ç†RAM的百分比:
未指定size或nr_blocks時,默èªå€¼çˆ²size=50ï¼…
如果nr_blocks=0(或size=0),block個數將ä¸å—é™åˆ¶ï¼›å¦‚æžœnr_inodes=0,
@@ -71,26 +70,26 @@ inode個數將ä¸å—é™åˆ¶ã€‚這樣掛載通常是ä¸æ˜Žæ™ºçš„,因爲它å…許
場景下的訪å•ã€‚
tmpfs具有爲所有文件設置NUMA內存分é…策略掛載é¸é …(如果啓用了CONFIG_NUMA),
-å¯ä»¥é€šéŽã€Œmount -o remount ...ã€èª¿æ•´
+å¯ä»¥é€šéŽâ€œmount -o remount ...â€èª¿æ•´
======================== =========================
mpol=default 採用進程分é…ç­–ç•¥
(è«‹åƒé–± set_mempolicy(2))
mpol=prefer:Node 傾å‘從給定的節點分é…
-mpol=bind:NodeList åªå…許從指定的éŠè¡¨åˆ†é…
+mpol=bind:NodeList åªå…許從指定的éˆè¡¨åˆ†é…
mpol=interleave 傾å‘æ–¼ä¾æ¬¡å¾žæ¯å€‹ç¯€é»žåˆ†é…
mpol=interleave:NodeList ä¾æ¬¡å¾žæ¯å€‹ç¯€é»žåˆ†é…
mpol=local 優先本地節點分é…內存
======================== =========================
-NodeListæ ¼å¼æ˜¯ä»¥é€—號分隔的å進ä½æ•¸å­—表示大å°å’Œç¯„åœï¼Œæœ€å¤§å’Œæœ€å°ç¯„åœæ˜¯ç”¨-
-分隔符的å進ä½æ•¸ä¾†è¡¨ç¤ºã€‚例如,mpol=bind0-3,5,7,9-15
+NodeListæ ¼å¼æ˜¯ä»¥é€—號分隔的å進制數字表示大å°å’Œç¯„åœï¼Œæœ€å¤§å’Œæœ€å°ç¯„åœæ˜¯ç”¨-
+分隔符的å進制數來表示。例如,mpol=bind0-3,5,7,9-15
帶有有效NodeList的內存策略將按指定格å¼ä¿å­˜ï¼Œåœ¨å‰µå»ºæ–‡ä»¶æ™‚使用。當任務在該
文件系統上創建文件時,會使用到掛載時的內存策略NodeListé¸é …,如果設置的話,
由調用任務的cpuset[è«‹åƒè¦‹Documentation/admin-guide/cgroup-v1/cpusets.rst]
以åŠä¸‹é¢åˆ—出的å¯é¸æ¨™èªŒç´„æŸã€‚如果NodeLists爲設置爲空集,則文件的內存策略將
-æ¢å¾©çˆ²ã€Œé»˜èªã€ç­–略。
+æ¢å¾©çˆ²â€œé»˜èªâ€ç­–略。
NUMA內存分é…策略有å¯é¸æ¨™èªŒï¼Œå¯ä»¥ç”¨æ–¼æ¨¡å¼çµåˆã€‚在掛載tmpfs時指定這些å¯é¸
標誌å¯ä»¥åœ¨NodeList之å‰ç”Ÿæ•ˆã€‚
@@ -107,12 +106,12 @@ Documentation/admin-guide/mm/numa_memory_policy.rst列出所有å¯ç”¨çš„內存
請注æ„,如果內核ä¸æ”¯æŒNUMA,那麼使用mpolé¸é …掛載tmpfs將會失敗;nodelist指定ä¸
在線的節點也會失敗。如果您的系統ä¾è³´æ–¼æ­¤ï¼Œä½†å…§æ ¸æœƒé‹è¡Œä¸å¸¶NUMA功能(也許是安全
revocery內核),或者具有較少的節點在線,建議從自動模å¼ä¸­çœç•¥mpolé¸é …掛載é¸é …。
-å¯ä»¥åœ¨ä»¥å¾Œé€šéŽã€Œmount -o remount,mpol=Policy:NodeList MountPointã€æ·»åŠ åˆ°æŽ›è¼‰é»žã€‚
+å¯ä»¥åœ¨ä»¥å¾Œé€šéŽâ€œmount -o remount,mpol=Policy:NodeList MountPointâ€æ·»åŠ åˆ°æŽ›è¼‰é»žã€‚
è¦æŒ‡å®šåˆå§‹æ ¹ç›®éŒ„,å¯ä»¥ä½¿ç”¨å¦‚下掛載é¸é …:
==== ====================
-æ¨¡å¼ æ¬Šé™ç”¨å…«é€²ä½æ•¸å­—表示
+æ¨¡å¼ æ¬Šé™ç”¨å…«é€²åˆ¶æ•¸å­—表示
uid 用戶ID
gid 組ID
==== ====================
@@ -129,7 +128,7 @@ inode32 使用32ä½inode
在32ä½å…§æ ¸ä¸Šï¼Œé»˜èªæ˜¯inode32,掛載時指定inode64會被拒絕。
在64ä½å…§æ ¸ä¸Šï¼Œé»˜èªé…置是CONFIG_TMPFS_INODE64。inode64é¿å…了單個設備上å¯èƒ½æœ‰å¤šå€‹
-具有相åŒinode編號的文件;比如32ä½æ‡‰ç”¨ç¨‹å¼ä½¿ç”¨glibc如果長期訪å•tmpfs,一旦é”到33
+具有相åŒinode編號的文件;比如32ä½æ‡‰ç”¨ç¨‹åºä½¿ç”¨glibc如果長期訪å•tmpfs,一旦é”到33
ä½inode編號,就有EOVERFLOW失敗的å±éšªï¼Œç„¡æ³•æ‰“開大於2GiB的文件,並返回EINVAL。
所以'mount -t tmpfs -o size=10G,nr_inodes=10k,mode=700 tmpfs /mytmpfs'將在
diff --git a/Documentation/translations/zh_TW/filesystems/virtiofs.rst b/Documentation/translations/zh_TW/filesystems/virtiofs.rst
index 086fce5839dd..6150ad964e78 100644
--- a/Documentation/translations/zh_TW/filesystems/virtiofs.rst
+++ b/Documentation/translations/zh_TW/filesystems/virtiofs.rst
@@ -10,7 +10,6 @@
中文版維護者: 王文虎 Wang Wenhu <wenhu.wang@vivo.com>
中文版翻譯者: 王文虎 Wang Wenhu <wenhu.wang@vivo.com>
中文版校譯者: 王文虎 Wang Wenhu <wenhu.wang@vivo.com>
- 中文版校譯者: 王文虎 Wang Wenhu <wenhu.wang@vivo.com>
ç¹é«”中文版校譯者:胡皓文 Hu Haowen <src.res.211@gmail.com>
===========================================
@@ -21,7 +20,7 @@ virtiofs: virtio-fs 主機<->客機共享文件系統
介紹
====
-Linuxçš„virtiofs文件系統實ç¾äº†ä¸€å€‹åŠè™›æ“¬åŒ–VIRTIO類型「virtio-fsã€è¨­å‚™çš„驅動,通éŽè©²\
+Linuxçš„virtiofs文件系統實ç¾äº†ä¸€å€‹åŠè™›æ“¬åŒ–VIRTIO類型“virtio-fsâ€è¨­å‚™çš„驅動,通éŽè©²\
類型設備實ç¾å®¢æ©Ÿ<->主機文件系統共享。它å…許客機掛載一個已經導出到主機的目錄。
客機通常需è¦è¨ªå•ä¸»æ©Ÿæˆ–者é ç¨‹ç³»çµ±ä¸Šçš„文件。使用場景包括:在新客機安è£æ™‚讓文件å°å…¶\
@@ -42,12 +41,12 @@ Linuxçš„virtiofs文件系統實ç¾äº†ä¸€å€‹åŠè™›æ“¬åŒ–VIRTIO類型「virtio-fsã
guest# mount -t virtiofs myfs /mnt
-請查閱 https://virtio-fs.gitlab.io/ 了解é…ç½®QEMUå’Œvirtiofsd守護程åºçš„詳細信æ¯ã€‚
+請查閱 https://virtio-fs.gitlab.io/ 瞭解é…ç½®QEMUå’Œvirtiofsd守護程åºçš„詳細信æ¯ã€‚
內幕
====
由於virtio-fs設備將FUSEå”議用於文件系統請求,因此Linuxçš„virtiofs文件系統與FUSEæ–‡\
-件系統客戶端緊密集æˆåœ¨ä¸€èµ·ã€‚客機充當FUSE客戶端而主機充當FUSE伺æœå™¨ï¼Œå…§æ ¸èˆ‡ç”¨æˆ¶ç©º\
+件系統客戶端緊密集æˆåœ¨ä¸€èµ·ã€‚客機充當FUSE客戶端而主機充當FUSEæœå‹™å™¨ï¼Œå…§æ ¸èˆ‡ç”¨æˆ¶ç©º\
間之間的/dev/fuse接å£ç”±virtio-fs設備接å£ä»£æ›¿ã€‚
FUSE請求被置於虛擬隊列中由主機處ç†ã€‚主機填充緩è¡å€ä¸­çš„響應部分,而客機處ç†è«‹æ±‚的完æˆéƒ¨åˆ†ã€‚
@@ -55,7 +54,7 @@ FUSE請求被置於虛擬隊列中由主機處ç†ã€‚主機填充緩è¡å€ä¸­çš„é
å°‡/dev/fuse映射到虛擬隊列需è¦è§£æ±º/dev/fuse和虛擬隊列之間語義上的差異。æ¯æ¬¡è®€å–\
/dev/fuse設備時,FUSE客戶端都å¯ä»¥é¸æ“‡è¦å‚³è¼¸çš„請求,從而å¯ä»¥ä½¿æŸäº›è«‹æ±‚優先於其他\
請求。虛擬隊列有其隊列語義,無法更改已入隊請求的順åºã€‚在虛擬隊列已滿的情æ³ä¸‹å°¤
-其關éµï¼Œå› çˆ²æ­¤æ™‚ä¸å¯èƒ½åŠ å…¥é«˜å„ªå…ˆç´šçš„請求。爲了解決此差異,virtio-fs設備採用「hiprioã€\
+其關éµï¼Œå› çˆ²æ­¤æ™‚ä¸å¯èƒ½åŠ å…¥é«˜å„ªå…ˆç´šçš„請求。爲了解決此差異,virtio-fs設備採用“hiprioâ€\
(高優先級)虛擬隊列,專門用於有別於普通請求的高優先級請求。
diff --git a/Documentation/translations/zh_TW/index.rst b/Documentation/translations/zh_TW/index.rst
index d1cf0b4d8e46..563ac9bfc66b 100644
--- a/Documentation/translations/zh_TW/index.rst
+++ b/Documentation/translations/zh_TW/index.rst
@@ -55,11 +55,11 @@ TODOList:
:maxdepth: 1
process/license-rules
+ dev-tools/index
TODOList:
* doc-guide/index
-* dev-tools/index
* dev-tools/testing-overview
* kernel-hacking/index
* rust/index
@@ -101,9 +101,10 @@ TODOList:
體系çµæ§‹æ–‡æª”
------------
-TODOList:
+.. toctree::
+ :maxdepth: 1
-* arch/index
+ arch/index
其他文檔
--------
diff --git a/Documentation/translations/zh_TW/process/1.Intro.rst b/Documentation/translations/zh_TW/process/1.Intro.rst
index f236fe95a6c6..6e754ac48964 100644
--- a/Documentation/translations/zh_TW/process/1.Intro.rst
+++ b/Documentation/translations/zh_TW/process/1.Intro.rst
@@ -22,12 +22,12 @@
--------
本節的其餘部分涵蓋了內核開發的éŽç¨‹ï¼Œä»¥åŠé–‹ç™¼äººå“¡åŠå…¶åƒ±ä¸»åœ¨é€™æ–¹é¢å¯èƒ½é‡åˆ°çš„
-å„種å•é¡Œã€‚有很多原因使內核代碼應被åˆä½µåˆ°æ­£å¼çš„(「主線ã€ï¼‰å…§æ ¸ä¸­ï¼ŒåŒ…括å°ç”¨æˆ¶
+å„種å•é¡Œã€‚有很多原因使內核代碼應被åˆä½µåˆ°æ­£å¼çš„(“主線â€ï¼‰å…§æ ¸ä¸­ï¼ŒåŒ…括å°ç”¨æˆ¶
的自動å¯ç”¨æ€§ã€å¤šç¨®å½¢å¼çš„社å€æ”¯æŒä»¥åŠå½±éŸ¿å…§æ ¸é–‹ç™¼æ–¹å‘的能力。æ供給Linux內核
的代碼必須在與GPL兼容的許å¯è­‰ä¸‹å¯ç”¨ã€‚
-:ref:`tw_development_process` 介紹了開發éŽç¨‹ã€å…§æ ¸ç™¼å¸ƒå‘¨æœŸå’Œåˆä½µçª—å£çš„機制。
-涵蓋了補ä¸é–‹ç™¼ã€å¯©æŸ¥å’Œåˆä½µå‘¨æœŸä¸­çš„å„個階段。還有一些關於工具和郵件列表的討論?
+:ref:`tw_development_process` 介紹了開發éŽç¨‹ã€å…§æ ¸ç™¼ä½ˆé€±æœŸå’Œåˆä¸¦çª—å£çš„機制。
+涵蓋了補ä¸é–‹ç™¼ã€å¯©æŸ¥å’Œåˆä¸¦é€±æœŸä¸­çš„å„個階段。還有一些關於工具和郵件列表的討論?
鼓勵希望開始內核開發的開發人員跟蹤並修復缺陷以作爲åˆæ­¥ç·´ç¿’。
@@ -38,39 +38,39 @@
陷阱。也涵蓋了å°è£œä¸çš„一些è¦æ±‚,並且介紹了一些工具,這些工具有助於確ä¿å…§æ ¸
補ä¸æ˜¯æ­£ç¢ºçš„。
-:ref:`tw_development_posting` æ述發布補ä¸ä»¥ä¾›è©•å¯©çš„éŽç¨‹ã€‚爲了讓開發社å€èƒ½
+:ref:`tw_development_posting` æ述發佈補ä¸ä»¥ä¾›è©•å¯©çš„éŽç¨‹ã€‚爲了讓開發社å€èƒ½
èªçœŸå°å¾…,補ä¸å¿…須被正確格å¼åŒ–å’Œæ述,並且必須發é€åˆ°æ­£ç¢ºçš„地方。éµå¾ªæœ¬ç¯€ä¸­çš„
建議有助於確ä¿æ‚¨çš„工作能被較好地接ç´ã€‚
-:ref:`tw_development_followthrough` 介紹了發布補ä¸ä¹‹å¾Œç™¼ç”Ÿçš„事情;工作在這時
+:ref:`tw_development_followthrough` 介紹了發佈補ä¸ä¹‹å¾Œç™¼ç”Ÿçš„事情;工作在這時
é‚„é é æ²’有完æˆã€‚與審閱者一起工作是開發éŽç¨‹ä¸­çš„一個é‡è¦éƒ¨åˆ†ï¼›æœ¬ç¯€æ供了一些
關於如何在這個é‡è¦éšŽæ®µé¿å…å•é¡Œçš„æ示。當補ä¸è¢«åˆä½µåˆ°ä¸»ç·šä¸­æ™‚,開發人員è¦æ³¨æ„
ä¸è¦å‡å®šä»»å‹™å·²ç¶“完æˆã€‚
-:ref:`tw_development_advancedtopics` 介紹了兩個「高級ã€ä¸»é¡Œï¼šä½¿ç”¨Git管ç†è£œä¸
-和查看其他人發布的補ä¸ã€‚
+:ref:`tw_development_advancedtopics` 介紹了兩個“高級â€ä¸»é¡Œï¼šä½¿ç”¨Git管ç†è£œä¸
+和查看其他人發佈的補ä¸ã€‚
:ref:`tw_development_conclusion` 總çµäº†æœ‰é—œå…§æ ¸é–‹ç™¼çš„更多信æ¯ï¼Œé™„帶有相關資æº
-連çµã€‚
+éˆæŽ¥ã€‚
這個文檔是關於什麼的
--------------------
Linux內核有超éŽ800è¬è¡Œä»£ç¢¼ï¼Œæ¯å€‹ç‰ˆæœ¬çš„è²¢ç»è€…超éŽ1000人,是ç¾å­˜æœ€å¤§ã€æœ€æ´»èºçš„
-å…費軟體項目之一。從1991年開始,這個內核已經發展æˆçˆ²ä¸€å€‹æœ€å¥½çš„作業系統組件,
-é‹è¡Œåœ¨è¢–ç數ä½éŸ³æ¨‚播放器ã€æ¡Œä¸Šåž‹é›»è…¦ã€ç¾å­˜æœ€å¤§çš„超級計算機以åŠæ‰€æœ‰é¡žåž‹çš„系統上。
+å…費軟件項目之一。從1991年開始,這個內核已經發展æˆçˆ²ä¸€å€‹æœ€å¥½çš„æ“作系統組件,
+é‹è¡Œåœ¨è¢–ç數字音樂播放器ã€è‡ºå¼é›»è…¦ã€ç¾å­˜æœ€å¤§çš„超級計算機以åŠæ‰€æœ‰é¡žåž‹çš„系統上。
它是一種é©ç”¨æ–¼å¹¾ä¹Žä»»ä½•æƒ…æ³çš„å¥å£¯ã€é«˜æ•ˆå’Œå¯æ“´å±•çš„解決方案。
-隨著Linux的發展,希望åƒèˆ‡å…¶é–‹ç™¼çš„開發人員(和公å¸ï¼‰çš„數é‡ä¹Ÿåœ¨å¢žåŠ ã€‚硬體供應商
+隨ç€Linux的發展,希望åƒèˆ‡å…¶é–‹ç™¼çš„開發人員(和公å¸ï¼‰çš„數é‡ä¹Ÿåœ¨å¢žåŠ ã€‚硬件供應商
希望確ä¿Linux能夠很好地支æŒä»–們的產å“,使這些產å“å°Linux用戶具有å¸å¼•åŠ›ã€‚嵌入
å¼ç³»çµ±ä¾›æ‡‰å•†ä½¿ç”¨Linux作爲集æˆç”¢å“的組件,希望Linux能夠儘å¯èƒ½åœ°å‹ä»»æ‰‹é ­çš„任務。
-分銷商和其他基於Linux的軟體供應商切實關心Linux內核的功能ã€æ€§èƒ½å’Œå¯é æ€§ã€‚最終
+分銷商和其他基於Linux的軟件供應商切實關心Linux內核的功能ã€æ€§èƒ½å’Œå¯é æ€§ã€‚最終
用戶也常常希望修改Linux,使之能更好地滿足他們的需求。
Linux最引人注目的特性之一是這些開發人員å¯ä»¥è¨ªå•å®ƒï¼›ä»»ä½•å…·å‚™å¿…è¦æŠ€èƒ½çš„人都å¯ä»¥
-改進Linux並影響其開發方å‘。專有產å“ä¸èƒ½æ供這種開放性,這是自由軟體的一個特點。
-如果有什麼ä¸åŒçš„話,那就是內核比大多數其他自由軟體項目更開放。一個典型的三個
-月內核開發周期å¯ä»¥æ¶‰åŠ1000多個開發人員,他們爲100多個ä¸åŒçš„å…¬å¸ï¼ˆæˆ–者根本ä¸
+改進Linux並影響其開發方å‘。專有產å“ä¸èƒ½æ供這種開放性,這是自由軟件的一個特點。
+如果有什麼ä¸åŒçš„話,那就是內核比大多數其他自由軟件項目更開放。一個典型的三個
+月內核開發週期å¯ä»¥æ¶‰åŠ1000多個開發人員,他們爲100多個ä¸åŒçš„å…¬å¸ï¼ˆæˆ–者根本ä¸
隸屬公å¸ï¼‰å·¥ä½œã€‚
與內核開發社å€åˆä½œä¸¦ä¸æ˜¯ç‰¹åˆ¥å›°é›£ã€‚但儘管如此,ä»æœ‰è¨±å¤šæ½›åœ¨çš„è²¢ç»è€…在嘗試åš
@@ -79,7 +79,7 @@ Linux最引人注目的特性之一是這些開發人員å¯ä»¥è¨ªå•å®ƒï¼›ä»»ä½•
éŽç¨‹èˆ‡å°ˆæœ‰çš„開發模å¼æœ‰å¾ˆå¤§çš„ä¸åŒä¹Ÿå°±ä¸è¶³çˆ²å¥‡äº†ã€‚
å°æ–¼æ–°é–‹ç™¼äººå“¡ä¾†èªªï¼Œå…§æ ¸çš„開發éŽç¨‹å¯èƒ½æœƒè®“人感到奇怪和æ懼,但這背後有充分的
-ç†ç”±å’Œå …實的經驗。一個ä¸äº†è§£å…§æ ¸ç¤¾å€å·¥ä½œæ–¹å¼çš„開發人員(或者更糟的是,他們
+ç†ç”±å’Œå …實的經驗。一個ä¸çž­è§£å…§æ ¸ç¤¾å€å·¥ä½œæ–¹å¼çš„開發人員(或者更糟的是,他們
試圖拋棄或è¦é¿ä¹‹ï¼‰æœƒå¾—到令人沮喪的體驗。開發社å€åœ¨å¹«åŠ©é‚£äº›è©¦åœ–學習的人的åŒæ™‚,
沒有時間幫助那些ä¸é¡˜æ„傾è½æˆ–ä¸é—œå¿ƒé–‹ç™¼éŽç¨‹çš„人。
@@ -102,20 +102,20 @@ Andrew Morton, Andrew Price, Tsugikazu Shibata 和 Jochen Voß 。
--------------------
有些公å¸å’Œé–‹ç™¼äººå“¡å¶çˆ¾æœƒæƒ³ï¼Œçˆ²ä»€éº¼ä»–們è¦è²»å¿ƒå­¸ç¿’如何與內核社å€åˆä½œï¼Œä¸¦å°‡ä»£ç¢¼
-放入主線內核(「主線ã€æ˜¯ç”±Linus Torvalds維護的內核,Linux發行商將其用作基礎)。
+放入主線內核(“主線â€æ˜¯ç”±Linus Torvalds維護的內核,Linux發行商將其用作基礎)。
在短期內,貢ç»ä»£ç¢¼çœ‹èµ·ä¾†åƒæ˜¯ä¸€ç¨®å¯ä»¥é¿å…的開銷;維護ç¨ç«‹ä»£ç¢¼ä¸¦ç›´æŽ¥æ”¯æŒç”¨æˆ¶
-似乎更容易。事實上,ä¿æŒä»£ç¢¼ç¨ç«‹ï¼ˆã€Œæ¨¹å¤–ã€ï¼‰æ˜¯åœ¨ç¶“濟上是錯誤的。
+似乎更容易。事實上,ä¿æŒä»£ç¢¼ç¨ç«‹ï¼ˆâ€œæ¨¹å¤–â€ï¼‰æ˜¯åœ¨ç¶“濟上是錯誤的。
爲了說明樹外代碼æˆæœ¬ï¼Œä¸‹é¢çµ¦å‡ºå…§æ ¸é–‹ç™¼éŽç¨‹çš„一些相關方é¢ï¼›æœ¬æ–‡ç¨å¾Œå°‡æ›´è©³ç´°åœ°
討論其中的大部分內容。請考慮:
- 所有Linux用戶都å¯ä»¥ä½¿ç”¨åˆä½µåˆ°ä¸»ç·šå…§æ ¸ä¸­çš„代碼。它將自動出ç¾åœ¨æ‰€æœ‰å•“用它的
- 發行版上。無需驅動程åºç£ç¢Ÿã€é¡å¤–下載,也ä¸éœ€è¦çˆ²å¤šå€‹ç™¼è¡Œç‰ˆçš„多個版本æä¾›
+ 發行版上。無需驅動程åºç£ç›¤ã€é¡å¤–下載,也ä¸éœ€è¦çˆ²å¤šå€‹ç™¼è¡Œç‰ˆçš„多個版本æä¾›
支æŒï¼›é€™ä¸€åˆ‡å°‡æ–¹ä¾¿æ‰€æœ‰é–‹ç™¼äººå“¡å’Œç”¨æˆ¶ã€‚併入主線解決了大é‡çš„分發和支æŒå•é¡Œã€‚
- 當內核開發人員努力維護一個穩定的用戶空間接å£æ™‚,內核內部API處於ä¸æ–·è®ŠåŒ–之中。
ä¸ç¶­æŒç©©å®šçš„內部接å£æ˜¯ä¸€å€‹æ…Žé‡çš„設計決策;它å…許在任何時候進行基本的改進,
- 並產出更高質é‡çš„代碼。但該策略導致çµæžœæ˜¯ï¼Œè‹¥è¦ä½¿ç”¨æ–°çš„內核,任何樹外代碼都
+ 併產出更高質é‡çš„代碼。但該策略導致çµæžœæ˜¯ï¼Œè‹¥è¦ä½¿ç”¨æ–°çš„內核,任何樹外代碼都
需è¦æŒçºŒçš„維護。維護樹外代碼會需è¦å¤§é‡çš„工作æ‰èƒ½ä½¿ä»£ç¢¼ä¿æŒæ­£å¸¸é‹è¡Œã€‚
相å,ä½æ–¼ä¸»ç·šä¸­çš„代碼ä¸éœ€è¦é€™æ¨£åšï¼Œå› çˆ²åŸºæœ¬è¦å‰‡è¦æ±‚進行API更改的任何開發
@@ -140,60 +140,60 @@ Andrew Morton, Andrew Price, Tsugikazu Shibata 和 Jochen Voß 。
- 代碼的貢ç»æ˜¯ä½¿æ•´å€‹æµç¨‹å·¥ä½œçš„根本。通éŽè²¢ç»ä»£ç¢¼ï¼Œæ‚¨å¯ä»¥å‘內核添加新功能,並
æ供其他內核開發人員使用的功能和示例。如果您已經爲Linux開發了代碼(或者正在
- 考慮這樣åšï¼‰ï¼Œé‚£éº¼æ‚¨é¡¯ç„¶å°é€™å€‹å¹³å°çš„æŒçºŒæˆåŠŸæ„Ÿèˆˆè¶£ï¼›è²¢ç»ä»£ç¢¼æ˜¯ç¢ºä¿æˆåŠŸçš„
+ 考慮這樣åšï¼‰ï¼Œé‚£éº¼æ‚¨é¡¯ç„¶å°é€™å€‹å¹³è‡ºçš„æŒçºŒæˆåŠŸæ„Ÿèˆˆè¶£ï¼›è²¢ç»ä»£ç¢¼æ˜¯ç¢ºä¿æˆåŠŸçš„
最好方法之一。
-上述所有ç†ç”±éƒ½é©ç”¨æ–¼ä»»ä½•æ¨¹å¤–內核代碼,包括以專有的ã€åƒ…二進ä½å½¢å¼åˆ†ç™¼çš„代碼。
-然而,在考慮任何類型的純二進ä½å…§æ ¸ä»£ç¢¼åˆ†å¸ƒä¹‹å‰ï¼Œé‚„需è¦è€ƒæ…®å…¶ä»–因素。包括:
+上述所有ç†ç”±éƒ½é©ç”¨æ–¼ä»»ä½•æ¨¹å¤–內核代碼,包括以專有的ã€åƒ…二進制形å¼åˆ†ç™¼çš„代碼。
+然而,在考慮任何類型的純二進制內核代碼分佈之å‰ï¼Œé‚„需è¦è€ƒæ…®å…¶ä»–因素。包括:
- åœç¹žå°ˆæœ‰å…§æ ¸æ¨¡å¡Šåˆ†ç™¼çš„法律å•é¡Œå…¶å¯¦è¼ƒçˆ²æ¨¡ç³Šï¼›ç›¸ç•¶å¤šçš„內核版權所有者èªçˆ²ï¼Œ
- 大多數僅二進ä½çš„模塊是內核的派生產å“,因此,它們的分發é•å了GNU通用公共
+ 大多數僅二進制的模塊是內核的派生產å“,因此,它們的分發é•å了GNU通用公共
許å¯è­‰ï¼ˆä¸‹é¢å°‡è©³ç´°ä»‹ç´¹ï¼‰ã€‚本文作者ä¸æ˜¯å¾‹å¸«ï¼Œæœ¬æ–‡æª”中的任何內容都ä¸å¯èƒ½è¢«
- 視爲法律建議。å°é–‰åŽŸå§‹ç¢¼æ¨¡å¡Šçš„真實法律地ä½åªèƒ½ç”±æ³•é™¢æ±ºå®šã€‚但ä¸ç®¡æ€Žæ¨£ï¼Œå›°æ“¾
+ 視爲法律建議。å°é–‰æºä»£ç¢¼æ¨¡å¡Šçš„真實法律地ä½åªèƒ½ç”±æ³•é™¢æ±ºå®šã€‚但ä¸ç®¡æ€Žæ¨£ï¼Œå›°æ“¾
這些模塊的ä¸ç¢ºå®šæ€§ä»ç„¶å­˜åœ¨ã€‚
-- 二進ä½æ¨¡å¡Šå¤§å¤§å¢žåŠ äº†èª¿è©¦å…§æ ¸å•é¡Œçš„難度,以至於大多數內核開發人員甚至都ä¸æœƒ
- 嘗試。因此,åªåˆ†ç™¼äºŒé€²ä½æ¨¡å¡Šå°‡ä½¿æ‚¨çš„用戶更難從社å€ç²å¾—支æŒã€‚
+- 二進制模塊大大增加了調試內核å•é¡Œçš„難度,以至於大多數內核開發人員甚至都ä¸æœƒ
+ 嘗試。因此,åªåˆ†ç™¼äºŒé€²åˆ¶æ¨¡å¡Šå°‡ä½¿æ‚¨çš„用戶更難從社å€ç²å¾—支æŒã€‚
-- å°æ–¼åƒ…二進ä½çš„模塊的發行者來說,支æŒä¹Ÿæ›´åŠ å›°é›£ï¼Œä»–們必須爲他們希望支æŒçš„
+- å°æ–¼åƒ…二進制的模塊的發行者來說,支æŒä¹Ÿæ›´åŠ å›°é›£ï¼Œä»–們必須爲他們希望支æŒçš„
æ¯å€‹ç™¼è¡Œç‰ˆå’Œæ¯å€‹å…§æ ¸ç‰ˆæœ¬æä¾›ä¸åŒç‰ˆæœ¬çš„模塊。爲了æ供較爲全é¢çš„覆蓋範åœï¼Œ
å¯èƒ½éœ€è¦ä¸€å€‹æ¨¡å¡Šçš„å¹¾å個構建,並且æ¯æ¬¡å‡ç´šå…§æ ¸æ™‚,您的用戶都必須單ç¨å‡ç´š
這些模塊。
-- 上é¢æ到的關於代碼評審的所有å•é¡Œéƒ½æ›´åŠ å­˜åœ¨æ–¼å°é–‰åŽŸå§‹ç¢¼ä¸­ã€‚由於該代碼根本
+- 上é¢æ到的關於代碼評審的所有å•é¡Œéƒ½æ›´åŠ å­˜åœ¨æ–¼å°é–‰æºä»£ç¢¼ä¸­ã€‚由於該代碼根本
ä¸å¯å¾—,因此社å€ç„¡æ³•å°å…¶é€²è¡Œå¯©æŸ¥ï¼Œæ¯«ç„¡ç–‘å•ï¼Œå®ƒå°‡å­˜åœ¨åš´é‡å•é¡Œã€‚
尤其是嵌入å¼ç³»çµ±çš„製造商,å¯èƒ½æœƒå‚¾å‘於忽視本節中所說的大部分內容;因爲他們
-相信自己正在商用一種使用å‡çµå…§æ ¸ç‰ˆæœ¬çš„ç¨ç«‹ç”¢å“,在發布後ä¸éœ€è¦å†é€²è¡Œé–‹ç™¼ã€‚
+相信自己正在商用一種使用å‡çµå…§æ ¸ç‰ˆæœ¬çš„ç¨ç«‹ç”¢å“,在發佈後ä¸éœ€è¦å†é€²è¡Œé–‹ç™¼ã€‚
這個論點忽略了廣泛的代碼審查的價值以åŠå…許用戶å‘產å“添加功能的價值。但這些
-產å“的商業壽命有é™ï¼Œä¹‹å¾Œå¿…須發布新版本的產å“。在這一點上,代碼在主線上並得到
-良好維護的供應商將能夠更好地å ä½ï¼Œä»¥ä½¿æ–°ç”¢å“快速上市。
+產å“的商業壽命有é™ï¼Œä¹‹å¾Œå¿…須發佈新版本的產å“。在這一點上,代碼在主線上並得到
+良好維護的供應商將能夠更好地佔ä½ï¼Œä»¥ä½¿æ–°ç”¢å“快速上市。
許å¯
----
代碼是根據一些許å¯è­‰æ供給Linux內核的,但是所有代碼都必須與GNU通用公共許å¯
證(GPLV2)的版本2兼容,該版本是覆蓋整個內核分發的許å¯è­‰ã€‚在實è¸ä¸­ï¼Œé€™æ„味
-著所有代碼貢ç»éƒ½ç”±GPLv2(å¯é¸åœ°ï¼Œèªžè¨€å…許在更高版本的GPL下分發)或3å­å¥BSD
+ç€æ‰€æœ‰ä»£ç¢¼è²¢ç»éƒ½ç”±GPLv2(å¯é¸åœ°ï¼Œèªžè¨€å…許在更高版本的GPL下分發)或3å­å¥BSD
許å¯ï¼ˆNew BSD License,譯者注)覆蓋。任何ä¸åŒ…å«åœ¨å…¼å®¹è¨±å¯è­‰ä¸­çš„è²¢ç»éƒ½ä¸æœƒ
被接å—到內核中。
è²¢ç»çµ¦å…§æ ¸çš„代碼ä¸éœ€è¦ï¼ˆæˆ–請求)版權分é…。åˆä½µåˆ°ä¸»ç·šå…§æ ¸ä¸­çš„所有代碼都ä¿ç•™
其原始所有權;因此,內核ç¾åœ¨æ“有數åƒå€‹æ‰€æœ‰è€…。
-這種所有權çµæ§‹ä¹Ÿæš—示著,任何改變內核許å¯çš„嘗試都註定會失敗。很少有實際情æ³
+這種所有權çµæ§‹ä¹Ÿæš—示ç€ï¼Œä»»ä½•æ”¹è®Šå…§æ ¸è¨±å¯çš„嘗試都註定會失敗。很少有實際情æ³
å¯ä»¥ç²å¾—所有版權所有者的åŒæ„(或者從內核中刪除他們的代碼)。因此,尤其是在
å¯é è¦‹çš„將來,許å¯è­‰ä¸å¤§å¯èƒ½é·ç§»åˆ°GPL的版本3。
-所有貢ç»çµ¦å…§æ ¸çš„代碼都必須是åˆæ³•çš„å…費軟體。因此,ä¸æŽ¥å—匿å(或化å)貢ç»
-者的代碼。所有貢ç»è€…都需è¦åœ¨ä»–們的代碼上「sign off(簽發)ã€ï¼Œè²æ˜Žä»£ç¢¼å¯ä»¥
-在GPL下與內核一起分發。無法æ供未被其所有者許å¯çˆ²å…費軟體的代碼,或å¯èƒ½çˆ²
+所有貢ç»çµ¦å…§æ ¸çš„代碼都必須是åˆæ³•çš„å…費軟件。因此,ä¸æŽ¥å—匿å(或化å)貢ç»
+者的代碼。所有貢ç»è€…都需è¦åœ¨ä»–們的代碼上“sign off(簽發)â€ï¼Œè²æ˜Žä»£ç¢¼å¯ä»¥
+在GPL下與內核一起分發。無法æ供未被其所有者許å¯çˆ²å…費軟件的代碼,或å¯èƒ½çˆ²
內核造æˆç‰ˆæ¬Šç›¸é—œå•é¡Œçš„代碼(例如,由缺ä¹é©ç•¶ä¿è­·çš„åå‘工程工作派生的代碼)
ä¸èƒ½è¢«æŽ¥å—。
有關版權å•é¡Œçš„æå•åœ¨Linux開發郵件列表中很常見。這樣的å•é¡Œé€šå¸¸æœƒå¾—到ä¸å°‘答案,
-但請記ä½ï¼Œå›žç­”這些å•é¡Œçš„人ä¸æ˜¯å¾‹å¸«ï¼Œä¸èƒ½æ供法律諮詢。如果您有關於Linux原始碼
-的法律å•é¡Œï¼Œæ²’有什麼å¯ä»¥ä»£æ›¿è«®è©¢äº†è§£é€™ä¸€é ˜åŸŸçš„律師。ä¾è³´å¾žæŠ€è¡“郵件列表中ç²å¾—
+但請記ä½ï¼Œå›žç­”這些å•é¡Œçš„人ä¸æ˜¯å¾‹å¸«ï¼Œä¸èƒ½æ供法律諮詢。如果您有關於Linuxæºä»£ç¢¼
+的法律å•é¡Œï¼Œæ²’有什麼å¯ä»¥ä»£æ›¿è«®è©¢çž­è§£é€™ä¸€é ˜åŸŸçš„律師。ä¾è³´å¾žæŠ€è¡“郵件列表中ç²å¾—
的答案是一件冒險的事情。
diff --git a/Documentation/translations/zh_TW/process/2.Process.rst b/Documentation/translations/zh_TW/process/2.Process.rst
index 17bb4e07d171..49385d65c216 100644
--- a/Documentation/translations/zh_TW/process/2.Process.rst
+++ b/Documentation/translations/zh_TW/process/2.Process.rst
@@ -26,8 +26,8 @@
總覽
----
-內核開發人員使用一個鬆散的基於時間的發布éŽç¨‹ï¼Œæ¯å…©åˆ°ä¸‰å€‹æœˆç™¼å¸ƒä¸€æ¬¡æ–°çš„主è¦
-內核版本。最近的發布歷å²è¨˜éŒ„如下:
+內核開發人員使用一個鬆散的基於時間的發佈éŽç¨‹ï¼Œæ¯å…©åˆ°ä¸‰å€‹æœˆç™¼ä½ˆä¸€æ¬¡æ–°çš„主è¦
+內核版本。最近的發佈歷å²è¨˜éŒ„如下:
====== =================
5.0 2019年3月3日
@@ -42,33 +42,33 @@
版本包å«å¤§ç´„13000個變更集,變更了幾åè¬è¡Œä»£ç¢¼ã€‚因此,5.x是Linux內核開發的å‰
沿;內核使用滾動開發模型,ä¸æ–·é›†æˆé‡å¤§è®ŠåŒ–。
-å°æ–¼æ¯å€‹ç‰ˆæœ¬çš„補ä¸åˆä½µï¼Œéµå¾ªä¸€å€‹ç›¸å°ç°¡å–®çš„è¦å‰‡ã€‚在æ¯å€‹é–‹ç™¼å‘¨æœŸçš„開頭,「åˆä½µ
-窗å£ã€è¢«æ‰“開。這時,被èªçˆ²è¶³å¤ ç©©å®šï¼ˆä¸¦ä¸”被開發社å€æŽ¥å—)的代碼被åˆä½µåˆ°ä¸»ç·šå…§
-核中。在這段時間內,新開發周期的大部分變更(以åŠæ‰€æœ‰ä¸»è¦è®Šæ›´ï¼‰å°‡ä»¥æŽ¥è¿‘æ¯å¤©
-1000次變更(「補ä¸ã€æˆ–「變更集ã€ï¼‰çš„速度åˆä½µã€‚
+å°æ–¼æ¯å€‹ç‰ˆæœ¬çš„補ä¸åˆä½µï¼Œéµå¾ªä¸€å€‹ç›¸å°ç°¡å–®çš„è¦å‰‡ã€‚在æ¯å€‹é–‹ç™¼é€±æœŸçš„開頭,“åˆä½µ
+窗å£â€è¢«æ‰“開。這時,被èªçˆ²è¶³å¤ ç©©å®šï¼ˆä¸¦ä¸”被開發社å€æŽ¥å—)的代碼被åˆä½µåˆ°ä¸»ç·šå…§
+核中。在這段時間內,新開發週期的大部分變更(以åŠæ‰€æœ‰ä¸»è¦è®Šæ›´ï¼‰å°‡ä»¥æŽ¥è¿‘æ¯å¤©
+1000次變更(“補ä¸â€æˆ–“變更集â€ï¼‰çš„速度åˆä½µã€‚
(順便說一å¥ï¼Œå€¼å¾—注æ„的是,åˆä½µçª—å£æœŸé–“集æˆçš„更改並ä¸æ˜¯æ†‘空產生的;它們是經
æå‰æ”¶é›†ã€æ¸¬è©¦å’Œåˆ†ç´šçš„。ç¨å¾Œå°‡è©³ç´°æ述該éŽç¨‹çš„工作方å¼ã€‚)
-åˆä½µçª—å£æŒçºŒå¤§ç´„兩周。在這段時間çµæŸæ™‚,LinusTorvaldså°‡è²æ˜Žçª—å£å·²é—œé–‰ï¼Œä¸¦
-釋放第一個「rcã€å…§æ ¸ã€‚例如,å°æ–¼ç›®æ¨™çˆ²5.6的內核,在åˆä½µçª—å£çµæŸæ™‚發生的釋放
+åˆä½µçª—å£æŒçºŒå¤§ç´„兩週。在這段時間çµæŸæ™‚,Linus Torvaldså°‡è²æ˜Žçª—å£å·²é—œé–‰ï¼Œä¸¦
+釋放第一個“rcâ€å…§æ ¸ã€‚例如,å°æ–¼ç›®æ¨™çˆ²5.6的內核,在åˆä½µçª—å£çµæŸæ™‚發生的釋放
將被稱爲5.6-rc1。-rc1 版本是一個信號,表示åˆä½µæ–°ç‰¹æ€§çš„時間已經éŽåŽ»ï¼Œç©©å®šä¸‹ä¸€
個內核的時間已經到來。
在接下來的6到10周內,åªæœ‰ä¿®å¾©å•é¡Œçš„補ä¸æ‰æ‡‰è©²æ交給主線。有時會å…許更大的
更改,但這種情æ³å¾ˆå°‘發生;試圖在åˆä½µçª—å£å¤–åˆä½µæ–°åŠŸèƒ½çš„開發人員往往å—ä¸åˆ°
å‹å¥½çš„接待。一般來說,如果您錯éŽäº†çµ¦å®šç‰¹æ€§çš„åˆä½µçª—å£ï¼Œæœ€å¥½çš„åšæ³•æ˜¯ç­‰å¾…下一
-個開發周期。(å¶çˆ¾æœƒå°æœªæ”¯æŒç¡¬é«”的驅動程åºé€²è¡Œä¾‹å¤–;如果它們ä¸æ”¹è®Šå·²æœ‰ä»£ç¢¼ï¼Œ
-則ä¸æœƒå°Žè‡´å›žæ­¸ï¼Œæ‡‰è©²å¯ä»¥éš¨æ™‚被安全地加入)。
+個開發週期。(å¶çˆ¾æœƒå°æœªæ”¯æŒç¡¬ä»¶çš„驅動程åºé€²è¡Œä¾‹å¤–;如果它們ä¸æ”¹è®Šå·²æœ‰ä»£ç¢¼ï¼Œ
+則ä¸æœƒå°Žè‡´è¿´æ­¸ï¼Œæ‡‰è©²å¯ä»¥éš¨æ™‚被安全地加入)。
-隨著修復程åºé€²å…¥ä¸»ç·šï¼Œè£œä¸é€Ÿåº¦å°‡éš¨è‘—時間的推移而變慢。Linus大約æ¯å‘¨ç™¼å¸ƒä¸€æ¬¡
-æ–°çš„-rc內核;在內核被èªçˆ²è¶³å¤ ç©©å®šä¸¦æœ€çµ‚發布å‰ï¼Œä¸€èˆ¬æœƒé”到-rc6到-rc9之間。
+隨ç€ä¿®å¾©ç¨‹åºé€²å…¥ä¸»ç·šï¼Œè£œä¸é€Ÿåº¦å°‡éš¨ç€æ™‚間的推移而變慢。Linus大約æ¯é€±ç™¼ä½ˆä¸€æ¬¡
+æ–°çš„-rc內核;在內核被èªçˆ²è¶³å¤ ç©©å®šä¸¦æœ€çµ‚發佈å‰ï¼Œä¸€èˆ¬æœƒé”到-rc6到-rc9之間。
然後,整個éŽç¨‹åˆé‡æ–°é–‹å§‹äº†ã€‚
-例如,這裡是5.4的開發周期進行情æ³ï¼ˆ2019年):
+例如,這è£æ˜¯5.4的開發週期進行情æ³ï¼ˆ2019年):
============== ==============================
- ä¹æœˆ 15 5.3 穩定版發布
+ ä¹æœˆ 15 5.3 穩定版發佈
ä¹æœˆ 30 5.4-rc1 åˆä½µçª—å£é—œé–‰
å月 6 5.4-rc2
å月 13 5.4-rc3
@@ -77,26 +77,26 @@
å一月 3 5.4-rc6
å一月 10 5.4-rc7
å一月 17 5.4-rc8
- å一月 24 5.4 穩定版發布
+ å一月 24 5.4 穩定版發佈
============== ==============================
-開發人員如何決定何時çµæŸé–‹ç™¼å‘¨æœŸä¸¦å‰µå»ºç©©å®šç‰ˆæœ¬ï¼Ÿæœ€é‡è¦çš„指標是以å‰ç‰ˆæœ¬çš„
-回歸列表。ä¸æ­¡è¿Žå‡ºç¾ä»»ä½•éŒ¯èª¤ï¼Œä½†æ˜¯é‚£äº›ç ´å£žäº†ä»¥å‰èƒ½å·¥ä½œçš„系統的錯誤被èªçˆ²æ˜¯
-特別嚴é‡çš„。因此,導致回歸的補ä¸æ˜¯ä¸å—歡迎的,很å¯èƒ½åœ¨ç©©å®šæœŸå…§åˆªé™¤ã€‚
+開發人員如何決定何時çµæŸé–‹ç™¼é€±æœŸä¸¦å‰µå»ºç©©å®šç‰ˆæœ¬ï¼Ÿæœ€é‡è¦çš„指標是以å‰ç‰ˆæœ¬çš„
+迴歸列表。ä¸æ­¡è¿Žå‡ºç¾ä»»ä½•éŒ¯èª¤ï¼Œä½†æ˜¯é‚£äº›ç ´å£žäº†ä»¥å‰èƒ½å·¥ä½œçš„系統的錯誤被èªçˆ²æ˜¯
+特別嚴é‡çš„。因此,導致迴歸的補ä¸æ˜¯ä¸å—歡迎的,很å¯èƒ½åœ¨ç©©å®šæœŸå…§åˆªé™¤ã€‚
-開發人員的目標是在穩定發布之å‰ä¿®å¾©æ‰€æœ‰å·²çŸ¥çš„回歸。在ç¾å¯¦ä¸–界中,這種完美是
+開發人員的目標是在穩定發佈之å‰ä¿®å¾©æ‰€æœ‰å·²çŸ¥çš„迴歸。在ç¾å¯¦ä¸–界中,這種完美是
很難實ç¾çš„;在這種è¦æ¨¡çš„項目中,變數太多了。需è¦èªªæ˜Žçš„是,延é²æœ€çµ‚版本åªæœƒ
-使å•é¡Œè®Šå¾—更糟;等待下一個åˆä½µçª—å£çš„更改將變多,導致下次出ç¾æ›´å¤šçš„回歸錯誤。
-因此,大多數5.x內核都有一些已知的回歸錯誤,ä¸éŽï¼Œå¸Œæœ›æ²’有一個是嚴é‡çš„。
+使å•é¡Œè®Šå¾—更糟;等待下一個åˆä½µçª—å£çš„更改將變多,導致下次出ç¾æ›´å¤šçš„迴歸錯誤。
+因此,大多數5.x內核都有一些已知的迴歸錯誤,ä¸éŽï¼Œå¸Œæœ›æ²’有一個是嚴é‡çš„。
-一旦一個穩定的版本發布,它的æŒçºŒç¶­è­·å·¥ä½œå°±è¢«ç§»äº¤çµ¦ã€Œç©©å®šåœ˜éšŠã€ï¼Œç›®å‰ç”±
-Greg Kroah-Hartman領導。穩定團隊將使用5.x.y編號方案ä¸å®šæœŸåœ°ç™¼å¸ƒç©©å®šç‰ˆæœ¬çš„
+一旦一個穩定的版本發佈,它的æŒçºŒç¶­è­·å·¥ä½œå°±è¢«ç§»äº¤çµ¦â€œç©©å®šåœ˜éšŠâ€ï¼Œç›®å‰ç”±
+Greg Kroah-Hartman領導。穩定團隊將使用5.x.y編號方案ä¸å®šæœŸåœ°ç™¼ä½ˆç©©å®šç‰ˆæœ¬çš„
更新。è¦åˆå…¥æ›´æ–°ç‰ˆæœ¬ï¼Œè£œä¸å¿…須(1)修復一個é‡è¦çš„缺陷,且(2)已經åˆä½µåˆ°
-下一個開發版本主線中。內核通常會在其åˆå§‹ç‰ˆæœ¬å¾Œçš„一個以上的開發周期內收到
+下一個開發版本主線中。內核通常會在其åˆå§‹ç‰ˆæœ¬å¾Œçš„一個以上的開發週期內收到
穩定版更新。例如,5.2內核的歷å²å¦‚下(2019年):
============== ===============================
- 七月 7 5.2 穩定版發布
+ 七月 7 5.2 穩定版發佈
七月 13 5.2.1
七月 21 5.2.2
七月 26 5.2.3
@@ -108,7 +108,7 @@ Greg Kroah-Hartman領導。穩定團隊將使用5.x.y編號方案ä¸å®šæœŸåœ°ç™¼
5.2.21是5.2版本的最終穩定更新。
-有些內核被指定爲「長期ã€å…§æ ¸ï¼›å®ƒå€‘將得到更長時間的支æŒã€‚在本文中,當å‰çš„長期
+有些內核被指定爲“長期â€å…§æ ¸ï¼›å®ƒå€‘將得到更長時間的支æŒã€‚在本文中,當å‰çš„長期
內核åŠå…¶ç¶­è­·è€…是:
====== ================================ ================
@@ -121,9 +121,9 @@ Greg Kroah-Hartman領導。穩定團隊將使用5.x.y編號方案ä¸å®šæœŸåœ°ç™¼
====== ================================ ================
長期支æŒå…§æ ¸çš„é¸æ“‡ç´”粹是維護人員是å¦æœ‰éœ€æ±‚和時間來維護該版本的å•é¡Œã€‚
-ç›®å‰é‚„沒有爲å³å°‡ç™¼å¸ƒçš„任何特定版本æ供長期支æŒçš„已知計劃。
+ç›®å‰é‚„沒有爲å³å°‡ç™¼ä½ˆçš„任何特定版本æ供長期支æŒçš„已知計劃。
-補ä¸çš„生命周期
+補ä¸çš„生命週期
--------------
補ä¸ä¸æœƒç›´æŽ¥å¾žé–‹ç™¼äººå“¡çš„éµç›¤é€²å…¥ä¸»ç·šå…§æ ¸ã€‚相å,有一個ç¨å¾®è¤‡é›œï¼ˆå¦‚果有些éž
@@ -140,7 +140,7 @@ Greg Kroah-Hartman領導。穩定團隊將使用5.x.y編號方案ä¸å®šæœŸåœ°ç™¼
是在ä¸æ¶‰åŠç¤¾å€çš„情æ³ä¸‹å®Œæˆçš„,但是如果å¯èƒ½çš„話,最好是在公開的情æ³ä¸‹å®Œæˆ
這項工作;這樣å¯ä»¥ç¯€çœå¾ˆå¤šç¨å¾Œå†é‡æ–°è¨­è¨ˆçš„時間。
-- 早期評審。補ä¸è¢«ç™¼å¸ƒåˆ°ç›¸é—œçš„郵件列表中,列表中的開發人員會回復他們å¯èƒ½æœ‰
+- 早期評審。補ä¸è¢«é«®å¸ƒåˆ°ç›¸é—œçš„郵件列表中,列表中的開發人員會回覆他們å¯èƒ½æœ‰
的任何評論。如果一切順利的話,這個éŽç¨‹æ‡‰è©²æœƒç™¼ç¾è£œä¸çš„任何主è¦å•é¡Œã€‚
- 更廣泛的評審。當補ä¸æŽ¥è¿‘準備好ç´å…¥ä¸»ç·šæ™‚,它應該被相關的å­ç³»çµ±ç¶­è­·äººå“¡
@@ -153,48 +153,48 @@ Greg Kroah-Hartman領導。穩定團隊將使用5.x.y編號方案ä¸å®šæœŸåœ°ç™¼
如果您的補ä¸å¾—到了需è¦æ›´æ”¹çš„å饋,那麼您應該進行這些更改,或者解釋爲何
ä¸æ‡‰è©²é€²è¡Œé€™äº›æ›´æ”¹ã€‚如果您的補ä¸æ²’有評審æ„見,也沒有被其相應的å­ç³»çµ±æˆ–
驅動程åºç¶­è­·è€…接å—,那麼您應該堅æŒä¸æ‡ˆåœ°å°‡è£œä¸æ›´æ–°åˆ°ç•¶å‰å…§æ ¸ä½¿å…¶å¯è¢«æ­£å¸¸
- 應用,並ä¸æ–·åœ°ç™¼é€å®ƒä»¥ä¾›å¯©æŸ¥å’Œåˆä½µã€‚
+ 應用,並ä¸æ–·åœ°ç™¼é€å®ƒä»¥ä¾›å¯©æŸ¥å’Œåˆä¸¦ã€‚
- åˆä½µåˆ°ä¸»ç·šã€‚最終,一個æˆåŠŸçš„補ä¸å°‡è¢«åˆä½µåˆ°ç”±LinusTorvalds管ç†çš„主線存儲庫
中。此時å¯èƒ½æœƒå‡ºç¾æ›´å¤šçš„è©•è«–å’Œ/或å•é¡Œï¼›å°é–‹ç™¼äººå“¡ä¾†èªªæ‡‰å°é€™äº›å•é¡Œä¸¦è§£æ±º
出ç¾çš„任何å•é¡Œä»å¾ˆé‡è¦ã€‚
-- 穩定版發布。大é‡ç”¨æˆ¶å¯èƒ½å—此補ä¸å½±éŸ¿ï¼Œå› æ­¤å¯èƒ½å†æ¬¡å‡ºç¾æ–°çš„å•é¡Œã€‚
+- 穩定版發佈。大é‡ç”¨æˆ¶å¯èƒ½å—此補ä¸å½±éŸ¿ï¼Œå› æ­¤å¯èƒ½å†æ¬¡å‡ºç¾æ–°çš„å•é¡Œã€‚
- 長期維護。雖然開發人員在åˆä½µä»£ç¢¼å¾Œå¯èƒ½æœƒå¿˜è¨˜ä»£ç¢¼ï¼Œä½†é€™ç¨®è¡Œçˆ²å¾€å¾€æœƒçµ¦é–‹ç™¼
社å€ç•™ä¸‹ä¸è‰¯å°è±¡ã€‚åˆä½µä»£ç¢¼æ¶ˆé™¤äº†ä¸€äº›ç¶­è­·è² æ“”,因爲其他人將修復由API更改
引起的å•é¡Œã€‚但是,如果代碼è¦é•·æœŸä¿æŒå¯ç”¨ï¼ŒåŽŸå§‹é–‹ç™¼äººå“¡æ‡‰è©²ç¹¼çºŒçˆ²ä»£ç¢¼è² è²¬ã€‚
-內核開發人員(或他們的僱主)犯的最大錯誤之一是試圖將æµç¨‹ç°¡åŒ–爲一個「åˆä½µåˆ°
-主線ã€æ­¥é©Ÿã€‚這種方法總是會讓所有相關人員感到沮喪。
+內核開發人員(或他們的僱主)犯的最大錯誤之一是試圖將æµç¨‹ç°¡åŒ–爲一個“åˆä½µåˆ°
+主線â€æ­¥é©Ÿã€‚這種方法總是會讓所有相關人員感到沮喪。
補ä¸å¦‚何進入內核
----------------
-åªæœ‰ä¸€å€‹äººå¯ä»¥å°‡è£œä¸åˆä½µåˆ°ä¸»ç·šå…§æ ¸å­˜å„²åº«ä¸­ï¼šLinusTorvalds。但是,在進入
+åªæœ‰ä¸€å€‹äººå¯ä»¥å°‡è£œä¸åˆä½µåˆ°ä¸»ç·šå…§æ ¸å­˜å„²åº«ä¸­ï¼šLinus Torvalds。但是,在進入
2.6.38內核的9500多個補ä¸ä¸­ï¼Œåªæœ‰112個(大約1.3%)是由Linus自己直接é¸æ“‡çš„。
內核項目已經發展到一個沒有一個開發人員å¯ä»¥åœ¨æ²’有支æŒçš„情æ³ä¸‹æª¢æŸ¥å’Œé¸æ“‡æ¯å€‹
補ä¸çš„è¦æ¨¡ã€‚內核開發人員處ç†é€™ç¨®å¢žé•·çš„æ–¹å¼æ˜¯ä½¿ç”¨åœç¹žä¿¡ä»»éˆæ§‹å»ºçš„助ç†ç³»çµ±ã€‚
內核代碼庫在é‚輯上被分解爲一組å­ç³»çµ±ï¼šç¶²çµ¡ã€ç‰¹å®šé«”ç³»çµæ§‹æ”¯æŒã€å…§å­˜ç®¡ç†ã€è¦–
頻設備等。大多數å­ç³»çµ±éƒ½æœ‰ä¸€å€‹æŒ‡å®šçš„維護人員,其總體負責該å­ç³»çµ±ä¸­çš„代碼。
-這些å­ç³»çµ±ç¶­è­·è€…(鬆散地)是他們所管ç†çš„內核部分的「守門員ã€ï¼›ä»–們(通常)
+這些å­ç³»çµ±ç¶­è­·è€…(鬆散地)是他們所管ç†çš„內核部分的“守門員â€ï¼›ä»–們(通常)
會接å—一個補ä¸ä»¥åŒ…å«åˆ°ä¸»ç·šå…§æ ¸ä¸­ã€‚
-å­ç³»çµ±ç¶­è­·äººå“¡æ¯å€‹äººéƒ½ç®¡ç†è‘—自己版本的內核原始碼樹,通常(並éžç¸½æ˜¯ï¼‰ä½¿ç”¨Git。
+å­ç³»çµ±ç¶­è­·äººå“¡æ¯å€‹äººéƒ½ç®¡ç†ç€è‡ªå·±ç‰ˆæœ¬çš„內核æºä»£ç¢¼æ¨¹ï¼Œé€šå¸¸ï¼ˆä¸¦éžç¸½æ˜¯ï¼‰ä½¿ç”¨Git。
Git等工具(以åŠQuilt或Mercurial等相關工具)å…許維護人員跟蹤補ä¸åˆ—表,包括作者
ä¿¡æ¯å’Œå…¶ä»–元數據。在任何給定的時間,維護人員都å¯ä»¥ç¢ºå®šä»–或她的存儲庫中的哪
些補ä¸åœ¨ä¸»ç·šä¸­æ‰¾ä¸åˆ°ã€‚
-當åˆä½µçª—å£æ‰“開時,頂級維護人員將è¦æ±‚Linus從存儲庫中「拉出ã€ä»–們爲åˆä½µé¸æ“‡
+當åˆä¸¦çª—å£æ‰“開時,頂級維護人員將è¦æ±‚Linus從存儲庫中“拉出â€ä»–們爲åˆä½µé¸æ“‡
的補ä¸ã€‚如果LinusåŒæ„,補ä¸æµå°‡æµå‘他的存儲庫,æˆçˆ²ä¸»ç·šå…§æ ¸çš„一部分。
Linuså°æ‹‰å–中接收到的特定補ä¸çš„關注程度å„ä¸ç›¸åŒã€‚很明顯,有時他看起來很
-關注。但是一般來說,Linus相信å­ç³»çµ±ç¶­è­·äººå“¡ä¸æœƒå‘上游發é€å£žè£œä¸ã€‚
+關注。但是一般來說,Linus相信å­ç³»çµ±ç¶­è­·äººå“¡ä¸æœƒå‘上éŠç™¼é€å£žè£œä¸ã€‚
-å­ç³»çµ±ç¶­è­·äººå“¡åéŽä¾†ä¹Ÿå¯ä»¥å¾žå…¶ä»–維護人員那裡ç²å–補ä¸ã€‚例如,網絡樹是由首先
+å­ç³»çµ±ç¶­è­·äººå“¡åéŽä¾†ä¹Ÿå¯ä»¥å¾žå…¶ä»–維護人員那è£ç²å–補ä¸ã€‚例如,網絡樹是由首先
在專用於網絡設備驅動程åºã€ç„¡ç·šç¶²çµ¡ç­‰çš„樹中ç©ç´¯çš„補ä¸æ§‹å»ºçš„。此存儲éˆå¯ä»¥
-ä»»æ„長,但很少超éŽå…©å€‹æˆ–三個連çµã€‚由於éˆä¸­çš„æ¯å€‹ç¶­è­·è€…都信任那些管ç†è¼ƒä½Ž
-級別樹的維護者,所以這個éŽç¨‹ç¨±çˆ²ã€Œä¿¡ä»»éˆã€ã€‚
+ä»»æ„長,但很少超éŽå…©å€‹æˆ–三個éˆæŽ¥ã€‚由於éˆä¸­çš„æ¯å€‹ç¶­è­·è€…都信任那些管ç†è¼ƒä½Ž
+級別樹的維護者,所以這個éŽç¨‹ç¨±çˆ²â€œä¿¡ä»»éˆâ€ã€‚
顯然,在這樣的系統中,ç²å–內核補ä¸å–決於找到正確的維護者。直接å‘Linus發é€
補ä¸é€šå¸¸ä¸æ˜¯æ­£ç¢ºçš„方法。
@@ -204,30 +204,30 @@ Next 樹
å­ç³»çµ±æ¨¹éˆå¼•å°Žè£œä¸æµåˆ°å…§æ ¸ï¼Œä½†å®ƒä¹Ÿæ出了一個有趣的å•é¡Œï¼šå¦‚果有人想查看爲
下一個åˆä½µçª—å£æº–備的所有補ä¸æ€Žéº¼è¾¦ï¼Ÿé–‹ç™¼äººå“¡å°‡æ„Ÿèˆˆè¶£çš„是,還有什麼其他的
-更改有待解決,以了解是å¦å­˜åœ¨éœ€è¦æ“”心的è¡çªï¼›ä¾‹å¦‚,更改核心內核函數原型的
+更改有待解決,以瞭解是å¦å­˜åœ¨éœ€è¦æ“”心的è¡çªï¼›ä¾‹å¦‚,更改核心內核函數原型的
修補程åºå°‡èˆ‡ä½¿ç”¨è©²å‡½æ•¸èˆŠå½¢å¼çš„任何其他修補程åºè¡çªã€‚審查人員和測試人員希望
在所有這些變更到é”主線內核之å‰ï¼Œèƒ½å¤ è¨ªå•å®ƒå€‘的集æˆå½¢å¼çš„變更。您å¯ä»¥å¾žæ‰€æœ‰
相關的å­ç³»çµ±æ¨¹ä¸­æå–更改,但這將是一項複雜且容易出錯的工作。
-解決方案以-next樹的形å¼å‡ºç¾ï¼Œåœ¨é€™è£¡å­ç³»çµ±æ¨¹è¢«æ”¶é›†ä»¥ä¾›æ¸¬è©¦å’Œå¯©æŸ¥ã€‚這些樹中
-ç”±Andrew Morton維護的較è€çš„一個,被稱爲「-mmã€ï¼ˆç”¨æ–¼å…§å­˜ç®¡ç†ï¼Œå‰µå»ºæ™‚爲此)。
+解決方案以-next樹的形å¼å‡ºç¾ï¼Œåœ¨é€™è£å­ç³»çµ±æ¨¹è¢«æ”¶é›†ä»¥ä¾›æ¸¬è©¦å’Œå¯©æŸ¥ã€‚這些樹中
+ç”±Andrew Morton維護的較è€çš„一個,被稱爲“-mmâ€ï¼ˆç”¨æ–¼å…§å­˜ç®¡ç†ï¼Œå‰µå»ºæ™‚爲此)。
-mm 樹集æˆäº†ä¸€é•·ä¸²å­ç³»çµ±æ¨¹ä¸­çš„補ä¸ï¼›å®ƒé‚„包å«ä¸€äº›æ—¨åœ¨å¹«åŠ©èª¿è©¦çš„補ä¸ã€‚
除此之外,-mm 還包å«å¤§é‡ç”±Andrew直接é¸æ“‡çš„補ä¸ã€‚這些補ä¸å¯èƒ½å·²ç¶“發布在郵件
列表上,或者它們å¯èƒ½æ‡‰ç”¨æ–¼å…§æ ¸ä¸­æœªæŒ‡å®šå­ç³»çµ±æ¨¹çš„部分。åŒæ™‚,-mm 作爲最後
手段的å­ç³»çµ±æ¨¹ï¼›å¦‚果沒有其他明顯的路徑å¯ä»¥è®“補ä¸é€²å…¥ä¸»ç·šï¼Œé‚£éº¼å®ƒå¾ˆå¯èƒ½æœ€
終é¸æ“‡-mm 樹。累ç©åœ¨-mm 中的å„種補ä¸æœ€çµ‚將被轉發到é©ç•¶çš„å­ç³»çµ±æ¨¹ï¼Œæˆ–者直接
-發é€åˆ°Linus。在典型的開發周期中,大約5-10%的補ä¸é€šéŽ-mm 進入主線。
+發é€åˆ°Linus。在典型的開發週期中,大約5-10%的補ä¸é€šéŽ-mm 進入主線。
-當å‰-mm 補ä¸å¯åœ¨ã€Œmmotmã€ï¼ˆ-mm of the moment)目錄中找到:
+當å‰-mm 補ä¸å¯åœ¨â€œmmotmâ€ï¼ˆ-mm of the moment)目錄中找到:
https://www.ozlabs.org/~akpm/mmotm/
然而,使用MMOTM樹å¯èƒ½æœƒå分令人頭疼;它甚至å¯èƒ½ç„¡æ³•ç·¨è­¯ã€‚
-下一個周期補ä¸åˆä½µçš„主è¦æ¨¹æ˜¯linux-next,由Stephen Rothwell 維護。根據設計
+下一個週期補ä¸åˆä½µçš„主è¦æ¨¹æ˜¯linux-next,由Stephen Rothwell 維護。根據設計
linux-next 是下一個åˆä½µçª—å£é—œé–‰å¾Œä¸»ç·šçš„快照。linux-next樹在Linux-kernel å’Œ
-Linux-next 郵件列表中發布,å¯å¾žä»¥ä¸‹ä½ç½®ä¸‹è¼‰ï¼š
+Linux-next 郵件列表中發佈,å¯å¾žä»¥ä¸‹ä½ç½®ä¸‹è¼‰ï¼š
https://www.kernel.org/pub/linux/kernel/next/
@@ -237,7 +237,7 @@ Linux-next 已經æˆçˆ²å…§æ ¸é–‹ç™¼éŽç¨‹ä¸­ä¸å¯æˆ–缺的一部分;在一個
Staging 樹
----------
-內核原始碼樹包å«drivers/staging/目錄,其中有許多驅動程åºæˆ–文件系統的å­ç›®éŒ„
+內核æºä»£ç¢¼æ¨¹åŒ…å«drivers/staging/目錄,其中有許多驅動程åºæˆ–文件系統的å­ç›®éŒ„
正在被添加到內核樹中。它們在ä»ç„¶éœ€è¦æ›´å¤šçš„修正的時候å¯ä»¥ä¿ç•™åœ¨driver/staging/
目錄中;一旦完æˆï¼Œå°±å¯ä»¥å°‡å®ƒå€‘移到內核中。這是一種跟蹤ä¸ç¬¦åˆLinux內核編碼或
質é‡æ¨™æº–的驅動程åºçš„方法,人們å¯èƒ½å¸Œæœ›ä½¿ç”¨å®ƒå€‘並跟蹤開發。
@@ -251,7 +251,7 @@ Greg Kroah Hartman ç›®å‰è² è²¬ç¶­è­·staging 樹。ä»éœ€è¦ä¿®æ­£çš„驅動程åº
Staging 是一種讓新的驅動程åºé€²å…¥ä¸»ç·šçš„相å°å®¹æ˜“的方法,它們會幸é‹åœ°å¼•èµ·å…¶ä»–
開發人員的注æ„,並迅速改進。然而,進入staging並ä¸æ˜¯æ•…事的çµå°¾ï¼›staging中
沒有看到常è¦é€²å±•çš„代碼最終將被刪除。經銷商也傾å‘於相å°ä¸é¡˜æ„使用stagingé©…å‹•
-程åºã€‚因此,在æˆçˆ²ä¸€å€‹åˆé©çš„主線驅動的路上,staging 僅是一個中轉站。
+程åºã€‚因此,在æˆçˆ²ä¸€å€‹åˆé©çš„主線驅動的路上,staging 僅是一箇中轉站。
工具
----
@@ -260,9 +260,9 @@ Staging 是一種讓新的驅動程åºé€²å…¥ä¸»ç·šçš„相å°å®¹æ˜“的方法,它
能力。如果沒有é©ç•¶å¼·å¤§çš„工具,整個系統將無法在任何地方正常工作。關於如何使用
這些工具的教程é é è¶…出了本文檔的範åœï¼Œä½†é‚„是用一點篇幅介紹一些關éµé»žã€‚
-到目å‰çˆ²æ­¢ï¼Œå…§æ ¸ç¤¾å€ä½¿ç”¨çš„主è¦åŽŸå§‹ç¢¼ç®¡ç†ç³»çµ±æ˜¯git。Git是在自由軟體社å€ä¸­é–‹ç™¼
-的許多分布å¼ç‰ˆæœ¬æŽ§åˆ¶ç³»çµ±ä¹‹ä¸€ã€‚它éžå¸¸é©åˆå…§æ ¸é–‹ç™¼ï¼Œå› çˆ²å®ƒåœ¨è™•ç†å¤§åž‹å­˜å„²åº«å’Œ
-大é‡è£œä¸æ™‚性能éžå¸¸å¥½ã€‚它也以難以學習和使用而著稱,儘管隨著時間的推移它變得
+到目å‰çˆ²æ­¢ï¼Œå…§æ ¸ç¤¾å€ä½¿ç”¨çš„主è¦æºä»£ç¢¼ç®¡ç†ç³»çµ±æ˜¯git。Git是在自由軟件社å€ä¸­é–‹ç™¼
+的許多分佈å¼ç‰ˆæœ¬æŽ§åˆ¶ç³»çµ±ä¹‹ä¸€ã€‚它éžå¸¸é©åˆå…§æ ¸é–‹ç™¼ï¼Œå› çˆ²å®ƒåœ¨è™•ç†å¤§åž‹å­˜å„²åº«å’Œ
+大é‡è£œä¸æ™‚性能éžå¸¸å¥½ã€‚它也以難以學習和使用而著稱,儘管隨ç€æ™‚間的推移它變得
更好了。å°æ–¼å…§æ ¸é–‹ç™¼äººå“¡ä¾†èªªï¼Œå°Gitçš„æŸç¨®ç†Ÿæ‚‰å¹¾ä¹Žæ˜¯ä¸€ç¨®è¦æ±‚ï¼›å³ä½¿ä»–們ä¸å°‡å®ƒ
用於自己的工作,他們也需è¦Git來跟上其他開發人員(以åŠä¸»ç·šï¼‰æ­£åœ¨åšçš„事情。
@@ -270,7 +270,7 @@ Staging 是一種讓新的驅動程åºé€²å…¥ä¸»ç·šçš„相å°å®¹æ˜“的方法,它
https://git-scm.com/
-æ­¤é é¢åŒ…å«äº†æ–‡æª”和教程的連çµã€‚
+æ­¤é é¢åŒ…å«äº†æ–‡æª”和教程的éˆæŽ¥ã€‚
在ä¸ä½¿ç”¨git的內核開發人員中,最æµè¡Œçš„é¸æ“‡å¹¾ä¹Žè‚¯å®šæ˜¯Mercurial:
@@ -282,16 +282,16 @@ Mercurial與Git共享許多特性,但它æ供了一個界é¢ï¼Œè¨±å¤šäººè¦ºå¾
https://savannah.nongnu.org/projects/quilt
-Quilt 是一個補ä¸ç®¡ç†ç³»çµ±ï¼Œè€Œä¸æ˜¯åŽŸå§‹ç¢¼ç®¡ç†ç³»çµ±ã€‚它ä¸æœƒéš¨è‘—時間的推移跟蹤歷å²ï¼›
+Quilt 是一個補ä¸ç®¡ç†ç³»çµ±ï¼Œè€Œä¸æ˜¯æºä»£ç¢¼ç®¡ç†ç³»çµ±ã€‚它ä¸æœƒéš¨ç€æ™‚間的推移跟蹤歷å²ï¼›
相å,它é¢å‘根據ä¸æ–·ç™¼å±•çš„代碼庫跟蹤一組特定的更改。一些主è¦çš„å­ç³»çµ±ç¶­è­·äººå“¡
-使用Quilt來管ç†æ‰“ç®—å‘上游移動的補ä¸ã€‚å°æ–¼æŸäº›æ¨¹çš„管ç†ï¼ˆä¾‹å¦‚-mm),quilt 是
+使用Quilt來管ç†æ‰“ç®—å‘上éŠç§»å‹•çš„補ä¸ã€‚å°æ–¼æŸäº›æ¨¹çš„管ç†ï¼ˆä¾‹å¦‚-mm),quilt 是
最好的工具。
郵件列表
--------
大é‡çš„Linux內核開發工作是通éŽéƒµä»¶åˆ—表完æˆçš„。如果ä¸åŠ å…¥è‡³å°‘一個æŸå€‹åˆ—表,
-就很難æˆçˆ²ç¤¾å€ä¸­çš„一個「全功能ã€æˆå“¡ã€‚但是,Linux郵件列表å°é–‹ç™¼äººå“¡ä¾†èªªä¹Ÿæ˜¯
+就很難æˆçˆ²ç¤¾å€ä¸­çš„一個“全功能â€æˆå“¡ã€‚但是,Linux郵件列表å°é–‹ç™¼äººå“¡ä¾†èªªä¹Ÿæ˜¯
一個潛在的å±éšªï¼Œä»–們å¯èƒ½æœƒè¢«ä¸€å †é›»å­éƒµä»¶æ·¹æ²’ã€é•åLinux列表上使用的約定,
或者兩者兼而有之。
@@ -316,14 +316,14 @@ redhat.com/mailman/listinfo。
- ä¸è¦å›žå¾©æŒ‘事的人。如果有人試圖激起憤怒,請忽略他們。
-- 當回復Linux內核電å­éƒµä»¶ï¼ˆæˆ–其他列表上的電å­éƒµä»¶ï¼‰æ™‚,請爲所有相關人員ä¿ç•™
+- 當回覆Linux內核電å­éƒµä»¶ï¼ˆæˆ–其他列表上的電å­éƒµä»¶ï¼‰æ™‚,請爲所有相關人員ä¿ç•™
Cc: 抄é€é ­ã€‚如果沒有確實的ç†ç”±ï¼ˆå¦‚明確的請求),則ä¸æ‡‰åˆªé™¤æ”¶ä»¶äººã€‚一定è¦
確ä¿ä½ è¦å›žå¾©çš„人在抄é€åˆ—表中。這個慣例也使你ä¸å¿…在回覆郵件時明確è¦æ±‚被抄é€ã€‚
- 在æ出å•é¡Œä¹‹å‰ï¼Œæœç´¢åˆ—表存檔(和整個網絡)。有些開發人員å¯èƒ½æœƒå°é‚£äº›é¡¯ç„¶
沒有完æˆå®¶åº­ä½œæ¥­çš„人感到ä¸è€ç…©ã€‚
-- é¿å…頂部回復(把你的答案放在你è¦å›žå¾©çš„引文上é¢çš„åšæ³•ï¼‰ã€‚這會讓你的回答更難
+- é¿å…頂部回覆(把你的答案放在你è¦å›žå¾©çš„引文上é¢çš„åšæ³•ï¼‰ã€‚這會讓你的回答更難
ç†è§£ï¼Œå°è±¡ä¹Ÿå¾ˆå·®ã€‚
- 在正確的郵件列表發å•ã€‚linux-kernel å¯èƒ½æ˜¯é€šç”¨çš„討論場所,但它ä¸æ˜¯å°‹æ‰¾æ‰€æœ‰
@@ -332,7 +332,7 @@ redhat.com/mailman/listinfo。
最後一點——找到正確的郵件列表——是開發人員常出錯的地方。在linux-kernel上
æ出與網絡相關的å•é¡Œçš„人幾乎肯定會收到一個禮貌的建議,轉到netdev列表上æ出,
因爲這是大多數網絡開發人員經常出ç¾çš„列表。還有其他列表å¯ç”¨æ–¼scsiã€video4linuxã€
-ideã€filesystemç­‰å­ç³»çµ±ã€‚查找郵件列表的最佳ä½ç½®æ˜¯èˆ‡å…§æ ¸åŽŸå§‹ç¢¼ä¸€èµ·æ‰“包的
+ideã€filesystemç­‰å­ç³»çµ±ã€‚查找郵件列表的最佳ä½ç½®æ˜¯èˆ‡å…§æ ¸æºä»£ç¢¼ä¸€èµ·æ‰“包的
MAINTAINERS文件。
開始內核開發
@@ -344,7 +344,7 @@ MAINTAINERS文件。
å…¬å¸é€šå¸¸å¸Œæœ›è˜è«‹çŸ¥å的開發人員來啓動開發團隊。實際上,這是一種有效的技術。
但它也往往是昂貴的,而且å°å¢žåŠ æœ‰ç¶“驗的內核開發人員的數é‡æ²’有多大幫助。考
慮到時間投入,å¯ä»¥è®“內部開發人員加快Linux內核的開發速度。利用這段時間å¯ä»¥
-讓僱主æ“有一批既了解內核åˆäº†è§£å…¬å¸çš„開發人員,還å¯ä»¥å¹«åŠ©åŸ¹è¨“其他人。從中期
+讓僱主æ“有一批既瞭解內核åˆçž­è§£å…¬å¸çš„開發人員,還å¯ä»¥å¹«åŠ©åŸ¹è¨“其他人。從中期
來看,這通常是更有利å¯åœ–的方法。
å¯ä»¥ç†è§£çš„是,單個開發人員往往å°èµ·æ­¥æ„Ÿåˆ°èŒ«ç„¶ã€‚從一個大型項目開始å¯èƒ½æœƒå¾ˆ
@@ -353,17 +353,17 @@ MAINTAINERS文件。
這會分散整個開發社å€çš„注æ„力,因此,它們越來越被人ä¸çœ‹é‡ã€‚希望å‘社å€ä»‹ç´¹
自己的新開發人員將無法通éŽé€™äº›æ–¹å¼ç²å¾—他們期待的å響。
-Andrew Morton 爲有抱負的內核開發人員æ供了如下建議
+Andrew Morton 爲有抱負的內核開發人員æ供瞭如下建議
::
- 所有內核開發者的第一個項目肯定應該是「確ä¿å…§æ ¸åœ¨æ‚¨å¯ä»¥æ“作的所有
- 機器上始終完美é‹è¡Œã€ã€‚通常的方法是和其他人一起解決å•é¡Œï¼ˆé€™å¯èƒ½éœ€
+ 所有內核開發者的第一個項目肯定應該是“確ä¿å…§æ ¸åœ¨æ‚¨å¯ä»¥æ“作的所有
+ 機器上始終完美é‹è¡Œâ€ã€‚通常的方法是和其他人一起解決å•é¡Œï¼ˆé€™å¯èƒ½éœ€
è¦å …æŒï¼ï¼‰ï¼Œä½†å°±æ˜¯å¦‚此——這是內核開發的一部分。
(http://lwn.net/Articles/283982/)
-在沒有明顯å•é¡Œéœ€è¦è§£æ±ºçš„情æ³ä¸‹ï¼Œé€šå¸¸å»ºè­°é–‹ç™¼äººå“¡æŸ¥çœ‹ç•¶å‰çš„回歸和開放缺陷
+在沒有明顯å•é¡Œéœ€è¦è§£æ±ºçš„情æ³ä¸‹ï¼Œé€šå¸¸å»ºè­°é–‹ç™¼äººå“¡æŸ¥çœ‹ç•¶å‰çš„迴歸和開放缺陷
列表。從來都ä¸ç¼ºå°‘需è¦è§£æ±ºçš„å•é¡Œï¼›é€šéŽè§£æ±ºé€™äº›å•é¡Œï¼Œé–‹ç™¼äººå“¡å°‡å¾žè©²éŽç¨‹ç²å¾—
經驗,åŒæ™‚與開發社å€çš„其他æˆå“¡å»ºç«‹ç›¸äº’å°Šé‡ã€‚
diff --git a/Documentation/translations/zh_TW/process/3.Early-stage.rst b/Documentation/translations/zh_TW/process/3.Early-stage.rst
index 636e506fd196..a6959e6350f4 100644
--- a/Documentation/translations/zh_TW/process/3.Early-stage.rst
+++ b/Documentation/translations/zh_TW/process/3.Early-stage.rst
@@ -26,13 +26,13 @@
--------
與任何工程項目一樣,æˆåŠŸçš„內核改善從清晰æè¿°è¦è§£æ±ºçš„å•é¡Œé–‹å§‹ã€‚在æŸäº›æƒ…æ³
-下,這個步驟很容易:例如當æŸå€‹ç‰¹å®šç¡¬é«”需è¦é©…動程åºæ™‚。ä¸éŽï¼Œåœ¨å…¶ä»–情æ³ä¸‹ï¼Œ
+下,這個步驟很容易:例如當æŸå€‹ç‰¹å®šç¡¬ä»¶éœ€è¦é©…動程åºæ™‚。ä¸éŽï¼Œåœ¨å…¶ä»–情æ³ä¸‹ï¼Œ
很容易將實際å•é¡Œèˆ‡å»ºè­°çš„解決方案混在一起,這å¯èƒ½æœƒå°Žè‡´éº»ç…©ã€‚
-舉個例å­ï¼šå¹¾å¹´å‰ï¼ŒLinux音頻的開發人員尋求一種方法來é‹è¡Œæ‡‰ç”¨ç¨‹å¼ï¼Œè€Œä¸æœƒå› 
+舉個例å­ï¼šå¹¾å¹´å‰ï¼ŒLinux音頻的開發人員尋求一種方法來é‹è¡Œæ‡‰ç”¨ç¨‹åºï¼Œè€Œä¸æœƒå› 
系統延é²éŽå¤§è€Œå°Žè‡´é€€å‡ºæˆ–其他å•é¡Œã€‚他們得到的解決方案是一個連接到Linux安全
-模塊(LSM)框架中的內核模塊;這個模塊å¯ä»¥é…置爲å…許特定的應用程å¼è¨ªå•å¯¦æ™‚
-調度程åºã€‚這個模塊被實ç¾ä¸¦ç™¼åˆ°linux-kernel郵件列表,在那裡它立å³é‡åˆ°äº†éº»ç…©ã€‚
+模塊(LSM)框架中的內核模塊;這個模塊å¯ä»¥é…置爲å…許特定的應用程åºè¨ªå•å¯¦æ™‚
+調度程åºã€‚這個模塊被實ç¾ä½µç™¼åˆ°linux-kernel郵件列表,在那è£å®ƒç«‹å³é‡åˆ°äº†éº»ç…©ã€‚
å°æ–¼éŸ³é »é–‹ç™¼äººå“¡ä¾†èªªï¼Œé€™å€‹å®‰å…¨æ¨¡å¡Šè¶³ä»¥è§£æ±ºä»–們當å‰çš„å•é¡Œã€‚但是,å°æ–¼æ›´å»£æ³›çš„
內核社å€ä¾†èªªï¼Œé€™è¢«è¦–爲å°LSM框架的濫用(LSM框架並ä¸æ‰“算授予他們原本ä¸å…·å‚™çš„
@@ -41,15 +41,15 @@
然而,音頻社å€ç„¡æ³•è¶…越他們實施的特定解決方案來看å•é¡Œï¼›ä»–們ä¸é¡˜æ„接å—替代方案。
由此產生的分歧使這些開發人員å°æ•´å€‹å…§æ ¸é–‹ç™¼éŽç¨‹æ„Ÿåˆ°å¤±æœ›ï¼›å…¶ä¸­ä¸€å€‹é–‹ç™¼äººå“¡è¿”回
-到audio列表並發布了以下內容:
+到audio列表併發布了以下內容:
有很多éžå¸¸å¥½çš„Linux內核開發人員,但他們往往會被一羣傲慢的傻瓜所壓倒。
- 試圖å‘這些人傳é”用戶需求是浪費時間。他們太「è°æ˜Žã€äº†ï¼Œæ ¹æœ¬è½ä¸åˆ°å°‘數
+ 試圖å‘這些人傳é”用戶需求是浪費時間。他們太“è°æ˜Žâ€äº†ï¼Œæ ¹æœ¬è½ä¸åˆ°å°‘數
人的話。
(http://lwn.net/Articles/131776/)
-實際情æ³å»æ˜¯ä¸åŒçš„;與特定模塊相比,內核開發人員更關心系統穩定性ã€é•·æœŸç¶­è­·
+實際情æ³å»æ˜¯ä¸åŒçš„;與特定模塊相比,內核開發人員更關心繫統穩定性ã€é•·æœŸç¶­è­·
以åŠæ‰¾åˆ°å•é¡Œçš„正確解決方案。這個故事的寓æ„是把é‡é»žæ”¾åœ¨å•é¡Œä¸Šâ€”—而ä¸æ˜¯å…·é«”çš„
解決方案上——並在開始編寫代碼之å‰èˆ‡é–‹ç™¼ç¤¾å€è¨Žè«–這個å•é¡Œã€‚
@@ -72,7 +72,7 @@
- 很å¯èƒ½å•é¡Œæ˜¯ç”±å…§æ ¸ä»¥æ‚¨ä¸ç†è§£çš„æ–¹å¼è§£æ±ºçš„。Linux內核很大,具有許多ä¸æ˜Žé¡¯
的特性和功能。並ä¸æ˜¯æ‰€æœ‰çš„內核功能都åƒäººå€‘所希望的那樣有文檔記錄,而且很
- 容易éºæ¼ä¸€äº›æ±è¥¿ã€‚æŸä½œè€…發布了一個完整的驅動程åºï¼Œé‡è¤‡äº†ä¸€å€‹å…¶ä¸
+ 容易éºæ¼ä¸€äº›æ±è¥¿ã€‚æŸä½œè€…發佈了一個完整的驅動程åºï¼Œé‡è¤‡äº†ä¸€å€‹å…¶ä¸
知é“çš„ç¾æœ‰é©…動程åºã€‚é‡æ–°ç™¼æ˜Žç¾æœ‰è¼ªå­çš„代碼ä¸åƒ…浪費,而且ä¸æœƒè¢«æŽ¥å—到主線
內核中。
@@ -83,7 +83,7 @@
å¯èƒ½é¡˜æ„幫助創建這個解決方案。
在內核開發社å€çš„多年經驗給了我們一個明確的教訓:閉門設計和開發的內核代碼總是
-有一些å•é¡Œï¼Œé€™äº›å•é¡Œåªæœ‰åœ¨ä»£ç¢¼ç™¼å¸ƒåˆ°ç¤¾å€ä¸­æ™‚æ‰æœƒè¢«ç™¼ç¾ã€‚有時這些å•é¡Œå¾ˆåš´é‡ï¼Œ
+有一些å•é¡Œï¼Œé€™äº›å•é¡Œåªæœ‰åœ¨ä»£ç¢¼ç™¼ä½ˆåˆ°ç¤¾å€ä¸­æ™‚纔會被發ç¾ã€‚有時這些å•é¡Œå¾ˆåš´é‡ï¼Œ
需è¦æ•¸æœˆæˆ–數年的努力æ‰èƒ½ä½¿ä»£ç¢¼é”到內核社å€çš„標準。例如:
- 設計並實ç¾äº†å–®è™•ç†å™¨ç³»çµ±çš„DeviceScape網絡棧。åªæœ‰ä½¿å…¶é©åˆæ–¼å¤šè™•ç†å™¨ç³»çµ±ï¼Œ
@@ -103,16 +103,16 @@
找誰交æµï¼Ÿ
----------
-當開發人員決定公開他們的計劃時,下一個å•é¡Œæ˜¯ï¼šæˆ‘們從哪裡開始?答案是找到正確
+當開發人員決定公開他們的計劃時,下一個å•é¡Œæ˜¯ï¼šæˆ‘們從哪è£é–‹å§‹ï¼Ÿç­”案是找到正確
的郵件列表和正確的維護者。å°æ–¼éƒµä»¶åˆ—表,最好的方法是在維護者(MAINTAINERS)文件
-中查找è¦ç™¼å¸ƒçš„相關ä½ç½®ã€‚如果有一個åˆé©çš„å­ç³»çµ±åˆ—表,那麼其上發布通常比在
-linux-kernel上發布更å¯å–;您更有å¯èƒ½æŽ¥è§¸åˆ°åœ¨ç›¸é—œå­ç³»çµ±ä¸­å…·æœ‰å°ˆæ¥­çŸ¥è­˜çš„開發
+中查找è¦ç™¼ä½ˆçš„相關ä½ç½®ã€‚如果有一個åˆé©çš„å­ç³»çµ±åˆ—表,那麼其上發佈通常比在
+linux-kernel上發佈更å¯å–;您更有å¯èƒ½æŽ¥è§¸åˆ°åœ¨ç›¸é—œå­ç³»çµ±ä¸­å…·æœ‰å°ˆæ¥­çŸ¥è­˜çš„開發
人員,並且環境å¯èƒ½å…·æ”¯æŒæ€§ã€‚
找到維護人員å¯èƒ½æœƒæœ‰é»žå›°é›£ã€‚åŒæ¨£ï¼Œç¶­è­·è€…文件是開始的地方。但是,該文件往往ä¸
-是最新的,並且並éžæ‰€æœ‰å­ç³»çµ±éƒ½åœ¨é‚£è£¡é¡¯ç¤ºã€‚實際上,維護者文件中列出的人員å¯èƒ½
+是最新的,並且並éžæ‰€æœ‰å­ç³»çµ±éƒ½åœ¨é‚£è£é¡¯ç¤ºã€‚實際上,維護者文件中列出的人員å¯èƒ½
ä¸æ˜¯ç•¶å‰å¯¦éš›æ“”任該角色的人員。因此,當å°è¯ç¹«èª°æœ‰ç–‘å•æ™‚,一個有用的技巧是使用
-git(尤其是「git-logã€ï¼‰æŸ¥çœ‹æ„Ÿèˆˆè¶£çš„å­ç³»çµ±ä¸­ç•¶å‰æ´»å‹•çš„用戶。看看誰在寫補ä¸ã€
+git(尤其是“git-logâ€ï¼‰æŸ¥çœ‹æ„Ÿèˆˆè¶£çš„å­ç³»çµ±ä¸­ç•¶å‰æ´»å‹•çš„用戶。看看誰在寫補ä¸ã€
誰會在這些補ä¸ä¸ŠåŠ ä¸ŠSigned-off-by行簽å(如有)。這些人將是幫助新開發項目的
最佳人é¸ã€‚
@@ -123,7 +123,7 @@ git(尤其是「git-logã€ï¼‰æŸ¥çœ‹æ„Ÿèˆˆè¶£çš„å­ç³»çµ±ä¸­ç•¶å‰æ´»å‹•çš„用æ
.../scripts/get_maintainer.pl
-當給定「-fã€é¸é …時,此腳本將返回指定文件或目錄的當å‰ç¶­è­·è€…。如果在命令行上
+當給定“-fâ€é¸é …時,此腳本將返回指定文件或目錄的當å‰ç¶­è­·è€…。如果在命令行上
給出了一個補ä¸ï¼Œå®ƒå°‡åˆ—出å¯èƒ½æŽ¥æ”¶è£œä¸å‰¯æœ¬çš„維護人員。有許多é¸é …å¯ä»¥èª¿ç¯€
get_maintainer.plæœç´¢ç¶­è­·è€…的嚴格程度;請å°å¿ƒä½¿ç”¨æ›´æ¿€é€²çš„é¸é …,因爲最終çµæžœ
å¯èƒ½æœƒåŒ…括å°æ‚¨æ­£åœ¨ä¿®æ”¹çš„代碼沒有真正興趣的開發人員。
@@ -134,17 +134,17 @@ get_maintainer.plæœç´¢ç¶­è­·è€…的嚴格程度;請å°å¿ƒä½¿ç”¨æ›´æ¿€é€²çš„é¸
何時郵寄?
----------
-如果å¯èƒ½çš„話,在早期階段發布你的計劃åªæœƒæ›´æœ‰å¹«åŠ©ã€‚æ述正在解決的å•é¡Œä»¥åŠå·²ç¶“
+如果å¯èƒ½çš„話,在早期階段發佈你的計劃åªæœƒæ›´æœ‰å¹«åŠ©ã€‚æ述正在解決的å•é¡Œä»¥åŠå·²ç¶“
制定的關於如何實施的任何計劃。您å¯ä»¥æ供的任何信æ¯éƒ½å¯ä»¥å¹«åŠ©é–‹ç™¼ç¤¾å€çˆ²é …ç›®
æ供有用的輸入。
在這個階段å¯èƒ½ç™¼ç”Ÿçš„一件令人沮喪的事情ä¸æ˜¯å¾—到åå°æ„見,而是很少或根本沒有
å饋。令人傷心的事實是:(1)內核開發人員往往很忙;(2)ä¸ç¼ºå°‘有å®å‰è¨ˆåŠƒä½†
代碼(甚至代碼設想)很少的人去支æŒä»–們;(3)沒有人有義務審查或評論別人發表
-的想法。除此之外,高層級的設計常常隱è—著一些å•é¡Œï¼Œé€™äº›å•é¡Œåªæœ‰åœ¨æœ‰äººçœŸæ­£å˜—試
-實ç¾é€™äº›è¨­è¨ˆæ™‚æ‰æœƒè¢«ç™¼ç¾ï¼›å› æ­¤ï¼Œå…§æ ¸é–‹ç™¼äººå“¡å¯§é¡˜çœ‹åˆ°ä»£ç¢¼ã€‚
+的想法。除此之外,高層級的設計常常隱è—ç€ä¸€äº›å•é¡Œï¼Œé€™äº›å•é¡Œåªæœ‰åœ¨æœ‰äººçœŸæ­£å˜—試
+實ç¾é€™äº›è¨­è¨ˆæ™‚纔會被發ç¾ï¼›å› æ­¤ï¼Œå…§æ ¸é–‹ç™¼äººå“¡å¯§é¡˜çœ‹åˆ°ä»£ç¢¼ã€‚
-如果發布請求評論(RFC)並沒得到什麼有用的評論,ä¸è¦ä»¥çˆ²é€™æ„味著無人å°æ­¤é …ç›®
+如果發佈請求評論(RFC)並沒得到什麼有用的評論,ä¸è¦ä»¥çˆ²é€™æ„味ç€ç„¡äººå°æ­¤é …ç›®
有興趣,åŒæ™‚你也ä¸èƒ½å‡è¨­ä½ çš„想法沒有å•é¡Œã€‚在這種情æ³ä¸‹ï¼Œæœ€å¥½çš„åšæ³•æ˜¯ç¹¼çºŒé€²
行,把你的進展隨時通知社å€ã€‚
@@ -152,12 +152,12 @@ get_maintainer.plæœç´¢ç¶­è­·è€…的嚴格程度;請å°å¿ƒä½¿ç”¨æ›´æ¿€é€²çš„é¸
-----------------------
如果您的工作是在公å¸ç’°å¢ƒä¸­å®Œæˆçš„,就åƒå¤§å¤šæ•¸Linux內核工作一樣;顯然,在您將
-å…¬å¸çš„計劃或代碼發布到公共郵件列表之å‰ï¼Œå¿…é ˆç²å¾—有é©ç•¶æ¬Šåˆ©ç¶“ç†çš„許å¯ã€‚發布
-ä¸ç¢ºå®šæ˜¯å¦å…¼å®¹GPL的代碼尤其會帶來å•é¡Œï¼›å…¬å¸çš„管ç†å±¤å’Œæ³•å¾‹äººå“¡è¶Šæ—©èƒ½å¤ å°±ç™¼å¸ƒ
+å…¬å¸çš„計劃或代碼發佈到公共郵件列表之å‰ï¼Œå¿…é ˆç²å¾—有é©ç•¶æ¬Šåˆ©ç¶“ç†çš„許å¯ã€‚發佈
+ä¸ç¢ºå®šæ˜¯å¦å…¼å®¹GPL的代碼尤其會帶來å•é¡Œï¼›å…¬å¸çš„管ç†å±¤å’Œæ³•å¾‹äººå“¡è¶Šæ—©èƒ½å¤ å°±ç™¼ä½ˆ
內核開發項目é”æˆä¸€è‡´ï¼Œå°åƒèˆ‡çš„æ¯å€‹äººéƒ½è¶Šå¥½ã€‚
一些讀者å¯èƒ½æœƒèªçˆ²ä»–們的核心工作是爲了支æŒé‚„沒有正å¼æ‰¿èªå­˜åœ¨çš„產å“。將僱主
-的計劃公布在公共郵件列表上å¯èƒ½ä¸æ˜¯ä¸€å€‹å¯è¡Œçš„é¸æ“‡ã€‚在這種情æ³ä¸‹ï¼Œæœ‰å¿…è¦è€ƒæ…®
+的計劃公佈在公共郵件列表上å¯èƒ½ä¸æ˜¯ä¸€å€‹å¯è¡Œçš„é¸æ“‡ã€‚在這種情æ³ä¸‹ï¼Œæœ‰å¿…è¦è€ƒæ…®
ä¿å¯†æ˜¯å¦çœŸçš„是必è¦çš„;通常ä¸éœ€è¦æŠŠé–‹ç™¼è¨ˆåŠƒé—œåœ¨é–€å…§ã€‚
的確,有些情æ³ä¸‹ä¸€å®¶å…¬å¸åœ¨é–‹ç™¼éŽç¨‹çš„早期無法åˆæ³•åœ°æŠ«éœ²å…¶è¨ˆåŠƒã€‚æ“有經驗è±å¯Œ
diff --git a/Documentation/translations/zh_TW/process/4.Coding.rst b/Documentation/translations/zh_TW/process/4.Coding.rst
index adb5339aab6a..7a4e01eabd81 100644
--- a/Documentation/translations/zh_TW/process/4.Coding.rst
+++ b/Documentation/translations/zh_TW/process/4.Coding.rst
@@ -19,7 +19,7 @@
======================
雖然一個堅實的ã€é¢å‘社å€çš„設計éŽç¨‹æœ‰å¾ˆå¤šå€¼å¾—說é“的,但是任何內核開發項目工作
-的證明都å映在代碼中。它是將由其他開發人員檢查併åˆä¸¦ï¼ˆæˆ–ä¸åˆä½µï¼‰åˆ°ä¸»ç·šæ¨¹ä¸­
+的證明都å映在代碼中。它是將由其他開發人員檢查併åˆä¸¦ï¼ˆæˆ–ä¸åˆä¸¦ï¼‰åˆ°ä¸»ç·šæ¨¹ä¸­
的代碼。所以這段代碼的質é‡æ±ºå®šäº†é …目的最終æˆåŠŸã€‚
本節將檢查編碼éŽç¨‹ã€‚我們將從內核開發人員常犯的幾種錯誤開始。然後é‡é»žå°‡è½‰ç§»
@@ -32,7 +32,7 @@
********
內核長期以來都有其標準的代碼風格,如
-:ref:`Documentation/translations/zh_TW/process/coding-style.rst <tw_codingstyle>`
+:ref:`Documentation/translations/zh_CN/process/coding-style.rst <tw_codingstyle>`
中所述。在多數時候,該文檔中æ述的準則至多被èªçˆ²æ˜¯å»ºè­°æ€§çš„。因此,內核中存在
大é‡ä¸ç¬¦åˆä»£ç¢¼é¢¨æ ¼æº–則的代碼。這種代碼的存在會給內核開發人員帶來兩方é¢çš„å±å®³ã€‚
@@ -42,7 +42,7 @@
開發人員能夠快速ç†è§£å…¶ä¸­çš„任何部分。所以å†ä¹Ÿç¶“ä¸èµ·å¥‡æ€ªæ ¼å¼çš„代碼的折騰了。
內核的代碼風格å¶çˆ¾æœƒèˆ‡åƒ±ä¸»çš„強制風格發生è¡çªã€‚在這種情æ³ä¸‹ï¼Œå¿…須在代碼åˆä½µ
-之å‰éµå¾žå…§æ ¸ä»£ç¢¼é¢¨æ ¼ã€‚將代碼放入內核æ„味著以多種方å¼æ”¾æ£„一定程度的控制權——
+之å‰éµå¾žå…§æ ¸ä»£ç¢¼é¢¨æ ¼ã€‚將代碼放入內核æ„味ç€ä»¥å¤šç¨®æ–¹å¼æ”¾æ£„一定程度的控制權——
包括控制代碼樣å¼ã€‚
å¦ä¸€å€‹å±å®³æ˜¯èªçˆ²å·²ç¶“在內核中的代碼迫切需è¦ä¿®å¾©ä»£ç¢¼æ¨£å¼ã€‚開發者å¯èƒ½æœƒé–‹å§‹ç·¨å¯«
@@ -70,21 +70,21 @@
簡單點,先考慮一個調用時始終åªæœ‰ä¸€å€‹åƒæ•¸ä¸”總爲零的函數。我們å¯ä»¥ä¿ç•™é€™å€‹åƒæ•¸ï¼Œ
以在需è¦ä½¿ç”¨å®ƒæ™‚æ供的é¡å¤–éˆæ´»æ€§ã€‚ä¸éŽï¼Œåœ¨é‚£æ™‚實ç¾äº†é€™å€‹é¡å¤–åƒæ•¸çš„代碼很有
å¯èƒ½ä»¥æŸç¨®å¾žæœªè¢«æ³¨æ„到的微妙方å¼è¢«ç ´å£žâ€”—因爲它從未被使用éŽã€‚或者當需è¦é¡å¤–
-çš„éˆæ´»æ€§æ™‚,它並未以符åˆç¨‹å¼è¨­è¨ˆå¸«ç•¶åˆæœŸæœ›çš„æ–¹å¼ä¾†å¯¦ç¾ã€‚內核開發人員通常會æ交
+çš„éˆæ´»æ€§æ™‚,它並未以符åˆç¨‹åºå“¡ç•¶åˆæœŸæœ›çš„æ–¹å¼ä¾†å¯¦ç¾ã€‚內核開發人員通常會æ交
補ä¸ä¾†åˆªé™¤æœªä½¿ç”¨çš„åƒæ•¸ï¼›ä¸€èˆ¬ä¾†èªªï¼Œä¸€é–‹å§‹å°±ä¸æ‡‰è©²æ·»åŠ é€™äº›åƒæ•¸ã€‚
-éš±è—硬體訪å•çš„抽象層——通常爲了å…許大é‡çš„驅動程åºå…¼å®¹å¤šå€‹ä½œæ¥­ç³»çµ±â€”—尤其ä¸å—
+éš±è—硬件訪å•çš„抽象層——通常爲了å…許大é‡çš„驅動程åºå…¼å®¹å¤šå€‹æ“作系統——尤其ä¸å—
歡迎。這樣的層使代碼變得模糊,å¯èƒ½æœƒé€ æˆæ€§èƒ½æ失;它們ä¸å±¬æ–¼Linux內核。
å¦ä¸€æ–¹é¢ï¼Œå¦‚果您發ç¾è‡ªå·±å¾žå¦ä¸€å€‹å…§æ ¸å­ç³»çµ±è¤‡è£½äº†å¤§é‡çš„代碼,那麼是時候
-了解一下:是å¦éœ€è¦å°‡é€™äº›ä»£ç¢¼ä¸­çš„部分æå–到單ç¨çš„庫中,或者在更高的層次上
+瞭解一下:是å¦éœ€è¦å°‡é€™äº›ä»£ç¢¼ä¸­çš„部分æå–到單ç¨çš„庫中,或者在更高的層次上
實ç¾é€™äº›åŠŸèƒ½ã€‚在整個內核中複製相åŒçš„代碼沒有價值。
#ifdef å’Œé è™•ç†
***************
-Cé è™•ç†å™¨ä¼¼ä¹Žçµ¦ä¸€äº›C程å¼è¨­è¨ˆå¸«å¸¶ä¾†äº†å¼·å¤§çš„誘惑,他們èªçˆ²å®ƒæ˜¯ä¸€ç¨®å°‡å¤§é‡éˆæ´»æ€§åŠ å…¥
-原始碼中的方法。但是é è™•ç†å™¨ä¸æ˜¯C,大é‡ä½¿ç”¨å®ƒæœƒå°Žè‡´ä»£ç¢¼å°å…¶ä»–人來說更難閱讀,
+Cé è™•ç†å™¨ä¼¼ä¹Žçµ¦ä¸€äº›C程åºå“¡å¸¶ä¾†äº†å¼·å¤§çš„誘惑,他們èªçˆ²å®ƒæ˜¯ä¸€ç¨®å°‡å¤§é‡éˆæ´»æ€§åŠ å…¥
+æºä»£ç¢¼ä¸­çš„方法。但是é è™•ç†å™¨ä¸æ˜¯C,大é‡ä½¿ç”¨å®ƒæœƒå°Žè‡´ä»£ç¢¼å°å…¶ä»–人來說更難閱讀,
å°ç·¨è­¯å™¨ä¾†èªªæ›´é›£æª¢æŸ¥æ­£ç¢ºæ€§ã€‚使用了大é‡é è™•ç†å™¨å¹¾ä¹Žç¸½æ˜¯ä»£ç¢¼éœ€è¦ä¸€äº›
清ç†å·¥ä½œçš„標誌。
@@ -100,23 +100,23 @@ Cé è™•ç†å™¨å®å­˜åœ¨è¨±å¤šå±éšªæ€§ï¼ŒåŒ…括å¯èƒ½å°å…·æœ‰å‰¯ä½œç”¨ä¸”沒有é
å…§è¯å‡½æ•¸
********
-ä¸éŽï¼Œå…§è¯å‡½æ•¸æœ¬èº«ä¹Ÿå­˜åœ¨é¢¨éšªã€‚程å¼è¨­è¨ˆå¸«å¯ä»¥å‚¾å¿ƒæ–¼é¿å…函數調用和用內è¯å‡½æ•¸å¡«å……æº
+ä¸éŽï¼Œå…§è¯å‡½æ•¸æœ¬èº«ä¹Ÿå­˜åœ¨é¢¨éšªã€‚程åºå“¡å¯ä»¥å‚¾å¿ƒæ–¼é¿å…函數調用和用內è¯å‡½æ•¸å¡«å……æº
文件所固有的效率。然而,這些功能實際上會é™ä½Žæ€§èƒ½ã€‚因爲它們的代碼在æ¯å€‹èª¿ç”¨ç«™
-點都被複製一é,所以最終會增加編譯內核的大å°ã€‚此外,這也å°è™•ç†å™¨çš„內存緩存
+點都被複制一é,所以最終會增加編譯內核的大å°ã€‚此外,這也å°è™•ç†å™¨çš„內存緩存
造æˆå£“力,從而大大é™ä½ŽåŸ·è¡Œé€Ÿåº¦ã€‚通常內è¯å‡½æ•¸æ‡‰è©²éžå¸¸å°ï¼Œè€Œä¸”相å°è¼ƒå°‘。畢竟
函數調用的æˆæœ¬ä¸¦ä¸é«˜ï¼›å¤§é‡å‰µå»ºå…§è¯å‡½æ•¸æ˜¯éŽæ—©å„ªåŒ–的典型例å­ã€‚
-一般來說,內核程å¼è¨­è¨ˆå¸«æœƒè‡ªå†’風險忽略緩存效果。在數據çµæ§‹èª²ç¨‹é–‹é ­ä¸­çš„經典
-時間/空間權衡通常ä¸é©ç”¨æ–¼ç•¶ä»£ç¡¬é«”。空間 *就是* 時間,因爲一個大的程åºæ¯”一個
+一般來說,內核程åºå“¡æœƒè‡ªå†’風險忽略緩存效果。在數據çµæ§‹èª²ç¨‹é–‹é ­ä¸­çš„經典
+時間/空間權衡通常ä¸é©ç”¨æ–¼ç•¶ä»£ç¡¬ä»¶ã€‚空間 *就是* 時間,因爲一個大的程åºæ¯”一個
更緊湊的程åºé‹è¡Œå¾—慢。
較新的編譯器越來越激進地決定一個給定函數是å¦æ‡‰è©²å…§è¯ã€‚因此,隨æ„放置使用
-「inlineã€é—œéµå­—å¯èƒ½ä¸åƒ…僅是éŽåº¦çš„,也å¯èƒ½æ˜¯ç„¡ç”¨çš„。
+“inlineâ€é—œéµå­—å¯èƒ½ä¸åƒ…僅是éŽåº¦çš„,也å¯èƒ½æ˜¯ç„¡ç”¨çš„。
鎖
**
-2006å¹´5月,「deviceescapeã€ç¶²çµ¡å †æ£§åœ¨å‰å‘¼å¾Œæ“下以GPL發布,並被ç´å…¥ä¸»ç·šå…§æ ¸ã€‚
+2006å¹´5月,“deviceescapeâ€ç¶²çµ¡å †æ£§åœ¨å‰å‘¼å¾Œæ“下以GPL發佈,並被ç´å…¥ä¸»ç·šå…§æ ¸ã€‚
這是一個å—歡迎的消æ¯ï¼›Linux中å°ç„¡ç·šç¶²çµ¡çš„支æŒå……å…¶é‡è¢«èªçˆ²æ˜¯ä¸åˆæ ¼çš„,而
Deviceescape堆棧承諾修復這種情æ³ã€‚然而直到2007å¹´6月(2.6.22),這段代碼æ‰çœŸ
正進入主線。發生了什麼?
@@ -125,25 +125,25 @@ Deviceescape堆棧承諾修復這種情æ³ã€‚然而直到2007å¹´6月(2.6.22)
設計。在åˆä½µé€™å€‹ç¶²çµ¡å †æ£§ï¼ˆç¾åœ¨ç¨±çˆ²mac80211)之å‰ï¼Œéœ€è¦å°å…¶é€²è¡Œä¸€å€‹éŽ–方案的
改造。
-曾經,Linux內核代碼å¯ä»¥åœ¨ä¸è€ƒæ…®å¤šè™•ç†å™¨ç³»çµ±æ‰€å¸¶ä¾†çš„並發性å•é¡Œçš„情æ³ä¸‹é€²è¡Œ
+曾經,Linux內核代碼å¯ä»¥åœ¨ä¸è€ƒæ…®å¤šè™•ç†å™¨ç³»çµ±æ‰€å¸¶ä¾†çš„併發性å•é¡Œçš„情æ³ä¸‹é€²è¡Œ
開發。然而ç¾åœ¨ï¼Œé€™å€‹æ–‡æª”就是在雙核筆記本電腦上寫的。å³ä½¿åœ¨å–®è™•ç†å™¨ç³»çµ±ä¸Šï¼Œ
-爲æ高響應能力所åšçš„工作也會æ高內核內的並發性水平。編寫內核代碼而ä¸è€ƒæ…®éŽ–
+爲æ高響應能力所åšçš„工作也會æ高內核內的併發性水平。編寫內核代碼而ä¸è€ƒæ…®éŽ–
çš„æ—¥å­æ—©å·²é åŽ»ã€‚
-å¯ä»¥ç”±å¤šå€‹ç·šç¨‹ä¸¦ç™¼è¨ªå•çš„任何資æºï¼ˆæ•¸æ“šçµæ§‹ã€ç¡¬é«”寄存器等)必須由鎖ä¿è­·ã€‚æ–°
+å¯ä»¥ç”±å¤šå€‹ç·šç¨‹ä½µç™¼è¨ªå•çš„任何資æºï¼ˆæ•¸æ“šçµæ§‹ã€ç¡¬ä»¶å¯„存器等)必須由鎖ä¿è­·ã€‚æ–°
的代碼應該謹記這一è¦æ±‚;事後修改鎖是一項相當困難的任務。內核開發人員應該花
-時間充分了解å¯ç”¨çš„鎖原語,以便爲工作é¸æ“‡æ­£ç¢ºçš„工具。å°ä¸¦ç™¼æ€§ç¼ºä¹é—œæ³¨çš„代碼
+時間充分了解å¯ç”¨çš„鎖原語,以便爲工作é¸æ“‡æ­£ç¢ºçš„工具。å°ä½µç™¼æ€§ç¼ºä¹é—œæ³¨çš„代碼
很難進入主線。
-回歸
+è¿´æ­¸
****
-最後一個值得一æçš„å±éšªæ˜¯å›žæ­¸ï¼šå®ƒå¯èƒ½æœƒå¼•èµ·å°Žè‡´ç¾æœ‰ç”¨æˆ¶çš„æŸäº›æ±è¥¿ä¸­æ–·çš„改變
-(這也å¯èƒ½æœƒå¸¶ä¾†å¾ˆå¤§çš„改進)。這種變化被稱爲「回歸ã€ï¼Œå›žæ­¸å·²ç¶“æˆçˆ²ä¸»ç·šå…§æ ¸
-最ä¸å—æ­¡è¿Žçš„å•é¡Œã€‚除了少數例外情æ³ï¼Œå¦‚果回歸ä¸èƒ½åŠæ™‚修正,會導致回歸的修改
-將被å–消。最好首先é¿å…回歸發生。
+最後一個值得一æçš„å±éšªæ˜¯è¿´æ­¸ï¼šå®ƒå¯èƒ½æœƒå¼•èµ·å°Žè‡´ç¾æœ‰ç”¨æˆ¶çš„æŸäº›æ±è¥¿ä¸­æ–·çš„改變
+(這也å¯èƒ½æœƒå¸¶ä¾†å¾ˆå¤§çš„改進)。這種變化被稱爲“迴歸â€ï¼Œè¿´æ­¸å·²ç¶“æˆçˆ²ä¸»ç·šå…§æ ¸
+最ä¸å—æ­¡è¿Žçš„å•é¡Œã€‚除了少數例外情æ³ï¼Œå¦‚果迴歸ä¸èƒ½åŠæ™‚修正,會導致迴歸的修改
+將被å–消。最好首先é¿å…迴歸發生。
-人們常常爭論,如果回歸帶來的功能é è¶…éŽç”¢ç”Ÿçš„å•é¡Œï¼Œé‚£éº¼å›žæ­¸æ˜¯å¦çˆ²å¯æŽ¥å—的。
+人們常常爭論,如果迴歸帶來的功能é è¶…éŽç”¢ç”Ÿçš„å•é¡Œï¼Œé‚£éº¼è¿´æ­¸æ˜¯å¦çˆ²å¯æŽ¥å—的。
如果它破壞了一個系統å»çˆ²å個系統帶來新的功能,爲何ä¸æ”¹æ”¹æ…‹åº¦å‘¢ï¼Ÿ2007å¹´7月,
Linuså°é€™å€‹å•é¡Œçµ¦å‡ºäº†æœ€ä½³ç­”案:
@@ -154,7 +154,7 @@ Linuså°é€™å€‹å•é¡Œçµ¦å‡ºäº†æœ€ä½³ç­”案:
(http://lwn.net/Articles/243460/)
-特別ä¸å—歡迎的一種回歸類型是用戶空間ABI的任何變化。一旦接å£è¢«å°Žå‡ºåˆ°ç”¨æˆ¶ç©ºé–“,
+特別ä¸å—歡迎的一種迴歸類型是用戶空間ABI的任何變化。一旦接å£è¢«å°Žå‡ºåˆ°ç”¨æˆ¶ç©ºé–“,
就必須無é™æœŸåœ°æ”¯æŒå®ƒã€‚這一事實使得用戶空間接å£çš„創建特別具有挑戰性:因爲它們
ä¸èƒ½ä»¥ä¸å…¼å®¹çš„æ–¹å¼é€²è¡Œæ›´æ”¹ï¼Œæ‰€ä»¥å¿…須一次就å°ã€‚因此,用戶空間接å£ç¸½æ˜¯éœ€è¦å¤§é‡
çš„æ€è€ƒã€æ¸…晰的文檔和廣泛的審查。
@@ -171,19 +171,19 @@ Linuså°é€™å€‹å•é¡Œçµ¦å‡ºäº†æœ€ä½³ç­”案:
第一步是注æ„編譯器產生的警告。當å‰ç‰ˆæœ¬çš„GCCå¯ä»¥æª¢æ¸¬ï¼ˆä¸¦è­¦å‘Šï¼‰å¤§é‡æ½›åœ¨éŒ¯èª¤ã€‚
通常,這些警告都指å‘真正的å•é¡Œã€‚æ交以供審閱的代碼一般ä¸æœƒç”¢ç”Ÿä»»ä½•ç·¨è­¯å™¨è­¦å‘Šã€‚
-在消除警告時,注æ„了解真正的原因,並儘é‡é¿å…僅「修復ã€ä½¿è­¦å‘Šæ¶ˆå¤±è€Œä¸è§£æ±ºå…¶åŽŸå› ã€‚
+在消除警告時,注æ„瞭解真正的原因,並儘é‡é¿å…僅“修復â€ä½¿è­¦å‘Šæ¶ˆå¤±è€Œä¸è§£æ±ºå…¶åŽŸå› ã€‚
-請注æ„,並éžæ‰€æœ‰ç·¨è­¯å™¨è­¦å‘Šéƒ½é»˜èªå•“用。使用「make KCFLAGS=-Wã€æ§‹å»ºå…§æ ¸ä»¥
+請注æ„,並éžæ‰€æœ‰ç·¨è­¯å™¨è­¦å‘Šéƒ½é»˜èªå•“用。使用“make KCFLAGS=-Wâ€æ§‹å»ºå…§æ ¸ä»¥
ç²å¾—完整集åˆã€‚
-內核æ供了幾個é…ç½®é¸é …,å¯ä»¥æ‰“開調試功能;大多數é…ç½®é¸é …ä½æ–¼ã€Œkernel hackingã€
+內核æ供了幾個é…ç½®é¸é …,å¯ä»¥æ‰“開調試功能;大多數é…ç½®é¸é …ä½æ–¼â€œkernel hackingâ€
å­èœå–®ä¸­ã€‚å°æ–¼ä»»ä½•ç”¨æ–¼é–‹ç™¼æˆ–測試目的的內核,都應該啓用其中幾個é¸é …。特別是,
您應該打開:
- FRAME_WARN ç²å–大於給定數é‡çš„堆棧幀的警告。
這些警告生æˆçš„輸出å¯èƒ½æ¯”較冗長,但您ä¸å¿…擔心來自內核其他部分的警告。
- - DEBUG_OBJECTS 將添加代碼以跟蹤內核創建的å„種å°è±¡çš„生命周期,並在出ç¾å•é¡Œ
+ - DEBUG_OBJECTS 將添加代碼以跟蹤內核創建的å„種å°è±¡çš„生命週期,並在出ç¾å•é¡Œ
時發出警告。如果你è¦æ·»åŠ å‰µå»ºï¼ˆå’Œå°Žå‡ºï¼‰é—œæ–¼å…¶è‡ªå·±çš„複雜å°è±¡çš„å­ç³»çµ±ï¼Œè«‹
考慮打開å°è±¡èª¿è©¦åŸºç¤Žçµæ§‹çš„支æŒã€‚
@@ -195,34 +195,34 @@ Linuså°é€™å€‹å•é¡Œçµ¦å‡ºäº†æœ€ä½³ç­”案:
還有很多其他調試é¸é …,其中一些將在下é¢è¨Žè«–。其中一些有顯著的性能影響,ä¸æ‡‰
一直使用。在學習å¯ç”¨é¸é …上花費一些時間,å¯èƒ½æœƒåœ¨çŸ­æœŸå…§å¾—到許多回報。
-其中一個較é‡çš„調試工具是鎖檢查器或「lockdepã€ã€‚該工具將跟蹤系統中æ¯å€‹éŽ–
+其中一個較é‡çš„調試工具是鎖檢查器或“lockdepâ€ã€‚該工具將跟蹤系統中æ¯å€‹éŽ–
(spinlock或mutex)的ç²å–和釋放ã€ç²å–鎖的相å°é †åºã€ç•¶å‰ä¸­æ–·ç’°å¢ƒç­‰ç­‰ã€‚然後,
它å¯ä»¥ç¢ºä¿ç¸½æ˜¯ä»¥ç›¸åŒçš„é †åºç²å–鎖,相åŒçš„中斷å‡è¨­é©ç”¨æ–¼æ‰€æœ‰æƒ…æ³ç­‰ç­‰ã€‚æ›å¥è©±
說,lockdepå¯ä»¥æ‰¾åˆ°è¨±å¤šå°Žè‡´ç³»çµ±æ­»éŽ–的場景。在部署的系統中,這種å•é¡Œå¯èƒ½æœƒ
很痛苦(å°æ–¼é–‹ç™¼äººå“¡å’Œç”¨æˆ¶è€Œè¨€ï¼‰ï¼›LockDepå…許æå‰ä»¥è‡ªå‹•æ–¹å¼ç™¼ç¾å•é¡Œã€‚具有
-任何類型的éžæ™®é€šéŽ–的代碼在æ交åˆä½µå‰æ‡‰åœ¨å•“用lockdep的情æ³ä¸‹é‹è¡Œæ¸¬è©¦ã€‚
+任何類型的éžæ™®é€šéŽ–的代碼在æ交åˆä¸¦å‰æ‡‰åœ¨å•“用lockdep的情æ³ä¸‹é‹è¡Œæ¸¬è©¦ã€‚
-作爲一個勤奮的內核程å¼è¨­è¨ˆå¸«ï¼Œæ¯«ç„¡ç–‘å•ï¼Œæ‚¨å°‡æª¢æŸ¥ä»»ä½•å¯èƒ½å¤±æ•—çš„æ“作(如內存分é…)
+作爲一個勤奮的內核程åºå“¡ï¼Œæ¯«ç„¡ç–‘å•ï¼Œæ‚¨å°‡æª¢æŸ¥ä»»ä½•å¯èƒ½å¤±æ•—çš„æ“作(如內存分é…)
的返回狀態。然而,事實上,最終的故障復ç¾è·¯å¾‘å¯èƒ½å®Œå…¨æ²’有經éŽæ¸¬è©¦ã€‚未測試的
代碼往往會出å•é¡Œï¼›å¦‚果所有這些錯誤處ç†è·¯å¾‘都被執行了幾次,那麼您å¯èƒ½å°ä»£ç¢¼
更有信心。
內核æ供了一個å¯ä»¥åšåˆ°é€™ä¸€é»žçš„錯誤注入框架,特別是在涉åŠå…§å­˜åˆ†é…的情æ³ä¸‹ã€‚
啓用故障注入後,內存分é…çš„å¯é…置失敗的百分比;這些失敗å¯ä»¥é™å®šåœ¨ç‰¹å®šçš„代碼
-範åœå…§ã€‚在啓用了故障注入的情æ³ä¸‹é‹è¡Œï¼Œç¨‹å¼è¨­è¨ˆå¸«å¯ä»¥çœ‹åˆ°ç•¶æƒ…æ³æƒ¡åŒ–時代碼如何響
+範åœå…§ã€‚在啓用了故障注入的情æ³ä¸‹é‹è¡Œï¼Œç¨‹åºå“¡å¯ä»¥çœ‹åˆ°ç•¶æƒ…æ³æƒ¡åŒ–時代碼如何響
應。有關如何使用此工具的詳細信æ¯ï¼Œè«‹åƒé–±
Documentation/fault-injection/fault-injection.rst。
-「sparseã€éœæ…‹åˆ†æžå·¥å…·å¯ä»¥ç™¼ç¾å…¶ä»–類型的錯誤。sparseå¯ä»¥è­¦å‘Šç¨‹å¼è¨­è¨ˆå¸«ç”¨æˆ¶ç©ºé–“
+“sparseâ€éœæ…‹åˆ†æžå·¥å…·å¯ä»¥ç™¼ç¾å…¶ä»–類型的錯誤。sparseå¯ä»¥è­¦å‘Šç¨‹åºå“¡ç”¨æˆ¶ç©ºé–“
和內核空間地å€ä¹‹é–“çš„æ··æ·†ã€å¤§ç«¯åºèˆ‡å°ç«¯åºçš„æ··æ·†ã€åœ¨éœ€è¦ä¸€çµ„ä½æ¨™èªŒçš„地方傳éž
-整數值等等。sparse必須單ç¨å®‰è£(如果您的分發伺æœå™¨æ²’有將其打包,
+整數值等等。sparse必須單ç¨å®‰è£(如果您的分發æœå‹™å™¨æ²’有將其打包,
å¯ä»¥åœ¨ https://sparse.wiki.kernel.org/index.php/Main_page 找到),
-然後å¯ä»¥é€šéŽåœ¨make命令中添加「C=1ã€åœ¨ä»£ç¢¼ä¸Šé‹è¡Œå®ƒã€‚
+然後å¯ä»¥é€šéŽåœ¨make命令中添加“C=1â€åœ¨ä»£ç¢¼ä¸Šé‹è¡Œå®ƒã€‚
-「Coccinelleã€å·¥å…· :ref:`http://coccinelle.lip6.fr/ <devtools_coccinelle>`
-能夠發ç¾å„種潛在的編碼å•é¡Œï¼›å®ƒé‚„å¯ä»¥çˆ²é€™äº›å•é¡Œæ出修複方案。在
-scripts/coccinelle目錄下已經打包了相當多的內核「語義補ä¸ã€ï¼›é‹è¡Œ
-「make coccicheckã€å°‡é‹è¡Œé€™äº›èªžç¾©è£œä¸ä¸¦å ±å‘Šç™¼ç¾çš„任何å•é¡Œã€‚有關詳細信æ¯ï¼Œè«‹åƒé–±
+“Coccinelleâ€å·¥å…· :ref:`http://coccinelle.lip6.fr/ <devtools_coccinelle>`
+能夠發ç¾å„種潛在的編碼å•é¡Œï¼›å®ƒé‚„å¯ä»¥çˆ²é€™äº›å•é¡Œæ出修復方案。在
+scripts/coccinelle目錄下已經打包了相當多的內核“語義補ä¸â€ï¼›é‹è¡Œ
+“make coccicheckâ€å°‡é‹è¡Œé€™äº›èªžç¾©è£œä¸ä¸¦å ±å‘Šç™¼ç¾çš„任何å•é¡Œã€‚有關詳細信æ¯ï¼Œè«‹åƒé–±
:ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>`
@@ -247,7 +247,7 @@ scripts/coccinelle目錄下已經打包了相當多的內核「語義補ä¸ã€ï¼
任何添加新用戶空間接å£çš„代碼——包括新的sysfs或/proc文件——都應該包å«è©²æŽ¥å£
的文檔,該文檔使用戶空間開發人員能夠知é“他們在使用什麼。請åƒé–±
-Documentation/ABI/README,了解如何此文檔格å¼ä»¥åŠéœ€è¦æ供哪些信æ¯ã€‚
+Documentation/ABI/README,瞭解如何此文檔格å¼ä»¥åŠéœ€è¦æ供哪些信æ¯ã€‚
文檔 :ref:`Documentation/admin-guide/kernel-parameters.rst <kernelparameters>`
æ述了內核的所有引導時間åƒæ•¸ã€‚任何添加新åƒæ•¸çš„補ä¸éƒ½æ‡‰è©²å‘該文檔添加é©ç•¶çš„
@@ -256,27 +256,27 @@ Documentation/ABI/README,了解如何此文檔格å¼ä»¥åŠéœ€è¦æ供哪些ä¿
任何新的é…ç½®é¸é …都必須附有幫助文本,幫助文本需清楚地解釋這些é¸é …以åŠç”¨æˆ¶å¯èƒ½
希望何時使用它們。
-許多å­ç³»çµ±çš„內部APIä¿¡æ¯é€šéŽå°ˆé–€æ ¼å¼åŒ–的注釋進行記錄;這些注釋å¯ä»¥é€šéŽ
-「kernel-docã€è…³æœ¬ä»¥å¤šç¨®æ–¹å¼æå–和格å¼åŒ–。如果您在具有kerneldoc注釋的å­ç³»çµ±ä¸­
+許多å­ç³»çµ±çš„內部APIä¿¡æ¯é€šéŽå°ˆé–€æ ¼å¼åŒ–的註釋進行記錄;這些註釋å¯ä»¥é€šéŽ
+“kernel-docâ€è…³æœ¬ä»¥å¤šç¨®æ–¹å¼æå–和格å¼åŒ–。如果您在具有kerneldoc註釋的å­ç³»çµ±ä¸­
工作,則應該維護它們,並根據需è¦çˆ²å¤–部å¯ç”¨çš„功能添加它們。å³ä½¿åœ¨æ²’有如此記錄
-的領域中,爲將來添加kerneldoc注釋也沒有壞處;實際上,這å°æ–¼å‰›é–‹å§‹é–‹ç™¼å…§æ ¸çš„人
-來說是一個有用的活動。這些注釋的格å¼ä»¥åŠå¦‚何創建kerneldoc模æ¿çš„一些信æ¯å¯ä»¥åœ¨
+的領域中,爲將來添加kerneldoc註釋也沒有壞處;實際上,這å°æ–¼å‰›é–‹å§‹é–‹ç™¼å…§æ ¸çš„人
+來說是一個有用的活動。這些註釋的格å¼ä»¥åŠå¦‚何創建kerneldoc模æ¿çš„一些信æ¯å¯ä»¥åœ¨
:ref:`Documentation/doc-guide/ <doc_guide>` 上找到。
-任何閱讀大é‡ç¾æœ‰å…§æ ¸ä»£ç¢¼çš„人都會注æ„到,注釋的缺失往往是最值得注æ„的。åŒæ™‚,
-å°æ–°ä»£ç¢¼çš„è¦æ±‚比éŽåŽ»æ›´é«˜ï¼›åˆä½µæœªæ³¨é‡‹çš„代碼將更加困難。這就是說,人們並ä¸æœŸæœ›
-詳細注釋的代碼。代碼本身應該是自解釋的,注釋闡釋了更微妙的方é¢ã€‚
+任何閱讀大é‡ç¾æœ‰å…§æ ¸ä»£ç¢¼çš„人都會注æ„到,註釋的缺失往往是最值得注æ„的。åŒæ™‚,
+å°æ–°ä»£ç¢¼çš„è¦æ±‚比éŽåŽ»æ›´é«˜ï¼›åˆä½µæœªè¨»é‡‹çš„代碼將更加困難。這就是說,人們並ä¸æœŸæœ›
+詳細註釋的代碼。代碼本身應該是自解釋的,註釋闡釋了更微妙的方é¢ã€‚
-æŸäº›äº‹æƒ…應該總是被注釋。使用內存å±éšœæ™‚,應附上一行文字,解釋爲什麼需è¦è¨­ç½®å…§å­˜
+æŸäº›äº‹æƒ…應該總是被註釋。使用內存å±éšœæ™‚,應附上一行文字,解釋爲什麼需è¦è¨­ç½®å…§å­˜
å±éšœã€‚數據çµæ§‹çš„鎖è¦å‰‡é€šå¸¸éœ€è¦åœ¨æŸå€‹åœ°æ–¹è§£é‡‹ã€‚一般來說,主è¦æ•¸æ“šçµæ§‹éœ€è¦å…¨é¢
的文檔。應該指出代碼中分立的ä½ä¹‹é–“ä¸æ˜Žé¡¯çš„ä¾è³´æ€§ã€‚任何å¯èƒ½èª˜ä½¿ä»£ç¢¼ç®¡ç†äººé€²è¡Œ
-錯誤的「清ç†ã€çš„事情都需è¦ä¸€å€‹æ³¨é‡‹ä¾†èªªæ˜Žçˆ²ä»€éº¼è¦é€™æ¨£åšã€‚等等。
+錯誤的“清ç†â€çš„事情都需è¦ä¸€å€‹è¨»é‡‹ä¾†èªªæ˜Žçˆ²ä»€éº¼è¦é€™æ¨£åšã€‚等等。
內部API更改
-----------
-內核æ供給用戶空間的二進ä½æŽ¥å£ä¸èƒ½è¢«ç ´å£žï¼Œé™¤éžé€¼ä¸å¾—已。而內核的內部編程接å£
+內核æ供給用戶空間的二進制接å£ä¸èƒ½è¢«ç ´å£žï¼Œé™¤éžé€¼ä¸å¾—已。而內核的內部編程接å£
是高度æµå‹•çš„,當需è¦æ™‚å¯ä»¥æ›´æ”¹ã€‚如果你發ç¾è‡ªå·±ä¸å¾—ä¸è™•ç†ä¸€å€‹å…§æ ¸API,或者僅
僅因爲它ä¸æ»¿è¶³ä½ çš„需求導致無法使用特定的功能,這å¯èƒ½æ˜¯API需è¦æ”¹è®Šçš„一個標誌。
作爲內核開發人員,您有權進行此類更改。
@@ -287,7 +287,7 @@ Documentation/ABI/README,了解如何此文檔格å¼ä»¥åŠéœ€è¦æ供哪些ä¿
å¦ä¸€å€‹è¦é»žæ˜¯ï¼Œæ›´æ”¹å…§éƒ¨API的開發人員通常è¦è² è²¬ä¿®å¾©å…§æ ¸æ¨¹ä¸­è¢«æ›´æ”¹ç ´å£žçš„任何代碼。
å°æ–¼ä¸€å€‹å»£æ³›ä½¿ç”¨çš„函數,這個責任å¯ä»¥å°Žè‡´æˆç™¾ä¸Šåƒçš„變化,其中許多變化å¯èƒ½èˆ‡å…¶ä»–
-開發人員正在åšçš„工作相è¡çªã€‚ä¸ç”¨èªªï¼Œé€™å¯èƒ½æ˜¯ä¸€é …大工程,所以最好確ä¿ç†ç”±æ˜¯
+開發人員正在åšçš„工作相沖çªã€‚ä¸ç”¨èªªï¼Œé€™å¯èƒ½æ˜¯ä¸€é …大工程,所以最好確ä¿ç†ç”±æ˜¯
å¯é çš„。請注æ„,coccinelle工具å¯ä»¥å¹«åŠ©é€²è¡Œå»£æ³›çš„API更改。
在進行ä¸å…¼å®¹çš„API更改時,應儘å¯èƒ½ç¢ºä¿ç·¨è­¯å™¨æ•ç²æœªæ›´æ–°çš„代碼。這將幫助您確ä¿æ‰¾
diff --git a/Documentation/translations/zh_TW/process/5.Posting.rst b/Documentation/translations/zh_TW/process/5.Posting.rst
index 27015622ad63..d398dda427aa 100644
--- a/Documentation/translations/zh_TW/process/5.Posting.rst
+++ b/Documentation/translations/zh_TW/process/5.Posting.rst
@@ -15,27 +15,27 @@
.. _tw_development_posting:
-發布補ä¸
+發佈補ä¸
========
您的工作é²æ—©æœƒæº–備好æ交給社å€é€²è¡Œå¯©æŸ¥ï¼Œä¸¦æœ€çµ‚包å«åˆ°ä¸»ç·šå…§æ ¸ä¸­ã€‚毫ä¸ç¨€å¥‡ï¼Œ
-內核開發社å€å·²ç¶“發展出一套用於發布補ä¸çš„約定和éŽç¨‹ï¼›éµå¾ªé€™äº›ç´„定和éŽç¨‹å°‡ä½¿
+內核開發社å€å·²ç¶“發展出一套用於發佈補ä¸çš„約定和éŽç¨‹ï¼›éµå¾ªé€™äº›ç´„定和éŽç¨‹å°‡ä½¿
åƒèˆ‡å…¶ä¸­çš„æ¯å€‹äººçš„生活更加輕鬆。本文檔試圖æ述這些約定的部分細節;更多信æ¯
也å¯åœ¨ä»¥ä¸‹æ–‡æª”中找到
-:ref:`Documentation/translations/zh_TW/process/submitting-patches.rst <tw_submittingpatches>`
-和 :ref:`Documentation/translations/zh_TW/process/submit-checklist.rst <tw_submitchecklist>`。
+:ref:`Documentation/translations/zh_CN/process/submitting-patches.rst <tw_submittingpatches>`
+和 :ref:`Documentation/translations/zh_CN/process/submit-checklist.rst <tw_submitchecklist>`。
-何時郵寄
+何時寄é€
--------
-在補ä¸å®Œå…¨ã€Œæº–備好ã€ä¹‹å‰ï¼Œé¿å…發布補ä¸æ˜¯ä¸€ç¨®æŒçºŒçš„誘惑。å°æ–¼ç°¡å–®çš„補ä¸ï¼Œé€™
+在補ä¸å®Œå…¨â€œæº–備好â€ä¹‹å‰ï¼Œé¿å…發佈補ä¸æ˜¯ä¸€ç¨®æŒçºŒçš„誘惑。å°æ–¼ç°¡å–®çš„補ä¸ï¼Œé€™
ä¸æ˜¯å•é¡Œã€‚但是如果正在完æˆçš„工作很複雜,那麼在工作完æˆä¹‹å‰å¾žç¤¾å€ç²å¾—å饋就
-å¯ä»¥ç²å¾—很多好處。因此,您應該考慮發布正在進行的工作,甚至維護一個å¯ç”¨çš„Git
+å¯ä»¥ç²å¾—很多好處。因此,您應該考慮發佈正在進行的工作,甚至維護一個å¯ç”¨çš„Git
樹,以便感興趣的開發人員å¯ä»¥éš¨æ™‚趕上您的工作。
-當發布中有尚未準備好被包å«çš„代碼,最好在發布中說明。還應æåŠä»»ä½•æœ‰å¾…完æˆçš„
+當發佈中有尚未準備好被包å«çš„代碼,最好在發佈中說明。還應æåŠä»»ä½•æœ‰å¾…完æˆçš„
主è¦å·¥ä½œå’Œä»»ä½•å·²çŸ¥å•é¡Œã€‚很少有人會願æ„看那些被èªçˆ²æ˜¯åŠç”Ÿä¸ç†Ÿçš„補ä¸ï¼Œä½†æ˜¯
-那些願æ„的人會帶著他們的點å­ä¾†ä¸€èµ·å¹«åŠ©ä½ æŠŠå·¥ä½œæŽ¨å‘正確的方å‘。
+那些願æ„的人會帶ç€ä»–們的點å­ä¾†ä¸€èµ·å¹«åŠ©ä½ æŠŠå·¥ä½œæŽ¨å‘正確的方å‘。
創建補ä¸ä¹‹å‰
------------
@@ -50,20 +50,20 @@
- 您的更改是å¦å…·æœ‰æ€§èƒ½å½±éŸ¿ï¼Ÿå¦‚果是這樣,您應該é‹è¡ŒåŸºæº–測試來顯示您的變更的
影響(或好處);çµæžœçš„摘è¦æ‡‰è©²åŒ…å«åœ¨è£œä¸ä¸­ã€‚
- - 確ä¿æ‚¨æœ‰æ¬Šç™¼å¸ƒä»£ç¢¼ã€‚如果這項工作是爲僱主完æˆçš„,僱主å°é€™é …工作具有所有權,
- 並且必須åŒæ„根據GPLå°å…¶é€²è¡Œç™¼å¸ƒã€‚
+ - 確ä¿æ‚¨æœ‰æ¬Šç™¼ä½ˆä»£ç¢¼ã€‚如果這項工作是爲僱主完æˆçš„,僱主å°é€™é …工作具有所有權,
+ 並且必須åŒæ„根據GPLå°å…¶é€²è¡Œç™¼ä½ˆã€‚
-一般來說,在發布代碼之å‰é€²è¡Œä¸€äº›é¡å¤–çš„æ€è€ƒï¼Œå¹¾ä¹Žç¸½æ˜¯èƒ½åœ¨çŸ­æ™‚間內得到回報。
+一般來說,在發佈代碼之å‰é€²è¡Œä¸€äº›é¡å¤–çš„æ€è€ƒï¼Œå¹¾ä¹Žç¸½æ˜¯èƒ½åœ¨çŸ­æ™‚間內得到回報。
補ä¸æº–å‚™
--------
-準備補ä¸ç™¼å¸ƒçš„工作é‡å¯èƒ½å¾ˆé©šäººï¼Œä½†åœ¨æ­¤å˜—試節çœæ™‚間通常是ä¸æ˜Žæ™ºçš„,å³ä½¿åœ¨çŸ­æœŸ
+準備補ä¸ç™¼ä½ˆçš„工作é‡å¯èƒ½å¾ˆé©šäººï¼Œä½†åœ¨æ­¤å˜—試節çœæ™‚間通常是ä¸æ˜Žæ™ºçš„,å³ä½¿åœ¨çŸ­æœŸ
內亦然。
å¿…é ˆé‡å°å…§æ ¸çš„特定版本準備補ä¸ã€‚一般來說,補ä¸æ‡‰è©²åŸºæ–¼Linusçš„Git樹中的當å‰
-主線。當以主線爲基礎時,請從一個衆所周知的發布點開始——如穩定版本或 -rc
-版本發布點——而ä¸æ˜¯åœ¨ä¸€å€‹ä»»æ„的主線分支點。
+主線。當以主線爲基礎時,請從一個衆所周知的發佈點開始——如穩定版本或 -rc
+版本發佈點——而ä¸æ˜¯åœ¨ä¸€å€‹ä»»æ„的主線分支點。
也å¯èƒ½éœ€è¦é‡å°-mmã€linux-next或å­ç³»çµ±æ¨¹ç”Ÿæˆç‰ˆæœ¬ï¼Œä»¥ä¾¿æ–¼æ›´å»£æ³›çš„測試和審查。
根據補ä¸çš„å€åŸŸä»¥åŠå…¶ä»–地方的情æ³ï¼Œé‡å°å…¶ä»–樹建立的補ä¸å¯èƒ½éœ€è¦å¤§é‡çš„工作來
@@ -73,12 +73,12 @@
分割補ä¸æ˜¯ä¸€é–€è—術;一些開發人員花了很長時間來弄清楚如何按照社å€æœŸæœ›çš„æ–¹å¼ä¾†
分割。ä¸éŽï¼Œé€™äº›ç¶“驗法則也許有幫助:
- - 您發布的補ä¸ç³»åˆ—幾乎肯定ä¸æœƒæ˜¯é–‹ç™¼éŽç¨‹ä¸­ç‰ˆæœ¬æŽ§åˆ¶ç³»çµ±ä¸­çš„一系列更改。相å,
+ - 您發佈的補ä¸ç³»åˆ—幾乎肯定ä¸æœƒæ˜¯é–‹ç™¼éŽç¨‹ä¸­ç‰ˆæœ¬æŽ§åˆ¶ç³»çµ±ä¸­çš„一系列更改。相å,
需è¦å°æ‚¨æ‰€åšæ›´æ”¹çš„最終形å¼åŠ ä»¥è€ƒæ…®ï¼Œç„¶å¾Œä»¥æœ‰æ„義的方å¼é€²è¡Œæ‹†åˆ†ã€‚開發人員å°
離散的ã€è‡ªåŒ…å«çš„更改感興趣,而ä¸æ˜¯æ‚¨å‰µé€ é€™äº›æ›´æ”¹çš„原始路徑。
- - æ¯å€‹é‚輯上ç¨ç«‹çš„變更都應該格å¼åŒ–爲單ç¨çš„補ä¸ã€‚這些更改å¯ä»¥æ˜¯å°çš„(如「å‘
- æ­¤çµæ§‹é«”添加欄ä½ã€ï¼‰æˆ–大的(如添加一個é‡è¦çš„新驅動程åºï¼‰ï¼Œä½†å®ƒå€‘在概念上
+ - æ¯å€‹é‚輯上ç¨ç«‹çš„變更都應該格å¼åŒ–爲單ç¨çš„補ä¸ã€‚這些更改å¯ä»¥æ˜¯å°çš„(如“å‘
+ æ­¤çµæ§‹é«”添加字段â€ï¼‰æˆ–大的(如添加一個é‡è¦çš„新驅動程åºï¼‰ï¼Œä½†å®ƒå€‘在概念上
應該是å°çš„,並且å¯ä»¥åœ¨ä¸€è¡Œå…§ç°¡è¿°ã€‚æ¯å€‹è£œä¸éƒ½æ‡‰è©²åšä¸€å€‹ç‰¹å®šçš„ã€å¯ä»¥å–®ç¨
檢查並驗證它所åšçš„事情的更改。
@@ -88,34 +88,34 @@
- æ¯å€‹è£œä¸éƒ½æ‡‰è©²èƒ½å‰µå»ºä¸€å€‹å¯ä»¥æ­£ç¢ºåœ°æ§‹å»ºå’Œé‹è¡Œçš„內核;如果補ä¸ç³»åˆ—在中間被
斷開,那麼çµæžœä»æ‡‰æ˜¯ä¸€å€‹æ­£å¸¸å·¥ä½œçš„內核。部分應用一系列補ä¸æ˜¯ä½¿ç”¨
- 「git bisctã€å·¥å…·æŸ¥æ‰¾å›žæ­¸çš„一個常見場景;如果çµæžœæ˜¯ä¸€å€‹æ壞的內核,那麼將使
+ “git bisctâ€å·¥å…·æŸ¥æ‰¾å›žæ­¸çš„一個常見場景;如果çµæžœæ˜¯ä¸€å€‹æ壞的內核,那麼將使
那些從事追蹤å•é¡Œçš„高尚工作的開發人員和用戶的生活更加艱難。
- ä¸è¦éŽåˆ†åˆ†å‰²ã€‚一ä½é–‹ç™¼äººå“¡æ›¾ç¶“將一組é‡å°å–®å€‹æ–‡ä»¶çš„編輯分æˆ500個單ç¨çš„補ä¸
- 發布,這並沒有使他æˆçˆ²å…§æ ¸éƒµä»¶åˆ—表中最å—歡迎的人。一個補ä¸å¯ä»¥ç›¸ç•¶å¤§ï¼Œ
+ 發佈,這並沒有使他æˆçˆ²å…§æ ¸éƒµä»¶åˆ—表中最å—歡迎的人。一個補ä¸å¯ä»¥ç›¸ç•¶å¤§ï¼Œ
åªè¦å®ƒä»ç„¶åŒ…å«ä¸€å€‹å–®ä¸€çš„ *é‚輯* 變更。
- 用一系列補ä¸æ·»åŠ ä¸€å€‹å…¨æ–°çš„基礎設施,但是該設施在系列中的最後一個補ä¸å•“用
整個變更之å‰ä¸èƒ½ä½¿ç”¨ï¼Œé€™çœ‹èµ·ä¾†å¾ˆèª˜äººã€‚如果å¯èƒ½çš„話,應該é¿å…這種誘惑;
- 如果這個系列增加了回歸,那麼二分法將指出最後一個補ä¸æ˜¯å°Žè‡´å•é¡Œçš„補ä¸ï¼Œ
+ 如果這個系列增加了迴歸,那麼二分法將指出最後一個補ä¸æ˜¯å°Žè‡´å•é¡Œçš„補ä¸ï¼Œ
å³ä½¿çœŸæ­£çš„bug在其他地方。åªè¦æœ‰å¯èƒ½ï¼Œæ·»åŠ æ–°ä»£ç¢¼çš„補ä¸ç¨‹åºæ‡‰è©²ç«‹å³æ¿€æ´»è©²
代碼。
-創建完美補ä¸ç³»åˆ—的工作å¯èƒ½æ˜¯ä¸€å€‹ä»¤äººæ²®å–ªçš„éŽç¨‹ï¼Œåœ¨å®Œæˆã€ŒçœŸæ­£çš„工作ã€ä¹‹å¾Œéœ€è¦
+創建完美補ä¸ç³»åˆ—的工作å¯èƒ½æ˜¯ä¸€å€‹ä»¤äººæ²®å–ªçš„éŽç¨‹ï¼Œåœ¨å®Œæˆâ€œçœŸæ­£çš„工作â€ä¹‹å¾Œéœ€è¦
花費大é‡çš„時間和æ€è€ƒã€‚但是如果åšå¾—好,花費的時間就是值得的。
補ä¸æ ¼å¼å’Œæ›´æ”¹æ—¥èªŒ
------------------
-所以ç¾åœ¨ä½ æœ‰äº†ä¸€ç³»åˆ—完美的補ä¸å¯ä»¥ç™¼å¸ƒï¼Œä½†æ˜¯é€™é …工作還沒有完æˆã€‚æ¯å€‹è£œä¸éƒ½
+所以ç¾åœ¨ä½ æœ‰äº†ä¸€ç³»åˆ—完美的補ä¸å¯ä»¥ç™¼ä½ˆï¼Œä½†æ˜¯é€™é …工作還沒有完æˆã€‚æ¯å€‹è£œä¸éƒ½
需è¦è¢«æ ¼å¼åŒ–æˆä¸€æ¢æ¶ˆæ¯ï¼Œä»¥å¿«é€Ÿè€Œæ¸…晰地將其目的傳é”到世界其他地方。爲此,
æ¯å€‹è£œä¸å°‡ç”±ä»¥ä¸‹éƒ¨åˆ†çµ„æˆï¼š
- - å¯é¸çš„「Fromã€è¡Œï¼Œè¡¨æ˜Žè£œä¸ä½œè€…。åªæœ‰ç•¶ä½ é€šéŽé›»å­éƒµä»¶ç™¼é€åˆ¥äººçš„補ä¸æ™‚,這一行
- æ‰æ˜¯å¿…須的,但是爲防止疑å•åŠ ä¸Šå®ƒä¹Ÿä¸æœƒæœ‰ä»€éº¼å£žè™•ã€‚
+ - å¯é¸çš„“Fromâ€è¡Œï¼Œè¡¨æ˜Žè£œä¸ä½œè€…。åªæœ‰ç•¶ä½ é€šéŽé›»å­éƒµä»¶ç™¼é€åˆ¥äººçš„補ä¸æ™‚,這一行
+ 纔是必須的,但是爲防止疑å•åŠ ä¸Šå®ƒä¹Ÿä¸æœƒæœ‰ä»€éº¼å£žè™•ã€‚
- 一行æ述,說明補ä¸çš„作用。å°æ–¼åœ¨æ²’有其他上下文的情æ³ä¸‹çœ‹åˆ°è©²æ¶ˆæ¯çš„讀者來說,
- 該消æ¯æ‡‰è¶³ä»¥ç¢ºå®šä¿®è£œç¨‹åºçš„範åœï¼›æ­¤è¡Œå°‡é¡¯ç¤ºåœ¨ã€Œshort form(簡短格å¼ï¼‰ã€è®Šæ›´
+ 該消æ¯æ‡‰è¶³ä»¥ç¢ºå®šä¿®è£œç¨‹åºçš„範åœï¼›æ­¤è¡Œå°‡é¡¯ç¤ºåœ¨â€œshort form(簡短格å¼ï¼‰â€è®Šæ›´
日誌中。此消æ¯é€šå¸¸éœ€è¦å…ˆåŠ ä¸Šå­ç³»çµ±å稱å‰ç¶´ï¼Œç„¶å¾Œæ˜¯è£œä¸çš„目的。例如:
::
@@ -144,17 +144,17 @@
一般來說,你越把自己放在æ¯å€‹é–±è®€ä½ è®Šæ›´æ—¥èªŒçš„人的ä½ç½®ä¸Šï¼Œè®Šæ›´æ—¥èªŒï¼ˆå’Œå…§æ ¸
作爲一個整體)就越好。
-ä¸æ¶ˆèªªï¼Œè®Šæ›´æ—¥èªŒæ˜¯å°‡è®Šæ›´æ交到版本控制系統時使用的文本。接下來將是:
+ä¸éœ€è¦èªªï¼Œè®Šæ›´æ—¥èªŒæ˜¯å°‡è®Šæ›´æ交到版本控制系統時使用的文本。接下來將是:
- - 補ä¸æœ¬èº«ï¼ŒæŽ¡ç”¨çµ±ä¸€çš„(「-uã€ï¼‰è£œä¸æ ¼å¼ã€‚使用「-pã€é¸é …來diff將使函數å與
+ - 補ä¸æœ¬èº«ï¼ŒæŽ¡ç”¨çµ±ä¸€çš„(“-uâ€ï¼‰è£œä¸æ ¼å¼ã€‚使用“-pâ€é¸é …來diff將使函數å與
更改相關è¯ï¼Œå¾žè€Œä½¿çµæžœè£œä¸æ›´å®¹æ˜“被其他人讀å–。
您應該é¿å…在補ä¸ä¸­åŒ…括與更改ä¸ç›¸é—œæ–‡ä»¶ï¼ˆä¾‹å¦‚,構建éŽç¨‹ç”Ÿæˆçš„文件或編輯器
-備份文件)。文檔目錄中的「dontdiffã€æ–‡ä»¶åœ¨é€™æ–¹é¢æœ‰å¹«åŠ©ï¼›ä½¿ç”¨ã€Œ-Xã€é¸é …å°‡
+備份文件)。文檔目錄中的“dontdiffâ€æ–‡ä»¶åœ¨é€™æ–¹é¢æœ‰å¹«åŠ©ï¼›ä½¿ç”¨â€œ-Xâ€é¸é …å°‡
其傳éžçµ¦diff。
上é¢æ到的標籤(tag)用於æè¿°å„種開發人員如何與這個補ä¸çš„開發相關è¯ã€‚
-:ref:`Documentation/translations/zh_TW/process/submitting-patches.rst <tw_submittingpatches>`
+:ref:`Documentation/translations/zh_CN/process/submitting-patches.rst <tw_submittingpatches>`
文檔中å°å®ƒå€‘進行了詳細æ述;下é¢æ˜¯ä¸€å€‹ç°¡çŸ­çš„總çµã€‚æ¯ä¸€è¡Œçš„æ ¼å¼å¦‚下:
::
@@ -165,14 +165,14 @@
- Signed-off-by: 這是一個開發人員的證明,證明他或她有權æ交補ä¸ä»¥åŒ…å«åˆ°å…§æ ¸
中。這表明åŒæ„開發者來æºèªè­‰å”議,其全文見
- :ref:`Documentation/translations/zh_TW/process/submitting-patches.rst <tw_submittingpatches>`
+ :ref:`Documentation/translations/zh_CN/process/submitting-patches.rst <tw_submittingpatches>`
如果沒有åˆé©çš„簽字,則ä¸èƒ½åˆä½µåˆ°ä¸»ç·šä¸­ã€‚
- Co-developed-by: è²æ˜Žè£œä¸æ˜¯ç”±å¤šå€‹é–‹ç™¼äººå“¡å…±åŒå‰µå»ºçš„;當幾個人在一個補ä¸ä¸Š
工作時,它用於給出共åŒä½œè€…(除了 From: 所給出的作者之外)。由於
Co-developed-by: 表示作者身份,所以æ¯å€‹å…±åŒé–‹ç™¼äººï¼Œå¿…須緊跟在相關åˆä½œä½œè€…
的Signed-off-by之後。具體內容和示例見以下文件
- :ref:`Documentation/translations/zh_TW/process/submitting-patches.rst <tw_submittingpatches>`
+ :ref:`Documentation/translations/zh_CN/process/submitting-patches.rst <tw_submittingpatches>`
- Acked-by: 表示å¦ä¸€å€‹é–‹ç™¼äººå“¡ï¼ˆé€šå¸¸æ˜¯ç›¸é—œä»£ç¢¼çš„維護人員)åŒæ„補ä¸é©åˆåŒ…å«
在內核中。
@@ -180,7 +180,7 @@
- Tested-by: è²æ˜ŽæŸäººå·²ç¶“測試了補ä¸ä¸¦ç¢ºèªå®ƒå¯ä»¥å·¥ä½œã€‚
- Reviewed-by: 表示æŸé–‹ç™¼äººå“¡å·²ç¶“審查了補ä¸çš„正確性;有關詳細信æ¯ï¼Œè«‹åƒé–±
- :ref:`Documentation/translations/zh_TW/process/submitting-patches.rst <tw_submittingpatches>`
+ :ref:`Documentation/translations/zh_CN/process/submitting-patches.rst <tw_submittingpatches>`
- Reported-by: 指定報告此補ä¸ä¿®å¾©çš„å•é¡Œçš„用戶;此標記用於表示感è¬ã€‚
@@ -188,16 +188,16 @@
在補ä¸ä¸­æ·»åŠ æ¨™ç±¤æ™‚è¦å°å¿ƒï¼šåªæœ‰Cc:æ‰é©åˆåœ¨æ²’有指定人員明確許å¯çš„情æ³ä¸‹æ·»åŠ ã€‚
-發é€è£œä¸
+寄é€è£œä¸
--------
-在寄出補ä¸ä¹‹å‰ï¼Œæ‚¨é‚„需è¦æ³¨æ„以下幾點:
+在寄é€è£œä¸ä¹‹å‰ï¼Œæ‚¨é‚„需è¦æ³¨æ„以下幾點:
- 您確定您的郵件發é€ç¨‹åºä¸æœƒæ壞補ä¸å—Žï¼Ÿè¢«éƒµä»¶å®¢æˆ¶ç«¯æ›´æ”¹ç©ºç™½æˆ–修飾了行的補ä¸
無法被å¦ä¸€ç«¯æŽ¥å—,並且通常ä¸æœƒé€²è¡Œä»»ä½•è©³ç´°æª¢æŸ¥ã€‚如果有任何疑å•ï¼Œå…ˆæŠŠè£œä¸å¯„
給你自己,讓你自己確定它是完好無æ的。
- :ref:`Documentation/translations/zh_TW/process/email-clients.rst <tw_email_clients>`
+ :ref:`Documentation/translations/zh_CN/process/email-clients.rst <tw_email_clients>`
æ供了一些有用的æ示,å¯ä»¥è®“特定的郵件客戶端正常發é€è£œä¸ã€‚
- 你確定你的補ä¸æ²’有è’å”的錯誤嗎?您應該始終通éŽscripts/checkpatch.pl檢查
@@ -209,12 +209,12 @@
引用補ä¸çš„部分。相å,åªéœ€å°‡è£œä¸ç›´æŽ¥æ”¾åˆ°æ‚¨çš„消æ¯ä¸­ã€‚
寄出補ä¸æ™‚,é‡è¦çš„是將副本發é€çµ¦ä»»ä½•å¯èƒ½æ„Ÿèˆˆè¶£çš„人。與其他一些項目ä¸åŒï¼Œå…§æ ¸
-鼓勵人們甚至錯誤地發é€éŽå¤šçš„副本;ä¸è¦å‡å®šç›¸é—œäººå“¡æœƒçœ‹åˆ°æ‚¨åœ¨éƒµä»¶åˆ—表中的發布。
+鼓勵人們甚至錯誤地發é€éŽå¤šçš„副本;ä¸è¦å‡å®šç›¸é—œäººå“¡æœƒçœ‹åˆ°æ‚¨åœ¨éƒµä»¶åˆ—表中的發佈。
尤其是,副本應發é€è‡³ï¼š
- å—影響å­ç³»çµ±çš„維護人員。如å‰æ‰€è¿°ï¼Œç¶­è­·äººå“¡æ–‡ä»¶æ˜¯æŸ¥æ‰¾é€™äº›äººå“¡çš„首é¸åœ°æ–¹ã€‚
- - 其他在åŒä¸€é ˜åŸŸå·¥ä½œçš„開發人員,尤其是那些ç¾åœ¨å¯èƒ½åœ¨é‚£è£¡å·¥ä½œçš„開發人員。使用
+ - 其他在åŒä¸€é ˜åŸŸå·¥ä½œçš„開發人員,尤其是那些ç¾åœ¨å¯èƒ½åœ¨é‚£è£å·¥ä½œçš„開發人員。使用
git查看還有誰修改了您正在處ç†çš„文件,這很有幫助。
- 如果您å°æŸéŒ¯èª¤å ±å‘Šæˆ–功能請求åšå‡ºéŸ¿æ‡‰ï¼Œä¹Ÿå¯ä»¥æŠ„é€åŽŸå§‹ç™¼é€äººã€‚
@@ -223,7 +223,7 @@
- 如果您正在修復一個缺陷,請考慮該修復是å¦æ‡‰é€²å…¥ä¸‹ä¸€å€‹ç©©å®šæ›´æ–°ã€‚如果是這樣,
補ä¸å‰¯æœ¬ä¹Ÿæ‡‰ç™¼åˆ°stable@vger.kernel.org 。å¦å¤–,在補ä¸æœ¬èº«çš„標籤中添加一個
- 「Cc: stable@vger.kernel.orgã€ï¼›é€™å°‡ä½¿ç©©å®šç‰ˆåœ˜éšŠåœ¨ä¿®å¾©é€²å…¥ä¸»ç·šæ™‚收到通知。
+ “Cc: stable@vger.kernel.orgâ€ï¼›é€™å°‡ä½¿ç©©å®šç‰ˆåœ˜éšŠåœ¨ä¿®å¾©é€²å…¥ä¸»ç·šæ™‚收到通知。
當爲一個補ä¸é¸æ“‡æŽ¥æ”¶è€…時,最好清楚你èªçˆ²èª°æœ€çµ‚會接å—這個補ä¸ä¸¦å°‡å…¶åˆä½µã€‚雖然
å¯ä»¥å°‡è£œä¸ç›´æŽ¥ç™¼çµ¦Linus Torvalds並讓他åˆä½µï¼Œä½†é€šå¸¸æƒ…æ³ä¸‹ä¸æœƒé€™æ¨£åšã€‚Linus很
@@ -236,7 +236,7 @@
[PATCH nn/mm] subsys: one-line description of the patch
-其中「nnã€æ˜¯è£œä¸çš„åºè™Ÿï¼Œã€Œmmã€æ˜¯ç³»åˆ—中補ä¸çš„總數,「subsysã€æ˜¯å—影響å­ç³»çµ±çš„
+其中“nnâ€æ˜¯è£œä¸çš„åºè™Ÿï¼Œâ€œmmâ€æ˜¯ç³»åˆ—中補ä¸çš„總數,“subsysâ€æ˜¯å—影響å­ç³»çµ±çš„
å稱。當然,一個單ç¨çš„補ä¸å¯ä»¥çœç•¥nn/mm。
如果您有一系列é‡è¦çš„補ä¸ï¼Œé‚£éº¼é€šå¸¸ç™¼é€ä¸€å€‹ç°¡ä»‹ä½œçˆ²ç¬¬ã€‡éƒ¨åˆ†ã€‚ä¸éŽï¼Œé€™å€‹ç´„定
diff --git a/Documentation/translations/zh_TW/process/6.Followthrough.rst b/Documentation/translations/zh_TW/process/6.Followthrough.rst
index 5073b6e77c1c..bcc885ae1b8e 100644
--- a/Documentation/translations/zh_TW/process/6.Followthrough.rst
+++ b/Documentation/translations/zh_TW/process/6.Followthrough.rst
@@ -18,13 +18,13 @@
跟進
====
-此時,您已經éµå¾ªäº†åˆ°ç›®å‰çˆ²æ­¢çµ¦å‡ºçš„指導方é‡ï¼Œä¸¦ä¸”,隨著您自己的工程技能的增加,
+此時,您已經éµå¾ªäº†åˆ°ç›®å‰çˆ²æ­¢çµ¦å‡ºçš„指導方é‡ï¼Œä¸¦ä¸”,隨ç€æ‚¨è‡ªå·±çš„工程技能的增加,
已經發布了一系列完美的補ä¸ã€‚å³ä½¿æ˜¯ç¶“é©—è±å¯Œçš„內核開發人員也能犯的最大錯誤之一
-是,èªçˆ²ä»–們的工作ç¾åœ¨å·²ç¶“完æˆäº†ã€‚事實上,發布補ä¸æ„味著進入æµç¨‹çš„下一個階段,
+是,èªçˆ²ä»–們的工作ç¾åœ¨å·²ç¶“完æˆäº†ã€‚事實上,發佈補ä¸æ„味ç€é€²å…¥æµç¨‹çš„下一個階段,
å¯èƒ½é‚„需è¦åšå¾ˆå¤šå·¥ä½œã€‚
-一個補ä¸åœ¨é¦–次發布時就éžå¸¸å‡ºè‰²ã€æ²’有改進的餘地,這是很罕見的。內核開發æµç¨‹å·²
-èªè­˜åˆ°é€™ä¸€äº‹å¯¦ï¼Œå› æ­¤å®ƒéžå¸¸æ³¨é‡å°å·²ç™¼å¸ƒä»£ç¢¼çš„改進。作爲代碼的作者,您應該與
+一個補ä¸åœ¨é¦–次發佈時就éžå¸¸å‡ºè‰²ã€æ²’有改進的餘地,這是很罕見的。內核開發æµç¨‹å·²
+èªè­˜åˆ°é€™ä¸€äº‹å¯¦ï¼Œå› æ­¤å®ƒéžå¸¸æ³¨é‡å°å·²ç™¼ä½ˆä»£ç¢¼çš„改進。作爲代碼的作者,您應該與
內核社å€åˆä½œï¼Œä»¥ç¢ºä¿æ‚¨çš„代碼符åˆå…§æ ¸çš„質é‡æ¨™æº–。如果ä¸åƒèˆ‡é€™å€‹éŽç¨‹ï¼Œå¾ˆå¯èƒ½æœƒ
無法將補ä¸åˆä½µåˆ°ä¸»ç·šä¸­ã€‚
@@ -41,7 +41,7 @@
調整到大é‡çš„é‡å¯«â€”—都來自於å°Linuxçš„ç†è§£ï¼Œå³å¾žç¾åœ¨èµ·å年後,Linuxä»å°‡
在開發中。
- - 代碼審查是一項艱苦的工作,這是一項相å°åƒåŠ›ä¸è¨Žå¥½çš„工作;人們記得誰編寫了
+ - 代碼審查是一項艱苦的工作,這是一項相å°å–«åŠ›ä¸è¨Žå¥½çš„工作;人們記得誰編寫了
內核代碼,但å°æ–¼é‚£äº›å¯©æŸ¥å®ƒçš„人來說,幾乎沒有什麼長久的åè²ã€‚因此,審閱
人員å¯èƒ½æœƒè®Šå¾—æš´èºï¼Œå°¤å…¶æ˜¯ç•¶ä»–們看到åŒæ¨£çš„錯誤被一éåˆä¸€é地犯下時。如果
你得到了一個看起來憤怒ã€ä¾®è¾±æˆ–完全冒犯你的評論,請抑制以åŒæ¨£æ–¹å¼å›žæ‡‰çš„è¡å‹•ã€‚
@@ -54,7 +54,7 @@
所有這些歸根çµåº•å°±æ˜¯ï¼Œç•¶å¯©é–±è€…å‘您發é€è©•è«–時,您需è¦æ³¨æ„他們正在進行的技術
評論。ä¸è¦è®“他們的表é”æ–¹å¼æˆ–你自己的驕傲阻止此事。當你在一個補ä¸ä¸Šå¾—到評論
-時,花點時間去ç†è§£è©•è«–人想說什麼。如果å¯èƒ½çš„話,請修覆審閱者è¦æ±‚您修復的內
+時,花點時間去ç†è§£è©•è«–人想說什麼。如果å¯èƒ½çš„話,請修復審閱者è¦æ±‚您修復的內
容。然後回覆審閱者:è¬è¬ä»–們,並æ述你將如何回答他們的å•é¡Œã€‚
請注æ„,您ä¸å¿…åŒæ„審閱者建議的æ¯å€‹æ›´æ”¹ã€‚如果您èªçˆ²å¯©é–±è€…誤解了您的代碼,請
@@ -65,19 +65,19 @@
是錯誤的,或者你甚至沒有解決正確的å•é¡Œã€‚
Andrew Morton建議,æ¯ä¸€å€‹ä¸æœƒå°Žè‡´ä»£ç¢¼æ›´æ”¹çš„審閱評論都應該產生一個é¡å¤–的代碼
-注釋;這å¯ä»¥å¹«åŠ©æœªä¾†çš„審閱人員é¿å…第一次出ç¾çš„å•é¡Œã€‚
+註釋;這å¯ä»¥å¹«åŠ©æœªä¾†çš„審閱人員é¿å…第一次出ç¾çš„å•é¡Œã€‚
一個致命的錯誤是忽視評論,希望它們會消失。它們ä¸æœƒèµ°çš„。如果您在沒有å°ä¹‹å‰
收到的評論åšå‡ºéŸ¿æ‡‰çš„情æ³ä¸‹é‡æ–°ç™¼å¸ƒä»£ç¢¼ï¼Œé‚£éº¼å¾ˆå¯èƒ½æœƒç™¼ç¾è£œä¸æ¯«ç„¡ç”¨è™•ã€‚
-說到é‡æ–°ç™¼å¸ƒä»£ç¢¼ï¼šè«‹è¨˜ä½ï¼Œå¯©é–±è€…ä¸æœƒè¨˜ä½æ‚¨ä¸Šæ¬¡ç™¼å¸ƒçš„代碼的所有細節。因此,
+說到é‡æ–°ç™¼å¸ƒä»£ç¢¼ï¼šè«‹è¨˜ä½ï¼Œå¯©é–±è€…ä¸æœƒè¨˜ä½æ‚¨ä¸Šæ¬¡ç™¼ä½ˆçš„代碼的所有細節。因此,
æ醒審閱人員以å‰æ出的å•é¡Œä»¥åŠæ‚¨å¦‚何處ç†é€™äº›å•é¡Œç¸½æ˜¯ä¸€å€‹å¥½ä¸»æ„;補ä¸è®Šæ›´
日誌是æ供此類信æ¯çš„好地方。審閱者ä¸å¿…æœç´¢åˆ—表檔案來熟悉上次所說的內容;
如果您幫助他們直接開始,當他們é‡æ–°æŸ¥çœ‹æ‚¨çš„代碼時,心情會更好。
-如果你已經試著åšæ­£ç¢ºçš„事情,但事情ä»ç„¶æ²’有進展呢?大多數技術上的分歧都å¯ä»¥
+如果你已經試ç€åšæ­£ç¢ºçš„事情,但事情ä»ç„¶æ²’有進展呢?大多數技術上的分歧都å¯ä»¥
通éŽè¨Žè«–來解決,但有時人們ä»éœ€è¦åšå‡ºæ±ºå®šã€‚如果你真的èªçˆ²é€™å€‹æ±ºå®šå°ä½ ä¸åˆ©ï¼Œ
-ä½ å¯ä»¥è©¦è‘—å‘有更高權力的人上訴。å°æ–¼æœ¬æ–‡ï¼Œæ›´é«˜æ¬ŠåŠ›çš„人是 Andrew Morton 。
+ä½ å¯ä»¥è©¦ç€å‘有更高權力的人上訴。å°æ–¼æœ¬æ–‡ï¼Œæ›´é«˜æ¬ŠåŠ›çš„人是 Andrew Morton 。
Andrew 在內核開發社å€ä¸­éžå¸¸å—尊敬;他經常爲似乎被絕望阻塞的事情清障。儘管
如此,ä¸æ‡‰è¼•æ˜“就直接找 Andrew ,也ä¸æ‡‰åœ¨æ‰€æœ‰å…¶ä»–替代方案都被嘗試之å‰æ‰¾ä»–。
當然,記ä½ï¼Œä»–也å¯èƒ½ä¸åŒæ„ä½ çš„æ„見。
@@ -95,7 +95,7 @@ Andrew 在內核開發社å€ä¸­éžå¸¸å—尊敬;他經常爲似乎被絕望阻å
包å«åœ¨å­ç³»çµ±æ¨¹ä¸­å¯ä»¥æ高補ä¸çš„å¯è¦‹æ€§ã€‚ç¾åœ¨ï¼Œä½¿ç”¨è©²æ¨¹çš„其他開發人員將默èªç²
得補ä¸ã€‚å­ç³»çµ±æ¨¹é€šå¸¸ä¹Ÿçˆ²Linuxæ供支æŒï¼Œä½¿å…¶å…§å®¹å°æ•´å€‹é–‹ç™¼ç¤¾å€å¯è¦‹ã€‚在這一點
-上,您很å¯èƒ½æœƒå¾žä¸€çµ„新的審閱者那裡得到更多的評論;這些評論需è¦åƒä¸Šä¸€è¼ªé‚£æ¨£
+上,您很å¯èƒ½æœƒå¾žä¸€çµ„新的審閱者那è£å¾—到更多的評論;這些評論需è¦åƒä¸Šä¸€è¼ªé‚£æ¨£
得到回應。
在這時也會發生點什麼,這å–決於你的補ä¸çš„性質,是å¦èˆ‡å…¶ä»–人正在åšçš„工作發生
@@ -114,23 +114,23 @@ Andrew 在內核開發社å€ä¸­éžå¸¸å—尊敬;他經常爲似乎被絕望阻å
這種誘惑,您ä»ç„¶éœ€è¦å°æœ‰å•é¡Œæˆ–建議的開發人員作出響應。
ä¸éŽï¼Œæ›´é‡è¦çš„是:將代碼包å«åœ¨ä¸»ç·šä¸­æœƒå°‡ä»£ç¢¼äº¤çµ¦æ›´å¤šçš„一些測試人員。å³ä½¿æ‚¨
-爲尚未å¯ç”¨çš„硬體æ供了驅動程åºï¼Œæ‚¨ä¹Ÿæœƒé©šè¨æ–¼æœ‰å¤šå°‘人會將您的代碼構建到內核
+爲尚未å¯ç”¨çš„硬件æ供了驅動程åºï¼Œæ‚¨ä¹Ÿæœƒé©šè¨æ–¼æœ‰å¤šå°‘人會將您的代碼構建到內核
中。當然,如果有測試人員,也å¯èƒ½æœƒæœ‰éŒ¯èª¤å ±å‘Šã€‚
-最糟糕的錯誤報告是回歸。如果你的補ä¸å°Žè‡´å›žæ­¸ï¼Œä½ æœƒç™¼ç¾å¤šåˆ°è®“ä½ ä¸èˆ’æœçš„眼ç›ç›¯
-著你;回歸需è¦å„˜å¿«ä¿®å¾©ã€‚如果您ä¸é¡˜æ„或無法修復回歸(其他人都ä¸æœƒçˆ²æ‚¨ä¿®å¾©ï¼‰ï¼Œ
+最糟糕的錯誤報告是迴歸。如果你的補ä¸å°Žè‡´è¿´æ­¸ï¼Œä½ æœƒç™¼ç¾å¤šåˆ°è®“ä½ ä¸èˆ’æœçš„眼ç›ç›¯
+ç€ä½ ï¼›è¿´æ­¸éœ€è¦å„˜å¿«ä¿®å¾©ã€‚如果您ä¸é¡˜æ„或無法修復迴歸(其他人都ä¸æœƒçˆ²æ‚¨ä¿®å¾©ï¼‰ï¼Œ
那麼在穩定期內,您的補ä¸å¹¾ä¹Žè‚¯å®šæœƒè¢«ç§»é™¤ã€‚除了å¦å®šæ‚¨çˆ²ä½¿è£œä¸é€²å…¥ä¸»ç·šæ‰€åšçš„
-所有工作之外,如果由於未能修復回歸而å–消補ä¸ï¼Œå¾ˆå¯èƒ½æœƒä½¿å°‡ä¾†çš„工作更難被åˆä½µã€‚
+所有工作之外,如果由於未能修復迴歸而å–消補ä¸ï¼Œå¾ˆå¯èƒ½æœƒä½¿å°‡ä¾†çš„工作更難被åˆä½µã€‚
-在處ç†å®Œä»»ä½•å›žæ­¸ä¹‹å¾Œï¼Œå¯èƒ½é‚„有其他普通缺陷需è¦è™•ç†ã€‚穩定期是修復這些錯誤並
-確ä¿ä»£ç¢¼åœ¨ä¸»ç·šå…§æ ¸ç‰ˆæœ¬ä¸­çš„首次發布儘å¯èƒ½å¯é çš„最好機會。所以,請回應錯誤
+在處ç†å®Œä»»ä½•è¿´æ­¸ä¹‹å¾Œï¼Œå¯èƒ½é‚„有其他普通缺陷需è¦è™•ç†ã€‚穩定期是修復這些錯誤並
+確ä¿ä»£ç¢¼åœ¨ä¸»ç·šå…§æ ¸ç‰ˆæœ¬ä¸­çš„首次發佈儘å¯èƒ½å¯é çš„最好機會。所以,請回應錯誤
報告,並儘å¯èƒ½è§£æ±ºå•é¡Œã€‚這就是穩定期的目的;一旦解決了舊補ä¸çš„任何å•é¡Œï¼Œå°±
å¯ä»¥é–‹å§‹ç›¡æƒ…創建新補ä¸ã€‚
別忘了,還有其他節點也å¯èƒ½æœƒå‰µå»ºç¼ºé™·å ±å‘Šï¼šä¸‹ä¸€å€‹ä¸»ç·šç©©å®šç‰ˆæœ¬ï¼Œç•¶è‘—å的發行
商é¸æ“‡åŒ…å«æ‚¨è£œä¸çš„內核版本時等等。繼續響應這些報告是您工作的基本素養。但是
如果這ä¸èƒ½æ供足夠的動機,那麼也需è¦è€ƒæ…®ï¼šé–‹ç™¼ç¤¾å€æœƒè¨˜ä½é‚£äº›åœ¨åˆä½µå¾Œå°ä»£ç¢¼
-失去興趣的開發人員。下一次你發布補ä¸æ™‚,他們會以你以後ä¸æœƒæŒçºŒç¶­è­·å®ƒçˆ²å‰æ
+失去興趣的開發人員。下一次你發佈補ä¸æ™‚,他們會以你以後ä¸æœƒæŒçºŒç¶­è­·å®ƒçˆ²å‰æ
來評估它。
其他å¯èƒ½ç™¼ç”Ÿçš„事情
@@ -141,15 +141,15 @@ Andrew 在內核開發社å€ä¸­éžå¸¸å—尊敬;他經常爲似乎被絕望阻å
維護人員(確ä¿åŒ…å«ä¸€å€‹æ­£ç¢ºçš„From:行,這樣屬性是正確的,並添加一個您自己的
signoff ),或者回復一個 Acked-by: 讓原始發é€è€…å‘上發é€å®ƒã€‚
-如果您ä¸åŒæ„補ä¸ï¼Œè«‹ç¦®è²Œåœ°å›žå¾©ï¼Œè§£é‡‹åŽŸå› ã€‚如果å¯èƒ½çš„話,告訴作者需è¦åšå“ªäº›
-更改æ‰èƒ½è®“您接å—補ä¸ã€‚åˆä½µä»£ç¢¼çš„編寫者和維護者所åå°çš„補ä¸çš„確存在著一定的
+如果您ä¸åŒæ„補ä¸ï¼Œè«‹ç¦®è²Œåœ°å›žè¦†ï¼Œè§£é‡‹åŽŸå› ã€‚如果å¯èƒ½çš„話,告訴作者需è¦åšå“ªäº›
+更改æ‰èƒ½è®“您接å—補ä¸ã€‚åˆä½µä»£ç¢¼çš„編寫者和維護者所åå°çš„補ä¸çš„確存在ç€ä¸€å®šçš„
阻力,但僅此而已。如果你被èªçˆ²ä¸å¿…è¦çš„阻礙了好的工作,那麼這些補ä¸æœ€çµ‚會
繞éŽä½ ä¸¦é€²å…¥ä¸»ç·šã€‚在Linux內核中,沒有人å°ä»»ä½•ä»£ç¢¼æ“有絕å°çš„å¦æ±ºæ¬Šã€‚å¯èƒ½é™¤
了Linus。
-在éžå¸¸ç½•è¦‹çš„情æ³ä¸‹ï¼Œæ‚¨å¯èƒ½æœƒçœ‹åˆ°å®Œå…¨ä¸åŒçš„æ±è¥¿ï¼šå¦ä¸€å€‹é–‹ç™¼äººå“¡ç™¼å¸ƒäº†é‡å°æ‚¨
-çš„å•é¡Œçš„ä¸åŒè§£æ±ºæ–¹æ¡ˆã€‚在這時,兩個補ä¸ä¹‹ä¸€å¯èƒ½ä¸æœƒè¢«åˆä½µï¼Œã€Œæˆ‘的補ä¸é¦–å…ˆ
-發布ã€ä¸è¢«èªçˆ²æ˜¯ä¸€å€‹ä»¤äººä¿¡æœçš„技術論據。如果有別人的補ä¸å–代了你的補ä¸è€Œé€²
+在éžå¸¸ç½•è¦‹çš„情æ³ä¸‹ï¼Œæ‚¨å¯èƒ½æœƒçœ‹åˆ°å®Œå…¨ä¸åŒçš„æ±è¥¿ï¼šå¦ä¸€å€‹é–‹ç™¼äººå“¡ç™¼ä½ˆäº†é‡å°æ‚¨
+çš„å•é¡Œçš„ä¸åŒè§£æ±ºæ–¹æ¡ˆã€‚在這時,兩個補ä¸ä¹‹ä¸€å¯èƒ½ä¸æœƒè¢«åˆä½µï¼Œâ€œæˆ‘的補ä¸é¦–å…ˆ
+發佈â€ä¸è¢«èªçˆ²æ˜¯ä¸€å€‹ä»¤äººä¿¡æœçš„技術論據。如果有別人的補ä¸å–代了你的補ä¸è€Œé€²
入了主線,那麼åªæœ‰ä¸€ç¨®æ–¹æ³•å¯ä»¥å›žæ‡‰ä½ ï¼šå¾ˆé«˜èˆˆä½ çš„å•é¡Œè§£æ±ºäº†ï¼Œè«‹ç¹¼çºŒå·¥ä½œå§ã€‚
以這種方å¼æŠŠæŸäººçš„工作推到一邊å¯èƒ½å°Žè‡´å‚·å¿ƒå’Œæ°£é¤’,但是社å€æœƒè¨˜ä½ä½ çš„å應,
å³ä½¿å¾ˆä¹…以後他們已經忘記了誰的補ä¸çœŸæ­£è¢«åˆä½µã€‚
diff --git a/Documentation/translations/zh_TW/process/7.AdvancedTopics.rst b/Documentation/translations/zh_TW/process/7.AdvancedTopics.rst
index 2cbd16bfed29..db74d8ca3f3b 100644
--- a/Documentation/translations/zh_TW/process/7.AdvancedTopics.rst
+++ b/Documentation/translations/zh_TW/process/7.AdvancedTopics.rst
@@ -24,14 +24,14 @@
使用Git管ç†è£œä¸
---------------
-內核使用分布å¼ç‰ˆæœ¬æŽ§åˆ¶å§‹æ–¼2002å¹´åˆï¼Œç•¶æ™‚Linus首次開始使用專有的Bitkeeper應用
-程åºã€‚雖然BitKeeper存在爭議,但它所體ç¾çš„軟體版本管ç†æ–¹æ³•å»è‚¯å®šä¸æ˜¯ã€‚分布å¼
+內核使用分佈å¼ç‰ˆæœ¬æŽ§åˆ¶å§‹æ–¼2002å¹´åˆï¼Œç•¶æ™‚Linus首次開始使用專有的Bitkeeper應用
+程åºã€‚雖然BitKeeper存在爭議,但它所體ç¾çš„軟件版本管ç†æ–¹æ³•å»è‚¯å®šä¸æ˜¯ã€‚分佈å¼
版本控制å¯ä»¥ç«‹å³åŠ é€Ÿå…§æ ¸é–‹ç™¼é …目。ç¾åœ¨æœ‰å¥½å¹¾ç¨®å…費的BitKeeper替代å“。
但無論好壞,內核項目都已經é¸æ“‡äº†Git作爲其工具。
-使用Git管ç†è£œä¸å¯ä»¥ä½¿é–‹ç™¼äººå“¡çš„生活更加輕鬆,尤其是隨著補ä¸æ•¸é‡çš„增長。Git也
+使用Git管ç†è£œä¸å¯ä»¥ä½¿é–‹ç™¼äººå“¡çš„生活更加輕鬆,尤其是隨ç€è£œä¸æ•¸é‡çš„增長。Git也
有其粗糙的邊角和一定的å±éšªæ€§ï¼Œå®ƒæ˜¯ä¸€å€‹å¹´è¼•å’Œå¼·å¤§çš„工具,ä»ç„¶åœ¨å…¶é–‹ç™¼äººå“¡å®Œå–„
-中。本文檔ä¸æœƒè©¦åœ–教會讀者如何使用git;這會是個巨長的文檔。相å,這裡的é‡é»ž
+中。本文檔ä¸æœƒè©¦åœ–教會讀者如何使用git;這會是個巨長的文檔。相å,這è£çš„é‡é»ž
將是Git如何特別é©åˆå…§æ ¸é–‹ç™¼éŽç¨‹ã€‚想è¦åŠ å¿«ç”¨Git速度的開發人員å¯ä»¥åœ¨ä»¥ä¸‹ç¶²ç«™ä¸Š
找到更多信æ¯ï¼š
@@ -42,22 +42,22 @@
åŒæ™‚網上也能找到å„種å„樣的教程。
在嘗試使用它生æˆè£œä¸ä¾›ä»–人使用之å‰ï¼Œç¬¬ä¸€è¦å‹™æ˜¯é–±è®€ä¸Šè¿°ç¶²é ï¼Œå°Git的工作方å¼
-有一個紮實的了解。使用Git的開發人員應能進行拉å–主線存儲庫的副本,查詢修訂
-æ­·å²ï¼Œæ交å°æ¨¹çš„更改,使用分支等æ“作。了解Git用於é‡å¯«æ­·å²çš„工具(如rebase)
-也很有用。Git有自己的術語和概念;Git的新用戶應該了解引用ã€é ç¨‹åˆ†æ”¯ã€ç´¢å¼•ã€
-快進åˆä½µã€æŽ¨æ‹‰ã€æ¸¸é›¢é ­ç­‰ã€‚一開始å¯èƒ½æœ‰é»žåš‡äººï¼Œä½†é€™äº›æ¦‚念ä¸é›£é€šéŽä¸€é»žå­¸ç¿’來
+有一個紮實的瞭解。使用Git的開發人員應能進行拉å–主線存儲庫的副本,查詢修訂
+æ­·å²ï¼Œæ交å°æ¨¹çš„更改,使用分支等æ“作。瞭解Git用於é‡å¯«æ­·å²çš„工具(如rebase)
+也很有用。Git有自己的術語和概念;Git的新用戶應該瞭解引用ã€é ç¨‹åˆ†æ”¯ã€ç´¢å¼•ã€
+快進åˆä½µã€æŽ¨æ‹‰ã€éŠé›¢é ­ç­‰ã€‚一開始å¯èƒ½æœ‰é»žåš‡äººï¼Œä½†é€™äº›æ¦‚念ä¸é›£é€šéŽä¸€é»žå­¸ç¿’來
ç†è§£ã€‚
使用git生æˆé€šéŽé›»å­éƒµä»¶æ交的補ä¸æ˜¯æ高速度的一個很好的練習。
-當您準備好開始建立Git樹供其他人查看時,無疑需è¦ä¸€å€‹å¯ä»¥å¾žä¸­æ‹‰å–的伺æœå™¨ã€‚
-如果您有一個å¯ä»¥è¨ªå•ç¶²éš›ç¶²è·¯çš„系統,那麼使用git-daemon設置這樣的伺æœå™¨ç›¸å°
+當您準備好開始建立Git樹供其他人查看時,無疑需è¦ä¸€å€‹å¯ä»¥å¾žä¸­æ‹‰å–çš„æœå‹™å™¨ã€‚
+如果您有一個å¯ä»¥è¨ªå•å› ç‰¹ç¶²çš„系統,那麼使用git-daemon設置這樣的æœå‹™å™¨ç›¸å°
簡單。åŒæ™‚,å…費的公共託管網站(例如github)也開始出ç¾åœ¨ç¶²çµ¡ä¸Šã€‚æˆç†Ÿçš„開發
人員å¯ä»¥åœ¨kernel.org上ç²å¾—一個帳戶,但這些帳戶並ä¸å®¹æ˜“得到;更多有關信æ¯ï¼Œ
è«‹åƒé–± https://kernel.org/faq/ 。
-正常的Git工作æµç¨‹æ¶‰åŠåˆ°è¨±å¤šåˆ†æ”¯çš„使用。æ¯ä¸€æ¢é–‹ç™¼ç·šéƒ½å¯ä»¥åˆ†çˆ²å–®ç¨çš„「主題
-分支ã€ï¼Œä¸¦ç¨ç«‹ç¶­è­·ã€‚Git的分支很容易使用,沒有ç†ç”±ä¸ä½¿ç”¨å®ƒå€‘。而且,在任何
+正常的Git工作æµç¨‹æ¶‰åŠåˆ°è¨±å¤šåˆ†æ”¯çš„使用。æ¯ä¸€æ¢é–‹ç™¼ç·šéƒ½å¯ä»¥åˆ†çˆ²å–®ç¨çš„“主題
+分支â€ï¼Œä¸¦ç¨ç«‹ç¶­è­·ã€‚Git的分支很容易使用,沒有ç†ç”±ä¸ä½¿ç”¨å®ƒå€‘。而且,在任何
情æ³ä¸‹ï¼Œæ‚¨éƒ½ä¸æ‡‰è©²åœ¨ä»»ä½•æ‚¨æ‰“算讓其他人從中拉å–的分支中進行開發。應該å°å¿ƒåœ°
創建公開å¯ç”¨çš„分支;當開發分支處於完整狀態並已準備好時(而ä¸æ˜¯ä¹‹å‰ï¼‰æ‰åˆä½µ
開發分支的補ä¸ã€‚
@@ -72,10 +72,10 @@ Gitæ供了一些強大的工具,å¯ä»¥è®“您é‡å¯«é–‹ç™¼æ­·å²ã€‚一個ä¸æ–
簡單癡迷。é‡å¯«æ­·å²å°‡é‡å¯«è©²æ­·å²ä¸­åŒ…å«çš„更改,將經éŽæ¸¬è©¦ï¼ˆå¸Œæœ›å¦‚此)的內核樹
變爲未經測試的內核樹。除此之外,如果開發人員沒有共享項目歷å²ï¼Œä»–們就無法
輕鬆地å”作;如果您é‡å¯«äº†å…¶ä»–開發人員拉入他們存儲庫的歷å²ï¼Œæ‚¨å°‡ä½¿é€™äº›é–‹ç™¼
-人員的生活更加困難。因此,這裡有一個簡單的經驗法則:被導出到其他地方的歷å²
+人員的生活更加困難。因此,這è£æœ‰ä¸€å€‹ç°¡å–®çš„經驗法則:被導出到其他地方的歷å²
在此後通常被èªçˆ²æ˜¯ä¸å¯è®Šçš„。
-因此,一旦將一組更改推é€åˆ°å…¬é–‹å¯ç”¨çš„伺æœå™¨ä¸Šï¼Œå°±ä¸æ‡‰è©²é‡å¯«é€™äº›æ›´æ”¹ã€‚如果您
+因此,一旦將一組更改推é€åˆ°å…¬é–‹å¯ç”¨çš„æœå‹™å™¨ä¸Šï¼Œå°±ä¸æ‡‰è©²é‡å¯«é€™äº›æ›´æ”¹ã€‚如果您
嘗試強制進行無法快進åˆä½µçš„更改(å³ä¸å…±äº«åŒä¸€æ­·å²è¨˜éŒ„的更改),Git將嘗試強制
執行此è¦å‰‡ã€‚這å¯èƒ½è¦†è“‹æª¢æŸ¥ï¼Œæœ‰æ™‚甚至需è¦é‡å¯«å°Žå‡ºçš„樹。在樹之間移動變更集以
é¿å…linux-next中的è¡çªå°±æ˜¯ä¸€å€‹ä¾‹å­ã€‚但這種行爲應該是罕見的。這就是爲什麼
@@ -86,9 +86,9 @@ Gitæ供了一些強大的工具,å¯ä»¥è®“您é‡å¯«é–‹ç™¼æ­·å²ã€‚一個ä¸æ–
å°æ–¼ä¸€å€‹ç§æœ‰çš„分支,rebasing å¯èƒ½æ˜¯ä¸€å€‹å¾ˆå®¹æ˜“跟上å¦ä¸€æ£µæ¨¹çš„方法,但是一旦
一棵樹被導出到外界,rebasingå°±ä¸å¯å–了。一旦發生這種情æ³ï¼Œå°±å¿…須進行完全
åˆä½µï¼ˆmerge)。åˆä½µæœ‰æ™‚是很有æ„義的,但是éŽæ–¼é »ç¹çš„åˆä½µæœƒä¸å¿…è¦åœ°æ“¾äº‚æ­·å²ã€‚
-在這種情æ³ä¸‹å»ºè­°çš„åšæ³•æ˜¯ä¸è¦é »ç¹åˆä½µï¼Œé€šå¸¸åªåœ¨ç‰¹å®šçš„發布點(如主線-rc發布)
+在這種情æ³ä¸‹å»ºè­°çš„åšæ³•æ˜¯ä¸è¦é »ç¹åˆä½µï¼Œé€šå¸¸åªåœ¨ç‰¹å®šçš„發佈點(如主線-rc發佈)
åˆä½µã€‚如果您å°ç‰¹å®šçš„更改感到緊張,則å¯ä»¥å§‹çµ‚在ç§æœ‰åˆ†æ”¯ä¸­åŸ·è¡Œæ¸¬è©¦åˆä½µã€‚在
-這種情æ³ä¸‹ï¼Œgit「rerereã€å·¥å…·å¾ˆæœ‰ç”¨ï¼›å®ƒèƒ½è¨˜ä½åˆä½µè¡çªæ˜¯å¦‚何解決的,這樣您
+這種情æ³ä¸‹ï¼Œgit“rerereâ€å·¥å…·å¾ˆæœ‰ç”¨ï¼›å®ƒèƒ½è¨˜ä½åˆä½µè¡çªæ˜¯å¦‚何解決的,這樣您
å°±ä¸å¿…é‡è¤‡ç›¸åŒçš„工作。
關於Git這樣的工具的一個最大的å覆抱怨是:補ä¸å¾žä¸€å€‹å­˜å„²åº«åˆ°å¦ä¸€å€‹å­˜å„²åº«çš„
@@ -98,36 +98,36 @@ Gitæ供了一些強大的工具,å¯ä»¥è®“您é‡å¯«é–‹ç™¼æ­·å²ã€‚一個ä¸æ–
::
- ä½ å¯ä»¥çµ¦æˆ‘發補ä¸ï¼Œä½†ç•¶æˆ‘從你那裡拉å–一個Git補ä¸æ™‚,我需è¦çŸ¥é“你清楚
+ ä½ å¯ä»¥çµ¦æˆ‘發補ä¸ï¼Œä½†ç•¶æˆ‘從你那è£æ‹‰å–一個Git補ä¸æ™‚,我需è¦çŸ¥é“你清楚
自己在åšä»€éº¼ï¼Œæˆ‘需è¦èƒ½å¤ ç›¸ä¿¡äº‹æƒ…而 *無需* 手動檢查æ¯å€‹å–®ç¨çš„更改。
(http://lwn.net/Articles/224135/)。
-爲了é¿å…這種情æ³ï¼Œè«‹ç¢ºä¿çµ¦å®šåˆ†æ”¯ä¸­çš„所有補ä¸éƒ½èˆ‡ç›¸é—œä¸»é¡Œç·Šå¯†ç›¸é—œï¼›ã€Œé©…動程åº
-修復ã€åˆ†æ”¯ä¸æ‡‰æ›´æ”¹æ ¸å¿ƒå…§å­˜ç®¡ç†ä»£ç¢¼ã€‚而且,最é‡è¦çš„是,ä¸è¦ä½¿ç”¨Git樹來繞éŽ
-審查éŽç¨‹ã€‚ä¸æ™‚的將樹的摘è¦ç™¼å¸ƒåˆ°ç›¸é—œçš„列表中,在åˆé©æ™‚候請求linux-next中
+爲了é¿å…這種情æ³ï¼Œè«‹ç¢ºä¿çµ¦å®šåˆ†æ”¯ä¸­çš„所有補ä¸éƒ½èˆ‡ç›¸é—œä¸»é¡Œç·Šå¯†ç›¸é—œï¼›â€œé©…動程åº
+修復â€åˆ†æ”¯ä¸æ‡‰æ›´æ”¹æ ¸å¿ƒå…§å­˜ç®¡ç†ä»£ç¢¼ã€‚而且,最é‡è¦çš„是,ä¸è¦ä½¿ç”¨Git樹來繞éŽ
+審查éŽç¨‹ã€‚ä¸æ™‚的將樹的摘è¦ç™¼ä½ˆåˆ°ç›¸é—œçš„列表中,在åˆé©æ™‚候請求linux-next中
包å«è©²æ¨¹ã€‚
如果其他人開始發é€è£œä¸ä»¥åŒ…å«åˆ°æ‚¨çš„樹中,ä¸è¦å¿˜è¨˜å¯©é–±å®ƒå€‘。還è¦ç¢ºä¿æ‚¨ç¶­è­·æ­£ç¢º
-的作者信æ¯ï¼› git 「amã€å·¥å…·åœ¨é€™æ–¹é¢åšå¾—最好,但是如果補ä¸é€šéŽç¬¬ä¸‰æ–¹è½‰ç™¼çµ¦æ‚¨ï¼Œ
-您å¯èƒ½éœ€è¦åœ¨è£œä¸ä¸­æ·»åŠ ã€ŒFrom:ã€è¡Œã€‚
+的作者信æ¯ï¼› git “amâ€å·¥å…·åœ¨é€™æ–¹é¢åšå¾—最好,但是如果補ä¸é€šéŽç¬¬ä¸‰æ–¹è½‰ç™¼çµ¦æ‚¨ï¼Œ
+您å¯èƒ½éœ€è¦åœ¨è£œä¸ä¸­æ·»åŠ â€œFrom:â€è¡Œã€‚
請求拉å–時,請務必æ供所有相關信æ¯ï¼šæ¨¹çš„ä½ç½®ã€è¦æ‹‰å–的分支以åŠæ‹‰å–將導致的
æ›´æ”¹ã€‚åœ¨é€™æ–¹é¢ git request-pull 命令éžå¸¸æœ‰ç”¨ï¼›å®ƒå°‡æŒ‰ç…§å…¶ä»–開發人員所期望的
-æ ¼å¼åŒ–請求,並檢查以確ä¿æ‚¨å·²è¨˜å¾—將這些更改推é€åˆ°å…¬å…±ä¼ºæœå™¨ã€‚
+æ ¼å¼åŒ–請求,並檢查以確ä¿æ‚¨å·²è¨˜å¾—將這些更改推é€åˆ°å…¬å…±æœå‹™å™¨ã€‚
審閱補ä¸
--------
-一些讀者顯然會åå°å°‡æœ¬ç¯€èˆ‡ã€Œé«˜ç´šä¸»é¡Œã€æ”¾åœ¨ä¸€èµ·ï¼Œå› çˆ²å³ä½¿æ˜¯å‰›é–‹å§‹çš„內核開發人員
-也應該審閱補ä¸ã€‚當然,沒有比查看其他人發布的代碼更好的方法來學習如何在內核環境
+一些讀者顯然會åå°å°‡æœ¬ç¯€èˆ‡â€œé«˜ç´šä¸»é¡Œâ€æ”¾åœ¨ä¸€èµ·ï¼Œå› çˆ²å³ä½¿æ˜¯å‰›é–‹å§‹çš„內核開發人員
+也應該審閱補ä¸ã€‚當然,沒有比查看其他人發佈的代碼更好的方法來學習如何在內核環境
中編程了。此外,審閱者永é ä¾›ä¸æ‡‰æ±‚;通éŽå¯©é–±ä»£ç¢¼ï¼Œæ‚¨å¯ä»¥å°æ•´å€‹æµç¨‹åšå‡ºé‡å¤§è²¢ç»ã€‚
審查代碼å¯èƒ½æ˜¯ä¸€å‰¯ä»¤äººç”Ÿç•çš„圖景,特別是å°ä¸€å€‹æ–°çš„內核開發人員來說,他們
-å¯èƒ½æœƒå°å…¬é–‹è©¢å•ä»£ç¢¼æ„Ÿåˆ°ç·Šå¼µï¼Œè€Œé€™äº›ä»£ç¢¼æ˜¯ç”±é‚£äº›æœ‰æ›´å¤šç¶“驗的人發布的。ä¸éŽï¼Œ
+å¯èƒ½æœƒå°å…¬é–‹è©¢å•ä»£ç¢¼æ„Ÿåˆ°ç·Šå¼µï¼Œè€Œé€™äº›ä»£ç¢¼æ˜¯ç”±é‚£äº›æœ‰æ›´å¤šç¶“驗的人發佈的。ä¸éŽï¼Œ
å³ä½¿æ˜¯æœ€æœ‰ç¶“驗的開發人員編寫的代碼也å¯ä»¥å¾—到改進。也許å°ï¼ˆæ‰€æœ‰ï¼‰å¯©é–±è€…最好
-的建議是:把審閱評論當æˆå•é¡Œè€Œä¸æ˜¯æ‰¹è©•ã€‚è©¢å•ã€Œåœ¨é€™æ¢è·¯å¾‘中如何釋放鎖?ã€
-總是比說「這裡的鎖是錯誤的ã€æ›´å¥½ã€‚
+的建議是:把審閱評論當æˆå•é¡Œè€Œä¸æ˜¯æ‰¹è©•ã€‚è©¢å•â€œåœ¨é€™æ¢è·¯å¾‘中如何釋放鎖?â€
+總是比說“這è£çš„鎖是錯誤的â€æ›´å¥½ã€‚
ä¸åŒçš„開發人員將從ä¸åŒçš„角度審查代碼。部分人會主è¦é—œæ³¨ä»£ç¢¼é¢¨æ ¼ä»¥åŠä»£ç¢¼è¡Œæ˜¯
å¦æœ‰å°¾éš¨ç©ºæ ¼ã€‚其他人會主è¦é—œæ³¨è£œä¸ä½œçˆ²ä¸€å€‹æ•´é«”實ç¾çš„變更是å¦å°å…§æ ¸æœ‰å¥½è™•ã€‚
diff --git a/Documentation/translations/zh_TW/process/8.Conclusion.rst b/Documentation/translations/zh_TW/process/8.Conclusion.rst
index 1207991d1570..a0c00741f912 100644
--- a/Documentation/translations/zh_TW/process/8.Conclusion.rst
+++ b/Documentation/translations/zh_TW/process/8.Conclusion.rst
@@ -17,13 +17,13 @@
更多信æ¯
========
-關於Linux內核開發和相關主題的信æ¯ä¾†æºå¾ˆå¤šã€‚首先是在內核原始碼分發中找到的
+關於Linux內核開發和相關主題的信æ¯ä¾†æºå¾ˆå¤šã€‚首先是在內核æºä»£ç¢¼åˆ†ç™¼ä¸­æ‰¾åˆ°çš„
文檔目錄。頂級
-:ref:`Documentation/translations/zh_TW/process/howto.rst <tw_process_howto>`
+:ref:`Documentation/translations/zh_CN/process/howto.rst <tw_process_howto>`
文件是一個é‡è¦çš„起點;
-:ref:`Documentation/translations/zh_TW/process/submitting-patches.rst <tw_submittingpatches>`
+:ref:`Documentation/translations/zh_CN/process/submitting-patches.rst <tw_submittingpatches>`
也是所有內核開發人員都應該閱讀的內容。許多內部內核API都是使用kerneldoc機制
-記錄的;「make htmldocsã€æˆ–「make pdfdocsã€å¯ç”¨æ–¼ä»¥HTML或PDFæ ¼å¼ç”Ÿæˆé€™äº›æ–‡æª”
+記錄的;“make htmldocsâ€æˆ–“make pdfdocsâ€å¯ç”¨æ–¼ä»¥HTML或PDFæ ¼å¼ç”Ÿæˆé€™äº›æ–‡æª”
(儘管æŸäº›ç™¼è¡Œç‰ˆæ供的tex版本會é‡åˆ°å…§éƒ¨é™åˆ¶ï¼Œç„¡æ³•æ­£ç¢ºè™•ç†æ–‡æª”)。
ä¸åŒçš„網站在å„個細節層次上討論內核開發。本文作者想謙虛地建議用 https://lwn.net/
@@ -35,7 +35,7 @@
https://kernelnewbies.org/
-當然,也ä¸æ‡‰è©²å¿˜è¨˜ https://kernel.org/ ,這是內核發布信æ¯çš„最終ä½ç½®ã€‚
+當然,也ä¸æ‡‰è©²å¿˜è¨˜ https://kernel.org/ ,這是內核發佈信æ¯çš„最終ä½ç½®ã€‚
關於內核開發有很多書:
@@ -47,7 +47,7 @@
《深入ç†è§£Linux內核》(Daniel Bovetå’ŒMarco Cesati)
然而,所有這些書都有一個共åŒçš„缺點:它們上架時就往往有些éŽæ™‚,而且已經上架
-一段時間了。ä¸éŽï¼Œåœ¨é‚£è£¡é‚„是å¯ä»¥æ‰¾åˆ°ç›¸ç•¶å¤šçš„好信æ¯ã€‚
+一段時間了。ä¸éŽï¼Œåœ¨é‚£è£é‚„是å¯ä»¥æ‰¾åˆ°ç›¸ç•¶å¤šçš„好信æ¯ã€‚
有關git的文檔,請訪å•ï¼š
@@ -61,7 +61,7 @@
ç¥è³€æ‰€æœ‰é€šéŽé€™ç¯‡å†—長的文檔的人。希望它能夠幫助您ç†è§£Linux內核是如何開發的,
以åŠæ‚¨å¦‚何åƒèˆ‡é€™å€‹éŽç¨‹ã€‚
-最後,é‡è¦çš„是åƒèˆ‡ã€‚任何開æºè»Ÿé«”項目都ä¸æœƒè¶…éŽå…¶è²¢ç»è€…投入其中的總和。Linux
+最後,é‡è¦çš„是åƒèˆ‡ã€‚任何開æºè»Ÿä»¶é …目都ä¸æœƒè¶…éŽå…¶è²¢ç»è€…投入其中的總和。Linux
內核的發展速度和以å‰ä¸€æ¨£å¿«ï¼Œå› çˆ²å®ƒå¾—到了大é‡é–‹ç™¼äººå“¡çš„幫助,他們都在努力使它
變得更好。內核是一個最æˆåŠŸçš„例å­ï¼Œèªªæ˜Žäº†ç•¶æˆåƒä¸Šè¬çš„人爲了一個共åŒçš„目標一起
工作時,å¯ä»¥åšå‡ºä»€éº¼ã€‚
diff --git a/Documentation/translations/zh_TW/process/code-of-conduct-interpretation.rst b/Documentation/translations/zh_TW/process/code-of-conduct-interpretation.rst
index 920bb0f36974..48df918000e9 100644
--- a/Documentation/translations/zh_TW/process/code-of-conduct-interpretation.rst
+++ b/Documentation/translations/zh_TW/process/code-of-conduct-interpretation.rst
@@ -8,34 +8,34 @@
.. _tw_code_of_conduct_interpretation:
-Linux內核貢ç»è€…契約行為準則解釋
+Linux內核貢ç»è€…契約行爲準則解釋
===============================
:ref:`tw_code_of_conduct` 準則是一個通用文檔,旨在爲幾乎所有開æºç¤¾å€æ供一套è¦å‰‡ã€‚
æ¯å€‹é–‹æºç¤¾å€éƒ½æ˜¯ç¨ä¸€ç„¡äºŒçš„,Linux內核也ä¸ä¾‹å¤–。因此,本文æ述了Linux內核社å€ä¸­
-如何解釋它。我們也ä¸å¸Œæœ›é€™ç¨®è§£é‡‹éš¨è‘—時間的推移是éœæ…‹çš„,並將根據需è¦é€²è¡Œèª¿æ•´ã€‚
+如何解釋它。我們也ä¸å¸Œæœ›é€™ç¨®è§£é‡‹éš¨ç€æ™‚間的推移是éœæ…‹çš„,並將根據需è¦é€²è¡Œèª¿æ•´ã€‚
-與開發軟體的「傳統ã€æ–¹æ³•ç›¸æ¯”,Linux內核開發工作是一個éžå¸¸å€‹äººåŒ–çš„éŽç¨‹ã€‚ä½ çš„è²¢ç»
+與開發軟件的“傳統â€æ–¹æ³•ç›¸æ¯”,Linux內核開發工作是一個éžå¸¸å€‹äººåŒ–çš„éŽç¨‹ã€‚ä½ çš„è²¢ç»
和背後的想法將被仔細審查,往往導致批判和批評。審查將幾乎總是需è¦æ”¹é€²ï¼Œææ–™æ‰
能包括在內核中。è¦çŸ¥é“這是因爲所有相關人員都希望看到Linuxæ•´é«”æˆåŠŸçš„最佳解決方
-案。這個開發éŽç¨‹å·²ç¶“被證明å¯ä»¥å‰µå»ºæœ‰å²ä»¥ä¾†æœ€å¥å£¯çš„作業系統內核,我們ä¸æƒ³åšä»»ä½•
+案。這個開發éŽç¨‹å·²ç¶“被證明å¯ä»¥å‰µå»ºæœ‰å²ä»¥ä¾†æœ€å¥å£¯çš„æ“作系統內核,我們ä¸æƒ³åšä»»ä½•
事情來導致æ交質é‡å’Œæœ€çµ‚çµæžœçš„下é™ã€‚
維護者
------
-行為準則多次使用「維護者ã€ä¸€è©žã€‚在內核社å€ä¸­ï¼Œã€Œç¶­è­·è€…ã€æ˜¯è² è²¬å­ç³»çµ±ã€é©…動程åºæˆ–
-文件的任何人,並在內核原始碼樹的維護者文件中列出。
+行爲準則多次使用“維護者â€ä¸€è©žã€‚在內核社å€ä¸­ï¼Œâ€œç¶­è­·è€…â€æ˜¯è² è²¬å­ç³»çµ±ã€é©…動程åºæˆ–
+文件的任何人,並在內核æºä»£ç¢¼æ¨¹çš„維護者文件中列出。
責任
----
-《行為準則》æ到了維護人員的權利和責任,這需è¦é€²ä¸€æ­¥æ¾„清。
+《行爲準則》æ到了維護人員的權利和責任,這需è¦é€²ä¸€æ­¥æ¾„清。
首先,最é‡è¦çš„是,有一個åˆç†çš„期望是由維護人員通éŽå¯¦ä¾‹ä¾†é ˜å°Žã€‚
也就是說,我們的社å€æ˜¯å»£é—Šçš„,å°ç¶­è­·è€…沒有新的è¦æ±‚,他們單方é¢è™•ç†å…¶ä»–人在
-他們活èºçš„社å€çš„行爲。這一責任由我們所有人承擔,最終《行為準則》記錄了最終的
+他們活èºçš„社å€çš„行爲。這一責任由我們所有人承擔,最終《行爲準則》記錄了最終的
上訴路徑,以防有關行爲å•é¡Œçš„å•é¡Œæ‡¸è€Œæœªæ±ºã€‚
維護人員應該願æ„在出ç¾å•é¡Œæ™‚æ供幫助,並在需è¦æ™‚與社å€ä¸­çš„其他人åˆä½œã€‚如果您
@@ -43,10 +43,10 @@ Linux內核貢ç»è€…契約行為準則解釋
除éžæ‚¨é¡˜æ„,å¦å‰‡ä¸æœƒå°‡å…¶è¦–爲é•è¦å ±å‘Šã€‚如果您ä¸ç¢ºå®šæ˜¯å¦è©²è¯ç¹«TAB 或任何其他維
護人員,請è¯ç¹«æˆ‘們的è¡çªèª¿è§£äºº Mishi Choudhary <mishi@linux.com>。
-最後,「善待å°æ–¹ã€æ‰æ˜¯æ¯å€‹äººçš„最終目標。我們知é“æ¯å€‹äººéƒ½æ˜¯äººï¼Œæœ‰æ™‚我們都會失敗,
-但我們所有人的首è¦ç›®æ¨™æ‡‰è©²æ˜¯åŠªåŠ›å‹å¥½åœ°è§£æ±ºå•é¡Œã€‚執行行為準則將是最後的é¸æ“‡ã€‚
+最後,“善待å°æ–¹â€çº”是æ¯å€‹äººçš„最終目標。我們知é“æ¯å€‹äººéƒ½æ˜¯äººï¼Œæœ‰æ™‚我們都會失敗,
+但我們所有人的首è¦ç›®æ¨™æ‡‰è©²æ˜¯åŠªåŠ›å‹å¥½åœ°è§£æ±ºå•é¡Œã€‚執行行爲準則將是最後的é¸æ“‡ã€‚
-我們的目標是創建一個強大的ã€æŠ€è¡“先進的作業系統,以åŠæ‰€æ¶‰åŠçš„技術複雜性,這自
+我們的目標是創建一個強大的ã€æŠ€è¡“先進的æ“作系統,以åŠæ‰€æ¶‰åŠçš„技術複雜性,這自
然需è¦å°ˆæ¥­çŸ¥è­˜å’Œæ±ºç­–。
所需的專業知識因貢ç»é ˜åŸŸè€Œç•°ã€‚它主è¦ç”±ä¸Šä¸‹æ–‡å’ŒæŠ€è¡“複雜性決定,其次由貢ç»è€…å’Œ
@@ -55,58 +55,58 @@ Linux內核貢ç»è€…契約行為準則解釋
專家的期望和決策都è¦ç¶“éŽè¨Žè«–,但在最後,爲了å–得進展,必須能夠åšå‡ºæ±ºç­–。這一
特權掌æ¡åœ¨ç¶­è­·äººå“¡å’Œé …目領導的手中,é è¨ˆå°‡å–„æ„使用。
-因此,設定專業知識期望ã€ä½œå‡ºæ±ºå®šå’Œæ‹’絕ä¸é©ç•¶çš„è²¢ç»ä¸è¢«è¦–爲é•å行為準則。
+因此,設定專業知識期望ã€ä½œå‡ºæ±ºå®šå’Œæ‹’絕ä¸é©ç•¶çš„è²¢ç»ä¸è¢«è¦–爲é•å行爲準則。
雖然維護人員一般都歡迎新來者,但他們幫助(新)貢ç»è€…å…‹æœéšœç¤™çš„能力有é™ï¼Œå› æ­¤
-他們必須確定優先事項。這也ä¸æ‡‰è¢«è¦–爲é•å了行為準則。內核社å€æ„識到這一點,並
+他們必須確定優先事項。這也ä¸æ‡‰è¢«è¦–爲é•å了行爲準則。內核社å€æ„識到這一點,並
以å„種形å¼æ供入門級節目,如 kernelnewbies.org 。
範åœ
----
-Linux內核社å€ä¸»è¦åœ¨ä¸€çµ„公共電å­éƒµä»¶åˆ—表上進行交互,這些列表分布在由多個ä¸åŒ
-å…¬å¸æˆ–個人控制的多個ä¸åŒä¼ºæœå™¨ä¸Šã€‚所有這些列表都在內核原始碼樹中的
+Linux內核社å€ä¸»è¦åœ¨ä¸€çµ„公共電å­éƒµä»¶åˆ—表上進行交互,這些列表分佈在由多個ä¸åŒ
+å…¬å¸æˆ–個人控制的多個ä¸åŒæœå‹™å™¨ä¸Šã€‚所有這些列表都在內核æºä»£ç¢¼æ¨¹ä¸­çš„
MAINTAINERS 文件中定義。發é€åˆ°é€™äº›éƒµä»¶åˆ—表的任何電å­éƒµä»¶éƒ½è¢«è¦–爲包å«åœ¨è¡Œçˆ²
準則中。
使用 kernel.org bugzilla和其他å­ç³»çµ±bugzilla 或bug跟蹤工具的開發人員應該éµå¾ª
-行為準則的指導原則。Linux內核社å€æ²’有「官方ã€é …目電å­éƒµä»¶åœ°å€æˆ–「官方ã€ç¤¾äº¤åª’é«”
-地å€ã€‚使用kernel.orgé›»å­éƒµä»¶å¸³æˆ¶åŸ·è¡Œçš„任何活動必須éµå¾ªçˆ²kernel.org發布的行爲
+行爲準則的指導原則。Linux內核社å€æ²’有“官方â€é …目電å­éƒµä»¶åœ°å€æˆ–“官方â€ç¤¾äº¤åª’é«”
+地å€ã€‚使用kernel.orgé›»å­éƒµä»¶å¸³æˆ¶åŸ·è¡Œçš„任何活動必須éµå¾ªçˆ²kernel.org發佈的行爲
準則,就åƒä»»ä½•ä½¿ç”¨å…¬å¸é›»å­éƒµä»¶å¸³æˆ¶çš„個人必須éµå¾ªè©²å…¬å¸çš„特定è¦å‰‡ä¸€æ¨£ã€‚
-行為準則並ä¸ç¦æ­¢åœ¨éƒµä»¶åˆ—表消æ¯ã€å…§æ ¸æ›´æ”¹æ—¥èªŒæ¶ˆæ¯æˆ–代碼注釋中繼續包å«å稱ã€
+行爲準則並ä¸ç¦æ­¢åœ¨éƒµä»¶åˆ—表消æ¯ã€å…§æ ¸æ›´æ”¹æ—¥èªŒæ¶ˆæ¯æˆ–代碼註釋中繼續包å«å稱ã€
é›»å­éƒµä»¶åœ°å€å’Œç›¸é—œæ³¨é‡‹ã€‚
-其他論壇中的互動包括在é©ç”¨æ–¼ä¸Šè¿°è«–壇的任何è¦å‰‡ä¸­ï¼Œé€šå¸¸ä¸åŒ…括在行為準則中。
+其他論壇中的互動包括在é©ç”¨æ–¼ä¸Šè¿°è«–壇的任何è¦å‰‡ä¸­ï¼Œé€šå¸¸ä¸åŒ…括在行爲準則中。
除了在極端情æ³ä¸‹å¯è€ƒæ…®çš„例外情æ³ã€‚
-æ交給內核的貢ç»æ‡‰è©²ä½¿ç”¨é©ç•¶çš„語言。在行為準則之å‰å·²ç¶“存在的內容ç¾åœ¨ä¸æœƒè¢«
+æ交給內核的貢ç»æ‡‰è©²ä½¿ç”¨é©ç•¶çš„語言。在行爲準則之å‰å·²ç¶“存在的內容ç¾åœ¨ä¸æœƒè¢«
視爲é•å。然而,ä¸é©ç•¶çš„語言å¯ä»¥è¢«è¦–爲一個bug;如果任何相關方æ交補ä¸ï¼Œ
這樣的bug將被更快地修復。當å‰å±¬æ–¼ç”¨æˆ¶/內核API的一部分的表é”å¼ï¼Œæˆ–者å映已
-發布標準或è¦ç¯„中使用的術語的表é”å¼ï¼Œä¸è¢«è¦–爲bug。
+發佈標準或è¦ç¯„中使用的術語的表é”å¼ï¼Œä¸è¢«è¦–爲bug。
執行
----
-行為準則中列出的地å€å±¬æ–¼è¡Œç‚ºæº–則委員會。https://kernel.org/code-of-conduct.html
+行爲準則中列出的地å€å±¬æ–¼è¡Œçˆ²æº–則委員會。https://kernel.org/code-of-conduct.html
列出了在任何給定時間接收這些電å­éƒµä»¶çš„確切æˆå“¡ã€‚æˆå“¡ä¸èƒ½è¨ªå•åœ¨åŠ å…¥å§”員會之å‰
或離開委員會之後所åšçš„報告。
-最åˆçš„行為準則委員會由TAB的志願者以åŠä½œçˆ²ä¸­ç«‹ç¬¬ä¸‰æ–¹çš„專業調解人組æˆã€‚委員會
+最åˆçš„行爲準則委員會由TAB的志願者以åŠä½œçˆ²ä¸­ç«‹ç¬¬ä¸‰æ–¹çš„專業調解人組æˆã€‚委員會
的首è¦ä»»å‹™æ˜¯å»ºç«‹æ–‡ä»¶åŒ–çš„æµç¨‹ï¼Œä¸¦å°‡å…¶å…¬é–‹ã€‚
如果報告人ä¸å¸Œæœ›å°‡æ•´å€‹å§”員會ç´å…¥æŠ•è¨´æˆ–關切,å¯ç›´æŽ¥è¯ç¹«å§”員會的任何æˆå“¡ï¼ŒåŒ…括
調解人。
-行為準則委員會根據æµç¨‹å¯©æŸ¥æ¡ˆä¾‹ï¼ˆè¦‹ä¸Šæ–‡ï¼‰ï¼Œä¸¦æ ¹æ“šéœ€è¦å’Œé©ç•¶èˆ‡TABå”商,例如請求
+行爲準則委員會根據æµç¨‹å¯©æŸ¥æ¡ˆä¾‹ï¼ˆè¦‹ä¸Šæ–‡ï¼‰ï¼Œä¸¦æ ¹æ“šéœ€è¦å’Œé©ç•¶èˆ‡TABå”商,例如請求
和接收有關內核社å€çš„ä¿¡æ¯ã€‚
委員會åšå‡ºçš„任何決定都將æ交到表中,以便在必è¦æ™‚與相關維護人員一起執行。行爲
準則委員會的決定å¯ä»¥é€šéŽä¸‰åˆ†ä¹‹äºŒçš„投票推翻。
-æ¯å­£åº¦ï¼Œè¡Œç‚ºæº–則委員會和標籤將æ供一份報告,概述行為準則委員會收到的匿å報告
+æ¯å­£åº¦ï¼Œè¡Œçˆ²æº–則委員會和標籤將æ供一份報告,概述行爲準則委員會收到的匿å報告
åŠå…¶ç‹€æ…‹ï¼Œä»¥åŠä»»ä½•å¦æ±ºæ±ºå®šçš„細節,包括完整和å¯è­˜åˆ¥çš„投票細節。
-我們希望在啓動期之後爲行為準則委員會人員é…備建立一個ä¸åŒçš„æµç¨‹ã€‚發生此情æ³æ™‚,
+我們希望在啓動期之後爲行爲準則委員會人員é…備建立一個ä¸åŒçš„æµç¨‹ã€‚發生此情æ³æ™‚,
將使用該信æ¯æ›´æ–°æ­¤æ–‡æª”。
diff --git a/Documentation/translations/zh_TW/process/code-of-conduct.rst b/Documentation/translations/zh_TW/process/code-of-conduct.rst
index e3087112f0bc..a7a31de03526 100644
--- a/Documentation/translations/zh_TW/process/code-of-conduct.rst
+++ b/Documentation/translations/zh_TW/process/code-of-conduct.rst
@@ -8,7 +8,7 @@
.. _tw_code_of_conduct:
-è²¢ç»è€…契約行為準則
+è²¢ç»è€…契約行爲準則
++++++++++++++++++
我們的誓言
@@ -35,7 +35,7 @@
* 使用性æ„味的語言或æ„象以åŠä¸å—歡迎的性注æ„或者更éŽåˆ†çš„行爲
* 煽動ã€ä¾®è¾±/貶æ評論以åŠå€‹äººæˆ–政治攻擊
* 公開或ç§ä¸‹é¨·æ“¾
-* 未經明確許å¯ï¼Œç™¼å¸ƒä»–人的ç§äººä¿¡æ¯ï¼Œå¦‚物ç†æˆ–é›»å­åœ°å€ã€‚
+* 未經明確許å¯ï¼Œç™¼ä½ˆä»–人的ç§äººä¿¡æ¯ï¼Œå¦‚物ç†æˆ–é›»å­åœ°å€ã€‚
* 在專業場åˆè¢«åˆç†èªçˆ²ä¸é©ç•¶çš„其他行爲
我們的責任
@@ -44,29 +44,29 @@
維護人員負責澄清å¯æŽ¥å—行爲的標準,並應é‡å°ä»»ä½•ä¸å¯æŽ¥å—行爲採å–é©ç•¶å’Œå…¬å¹³çš„
糾正措施。
-維護人員有權和責任刪除ã€ç·¨è¼¯æˆ–拒絕與本行為準則ä¸ä¸€è‡´çš„è©•è«–ã€æ‰¿è«¾ã€ä»£ç¢¼ã€
+維護人員有權和責任刪除ã€ç·¨è¼¯æˆ–拒絕與本行爲準則ä¸ä¸€è‡´çš„è©•è«–ã€æ‰¿è«¾ã€ä»£ç¢¼ã€
wiki編輯ã€å•é¡Œå’Œå…¶ä»–è²¢ç»ï¼Œæˆ–暫時或永久ç¦æ­¢ä»»ä½•è²¢ç»è€…從事他們èªçˆ²ä¸é©ç•¶ã€
å¨è„…ã€å†’犯或有害的其他行爲。
範åœ
====
-當個人代表項目或其社å€æ™‚,本行為準則既é©ç”¨æ–¼é …目空間,也é©ç”¨æ–¼å…¬å…±ç©ºé–“。
+當個人代表項目或其社å€æ™‚,本行爲準則既é©ç”¨æ–¼é …目空間,也é©ç”¨æ–¼å…¬å…±ç©ºé–“。
代表一個項目或社å€çš„例å­åŒ…括使用一個正å¼çš„項目電å­éƒµä»¶åœ°å€ï¼Œé€šéŽä¸€å€‹æ­£å¼
-的社交媒體帳戶發布,或者在在線或離線事件中擔任指定的代表。項目維護人員å¯ä»¥
+的社交媒體帳戶發佈,或者在在線或離線事件中擔任指定的代表。項目維護人員å¯ä»¥
進一步定義和澄清項目的表示。
執行
====
-如有濫用ã€é¨·æ“¾æˆ–其他ä¸å¯æŽ¥å—的行爲,å¯è¯ç¹«è¡Œç‚ºæº–則委員會<conduct@kernel.org>。
-所有投訴都將接å—審查和調查,並將得到必è¦å’Œé©ç•¶çš„答覆。行為準則委員會有義務
-å°äº‹ä»¶å ±å‘Šäººä¿å¯†ã€‚具體執行政策的進一步細節å¯å–®ç¨å…¬å¸ƒã€‚
+如有濫用ã€é¨·æ“¾æˆ–其他ä¸å¯æŽ¥å—的行爲,å¯è¯ç¹«è¡Œçˆ²æº–則委員會<conduct@kernel.org>。
+所有投訴都將接å—審查和調查,並將得到必è¦å’Œé©ç•¶çš„答覆。行爲準則委員會有義務
+å°äº‹ä»¶å ±å‘Šäººä¿å¯†ã€‚具體執行政策的進一步細節å¯å–®ç¨å…¬ä½ˆã€‚
歸屬
====
-本行為準則改編自《貢ç»è€…契約》,版本1.4,å¯å¾ž
+本行爲準則改編自《貢ç»è€…契約》,版本1.4,å¯å¾ž
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html ç²å–。
解釋
diff --git a/Documentation/translations/zh_TW/process/coding-style.rst b/Documentation/translations/zh_TW/process/coding-style.rst
index 83862e4d3b64..5749363de421 100644
--- a/Documentation/translations/zh_TW/process/coding-style.rst
+++ b/Documentation/translations/zh_TW/process/coding-style.rst
@@ -2,42 +2,44 @@
.. include:: ../disclaimer-zh_TW.rst
-:Original: :ref:`Documentation/process/coding-style.rst <codingstyle>`
+:Original: Documentation/process/coding-style.rst
.. _tw_codingstyle:
-譯者::
+:譯者:
+ - 張樂 Zhang Le <r0bertz@gentoo.org>
+ - Andy Deng <theandy.deng@gmail.com>
+ - å³æƒ³æˆ <bobwxc@email.cn>
- 中文版維護者: 張樂 Zhang Le <r0bertz@gentoo.org>
- 中文版翻譯者: 張樂 Zhang Le <r0bertz@gentoo.org>
- 中文版校譯者: çŽ‹è° Wang Cong <xiyou.wangcong@gmail.com>
- wheelz <kernel.zeng@gmail.com>
- ç®¡æ—­æ± Xudong Guan <xudong.guan@gmail.com>
- Li Zefan <lizf@cn.fujitsu.com>
- Wang Chen <wangchen@cn.fujitsu.com>
- Hu Haowen <src.res.211@gmail.com>
+:æ ¡è­¯:
+ - çŽ‹è° Wang Cong <xiyou.wangcong@gmail.com>
+ - wheelz <kernel.zeng@gmail.com>
+ - ç®¡æ—­æ± Xudong Guan <xudong.guan@gmail.com>
+ - Li Zefan <lizf@cn.fujitsu.com>
+ - Wang Chen <wangchen@cn.fujitsu.com>
+ - Hu Haowen <src.res.211@gmail.com>
Linux 內核代碼風格
-=========================
+==================
這是一個簡短的文檔,æ述了 linux 內核的首é¸ä»£ç¢¼é¢¨æ ¼ã€‚代碼風格是因人而異的,
而且我ä¸é¡˜æ„把自己的觀點強加給任何人,但這就åƒæˆ‘去åšä»»ä½•äº‹æƒ…都必須éµå¾ªçš„原則
-那樣,我也希望在絕大多數事上ä¿æŒé€™ç¨®çš„態度。請 (在寫代碼時) 至少考慮一下這裡
+那樣,我也希望在絕大多數事上ä¿æŒé€™ç¨®çš„態度。請 (在寫代碼時) 至少考慮一下這è£
的代碼風格。
-首先,我建議你列å°ä¸€ä»½ GNU 代碼è¦ç¯„,然後ä¸è¦è®€ã€‚燒了它,這是一個具有é‡å¤§è±¡å¾µ
+首先,我建議你打å°ä¸€ä»½ GNU 代碼è¦ç¯„,然後ä¸è¦è®€ã€‚燒了它,這是一個具有é‡å¤§è±¡å¾µ
性æ„義的動作。
ä¸ç®¡æ€Žæ¨£ï¼Œç¾åœ¨æˆ‘們開始:
1) 縮進
---------------
+-------
-制表符是 8 個字符,所以縮進也是 8 個字符。有些異端é‹å‹•è©¦åœ–將縮進變爲 4 (甚至
+製表符是 8 個字符,所以縮進也是 8 個字符。有些異端é‹å‹•è©¦åœ–將縮進變爲 4 (甚至
2ï¼) 字符深,這幾乎相當於嘗試將圓周率的值定義爲 3。
-ç†ç”±ï¼šç¸®é€²çš„全部æ„義就在於清楚的定義一個控制塊起止於何處。尤其是當你盯著你的
+ç†ç”±ï¼šç¸®é€²çš„全部æ„義就在於清楚的定義一個控制塊起止於何處。尤其是當你盯ç€ä½ çš„
å±å¹•é€£çºŒçœ‹äº† 20 å°æ™‚之後,你將會發ç¾å¤§ä¸€é»žçš„縮進會使你更容易分辨縮進。
ç¾åœ¨ï¼Œæœ‰äº›äººæœƒæŠ±æ€¨ 8 個字符的縮進會使代碼å‘å³é‚Šç§»å‹•çš„太é ï¼Œåœ¨ 80 個字符的終端
@@ -69,39 +71,60 @@ Linux 內核代碼風格
break;
}
-ä¸è¦æŠŠå¤šå€‹èªžå¥æ”¾åœ¨ä¸€è¡Œé‡Œï¼Œé™¤éžä½ æœ‰ä»€éº¼æ±è¥¿è¦éš±è—:
+ä¸è¦æŠŠå¤šå€‹èªžå¥æ”¾åœ¨ä¸€è¡Œè£ï¼Œé™¤éžä½ æœ‰ä»€éº¼æ±è¥¿è¦éš±è—:
.. code-block:: c
if (condition) do_this;
do_something_everytime;
-也ä¸è¦åœ¨ä¸€è¡Œé‡Œæ”¾å¤šå€‹è³¦å€¼èªžå¥ã€‚內核代碼風格超級簡單。就是é¿å…å¯èƒ½å°Žè‡´åˆ¥äººèª¤è®€
+ä¸è¦ä½¿ç”¨é€—號來é¿å…使用大括號:
+
+.. code-block:: c
+
+ if (condition)
+ do_this(), do_that();
+
+使用大括號包裹多語å¥ï¼š
+
+.. code-block:: c
+
+ if (condition) {
+ do_this();
+ do_that();
+ }
+
+也ä¸è¦åœ¨ä¸€è¡Œè£æ”¾å¤šå€‹è³¦å€¼èªžå¥ã€‚內核代碼風格超級簡單。就是é¿å…å¯èƒ½å°Žè‡´åˆ¥äººèª¤è®€
的表é”å¼ã€‚
-除了注釋ã€æ–‡æª”å’Œ Kconfig 之外,ä¸è¦ä½¿ç”¨ç©ºæ ¼ä¾†ç¸®é€²ï¼Œå‰é¢çš„例å­æ˜¯ä¾‹å¤–,是有æ„爲
+除了註釋ã€æ–‡æª”å’Œ Kconfig 之外,ä¸è¦ä½¿ç”¨ç©ºæ ¼ä¾†ç¸®é€²ï¼Œå‰é¢çš„例å­æ˜¯ä¾‹å¤–,是有æ„爲
之。
é¸ç”¨ä¸€å€‹å¥½çš„編輯器,ä¸è¦åœ¨è¡Œå°¾ç•™ç©ºæ ¼ã€‚
2) 把長的行和字符串打散
-------------------------------
+-----------------------
代碼風格的æ„義就在於使用平常使用的工具來維æŒä»£ç¢¼çš„å¯è®€æ€§å’Œå¯ç¶­è­·æ€§ã€‚
æ¯ä¸€è¡Œçš„長度的é™åˆ¶æ˜¯ 80 列,我們強烈建議您éµå®ˆé€™å€‹æ…£ä¾‹ã€‚
é•·æ–¼ 80 列的語å¥è¦æ‰“æ•£æˆæœ‰æ„義的片段。除éžè¶…éŽ 80 列能顯著增加å¯è®€æ€§ï¼Œä¸¦ä¸”ä¸
-會隱è—ä¿¡æ¯ã€‚å­ç‰‡æ®µè¦æ˜Žé¡¯çŸ­æ–¼æ¯ç‰‡æ®µï¼Œä¸¦æ˜Žé¡¯é å³ã€‚這åŒæ¨£é©ç”¨æ–¼æœ‰è‘—很長åƒæ•¸åˆ—表
-的函數頭。然而,絕å°ä¸è¦æ‰“æ•£å°ç”¨æˆ¶å¯è¦‹çš„字符串,例如 printk ä¿¡æ¯ï¼Œå› çˆ²é€™æ¨£å°±
+會隱è—ä¿¡æ¯ã€‚
+
+å­ç‰‡æ®µè¦æ˜Žé¡¯çŸ­æ–¼æ¯ç‰‡æ®µï¼Œä¸¦æ˜Žé¡¯é å³ã€‚一種éžå¸¸å¸¸ç”¨çš„樣å¼æ˜¯å°‡å­é«”與函數左括號å°é½Šã€‚
+
+這åŒæ¨£é©ç”¨æ–¼æœ‰ç€å¾ˆé•·åƒæ•¸åˆ—表的函數頭。
+
+然而,絕å°ä¸è¦æ‰“æ•£å°ç”¨æˆ¶å¯è¦‹çš„字符串,例如 printk ä¿¡æ¯ï¼Œå› çˆ²é€™æ¨£å°±
很難å°å®ƒå€‘ grep。
3) 大括號和空格的放置
-------------------------------
+---------------------
-C 語言風格中å¦å¤–一個常見å•é¡Œæ˜¯å¤§æ‹¬è™Ÿçš„放置。和縮進大å°ä¸åŒï¼Œé¸æ“‡æˆ–棄用æŸç§æ”¾
+C 語言風格中å¦å¤–一個常見å•é¡Œæ˜¯å¤§æ‹¬è™Ÿçš„放置。和縮進大å°ä¸åŒï¼Œé¸æ“‡æˆ–棄用æŸç¨®æ”¾
置策略並沒有多少技術上的原因,ä¸éŽé¦–é¸çš„æ–¹å¼ï¼Œå°±åƒ Kernighan å’Œ Ritchie 展示
給我們的,是把起始大括號放在行尾,而把çµæŸå¤§æ‹¬è™Ÿæ”¾åœ¨è¡Œé¦–,所以:
@@ -135,12 +158,12 @@ C 語言風格中å¦å¤–一個常見å•é¡Œæ˜¯å¤§æ‹¬è™Ÿçš„放置。和縮進大å°
body of function
}
-全世界的異端å¯èƒ½æœƒæŠ±æ€¨é€™å€‹ä¸ä¸€è‡´æ€§æ˜¯... 呃... ä¸ä¸€è‡´çš„,ä¸éŽæ‰€æœ‰æ€ç¶­å¥å…¨çš„人
+全世界的異端å¯èƒ½æœƒæŠ±æ€¨é€™å€‹ä¸ä¸€è‡´æ€§æ˜¯â€¦â€¦å‘ƒâ€¦â€¦ä¸ä¸€è‡´ï¼Œä¸éŽæ‰€æœ‰æ€ç¶­å¥å…¨çš„人
éƒ½çŸ¥é“ (a) K&R 是 **正確的** 並且 (b) K&R 是正確的。此外,ä¸ç®¡æ€Žæ¨£å‡½æ•¸éƒ½æ˜¯ç‰¹
殊的 (C 函數是ä¸èƒ½åµŒå¥—çš„)。
-注æ„çµæŸå¤§æ‹¬è™Ÿç¨è‡ªå æ“šä¸€è¡Œï¼Œé™¤éžå®ƒå¾Œé¢è·Ÿè‘—åŒä¸€å€‹èªžå¥çš„剩餘部分,也就是 do 語
-å¥ä¸­çš„ "while" 或者 if 語å¥ä¸­çš„ "else",åƒé€™æ¨£ï¼š
+注æ„çµæŸå¤§æ‹¬è™Ÿç¨è‡ªä½”據一行,除éžå®ƒå¾Œé¢è·Ÿç€åŒä¸€å€‹èªžå¥çš„剩餘部分,也就是 do 語
+å¥ä¸­çš„ ``while`` 或者 if 語å¥ä¸­çš„ ``else`` ,åƒé€™æ¨£ï¼š
.. code-block:: c
@@ -164,7 +187,7 @@ C 語言風格中å¦å¤–一個常見å•é¡Œæ˜¯å¤§æ‹¬è™Ÿçš„放置。和縮進大å°
也請注æ„這種大括號的放置方å¼ä¹Ÿèƒ½ä½¿ç©º (或者差ä¸å¤šç©ºçš„) 行的數é‡æœ€å°åŒ–,åŒæ™‚ä¸
失å¯è®€æ€§ã€‚因此,由於你的å±å¹•ä¸Šçš„新行是ä¸å¯å†ç”Ÿè³‡æº (想想 25 行的終端å±å¹•),你
-將會有更多的空行來放置注釋。
+將會有更多的空行來放置註釋。
當åªæœ‰ä¸€å€‹å–®ç¨çš„語å¥çš„時候,ä¸ç”¨åŠ ä¸å¿…è¦çš„大括號。
@@ -194,12 +217,12 @@ C 語言風格中å¦å¤–一個常見å•é¡Œæ˜¯å¤§æ‹¬è™Ÿçš„放置。和縮進大å°
}
3.1) 空格
-********************
+*********
Linux å…§æ ¸çš„ç©ºæ ¼ä½¿ç”¨æ–¹å¼ (主è¦) å–決於它是用於函數還是關éµå­—。(大多數) é—œéµå­—
後è¦åŠ ä¸€å€‹ç©ºæ ¼ã€‚值得注æ„的例外是 sizeof, typeof, alignof å’Œ __attribute__,這
-些關éµå­—æŸäº›ç¨‹åº¦ä¸Šçœ‹èµ·ä¾†æ›´åƒå‡½æ•¸ (它們在 Linux 里也常常伴隨å°æ‹¬è™Ÿè€Œä½¿ç”¨ï¼Œå„˜ç®¡
-在 C 里這樣的å°æ‹¬è™Ÿä¸æ˜¯å¿…éœ€çš„ï¼Œå°±åƒ ``struct fileinfo info;`` è²æ˜ŽéŽå¾Œçš„
+些關éµå­—æŸäº›ç¨‹åº¦ä¸Šçœ‹èµ·ä¾†æ›´åƒå‡½æ•¸ (它們在 Linux è£ä¹Ÿå¸¸å¸¸ä¼´éš¨å°æ‹¬è™Ÿè€Œä½¿ç”¨ï¼Œå„˜ç®¡
+在 C è£é€™æ¨£çš„å°æ‹¬è™Ÿä¸æ˜¯å¿…éœ€çš„ï¼Œå°±åƒ ``struct fileinfo info;`` è²æ˜ŽéŽå¾Œçš„
``sizeof info``)。
所以在這些關éµå­—之後放一個空格::
@@ -213,7 +236,7 @@ Linux å…§æ ¸çš„ç©ºæ ¼ä½¿ç”¨æ–¹å¼ (主è¦) å–決於它是用於函數還是關é
s = sizeof(struct file);
-ä¸è¦åœ¨å°æ‹¬è™Ÿé‡Œçš„表é”å¼å…©å´åŠ ç©ºæ ¼ã€‚這是一個 **å例** :
+ä¸è¦åœ¨å°æ‹¬è™Ÿè£çš„表é”å¼å…©å´åŠ ç©ºæ ¼ã€‚這是一個 **å例** :
.. code-block:: c
@@ -257,10 +280,10 @@ Linux å…§æ ¸çš„ç©ºæ ¼ä½¿ç”¨æ–¹å¼ (主è¦) å–決於它是用於函數還是關é
4) 命å
-------------------------------
+-------
-C 是一個簡樸的語言,你的命å也應該這樣。和 Modula-2 å’Œ Pascal 程å¼è¨­è¨ˆå¸«ä¸åŒï¼Œ
-C 程å¼è¨­è¨ˆå¸«ä¸ä½¿ç”¨é¡žä¼¼ ThisVariableIsATemporaryCounter 這樣è¯éº—çš„å字。C 程å¼è¨­è¨ˆå¸«æœƒ
+C 是一個簡樸的語言,你的命å也應該這樣。和 Modula-2 å’Œ Pascal 程åºå“¡ä¸åŒï¼Œ
+C 程åºå“¡ä¸ä½¿ç”¨é¡žä¼¼ ThisVariableIsATemporaryCounter 這樣è¯éº—çš„å字。C 程åºå“¡æœƒ
稱那個變é‡çˆ² ``tmp`` ,這樣寫起來會更容易,而且至少ä¸æœƒä»¤å…¶é›£æ–¼ç†è§£ã€‚
ä¸éŽï¼Œé›–然混用大å°å¯«çš„å字是ä¸æ倡使用的,但是全局變é‡é‚„是需è¦ä¸€å€‹å…·æ述性的
@@ -271,23 +294,42 @@ C 程å¼è¨­è¨ˆå¸«ä¸ä½¿ç”¨é¡žä¼¼ ThisVariableIsATemporaryCounter 這樣è¯éº—çš„
``count_active_users()`` 或者類似的å字,你ä¸æ‡‰è©²å«å®ƒ ``cntuser()`` 。
在函數å中包å«å‡½æ•¸é¡žåž‹ (所謂的匈牙利命å法) 是腦å­å‡ºäº†å•é¡Œâ€”—編譯器知é“那些類
-型而且能夠檢查那些類型,這樣åšåªèƒ½æŠŠç¨‹å¼è¨­è¨ˆå¸«å¼„糊塗了。難怪微軟總是製造出有å•é¡Œ
-的程åºã€‚
+型而且能夠檢查那些類型,這樣åšåªèƒ½æŠŠç¨‹åºå“¡å¼„糊塗了。
本地變é‡å應該簡短,而且能夠表é”相關的å«ç¾©ã€‚如果你有一些隨機的整數型的循環計
數器,它應該被稱爲 ``i`` 。å«å®ƒ ``loop_counter`` 並無益處,如果它沒有被誤解的
å¯èƒ½çš„話。類似的, ``tmp`` å¯ä»¥ç”¨ä¾†ç¨±å‘¼ä»»æ„類型的臨時變é‡ã€‚
如果你怕混淆了你的本地變é‡å,你就é‡åˆ°å¦ä¸€å€‹å•é¡Œäº†ï¼Œå«åšå‡½æ•¸å¢žé•·è·çˆ¾è’™å¤±è¡¡ç¶œ
-åˆç—‡ã€‚請看第六章 (函數)。
+åˆå¾µã€‚請看第六章 (函數)。
+å°æ–¼ç¬¦è™Ÿå稱和文檔,é¿å…引入新的“master/slaveâ€ï¼ˆæˆ–ç¨ç«‹æ–¼â€œmasterâ€çš„“slaveâ€ï¼‰
+和“blacklist/whitelistâ€ã€‚
+
+“master/slaveâ€æŽ¨è–¦æ›¿æ›çˆ²ï¼š
+ '{primary,main} / {secondary,replica,subordinate}'
+ '{initiator,requester} / {target,responder}'
+ '{controller,host} / {device,worker,proxy}'
+ 'leader/follower'
+ 'director/performer'
+
+“blacklist/whitelistâ€æŽ¨è–¦æ›¿æ›çˆ²ï¼š
+ 'denylist/allowlist'
+ 'blocklist/passlist'
+
+引入新用法的例外情æ³æ˜¯ï¼šç¶­è­·ç”¨æˆ¶ç©ºé–“ABI/API,或更新ç¾æœ‰ï¼ˆæˆªè‡³2020年)硬件或
+å”è­°è¦ç¯„的代碼時è¦æ±‚這些術語。å°æ–¼æ–°è¦ç¯„,儘å¯èƒ½å°‡è¡“語的è¦ç¯„用法轉æ›çˆ²å…§æ ¸
+編碼標準。
+
+.. warning::
+ 以上主從ã€é»‘白åå–®è¦å‰‡ä¸é©ç”¨æ–¼ä¸­æ–‡æ–‡æª”,請勿更改中文術語ï¼
5) Typedef
------------
+----------
ä¸è¦ä½¿ç”¨é¡žä¼¼ ``vps_t`` 之類的æ±è¥¿ã€‚
-å°çµæ§‹é«”和指é‡ä½¿ç”¨ typedef 是一個 **錯誤** 。當你在代碼里看到:
+å°çµæ§‹é«”和指é‡ä½¿ç”¨ typedef 是一個 **錯誤** 。當你在代碼è£çœ‹åˆ°ï¼š
.. code-block:: c
@@ -312,13 +354,13 @@ C 程å¼è¨­è¨ˆå¸«ä¸ä½¿ç”¨é¡žä¼¼ ThisVariableIsATemporaryCounter 這樣è¯éº—çš„
.. note::
- ä¸é€æ˜Žæ€§å’Œ "訪å•å‡½æ•¸" 本身是ä¸å¥½çš„。我們使用 pte_t 等類型的原因在於真
+ ä¸é€æ˜Žæ€§å’Œâ€œè¨ªå•å‡½æ•¸â€æœ¬èº«æ˜¯ä¸å¥½çš„。我們使用 pte_t 等類型的原因在於真
的是完全沒有任何共用的å¯è¨ªå•ä¿¡æ¯ã€‚
(b) 清楚的整數類型,如此,這層抽象就å¯ä»¥ **幫助** 消除到底是 ``int`` 還是
``long`` 的混淆。
- u8/u16/u32 是完全沒有å•é¡Œçš„ typedef,ä¸éŽå®ƒå€‘更符åˆé¡žåˆ¥ (d) 而ä¸æ˜¯é€™è£¡ã€‚
+ u8/u16/u32 是完全沒有å•é¡Œçš„ typedef,ä¸éŽå®ƒå€‘更符åˆé¡žåˆ¥ (d) 而ä¸æ˜¯é€™è£ã€‚
.. note::
@@ -345,30 +387,30 @@ C 程å¼è¨­è¨ˆå¸«ä¸ä½¿ç”¨é¡žä¼¼ ThisVariableIsATemporaryCounter 這樣è¯éº—çš„
(e) å¯ä»¥åœ¨ç”¨æˆ¶ç©ºé–“安全使用的類型。
- 在æŸäº›ç”¨æˆ¶ç©ºé–“å¯è¦‹çš„çµæ§‹é«”裡,我們ä¸èƒ½è¦æ±‚ C99 類型而且ä¸èƒ½ç”¨ä¸Šé¢æ到的
+ 在æŸäº›ç”¨æˆ¶ç©ºé–“å¯è¦‹çš„çµæ§‹é«”è£ï¼Œæˆ‘們ä¸èƒ½è¦æ±‚ C99 類型而且ä¸èƒ½ç”¨ä¸Šé¢æ到的
``u32`` 類型。因此,我們在與用戶空間共享的所有çµæ§‹é«”中使用 __u32 和類似
的類型。
å¯èƒ½é‚„有其他的情æ³ï¼Œä¸éŽåŸºæœ¬çš„è¦å‰‡æ˜¯ **æ°¸é ä¸è¦** 使用 typedef,除éžä½ å¯ä»¥æ˜Ž
確的應用上述æŸå€‹è¦å‰‡ä¸­çš„一個。
-總的來說,如果一個指é‡æˆ–者一個çµæ§‹é«”裡的元素å¯ä»¥åˆç†çš„被直接訪å•åˆ°ï¼Œé‚£éº¼å®ƒå€‘
+總的來說,如果一個指é‡æˆ–者一個çµæ§‹é«”è£çš„元素å¯ä»¥åˆç†çš„被直接訪å•åˆ°ï¼Œé‚£éº¼å®ƒå€‘
å°±ä¸æ‡‰è©²æ˜¯ä¸€å€‹ typedef。
6) 函數
-------------------------------
+-------
函數應該簡短而漂亮,並且åªå®Œæˆä¸€ä»¶äº‹æƒ…。函數應該å¯ä»¥ä¸€å±æˆ–者兩å±é¡¯ç¤ºå®Œ (我們
éƒ½çŸ¥é“ ISO/ANSI å±å¹•å¤§å°æ˜¯ 80x24),åªåšä¸€ä»¶äº‹æƒ…,而且把它åšå¥½ã€‚
一個函數的最大長度是和該函數的複雜度和縮進級數æˆå比的。所以,如果你有一個ç†
論上很簡單的åªæœ‰ä¸€å€‹å¾ˆé•· (但是簡單) çš„ case 語å¥çš„函數,而且你需è¦åœ¨æ¯å€‹ case
-里åšå¾ˆå¤šå¾ˆå°çš„事情,這樣的函數儘管很長,但也是å¯ä»¥çš„。
+è£åšå¾ˆå¤šå¾ˆå°çš„事情,這樣的函數儘管很長,但也是å¯ä»¥çš„。
ä¸éŽï¼Œå¦‚果你有一個複雜的函數,而且你懷疑一個天分ä¸æ˜¯å¾ˆé«˜çš„高中一年級學生å¯èƒ½
甚至æžä¸æ¸…楚這個函數的目的,你應該嚴格éµå®ˆå‰é¢æ到的長度é™åˆ¶ã€‚使用輔助函數,
-並爲之å–個具æ述性的åå­— (如果你覺得它們的性能很é‡è¦çš„話,å¯ä»¥è®“編譯器內è¯å®ƒ
+併爲之å–個具æ述性的åå­— (如果你覺得它們的性能很é‡è¦çš„話,å¯ä»¥è®“編譯器內è¯å®ƒ
們,這樣的效果往往會比你寫一個複雜函數的效果è¦å¥½ã€‚)
函數的å¦å¤–一個衡é‡æ¨™æº–是本地變é‡çš„數é‡ã€‚此數é‡ä¸æ‡‰è¶…éŽ 5ï¼10 個,å¦å‰‡ä½ çš„函數
@@ -376,7 +418,7 @@ C 程å¼è¨­è¨ˆå¸«ä¸ä½¿ç”¨é¡žä¼¼ ThisVariableIsATemporaryCounter 這樣è¯éº—çš„
çš„åŒæ™‚跟蹤 7 個ä¸åŒçš„事物,如果å†å¢žå¤šçš„話,就會糊塗了。å³ä¾¿ä½ è°ç©ŽéŽäººï¼Œä½ ä¹Ÿå¯
能會記ä¸æ¸…ä½  2 個星期å‰åšéŽçš„事情。
-在æºæ–‡ä»¶é‡Œï¼Œä½¿ç”¨ç©ºè¡Œéš”é–‹ä¸åŒçš„函數。如果該函數需è¦è¢«å°Žå‡ºï¼Œå®ƒçš„ **EXPORT** å®
+在æºæ–‡ä»¶è£ï¼Œä½¿ç”¨ç©ºè¡Œéš”é–‹ä¸åŒçš„函數。如果該函數需è¦è¢«å°Žå‡ºï¼Œå®ƒçš„ **EXPORT** å®
應該緊貼在它的çµæŸå¤§æ‹¬è™Ÿä¹‹ä¸‹ã€‚比如:
.. code-block:: c
@@ -387,12 +429,46 @@ C 程å¼è¨­è¨ˆå¸«ä¸ä½¿ç”¨é¡žä¼¼ ThisVariableIsATemporaryCounter 這樣è¯éº—çš„
}
EXPORT_SYMBOL(system_is_up);
-在函數原型中,包å«å‡½æ•¸å和它們的數據類型。雖然 C 語言裡沒有這樣的è¦æ±‚,在
-Linux 里這是æ倡的åšæ³•ï¼Œå› çˆ²é€™æ¨£å¯ä»¥å¾ˆç°¡å–®çš„給讀者æ供更多的有價值的信æ¯ã€‚
+6.1) 函數原型
+*************
+
+在函數原型中包å«åƒæ•¸å和它們的數據類型。雖然 C 語言è£æ²’有這樣的è¦æ±‚,但在
+Linux è£é€™æ˜¯æ倡的åšæ³•ï¼Œå› çˆ²é€™æ¨£å¯ä»¥å¾ˆç°¡å–®çš„給讀者æ供更多的有價值的信æ¯ã€‚
+ä¸è¦åœ¨å‡½æ•¸è²æ˜Žè£ä½¿ç”¨ ``extern`` é—œéµå­—,因爲這會導致代碼行變長,並且ä¸æ˜¯åš´æ ¼
+必需的。
+
+寫函數原型時,請ä¿æŒ `元素順åºè¦å‰‡ <https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_ 。
+例如下列函數è²æ˜Ž::
+
+ __init void * __must_check action(enum magic value, size_t size, u8 count,
+ char *fmt, ...) __printf(4, 5) __malloc;
+
+推薦的函數原型元素順åºæ˜¯ï¼š
+
+- 儲存類型(下方的 ``static __always_inline`` ï¼Œæ³¨æ„ ``__always_inline``
+ æŠ€è¡“ä¸Šä¾†è¬›æ˜¯å€‹å±¬æ€§ä½†è¢«ç•¶åš ``inline`` )
+- 儲存類型屬性(上方的 ``__init`` ——å³ç¯€è²æ˜Žï¼Œä½†ä¹Ÿåƒ ``__cold`` )
+- 返回類型(上方的 ``void *`` )
+- 返回類型屬性(上方的 ``__must_check`` )
+- 函數å(上方的 ``action`` )
+- 函數åƒæ•¸ï¼ˆä¸Šæ–¹çš„ ``(enum magic value, size_t size, u8 count, char *fmt, ...)`` ,
+ 注æ„必須寫上åƒæ•¸å)
+- 函數åƒæ•¸å±¬æ€§ï¼ˆä¸Šæ–¹çš„ ``__printf(4, 5)`` )
+- 函數行爲屬性(上方的 ``__malloc`` )
+
+請注æ„,å°æ–¼å‡½æ•¸ **定義** (å³å¯¦éš›å‡½æ•¸é«”),編譯器ä¸å…許在函數åƒæ•¸ä¹‹å¾Œæ·»åŠ å‡½
+數åƒæ•¸å±¬æ€§ã€‚在這種情æ³ä¸‹ï¼Œå®ƒå€‘應該跟隨存儲類型屬性(例如,與上é¢çš„ **è²æ˜Ž**
+示例相比,請注æ„下é¢çš„ ``__printf(4, 5)`` çš„ä½ç½®ç™¼ç”Ÿäº†è®ŠåŒ–)::
+
+ static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value,
+ size_t size, u8 count, char *fmt, ...) __malloc
+ {
+ ...
+ }
7) 集中的函數退出途徑
-------------------------------
+---------------------
雖然被æŸäº›äººè²ç¨±å·²ç¶“éŽæ™‚,但是 goto 語å¥çš„等價物還是經常被編譯器所使用,具體
å½¢å¼æ˜¯ç„¡æ¢ä»¶è·³è½‰æŒ‡ä»¤ã€‚
@@ -436,7 +512,7 @@ Linux 里這是æ倡的åšæ³•ï¼Œå› çˆ²é€™æ¨£å¯ä»¥å¾ˆç°¡å–®çš„給讀者æä¾›æ›
return result;
}
-一個需è¦æ³¨æ„的常見錯誤是 ``一個 err 錯誤`` ,就åƒé€™æ¨£ï¼š
+一個需è¦æ³¨æ„的常見錯誤是 ``å–® err 錯誤`` ,就åƒé€™æ¨£ï¼š
.. code-block:: c
@@ -459,22 +535,22 @@ Linux 里這是æ倡的åšæ³•ï¼Œå› çˆ²é€™æ¨£å¯ä»¥å¾ˆç°¡å–®çš„給讀者æä¾›æ›
ç†æƒ³æƒ…æ³ä¸‹ï¼Œä½ æ‡‰è©²æ¨¡æ“¬éŒ¯èª¤ä¾†æ¸¬è©¦æ‰€æœ‰é€€å‡ºè·¯å¾‘。
-8) 注釋
-------------------------------
+8) 註釋
+-------
-注釋是好的,ä¸éŽæœ‰éŽåº¦æ³¨é‡‹çš„å±éšªã€‚æ°¸é ä¸è¦åœ¨æ³¨é‡‹é‡Œè§£é‡‹ä½ çš„代碼是如何é‹ä½œçš„:
+註釋是好的,ä¸éŽæœ‰éŽåº¦è¨»é‡‹çš„å±éšªã€‚æ°¸é ä¸è¦åœ¨è¨»é‡‹è£è§£é‡‹ä½ çš„代碼是如何é‹ä½œçš„:
更好的åšæ³•æ˜¯è®“別人一看你的代碼就å¯ä»¥æ˜Žç™½ï¼Œè§£é‡‹å¯«çš„很差的代碼是浪費時間。
-一般的,你想è¦ä½ çš„注釋告訴別人你的代碼åšäº†ä»€éº¼ï¼Œè€Œä¸æ˜¯æ€Žéº¼åšçš„。也請你ä¸è¦æŠŠ
-注釋放在一個函數體內部:如果函數複雜到你需è¦ç¨ç«‹çš„注釋其中的一部分,你很å¯èƒ½
+一般來說你用註釋告訴別人你的代碼åšäº†ä»€éº¼ï¼Œè€Œä¸æ˜¯æ€Žéº¼åšçš„。也請你ä¸è¦æŠŠ
+註釋放在一個函數體內部:如果函數複雜到你需è¦ç¨ç«‹çš„註釋其中的一部分,你很å¯èƒ½
需è¦å›žåˆ°ç¬¬å…­ç« çœ‹ä¸€çœ‹ã€‚ä½ å¯ä»¥åšä¸€äº›å°æ³¨é‡‹ä¾†è¨»æ˜Žæˆ–警告æŸäº›å¾ˆè°æ˜Ž (或者槽糕) çš„
-åšæ³•ï¼Œä½†ä¸è¦åŠ å¤ªå¤šã€‚你應該åšçš„,是把注釋放在函數的頭部,告訴人們它åšäº†ä»€éº¼ï¼Œ
+åšæ³•ï¼Œä½†ä¸è¦åŠ å¤ªå¤šã€‚你應該åšçš„,是把註釋放在函數的頭部,告訴人們它åšäº†ä»€éº¼ï¼Œ
也å¯ä»¥åŠ ä¸Šå®ƒåšé€™äº›äº‹æƒ…的原因。
-當注釋內核 API 函數時,請使用 kernel-doc æ ¼å¼ã€‚請看
-Documentation/doc-guide/ å’Œ scripts/kernel-doc 以ç²å¾—詳細信æ¯ã€‚
+當註釋內核 API 函數時,請使用 kernel-doc æ ¼å¼ã€‚詳見
+Documentation/translations/zh_CN/doc-guide/index.rst 和 scripts/kernel-doc 。
-é•· (多行) 注釋的首é¸é¢¨æ ¼æ˜¯ï¼š
+é•· (多行) 註釋的首é¸é¢¨æ ¼æ˜¯ï¼š
.. code-block:: c
@@ -487,7 +563,7 @@ Documentation/doc-guide/ å’Œ scripts/kernel-doc 以ç²å¾—詳細信æ¯ã€‚
* with beginning and ending almost-blank lines.
*/
-å°æ–¼åœ¨ net/ å’Œ drivers/net/ 的文件,首é¸çš„é•· (多行) 注釋風格有些ä¸åŒã€‚
+å°æ–¼åœ¨ net/ å’Œ drivers/net/ 的文件,首é¸çš„é•· (多行) 註釋風格有些ä¸åŒã€‚
.. code-block:: c
@@ -498,23 +574,24 @@ Documentation/doc-guide/ å’Œ scripts/kernel-doc 以ç²å¾—詳細信æ¯ã€‚
* but there is no initial almost-blank line.
*/
-注釋數據也是很é‡è¦çš„,ä¸ç®¡æ˜¯åŸºæœ¬é¡žåž‹é‚„是è¡ç”Ÿé¡žåž‹ã€‚爲了方便實ç¾é€™ä¸€é»žï¼Œæ¯ä¸€è¡Œ
+註釋數據也是很é‡è¦çš„,ä¸ç®¡æ˜¯åŸºæœ¬é¡žåž‹é‚„是è¡ç”Ÿé¡žåž‹ã€‚爲了方便實ç¾é€™ä¸€é»žï¼Œæ¯ä¸€è¡Œ
應åªè²æ˜Žä¸€å€‹æ•¸æ“š (ä¸è¦ä½¿ç”¨é€—號來一次è²æ˜Žå¤šå€‹æ•¸æ“š)。這樣你就有空間來爲æ¯å€‹æ•¸æ“š
寫一段å°æ³¨é‡‹ä¾†è§£é‡‹å®ƒå€‘的用途了。
9) 你已經把事情弄糟了
-------------------------------
+---------------------
-這沒什麼,我們都是這樣。å¯èƒ½ä½ çš„使用了很長時間 Unix 的朋å‹å·²ç¶“告訴你
-``GNU emacs`` 能自動幫你格å¼åŒ– C 原始碼,而且你也注æ„到了,確實是這樣,ä¸éŽå®ƒ
+這沒什麼,我們都是這樣。å¯èƒ½ä½ é•·æœŸä½¿ç”¨ Unix 的朋å‹å·²ç¶“告訴你
+``GNU emacs`` 能自動幫你格å¼åŒ– C æºä»£ç¢¼ï¼Œè€Œä¸”你也注æ„到了,確實是這樣,ä¸éŽå®ƒ
所使用的默èªå€¼å’Œæˆ‘們想è¦çš„ç›¸åŽ»ç”šé  (實際上,甚至比隨機打的還è¦å·®â€”—無數個猴å­
-在 GNU emacs 里打字永é ä¸æœƒå‰µé€ å‡ºä¸€å€‹å¥½ç¨‹åº) (譯註:Infinite Monkey Theorem)
+在 GNU emacs è£æ‰“å­—æ°¸é ä¸æœƒå‰µé€ å‡ºä¸€å€‹å¥½ç¨‹åº)
+*(譯註:Infinite Monkey Theorem)*
所以你è¦éº¼æ”¾æ£„ GNU emacs,è¦éº¼æ”¹è®Šå®ƒè®“它使用更åˆç†çš„設定。è¦æŽ¡ç”¨å¾Œä¸€å€‹æ–¹æ¡ˆï¼Œ
-ä½ å¯ä»¥æŠŠä¸‹é¢é€™æ®µç²˜è²¼åˆ°ä½ çš„ .emacs 文件里。
+ä½ å¯ä»¥æŠŠä¸‹é¢é€™æ®µç²˜è²¼åˆ°ä½ çš„ .emacs 文件è£ã€‚
-.. code-block:: none
+.. code-block:: elisp
(defun c-lineup-arglist-tabs-only (ignored)
"Line up argument lists by tabs, not spaces"
@@ -533,7 +610,7 @@ Documentation/doc-guide/ å’Œ scripts/kernel-doc 以ç²å¾—詳細信æ¯ã€‚
(c-offsets-alist . (
(arglist-close . c-lineup-arglist-tabs-only)
(arglist-cont-nonempty .
- (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only))
+ (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only))
(arglist-intro . +)
(brace-list-intro . +)
(c . c-lineup-C-comments)
@@ -565,24 +642,29 @@ Documentation/doc-guide/ å’Œ scripts/kernel-doc 以ç²å¾—詳細信æ¯ã€‚
這會讓 emacs 在 ``~/src/linux-trees`` 下的 C æºæ–‡ä»¶ç²å¾—更好的內核代碼風格。
-ä¸éŽå°±ç®—你嘗試讓 emacs 正確的格å¼åŒ–代碼失敗了,也並ä¸æ„味著你失去了一切:還å¯
+ä¸éŽå°±ç®—你嘗試讓 emacs 正確的格å¼åŒ–代碼失敗了,也並ä¸æ„味ç€ä½ å¤±åŽ»äº†ä¸€åˆ‡ï¼šé‚„å¯
以用 ``indent`` 。
ä¸éŽï¼ŒGNU indent 也有和 GNU emacs 一樣有å•é¡Œçš„設定,所以你需è¦çµ¦å®ƒä¸€äº›å‘½ä»¤é¸
項。ä¸éŽï¼Œé€™é‚„ä¸ç®—太糟糕,因爲就算是 GNU indent 的作者也èªåŒ K&R 的權å¨æ€§
(GNU 的人並ä¸æ˜¯å£žäººï¼Œä»–們åªæ˜¯åœ¨é€™å€‹å•é¡Œä¸Šè¢«åš´é‡çš„誤導了),所以你åªè¦çµ¦ indent
指定é¸é … ``-kr -i8`` (代表 ``K&R,8 字符縮進``),或使用 ``scripts/Lindent``
-這樣就å¯ä»¥ä»¥æœ€æ™‚髦的方å¼ç¸®é€²åŽŸå§‹ç¢¼ã€‚
+這樣就å¯ä»¥ä»¥æœ€æ™‚髦的方å¼ç¸®é€²æºä»£ç¢¼ã€‚
-``indent`` 有很多é¸é …,特別是é‡æ–°æ ¼å¼åŒ–注釋的時候,你å¯èƒ½éœ€è¦çœ‹ä¸€ä¸‹å®ƒçš„手冊。
+``indent`` 有很多é¸é …,特別是é‡æ–°æ ¼å¼åŒ–註釋的時候,你å¯èƒ½éœ€è¦çœ‹ä¸€ä¸‹å®ƒçš„手冊。
ä¸éŽè¨˜ä½ï¼š ``indent`` ä¸èƒ½ä¿®æ­£å£žçš„編程習慣。
+請注æ„,您還å¯ä»¥ä½¿ç”¨ ``clang-format`` 工具幫助您處ç†é€™äº›è¦å‰‡ï¼Œå¿«é€Ÿè‡ªå‹•é‡æ–°æ ¼
+å¼åŒ–部分代碼,並審閱整個文件以發ç¾ä»£ç¢¼é¢¨æ ¼éŒ¯èª¤ã€æ‰“字錯誤和å¯èƒ½çš„改進。它還å¯
+ä»¥æ–¹ä¾¿åœ°æŽ’åº ``#include`` ,å°é½Šè®Šé‡/å®ï¼Œé‡æŽ’文本和其他類似任務。
+詳見 Documentation/process/clang-format.rst 。
+
10) Kconfig é…置文件
-------------------------------
+--------------------
-å°æ–¼é布æºç¢¼æ¨¹çš„所有 Kconfig* é…置文件來說,它們縮進方å¼æœ‰æ‰€ä¸åŒã€‚緊挨著
-``config`` 定義的行,用一個制表符縮進,然而 help ä¿¡æ¯çš„縮進則é¡å¤–增加 2 個空
+å°æ–¼é佈æºç¢¼æ¨¹çš„所有 Kconfig* é…置文件來說,它們縮進方å¼æœ‰æ‰€ä¸åŒã€‚緊挨ç€
+``config`` 定義的行,用一個製表符縮進,然而 help ä¿¡æ¯çš„縮進則é¡å¤–增加 2 個空
格。舉個例å­::
config AUDIT
@@ -594,7 +676,7 @@ Documentation/doc-guide/ å’Œ scripts/kernel-doc 以ç²å¾—詳細信æ¯ã€‚
logging of avc messages output). Does not do system-call
auditing without CONFIG_AUDITSYSCALL.
-而那些å±éšªçš„功能 (比如æŸäº›æ–‡ä»¶ç³»çµ±çš„寫支æŒ) 應該在它們的æ示字符串里顯著的è²
+而那些å±éšªçš„功能 (比如æŸäº›æ–‡ä»¶ç³»çµ±çš„寫支æŒ) 應該在它們的æ示字符串è£é¡¯è‘—çš„è²
明這一點::
config ADFS_FS_RW
@@ -602,17 +684,17 @@ Documentation/doc-guide/ å’Œ scripts/kernel-doc 以ç²å¾—詳細信æ¯ã€‚
depends on ADFS_FS
...
-è¦æŸ¥çœ‹é…置文件的完整文檔,請看 Documentation/kbuild/kconfig-language.rst。
+è¦æŸ¥çœ‹é…置文件的完整文檔,請看 Documentation/kbuild/kconfig-language.rst 。
11) 數據çµæ§‹
-------------------------------
+------------
-如果一個數據çµæ§‹ï¼Œåœ¨å‰µå»ºå’ŒéŠ·æ¯€å®ƒçš„單線執行環境之外å¯è¦‹ï¼Œé‚£éº¼å®ƒå¿…é ˆè¦æœ‰ä¸€å€‹å¼•
-用計數器。內核里沒有垃圾收集 (並且內核之外的垃圾收集慢且效率低下),這æ„味著你
+如果一個數據çµæ§‹ï¼Œåœ¨å‰µå»ºå’ŒéŠ·ç‡¬å®ƒçš„單線執行環境之外å¯è¦‹ï¼Œé‚£éº¼å®ƒå¿…é ˆè¦æœ‰ä¸€å€‹å¼•
+用計數器。內核è£æ²’有垃圾收集 (並且內核之外的垃圾收集慢且效率低下),這æ„味ç€ä½ 
絕å°éœ€è¦è¨˜éŒ„ä½ å°é€™ç¨®æ•¸æ“šçµæ§‹çš„使用情æ³ã€‚
-引用計數æ„味著你能夠é¿å…上鎖,並且å…許多個用戶並行訪å•é€™å€‹æ•¸æ“šçµæ§‹â€”—而ä¸éœ€è¦
+引用計數æ„味ç€ä½ èƒ½å¤ é¿å…上鎖,並且å…許多個用戶並行訪å•é€™å€‹æ•¸æ“šçµæ§‹â€”—而ä¸éœ€è¦
擔心這個數據çµæ§‹åƒ…僅因爲暫時ä¸è¢«ä½¿ç”¨å°±æ¶ˆå¤±äº†ï¼Œé‚£äº›ç”¨æˆ¶å¯èƒ½ä¸éŽæ˜¯æ²‰ç¡äº†ä¸€é™£æˆ–
者åšäº†ä¸€äº›å…¶ä»–事情而已。
@@ -626,13 +708,13 @@ Documentation/doc-guide/ å’Œ scripts/kernel-doc 以ç²å¾—詳細信æ¯ã€‚
mm_count),和文件系統 (``struct super_block``: s_count 和 s_active) 中找到。
記ä½ï¼šå¦‚æžœå¦ä¸€å€‹åŸ·è¡Œç·šç´¢å¯ä»¥æ‰¾åˆ°ä½ çš„數據çµæ§‹ï¼Œä½†é€™å€‹æ•¸æ“šçµæ§‹æ²’有引用計數器,
-這裡幾乎肯定是一個 bug。
+這è£å¹¾ä¹Žè‚¯å®šæ˜¯ä¸€å€‹ bug。
12) å®ï¼Œæžšèˆ‰å’ŒRTL
-------------------------------
+-----------------
-用於定義常é‡çš„å®çš„åå­—åŠæžšèˆ‰é‡Œçš„標籤需è¦å¤§å¯«ã€‚
+用於定義常é‡çš„å®çš„åå­—åŠæžšèˆ‰è£çš„標籤需è¦å¤§å¯«ã€‚
.. code-block:: c
@@ -642,9 +724,9 @@ mm_count),和文件系統 (``struct super_block``: s_count å’Œ s_active) 中æ‰
å®çš„å字請用大寫字æ¯ï¼Œä¸éŽå½¢å¦‚函數的å®çš„åå­—å¯ä»¥ç”¨å°å¯«å­—æ¯ã€‚
-一般的,如果能寫æˆå…§è¯å‡½æ•¸å°±ä¸è¦å¯«æˆåƒå‡½æ•¸çš„å®ã€‚
+通常如果能寫æˆå…§è¯å‡½æ•¸å°±ä¸è¦å¯«æˆåƒå‡½æ•¸çš„å®ã€‚
-å«æœ‰å¤šå€‹èªžå¥çš„å®æ‡‰è©²è¢«åŒ…å«åœ¨ä¸€å€‹ do-while 代碼塊里:
+å«æœ‰å¤šå€‹èªžå¥çš„å®æ‡‰è©²è¢«åŒ…å«åœ¨ä¸€å€‹ do-while 代碼塊è£ï¼š
.. code-block:: c
@@ -667,7 +749,7 @@ mm_count),和文件系統 (``struct super_block``: s_count å’Œ s_active) 中æ‰
} while (0)
**éžå¸¸** ä¸å¥½ã€‚它看起來åƒä¸€å€‹å‡½æ•¸ï¼Œä¸éŽå»èƒ½å°Žè‡´ ``調用`` 它的函數退出;ä¸è¦æ‰“
-亂讀者大腦里的語法分æžå™¨ã€‚
+亂讀者大腦è£çš„語法分æžå™¨ã€‚
2) ä¾è³´æ–¼ä¸€å€‹å›ºå®šå字的本地變é‡çš„å®ï¼š
@@ -689,7 +771,7 @@ mm_count),和文件系統 (``struct super_block``: s_count å’Œ s_active) 中æ‰
#define CONSTANT 0x4000
#define CONSTEXP (CONSTANT | 3)
-5) 在å®é‡Œå®šç¾©é¡žä¼¼å‡½æ•¸çš„本地變é‡æ™‚命åè¡çªï¼š
+5) 在å®è£å®šç¾©é¡žä¼¼å‡½æ•¸çš„本地變é‡æ™‚命åè¡çªï¼š
.. code-block:: c
@@ -700,45 +782,46 @@ mm_count),和文件系統 (``struct super_block``: s_count å’Œ s_active) 中æ‰
(ret); \
})
-ret 是本地變é‡çš„通用åå­— - __foo_ret æ›´ä¸å®¹æ˜“與一個已存在的變é‡è¡çªã€‚
+ret 是本地變é‡çš„通用å字—— __foo_ret æ›´ä¸å®¹æ˜“與一個已存在的變é‡è¡çªã€‚
-cpp 手冊å°å®çš„講解很詳細。gcc internals 手冊也詳細講解了 RTL,內核里的彙編語
+cpp 手冊å°å®çš„講解很詳細。gcc internals 手冊也詳細講解了 RTL,內核è£çš„彙編語
言經常用到它。
-13) 列å°å…§æ ¸æ¶ˆæ¯
-------------------------------
+13) 打å°å…§æ ¸æ¶ˆæ¯
+----------------
-內核開發者應該是å—éŽè‰¯å¥½æ•™è‚²çš„。請一定注æ„內核信æ¯çš„拼寫,以給人以好的å°è±¡ã€‚
+內核開發者應該看起來有文化。請一定注æ„內核信æ¯çš„拼寫,以給人良好的å°è±¡ã€‚
ä¸è¦ç”¨ä¸è¦ç¯„的單詞比如 ``dont``,而è¦ç”¨ ``do not`` 或者 ``don't`` 。ä¿è­‰é€™äº›ä¿¡
-æ¯ç°¡å–®æ˜Žäº†,無歧義。
+æ¯ç°¡å–®æ˜Žçž­ã€ç„¡æ­§ç¾©ã€‚
內核信æ¯ä¸å¿…以英文å¥è™ŸçµæŸã€‚
-在å°æ‹¬è™Ÿé‡Œåˆ—å°æ•¸å­— (%d) 沒有任何價值,應該é¿å…這樣åšã€‚
+在å°æ‹¬è™Ÿè£æ‰“å°æ•¸å­— (%d) 沒有任何價值,應該é¿å…這樣åšã€‚
-<linux/device.h> 里有一些驅動模型診斷å®ï¼Œä½ æ‡‰è©²ä½¿ç”¨å®ƒå€‘,以確ä¿ä¿¡æ¯å°æ‡‰æ–¼æ­£ç¢º
+<linux/device.h> è£æœ‰ä¸€äº›é©…動模型診斷å®ï¼Œä½ æ‡‰è©²ä½¿ç”¨å®ƒå€‘,以確ä¿ä¿¡æ¯å°æ‡‰æ–¼æ­£ç¢º
的設備和驅動,並且被標記了正確的消æ¯ç´šåˆ¥ã€‚這些å®æœ‰ï¼šdev_err(), dev_warn(),
dev_info() 等等。å°æ–¼é‚£äº›ä¸å’ŒæŸå€‹ç‰¹å®šè¨­å‚™ç›¸é—œé€£çš„ä¿¡æ¯ï¼Œ<linux/printk.h> 定義
了 pr_notice(), pr_info(), pr_warn(), pr_err() 和其他。
寫出好的調試信æ¯å¯ä»¥æ˜¯ä¸€å€‹å¾ˆå¤§çš„挑戰;一旦你寫出後,這些信æ¯åœ¨é ç¨‹é™¤éŒ¯æ™‚能æ
-供極大的幫助。然而列å°èª¿è©¦ä¿¡æ¯çš„處ç†æ–¹å¼åŒåˆ—å°éžèª¿è©¦ä¿¡æ¯ä¸åŒã€‚其他 pr_XXX()
-函數能無æ¢ä»¶åœ°åˆ—å°ï¼Œpr_debug() å»ä¸ï¼›é»˜èªæƒ…æ³ä¸‹å®ƒä¸æœƒè¢«ç·¨è­¯ï¼Œé™¤éžå®šç¾©äº† DEBUG
+供極大的幫助。然而打å°èª¿è©¦ä¿¡æ¯çš„處ç†æ–¹å¼åŒæ‰“å°éžèª¿è©¦ä¿¡æ¯ä¸åŒã€‚其他 pr_XXX()
+函數能無æ¢ä»¶åœ°æ‰“å°ï¼Œpr_debug() å»ä¸ï¼›é»˜èªæƒ…æ³ä¸‹å®ƒä¸æœƒè¢«ç·¨è­¯ï¼Œé™¤éžå®šç¾©äº† DEBUG
或設定了 CONFIG_DYNAMIC_DEBUG。實際這åŒæ¨£æ˜¯çˆ²äº† dev_dbg(),一個相關約定是在一
個已經開啓了 DEBUG 時,使用 VERBOSE_DEBUG 來添加 dev_vdbg()。
-許多å­ç³»çµ±æ“有 Kconfig 調試é¸é …來開啓 -DDEBUG 在å°æ‡‰çš„ Makefile 裡é¢ï¼›åœ¨å…¶ä»–
-情æ³ä¸‹ï¼Œç‰¹æ®Šæ–‡ä»¶ä½¿ç”¨ #define DEBUG。當一æ¢èª¿è©¦ä¿¡æ¯éœ€è¦è¢«ç„¡æ¢ä»¶åˆ—å°æ™‚,例如,
+許多å­ç³»çµ±æ“有 Kconfig 調試é¸é …來開啓å°æ‡‰ Makefile è£é¢çš„ -DDEBUG;在其他
+情æ³ä¸‹ï¼Œç‰¹æ®Šæ–‡ä»¶ä½¿ç”¨ #define DEBUG。當一æ¢èª¿è©¦ä¿¡æ¯éœ€è¦è¢«ç„¡æ¢ä»¶æ‰“å°æ™‚,例如,
如果已經包å«ä¸€å€‹èª¿è©¦ç›¸é—œçš„ #ifdef æ¢ä»¶ï¼Œprintk(KERN_DEBUG ...) å°±å¯è¢«ä½¿ç”¨ã€‚
14) 分é…內存
-------------------------------
+------------
內核æ供了下é¢çš„一般用途的內存分é…函數:
kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc() 和 vzalloc()。
-è«‹åƒè€ƒ API 文檔以ç²å–有關它們的詳細信æ¯ã€‚
+è«‹åƒè€ƒ API 文檔以ç²å–有關它們的詳細信æ¯ï¼š
+Documentation/translations/zh_CN/core-api/memory-allocation.rst 。
傳éžçµæ§‹é«”大å°çš„首é¸å½¢å¼æ˜¯é€™æ¨£çš„:
@@ -765,17 +848,19 @@ kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc() 和 vzalloc()。
p = kcalloc(n, sizeof(...), ...);
-兩種形å¼æª¢æŸ¥åˆ†é…å¤§å° n * sizeof(...) 的溢出,如果溢出返回 NULL。
+兩種形å¼éƒ½æœƒæª¢æŸ¥åˆ†é… n * sizeof(...) 大å°æ™‚內存的溢出,如果溢出返回 NULL。
+在沒有 __GFP_NOWARN 的情æ³ä¸‹ä½¿ç”¨æ™‚,這些通用分é…函數都會在失敗時發起堆棧轉儲,
+因此當返回NULL時,沒有必è¦ç™¼å‡ºé¡å¤–的失敗消æ¯ã€‚
15) å…§è¯å¼Šç—…
-------------------------------
+------------
有一個常見的誤解是 ``å…§è¯`` 是 gcc æ供的å¯ä»¥è®“代碼é‹è¡Œæ›´å¿«çš„一個é¸é …。雖然使
用內è¯å‡½æ•¸æœ‰æ™‚候是æ°ç•¶çš„ (比如作爲一種替代å®çš„æ–¹å¼ï¼Œè«‹çœ‹ç¬¬å二章),ä¸éŽå¾ˆå¤šæƒ…
æ³ä¸‹ä¸æ˜¯é€™æ¨£ã€‚inline çš„éŽåº¦ä½¿ç”¨æœƒä½¿å…§æ ¸è®Šå¤§ï¼Œå¾žè€Œä½¿æ•´å€‹ç³»çµ±é‹è¡Œé€Ÿåº¦è®Šæ…¢ã€‚
-因爲體ç©å¤§å…§æ ¸æœƒå ç”¨æ›´å¤šçš„指令高速緩存,而且會導致 pagecache çš„å¯ç”¨å…§å­˜æ¸›å°‘。
-想åƒä¸€ä¸‹ï¼Œä¸€æ¬¡ pagecache 未命中就會導致一次ç£ç¢Ÿå°‹å€ï¼Œå°‡è€—時 5 毫秒。5 毫秒的
+因爲體ç©å¤§å…§æ ¸æœƒä½”用更多的指令高速緩存,而且會導致 pagecache çš„å¯ç”¨å…§å­˜æ¸›å°‘。
+想象一下,一次 pagecache 未命中就會導致一次ç£ç›¤å°‹å€ï¼Œå°‡è€—時 5 毫秒。5 毫秒的
時間內 CPU 能執行很多很多指令。
一個基本的原則是如果一個函數有 3 行以上,就ä¸è¦æŠŠå®ƒè®Šæˆå…§è¯å‡½æ•¸ã€‚這個原則的一
@@ -790,7 +875,7 @@ inline gcc 也å¯ä»¥è‡ªå‹•ä½¿å…¶å…§è¯ã€‚而且其他用戶å¯èƒ½æœƒè¦æ±‚移除
16) 函數返回值åŠå‘½å
-------------------------------
+--------------------
函數å¯ä»¥è¿”回多種ä¸åŒé¡žåž‹çš„值,最常見的一種是表明函數執行æˆåŠŸæˆ–者失敗的值。這樣
的一個值å¯ä»¥è¡¨ç¤ºçˆ²ä¸€å€‹éŒ¯èª¤ä»£ç¢¼æ•´æ•¸ (-Exxxï¼å¤±æ•—,0ï¼æˆåŠŸ) 或者一個 ``æˆåŠŸ``
@@ -801,7 +886,7 @@ inline gcc 也å¯ä»¥è‡ªå‹•ä½¿å…¶å…§è¯ã€‚而且其他用戶å¯èƒ½æœƒè¦æ±‚移除
產生這種 bug,請éµå¾ªä¸‹é¢çš„慣例::
如果函數的å字是一個動作或者強制性的命令,那麼這個函數應該返回錯誤代
- 碼整數。如果是一個判斷,那麼函數應該返回一個 "æˆåŠŸ" 布爾值。
+ 碼整數。如果是一個判斷,那麼函數應該返回一個“æˆåŠŸâ€å¸ƒçˆ¾å€¼ã€‚
比如, ``add work`` 是一個命令,所以 add_work() 在æˆåŠŸæ™‚返回 0,在失敗時返回
-EBUSY。類似的,因爲 ``PCI device present`` 是一個判斷,所以 pci_dev_present()
@@ -810,13 +895,35 @@ inline gcc 也å¯ä»¥è‡ªå‹•ä½¿å…¶å…§è¯ã€‚而且其他用戶å¯èƒ½æœƒè¦æ±‚移除
所有 EXPORTed 函數都必須éµå®ˆé€™å€‹æ…£ä¾‹ï¼Œæ‰€æœ‰çš„公共函數也都應該如此。ç§æœ‰
(static) 函數ä¸éœ€è¦å¦‚此,但是我們也推薦這樣åšã€‚
-返回值是實際計算çµæžœè€Œä¸æ˜¯è¨ˆç®—是å¦æˆåŠŸçš„標誌的函數ä¸å—此慣例的é™åˆ¶ã€‚一般的,
+返回值是實際計算çµæžœè€Œä¸æ˜¯è¨ˆç®—是å¦æˆåŠŸçš„標誌的函數ä¸å—此慣例的é™åˆ¶ã€‚通常
他們通éŽè¿”回一些正常值範åœä¹‹å¤–çš„çµæžœä¾†è¡¨ç¤ºå‡ºéŒ¯ã€‚典型的例å­æ˜¯è¿”回指é‡çš„函數,
他們使用 NULL 或者 ERR_PTR 機制來報告錯誤。
+17) 使用布爾類型
+----------------
+
+Linux內核布爾(bool)類型是C99 _Bool類型的別å。布爾值åªèƒ½çˆ²0或1,而å°å¸ƒçˆ¾çš„
+éš±å¼æˆ–顯å¼è½‰æ›å°‡è‡ªå‹•å°‡å€¼è½‰æ›çˆ²true或false。在使用布爾類型時 **ä¸éœ€è¦** 構造,
+它會消除一類錯誤。
+
+使用布爾值時,應使用trueå’Œfalse定義,而ä¸æ˜¯1å’Œ0。
-17) ä¸è¦é‡æ–°ç™¼æ˜Žå…§æ ¸å®
-------------------------------
+布爾函數返回類型和堆棧變é‡ç¸½æ˜¯å¯ä»¥åœ¨é©ç•¶çš„時候使用。鼓勵使用布爾來æ高å¯è®€æ€§ï¼Œ
+並且布爾值在存儲時通常比“intâ€æ›´å¥½ã€‚
+
+如果緩存行佈局或值的大å°å¾ˆé‡è¦ï¼Œè«‹ä¸è¦ä½¿ç”¨å¸ƒçˆ¾ï¼Œå› çˆ²å…¶å¤§å°å’Œå°é½Šæ–¹å¼æ ¹æ“šç·¨è­¯
+的體系çµæ§‹è€Œä¸åŒã€‚é‡å°å°é½Šå’Œå¤§å°é€²è¡Œå„ªåŒ–çš„çµæ§‹é«”ä¸æ‡‰ä½¿ç”¨å¸ƒçˆ¾ã€‚
+
+如果一個çµæ§‹é«”有多個true/false值,請考慮將它們åˆä½µçˆ²å…·æœ‰1比特æˆå“¡çš„ä½åŸŸï¼Œæˆ–使
+用é©ç•¶çš„固定寬度類型,如u8。
+
+類似地,å°æ–¼å‡½æ•¸åƒæ•¸ï¼Œå¤šå€‹true/false值å¯ä»¥åˆä½µçˆ²å–®å€‹æŒ‰ä½çš„“標誌â€åƒæ•¸ï¼Œå¦‚果調
+用點具有裸true/false常é‡ï¼Œâ€œæ¨™èªŒâ€åƒæ•¸é€šå¸¸æ˜¯æ›´å…·å¯è®€æ€§çš„替代方法。
+
+總之,在çµæ§‹é«”å’Œåƒæ•¸ä¸­æœ‰é™åœ°ä½¿ç”¨å¸ƒçˆ¾å¯ä»¥æ高å¯è®€æ€§ã€‚
+
+18) ä¸è¦é‡æ–°ç™¼æ˜Žå…§æ ¸å®
+----------------------
頭文件 include/linux/kernel.h 包å«äº†ä¸€äº›å®ï¼Œä½ æ‡‰è©²ä½¿ç”¨å®ƒå€‘,而ä¸è¦è‡ªå·±å¯«ä¸€äº›
它們的變種。比如,如果你需è¦è¨ˆç®—一個數組的長度,使用這個å®
@@ -832,15 +939,15 @@ inline gcc 也å¯ä»¥è‡ªå‹•ä½¿å…¶å…§è¯ã€‚而且其他用戶å¯èƒ½æœƒè¦æ±‚移除
#define sizeof_field(t, f) (sizeof(((t*)0)->f))
還有å¯ä»¥åšåš´æ ¼çš„類型檢查的 min() å’Œ max() å®ï¼Œå¦‚果你需è¦å¯ä»¥ä½¿ç”¨å®ƒå€‘。你å¯ä»¥
-自己看看那個頭文件里還定義了什麼你å¯ä»¥æ‹¿ä¾†ç”¨çš„æ±è¥¿ï¼Œå¦‚果有定義的話,你就ä¸æ‡‰
-在你的代碼里自己é‡æ–°å®šç¾©ã€‚
+自己看看那個頭文件è£é‚„定義了什麼你å¯ä»¥æ‹¿ä¾†ç”¨çš„æ±è¥¿ï¼Œå¦‚果有定義的話,你就ä¸æ‡‰
+在你的代碼è£è‡ªå·±é‡æ–°å®šç¾©ã€‚
-18) 編輯器模å¼è¡Œå’Œå…¶ä»–需è¦ç¾…嗦的事情
---------------------------------------------------
+19) 編輯器模å¼è¡Œå’Œå…¶ä»–需è¦ç¾…嗦的事情
+------------------------------------
-有一些編輯器å¯ä»¥è§£é‡‹åµŒå…¥åœ¨æºæ–‡ä»¶é‡Œçš„由一些特殊標記標明的é…置信æ¯ã€‚比如,emacs
-能夠解釋被標記æˆé€™æ¨£çš„行:
+有一些編輯器å¯ä»¥è§£é‡‹åµŒå…¥åœ¨æºæ–‡ä»¶è£çš„由一些特殊標記標明的é…置信æ¯ã€‚比如,emacs
+能夠解æžè¢«æ¨™è¨˜æˆé€™æ¨£çš„行:
.. code-block:: c
@@ -856,23 +963,23 @@ inline gcc 也å¯ä»¥è‡ªå‹•ä½¿å…¶å…§è¯ã€‚而且其他用戶å¯èƒ½æœƒè¦æ±‚移除
End:
*/
-Vim 能夠解釋這樣的標記:
+Vim 能夠解æžé€™æ¨£çš„標記:
.. code-block:: c
/* vim:set sw=8 noet */
-ä¸è¦åœ¨åŽŸå§‹ç¢¼ä¸­åŒ…å«ä»»ä½•é€™æ¨£çš„內容。æ¯å€‹äººéƒ½æœ‰ä»–自己的編輯器é…置,你的æºæ–‡ä»¶ä¸
+ä¸è¦åœ¨æºä»£ç¢¼ä¸­åŒ…å«ä»»ä½•é€™æ¨£çš„內容。æ¯å€‹äººéƒ½æœ‰ä»–自己的編輯器é…置,你的æºæ–‡ä»¶ä¸
應該覆蓋別人的é…置。這包括有關縮進和模å¼é…置的標記。人們å¯ä»¥ä½¿ç”¨ä»–們自己定製
的模å¼ï¼Œæˆ–者使用其他å¯ä»¥ç”¢ç”Ÿæ­£ç¢ºçš„縮進的巧妙方法。
-19) å…§è¯å½™ç·¨
-------------------------------
+20) å…§è¯å½™ç·¨
+------------
-在特定架構的代碼中,你å¯èƒ½éœ€è¦å…§è¯å½™ç·¨èˆ‡ CPU 和平å°ç›¸é—œåŠŸèƒ½é€£æŽ¥ã€‚需è¦é€™éº¼åšæ™‚
+在特定架構的代碼中,你å¯èƒ½éœ€è¦å…§è¯å½™ç·¨èˆ‡ CPU 和平臺相關功能連接。需è¦é€™éº¼åšæ™‚
å°±ä¸è¦çŒ¶è±«ã€‚然而,當 C å¯ä»¥å®Œæˆå·¥ä½œæ™‚,ä¸è¦å¹³ç™½ç„¡æ•…地使用內è¯å½™ç·¨ã€‚在å¯èƒ½çš„情
-æ³ä¸‹ï¼Œä½ å¯ä»¥ä¸¦ä¸”應該用 C 和硬體æºé€šã€‚
+æ³ä¸‹ï¼Œä½ å¯ä»¥ä¸¦ä¸”應該用 C 和硬件æºé€šã€‚
請考慮去寫æ†ç¶é€šç”¨ä½å…ƒ (wrap common bits) çš„å…§è¯å½™ç·¨çš„簡單輔助函數,別去é‡è¤‡
地寫下åªæœ‰ç´°å¾®å·®ç•°å…§è¯å½™ç·¨ã€‚記ä½å…§è¯å½™ç·¨å¯ä»¥ä½¿ç”¨ C åƒæ•¸ã€‚
@@ -883,9 +990,9 @@ Vim 能夠解釋這樣的標記:
ä½ å¯èƒ½éœ€è¦æŠŠå½™ç·¨èªžå¥æ¨™è¨˜çˆ² volatile,用來阻止 GCC 在沒發ç¾ä»»ä½•å‰¯ä½œç”¨å¾Œå°±æŠŠå®ƒ
移除了。你ä¸å¿…總是這樣åšï¼Œå„˜ç®¡ï¼Œé€™ä¸å¿…è¦çš„舉動會é™åˆ¶å„ªåŒ–。
-在寫一個包å«å¤šæ¢æŒ‡ä»¤çš„單個內è¯å½™ç·¨èªžå¥æ™‚,把æ¯æ¢æŒ‡ä»¤ç”¨å¼•è™Ÿåˆ†å‰²è€Œä¸”å„å ä¸€è¡Œï¼Œ
-除了最後一æ¢æŒ‡ä»¤å¤–,在æ¯å€‹æŒ‡ä»¤çµå°¾åŠ ä¸Š \n\t,讓彙編輸出時å¯ä»¥æ­£ç¢ºåœ°ç¸®é€²ä¸‹ä¸€æ¢
-指令:
+在寫一個包å«å¤šæ¢æŒ‡ä»¤çš„單個內è¯å½™ç·¨èªžå¥æ™‚,把æ¯æ¢æŒ‡ä»¤ç”¨å¼•è™Ÿåˆ†å‰²è€Œä¸”å„佔一行,
+除了最後一æ¢æŒ‡ä»¤å¤–,在æ¯å€‹æŒ‡ä»¤çµå°¾åŠ ä¸Š ``\n\t`` ,讓彙編輸出時å¯ä»¥æ­£ç¢ºåœ°ç¸®é€²
+下一æ¢æŒ‡ä»¤ï¼š
.. code-block:: c
@@ -894,10 +1001,10 @@ Vim 能夠解釋這樣的標記:
: /* outputs */ : /* inputs */ : /* clobbers */);
-20) æ¢ä»¶ç·¨è­¯
-------------------------------
+21) æ¢ä»¶ç·¨è­¯
+------------
-åªè¦å¯èƒ½ï¼Œå°±ä¸è¦åœ¨ .c 文件裡é¢ä½¿ç”¨é è™•ç†æ¢ä»¶ (#if, #ifdef);這樣åšè®“代碼更難
+åªè¦å¯èƒ½ï¼Œå°±ä¸è¦åœ¨ .c 文件è£é¢ä½¿ç”¨é è™•ç†æ¢ä»¶ (#if, #ifdef);這樣åšæœƒè®“代碼更難
閱讀並且更難去跟蹤é‚輯。替代方案是,在頭文件中用é è™•ç†æ¢ä»¶æ供給那些 .c 文件
使用,å†çµ¦ #else æä¾›ä¸€å€‹ç©ºæ¨ (no-op stub) 版本,然後在 .c 文件內無æ¢ä»¶åœ°èª¿ç”¨
那些 (定義在頭文件內的) 函數。這樣åšï¼Œç·¨è­¯å™¨æœƒé¿å…爲æ¨å‡½æ•¸ (stub) 的調用生æˆ
@@ -908,8 +1015,8 @@ Vim 能夠解釋這樣的標記:
æ¢ä»¶åˆ°é€™å€‹è¼”助函數內。
如果你有一個在特定é…置中,å¯èƒ½è®Šæˆæœªä½¿ç”¨çš„函數或變é‡ï¼Œç·¨è­¯å™¨æœƒè­¦å‘Šå®ƒå®šç¾©äº†ä½†
-未使用,把它標記爲 __maybe_unused 而ä¸æ˜¯å°‡å®ƒåŒ…å«åœ¨ä¸€å€‹é è™•ç†æ¢ä»¶ä¸­ã€‚(然而,如
-果一個函數或變é‡ç¸½æ˜¯æœªä½¿ç”¨ï¼Œå°±ç›´æŽ¥åˆªé™¤å®ƒã€‚)
+未使用,請把它標記爲 __maybe_unused 而ä¸æ˜¯å°‡å®ƒåŒ…å«åœ¨ä¸€å€‹é è™•ç†æ¢ä»¶ä¸­ã€‚(然而,
+如果一個函數或變é‡ç¸½æ˜¯æœªä½¿ç”¨ï¼Œå°±ç›´æŽ¥åˆªé™¤å®ƒã€‚)
在代碼中,儘å¯èƒ½åœ°ä½¿ç”¨ IS_ENABLED å®ä¾†è½‰åŒ–æŸå€‹ Kconfig 標記爲 C 的布爾
表é”å¼ï¼Œä¸¦åœ¨ä¸€èˆ¬çš„ C æ¢ä»¶ä¸­ä½¿ç”¨å®ƒï¼š
@@ -926,7 +1033,7 @@ Vim 能夠解釋這樣的標記:
ä¸å­˜åœ¨æ™‚,你還是必須去用 #ifdef。
在任何有æ„義的 #if 或 #ifdef 塊的末尾 (超éŽå¹¾è¡Œçš„),在 #endif åŒä¸€è¡Œçš„後é¢å¯«ä¸‹
-註解,注釋這個æ¢ä»¶è¡¨é”å¼ã€‚例如:
+註解,註釋這個æ¢ä»¶è¡¨é”å¼ã€‚例如:
.. code-block:: c
@@ -935,24 +1042,46 @@ Vim 能夠解釋這樣的標記:
#endif /* CONFIG_SOMETHING */
-附錄 I) åƒè€ƒ
--------------------
+附錄 I) åƒè€ƒè³‡æ–™
+----------------
-The C Programming Language, 第二版
+The C Programming Language, 2nd Edition
作者:Brian W. Kernighan 和 Denni M. Ritchie.
Prentice Hall, Inc., 1988.
-ISBN 0-13-110362-8 (軟皮), 0-13-110370-9 (硬皮).
+ISBN 0-13-110362-8 (å¹³è£), 0-13-110370-9 (ç²¾è£).
+
+.. note::
+
+ 《C程åºè¨­è¨ˆèªžè¨€ï¼ˆç¬¬2版)》
+ 作者:[美] Brian W. Kernighan / [美] Dennis M. Ritchie
+ 譯者:å¾å¯¶æ–‡ / æŽå¿— / 尤晉元(審校)
+ 出版社:機械工業出版社,2019
+ ISBN:9787111617945
The Practice of Programming
作者:Brian W. Kernighan 和 Rob Pike.
Addison-Wesley, Inc., 1999.
ISBN 0-201-61586-X.
+.. note::
+
+ 《程åºè¨­è¨ˆå¯¦è¸ã€‹
+ 作者:[美] Brian W. Kernighan / [美] Rob Pike
+ 出版社:機械工業出版社,2005
+ ISBN:9787111091578
+
+ 《程åºè¨­è¨ˆå¯¦è¸ã€‹
+ 作者:[美] Brian W. Kernighan / Rob Pike
+ 譯者:裘宗燕
+ 出版社:機械工業出版社,2000
+ ISBN:9787111075738
+
GNU 手冊 - éµå¾ª K&R 標準和此文本 - cpp, gcc, gcc internals and indent,
都å¯ä»¥å¾ž https://www.gnu.org/manual/ 找到
WG14 是 C 語言的國際標準化工作組,URL: http://www.open-std.org/JTC1/SC22/WG14/
-Kernel process/coding-style.rst,作者 greg@kroah.com 發表於 OLS 2002:
+內核文檔 Documentation/process/coding-style.rst,
+作者 greg@kroah.com 發表於 OLS 2002:
http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
diff --git a/Documentation/translations/zh_TW/process/development-process.rst b/Documentation/translations/zh_TW/process/development-process.rst
index f4cf5c2bbc82..7d803d3db89e 100644
--- a/Documentation/translations/zh_TW/process/development-process.rst
+++ b/Documentation/translations/zh_TW/process/development-process.rst
@@ -26,5 +26,5 @@
7.AdvancedTopics
8.Conclusion
-本文檔的目的是幫助開發人員(åŠå…¶ç¶“ç†ï¼‰ä»¥æœ€å°çš„挫折感與開發社å€åˆä½œã€‚它試圖記錄這個社å€å¦‚何以一種ä¸ç†Ÿæ‚‰Linux內核開發(或者實際上是自由軟體開發)的人å¯ä»¥è¨ªå•çš„æ–¹å¼å·¥ä½œã€‚雖然這裡有一些技術資料,但這是一個é¢å‘éŽç¨‹çš„討論,ä¸éœ€è¦æ·±å…¥äº†è§£å…§æ ¸ç·¨ç¨‹å°±å¯ä»¥ç†è§£ã€‚
+本文檔的目的是幫助開發人員(åŠå…¶ç¶“ç†ï¼‰ä»¥æœ€å°çš„挫折感與開發社å€åˆä½œã€‚它試圖記錄這個社å€å¦‚何以一種ä¸ç†Ÿæ‚‰Linux內核開發(或者實際上是自由軟件開發)的人å¯ä»¥è¨ªå•çš„æ–¹å¼å·¥ä½œã€‚雖然這è£æœ‰ä¸€äº›æŠ€è¡“資料,但這是一個é¢å‘éŽç¨‹çš„討論,ä¸éœ€è¦æ·±å…¥çž­è§£å…§æ ¸ç·¨ç¨‹å°±å¯ä»¥ç†è§£ã€‚
diff --git a/Documentation/translations/zh_TW/process/email-clients.rst b/Documentation/translations/zh_TW/process/email-clients.rst
index ae63e41d9cee..55e10d3fc28a 100644
--- a/Documentation/translations/zh_TW/process/email-clients.rst
+++ b/Documentation/translations/zh_TW/process/email-clients.rst
@@ -1,20 +1,21 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. _tw_email_clients:
+.. SPDX-License-Identifier: GPL-2.0-or-later
.. include:: ../disclaimer-zh_TW.rst
-:Original: :ref:`Documentation/process/email-clients.rst <email_clients>`
+.. _tw_email_clients:
-譯者::
+:Original: Documentation/process/email-clients.rst
- 中文版維護者: 賈å¨å¨ Harry Wei <harryxiyou@gmail.com>
- 中文版翻譯者: 賈å¨å¨ Harry Wei <harryxiyou@gmail.com>
- 時奎亮 Alex Shi <alex.shi@linux.alibaba.com>
- 中文版校譯者: Yinglin Luan <synmyth@gmail.com>
- Xiaochen Wang <wangxiaochen0@gmail.com>
- yaxinsn <yaxinsn@163.com>
- Hu Haowen <src.res.211@gmail.com>
+:譯者:
+ - 賈å¨å¨ Harry Wei <harryxiyou@gmail.com>
+ - 時奎亮 Alex Shi <alexs@kernel.org>
+ - å³æƒ³æˆ Wu XiangCheng <bobwxc@email.cn>
+
+:æ ¡è­¯:
+ - Yinglin Luan <synmyth@gmail.com>
+ - Xiaochen Wang <wangxiaochen0@gmail.com>
+ - yaxinsn <yaxinsn@163.com>
+ - Hu Haowen <src.res.211@gmail.com>
Linux郵件客戶端é…置信æ¯
=======================
@@ -30,30 +31,35 @@ Git
改日誌。如果工作正常,å†å°‡è£œä¸ç™¼é€åˆ°ç›¸æ‡‰çš„郵件列表。
-普通é…ç½®
+通用é…ç½®
--------
+
Linux內核補ä¸æ˜¯é€šéŽéƒµä»¶è¢«æ交的,最好把補ä¸ä½œçˆ²éƒµä»¶é«”的內嵌文本。有些維護者
接收附件,但是附件的內容格å¼æ‡‰è©²æ˜¯"text/plain"。然而,附件一般是ä¸è´Šæˆçš„,
因爲這會使補ä¸çš„引用部分在評論éŽç¨‹ä¸­è®Šçš„很困難。
+åŒæ™‚也強烈建議在補ä¸æˆ–其他郵件的正文中使用純文本格å¼ã€‚https://useplaintext.email
+有助於瞭解如何é…置你喜歡的郵件客戶端,並在您還沒有首é¸çš„情æ³ä¸‹åˆ—出一些推薦的
+客戶端。
+
用來發é€Linux內核補ä¸çš„郵件客戶端在發é€è£œä¸æ™‚應該處於文本的原始狀態。例如,
-他們ä¸èƒ½æ”¹è®Šæˆ–者刪除制表符或者空格,甚至是在æ¯ä¸€è¡Œçš„開頭或者çµå°¾ã€‚
+他們ä¸èƒ½æ”¹è®Šæˆ–者刪除製表符或者空格,甚至是在æ¯ä¸€è¡Œçš„開頭或者çµå°¾ã€‚
ä¸è¦é€šéŽ"format=flowed"模å¼ç™¼é€è£œä¸ã€‚這樣會引起ä¸å¯é æœŸä»¥åŠæœ‰å®³çš„斷行。
ä¸è¦è®“你的郵件客戶端進行自動æ›è¡Œã€‚這樣也會破壞你的補ä¸ã€‚
-郵件客戶端ä¸èƒ½æ”¹è®Šæ–‡æœ¬çš„字符集編碼方å¼ã€‚è¦ç™¼é€çš„補ä¸åªèƒ½æ˜¯ASCII或者UTF-8編碼方å¼ï¼Œ
-如果你使用UTF-8編碼方å¼ç™¼é€éƒµä»¶ï¼Œé‚£éº¼ä½ å°‡æœƒé¿å…一些å¯èƒ½ç™¼ç”Ÿçš„字符集å•é¡Œã€‚
+郵件客戶端ä¸èƒ½æ”¹è®Šæ–‡æœ¬çš„字符集編碼方å¼ã€‚è¦ç™¼é€çš„補ä¸åªèƒ½æ˜¯ASCII或者UTF-8編碼
+æ–¹å¼ï¼Œå¦‚果你使用UTF-8編碼方å¼ç™¼é€éƒµä»¶ï¼Œé‚£éº¼ä½ å°‡æœƒé¿å…一些å¯èƒ½ç™¼ç”Ÿçš„字符集å•é¡Œã€‚
-郵件客戶端應該形æˆä¸¦ä¸”ä¿æŒ References: 或者 In-Reply-To: 標題,那麼
-郵件話題就ä¸æœƒä¸­æ–·ã€‚
+郵件客戶端應該生æˆä¸¦ä¸”ä¿æŒâ€œReferences:â€æˆ–者“In-Reply-To:â€éƒµä»¶é ­ï¼Œé€™æ¨£éƒµä»¶æœƒè©±
+å°±ä¸æœƒä¸­æ–·ã€‚
-複製粘帖(或者剪貼粘帖)通常ä¸èƒ½ç”¨æ–¼è£œä¸ï¼Œå› çˆ²åˆ¶è¡¨ç¬¦æœƒè½‰æ›çˆ²ç©ºæ ¼ã€‚使用xclipboard, xclip
-或者xcutsel也許å¯ä»¥ï¼Œä½†æ˜¯æœ€å¥½æ¸¬è©¦ä¸€ä¸‹æˆ–者é¿å…使用複製粘帖。
+複製粘帖(或者剪貼粘帖)通常ä¸èƒ½ç”¨æ–¼è£œä¸ï¼Œå› çˆ²è£½è¡¨ç¬¦æœƒè½‰æ›çˆ²ç©ºæ ¼ã€‚使用xclipboard,
+xclip或者xcutsel也許å¯ä»¥ï¼Œä½†æ˜¯æœ€å¥½æ¸¬è©¦ä¸€ä¸‹æˆ–者é¿å…使用複製粘帖。
-ä¸è¦åœ¨ä½¿ç”¨PGP/GPGç½²å的郵件中包å«è£œä¸ã€‚這樣會使得很多腳本ä¸èƒ½è®€å–å’Œé©ç”¨æ–¼ä½ çš„補ä¸ã€‚
-(這個å•é¡Œæ‡‰è©²æ˜¯å¯ä»¥ä¿®å¾©çš„)
+ä¸è¦åœ¨ä½¿ç”¨PGP/GPGç°½å的郵件中包å«è£œä¸ã€‚這樣會使得很多腳本ä¸èƒ½è®€å–å’Œé©ç”¨æ–¼ä½ çš„
+補ä¸ã€‚(這個å•é¡Œæ‡‰è©²æ˜¯å¯ä»¥ä¿®å¾©çš„)
在給內核郵件列表發é€è£œä¸ä¹‹å‰ï¼Œçµ¦è‡ªå·±ç™¼é€ä¸€å€‹è£œä¸æ˜¯å€‹ä¸éŒ¯çš„主æ„,ä¿å­˜æŽ¥æ”¶åˆ°çš„
郵件,將補ä¸ç”¨'patch'命令打上,如果æˆåŠŸäº†ï¼Œå†çµ¦å…§æ ¸éƒµä»¶åˆ—表發é€ã€‚
@@ -61,100 +67,135 @@ Linux內核補ä¸æ˜¯é€šéŽéƒµä»¶è¢«æ交的,最好把補ä¸ä½œçˆ²éƒµä»¶é«”çš„
一些郵件客戶端æ示
------------------
-這裡給出一些詳細的MUAé…ç½®æ示,å¯ä»¥ç”¨æ–¼çµ¦Linux內核發é€è£œä¸ã€‚這些並ä¸æ„味是
-所有的軟體包é…置總çµã€‚
+
+這è£çµ¦å‡ºä¸€äº›è©³ç´°çš„MUAé…ç½®æ示,å¯ä»¥ç”¨æ–¼çµ¦Linux內核發é€è£œä¸ã€‚這些並ä¸æ„味是
+所有的軟件包é…置總çµã€‚
說明:
-TUI = 以文本爲基礎的用戶接å£
-GUI = 圖形界é¢ç”¨æˆ¶æŽ¥å£
+
+- TUI = 以文本爲基礎的用戶接å£
+- GUI = 圖形界é¢ç”¨æˆ¶æŽ¥å£
Alpine (TUI)
-~~~~~~~~~~~~
+************
é…ç½®é¸é …:
-在"Sending Preferences"部分:
-- "Do Not Send Flowed Text"必須開啓
-- "Strip Whitespace Before Sending"必須關閉
+在 :menuselection:`Sending Preferences` èœå–®ï¼š
+
+- :menuselection:`Do Not Send Flowed Text` 必須開啓
+- :menuselection:`Strip Whitespace Before Sending` 必須關閉
+
+當寫郵件時,光標應該放在補ä¸æœƒå‡ºç¾çš„地方,然後按下 :kbd:`CTRL-R` 組åˆéµï¼Œä½¿æŒ‡
+定的補ä¸æ–‡ä»¶åµŒå…¥åˆ°éƒµä»¶ä¸­ã€‚
-當寫郵件時,光標應該放在補ä¸æœƒå‡ºç¾çš„地方,然後按下CTRL-R組åˆéµï¼Œä½¿æŒ‡å®šçš„
-補ä¸æ–‡ä»¶åµŒå…¥åˆ°éƒµä»¶ä¸­ã€‚
+Claws Mail (GUI)
+****************
+
+å¯ä»¥ç”¨ï¼Œæœ‰äººç”¨å®ƒæˆåŠŸåœ°ç™¼éŽè£œä¸ã€‚
+
+用 :menuselection:`Message-->Insert File` (:kbd:`CTRL-I`) 或外置編輯器æ’入補ä¸ã€‚
+
+è‹¥è¦åœ¨Claws編輯窗å£é‡ä¿®æ”¹æ’入的補ä¸ï¼Œéœ€é—œé–‰
+:menuselection:`Configuration-->Preferences-->Compose-->Wrapping`
+的 `Auto wrapping` 。
Evolution (GUI)
-~~~~~~~~~~~~~~~
+***************
-一些開發者æˆåŠŸçš„使用它發é€è£œä¸
+一些開發者æˆåŠŸçš„使用它發é€è£œä¸ã€‚
-當é¸æ“‡éƒµä»¶é¸é …:Preformat
- 從Format->Heading->Preformatted (Ctrl-7)或者工具欄
+撰寫郵件時:
+從 :menuselection:`æ ¼å¼-->段è½æ¨£å¼-->é æ ¼å¼åŒ–` (:kbd:`CTRL-7`)
+或工具欄é¸æ“‡ :menuselection:`é æ ¼å¼åŒ–` ï¼›
然後使用:
- Insert->Text File... (Alt-n x)æ’入補ä¸æ–‡ä»¶ã€‚
+:menuselection:`æ’å…¥-->文本文件...` (:kbd:`ALT-N x`) æ’入補ä¸æ–‡ä»¶ã€‚
-ä½ é‚„å¯ä»¥"diff -Nru old.c new.c | xclip",é¸æ“‡Preformat,然後使用中間éµé€²è¡Œç²˜å¸–。
+ä½ é‚„å¯ä»¥ ``diff -Nru old.c new.c | xclip`` ,é¸æ“‡ :menuselection:`é æ ¼å¼åŒ–` ,
+然後使用鼠標中éµé€²è¡Œç²˜å¸–。
Kmail (GUI)
-~~~~~~~~~~~
+***********
一些開發者æˆåŠŸçš„使用它發é€è£œä¸ã€‚
-默èªè¨­ç½®ä¸çˆ²HTMLæ ¼å¼æ˜¯åˆé©çš„ï¼›ä¸è¦å•“用它。
+默èªæ’°å¯«è¨­ç½®ç¦ç”¨HTMLæ ¼å¼æ˜¯åˆé©çš„ï¼›ä¸è¦å•“用它。
+
+當書寫一å°éƒµä»¶çš„時候,在é¸é …下é¢ä¸è¦é¸æ“‡è‡ªå‹•æ›è¡Œã€‚唯一的缺點就是你在郵件中輸
+入的任何文本都ä¸æœƒè¢«è‡ªå‹•æ›è¡Œï¼Œå› æ­¤ä½ å¿…須在發é€è£œä¸ä¹‹å‰æ‰‹å‹•æ›è¡Œã€‚最簡單的方法
+就是啓用自動æ›è¡Œä¾†æ›¸å¯«éƒµä»¶ï¼Œç„¶å¾ŒæŠŠå®ƒä¿å­˜çˆ²è‰ç¨¿ã€‚一旦你在è‰ç¨¿ä¸­å†æ¬¡æ‰“開它,它
+已經全部自動æ›è¡Œäº†ï¼Œé‚£éº¼ä½ çš„郵件雖然沒有é¸æ“‡è‡ªå‹•æ›è¡Œï¼Œä½†æ˜¯é‚„ä¸æœƒå¤±åŽ»å·²æœ‰çš„自
+å‹•æ›è¡Œã€‚
-當書寫一å°éƒµä»¶çš„時候,在é¸é …下é¢ä¸è¦é¸æ“‡è‡ªå‹•æ›è¡Œã€‚唯一的缺點就是你在郵件中輸入的任何文本
-都ä¸æœƒè¢«è‡ªå‹•æ›è¡Œï¼Œå› æ­¤ä½ å¿…須在發é€è£œä¸ä¹‹å‰æ‰‹å‹•æ›è¡Œã€‚最簡單的方法就是啓用自動æ›è¡Œä¾†æ›¸å¯«éƒµä»¶ï¼Œ
-然後把它ä¿å­˜çˆ²è‰ç¨¿ã€‚一旦你在è‰ç¨¿ä¸­å†æ¬¡æ‰“開它,它已經全部自動æ›è¡Œäº†ï¼Œé‚£éº¼ä½ çš„郵件雖然沒有
-é¸æ“‡è‡ªå‹•æ›è¡Œï¼Œä½†æ˜¯é‚„ä¸æœƒå¤±åŽ»å·²æœ‰çš„自動æ›è¡Œã€‚
+在郵件的底部,æ’入補ä¸ä¹‹å‰ï¼Œæ”¾ä¸Šå¸¸ç”¨çš„補ä¸å®šç•Œç¬¦ï¼šä¸‰å€‹é€£å­—符(``---``)。
-在郵件的底部,æ’入補ä¸ä¹‹å‰ï¼Œæ”¾ä¸Šå¸¸ç”¨çš„補ä¸å®šç•Œç¬¦ï¼šä¸‰å€‹é€£å­—號(---)。
+然後在 :menuselection:`信件` èœå–®ï¼Œé¸æ“‡ :menuselection:`æ’入文本文件` ,接
+ç€é¸å–你的補ä¸æ–‡ä»¶ã€‚還有一個é¡å¤–çš„é¸é …,你å¯ä»¥é€šéŽå®ƒé…置你的創建新郵件工具欄,
+加上 :menuselection:`æ’入文本文件` 圖標。
-然後在"Message"èœå–®æ¢ç›®ï¼Œé¸æ“‡æ’入文件,接著é¸å–你的補ä¸æ–‡ä»¶ã€‚還有一個é¡å¤–çš„é¸é …,你å¯ä»¥
-通éŽå®ƒé…置你的郵件建立工具欄èœå–®ï¼Œé‚„å¯ä»¥å¸¶ä¸Š"insert file"圖標。
+將編輯器窗å£æ‹‰åˆ°è¶³å¤ å¯¬é¿å…折行。å°æ–¼KMail 1.13.5 (KDE 4.5.4),它會在發é€éƒµä»¶
+時å°ç·¨è¼¯å™¨çª—å£ä¸­é¡¯ç¤ºæŠ˜è¡Œçš„地方自動æ›è¡Œã€‚在é¸é …èœå–®ä¸­å–消自動æ›è¡Œä»ä¸èƒ½è§£æ±ºã€‚
+因此,如果你的補ä¸ä¸­æœ‰éžå¸¸é•·çš„行,必須在發é€ä¹‹å‰æŠŠç·¨è¼¯å™¨çª—å£æ‹‰å¾—éžå¸¸å¯¬ã€‚
+åƒè¦‹ï¼šhttps://bugs.kde.org/show_bug.cgi?id=174034
-ä½ å¯ä»¥å®‰å…¨åœ°é€šéŽGPG標記附件,但是內嵌補ä¸æœ€å¥½ä¸è¦ä½¿ç”¨GPG標記它們。作爲內嵌文本的簽發補ä¸ï¼Œ
-當從GPG中æå–7ä½ç·¨ç¢¼æ™‚會使他們變的更加複雜。
+ä½ å¯ä»¥å®‰å…¨åœ°ç”¨GPGç°½å附件,但是內嵌補ä¸æœ€å¥½ä¸è¦ä½¿ç”¨GPGç°½å它們。作爲內嵌文本
+æ’入的簽å補ä¸å°‡ä½¿å…¶é›£ä»¥å¾ž7-bit編碼中æå–。
-如果你éžè¦ä»¥é™„件的形å¼ç™¼é€è£œä¸ï¼Œé‚£éº¼å°±å³éµé»žæ“Šé™„件,然後é¸ä¸­å±¬æ€§ï¼Œçªå‡º"Suggest automatic
-display",這樣內嵌附件更容易讓讀者看到。
+如果你éžè¦ä»¥é™„件的形å¼ç™¼é€è£œä¸ï¼Œé‚£éº¼å°±å³éµé»žæ“Šé™„件,然後é¸æ“‡
+:menuselection:`屬性` ,打開 :menuselection:`建議自動顯示` ,使附件內è¯æ›´å®¹
+易讓讀者看到。
-當你è¦ä¿å­˜å°‡è¦ç™¼é€çš„內嵌文本補ä¸ï¼Œä½ å¯ä»¥å¾žæ¶ˆæ¯åˆ—表窗格é¸æ“‡åŒ…å«è£œä¸çš„郵件,然後å³æ“Šé¸æ“‡
-"save as"。你å¯ä»¥ä½¿ç”¨ä¸€å€‹æ²’有更改的包å«è£œä¸çš„郵件,如果它是以正確的形å¼çµ„æˆã€‚當你正真在它
-自己的窗å£ä¹‹ä¸‹å¯Ÿçœ‹ï¼Œé‚£æ™‚沒有é¸é …å¯ä»¥ä¿å­˜éƒµä»¶--已經有一個這樣的bug被匯報到了kmailçš„bugzilla
-並且希望這將會被處ç†ã€‚郵件是以åªé‡å°æŸå€‹ç”¨æˆ¶å¯è®€å¯«çš„權é™è¢«ä¿å­˜çš„,所以如果你想把郵件複製到其他地方,
-ä½ ä¸å¾—ä¸æŠŠä»–們的權é™æ”¹çˆ²çµ„或者整體å¯è®€ã€‚
+當你è¦ä¿å­˜å°‡è¦ç™¼é€çš„內嵌文本補ä¸ï¼Œä½ å¯ä»¥å¾žæ¶ˆæ¯åˆ—表窗格é¸æ“‡åŒ…å«è£œä¸çš„郵件,然
+後å³éµé¸æ“‡ :menuselection:`å¦å­˜çˆ²` 。如果整個電å­éƒµä»¶çš„組æˆæ­£ç¢ºï¼Œæ‚¨å¯ç›´æŽ¥å°‡
+其作爲補ä¸ä½¿ç”¨ã€‚é›»å­éƒµä»¶ä»¥ç•¶å‰ç”¨æˆ¶å¯è®€å¯«æ¬Šé™ä¿å­˜ï¼Œå› æ­¤æ‚¨å¿…é ˆ ``chmod`` ,以
+使其在複製到別處時用戶組和其他人å¯è®€ã€‚
Lotus Notes (GUI)
-~~~~~~~~~~~~~~~~~
+*****************
ä¸è¦ä½¿ç”¨å®ƒã€‚
+IBM Verse (Web GUI)
+*******************
+
+åŒä¸Šæ¢ã€‚
+
Mutt (TUI)
-~~~~~~~~~~
+**********
-很多Linux開發人員使用mutt客戶端,所以證明它肯定工作的éžå¸¸æ¼‚亮。
+很多Linux開發人員使用mutt客戶端,這證明它肯定工作得éžå¸¸æ¼‚亮。
-Muttä¸è‡ªå¸¶ç·¨è¼¯å™¨ï¼Œæ‰€ä»¥ä¸ç®¡ä½ ä½¿ç”¨ä»€éº¼ç·¨è¼¯å™¨éƒ½ä¸æ‡‰è©²å¸¶æœ‰è‡ªå‹•æ–·è¡Œã€‚大多數編輯器都帶有
-一個"insert file"é¸é …,它å¯ä»¥é€šéŽä¸æ”¹è®Šæ–‡ä»¶å…§å®¹çš„æ–¹å¼æ’入文件。
+Muttä¸è‡ªå¸¶ç·¨è¼¯å™¨ï¼Œæ‰€ä»¥ä¸ç®¡ä½ ä½¿ç”¨ä»€éº¼ç·¨è¼¯å™¨ï¼Œä¸è‡ªå‹•æ–·è¡Œå°±è¡Œã€‚大多數編輯器都有
+:menuselection:`æ’入文件` é¸é …,它å¯ä»¥åœ¨ä¸æ”¹è®Šæ–‡ä»¶å…§å®¹çš„情æ³ä¸‹æ’入文件。
+
+用 ``vim`` 作爲mutt的編輯器::
-'vim'作爲mutt的編輯器:
set editor="vi"
- 如果使用xclip,敲入以下命令
+如果使用xclip,敲入以下命令::
+
:set paste
- 按中éµä¹‹å‰æˆ–者shift-insert或者使用
+
+然後å†æŒ‰ä¸­éµæˆ–者shift-insert或者使用::
+
:r filename
-如果想è¦æŠŠè£œä¸ä½œçˆ²å…§åµŒæ–‡æœ¬ã€‚
-(a)ttach工作的很好,ä¸å¸¶æœ‰"set paste"。
+把補ä¸æ’入爲內嵌文本。
+在未設置 ``set paste`` 時(a)ttach工作的很好。
ä½ å¯ä»¥é€šéŽ ``git format-patch`` 生æˆè£œä¸ï¼Œç„¶å¾Œç”¨ Mutt發é€å®ƒå€‘::
- $ mutt -H 0001-some-bug-fix.patch
+ $ mutt -H 0001-some-bug-fix.patch
é…ç½®é¸é …:
+
它應該以默èªè¨­ç½®çš„å½¢å¼å·¥ä½œã€‚
-然而,把"send_charset"設置爲"us-ascii::utf-8"也是一個ä¸éŒ¯çš„主æ„。
+然而,把 ``send_charset`` 設置一下也是一個ä¸éŒ¯çš„主æ„::
-Mutt 是高度å¯é…置的。 這裡是個使用mutté€šéŽ Gmail 發é€çš„補ä¸çš„最å°é…ç½®::
+ set send_charset="us-ascii:utf-8"
+
+Mutt 是高度å¯é…置的。 這è£æ˜¯å€‹ä½¿ç”¨mutté€šéŽ Gmail 發é€çš„補ä¸çš„最å°é…ç½®::
# .muttrc
# ================ IMAP ====================
@@ -181,72 +222,108 @@ Mutt 是高度å¯é…置的。 這裡是個使用mutté€šéŽ Gmail 發é€çš„補ä¸
set from = "username@gmail.com"
set use_from = yes
-Mutt文檔å«æœ‰æ›´å¤šä¿¡æ¯:
+Mutt文檔å«æœ‰æ›´å¤šä¿¡æ¯ï¼š
- http://dev.mutt.org/trac/wiki/UseCases/Gmail
+ https://gitlab.com/muttmua/mutt/-/wikis/UseCases/Gmail
- http://dev.mutt.org/doc/manual.html
+ http://www.mutt.org/doc/manual/
Pine (TUI)
-~~~~~~~~~~
+**********
PineéŽåŽ»æœ‰ä¸€äº›ç©ºæ ¼åˆªæ¸›å•é¡Œï¼Œä½†æ˜¯é€™äº›ç¾åœ¨æ‡‰è©²éƒ½è¢«ä¿®å¾©äº†ã€‚
-如果å¯ä»¥ï¼Œè«‹ä½¿ç”¨alpine(pine的繼承者)
+如果å¯ä»¥ï¼Œè«‹ä½¿ç”¨alpine(pine的繼承者)。
é…ç½®é¸é …:
-- 最近的版本需è¦æ¶ˆé™¤æµç¨‹æ–‡æœ¬
-- "no-strip-whitespace-before-send"é¸é …也是需è¦çš„。
+
+- æœ€è¿‘çš„ç‰ˆæœ¬éœ€è¦ ``quell-flowed-text``
+- ``no-strip-whitespace-before-send`` é¸é …也是需è¦çš„。
Sylpheed (GUI)
-~~~~~~~~~~~~~~
+**************
- 內嵌文本å¯ä»¥å¾ˆå¥½çš„工作(或者使用附件)。
- å…許使用外部的編輯器。
-- å°æ–¼ç›®éŒ„較多時éžå¸¸æ…¢ã€‚
+- 收件箱較多時éžå¸¸æ…¢ã€‚
- 如果通éŽnon-SSL連接,無法使用TLS SMTP授權。
-- 在組æˆçª—å£ä¸­æœ‰ä¸€å€‹å¾ˆæœ‰ç”¨çš„ruler bar。
-- 給地å€æœ¬ä¸­æ·»åŠ åœ°å€å°±ä¸æœƒæ­£ç¢ºçš„了解顯示å。
+- 撰寫窗å£çš„標尺很有用。
+- 將地å€æ·»åŠ åˆ°é€šè¨Šç°¿æ™‚無法正確ç†è§£é¡¯ç¤ºçš„å稱。
Thunderbird (GUI)
-~~~~~~~~~~~~~~~~~
+*****************
+
+Thunderbird是Outlook的克隆版本,它很容易æ壞文本,但也有一些方法強制修正。
+
+在完æˆä¿®æ”¹å¾Œï¼ˆåŒ…括安è£æ“´å±•ï¼‰ï¼Œæ‚¨éœ€è¦é‡æ–°å•“å‹•Thunderbird。
+
+- å…許使用外部編輯器:
+
+ 使用Thunderbird發補ä¸æœ€ç°¡å–®çš„方法是使用擴展來打開您最喜歡的外部編輯器。
+
+ 下é¢æ˜¯ä¸€äº›èƒ½å¤ åšåˆ°é€™ä¸€é»žçš„擴展樣例。
+
+ - “External Editor Revivedâ€
+
+ https://github.com/Frederick888/external-editor-revived
+
+ https://addons.thunderbird.net/en-GB/thunderbird/addon/external-editor-revived/
+
+ 它需è¦å®‰è£â€œæœ¬åœ°æ¶ˆæ¯ä¸»æ©Ÿï¼ˆnative messaging host)â€ã€‚
+ åƒè¦‹ä»¥ä¸‹æ–‡æª”:
+ https://github.com/Frederick888/external-editor-revived/wiki
+
+ - “External Editorâ€
+
+ https://github.com/exteditor/exteditor
+
+ 下載並安è£æ­¤æ“´å±•ï¼Œç„¶å¾Œæ‰“é–‹ :menuselection:`新建消æ¯` 窗å£, 用
+ :menuselection:`查看-->工具欄-->自定義...` 給它增加一個按鈕,直接點擊此
+ 按鈕å³å¯ä½¿ç”¨å¤–置編輯器。
+
+ 請注æ„,“External Editorâ€è¦æ±‚你的編輯器ä¸èƒ½fork,æ›å¥è©±èªªï¼Œç·¨è¼¯å™¨å¿…須在
+ 關閉å‰ä¸è¿”回。你å¯èƒ½éœ€è¦å‚³éžé¡å¤–çš„åƒæ•¸æˆ–修改編輯器設置。最值得注æ„的是,
+ 如果您使用的是gvim,那麼您必須將 :menuselection:`external editor` 設置的
+ 編輯器字段設置爲 ``/usr/bin/gvim --nofork"`` (å‡è¨­å¯åŸ·è¡Œæ–‡ä»¶åœ¨
+ ``/usr/bin`` ï¼‰ï¼Œä»¥å‚³éž ``-f`` åƒæ•¸ã€‚如果您正在使用其他編輯器,請閱讀其
+ 手冊瞭解如何處ç†ã€‚
-默èªæƒ…æ³ä¸‹ï¼Œthunderbird很容易æ壞文本,但是還有一些方法å¯ä»¥å¼·åˆ¶å®ƒè®Šå¾—更好。
+è‹¥è¦ä¿®æ­£å…§éƒ¨ç·¨è¼¯å™¨ï¼Œè«‹åŸ·è¡Œä»¥ä¸‹æ“作:
-- 在用戶帳號設置里,組æˆå’Œå°‹å€ï¼Œä¸è¦é¸æ“‡"Compose messages in HTML format"。
+- 修改你的Thunderbird設置,ä¸è¦ä½¿ç”¨ ``format=flowed`` ï¼
+ 回到主窗å£ï¼ŒæŒ‰ç…§
+ :menuselection:`主èœå–®-->首é¸é …-->常è¦-->é…置編輯器...`
+ 打開Thunderbirdçš„é…置編輯器。
-- 編輯你的Thunderbirdé…置設置來使它ä¸è¦æ‹†è¡Œä½¿ç”¨ï¼šuser_pref("mailnews.wraplength", 0);
+ - 將 ``mailnews.send_plaintext_flowed`` 設爲 ``false``
-- 編輯你的Thunderbirdé…置設置,使它ä¸è¦ä½¿ç”¨"format=flowed"æ ¼å¼ï¼šuser_pref("mailnews.
- send_plaintext_flowed", false);
+ - 將 ``mailnews.wraplength`` 從 ``72`` 改爲 ``0``
-- 你需è¦ä½¿Thunderbird變爲é å…ˆæ ¼å¼æ–¹å¼ï¼š
- 如果默èªæƒ…æ³ä¸‹ä½ æ›¸å¯«çš„是HTMLæ ¼å¼ï¼Œé‚£ä¸æ˜¯å¾ˆé›£ã€‚僅僅從標題欄的下拉框中é¸æ“‡"Preformat"æ ¼å¼ã€‚
- 如果默èªæƒ…æ³ä¸‹ä½ æ›¸å¯«çš„是文本格å¼ï¼Œä½ ä¸å¾—把它改爲HTMLæ ¼å¼ï¼ˆåƒ…僅作爲一次性的)來書寫新的消æ¯ï¼Œ
- 然後強制使它回到文本格å¼ï¼Œå¦å‰‡å®ƒå°±æœƒæ‹†è¡Œã€‚è¦å¯¦ç¾å®ƒï¼Œåœ¨å¯«ä¿¡çš„圖標上使用shiftéµä¾†ä½¿å®ƒè®Šçˆ²HTML
- æ ¼å¼ï¼Œç„¶å¾Œæ¨™é¡Œæ¬„的下拉框中é¸æ“‡"Preformat"æ ¼å¼ã€‚
+- ä¸è¦å¯«HTML郵件ï¼
+ 回到主窗å£ï¼Œæ‰“é–‹
+ :menuselection:`主èœå–®-->賬戶設置-->ä½ çš„@郵件.地å€-->通訊錄/編寫&地å€ç°¿` ,
+ 關掉 ``以HTMLæ ¼å¼ç·¨å¯«æ¶ˆæ¯`` 。
-- å…許使用外部的編輯器:
- é‡å°Thunderbird打補ä¸æœ€ç°¡å–®çš„方法就是使用一個"external editor"擴展,然後使用你最喜歡的
- $EDITOR來讀å–或者åˆä½µè£œä¸åˆ°æ–‡æœ¬ä¸­ã€‚è¦å¯¦ç¾å®ƒï¼Œå¯ä»¥ä¸‹è¼‰ä¸¦ä¸”安è£é€™å€‹æ“´å±•ï¼Œç„¶å¾Œæ·»åŠ ä¸€å€‹ä½¿ç”¨å®ƒçš„
- 按éµView->Toolbars->Customize...最後當你書寫信æ¯çš„時候僅僅點擊它就å¯ä»¥äº†ã€‚
+- åªç”¨ç´”文本格å¼æŸ¥çœ‹éƒµä»¶ï¼
+ 回到主窗å£ï¼Œ :menuselection:`主èœå–®-->查看-->消æ¯é«”爲-->純文本` ï¼
TkRat (GUI)
-~~~~~~~~~~~
+***********
å¯ä»¥ä½¿ç”¨å®ƒã€‚使用"Insert file..."或者外部的編輯器。
Gmail (Web GUI)
-~~~~~~~~~~~~~~~
+***************
ä¸è¦ä½¿ç”¨å®ƒç™¼é€è£œä¸ã€‚
-Gmail網é å®¢æˆ¶ç«¯è‡ªå‹•åœ°æŠŠåˆ¶è¡¨ç¬¦è½‰æ›çˆ²ç©ºæ ¼ã€‚
+Gmail網é å®¢æˆ¶ç«¯è‡ªå‹•åœ°æŠŠè£½è¡¨ç¬¦è½‰æ›çˆ²ç©ºæ ¼ã€‚
-雖然制表符轉æ›çˆ²ç©ºæ ¼å•é¡Œå¯ä»¥è¢«å¤–部編輯器解決,åŒæ™‚它還會使用回車æ›è¡ŒæŠŠæ¯è¡Œæ‹†åˆ†çˆ²78個字符。
+雖然製表符轉æ›çˆ²ç©ºæ ¼å•é¡Œå¯ä»¥è¢«å¤–部編輯器解決,但它åŒæ™‚還會使用回車æ›è¡ŒæŠŠæ¯è¡Œ
+拆分爲78個字符。
-å¦ä¸€å€‹å•é¡Œæ˜¯Gmail還會把任何ä¸æ˜¯ASCII的字符的信æ¯æ”¹çˆ²base64編碼。它把æ±è¥¿è®Šçš„åƒæ­æ´²äººçš„å字。
+å¦ä¸€å€‹å•é¡Œæ˜¯Gmail還會把任何å«æœ‰éžASCII的字符的消æ¯æ”¹ç”¨base64編碼,如æ­æ´²äººçš„
+å字。
- ###
diff --git a/Documentation/translations/zh_TW/process/embargoed-hardware-issues.rst b/Documentation/translations/zh_TW/process/embargoed-hardware-issues.rst
index 8e4db8baa0d1..b9f6ab7b6666 100644
--- a/Documentation/translations/zh_TW/process/embargoed-hardware-issues.rst
+++ b/Documentation/translations/zh_TW/process/embargoed-hardware-issues.rst
@@ -6,17 +6,17 @@
:Translator: Alex Shi <alex.shi@linux.alibaba.com>
Hu Haowen <src.res.211@gmail.com>
-被é™åˆ¶çš„硬體å•é¡Œ
+被é™åˆ¶çš„硬件å•é¡Œ
================
範åœ
----
-導致安全å•é¡Œçš„硬體å•é¡Œèˆ‡åªå½±éŸ¿Linux內核的純軟體錯誤是ä¸åŒçš„安全錯誤類別。
+導致安全å•é¡Œçš„硬件å•é¡Œèˆ‡éš»å½±éŸ¿Linux內核的純軟件錯誤是ä¸åŒçš„安全錯誤類別。
-å¿…é ˆå€åˆ¥å°å¾…諸如熔毀(Meltdown)ã€Spectreã€L1TF等硬體å•é¡Œï¼Œå› çˆ²å®ƒå€‘通常會影響
-所有作業系統(「OSã€ï¼‰ï¼Œå› æ­¤éœ€è¦åœ¨ä¸åŒçš„OS供應商ã€ç™¼è¡Œç‰ˆã€ç¡¬é«”供應商和其他å„æ–¹
-之間進行å”調。å°æ–¼æŸäº›å•é¡Œï¼Œè»Ÿé«”緩解å¯èƒ½ä¾è³´æ–¼å¾®ç¢¼æˆ–固件更新,這需è¦é€²ä¸€æ­¥çš„
+å¿…é ˆå€åˆ¥å°å¾…諸如熔燬(Meltdown)ã€Spectreã€L1TF等硬件å•é¡Œï¼Œå› çˆ²å®ƒå€‘通常會影響
+所有æ“作系統(“OSâ€ï¼‰ï¼Œå› æ­¤éœ€è¦åœ¨ä¸åŒçš„OS供應商ã€ç™¼è¡Œç‰ˆã€ç¡¬ä»¶ä¾›æ‡‰å•†å’Œå…¶ä»–å„æ–¹
+之間進行å”調。å°æ–¼æŸäº›å•é¡Œï¼Œè»Ÿä»¶ç·©è§£å¯èƒ½ä¾è³´æ–¼å¾®ç¢¼æˆ–固件更新,這需è¦é€²ä¸€æ­¥çš„
å”調。
.. _tw_Contact:
@@ -24,9 +24,9 @@
接觸
----
-Linux內核硬體安全å°çµ„ç¨ç«‹æ–¼æ™®é€šçš„Linux內核安全å°çµ„。
+Linux內核硬件安全å°çµ„ç¨ç«‹æ–¼æ™®é€šçš„Linux內核安全å°çµ„。
-該å°çµ„åªè² è²¬å”調被é™åˆ¶çš„硬體安全å•é¡Œã€‚Linux內核中純軟體安全æ¼æ´žçš„報告ä¸ç”±è©²
+該å°çµ„åªè² è²¬å”調被é™åˆ¶çš„硬件安全å•é¡Œã€‚Linux內核中純軟件安全æ¼æ´žçš„報告ä¸ç”±è©²
å°çµ„處ç†ï¼Œå ±å‘Šè€…將被引導至常è¦Linux內核安全å°çµ„(:ref:`Documentation/admin-guide/
<securitybugs>`)è¯ç¹«ã€‚
@@ -37,13 +37,13 @@ Linux內核硬體安全å°çµ„ç¨ç«‹æ–¼æ™®é€šçš„Linux內核安全å°çµ„。
者的PGP密鑰或S/MIME證書籤å。該列表的PGP密鑰和S/MIME證書å¯å¾ž
https://www.kernel.org/.... ç²å¾—。
-雖然硬體安全å•é¡Œé€šå¸¸ç”±å—影響的硬體供應商處ç†ï¼Œä½†æˆ‘們歡迎發ç¾æ½›åœ¨ç¡¬é«”缺陷的研究
+雖然硬件安全å•é¡Œé€šå¸¸ç”±å—影響的硬件供應商處ç†ï¼Œä½†æˆ‘們歡迎發ç¾æ½›åœ¨ç¡¬ä»¶ç¼ºé™·çš„研究
人員或個人與我們è¯ç¹«ã€‚
-硬體安全官
+硬件安全官
^^^^^^^^^^
-ç›®å‰çš„硬體安全官å°çµ„:
+ç›®å‰çš„硬件安全官å°çµ„:
- Linus Torvalds(Linux基金會院士)
- Greg Kroah Hartman(Linux基金會院士)
@@ -62,50 +62,50 @@ Linux基金會目å‰çš„IT基礎設施安全總監是 Konstantin Ryabitsev。
ä¿å¯†å”è­°
--------
-Linux內核硬體安全å°çµ„ä¸æ˜¯æ­£å¼çš„機構,因此無法簽訂任何ä¿å¯†å”議。核心社å€æ„識到
+Linux內核硬件安全å°çµ„ä¸æ˜¯æ­£å¼çš„機構,因此無法簽訂任何ä¿å¯†å”議。核心社å€æ„識到
這些å•é¡Œçš„æ•æ„Ÿæ€§ï¼Œä¸¦æ供了一份諒解備忘錄。
諒解備忘錄
----------
-Linux內核社å€æ·±åˆ»ç†è§£åœ¨ä¸åŒä½œæ¥­ç³»çµ±ä¾›æ‡‰å•†ã€ç™¼è¡Œå•†ã€ç¡¬é«”供應商和其他å„方之間
-進行å”調時,ä¿æŒç¡¬é«”安全å•é¡Œè™•æ–¼é™åˆ¶ç‹€æ…‹çš„è¦æ±‚。
+Linux內核社å€æ·±åˆ»ç†è§£åœ¨ä¸åŒæ“作系統供應商ã€ç™¼è¡Œå•†ã€ç¡¬ä»¶ä¾›æ‡‰å•†å’Œå…¶ä»–å„方之間
+進行å”調時,ä¿æŒç¡¬ä»¶å®‰å…¨å•é¡Œè™•æ–¼é™åˆ¶ç‹€æ…‹çš„è¦æ±‚。
-Linux內核社å€åœ¨éŽåŽ»å·²ç¶“æˆåŠŸåœ°è™•ç†äº†ç¡¬é«”安全å•é¡Œï¼Œä¸¦ä¸”有必è¦çš„機制å…許在é™åˆ¶
+Linux內核社å€åœ¨éŽåŽ»å·²ç¶“æˆåŠŸåœ°è™•ç†äº†ç¡¬ä»¶å®‰å…¨å•é¡Œï¼Œä¸¦ä¸”有必è¦çš„機制å…許在é™åˆ¶
é™åˆ¶ä¸‹é€²è¡Œç¬¦åˆç¤¾å€çš„開發。
-Linux內核社å€æœ‰ä¸€å€‹å°ˆé–€çš„硬體安全å°çµ„負責åˆå§‹è¯ç¹«ï¼Œä¸¦ç›£ç£åœ¨é™åˆ¶è¦å‰‡ä¸‹è™•ç†
+Linux內核社å€æœ‰ä¸€å€‹å°ˆé–€çš„硬件安全å°çµ„負責åˆå§‹è¯ç¹«ï¼Œä¸¦ç›£ç£åœ¨é™åˆ¶è¦å‰‡ä¸‹è™•ç†
此類å•é¡Œçš„éŽç¨‹ã€‚
-硬體安全å°çµ„確定開發人員(領域專家),他們將組æˆç‰¹å®šå•é¡Œçš„åˆå§‹éŸ¿æ‡‰å°çµ„。最åˆ
+硬件安全å°çµ„確定開發人員(領域專家),他們將組æˆç‰¹å®šå•é¡Œçš„åˆå§‹éŸ¿æ‡‰å°çµ„。最åˆ
的響應å°çµ„å¯ä»¥å¼•å…¥æ›´å¤šçš„開發人員(領域專家)以最佳的技術方å¼è§£æ±ºé€™å€‹å•é¡Œã€‚
所有相關開發商承諾éµå®ˆé™åˆ¶è¦å®šï¼Œä¸¦å°æ”¶åˆ°çš„ä¿¡æ¯ä¿å¯†ã€‚é•å承諾將導致立å³å¾žç•¶å‰
-å•é¡Œä¸­æŽ’除,並從所有相關郵件列表中刪除。此外,硬體安全å°çµ„還將把é•å者排除在
+å•é¡Œä¸­æŽ’除,並從所有相關郵件列表中刪除。此外,硬件安全å°çµ„還將把é•å者排除在
未來的å•é¡Œä¹‹å¤–。這一後果的影響在我們社å€æ˜¯ä¸€ç¨®éžå¸¸æœ‰æ•ˆçš„å¨æ‡¾ã€‚如果發生é•è¦
-情æ³ï¼Œç¡¬é«”安全å°çµ„將立å³é€šçŸ¥ç›¸é—œæ–¹ã€‚如果您或任何人發ç¾æ½›åœ¨çš„é•è¦è¡Œçˆ²ï¼Œè«‹ç«‹å³
-å‘硬體安全人員報告。
+情æ³ï¼Œç¡¬ä»¶å®‰å…¨å°çµ„將立å³é€šçŸ¥ç›¸é—œæ–¹ã€‚如果您或任何人發ç¾æ½›åœ¨çš„é•è¦è¡Œçˆ²ï¼Œè«‹ç«‹å³
+å‘硬件安全人員報告。
æµç¨‹
^^^^
-由於Linux內核開發的全çƒåˆ†å¸ƒå¼ç‰¹æ€§ï¼Œé¢å°é¢çš„會議幾乎ä¸å¯èƒ½è§£æ±ºç¡¬é«”安全å•é¡Œã€‚
+由於Linux內核開發的全çƒåˆ†ä½ˆå¼ç‰¹æ€§ï¼Œé¢å°é¢çš„會議幾乎ä¸å¯èƒ½è§£æ±ºç¡¬ä»¶å®‰å…¨å•é¡Œã€‚
由於時å€å’Œå…¶ä»–因素,電話會議很難å”調,åªèƒ½åœ¨çµ•å°å¿…è¦æ™‚使用。加密電å­éƒµä»¶å·²è¢«
證明是解決此類å•é¡Œçš„最有效和最安全的通信方法。
開始披露
""""""""
-披露內容首先通éŽé›»å­éƒµä»¶è¯ç¹«Linux內核硬體安全å°çµ„。此åˆå§‹è¯ç¹«äººæ‡‰åŒ…å«å•é¡Œçš„
-æ述和任何已知å—影響硬體的列表。如果您的組織製造或分發å—影響的硬體,我們建議
-您也考慮哪些其他硬體å¯èƒ½æœƒå—到影響。
+披露內容首先通éŽé›»å­éƒµä»¶è¯ç¹«Linux內核硬件安全å°çµ„。此åˆå§‹è¯ç¹«äººæ‡‰åŒ…å«å•é¡Œçš„
+æ述和任何已知å—影響硬件的列表。如果您的組織製造或分發å—影響的硬件,我們建議
+您也考慮哪些其他硬件å¯èƒ½æœƒå—到影響。
-硬體安全å°çµ„å°‡æ供一個特定於事件的加密郵件列表,用於與報告者進行åˆæ­¥è¨Žè«–ã€
+硬件安全å°çµ„å°‡æ供一個特定於事件的加密郵件列表,用於與報告者進行åˆæ­¥è¨Žè«–ã€
進一步披露和å”調。
-硬體安全å°çµ„å°‡å‘披露方æ供一份開發人員(領域專家)å單,在與開發人員確èªä»–們
+硬件安全å°çµ„å°‡å‘披露方æ供一份開發人員(領域專家)å單,在與開發人員確èªä»–們
å°‡éµå®ˆæœ¬è«’解備忘錄和文件化æµç¨‹å¾Œï¼Œæ‡‰é¦–先告知開發人員有關該å•é¡Œçš„ä¿¡æ¯ã€‚這些開發
-人員組æˆåˆå§‹éŸ¿æ‡‰å°çµ„,並在åˆå§‹æŽ¥è§¸å¾Œè² è²¬è™•ç†å•é¡Œã€‚硬體安全å°çµ„支æŒéŸ¿æ‡‰å°çµ„,
+人員組æˆåˆå§‹éŸ¿æ‡‰å°çµ„,並在åˆå§‹æŽ¥è§¸å¾Œè² è²¬è™•ç†å•é¡Œã€‚硬件安全å°çµ„支æŒéŸ¿æ‡‰å°çµ„,
但ä¸ä¸€å®šåƒèˆ‡ç·©è§£é–‹ç™¼éŽç¨‹ã€‚
雖然個別開發人員å¯èƒ½é€šéŽå…¶åƒ±ä¸»å—到ä¿å¯†å”è­°çš„ä¿è­·ï¼Œä½†ä»–們ä¸èƒ½ä»¥Linux內核開發
@@ -113,7 +113,7 @@ Linux內核社å€æœ‰ä¸€å€‹å°ˆé–€çš„硬體安全å°çµ„負責åˆå§‹è¯ç¹«ï¼Œä¸¦ç›£
披露方應æ供已經或應該被告知該å•é¡Œçš„所有其他實體的è¯ç¹«äººå單。這有幾個目的:
- - 披露的實體列表å…許跨行業通信,例如其他作業系統供應商ã€ç¡¬é«”供應商等。
+ - 披露的實體列表å…許跨行業通信,例如其他æ“作系統供應商ã€ç¡¬ä»¶ä¾›æ‡‰å•†ç­‰ã€‚
- å¯è¯ç¹«å·²æŠ«éœ²çš„實體,指定應åƒèˆ‡ç·©è§£æŽªæ–½é–‹ç™¼çš„專家。
@@ -133,10 +133,10 @@ Linux內核社å€æœ‰ä¸€å€‹å°ˆé–€çš„硬體安全å°çµ„負責åˆå§‹è¯ç¹«ï¼Œä¸¦ç›£
åˆå§‹éŸ¿æ‡‰å°çµ„設置加密郵件列表,或在é©ç•¶çš„情æ³ä¸‹é‡æ–°ä¿®æ”¹ç¾æœ‰éƒµä»¶åˆ—表。
-使用郵件列表接近於正常的Linux開發éŽç¨‹ï¼Œä¸¦ä¸”在éŽåŽ»å·²ç¶“æˆåŠŸåœ°ç”¨æ–¼çˆ²å„種硬體安全
+使用郵件列表接近於正常的Linux開發éŽç¨‹ï¼Œä¸¦ä¸”在éŽåŽ»å·²ç¶“æˆåŠŸåœ°ç”¨æ–¼çˆ²å„種硬件安全
å•é¡Œé–‹ç™¼ç·©è§£æŽªæ–½ã€‚
-郵件列表的æ“作方å¼èˆ‡æ­£å¸¸çš„Linux開發相åŒã€‚發布ã€è¨Žè«–和審查修補程åºï¼Œå¦‚æžœåŒæ„,
+郵件列表的æ“作方å¼èˆ‡æ­£å¸¸çš„Linux開發相åŒã€‚發佈ã€è¨Žè«–和審查修補程åºï¼Œå¦‚æžœåŒæ„,
則應用於éžå…¬å…±git存儲庫,åƒèˆ‡é–‹ç™¼äººå“¡åªèƒ½é€šéŽå®‰å…¨é€£æŽ¥è¨ªå•è©²å­˜å„²åº«ã€‚存儲庫包å«
é‡å°ä¸»ç·šå…§æ ¸çš„主開發分支,並根據需è¦çˆ²ç©©å®šçš„內核版本æä¾›å‘後移æ¤åˆ†æ”¯ã€‚
@@ -155,9 +155,9 @@ Linux內核社å€æœ‰ä¸€å€‹å°ˆé–€çš„硬體安全å°çµ„負責åˆå§‹è¯ç¹«ï¼Œä¸¦ç›£
""""""""
有關å„方將å”商é™åˆ¶çµæŸçš„日期和時間。此時,準備好的緩解措施集æˆåˆ°ç›¸é—œçš„內核樹中
-並發布。
+併發布。
-雖然我們ç†è§£ç¡¬é«”安全å•é¡Œéœ€è¦å”調é™åˆ¶æ™‚間,但é™åˆ¶æ™‚間應é™åˆ¶åœ¨æ‰€æœ‰æœ‰é—œå„方制定ã€
+雖然我們ç†è§£ç¡¬ä»¶å®‰å…¨å•é¡Œéœ€è¦å”調é™åˆ¶æ™‚間,但é™åˆ¶æ™‚間應é™åˆ¶åœ¨æ‰€æœ‰æœ‰é—œå„方制定ã€
測試和準備緩解措施所需的最短時間內。人爲地延長é™åˆ¶æ™‚間以滿足會議討論日期或其他
éžæŠ€è¡“原因,會給相關的開發人員和響應å°çµ„帶來了更多的工作和負擔,因爲補ä¸éœ€è¦
ä¿æŒæœ€æ–°ï¼Œä»¥ä¾¿è·Ÿè¹¤æ­£åœ¨é€²è¡Œçš„上游內核開發,這å¯èƒ½æœƒé€ æˆè¡çªçš„更改。
@@ -165,7 +165,7 @@ Linux內核社å€æœ‰ä¸€å€‹å°ˆé–€çš„硬體安全å°çµ„負責åˆå§‹è¯ç¹«ï¼Œä¸¦ç›£
CVE分é…
"""""""
-硬體安全å°çµ„å’Œåˆå§‹éŸ¿æ‡‰å°çµ„都ä¸åˆ†é…CVE,開發éŽç¨‹ä¹Ÿä¸éœ€è¦CVE。如果CVE是由披露方
+硬件安全å°çµ„å’Œåˆå§‹éŸ¿æ‡‰å°çµ„都ä¸åˆ†é…CVE,開發éŽç¨‹ä¹Ÿä¸éœ€è¦CVE。如果CVE是由披露方
æ供的,則å¯ç”¨æ–¼æ–‡æª”中。
æµç¨‹å°ˆä½¿
@@ -196,22 +196,22 @@ CVE分é…
Google Kees Cook <keescook@chromium.org>
============= ========================================================
-如果è¦å°‡æ‚¨çš„組織添加到專使å單中,請與硬體安全å°çµ„è¯ç¹«ã€‚被æå的專使必須完全
+如果è¦å°‡æ‚¨çš„組織添加到專使å單中,請與硬件安全å°çµ„è¯ç¹«ã€‚被æå的專使必須完全
ç†è§£å’Œæ”¯æŒæˆ‘們的éŽç¨‹ï¼Œä¸¦ä¸”在Linux內核社å€ä¸­å¾ˆå®¹æ˜“è¯ç¹«ã€‚
加密郵件列表
------------
我們使用加密郵件列表進行通信。這些列表的工作原ç†æ˜¯ï¼Œç™¼é€åˆ°åˆ—表的電å­éƒµä»¶ä½¿ç”¨
-列表的PGP密鑰或列表的/MIME證書進行加密。郵件列表軟體å°é›»å­éƒµä»¶é€²è¡Œè§£å¯†ï¼Œä¸¦
+列表的PGP密鑰或列表的/MIME證書進行加密。郵件列表軟件å°é›»å­éƒµä»¶é€²è¡Œè§£å¯†ï¼Œä¸¦
使用訂閱者的PGP密鑰或S/MIME證書爲æ¯å€‹è¨‚閱者分別å°å…¶é€²è¡Œé‡æ–°åŠ å¯†ã€‚有關郵件列表
-軟體和用於確ä¿åˆ—表安全和數據ä¿è­·çš„設置的詳細信æ¯ï¼Œè«‹è¨ªå•:
+軟件和用於確ä¿åˆ—表安全和數據ä¿è­·çš„設置的詳細信æ¯ï¼Œè«‹è¨ªå•:
https://www.kernel.org/....
é—œéµé»ž
^^^^^^
-åˆæ¬¡æŽ¥è§¸è¦‹ :ref:`tw_Contact`. å°æ–¼ç‰¹å®šæ–¼äº‹ä»¶çš„郵件列表,密鑰和S/MIME證書通éŽ
+åˆæ¬¡æŽ¥è§¸è¦‹ :ref:`zh_Contact`. å°æ–¼ç‰¹å®šæ–¼äº‹ä»¶çš„郵件列表,密鑰和S/MIME證書通éŽ
特定列表發é€çš„é›»å­éƒµä»¶å‚³éžçµ¦è¨‚閱者。
訂閱事件特定列表
@@ -220,8 +220,8 @@ https://www.kernel.org/....
訂閱由響應å°çµ„處ç†ã€‚希望åƒèˆ‡é€šä¿¡çš„披露方將潛在訂戶的列表發é€çµ¦éŸ¿æ‡‰çµ„,以便
響應組å¯ä»¥é©—證訂閱請求。
-æ¯å€‹è¨‚戶都需è¦é€šéŽé›»å­éƒµä»¶å‘響應å°çµ„發é€è¨‚閱請求。電å­éƒµä»¶å¿…須使用訂閱伺æœå™¨
-çš„PGP密鑰或S/MIME證書籤å。如果使用PGP密鑰,則必須從公鑰伺æœå™¨ç²å¾—該密鑰,
+æ¯å€‹è¨‚戶都需è¦é€šéŽé›»å­éƒµä»¶å‘響應å°çµ„發é€è¨‚閱請求。電å­éƒµä»¶å¿…須使用訂閱æœå‹™å™¨
+çš„PGP密鑰或S/MIME證書籤å。如果使用PGP密鑰,則必須從公鑰æœå‹™å™¨ç²å¾—該密鑰,
並且ç†æƒ³æƒ…æ³ä¸‹è©²å¯†é‘°é€£æŽ¥åˆ°Linux內核的PGP信任網。å¦è«‹åƒè¦‹:
https://www.kernel.org/signature.html.
diff --git a/Documentation/translations/zh_TW/process/index.rst b/Documentation/translations/zh_TW/process/index.rst
index d742642dab01..6a0d98b2f9ee 100644
--- a/Documentation/translations/zh_TW/process/index.rst
+++ b/Documentation/translations/zh_TW/process/index.rst
@@ -13,11 +13,12 @@
.. _tw_process_index:
+========================
與Linux 內核社å€ä¸€èµ·å·¥ä½œ
========================
你想æˆçˆ²Linux內核開發人員嗎?歡迎之至ï¼åœ¨å­¸ç¿’許多關於內核的技術知識的åŒæ™‚,
-了解我們社å€çš„工作方å¼ä¹Ÿå¾ˆé‡è¦ã€‚閱讀這些文檔å¯ä»¥è®“您以更輕鬆的ã€éº»ç…©æ›´å°‘çš„
+瞭解我們社å€çš„工作方å¼ä¹Ÿå¾ˆé‡è¦ã€‚閱讀這些文檔å¯ä»¥è®“您以更輕鬆的ã€éº»ç…©æ›´å°‘çš„
æ–¹å¼å°‡æ›´æ”¹åˆä½µåˆ°å…§æ ¸ã€‚
以下是æ¯ä½é–‹ç™¼äººå“¡éƒ½æ‡‰é–±è®€çš„基本指å—:
@@ -49,7 +50,7 @@
management-style
embargoed-hardware-issues
-這些是一些總體性技術指å—,由於ä¸å¤§å¥½åˆ†é¡žè€Œæ”¾åœ¨é€™è£¡ï¼š
+這些是一些總體性技術指å—,由於ä¸å¤§å¥½åˆ†é¡žè€Œæ”¾åœ¨é€™è£ï¼š
.. toctree::
:maxdepth: 1
diff --git a/Documentation/translations/zh_TW/process/kernel-driver-statement.rst b/Documentation/translations/zh_TW/process/kernel-driver-statement.rst
index 963ecece3db1..e967089d2e1f 100644
--- a/Documentation/translations/zh_TW/process/kernel-driver-statement.rst
+++ b/Documentation/translations/zh_TW/process/kernel-driver-statement.rst
@@ -1,6 +1,6 @@
.. SPDX-License-Identifier: GPL-2.0
-.. _zh_process_statement_driver:
+.. _tw_process_statement_driver:
.. include:: ../disclaimer-zh_TW.rst
diff --git a/Documentation/translations/zh_TW/process/license-rules.rst b/Documentation/translations/zh_TW/process/license-rules.rst
index 503b6701bde4..2c43bcf2ac79 100644
--- a/Documentation/translations/zh_TW/process/license-rules.rst
+++ b/Documentation/translations/zh_TW/process/license-rules.rst
@@ -1,7 +1,5 @@
.. SPDX-License-Identifier: GPL-2.0
-.. SPDX-License-Identifier: GPL-2.0
-
.. include:: ../disclaimer-zh_TW.rst
:Original: :ref:`Documentation/process/license-rules.rst <kernel_licensing>`
@@ -17,10 +15,10 @@ Linux內核根據LICENSES/preferred/GPL-2.0中æ供的GNU通用公共許å¯è­‰ç
(GPL-2.0)的æ¢æ¬¾æ供,並在LICENSES/exceptions/Linux-syscall-note中顯å¼
æ述了例外的系統調用,如COPYING文件中所述。
-此文檔文件æ供了如何å°æ¯å€‹æºæ–‡ä»¶é€²è¡Œæ³¨é‡‹ä»¥ä½¿å…¶è¨±å¯è­‰æ¸…晰明確的說明。
+此文檔文件æ供瞭如何å°æ¯å€‹æºæ–‡ä»¶é€²è¡Œè¨»é‡‹ä»¥ä½¿å…¶è¨±å¯è­‰æ¸…晰明確的說明。
它ä¸æœƒå–代內核的許å¯è­‰ã€‚
-內核原始碼作爲一個整體é©ç”¨æ–¼COPYING文件中æ述的許å¯è­‰ï¼Œä½†æ˜¯å–®å€‹æºæ–‡ä»¶å¯ä»¥
+內核æºä»£ç¢¼ä½œçˆ²ä¸€å€‹æ•´é«”é©ç”¨æ–¼COPYING文件中æ述的許å¯è­‰ï¼Œä½†æ˜¯å–®å€‹æºæ–‡ä»¶å¯ä»¥
具有ä¸åŒçš„與GPL-20兼容的許å¯è­‰::
GPL-1.0+ : GNU通用公共許å¯è­‰v1.0或更高版本
@@ -34,18 +32,18 @@ Linux內核根據LICENSES/preferred/GPL-2.0中æ供的GNU通用公共許å¯è­‰ç
MIT等許å¯ã€‚
用戶空間API(UAPI)頭文件æ述了用戶空間程åºèˆ‡å…§æ ¸çš„接å£ï¼Œé€™æ˜¯ä¸€ç¨®ç‰¹æ®Šæƒ…æ³ã€‚
-根據內核COPYING文件中的注釋,syscall接å£æ˜¯ä¸€å€‹æ˜Žç¢ºçš„邊界,它ä¸æœƒå°‡GPLè¦æ±‚
-擴展到任何使用它與內核通信的軟體。由於UAPI頭文件必須包å«åœ¨å‰µå»ºåœ¨Linux內核
+根據內核COPYING文件中的註釋,syscall接å£æ˜¯ä¸€å€‹æ˜Žç¢ºçš„邊界,它ä¸æœƒå°‡GPLè¦æ±‚
+擴展到任何使用它與內核通信的軟件。由於UAPI頭文件必須包å«åœ¨å‰µå»ºåœ¨Linux內核
上é‹è¡Œçš„å¯åŸ·è¡Œæ–‡ä»¶çš„任何æºæ–‡ä»¶ä¸­ï¼Œå› æ­¤æ­¤ä¾‹å¤–必須記錄在特別的許å¯è­‰è¡¨è¿°ä¸­ã€‚
-表é”æºæ–‡ä»¶è¨±å¯è­‰çš„常用方法是將匹é…的樣æ¿æ–‡æœ¬æ·»åŠ åˆ°æ–‡ä»¶çš„頂部注釋中。由於
-æ ¼å¼ï¼Œæ‹¼å¯«éŒ¯èª¤ç­‰ï¼Œé€™äº›ã€Œæ¨£æ¿ã€å¾ˆé›£é€šéŽé‚£äº›åœ¨ä¸Šä¸‹æ–‡ä¸­ä½¿ç”¨çš„驗證許å¯è­‰åˆè¦æ€§
+表é”æºæ–‡ä»¶è¨±å¯è­‰çš„常用方法是將匹é…的樣æ¿æ–‡æœ¬æ·»åŠ åˆ°æ–‡ä»¶çš„頂部註釋中。由於
+æ ¼å¼ï¼Œæ‹¼å¯«éŒ¯èª¤ç­‰ï¼Œé€™äº›â€œæ¨£æ¿â€å¾ˆé›£é€šéŽé‚£äº›åœ¨ä¸Šä¸‹æ–‡ä¸­ä½¿ç”¨çš„驗證許å¯è­‰åˆè¦æ€§
的工具。
-樣æ¿æ–‡æœ¬çš„替代方法是在æ¯å€‹æºæ–‡ä»¶ä¸­ä½¿ç”¨è»Ÿé«”包數據交æ›ï¼ˆSPDX)許å¯è­‰æ¨™è­˜ç¬¦ã€‚
+樣æ¿æ–‡æœ¬çš„替代方法是在æ¯å€‹æºæ–‡ä»¶ä¸­ä½¿ç”¨è»Ÿä»¶åŒ…數據交æ›ï¼ˆSPDX)許å¯è­‰æ¨™è­˜ç¬¦ã€‚
SPDX許å¯è­‰æ¨™è­˜ç¬¦æ˜¯æ©Ÿå™¨å¯è§£æžçš„,並且是用於æ供文件內容的許å¯è­‰çš„精確縮寫。
SPDX許å¯è­‰æ¨™è­˜ç¬¦ç”±Linux 基金會的SPDX 工作組管ç†ï¼Œä¸¦å¾—到了整個行業,工具
-供應商和法律團隊的åˆä½œå¤¥ä¼´çš„一致åŒæ„。有關詳細信æ¯ï¼Œè«‹åƒé–±
+供應商和法律團隊的åˆä½œä¼™ä¼´çš„一致åŒæ„。有關詳細信æ¯ï¼Œè«‹åƒé–±
https://spdx.org/
Linux內核需è¦æ‰€æœ‰æºæ–‡ä»¶ä¸­çš„精確SPDX標識符。內核中使用的有效標識符在
@@ -58,7 +56,7 @@ https://spdx.org/licenses/ 上的官方SPDX許å¯è­‰åˆ—表中檢索,並附帶è
1.安置:
-   內核文件中的SPDX許å¯è­‰æ¨™è­˜ç¬¦æ‡‰æ·»åŠ åˆ°å¯åŒ…å«æ³¨é‡‹çš„文件中的第一行。å°æ–¼å¤§å¤š
+   內核文件中的SPDX許å¯è­‰æ¨™è­˜ç¬¦æ‡‰æ·»åŠ åˆ°å¯åŒ…å«è¨»é‡‹çš„文件中的第一行。å°æ–¼å¤§å¤š
數文件,這是第一行,除了那些在第一行中需è¦'#!PATH_TO_INTERPRETER'的腳本。
å°æ–¼é€™äº›è…³æœ¬ï¼ŒSPDX標識符進入第二行。
@@ -66,7 +64,7 @@ https://spdx.org/licenses/ 上的官方SPDX許å¯è­‰åˆ—表中檢索,並附帶è
2. 風格:
- SPDX許å¯è­‰æ¨™è­˜ç¬¦ä»¥æ³¨é‡‹çš„å½¢å¼æ·»åŠ ã€‚注釋樣å¼å–決於文件類型::
+ SPDX許å¯è­‰æ¨™è­˜ç¬¦ä»¥è¨»é‡‹çš„å½¢å¼æ·»åŠ ã€‚註釋樣å¼å–決於文件類型::
C source: // SPDX-License-Identifier: <SPDX License Expression>
C header: /* SPDX-License-Identifier: <SPDX License Expression> */
@@ -75,20 +73,20 @@ https://spdx.org/licenses/ 上的官方SPDX許å¯è­‰åˆ—表中檢索,並附帶è
.rst: .. SPDX-License-Identifier: <SPDX License Expression>
.dts{i}: // SPDX-License-Identifier: <SPDX License Expression>
- 如果特定工具無法處ç†æ¨™æº–注釋樣å¼ï¼Œå‰‡æ‡‰ä½¿ç”¨å·¥å…·æŽ¥å—的相應注釋機制。這是在
- C 頭文件中使用「/\*\*/ã€æ¨£å¼æ³¨é‡‹çš„原因。éŽåŽ»åœ¨ä½¿ç”¨ç”Ÿæˆçš„.lds文件中觀察到
- 構建被破壞,其中'ld'無法解æžC++注釋。ç¾åœ¨å·²ç¶“解決了這個å•é¡Œï¼Œä½†ä»ç„¶æœ‰è¼ƒ
- 舊的彙編程åºå·¥å…·ç„¡æ³•è™•ç†C++樣å¼çš„注釋。
+ 如果特定工具無法處ç†æ¨™æº–註釋樣å¼ï¼Œå‰‡æ‡‰ä½¿ç”¨å·¥å…·æŽ¥å—的相應註釋機制。這是在
+ C 頭文件中使用“/\*\*/â€æ¨£å¼è¨»é‡‹çš„原因。éŽåŽ»åœ¨ä½¿ç”¨ç”Ÿæˆçš„.lds文件中觀察到
+ 構建被破壞,其中'ld'無法解æžC++註釋。ç¾åœ¨å·²ç¶“解決了這個å•é¡Œï¼Œä½†ä»ç„¶æœ‰è¼ƒ
+ 舊的彙編程åºå·¥å…·ç„¡æ³•è™•ç†C++樣å¼çš„註釋。
|
3. å¥æ³•:
<SPDX許å¯è­‰è¡¨é”å¼>是SPDX許å¯è­‰åˆ—表中的SPDX短格å¼è¨±å¯è­‰æ¨™è­˜ç¬¦ï¼Œæˆ–者在許å¯
- 證例外é©ç”¨æ™‚由「WITHã€åˆ†éš”的兩個SPDX短格å¼è¨±å¯è­‰æ¨™è­˜ç¬¦çš„組åˆã€‚當應用多個許
- å¯è­‰æ™‚,表é”å¼ç”±åˆ†éš”å­è¡¨é”å¼çš„é—œéµå­—「ANDã€ï¼Œã€ŒORã€çµ„æˆï¼Œä¸¦ç”±ã€Œï¼ˆã€ï¼Œã€Œï¼‰ã€åŒ…åœã€‚
+ 證例外é©ç”¨æ™‚由“WITHâ€åˆ†éš”的兩個SPDX短格å¼è¨±å¯è­‰æ¨™è­˜ç¬¦çš„組åˆã€‚當應用多個許
+ å¯è­‰æ™‚,表é”å¼ç”±åˆ†éš”å­è¡¨é”å¼çš„é—œéµå­—“ANDâ€ï¼Œâ€œORâ€çµ„æˆï¼Œä¸¦ç”±â€œï¼ˆâ€ï¼Œâ€œï¼‰â€åŒ…åœã€‚
- 帶有「或更高ã€é¸é …çš„[L]GPL等許å¯è­‰çš„許å¯è­‰æ¨™è­˜ç¬¦é€šéŽä½¿ç”¨ã€Œ+ã€ä¾†è¡¨ç¤ºã€Œæˆ–更高ã€
+ 帶有“或更高â€é¸é …çš„[L]GPL等許å¯è­‰çš„許å¯è­‰æ¨™è­˜ç¬¦é€šéŽä½¿ç”¨â€œ+â€ä¾†è¡¨ç¤ºâ€œæˆ–更高â€
é¸é …來構建。::
// SPDX-License-Identifier: GPL-2.0+
@@ -230,7 +228,7 @@ https://spdx.org/licenses/ 上的官方SPDX許å¯è­‰åˆ—表中檢索,並附帶è
元標籤:
- 「其他ã€è¨±å¯è­‰çš„元標籤è¦æ±‚與 `優先許å¯`_ çš„è¦æ±‚相åŒã€‚
+ “其他â€è¨±å¯è­‰çš„元標籤è¦æ±‚與 `優先許å¯`_ çš„è¦æ±‚相åŒã€‚
文件格å¼ç¤ºä¾‹::
@@ -267,8 +265,8 @@ https://spdx.org/licenses/ 上的官方SPDX許å¯è­‰åˆ—表中檢索,並附帶è
LICENSES/exceptions/GCC-exception-2.0
- 包å«GCC'連çµä¾‹å¤–',它å…許ç¨ç«‹æ–¼å…¶è¨±å¯è­‰çš„任何二進ä½æ–‡ä»¶èˆ‡æ¨™è¨˜æœ‰æ­¤ä¾‹å¤–çš„
- 文件的編譯版本連çµã€‚這是從GPLä¸å…¼å®¹åŽŸå§‹ç¢¼å‰µå»ºå¯é‹è¡Œçš„å¯åŸ·è¡Œæ–‡ä»¶æ‰€å¿…需的。
+ 包å«GCC'éˆæŽ¥ä¾‹å¤–',它å…許ç¨ç«‹æ–¼å…¶è¨±å¯è­‰çš„任何二進制文件與標記有此例外的
+ 文件的編譯版本éˆæŽ¥ã€‚這是從GPLä¸å…¼å®¹æºä»£ç¢¼å‰µå»ºå¯é‹è¡Œçš„å¯åŸ·è¡Œæ–‡ä»¶æ‰€å¿…需的。
_`例外元標記`:
@@ -333,11 +331,11 @@ https://spdx.org/licenses/ 上的官方SPDX許å¯è­‰åˆ—表中檢索,並附帶è
_`模塊許å¯`
-----------------
- å¯åŠ è¼‰å…§æ ¸æ¨¡å¡Šé‚„需è¦MODULE_LICENSE()標記。此標記既ä¸æ›¿ä»£æ­£ç¢ºçš„原始碼
+ å¯åŠ è¼‰å…§æ ¸æ¨¡å¡Šé‚„需è¦MODULE_LICENSE()標記。此標記既ä¸æ›¿ä»£æ­£ç¢ºçš„æºä»£ç¢¼
許å¯è­‰ä¿¡æ¯ï¼ˆSPDX-License-Identifier),也ä¸ä»¥ä»»ä½•æ–¹å¼è¡¨ç¤ºæˆ–確定æ供模塊
- 原始碼的確切許å¯è­‰ã€‚
+ æºä»£ç¢¼çš„確切許å¯è­‰ã€‚
- 此標記的唯一目的是æ供足夠的信æ¯ï¼Œè©²æ¨¡å¡Šæ˜¯å¦æ˜¯è‡ªç”±è»Ÿé«”或者是內核模塊加
+ 此標記的唯一目的是æ供足夠的信æ¯ï¼Œè©²æ¨¡å¡Šæ˜¯å¦æ˜¯è‡ªç”±è»Ÿä»¶æˆ–者是內核模塊加
載器和用戶空間工具的專有模塊。
MODULE_LICENSE()的有效許å¯è­‰å­—符串是:
@@ -365,9 +363,9 @@ _`模塊許å¯`
åªèƒ½é€šéŽç›¸æ‡‰çš„æºæ–‡ä»¶ä¸­çš„許å¯è­‰ä¿¡æ¯ä¾†ç¢ºå®šã€‚
"Proprietary" 該模塊屬於專有許å¯ã€‚此字符串僅用於專有的第三
- 方模塊,ä¸èƒ½ç”¨æ–¼åœ¨å…§æ ¸æ¨¹ä¸­å…·æœ‰åŽŸå§‹ç¢¼çš„模塊。
- 以這種方å¼æ¨™è¨˜çš„模塊在加載時會使用'P'標記汙
- 染內核,並且內核模塊加載器拒絕將這些模塊連çµ
+ 方模塊,ä¸èƒ½ç”¨æ–¼åœ¨å…§æ ¸æ¨¹ä¸­å…·æœ‰æºä»£ç¢¼çš„模塊。
+ 以這種方å¼æ¨™è¨˜çš„模塊在加載時會使用'P'標記污
+ 染內核,並且內核模塊加載器拒絕將這些模塊éˆæŽ¥
到使用EXPORT_SYMBOL_GPL()導出的符號。
============================= =============================================
diff --git a/Documentation/translations/zh_TW/process/management-style.rst b/Documentation/translations/zh_TW/process/management-style.rst
index e9d29024f4c9..f3913e3c159d 100644
--- a/Documentation/translations/zh_TW/process/management-style.rst
+++ b/Documentation/translations/zh_TW/process/management-style.rst
@@ -16,20 +16,20 @@ Linux內核管ç†é¢¨æ ¼
主è¦æ˜¯çˆ²äº†é¿å…å覆回答 [#cnf1]_ 相åŒï¼ˆæˆ–類似)的å•é¡Œã€‚
管ç†é¢¨æ ¼æ˜¯éžå¸¸å€‹äººåŒ–的,比簡單的編碼風格è¦å‰‡æ›´é›£ä»¥é‡åŒ–,因此本文檔å¯èƒ½èˆ‡å¯¦
-際情æ³æœ‰é—œï¼Œä¹Ÿå¯èƒ½èˆ‡å¯¦éš›æƒ…æ³ç„¡é—œã€‚èµ·åˆå®ƒæ˜¯ä¸€å€‹çŽ©ç¬‘,但這並ä¸æ„味著它å¯èƒ½ä¸
+際情æ³æœ‰é—œï¼Œä¹Ÿå¯èƒ½èˆ‡å¯¦éš›æƒ…æ³ç„¡é—œã€‚èµ·åˆå®ƒæ˜¯ä¸€å€‹çŽ©ç¬‘,但這並ä¸æ„味ç€å®ƒå¯èƒ½ä¸
是真的。你得自己決定。
-順便說一å¥ï¼Œåœ¨è«‡åˆ°ã€Œæ ¸å¿ƒç®¡ç†è€…ã€æ™‚,主è¦æ˜¯æŠ€è¡“負責人,而ä¸æ˜¯åœ¨å…¬å¸å…§éƒ¨é€²è¡Œå‚³
-統管ç†çš„人。如果你簽署了採購訂單或者å°ä½ çš„團隊的é ç®—有任何了解,你幾乎肯定
+順便說一å¥ï¼Œåœ¨è«‡åˆ°â€œæ ¸å¿ƒç®¡ç†è€…â€æ™‚,主è¦æ˜¯æŠ€è¡“負責人,而ä¸æ˜¯åœ¨å…¬å¸å…§éƒ¨é€²è¡Œå‚³
+統管ç†çš„人。如果你簽署了採購訂單或者å°ä½ çš„團隊的é ç®—有任何瞭解,你幾乎肯定
ä¸æ˜¯ä¸€å€‹æ ¸å¿ƒç®¡ç†è€…。這些建議å¯èƒ½é©ç”¨æ–¼æ‚¨ï¼Œä¹Ÿå¯èƒ½ä¸é©ç”¨æ–¼æ‚¨ã€‚
-首先,我建議你購買「高效人的七個習慣ã€ï¼Œè€Œä¸æ˜¯é–±è®€å®ƒã€‚燒了它,這是一個å‰å¤§çš„
+首先,我建議你購買“高效人的七個習慣â€ï¼Œè€Œä¸æ˜¯é–±è®€å®ƒã€‚燒了它,這是一個å‰å¤§çš„
象徵性姿態。
.. [#cnf1] 本文件並ä¸æ˜¯é€šéŽå›žç­”å•é¡Œï¼Œè€Œæ˜¯é€šéŽè®“æå•è€…痛苦地明白,我們ä¸çŸ¥é“
答案是什麼。
-ä¸ç®¡æ€Žæ¨£ï¼Œé€™è£¡æ˜¯ï¼š
+ä¸ç®¡æ€Žæ¨£ï¼Œé€™è£æ˜¯ï¼š
.. _tw_decisions:
@@ -39,14 +39,14 @@ Linux內核管ç†é¢¨æ ¼
æ¯å€‹äººéƒ½èªçˆ²ç®¡ç†è€…åšæ±ºå®šï¼Œè€Œä¸”決策很é‡è¦ã€‚決定越大越痛苦,管ç†è€…就必須越高級。
這很明顯,但事實並éžå¦‚此。
-éŠæˆ²çš„å字是 **é¿å…** åšå‡ºæ±ºå®šã€‚尤其是,如果有人告訴你「é¸æ“‡ï¼ˆa)或(b),
-我們真的需è¦ä½ ä¾†åšæ±ºå®šã€ï¼Œä½ å°±æ˜¯é™·å…¥éº»ç…©çš„管ç†è€…。你管ç†çš„人比你更了解細節,
+最é‡è¦çš„是 **é¿å…** åšå‡ºæ±ºå®šã€‚尤其是,如果有人告訴你“é¸æ“‡ï¼ˆa)或(b),
+我們真的需è¦ä½ ä¾†åšæ±ºå®šâ€ï¼Œä½ å°±æ˜¯é™·å…¥éº»ç…©çš„管ç†è€…。你管ç†çš„人比你更瞭解細節,
所以如果他們來找你åšæŠ€è¡“決策,你完蛋了。你顯然沒有能力爲他們åšé€™å€‹æ±ºå®šã€‚
-(推論:如果你管ç†çš„人ä¸æ¯”你更了解細節,你也會被æžç ¸ï¼Œå„˜ç®¡åŽŸå› å®Œå…¨ä¸åŒã€‚
+(推論:如果你管ç†çš„人ä¸æ¯”你更瞭解細節,你也會被æžç ¸ï¼Œå„˜ç®¡åŽŸå› å®Œå…¨ä¸åŒã€‚
也就是說,你的工作是錯的,他們應該管ç†ä½ çš„æ‰æ™ºï¼‰
-所以éŠæˆ²çš„å字是 **é¿å…** åšå‡ºæ±ºå®šï¼Œè‡³å°‘是那些大而痛苦的決定。åšä¸€äº›å°çš„
+所以最é‡è¦çš„是 **é¿å…** åšå‡ºæ±ºå®šï¼Œè‡³å°‘是那些大而痛苦的決定。åšä¸€äº›å°çš„
å’Œéžçµæžœæ€§çš„決定是很好的,並且使您看起來好åƒçŸ¥é“自己在åšä»€éº¼ï¼Œæ‰€ä»¥å…§æ ¸ç®¡ç†è€…
需è¦åšçš„是將那些大的和痛苦的決定變æˆé‚£äº›æ²’有人真正關心的å°äº‹æƒ…。
@@ -61,7 +61,7 @@ Linux內核管ç†é¢¨æ ¼
逃離的角è½ã€‚走投無路的è€é¼ å¯èƒ½å¾ˆå±éšªâ€”—走投無路的管ç†è€…真å¯æ†ã€‚
事實證明,由於沒有人會愚蠢到讓內核管ç†è€…承擔巨大的財政責任,所以通常很容易
-回溯。既然你ä¸å¯èƒ½æµªè²»æŽ‰ä½ ç„¡æ³•å„Ÿé‚„çš„å·¨é¡è³‡é‡‘,你唯一å¯ä»¥å›žæº¯çš„就是技術決策,
+回溯。既然你ä¸å¯èƒ½æµªè²»æŽ‰ä½ ç„¡æ³•å„Ÿé‚„的鉅é¡è³‡é‡‘,你唯一å¯ä»¥å›žæº¯çš„就是技術決策,
而回溯很容易:åªè¦å‘Šè¨´å¤§å®¶ä½ æ˜¯å€‹ä¸ç¨±è·çš„傻瓜,說å°ä¸èµ·ï¼Œç„¶å¾Œæ’¤éŠ·ä½ åŽ»å¹´è®“別
人所åšçš„毫無價值的工作。çªç„¶é–“,你一年å‰åšçš„決定ä¸åœ¨æ˜¯ä¸€å€‹é‡å¤§çš„決定,因爲
它很容易被推翻。
@@ -72,7 +72,7 @@ Linux內核管ç†é¢¨æ ¼
確實很難。
- 如果有人告訴你,你去年所åšçš„工作終究是ä¸å€¼å¾—的,那麼å°é‚£äº›å¯æ†çš„低級工
程師來說也是很困難的,雖然實際的 **工作** 很容易刪除,但你å¯èƒ½å·²ç¶“ä¸å¯
- 挽回地失去了工程師的信任。記ä½ï¼šã€Œä¸å¯æ’¤éŠ·ã€æ˜¯æˆ‘們一開始就試圖é¿å…的,
+ 挽回地失去了工程師的信任。記ä½ï¼šâ€œä¸å¯æ’¤éŠ·â€æ˜¯æˆ‘們一開始就試圖é¿å…的,
而你的決定終究是一個é‡å¤§çš„決定。
令人欣慰的是,這兩個原因都å¯ä»¥é€šéŽé å…ˆæ‰¿èªä½ æ²’有任何線索,æå‰å‘Šè¨´äººå€‘ä½ çš„
@@ -80,19 +80,19 @@ Linux內核管ç†é¢¨æ ¼
的權利,並讓人們 **æ„è­˜** 到這一點。當你 **還沒有** åšéŽçœŸæ­£æ„šè ¢çš„事情的時
候,承èªè‡ªå·±æ˜¯æ„šè ¢çš„è¦å®¹æ˜“得多。
-然後,當它真的被證明是愚蠢的時候,人們就轉動他們的眼ç èªªã€Œå“Žå‘€ï¼Œä¸‹æ¬¡ä¸è¦äº†ã€ã€‚
+然後,當它真的被證明是愚蠢的時候,人們就轉動他們的眼ç èªªâ€œå“Žå‘€ï¼Œä¸‹æ¬¡ä¸è¦äº†â€ã€‚
這種å°ä¸ç¨±è·çš„先發制人的承èªï¼Œä¹Ÿå¯èƒ½ä½¿çœŸæ­£åšé€™é …工作的人也會三æ€æ˜¯å¦å€¼å¾—åšã€‚
畢竟,如果他們ä¸ç¢ºå®šé€™æ˜¯å¦æ˜¯ä¸€å€‹å¥½ä¸»æ„,你肯定ä¸æ‡‰è©²é€šéŽå‘他們ä¿è­‰ä»–們所åš
的工作將會進入(內核)鼓勵他們。在他們開始一項巨大的努力之å‰ï¼Œè‡³å°‘讓他們三
æ€è€Œå¾Œè¡Œã€‚
-記ä½ï¼šä»–們最好比你更了解細節,而且他們通常èªçˆ²ä»–們å°æ¯ä»¶äº‹éƒ½æœ‰ç­”案。作爲一
+記ä½ï¼šä»–們最好比你更瞭解細節,而且他們通常èªçˆ²ä»–們å°æ¯ä»¶äº‹éƒ½æœ‰ç­”案。作爲一
個管ç†è€…,你能åšçš„最好的事情ä¸æ˜¯çŒè¼¸è‡ªä¿¡ï¼Œè€Œæ˜¯å°ä»–們所åšçš„事情進行å¥åº·çš„批
判性æ€è€ƒã€‚
-順便說一å¥ï¼Œå¦ä¸€ç¨®é¿å…åšå‡ºæ±ºå®šçš„方法是看起來很å¯æ†çš„抱怨 「我們ä¸èƒ½å…©è€…å…¼
-得嗎?〠相信我,它是有效的。如果ä¸æ¸…楚哪種方法更好,他們最終會弄清楚的。
+順便說一å¥ï¼Œå¦ä¸€ç¨®é¿å…åšå‡ºæ±ºå®šçš„方法是看起來很å¯æ†çš„抱怨 “我們ä¸èƒ½å…©è€…å…¼
+得嗎?†相信我,它是有效的。如果ä¸æ¸…楚哪種方法更好,他們最終會弄清楚的。
最終的答案å¯èƒ½æ˜¯å…©å€‹åœ˜éšŠéƒ½æœƒå› çˆ²é€™ç¨®æƒ…æ³è€Œæ„Ÿåˆ°æ²®å–ªï¼Œä»¥è‡³æ–¼ä»–們放棄了。
這è½èµ·ä¾†åƒæ˜¯ä¸€å€‹å¤±æ•—,但這通常是一個跡象,表明兩個項目都有å•é¡Œï¼Œè€Œåƒèˆ‡å…¶ä¸­
@@ -102,7 +102,7 @@ Linux內核管ç†é¢¨æ ¼
2)人
-----
-大多數人都是白癡,åšä¸€å管ç†è€…æ„味著你必須處ç†å¥½é€™ä»¶äº‹ï¼Œä¹Ÿè¨±æ›´é‡è¦çš„是,
+大多數人都是白癡,åšä¸€å管ç†è€…æ„味ç€ä½ å¿…須處ç†å¥½é€™ä»¶äº‹ï¼Œä¹Ÿè¨±æ›´é‡è¦çš„是,
**他們** 必須處ç†å¥½ä½ ã€‚
事實證明,雖然很容易糾正技術錯誤,但ä¸å®¹æ˜“糾正人格障礙。你åªèƒ½å’Œä»–們的和
@@ -110,16 +110,16 @@ Linux內核管ç†é¢¨æ ¼
但是,爲了åšå¥½ä½œçˆ²å…§æ ¸ç®¡ç†è€…的準備,最好記ä½ä¸è¦ç‡’掉任何橋樑,ä¸è¦è½Ÿç‚¸ä»»ä½•
無辜的æ‘民,也ä¸è¦ç–é å¤ªå¤šçš„內核開發人員。事實證明,ç–é äººæ˜¯ç›¸ç•¶å®¹æ˜“的,而
-親近一個ç–é çš„人是很難的。因此,「ç–é ã€ç«‹å³å±¬æ–¼ã€Œä¸å¯é€†ã€çš„範疇,並根據
+親近一個ç–é çš„人是很難的。因此,“ç–é â€ç«‹å³å±¬æ–¼â€œä¸å¯é€†â€çš„範疇,並根據
:ref:`tw_decisions` æˆçˆ²çµ•ä¸å¯ä»¥åšçš„事情。
-這裡åªæœ‰å¹¾å€‹ç°¡å–®çš„è¦å‰‡ï¼š
+這è£åªæœ‰å¹¾å€‹ç°¡å–®çš„è¦å‰‡ï¼š
(1) ä¸è¦å«äººç¬¨è›‹ï¼ˆè‡³å°‘ä¸è¦åœ¨å…¬å…±å ´åˆï¼‰
(2) 學習如何在忘記è¦å‰‡(1)時é“æ­‰
-å•é¡Œåœ¨æ–¼ #1 很容易去åšï¼Œå› çˆ²ä½ å¯ä»¥ç”¨æ•¸ç™¾è¬ç¨®ä¸åŒçš„æ–¹å¼èªªã€Œä½ æ˜¯ä¸€å€‹ç¬¨è›‹ã€ [#cnf2]_
-有時甚至沒有æ„識到,而且幾乎總是帶著一種白熱化的信念,èªçˆ²ä½ æ˜¯å°çš„。
+å•é¡Œåœ¨æ–¼ #1 很容易去åšï¼Œå› çˆ²ä½ å¯ä»¥ç”¨æ•¸ç™¾è¬ç¨®ä¸åŒçš„æ–¹å¼èªªâ€œä½ æ˜¯ä¸€å€‹ç¬¨è›‹â€ [#cnf2]_
+有時甚至沒有æ„識到,而且幾乎總是帶ç€ä¸€ç¨®ç™½ç†±åŒ–的信念,èªçˆ²ä½ æ˜¯å°çš„。
你越確信自己是å°çš„(讓我們é¢å°ç¾å¯¦å§ï¼Œä½ å¯ä»¥æŠŠå¹¾ä¹Žæ‰€æœ‰äººéƒ½ç¨±çˆ²å£žäººï¼Œè€Œä¸”ä½ 
經常是å°çš„),事後é“歉就越難。
@@ -127,12 +127,12 @@ Linux內核管ç†é¢¨æ ¼
è¦è§£æ±ºæ­¤å•é¡Œï¼Œæ‚¨å¯¦éš›ä¸Šåªæœ‰å…©å€‹é¸é …:
- éžå¸¸æ“…é•·é“æ­‰
- - 把「愛ã€å‡å‹»åœ°æ•£é–‹ï¼Œæ²’有人會真正感覺到自己被ä¸å…¬å¹³åœ°çž„準了。讓它有足夠的
+ - 把“愛â€å‡å‹»åœ°æ•£é–‹ï¼Œæ²’有人會真正感覺到自己被ä¸å…¬å¹³åœ°çž„準了。讓它有足夠的
創造性,他們甚至å¯èƒ½æœƒè¦ºå¾—好笑。
é¸æ“‡æ°¸é ä¿æŒç¦®è²Œæ˜¯ä¸å­˜åœ¨çš„。沒有人會相信一個如此明顯地隱è—了他們真實性格的人。
-.. [#cnf2] ä¿ç¾…·西蒙演唱了「離開愛人的50種方法ã€ï¼Œå› çˆ²å¦çŽ‡åœ°èªªï¼Œã€Œå‘Šè¨´é–‹ç™¼è€…
+.. [#cnf2] ä¿ç¾…·西蒙演唱了“離開愛人的50種方法â€ï¼Œå› çˆ²å¦çŽ‡åœ°èªªï¼Œâ€œå‘Šè¨´é–‹ç™¼è€…
他們是D*CKHEAD" çš„100è¬ç¨®æ–¹æ³•éƒ½ç„¡æ³•ç¢ºèªã€‚但我確信他已經這麼想了。
3)人2 - 好人
@@ -148,8 +148,8 @@ Linux內核管ç†é¢¨æ ¼
特別是,他們能夠爲你åšæ±ºå®šï¼Œé€™å°±æ˜¯éŠæˆ²çš„全部內容。
所以當你發ç¾ä¸€å€‹æ¯”ä½ è°æ˜Žçš„人時,就順其自然å§ã€‚你的管ç†è·è²¬åœ¨å¾ˆå¤§ç¨‹åº¦ä¸Šè®Šæˆ
-了「è½èµ·ä¾†åƒæ˜¯å€‹å¥½ä¸»æ„——去嘗試å§ã€ï¼Œæˆ–者「è½èµ·ä¾†ä¸éŒ¯ï¼Œä½†æ˜¯XXX呢?ã€ã€Œã€‚第二個版
-本尤其是一個很好的方法,è¦éº¼å­¸ç¿’一些關於「XXXã€çš„æ–°æ±è¥¿ï¼Œè¦éº¼é€šéŽæŒ‡å‡ºä¸€äº›è°æ˜Ž
+了“è½èµ·ä¾†åƒæ˜¯å€‹å¥½ä¸»æ„——去嘗試å§â€ï¼Œæˆ–者“è½èµ·ä¾†ä¸éŒ¯ï¼Œä½†æ˜¯XXX呢?â€â€œã€‚第二個版
+本尤其是一個很好的方法,è¦éº¼å­¸ç¿’一些關於“XXXâ€çš„æ–°æ±è¥¿ï¼Œè¦éº¼é€šéŽæŒ‡å‡ºä¸€äº›è°æ˜Ž
人沒有想到的æ±è¥¿ä¾†é¡¯å¾—更具管ç†æ€§ã€‚無論哪種情æ³ï¼Œä½ éƒ½æœƒè´ã€‚
è¦æ³¨æ„的一件事是èªè­˜åˆ°ä¸€å€‹é ˜åŸŸçš„å‰å¤§ä¸ä¸€å®šæœƒè½‰åŒ–爲其他領域。所以你å¯èƒ½æœƒå‘
@@ -172,22 +172,22 @@ Linux內核管ç†é¢¨æ ¼
他們也å¯èƒ½æ˜¯èƒ½å¤ è§£æ±ºå•é¡Œçš„人。因爲,讓我們é¢å°ç¾å¯¦å§ï¼Œè‚¯å®šä¸æ˜¯ä½ ã€‚
承擔責任也是你首先æˆçˆ²ç®¡ç†è€…的原因。這是讓人們信任你,讓你ç²å¾—潛在的榮耀的
-一部分,因爲你就是那個會說「我æžç ¸äº†ã€çš„人。如果你已經éµå¾ªäº†ä»¥å‰çš„è¦å‰‡ï¼Œä½ ç¾
+一部分,因爲你就是那個會說“我æžç ¸äº†â€çš„人。如果你已經éµå¾ªäº†ä»¥å‰çš„è¦å‰‡ï¼Œä½ ç¾
在已經很擅長說了。
5)應é¿å…的事情
---------------
-有一件事人們甚至比被稱爲「笨蛋ã€æ›´è¨ŽåŽ­ï¼Œé‚£å°±æ˜¯åœ¨ä¸€å€‹ç¥žè–çš„è²éŸ³ä¸­è¢«ç¨±çˆ²ã€Œç¬¨è›‹ã€ã€‚
+有一件事人們甚至比被稱爲“笨蛋â€æ›´è¨ŽåŽ­ï¼Œé‚£å°±æ˜¯åœ¨ä¸€å€‹ç¥žè–çš„è²éŸ³ä¸­è¢«ç¨±çˆ²â€œç¬¨è›‹â€ã€‚
第一個你å¯ä»¥é“歉,第二個你ä¸æœƒçœŸæ­£å¾—到機會。å³ä½¿ä½ åšå¾—很好,他們也å¯èƒ½ä¸å†
傾è½ã€‚
-我們都èªçˆ²è‡ªå·±æ¯”別人強,這æ„味著當別人è£è…”作勢時,這會讓我們很惱ç«ã€‚你也許
+我們都èªçˆ²è‡ªå·±æ¯”別人強,這æ„味ç€ç•¶åˆ¥äººè£è…”作勢時,這會讓我們很惱ç«ã€‚你也許
在é“德和智力上比你周åœçš„æ¯å€‹äººéƒ½å„ªè¶Šï¼Œä½†ä¸è¦è©¦åœ–太明顯,除éžä½ çœŸçš„打算激怒
æŸäºº [#cnf3]_
åŒæ¨£ï¼Œä¸è¦å°äº‹æƒ…太客氣或太微妙。禮貌很容易è½å¾—è½èŠ±æµæ°´ï¼ŒæŠŠå•é¡Œéš±è—起來,
-正如他們所說,「在網際網路上,沒人能è½åˆ°ä½ çš„å«è“„。ã€ç”¨ä¸€å€‹éˆå™¨æŠŠé€™ä¸€é»žéŒ˜é€²åŽ»ï¼Œ
+正如他們所說,“在互è¯ç¶²ä¸Šï¼Œæ²’人能è½åˆ°ä½ çš„å«è“„。â€ç”¨ä¸€å€‹éˆå™¨æŠŠé€™ä¸€é»žéŒ˜é€²åŽ»ï¼Œ
因爲你ä¸èƒ½çœŸçš„ä¾é åˆ¥äººä¾†ç²å¾—你的觀點。
一些幽默å¯ä»¥å¹«åŠ©ç·©å’Œç›´çŽ‡å’Œé“德化。éŽåº¦åˆ°è’謬的地步,å¯ä»¥çŒè¼¸ä¸€å€‹è§€é»žï¼Œè€Œä¸
@@ -203,8 +203,8 @@ Linux內核管ç†é¢¨æ ¼
既然你的主è¦è²¬ä»»ä¼¼ä¹Žæ˜¯çˆ²åˆ¥äººçš„錯誤承擔責任,並且讓別人痛苦地明白你是ä¸ç¨±è·
的,那麼顯而易見的å•é¡Œä¹‹ä¸€å°±è®Šæˆäº†çˆ²ä»€éº¼é¦–å…ˆè¦é€™æ¨£åšã€‚
-首先,雖然你å¯èƒ½æœƒæˆ–å¯èƒ½ä¸æœƒè½åˆ°å幾歲女孩(或男孩,讓我們ä¸è¦åœ¨é€™è£¡è©•åˆ¤æˆ–
-性別歧視)敲你的更衣室門,你會得到一個巨大的個人æˆå°±æ„Ÿçˆ²ã€Œè² è²¬ã€ã€‚別介æ„你真
+首先,雖然你å¯èƒ½æœƒæˆ–å¯èƒ½ä¸æœƒè½åˆ°å幾歲女孩(或男孩,讓我們ä¸è¦åœ¨é€™è£è©•åˆ¤æˆ–
+性別歧視)敲你的更衣室門,你會得到一個巨大的個人æˆå°±æ„Ÿçˆ²â€œè² è²¬â€ã€‚別介æ„你真
的在領導別人,你è¦è·Ÿä¸Šåˆ¥äººï¼Œå„˜å¯èƒ½å¿«åœ°è¿½è¶•ä»–們。æ¯å€‹äººéƒ½æœƒèªçˆ²ä½ æ˜¯è² è²¬äººã€‚
如果你å¯ä»¥åšåˆ°é€™å€‹ï¼Œ 這是個å‰å¤§çš„工作ï¼
diff --git a/Documentation/translations/zh_TW/process/stable-api-nonsense.rst b/Documentation/translations/zh_TW/process/stable-api-nonsense.rst
index 33fc85c2cc51..6839d25bb22a 100644
--- a/Documentation/translations/zh_TW/process/stable-api-nonsense.rst
+++ b/Documentation/translations/zh_TW/process/stable-api-nonsense.rst
@@ -17,45 +17,45 @@
Linux 內核驅動接å£
==================
-寫作本文檔的目的,是爲了解釋爲什麼Linux既沒有二進ä½å…§æ ¸æŽ¥å£ï¼Œä¹Ÿæ²’有穩定
-的內核接å£ã€‚這裡所說的內核接å£ï¼Œæ˜¯æŒ‡å…§æ ¸é‡Œçš„接å£ï¼Œè€Œä¸æ˜¯å…§æ ¸å’Œç”¨æˆ¶ç©ºé–“
-的接å£ã€‚內核到用戶空間的接å£ï¼Œæ˜¯æ供給應用程å¼ä½¿ç”¨çš„系統調用,系統調用
-在歷å²ä¸Šå¹¾ä¹Žæ²’有éŽè®ŠåŒ–,將來也ä¸æœƒæœ‰è®ŠåŒ–。我有一些è€æ‡‰ç”¨ç¨‹å¼æ˜¯åœ¨0.9版本
-或者更早版本的內核上編譯的,在使用2.6版本內核的Linux發布上ä¾ç„¶ç”¨å¾—很好
-。用戶和應用程å¼ä½œè€…å¯ä»¥å°‡é€™å€‹æŽ¥å£çœ‹æˆæ˜¯ç©©å®šçš„。
+寫作本文檔的目的,是爲了解釋爲什麼Linux既沒有二進制內核接å£ï¼Œä¹Ÿæ²’有穩定
+的內核接å£ã€‚這è£æ‰€èªªçš„內核接å£ï¼Œæ˜¯æŒ‡å…§æ ¸è£çš„接å£ï¼Œè€Œä¸æ˜¯å…§æ ¸å’Œç”¨æˆ¶ç©ºé–“
+的接å£ã€‚內核到用戶空間的接å£ï¼Œæ˜¯æ供給應用程åºä½¿ç”¨çš„系統調用,系統調用
+在歷å²ä¸Šå¹¾ä¹Žæ²’有éŽè®ŠåŒ–,將來也ä¸æœƒæœ‰è®ŠåŒ–。我有一些è€æ‡‰ç”¨ç¨‹åºæ˜¯åœ¨0.9版本
+或者更早版本的內核上編譯的,在使用2.6版本內核的Linux發佈上ä¾ç„¶ç”¨å¾—很好
+。用戶和應用程åºä½œè€…å¯ä»¥å°‡é€™å€‹æŽ¥å£çœ‹æˆæ˜¯ç©©å®šçš„。
執行綱è¦
--------
你也許以爲自己想è¦ç©©å®šçš„內核接å£ï¼Œä½†æ˜¯ä½ ä¸æ¸…楚你è¦çš„實際上ä¸æ˜¯å®ƒã€‚你需
-è¦çš„其實是穩定的驅動程åºï¼Œè€Œä½ åªæœ‰å°‡é©…動程åºæ”¾åˆ°å…¬ç‰ˆå…§æ ¸çš„原始碼樹里,
-æ‰æœ‰å¯èƒ½é”到這個目的。而且這樣åšé‚„有很多其它好處,正是因爲這些好處使得
-Linux能æˆçˆ²å¼·å£¯ï¼Œç©©å®šï¼Œæˆç†Ÿçš„作業系統,這也是你最開始é¸æ“‡Linux的原因。
+è¦çš„其實是穩定的驅動程åºï¼Œè€Œä½ åªæœ‰å°‡é©…動程åºæ”¾åˆ°å…¬ç‰ˆå…§æ ¸çš„æºä»£ç¢¼æ¨¹è£ï¼Œ
+纔有å¯èƒ½é”到這個目的。而且這樣åšé‚„有很多其它好處,正是因爲這些好處使得
+Linux能æˆçˆ²å¼·å£¯ï¼Œç©©å®šï¼Œæˆç†Ÿçš„æ“作系統,這也是你最開始é¸æ“‡Linux的原因。
入門
-----
-åªæœ‰é‚£äº›å¯«é©…動程åºçš„「怪人ã€æ‰æœƒæ“”心內核接å£çš„改變,å°å»£å¤§ç”¨æˆ¶ä¾†èªªï¼Œæ—¢
+åªæœ‰é‚£äº›å¯«é©…動程åºçš„“怪人â€çº”會擔心內核接å£çš„改變,å°å»£å¤§ç”¨æˆ¶ä¾†èªªï¼Œæ—¢
看ä¸åˆ°å…§æ ¸æŽ¥å£ï¼Œä¹Ÿä¸éœ€è¦åŽ»é—œå¿ƒå®ƒã€‚
首先,我ä¸æ‰“算討論關於任何éžGPL許å¯çš„內核驅動的法律å•é¡Œï¼Œé€™äº›éžGPL許å¯
-的驅動程åºåŒ…括ä¸å…¬é–‹åŽŸå§‹ç¢¼ï¼Œéš±è—原始碼,二進ä½æˆ–者是用原始碼包è£ï¼Œæˆ–者
-是其它任何形å¼çš„ä¸èƒ½ä»¥GPL許å¯å…¬é–‹åŽŸå§‹ç¢¼çš„驅動程åºã€‚如果有法律å•é¡Œï¼Œè«‹å’¨
-詢律師,我åªæ˜¯ä¸€å€‹ç¨‹å¼è¨­è¨ˆå¸«ï¼Œæ‰€ä»¥æˆ‘åªæ‰“算探討技術å•é¡Œï¼ˆä¸æ˜¯å°çœ‹æ³•å¾‹å•é¡Œï¼Œ
+的驅動程åºåŒ…括ä¸å…¬é–‹æºä»£ç¢¼ï¼Œéš±è—æºä»£ç¢¼ï¼ŒäºŒé€²åˆ¶æˆ–者是用æºä»£ç¢¼åŒ…è£ï¼Œæˆ–者
+是其它任何形å¼çš„ä¸èƒ½ä»¥GPL許å¯å…¬é–‹æºä»£ç¢¼çš„驅動程åºã€‚如果有法律å•é¡Œï¼Œè«‹è«®
+詢律師,我åªæ˜¯ä¸€å€‹ç¨‹åºå“¡ï¼Œæ‰€ä»¥æˆ‘åªæ‰“算探討技術å•é¡Œï¼ˆä¸æ˜¯å°çœ‹æ³•å¾‹å•é¡Œï¼Œ
法律å•é¡Œå¾ˆå¯¦éš›ï¼Œä¸¦ä¸”需è¦ä¸€ç›´é—œæ³¨ï¼‰ã€‚
-既然åªè«‡æŠ€è¡“å•é¡Œï¼Œæˆ‘們就有了下é¢å…©å€‹ä¸»é¡Œï¼šäºŒé€²ä½å…§æ ¸æŽ¥å£å’Œç©©å®šçš„內核æº
-代碼接å£ã€‚這兩個å•é¡Œæ˜¯äº’相關è¯çš„,讓我們先解決掉二進ä½æŽ¥å£çš„å•é¡Œã€‚
+既然åªè«‡æŠ€è¡“å•é¡Œï¼Œæˆ‘們就有了下é¢å…©å€‹ä¸»é¡Œï¼šäºŒé€²åˆ¶å…§æ ¸æŽ¥å£å’Œç©©å®šçš„內核æº
+代碼接å£ã€‚這兩個å•é¡Œæ˜¯äº’相關è¯çš„,讓我們先解決掉二進制接å£çš„å•é¡Œã€‚
-二進ä½å…§æ ¸æŽ¥å£
+二進制內核接å£
--------------
-å‡å¦‚我們有一個穩定的內核原始碼接å£ï¼Œé‚£éº¼è‡ªç„¶è€Œç„¶çš„,我們就æ“有了穩定的
-二進ä½æŽ¥å£ï¼Œæ˜¯é€™æ¨£çš„嗎?錯。讓我們看看關於Linux內核的幾點事實:
+å‡å¦‚我們有一個穩定的內核æºä»£ç¢¼æŽ¥å£ï¼Œé‚£éº¼è‡ªç„¶è€Œç„¶çš„,我們就æ“有了穩定的
+二進制接å£ï¼Œæ˜¯é€™æ¨£çš„嗎?錯。讓我們看看關於Linux內核的幾點事實:
- - å–決於所用的C編譯器的版本,ä¸åŒçš„內核數據çµæ§‹é‡Œçš„çµæ§‹é«”çš„å°é½Šæ–¹
+ - å–決於所用的C編譯器的版本,ä¸åŒçš„內核數據çµæ§‹è£çš„çµæ§‹é«”çš„å°é½Šæ–¹
å¼æœƒæœ‰å·®åˆ¥ï¼Œä»£ç¢¼ä¸­ä¸åŒå‡½æ•¸çš„表ç¾å½¢å¼ä¹Ÿä¸ä¸€æ¨£ï¼ˆå‡½æ•¸æ˜¯ä¸æ˜¯è¢«inline
編譯å–決於編譯器行爲)。ä¸åŒçš„函數的表ç¾å½¢å¼ä¸¦ä¸é‡è¦ï¼Œä½†æ˜¯æ•¸æ“š
çµæ§‹å…§éƒ¨çš„å°é½Šæ–¹å¼å¾ˆé—œéµã€‚
@@ -69,33 +69,33 @@ Linux能æˆçˆ²å¼·å£¯ï¼Œç©©å®šï¼Œæˆç†Ÿçš„作業系統,這也是你最開始é¸
項。
- Linuxå¯ä»¥åœ¨å¾ˆå¤šçš„ä¸åŒé«”ç³»çµæ§‹çš„處ç†å™¨ä¸Šé‹è¡Œã€‚在æŸå€‹é«”ç³»çµæ§‹ä¸Šç·¨
- 譯好的二進ä½é©…動程åºï¼Œä¸å¯èƒ½åœ¨å¦å¤–一個體系çµæ§‹ä¸Šæ­£ç¢ºçš„é‹è¡Œã€‚
+ 譯好的二進制驅動程åºï¼Œä¸å¯èƒ½åœ¨å¦å¤–一個體繫çµæ§‹ä¸Šæ­£ç¢ºçš„é‹è¡Œã€‚
å°æ–¼ä¸€å€‹ç‰¹å®šçš„內核,滿足這些æ¢ä»¶ä¸¦ä¸é›£ï¼Œä½¿ç”¨åŒä¸€å€‹C編譯器和åŒæ¨£çš„內核é…
-ç½®é¸é …來編譯驅動程åºæ¨¡å¡Šå°±å¯ä»¥äº†ã€‚這å°æ–¼çµ¦ä¸€å€‹ç‰¹å®šLinux發布的特定版本æ
-供驅動程åºï¼Œæ˜¯å®Œå…¨å¯ä»¥æ»¿è¶³éœ€æ±‚的。但是如果你è¦çµ¦ä¸åŒç™¼å¸ƒçš„ä¸åŒç‰ˆæœ¬éƒ½ç™¼
-布一個驅動程åºï¼Œå°±éœ€è¦åœ¨æ¯å€‹ç™¼å¸ƒä¸Šç”¨ä¸åŒçš„內核設置åƒæ•¸éƒ½ç·¨è­¯ä¸€æ¬¡å…§æ ¸ï¼Œ
-這簡直跟噩夢一樣。而且還è¦æ³¨æ„到,æ¯å€‹Linux發布還æä¾›ä¸åŒçš„Linux內核,
-這些內核都é‡å°ä¸åŒçš„硬體類型進行了優化(有很多種ä¸åŒçš„處ç†å™¨ï¼Œé‚„有ä¸åŒ
-的內核設置é¸é …)。所以æ¯ç™¼å¸ƒä¸€æ¬¡é©…動程åºï¼Œéƒ½éœ€è¦æ供很多ä¸åŒç‰ˆæœ¬çš„內核
+ç½®é¸é …來編譯驅動程åºæ¨¡å¡Šå°±å¯ä»¥äº†ã€‚這å°æ–¼çµ¦ä¸€å€‹ç‰¹å®šLinux發佈的特定版本æ
+供驅動程åºï¼Œæ˜¯å®Œå…¨å¯ä»¥æ»¿è¶³éœ€æ±‚的。但是如果你è¦çµ¦ä¸åŒç™¼ä½ˆçš„ä¸åŒç‰ˆæœ¬éƒ½ç™¼
+佈一個驅動程åºï¼Œå°±éœ€è¦åœ¨æ¯å€‹ç™¼ä½ˆä¸Šç”¨ä¸åŒçš„內核設置åƒæ•¸éƒ½ç·¨è­¯ä¸€æ¬¡å…§æ ¸ï¼Œ
+這簡直跟噩夢一樣。而且還è¦æ³¨æ„到,æ¯å€‹Linux發佈還æä¾›ä¸åŒçš„Linux內核,
+這些內核都é‡å°ä¸åŒçš„硬件類型進行了優化(有很多種ä¸åŒçš„處ç†å™¨ï¼Œé‚„有ä¸åŒ
+的內核設置é¸é …)。所以æ¯ç™¼ä½ˆä¸€æ¬¡é©…動程åºï¼Œéƒ½éœ€è¦æ供很多ä¸åŒç‰ˆæœ¬çš„內核
模塊。
-相信我,如果你真的è¦æŽ¡å–這種發布方å¼ï¼Œä¸€å®šæœƒæ…¢æ…¢ç˜‹æŽ‰ï¼Œæˆ‘很久以å‰å°±æœ‰éŽ
+相信我,如果你真的è¦æŽ¡å–這種發佈方å¼ï¼Œä¸€å®šæœƒæ…¢æ…¢ç˜‹æŽ‰ï¼Œæˆ‘很久以å‰å°±æœ‰éŽ
深刻的教訓...
-穩定的內核原始碼接å£
+穩定的內核æºä»£ç¢¼æŽ¥å£
--------------------
-如果有人ä¸å°‡ä»–的內核驅動程åºï¼Œæ”¾å…¥å…¬ç‰ˆå…§æ ¸çš„原始碼樹,而åˆæƒ³è®“驅動程åº
+如果有人ä¸å°‡ä»–的內核驅動程åºï¼Œæ”¾å…¥å…¬ç‰ˆå…§æ ¸çš„æºä»£ç¢¼æ¨¹ï¼Œè€Œåˆæƒ³è®“驅動程åº
一直ä¿æŒåœ¨æœ€æ–°çš„內核中å¯ç”¨ï¼Œé‚£éº¼é€™å€‹è©±é¡Œå°‡æœƒè®Šå¾—沒完沒了。
內核開發是æŒçºŒè€Œä¸”快節å¥çš„,從來都ä¸æœƒæ…¢ä¸‹ä¾†ã€‚內核開發人員在當å‰æŽ¥å£ä¸­
找到bug,或者找到更好的實ç¾æ–¹å¼ã€‚一旦發ç¾é€™äº›ï¼Œä»–們就很快會去修改當å‰çš„
-接å£ã€‚修改接å£æ„味著,函數åå¯èƒ½æœƒæ”¹è®Šï¼Œçµæ§‹é«”å¯èƒ½è¢«æ“´å……或者刪減,函數
+接å£ã€‚修改接å£æ„味ç€ï¼Œå‡½æ•¸åå¯èƒ½æœƒæ”¹è®Šï¼Œçµæ§‹é«”å¯èƒ½è¢«æ“´å……或者刪減,函數
çš„åƒæ•¸ä¹Ÿå¯èƒ½ç™¼ç”Ÿæ”¹è®Šã€‚一旦接å£è¢«ä¿®æ”¹ï¼Œå…§æ ¸ä¸­ä½¿ç”¨é€™äº›æŽ¥å£çš„地方需è¦åŒæ™‚
修正,這樣æ‰èƒ½ä¿è­‰æ‰€æœ‰çš„æ±è¥¿ç¹¼çºŒå·¥ä½œã€‚
-舉一個例å­ï¼Œå…§æ ¸çš„USB驅動程åºæŽ¥å£åœ¨USBå­ç³»çµ±çš„整個生命周期中,至少經歷
+舉一個例å­ï¼Œå…§æ ¸çš„USB驅動程åºæŽ¥å£åœ¨USBå­ç³»çµ±çš„整個生命週期中,至少經歷
了三次é‡å¯«ã€‚這些é‡å¯«è§£æ±ºä»¥ä¸‹å•é¡Œï¼š
- 把數據æµå¾žåŒæ­¥æ¨¡å¼æ”¹æˆéžåŒæ­¥æ¨¡å¼ï¼Œé€™å€‹æ”¹å‹•æ¸›å°‘了一些驅動程åºçš„
@@ -104,11 +104,11 @@ Linux能æˆçˆ²å¼·å£¯ï¼Œç©©å®šï¼Œæˆç†Ÿçš„作業系統,這也是你最開始é¸
- 修改了USB核心代碼中爲USB驅動分é…數據包內存的方å¼ï¼Œæ‰€æœ‰çš„驅動都
需è¦æ供更多的åƒæ•¸çµ¦USB核心,以修正了很多已經被記錄在案的死鎖。
-這和一些å°é–‰åŽŸå§‹ç¢¼çš„作業系統形æˆé®®æ˜Žçš„å°æ¯”,在那些作業系統上,ä¸å¾—ä¸é¡
+這和一些å°é–‰æºä»£ç¢¼çš„æ“作系統形æˆé®®æ˜Žçš„å°æ¯”,在那些æ“作系統上,ä¸å¾—ä¸é¡
外的維護舊的USB接å£ã€‚這導致了一個å¯èƒ½æ€§ï¼Œæ–°çš„開發者ä¾ç„¶æœƒä¸å°å¿ƒä½¿ç”¨èˆŠçš„
-接å£ï¼Œä»¥ä¸æ°ç•¶çš„æ–¹å¼ç·¨å¯«ä»£ç¢¼ï¼Œé€²è€Œå½±éŸ¿åˆ°ä½œæ¥­ç³»çµ±çš„穩定性。
+接å£ï¼Œä»¥ä¸æ°ç•¶çš„æ–¹å¼ç·¨å¯«ä»£ç¢¼ï¼Œé€²è€Œå½±éŸ¿åˆ°æ“作系統的穩定性。
在上é¢çš„例å­ä¸­ï¼Œæ‰€æœ‰çš„開發者都åŒæ„這些é‡è¦çš„改動,在這樣的情æ³ä¸‹ä¿®æ”¹ä»£
-價很低。如果Linuxä¿æŒä¸€å€‹ç©©å®šçš„內核原始碼接å£ï¼Œé‚£éº¼å°±å¾—創建一個新的接å£
+價很低。如果Linuxä¿æŒä¸€å€‹ç©©å®šçš„內核æºä»£ç¢¼æŽ¥å£ï¼Œé‚£éº¼å°±å¾—創建一個新的接å£
;舊的,有å•é¡Œçš„接å£å¿…須一直維護,給Linux USB開發者帶來é¡å¤–的工作。既然
所有的Linux USB驅動的作者都是利用自己的時間工作,那麼è¦æ±‚他們去åšæ¯«ç„¡æ„
義的å…è²»é¡å¤–工作,是ä¸å¯èƒ½çš„。
@@ -126,28 +126,28 @@ Linux能æˆçˆ²å¼·å£¯ï¼Œç©©å®šï¼Œæˆç†Ÿçš„作業系統,這也是你最開始é¸
è¦åšä»€éº¼
--------
-如果你寫了一個Linux內核驅動,但是它還ä¸åœ¨Linux原始碼樹里,作爲一個開發
-者,你應該怎麼åšï¼Ÿçˆ²æ¯å€‹ç™¼å¸ƒçš„æ¯å€‹ç‰ˆæœ¬æ供一個二進ä½é©…動,那簡直是一個
+如果你寫了一個Linux內核驅動,但是它還ä¸åœ¨Linuxæºä»£ç¢¼æ¨¹è£ï¼Œä½œçˆ²ä¸€å€‹é–‹ç™¼
+者,你應該怎麼åšï¼Ÿçˆ²æ¯å€‹ç™¼ä½ˆçš„æ¯å€‹ç‰ˆæœ¬æ供一個二進制驅動,那簡直是一個
噩夢,è¦è·Ÿä¸Šæ°¸é è™•æ–¼è®ŠåŒ–之中的內核接å£ï¼Œä¹Ÿæ˜¯ä¸€ä»¶è¾›è‹¦æ´»ã€‚
-很簡單,讓你的驅動進入內核原始碼樹(è¦è¨˜å¾—我們在談論的是以GPL許å¯ç™¼è¡Œ
+很簡單,讓你的驅動進入內核æºä»£ç¢¼æ¨¹ï¼ˆè¦è¨˜å¾—我們在談論的是以GPL許å¯ç™¼è¡Œ
的驅動,如果你的代碼ä¸ç¬¦åˆGPL,那麼ç¥ä½ å¥½é‹ï¼Œä½ åªèƒ½è‡ªå·±è§£æ±ºé€™å€‹å•é¡Œäº†ï¼Œ
-你這個å¸è¡€é¬¼<把Andrewå’ŒLinuså°å¸è¡€é¬¼çš„定義連çµåˆ°é€™è£¡>)。當你的代碼加入
-公版內核原始碼樹之後,如果一個內核接å£æ”¹è®Šï¼Œä½ çš„驅動會直接被修改接å£çš„
+你這個å¸è¡€é¬¼<把Andrewå’ŒLinuså°å¸è¡€é¬¼çš„定義éˆæŽ¥åˆ°é€™è£>)。當你的代碼加入
+公版內核æºä»£ç¢¼æ¨¹ä¹‹å¾Œï¼Œå¦‚果一個內核接å£æ”¹è®Šï¼Œä½ çš„驅動會直接被修改接å£çš„
那個人修改。ä¿è­‰ä½ çš„é©…å‹•æ°¸é éƒ½å¯ä»¥ç·¨è­¯é€šéŽï¼Œä¸¦ä¸”一直工作,你幾乎ä¸éœ€è¦
åšä»€éº¼äº‹æƒ…。
-把驅動放到內核原始碼樹里會有很多的好處:
+把驅動放到內核æºä»£ç¢¼æ¨¹è£æœƒæœ‰å¾ˆå¤šçš„好處:
- 驅動的質é‡æœƒæå‡ï¼Œè€Œç¶­è­·æˆæœ¬ï¼ˆå°åŽŸå§‹ä½œè€…來說)會下é™ã€‚
- 其他人會給驅動添加新特性。
- 其他人會找到驅動中的bug並修復。
- 其他人會在驅動中找到性能優化的機會。
- 當外部的接å£çš„改變需è¦ä¿®æ”¹é©…動程åºçš„時候,其他人會修改驅動程åº
- - ä¸éœ€è¦è¯ç¹«ä»»ä½•ç™¼è¡Œå•†ï¼Œé€™å€‹é©…動會自動的隨著所有的Linux發布一起發
+ - ä¸éœ€è¦è¯ç¹«ä»»ä½•ç™¼è¡Œå•†ï¼Œé€™å€‹é©…動會自動的隨ç€æ‰€æœ‰çš„Linux發佈一起發
布。
-和別的作業系統相比,Linux爲更多ä¸åŒçš„設備æä¾›ç¾æˆçš„驅動,而且能在更多ä¸
-åŒé«”ç³»çµæ§‹çš„處ç†å™¨ä¸Šæ”¯æŒé€™äº›è¨­å‚™ã€‚這個經éŽè€ƒé©—的開發模å¼ï¼Œå¿…然是錯ä¸äº†
+和別的æ“作系統相比,Linux爲更多ä¸åŒçš„設備æä¾›ç¾æˆçš„驅動,而且能在更多ä¸
+åŒé«”繫çµæ§‹çš„處ç†å™¨ä¸Šæ”¯æŒé€™äº›è¨­å‚™ã€‚這個經éŽè€ƒé©—的開發模å¼ï¼Œå¿…然是錯ä¸äº†
çš„ :)
æ„Ÿè¬
diff --git a/Documentation/translations/zh_TW/process/stable-kernel-rules.rst b/Documentation/translations/zh_TW/process/stable-kernel-rules.rst
index 29d9a70a1868..bd82a8ff3969 100644
--- a/Documentation/translations/zh_TW/process/stable-kernel-rules.rst
+++ b/Documentation/translations/zh_TW/process/stable-kernel-rules.rst
@@ -17,10 +17,10 @@
- Kangkai Yin <e12051@motorola.com>
- 胡皓文 Hu Haowen <src.res.211@gmail.com>
-所有你想知é“的事情 - 關於linux穩定版發布
+所有你想知é“的事情 - 關於linux穩定版發佈
========================================
-關於Linux 2.6穩定版發布,所有你想知é“的事情。
+關於Linux 2.6穩定版發佈,所有你想知é“的事情。
關於哪些類型的補ä¸å¯ä»¥è¢«æŽ¥æ”¶é€²å…¥ç©©å®šç‰ˆä»£ç¢¼æ¨¹ï¼Œå“ªäº›ä¸å¯ä»¥çš„è¦å‰‡ï¼š
----------------------------------------------------------------
@@ -28,39 +28,39 @@
- 必須是顯而易見的正確,並且經éŽæ¸¬è©¦çš„。
- 連åŒä¸Šä¸‹æ–‡ï¼Œä¸èƒ½å¤§æ–¼100行。
- å¿…é ˆåªä¿®æ­£ä¸€ä»¶äº‹æƒ…。
- - 必須修正了一個給大家帶來麻煩的真正的bug(ä¸æ˜¯ã€Œé€™ä¹Ÿè¨±æ˜¯ä¸€å€‹å•é¡Œ...ã€
+ - 必須修正了一個給大家帶來麻煩的真正的bug(ä¸æ˜¯â€œé€™ä¹Ÿè¨±æ˜¯ä¸€å€‹å•é¡Œ...â€
那樣的æ±è¥¿ï¼‰ã€‚
- 必須修正帶來如下後果的å•é¡Œï¼šç·¨è­¯éŒ¯èª¤ï¼ˆå°è¢«æ¨™è¨˜çˆ²CONFIG_BROKEN的例外),
- 內核崩潰,掛起,數據æ壞,真正的安全å•é¡Œï¼Œæˆ–者一些類似「哦,這ä¸
- 好ã€çš„å•é¡Œã€‚簡短的說,就是一些致命的å•é¡Œã€‚
- - 沒有「ç†è«–上的競爭æ¢ä»¶ã€ï¼Œé™¤éžèƒ½çµ¦å‡ºç«¶çˆ­æ¢ä»¶å¦‚何被利用的解釋。
- - ä¸èƒ½å­˜åœ¨ä»»ä½•çš„「瑣碎的ã€ä¿®æ­£ï¼ˆæ‹¼å¯«ä¿®æ­£ï¼ŒåŽ»æŽ‰å¤šé¤˜ç©ºæ ¼ä¹‹é¡žçš„)。
+ 內核崩潰,掛起,數據æ壞,真正的安全å•é¡Œï¼Œæˆ–者一些類似“哦,這ä¸
+ 好â€çš„å•é¡Œã€‚簡短的說,就是一些致命的å•é¡Œã€‚
+ - 沒有“ç†è«–上的競爭æ¢ä»¶â€ï¼Œé™¤éžèƒ½çµ¦å‡ºç«¶çˆ­æ¢ä»¶å¦‚何被利用的解釋。
+ - ä¸èƒ½å­˜åœ¨ä»»ä½•çš„“瑣碎的â€ä¿®æ­£ï¼ˆæ‹¼å¯«ä¿®æ­£ï¼ŒåŽ»æŽ‰å¤šé¤˜ç©ºæ ¼ä¹‹é¡žçš„)。
- 必須被相關å­ç³»çµ±çš„維護者接å—。
- - å¿…é ˆéµå¾ªDocumentation/translations/zh_TW/process/submitting-patches.rst里的è¦å‰‡ã€‚
+ - å¿…é ˆéµå¾ªDocumentation/translations/zh_CN/process/submitting-patches.rstè£çš„è¦å‰‡ã€‚
å‘穩定版代碼樹æ交補ä¸çš„éŽç¨‹ï¼š
------------------------------
- 在確èªäº†è£œä¸ç¬¦åˆä»¥ä¸Šçš„è¦å‰‡å¾Œï¼Œå°‡è£œä¸ç™¼é€åˆ°stable@vger.kernel.org。
- - 如果補ä¸è¢«æŽ¥å—到隊列里,發é€è€…會收到一個ACK回復,如果沒有被接å—,收
- 到的是NAK回復。回復需è¦å¹¾å¤©çš„時間,這å–決於開發者的時間安排。
- - 被接å—的補ä¸æœƒè¢«åŠ åˆ°ç©©å®šç‰ˆæœ¬éšŠåˆ—里,等待其他開發者的審查。
+ - 如果補ä¸è¢«æŽ¥å—到隊列è£ï¼Œç™¼é€è€…會收到一個ACK回覆,如果沒有被接å—,收
+ 到的是NAK回覆。回覆需è¦å¹¾å¤©çš„時間,這å–決於開發者的時間安排。
+ - 被接å—的補ä¸æœƒè¢«åŠ åˆ°ç©©å®šç‰ˆæœ¬éšŠåˆ—è£ï¼Œç­‰å¾…其他開發者的審查。
- 安全方é¢çš„補ä¸ä¸è¦ç™¼åˆ°é€™å€‹åˆ—表,應該發é€åˆ°security@kernel.org。
-審查周期:
+審查週期:
----------
- - 當穩定版的維護者決定開始一個審查周期,補ä¸å°‡è¢«ç™¼é€åˆ°å¯©æŸ¥å§”員會,以
+ - 當穩定版的維護者決定開始一個審查週期,補ä¸å°‡è¢«é«®é€åˆ°å¯©æŸ¥å§”員會,以
åŠè¢«è£œä¸å½±éŸ¿çš„領域的維護者(除éžæ交者就是該領域的維護者)並且抄é€
到linux-kernel郵件列表。
- - 審查委員會有48å°æ™‚的時間,用來決定給該補ä¸å›žå¾©ACK還是NAK。
+ - 審查委員會有48å°æ™‚的時間,用來決定給該補ä¸å›žè¦†ACK還是NAK。
- 如果委員會中有æˆå“¡æ‹’絕這個補ä¸ï¼Œæˆ–者linux-kernel列表上有人åå°é€™å€‹
補ä¸ï¼Œä¸¦æ出維護者和審查委員會之å‰æ²’有æ„識到的å•é¡Œï¼Œè£œä¸æœƒå¾žéšŠåˆ—中
丟棄。
- - 在審查周期çµæŸçš„時候,那些得到ACK回應的補ä¸å°‡æœƒè¢«åŠ å…¥åˆ°æœ€æ–°çš„穩定版
- 發布中,一個新的穩定版發布就此產生。
- - 安全性補ä¸å°‡å¾žå…§æ ¸å®‰å…¨å°çµ„那裡直接接收到穩定版代碼樹中,而ä¸æ˜¯é€šéŽ
- 通常的審查周期。請è¯ç¹«å…§æ ¸å®‰å…¨å°çµ„以ç²å¾—關於這個éŽç¨‹çš„更多細節。
+ - 在審查週期çµæŸçš„時候,那些得到ACK回應的補ä¸å°‡æœƒè¢«åŠ å…¥åˆ°æœ€æ–°çš„穩定版
+ 發佈中,一個新的穩定版發佈就此產生。
+ - 安全性補ä¸å°‡å¾žå…§æ ¸å®‰å…¨å°çµ„é‚£è£ç›´æŽ¥æŽ¥æ”¶åˆ°ç©©å®šç‰ˆä»£ç¢¼æ¨¹ä¸­ï¼Œè€Œä¸æ˜¯é€šéŽ
+ 通常的審查週期。請è¯ç¹«å…§æ ¸å®‰å…¨å°çµ„以ç²å¾—關於這個éŽç¨‹çš„更多細節。
審查委員會:
------------
diff --git a/Documentation/translations/zh_TW/process/submit-checklist.rst b/Documentation/translations/zh_TW/process/submit-checklist.rst
index 12bf6f5ca5c6..942962d1e2f4 100644
--- a/Documentation/translations/zh_TW/process/submit-checklist.rst
+++ b/Documentation/translations/zh_TW/process/submit-checklist.rst
@@ -2,108 +2,114 @@
.. include:: ../disclaimer-zh_TW.rst
-:Original: :ref:`Documentation/process/submit-checklist.rst <submitchecklist>`
-:Translator: Alex Shi <alex.shi@linux.alibaba.com>
- Hu Haowen <src.res.211@gmail.com>
+:Original: Documentation/process/submit-checklist.rst
+:Translator:
+ - Alex Shi <alexs@kernel.org>
+ - Wu XiangCheng <bobwxc@email.cn>
+ - Hu Haowen <src.res.211@gmail.com>
.. _tw_submitchecklist:
-Linux內核補ä¸æ交清單
-~~~~~~~~~~~~~~~~~~~~~
+Linux內核補ä¸æ交檢查單
+~~~~~~~~~~~~~~~~~~~~~~~
如果開發人員希望看到他們的內核補ä¸æ交更快地被接å—,那麼他們應該åšä¸€äº›åŸºæœ¬
的事情。
-這些都是在
-:ref:`Documentation/translations/zh_TW/process/submitting-patches.rst <tw_submittingpatches>`
+這些都是在 Documentation/translations/zh_CN/process/submitting-patches.rst
和其他有關æ交Linux內核補ä¸çš„文檔中æ供的。
-1) 如果使用工具,則包括定義/è²æ˜Žè©²å·¥å…·çš„文件。ä¸è¦ä¾è³´æ–¼å…¶ä»–頭文件拉入您使用
+1) 如果使用工具,則包括定義/è²æ˜Žè©²å·¥å…·çš„文件。ä¸è¦ä¾è³´å…¶ä»–頭文件來引入您使用
的頭文件。
2) 乾淨的編譯:
- a) 使用é©ç”¨æˆ–修改的 ``CONFIG`` é¸é … ``=y``ã€``=m`` å’Œ ``=n`` 。沒有GCC
- 警告/錯誤,沒有連çµå™¨è­¦å‘Š/錯誤。
+ a) 使用åˆé©çš„ ``CONFIG`` é¸é … ``=y``ã€``=m`` å’Œ ``=n`` 。沒有 ``gcc``
+ 警告/錯誤,沒有éˆæŽ¥å™¨è­¦å‘Š/錯誤。
- b) 通éŽallnoconfigã€allmodconfig
+ b) é€šéŽ ``allnoconfig`` 〠``allmodconfig``
c) 使用 ``O=builddir`` 時å¯ä»¥æˆåŠŸç·¨è­¯
-3) 通éŽä½¿ç”¨æœ¬åœ°äº¤å‰ç·¨è­¯å·¥å…·æˆ–其他一些構建場在多個CPU體系çµæ§‹ä¸Šæ§‹å»ºã€‚
+ d) 任何 Doucmentation/ 下的變更都能æˆåŠŸæ§‹å»ºä¸”ä¸å¼•å…¥æ–°è­¦å‘Š/錯誤。
+ 用 ``make htmldocs`` 或 ``make pdfdocs`` 檢驗構建情æ³ä¸¦ä¿®å¾©å•é¡Œã€‚
+
+3) 通éŽä½¿ç”¨æœ¬åœ°äº¤å‰ç·¨è­¯å·¥å…·æˆ–其他一些構建設施在多個CPU體系çµæ§‹ä¸Šæ§‹å»ºã€‚
4) PPC64是一種很好的交å‰ç·¨è­¯æª¢æŸ¥é«”ç³»çµæ§‹ï¼Œå› çˆ²å®ƒå‚¾å‘æ–¼å°64ä½çš„數使用無符號
長整型。
-5) 如下所述 :ref:`Documentation/translations/zh_TW/process/coding-style.rst <tw_codingstyle>`.
- 檢查您的補ä¸æ˜¯å¦çˆ²å¸¸è¦æ¨£å¼ã€‚在æ交( ``scripts/check patch.pl`` )之å‰ï¼Œ
- 使用補ä¸æ¨£å¼æª¢æŸ¥å™¨æª¢æŸ¥æ˜¯å¦æœ‰è¼•å¾®çš„è¡çªã€‚您應該能夠處ç†æ‚¨çš„補ä¸ä¸­å­˜åœ¨çš„所有
+5) 按 Documentation/translations/zh_CN/process/coding-style.rst 所述檢查您的
+ 補ä¸æ˜¯å¦çˆ²å¸¸è¦æ¨£å¼ã€‚在æ交之å‰ä½¿ç”¨è£œä¸æ¨£å¼æª¢æŸ¥å™¨ ``scripts/checkpatch.pl``
+ 檢查是å¦æœ‰è¼•å¾®çš„è¡çªã€‚您應該能夠處ç†æ‚¨çš„補ä¸ä¸­å­˜åœ¨çš„所有
é•è¦è¡Œçˆ²ã€‚
-6) 任何新的或修改éŽçš„ ``CONFIG`` é¸é …都ä¸æœƒå¼„é«’é…ç½®èœå–®ï¼Œä¸¦é»˜èªçˆ²é—œé–‰ï¼Œé™¤éž
- å®ƒå€‘ç¬¦åˆ ``Documentation/kbuild/kconfig-language.rst`` 中記錄的異常æ¢ä»¶,
- èœå–®å±¬æ€§ï¼šé»˜èªå€¼.
+6) 任何新的或修改éŽçš„ ``CONFIG`` é¸é …都ä¸æ‡‰æžäº‚é…ç½®èœå–®ï¼Œä¸¦é»˜èªçˆ²é—œé–‰ï¼Œé™¤éž
+ å®ƒå€‘ç¬¦åˆ ``Documentation/kbuild/kconfig-language.rst`` èœå–®å±¬æ€§ï¼šé»˜èªå€¼ä¸­
+ 記錄的例外æ¢ä»¶ã€‚
7) 所有新的 ``kconfig`` é¸é …都有幫助文本。
-8) 已仔細審查了相關的 ``Kconfig`` 組åˆã€‚這很難用測試來糾正——腦力在這裡是有
+8) 已仔細審查了相關的 ``Kconfig`` 組åˆã€‚這很難用測試來糾正——腦力在這è£æ˜¯æœ‰
回報的。
-9) 用 sparse 檢查乾淨。
+9) é€šéŽ sparse 清查。
+ (åƒè¦‹ Documentation/translations/zh_CN/dev-tools/sparse.rst )
10) 使用 ``make checkstack`` å’Œ ``make namespacecheck`` 並修復他們發ç¾çš„任何
å•é¡Œã€‚
.. note::
- ``checkstack`` 並沒有明確指出å•é¡Œï¼Œä½†æ˜¯ä»»ä½•ä¸€å€‹åœ¨å †æ£§ä¸Šä½¿ç”¨è¶…éŽ512
+ ``checkstack`` 並ä¸æœƒæ˜Žç¢ºæŒ‡å‡ºå•é¡Œï¼Œä½†æ˜¯ä»»ä½•ä¸€å€‹åœ¨å †æ£§ä¸Šä½¿ç”¨è¶…éŽ512
字節的函數都å¯ä»¥é€²è¡Œæ›´æ”¹ã€‚
-11) 包括 :ref:`kernel-doc <kernel_doc>` 內核文檔以記錄全局內核API。(éœæ…‹å‡½æ•¸
- ä¸éœ€è¦ï¼Œä½†ä¹Ÿå¯ä»¥ã€‚)使用 ``make htmldocs`` 或 ``make pdfdocs`` 檢查
- :ref:`kernel-doc <kernel_doc>` 並修復任何å•é¡Œã€‚
+11) 包括 :ref:`kernel-doc <kernel_doc_zh>` 內核文檔以記錄全局內核API。(éœæ…‹
+ 函數ä¸éœ€è¦ï¼Œä½†ä¹Ÿå¯ä»¥ã€‚)使用 ``make htmldocs`` 或 ``make pdfdocs`` 檢查
+ :ref:`kernel-doc <kernel_doc_zh>` 並修復任何å•é¡Œã€‚
-12) 通éŽä»¥ä¸‹é¸é …åŒæ™‚啓用的測試 ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``,
+12) 通éŽä»¥ä¸‹é¸é …åŒæ™‚啓用的測試: ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``,
``CONFIG_DEBUG_SLAB``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``,
``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``,
- ``CONFIG_PROVE_RCU`` and ``CONFIG_DEBUG_OBJECTS_RCU_HEAD``
-
-13) 已經éŽæ§‹å»ºå’Œé‹è¡Œæ™‚測試,包括有或沒有 ``CONFIG_SMP``, ``CONFIG_PREEMPT``.
+ ``CONFIG_PROVE_RCU`` 和 ``CONFIG_DEBUG_OBJECTS_RCU_HEAD`` 。
-14) 如果補ä¸ç¨‹åºå½±éŸ¿IO/ç£ç¢Ÿç­‰ï¼šä½¿ç”¨æˆ–ä¸ä½¿ç”¨ ``CONFIG_LBDAF`` 進行測試。
+13) 在 ``CONFIG_SMP``, ``CONFIG_PREEMPT`` 開啓和關閉的情æ³ä¸‹éƒ½é€²è¡Œæ§‹å»ºå’Œé‹è¡Œ
+ 時測試。
-15) 所有代碼路徑都已在啓用所有lockdep功能的情æ³ä¸‹é‹è¡Œã€‚
+14) 所有代碼路徑都已在啓用所有死鎖檢測(lockdep)功能的情æ³ä¸‹é‹è¡Œã€‚
-16) 所有新的/procæ¢ç›®éƒ½è¨˜éŒ„在 ``Documentation/``
+15) 所有新的 ``/proc`` æ¢ç›®éƒ½è¨˜éŒ„在 ``Documentation/``
-17) 所有新的內核引導åƒæ•¸éƒ½è¨˜éŒ„在
+16) 所有新的內核引導åƒæ•¸éƒ½è¨˜éŒ„在
Documentation/admin-guide/kernel-parameters.rst 中。
-18) 所有新的模塊åƒæ•¸éƒ½è¨˜éŒ„在 ``MODULE_PARM_DESC()``
+17) 所有新的模塊åƒæ•¸éƒ½è¨˜éŒ„在 ``MODULE_PARM_DESC()``
-19) 所有新的用戶空間接å£éƒ½è¨˜éŒ„在 ``Documentation/ABI/`` 中。有關詳細信æ¯ï¼Œ
+18) 所有新的用戶空間接å£éƒ½è¨˜éŒ„在 ``Documentation/ABI/`` 中。有關詳細信æ¯ï¼Œ
è«‹åƒé–± ``Documentation/ABI/README`` 。更改用戶空間接å£çš„補ä¸æ‡‰è©²æŠ„é€
linux-api@vger.kernel.org。
-20) 已通éŽè‡³å°‘注入slabå’Œpage分é…失敗進行檢查。請åƒé–± ``Documentation/fault-injection/``
+19) 已通éŽè‡³å°‘注入slabå’Œpage分é…失敗進行檢查。請åƒé–± ``Documentation/fault-injection/`` 。
如果新代碼是實質性的,那麼添加å­ç³»çµ±ç‰¹å®šçš„故障注入å¯èƒ½æ˜¯åˆé©çš„。
-21) 新添加的代碼已經用 ``gcc -W`` 編譯(使用 ``make EXTRA-CFLAGS=-W`` )。這
- 將產生大é‡å™ªè²ï¼Œä½†å°æ–¼æŸ¥æ‰¾è«¸å¦‚「警告:有符號和無符號之間的比較ã€ä¹‹é¡žçš„錯誤
+20) 新添加的代碼已經用 ``gcc -W`` 編譯(使用 ``make EXTRA-CFLAGS=-W`` )。這
+ 將產生大é‡å™ªè²ï¼Œä½†å°æ–¼æŸ¥æ‰¾è«¸å¦‚“警告:有符號和無符號之間的比較â€ä¹‹é¡žçš„錯誤
很有用。
-22) 在它被åˆä½µåˆ°-mm補ä¸é›†ä¸­ä¹‹å¾Œé€²è¡Œæ¸¬è©¦ï¼Œä»¥ç¢ºä¿å®ƒä»ç„¶èˆ‡æ‰€æœ‰å…¶ä»–排隊的補ä¸ä»¥
+21) 在它被åˆä½µåˆ°-mm補ä¸é›†ä¸­ä¹‹å¾Œé€²è¡Œæ¸¬è©¦ï¼Œä»¥ç¢ºä¿å®ƒä»ç„¶èˆ‡æ‰€æœ‰å…¶ä»–排隊的補ä¸ä»¥
åŠVMã€VFS和其他å­ç³»çµ±ä¸­çš„å„種更改一起工作。
-23) 所有內存å±éšœä¾‹å¦‚ ``barrier()``, ``rmb()``, ``wmb()`` 都需è¦åŽŸå§‹ç¢¼ä¸­çš„注
+22) 所有內存å±éšœï¼ˆä¾‹å¦‚ ``barrier()``, ``rmb()``, ``wmb()`` )都需è¦æºä»£ç¢¼æ³¨
釋來解釋它們正在執行的æ“作åŠå…¶åŽŸå› çš„é‚輯。
-24) 如果補ä¸æ·»åŠ äº†ä»»ä½•ioctl,那麼也è¦æ›´æ–° ``Documentation/userspace-api/ioctl/ioctl-number.rst``
+23) 如果補ä¸æ·»åŠ äº†ä»»ä½•ioctl,那麼也è¦æ›´æ–°
+ ``Documentation/userspace-api/ioctl/ioctl-number.rst`` 。
-25) 如果修改後的原始碼ä¾è³´æˆ–使用與以下 ``Kconfig`` 符號相關的任何內核API或
+24) 如果修改後的æºä»£ç¢¼ä¾è³´æˆ–使用與以下 ``Kconfig`` 符號相關的任何內核API或
功能,則在ç¦ç”¨ç›¸é—œ ``Kconfig`` 符號和/或 ``=m`` (如果該é¸é …å¯ç”¨ï¼‰çš„情æ³
下測試以下多個構建[並éžæ‰€æœ‰é€™äº›éƒ½åŒæ™‚存在,åªæ˜¯å®ƒå€‘çš„å„種/隨機組åˆ]:
- ``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``, ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``,
- ``CONFIG_NET``, ``CONFIG_INET=n`` (但是後者伴隨 ``CONFIG_NET=y``).
+ ``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``,
+ ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``,
+ ``CONFIG_NET``, ``CONFIG_INET=n`` ï¼ˆä½†æ˜¯æœ€å¾Œä¸€å€‹éœ€è¦ ``CONFIG_NET=y`` )。
diff --git a/Documentation/translations/zh_TW/process/submitting-patches.rst b/Documentation/translations/zh_TW/process/submitting-patches.rst
index 0746809c31a2..8272b3218b54 100644
--- a/Documentation/translations/zh_TW/process/submitting-patches.rst
+++ b/Documentation/translations/zh_TW/process/submitting-patches.rst
@@ -1,229 +1,199 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. _tw_submittingpatches:
+.. SPDX-License-Identifier: GPL-2.0-or-later
.. include:: ../disclaimer-zh_TW.rst
-:Original: :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
+.. _tw_submittingpatches:
-譯者::
+:Original: Documentation/process/submitting-patches.rst
- 中文版維護者: é¾å®‡ TripleX Chung <xxx.phy@gmail.com>
- 中文版翻譯者: é¾å®‡ TripleX Chung <xxx.phy@gmail.com>
- 時奎亮 Alex Shi <alex.shi@linux.alibaba.com>
- 中文版校譯者: æŽé™½ Li Yang <leoyang.li@nxp.com>
- çŽ‹è° Wang Cong <xiyou.wangcong@gmail.com>
- 胡皓文 Hu Haowen <src.res.211@gmail.com>
+:譯者:
+ - é¾å®‡ TripleX Chung <xxx.phy@gmail.com>
+ - 時奎亮 Alex Shi <alexs@kernel.org>
+ - å³æƒ³æˆ Wu XiangCheng <bobwxc@email.cn>
+:æ ¡è­¯:
+ - æŽé™½ Li Yang <leoyang.li@nxp.com>
+ - çŽ‹è° Wang Cong <xiyou.wangcong@gmail.com>
+ - 胡皓文 Hu Haowen <src.res.211@gmail.com>
-如何讓你的改動進入內核
-======================
-å°æ–¼æƒ³è¦å°‡æ”¹å‹•æ交到 Linux 內核的個人或者公å¸ä¾†èªªï¼Œå¦‚æžœä¸ç†Ÿæ‚‰ã€Œè¦çŸ©ã€ï¼Œ
-æ交的æµç¨‹æœƒè®“人ç•æ‡¼ã€‚本文檔收集了一系列建議,這些建議å¯ä»¥å¤§å¤§çš„æ高你
+æ交補ä¸ï¼šå¦‚何讓你的改動進入內核
+================================
+
+å°æ–¼æƒ³è¦å°‡æ”¹å‹•æ交到 Linux 內核的個人或者公å¸ä¾†èªªï¼Œå¦‚æžœä¸ç†Ÿæ‚‰â€œè¦çŸ©â€ï¼Œ
+æ交的æµç¨‹æœƒè®“人ç•æ‡¼ã€‚本文檔包å«äº†ä¸€ç³»åˆ—建議,å¯ä»¥å¤§å¤§æ高你
的改動被接å—的機會.
-以下文檔å«æœ‰å¤§é‡ç°¡æ½”的建議, 具體請見:
-:ref:`Documentation/process <development_process_main>`
-åŒæ¨£ï¼Œ:ref:`Documentation/translations/zh_TW/process/submit-checklist.rst <tw_submitchecklist>`
-給出在æ交代碼å‰éœ€è¦æª¢æŸ¥çš„項目的列表。
+本文檔以較爲簡潔的行文給出了大é‡å»ºè­°ã€‚關於內核開發æµç¨‹å¦‚何進行的詳細信æ¯ï¼Œ
+åƒè¦‹ï¼š Documentation/translations/zh_CN/process/development-process.rst 。
+Documentation/translations/zh_CN/process/submit-checklist.rst 給出了一系列
+æ交補ä¸ä¹‹å‰è¦æª¢æŸ¥çš„事項。設備樹相關的補ä¸ï¼Œè«‹åƒé–±
+Documentation/devicetree/bindings/submitting-patches.rst 。
-其中許多步驟æ述了Git版本控制系統的默èªè¡Œçˆ²ï¼›å¦‚果您使用Git來準備補ä¸ï¼Œ
-您將發ç¾å®ƒçˆ²æ‚¨å®Œæˆçš„大部分機械工作,儘管您ä»ç„¶éœ€è¦æº–備和記錄一組åˆç†çš„
-補ä¸ã€‚一般來說,使用git將使您作爲內核開發人員的生活更輕鬆。
+本文檔å‡è¨­æ‚¨æ­£åœ¨ä½¿ç”¨ ``git`` 準備你的補ä¸ã€‚如果您ä¸ç†Ÿæ‚‰ ``git`` ,最好學習
+如何使用它,這將使您作爲內核開發人員的生活變得更加輕鬆。
+部分å­ç³»çµ±å’Œç¶­è­·äººå“¡çš„樹有一些關於其工作æµç¨‹å’Œè¦æ±‚çš„é¡å¤–ä¿¡æ¯ï¼Œè«‹åƒé–±
+Documentation/process/maintainer-handbooks.rst 。
-0) ç²å–當å‰æºç¢¼æ¨¹
------------------
+ç²å–當å‰æºç¢¼æ¨¹
+--------------
-如果您沒有一個å¯ä»¥ä½¿ç”¨ç•¶å‰å…§æ ¸åŽŸå§‹ç¢¼çš„存儲庫,請使用gitç²å–一個。您將è¦
-從主線存儲庫開始,它å¯ä»¥é€šéŽä»¥ä¸‹æ–¹å¼ç²å–::
+如果您手頭沒有當å‰å…§æ ¸æºä»£ç¢¼çš„存儲庫,請使用 ``git`` ç²å–一份。您需è¦å…ˆç²å–
+主線存儲庫,它å¯ä»¥é€šéŽä»¥ä¸‹å‘½ä»¤æ‹‰å–::
- git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
-但是,請注æ„,您å¯èƒ½ä¸å¸Œæœ›ç›´æŽ¥é‡å°ä¸»ç·šæ¨¹é€²è¡Œé–‹ç™¼ã€‚大多數å­ç³»çµ±ç¶­è­·äººå“¡é‹
+但是,請注æ„,您å¯èƒ½ä¸æƒ³ç›´æŽ¥é‡å°ä¸»ç·šæ¨¹é€²è¡Œé–‹ç™¼ã€‚大多數å­ç³»çµ±ç¶­è­·äººå“¡é‹
行自己的樹,並希望看到é‡å°é€™äº›æ¨¹æº–備的補ä¸ã€‚è«‹åƒè¦‹MAINTAINERS文件中å­ç³»
-統的 **T:** 項以查找該樹,或者簡單地詢å•ç¶­è­·è€…該樹是å¦æœªåœ¨å…¶ä¸­åˆ—出。
-
-ä»ç„¶å¯ä»¥é€šéŽtarballs下載內核版本(如下一節所述),但這是進行內核開發的
-一種困難的方å¼ã€‚
-
-1) "diff -up"
--------------
-
-使用 "diff -up" 或者 "diff -uprN" 來創建補ä¸ã€‚
-
-所有內核的改動,都是以補ä¸çš„å½¢å¼å‘ˆç¾çš„,補ä¸ç”± diff(1) 生æˆã€‚創建補ä¸çš„
-時候,è¦ç¢ºèªå®ƒæ˜¯ä»¥ "unified diff" æ ¼å¼å‰µå»ºçš„,這種格å¼ç”± diff(1) çš„ '-u'
-åƒæ•¸ç”Ÿæˆã€‚而且,請使用 '-p' åƒæ•¸ï¼Œé‚£æ¨£æœƒé¡¯ç¤ºæ¯å€‹æ”¹å‹•æ‰€åœ¨çš„C函數,使得
-產生的補ä¸å®¹æ˜“讀得多。補ä¸æ‡‰è©²åŸºæ–¼å…§æ ¸åŽŸå§‹ç¢¼æ¨¹çš„根目錄,而ä¸æ˜¯è£¡é‚Šçš„ä»»
-何å­ç›®éŒ„。
-
-爲一個單ç¨çš„文件創建補ä¸ï¼Œä¸€èˆ¬ä¾†èªªé€™æ¨£åšå°±å¤ äº†::
-
- SRCTREE=linux
- MYFILE=drivers/net/mydriver.c
-
- cd $SRCTREE
- cp $MYFILE $MYFILE.orig
- vi $MYFILE # make your change
- cd ..
- diff -up $SRCTREE/$MYFILE{.orig,} > /tmp/patch
-
-爲多個文件創建補ä¸ï¼Œä½ å¯ä»¥è§£é–‹ä¸€å€‹æ²’有修改éŽçš„內核原始碼樹,然後和你自
-å·±çš„ä»£ç¢¼æ¨¹ä¹‹é–“åš diff 。例如::
-
- MYSRC=/devel/linux
-
- tar xvfz linux-3.19.tar.gz
- mv linux-3.19 linux-3.19-vanilla
- diff -uprN -X linux-3.19-vanilla/Documentation/dontdiff \
- linux-3.19-vanilla $MYSRC > /tmp/patch
-
-"dontdiff" 是內核在編譯的時候產生的文件的列表,列表中的文件在 diff(1)
-產生的補ä¸é‡Œæœƒè¢«è·³éŽã€‚
-
-確定你的補ä¸é‡Œæ²’有包å«ä»»ä½•ä¸å±¬æ–¼é€™æ¬¡è£œä¸æ交的é¡å¤–文件。記得在用diff(1)
-生æˆè£œä¸ä¹‹å¾Œï¼Œå¯©é–±ä¸€æ¬¡è£œä¸ï¼Œä»¥ç¢ºä¿æº–確。
-
-如果你的改動很散亂,你應該研究一下如何將補ä¸åˆ†å‰²æˆç¨ç«‹çš„部分,將改動分
-割æˆä¸€ç³»åˆ—åˆä¹Žé‚輯的步驟。這樣更容易讓其他內核開發者審核,如果你想你的
-補ä¸è¢«æŽ¥å—,這是很é‡è¦çš„。請åƒé–±ï¼š
-:ref:`tw_split_changes`
-
-如果你用 ``git`` , ``git rebase -i`` å¯ä»¥å¹«åŠ©ä½ é€™ä¸€é»žã€‚如果你ä¸ç”¨ ``git``,
-``quilt`` <https://savannah.nongnu.org/projects/quilt> å¦å¤–一個æµè¡Œçš„é¸æ“‡ã€‚
+統的 **T:** 項以查找該樹,或者直接詢å•ç¶­è­·è€…該樹是å¦æœªåœ¨å…¶ä¸­åˆ—出。
.. _tw_describe_changes:
-2) æ述你的改動
----------------
+æ述你的改動
+------------
æè¿°ä½ çš„å•é¡Œã€‚無論您的補ä¸æ˜¯ä¸€è¡ŒéŒ¯èª¤ä¿®å¾©é‚„是5000行新功能,都必須有一個潛在
-çš„å•é¡Œæ¿€å‹µæ‚¨å®Œæˆé€™é …工作。讓審稿人相信有一個å•é¡Œå€¼å¾—解決,讓他們讀完第一段
-是有æ„義的。
+çš„å•é¡Œæ¿€å‹µæ‚¨å®Œæˆé€™é …工作。說æœå¯©é–±è€…相信有一個å•é¡Œå€¼å¾—解決,讓他們讀完第一段
+後就能明白這一點。
æ述用戶å¯è¦‹çš„影響。直接崩潰和鎖定是相當有說æœåŠ›çš„,但並ä¸æ˜¯æ‰€æœ‰çš„錯誤都那麼
-明目張胆。å³ä½¿åœ¨ä»£ç¢¼å¯©æŸ¥æœŸé–“發ç¾äº†é€™å€‹å•é¡Œï¼Œä¹Ÿè¦æ述一下您èªçˆ²å®ƒå¯èƒ½å°ç”¨æˆ¶ç”¢
+明目張膽。å³ä½¿åœ¨ä»£ç¢¼å¯©é–±æœŸé–“發ç¾äº†é€™å€‹å•é¡Œï¼Œä¹Ÿè¦æ述一下您èªçˆ²å®ƒå¯èƒ½å°ç”¨æˆ¶ç”¢
生的影響。請記ä½ï¼Œå¤§å¤šæ•¸Linux安è£é‹è¡Œçš„內核來自二級穩定樹或特定於供應商/產å“
的樹,åªå¾žä¸Šæ¸¸ç²¾é¸ç‰¹å®šçš„補ä¸ï¼Œå› æ­¤è«‹åŒ…å«ä»»ä½•å¯ä»¥å¹«åŠ©æ‚¨å°‡æ›´æ”¹å®šä½åˆ°ä¸‹æ¸¸çš„內容:
-觸發的場景ã€DMESG的摘錄ã€å´©æ½°æè¿°ã€æ€§èƒ½å›žæ­¸ã€å»¶é²å°–峯ã€éŽ–定等。
+觸發的場景ã€DMESG的摘錄ã€å´©æ½°æè¿°ã€æ€§èƒ½è¿´æ­¸ã€å»¶é²å°–峯ã€éŽ–定等。
-é‡åŒ–優化和權衡。如果您è²ç¨±åœ¨æ€§èƒ½ã€å…§å­˜æ¶ˆè€—ã€å †æ£§å ç”¨ç©ºé–“或二進ä½å¤§å°æ–¹é¢æœ‰æ‰€
-改進,請包括支æŒå®ƒå€‘的數字。但也è¦æè¿°ä¸æ˜Žé¡¯çš„æˆæœ¬ã€‚優化通常ä¸æ˜¯å…費的,而是
-在CPUã€å…§å­˜å’Œå¯è®€æ€§ä¹‹é–“進行權衡;或者,探索性的工作,在ä¸åŒçš„工作負載之間進
+質é‡å„ªåŒ–和權衡。如果您è²ç¨±åœ¨æ€§èƒ½ã€å…§å­˜æ¶ˆè€—ã€å †æ£§ä½”用空間或二進制大å°æ–¹é¢æœ‰æ‰€
+改進,請包括支æŒå®ƒå€‘的數據。但也è¦æè¿°ä¸æ˜Žé¡¯çš„æˆæœ¬ã€‚優化通常ä¸æ˜¯é›¶æˆæœ¬çš„,而是
+在CPUã€å…§å­˜å’Œå¯è®€æ€§ä¹‹é–“進行權衡;或者,åšæŽ¢ç´¢æ€§çš„工作,在ä¸åŒçš„工作負載之間進
行權衡。請æ述優化的é æœŸç¼ºé»žï¼Œä»¥ä¾¿å¯©é–±è€…å¯ä»¥æ¬Šè¡¡æˆæœ¬å’Œæ”¶ç›Šã€‚
-一旦å•é¡Œå»ºç«‹èµ·ä¾†ï¼Œå°±è¦è©³ç´°åœ°æ述一下您實際在åšä»€éº¼ã€‚å°æ–¼å¯©é–±è€…來說,用簡單的
-英語æ述代碼的變化是很é‡è¦çš„,以驗證代碼的行爲是å¦ç¬¦åˆæ‚¨çš„æ„願。
+æ出å•é¡Œä¹‹å¾Œï¼Œå°±è¦è©³ç´°åœ°æ述一下您實際在åšçš„技術細節。å°æ–¼å¯©é–±è€…來說,用簡練的
+英語æ述代碼的變化是很é‡è¦çš„,以驗證代碼的行爲是å¦ç¬¦åˆæ‚¨çš„æ„圖。
-如果您將補ä¸æ述寫在一個表單中,這個表單å¯ä»¥å¾ˆå®¹æ˜“地作爲「æ交日誌ã€æ”¾å…¥Linux
-的原始碼管ç†ç³»çµ±git中,那麼維護人員將éžå¸¸æ„Ÿè¬æ‚¨ã€‚見 :ref:`tw_explicit_in_reply_to`.
+如果您將補ä¸æ述寫æˆâ€œæ¨™æº–æ ¼å¼â€ï¼Œå¯ä»¥å¾ˆå®¹æ˜“地作爲“æ交日誌â€æ”¾å…¥Linuxçš„æºä»£
+碼管ç†ç³»çµ± ``git`` 中,那麼維護人員將éžå¸¸æ„Ÿè¬æ‚¨ã€‚
+åƒè¦‹ :ref:`zh_the_canonical_patch_format` 。
æ¯å€‹è£œä¸åªè§£æ±ºä¸€å€‹å•é¡Œã€‚如果你的æ述開始變長,這就表明你å¯èƒ½éœ€è¦æ‹†åˆ†ä½ çš„補ä¸ã€‚
-請見 :ref:`tw_split_changes`
+請見 :ref:`zh_split_changes` 。
-æ交或é‡æ–°æ交修補程åºæˆ–修補程åºç³»åˆ—時,請包括完整的修補程åºèªªæ˜Žå’Œç†ç”±ã€‚ä¸è¦
+æ交或é‡æ–°æ交補ä¸æˆ–補ä¸ç³»åˆ—時,請包括完整的補ä¸èªªæ˜Žå’Œç†ç”±ã€‚ä¸è¦
åªèªªé€™æ˜¯è£œä¸ï¼ˆç³»åˆ—)的第幾版。ä¸è¦æœŸæœ›å­ç³»çµ±ç¶­è­·äººå“¡å¼•ç”¨æ›´æ—©çš„補ä¸ç‰ˆæœ¬æˆ–引用
URL來查找補ä¸æ述並將其放入補ä¸ä¸­ã€‚也就是說,補ä¸ï¼ˆç³»åˆ—)åŠå…¶æ述應該是ç¨ç«‹çš„。
-這å°ç¶­è­·äººå“¡å’Œå¯©æŸ¥äººå“¡éƒ½æœ‰å¥½è™•ã€‚一些評審者å¯èƒ½ç”šè‡³æ²’有收到補ä¸çš„早期版本。
+這å°ç¶­è­·äººå“¡å’Œå¯©é–±è€…都有好處。一些審閱者å¯èƒ½ç”šè‡³æ²’有收到補ä¸çš„早期版本。
-æ述你在命令語氣中的變化,例如「make xyzzy do frotzã€è€Œä¸æ˜¯ã€Œ[這個補ä¸]make
-xyzzy do frotzã€æˆ–「[我]changed xyzzy to do frotzã€ï¼Œå°±å¥½åƒä½ åœ¨å‘½ä»¤ä»£ç¢¼åº«æ”¹è®Š
+用祈使å¥æ述你的變更,例如“make xyzzy do frotzâ€è€Œä¸æ˜¯â€œ[This patch]make
+xyzzy do frotzâ€æˆ–“[I]changed xyzzy to do frotzâ€ï¼Œå°±å¥½åƒä½ åœ¨å‘½ä»¤ä»£ç¢¼åº«æ”¹è®Š
它的行爲一樣。
-如果修補程åºä¿®å¾©äº†ä¸€å€‹è¨˜éŒ„çš„bugæ¢ç›®ï¼Œè«‹æŒ‰ç·¨è™Ÿå’ŒURL引用該bugæ¢ç›®ã€‚如果補ä¸ä¾†
-自郵件列表討論,請給出郵件列表存檔的URL;使用帶有 ``Message-ID`` 的
-https://lore.kernel.org/ é‡å®šå‘,以確ä¿é€£çµä¸æœƒéŽæ™‚。
-
-但是,在沒有外部資æºçš„情æ³ä¸‹ï¼Œå„˜é‡è®“你的解釋å¯ç†è§£ã€‚除了æ供郵件列表存檔或
-bugçš„URL之外,還è¦ç¸½çµéœ€è¦æ交補ä¸çš„相關討論è¦é»žã€‚
-
-如果您想è¦å¼•ç”¨ä¸€å€‹ç‰¹å®šçš„æ交,ä¸è¦åªå¼•ç”¨æ交的 SHA-1 ID。還請包括æ交的一行
-摘è¦ï¼Œä»¥ä¾¿æ–¼å¯©é–±è€…了解它是關於什麼的。例如::
+如果您想è¦å¼•ç”¨ä¸€å€‹ç‰¹å®šçš„æ交,ä¸è¦åªå¼•ç”¨æ交的SHA-1 ID。還請包括æ交的一行
+摘è¦ï¼Œä»¥ä¾¿æ–¼å¯©é–±è€…瞭解它是關於什麼的。例如::
Commit e21d2170f36602ae2708 ("video: remove unnecessary
platform_set_drvdata()") removed the unnecessary
platform_set_drvdata(), but left the variable "dev" unused,
delete it.
-您還應該確ä¿è‡³å°‘使用å‰12ä½ SHA-1 ID. 內核存儲庫包å«*許多*å°è±¡ï¼Œä½¿èˆ‡è¼ƒçŸ­çš„ID
+您還應該確ä¿è‡³å°‘使用å‰12ä½SHA-1 IDã€‚å…§æ ¸å­˜å„²åº«åŒ…å« *許多* å°è±¡ï¼Œä½¿è¼ƒçŸ­çš„ID
發生è¡çªçš„å¯èƒ½æ€§å¾ˆå¤§ã€‚記ä½ï¼Œå³ä½¿ç¾åœ¨ä¸æœƒèˆ‡æ‚¨çš„六個字符ID發生è¡çªï¼Œé€™ç¨®æƒ…æ³
-å¯èƒ½äº”年後改變。
+也å¯èƒ½åœ¨äº”年後改變。
+
+如果該變更的相關討論或背景信æ¯å¯ä»¥åœ¨ç¶²ä¸ŠæŸ¥é–±ï¼Œè«‹åŠ ä¸Šâ€œLink:â€æ¨™ç±¤æŒ‡å‘它。例如
+你的補ä¸ä¿®å¾©äº†ä¸€å€‹ç¼ºé™·ï¼Œéœ€è¦æ·»åŠ ä¸€å€‹å¸¶æœ‰URL的標籤指å‘郵件列表存檔或缺陷跟蹤器
+的相關報告;如果該補ä¸æ˜¯ç”±ä¸€äº›æ—©å…ˆéƒµä»¶åˆ—表討論或網絡上的記錄引起的,請指å‘它。
+
+當éˆæŽ¥åˆ°éƒµä»¶åˆ—表存檔時,請首é¸lore.kernel.org郵件存檔æœå‹™ã€‚用郵件中的
+``Message-ID`` 頭(去掉尖括號)å¯ä»¥å‰µå»ºéˆæŽ¥URL。例如::
+
+ Link: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
+
+請檢查該éˆæŽ¥ä»¥ç¢ºä¿å¯ç”¨ä¸”指å‘正確的郵件。
+
+ä¸éŽï¼Œåœ¨æ²’有外部資æºçš„情æ³ä¸‹ï¼Œä¹Ÿè¦å„˜é‡è®“你的解釋å¯ç†è§£ã€‚除了æ供郵件列表存檔或
+缺陷的URL之外,還è¦éœ€è¦ç¸½çµè©²è£œä¸çš„相關討論è¦é»žã€‚
-如果修補程åºä¿®å¾©äº†ç‰¹å®šæ交中的錯誤,例如,使用 ``git bisct`` ,請使用帶有å‰
-12個字符SHA-1 ID çš„"Fixes:"標記和單行摘è¦ã€‚爲了簡化ä¸è¦å°‡æ¨™è¨˜æ‹†åˆ†çˆ²å¤šå€‹ï¼Œ
-è¡Œã€æ¨™è¨˜ä¸å—分æžè…³æœ¬ã€Œ75列æ›è¡Œã€è¦å‰‡çš„é™åˆ¶ã€‚例如::
+如果補ä¸ä¿®å¾©äº†ç‰¹å®šæ交中的錯誤,例如使用 ``git bisct`` 發ç¾äº†ä¸€å€‹å•é¡Œï¼Œè«‹ä½¿ç”¨
+帶有å‰12個字符SHA-1 ID的“Fixes:â€æ¨™ç±¤å’Œå–®è¡Œæ‘˜è¦ã€‚爲了簡化解æžè…³æœ¬ï¼Œä¸è¦å°‡è©²
+標籤拆分爲多行,標籤ä¸å—“75列æ›è¡Œâ€è¦å‰‡çš„é™åˆ¶ã€‚例如::
- Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")
+ Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")
-下列 ``git config`` 設置å¯ä»¥æ·»åŠ è®“ ``git log``, ``git show`` 漂亮的顯示格å¼::
+下列 ``git config`` 設置å¯ä»¥è®“ ``git log``, ``git show`` 增加上述風格的顯示格å¼::
[core]
abbrev = 12
[pretty]
fixes = Fixes: %h (\"%s\")
+使用示例::
+
+ $ git log -1 --pretty=fixes 54a4f0239f2e
+ Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")
+
.. _tw_split_changes:
-3) 拆分你的改動
----------------
+拆分你的改動
+------------
-å°‡æ¯å€‹é‚輯更改分隔æˆä¸€å€‹å–®ç¨çš„補ä¸ã€‚
+å°‡æ¯å€‹ **é‚輯更改** 拆分æˆä¸€å€‹å–®ç¨çš„補ä¸ã€‚
-例如,如果你的改動里åŒæ™‚有bug修正和性能優化,那麼把這些改動拆分到兩個或
-者更多的補ä¸æ–‡ä»¶ä¸­ã€‚如果你的改動包å«å°API的修改,並且修改了驅動程åºä¾†é©
-應這些新的API,那麼把這些修改分æˆå…©å€‹è£œä¸ã€‚
+例如,如果你的改動è£åŒæ™‚有bug修正和性能優化,那麼把這些改動拆分到兩個或
+者更多的補ä¸æ–‡ä»¶ä¸­ã€‚如果你的改動包å«å°API的修改,並且增加了一個使用該新API
+的驅動,那麼把這些修改分æˆå…©å€‹è£œä¸ã€‚
å¦ä¸€æ–¹é¢ï¼Œå¦‚果你將一個單ç¨çš„改動åšæˆå¤šå€‹è£œä¸æ–‡ä»¶ï¼Œé‚£éº¼å°‡å®ƒå€‘åˆä½µæˆä¸€å€‹
-å–®ç¨çš„補ä¸æ–‡ä»¶ã€‚這樣一個é‚輯上單ç¨çš„改動åªè¢«åŒ…å«åœ¨ä¸€å€‹è£œä¸æ–‡ä»¶é‡Œã€‚
+å–®ç¨çš„補ä¸æ–‡ä»¶ã€‚這樣一個é‚輯上單ç¨çš„改動åªè¢«åŒ…å«åœ¨ä¸€å€‹è£œä¸æ–‡ä»¶è£ã€‚
-如果有一個補ä¸ä¾è³´å¦å¤–一個補ä¸ä¾†å®Œæˆå®ƒçš„改動,那沒å•é¡Œã€‚簡單的在你的補
-ä¸æ述里指出「這個補ä¸ä¾è³´æŸè£œä¸ã€å°±å¥½äº†ã€‚
+需è¦è¨˜ä½çš„一點是,æ¯å€‹è£œä¸çš„更改都應易於ç†è§£ï¼Œä»¥ä¾¿å¯©é–±è€…驗證。æ¯å€‹è£œä¸éƒ½æ‡‰è©²
+å°å…¶åƒ¹å€¼é€²è¡Œé—¡è¿°ã€‚
-在將您的更改劃分爲一系列補ä¸æ™‚,è¦ç‰¹åˆ¥æ³¨æ„確ä¿å…§æ ¸åœ¨ç³»åˆ—中的æ¯å€‹è£œä¸ä¹‹å¾Œ
-都能正常構建和é‹è¡Œã€‚使用 ``git bisect`` 來追蹤å•é¡Œçš„開發者å¯èƒ½æœƒåœ¨ä»»ä½•æ™‚
-候分割你的補ä¸ç³»åˆ—;如果你在中間引入錯誤,他們ä¸æœƒæ„Ÿè¬ä½ ã€‚
+如果有一個補ä¸ä¾è³´å¦å¤–一個補ä¸ä¾†å®Œæˆå®ƒçš„改動,那沒å•é¡Œã€‚直接在你的補
+ä¸æè¿°è£æŒ‡å‡º **“這個補ä¸ä¾è³´æŸè£œä¸â€** 就好了。
-如果你ä¸èƒ½å°‡è£œä¸æ¿ƒç¸®æˆæ›´å°‘的文件,那麼æ¯æ¬¡å¤§ç´„發é€å‡º15個,然後等待審查
+在將您的更改劃分爲一系列補ä¸æ™‚,è¦ç‰¹åˆ¥æ³¨æ„確ä¿å…§æ ¸åœ¨æ‡‰ç”¨ç³»åˆ—中的æ¯å€‹è£œä¸ä¹‹å¾Œ
+都能正常構建和é‹è¡Œã€‚使用 ``git bisect`` 來追蹤å•é¡Œçš„開發者å¯èƒ½æœƒåœ¨ä»»ä½•åœ°æ–¹åˆ†
+割你的補ä¸ç³»åˆ—;如果你在中間引入錯誤,他們ä¸æœƒæ„Ÿè¬ä½ ã€‚
+
+如果你ä¸èƒ½å°‡è£œä¸ç³»åˆ—濃縮得更å°ï¼Œé‚£éº¼æ¯æ¬¡å¤§ç´„發é€å‡º15個補ä¸ï¼Œç„¶å¾Œç­‰å¾…審閱
和集æˆã€‚
-4) 檢查你的更改風格
--------------------
+檢查你的更改風格
+----------------
-檢查您的補ä¸æ˜¯å¦å­˜åœ¨åŸºæœ¬æ¨£å¼è¡çªï¼Œè©³ç´°ä¿¡æ¯å¯åœ¨
-:ref:`Documentation/translations/zh_TW/process/coding-style.rst <tw_codingstyle>`
-中找到。如果ä¸é€™æ¨£åšï¼Œåªæœƒæµªè²»å¯©ç¨¿äººçš„時間,並且會導致你的補ä¸è¢«æ‹’絕,甚至
+檢查您的補ä¸æ˜¯å¦é•å了基本樣å¼è¦å®šï¼Œè©³ç´°ä¿¡æ¯åƒè¦‹
+Documentation/translations/zh_CN/process/coding-style.rst
+中找到。如果ä¸é€™æ¨£åšï¼Œåªæœƒæµªè²»å¯©é–±è€…的時間,並且會導致你的補ä¸è¢«æ‹’絕,甚至
å¯èƒ½æ²’有被閱讀。
一個é‡è¦çš„例外是在將代碼從一個文件移動到å¦ä¸€å€‹æ–‡ä»¶æ™‚——在這種情æ³ä¸‹ï¼Œæ‚¨ä¸æ‡‰
該在移動代碼的åŒä¸€å€‹è£œä¸ä¸­ä¿®æ”¹ç§»å‹•çš„代碼。這清楚地æ述了移動代碼和您的更改
-的行爲。這大大有助於審查實際差異,並å…許工具更好地跟蹤代碼本身的歷å²ã€‚
+的行爲。這大大有助於審閱實際差異,並å…許工具更好地跟蹤代碼本身的歷å²ã€‚
在æ交之å‰ï¼Œä½¿ç”¨è£œä¸æ¨£å¼æª¢æŸ¥ç¨‹åºæª¢æŸ¥è£œä¸ï¼ˆscripts/check patch.pl)。ä¸éŽï¼Œ
請注æ„,樣å¼æª¢æŸ¥ç¨‹åºæ‡‰è©²è¢«è¦–爲一個指å—,而ä¸æ˜¯ä½œçˆ²äººé¡žåˆ¤æ–·çš„替代å“。如果您
-的代碼看起來更好,但有é•è¦è¡Œçˆ²ï¼Œé‚£éº¼æœ€å¥½ä¸è¦ä½¿ç”¨å®ƒã€‚
+的代碼看起來更好,但有é•è¦è¡Œçˆ²ï¼Œé‚£éº¼æœ€å¥½åˆ¥ç®¡å®ƒã€‚
檢查者報告三個級別:
- ERROR:很å¯èƒ½å‡ºéŒ¯çš„事情
- - WARNING:需è¦ä»”細審查的事項
+ - WARNING:需è¦ä»”細審閱的事項
- CHECK:需è¦æ€è€ƒçš„事情
您應該能夠判斷您的補ä¸ä¸­å­˜åœ¨çš„所有é•è¦è¡Œçˆ²ã€‚
-5) é¸æ“‡è£œä¸æ”¶ä»¶äºº
------------------
+é¸æ“‡è£œä¸æ”¶ä»¶äºº
+--------------
-您應該總是在任何補ä¸ä¸Šè¤‡è£½ç›¸æ‡‰çš„å­ç³»çµ±ç¶­è­·äººå“¡ï¼Œä»¥ç²å¾—他們維護的代碼;查看
-維護人員文件和原始碼修訂歷å²è¨˜éŒ„,以了解這些維護人員是誰。腳本
-scripts/get_Maintainer.pl在這個步驟中éžå¸¸æœ‰ç”¨ã€‚如果您找ä¸åˆ°æ­£åœ¨å·¥ä½œçš„å­ç³»çµ±
+您應該總是知會任何補ä¸ç›¸æ‡‰ä»£ç¢¼çš„å­ç³»çµ±ç¶­è­·äººå“¡ï¼›æŸ¥çœ‹
+維護人員文件和æºä»£ç¢¼ä¿®è¨‚æ­·å²è¨˜éŒ„,以瞭解這些維護人員是誰。腳本
+scripts/get_maintainer.pl在這個步驟中éžå¸¸æœ‰ç”¨ã€‚如果您找ä¸åˆ°æ­£åœ¨å·¥ä½œçš„å­ç³»çµ±
的維護人員,那麼Andrew Morton(akpm@linux-foundation.org)將充當最後的維護
人員。
-您通常還應該é¸æ“‡è‡³å°‘一個郵件列表來接收補ä¸é›†çš„。linux-kernel@vger.kernel.org
-作爲最後一個解決辦法的列表,但是這個列表上的體ç©å·²ç¶“引起了許多開發人員的拒絕。
-在MAINTAINERS文件中查找å­ç³»çµ±ç‰¹å®šçš„列表;您的補ä¸å¯èƒ½æœƒåœ¨é‚£è£¡å¾—到更多的關注。
+您通常還應該é¸æ“‡è‡³å°‘一個郵件列表來接收補ä¸é›†çš„副本。linux-kernel@vger.kernel.org
+是所有補ä¸çš„默èªåˆ—表,但是這個列表的æµé‡å·²ç¶“導致了許多開發人員ä¸å†çœ‹å®ƒã€‚
+在MAINTAINERS文件中查找å­ç³»çµ±ç‰¹å®šçš„列表;您的補ä¸å¯èƒ½æœƒåœ¨é‚£è£å¾—到更多的關注。
ä¸éŽï¼Œè«‹ä¸è¦ç™¼é€åžƒåœ¾éƒµä»¶åˆ°ç„¡é—œçš„列表。
許多與內核相關的列表託管在vger.kernel.org上;您å¯ä»¥åœ¨
@@ -232,188 +202,170 @@ http://vger.kernel.org/vger-lists.html 上找到它們的列表。ä¸éŽï¼Œä¹Ÿæœ
ä¸è¦ä¸€æ¬¡ç™¼é€è¶…éŽ15個補ä¸åˆ°vger郵件列表ï¼ï¼ï¼ï¼
-Linus Torvalds 是決定改動能å¦é€²å…¥ Linux 內核的最終è£æ±ºè€…。他的 e-mail
-地å€æ˜¯ <torvalds@linux-foundation.org> 。他收到的 e-mail 很多,所以一般
-的說,最好別給他發 e-mail。
+Linus Torvalds是決定改動能å¦é€²å…¥ Linux 內核的最終è£æ±ºè€…。他的郵件地å€æ˜¯
+torvalds@linux-foundation.org 。他收到的郵件很多,所以一般來說最好 **別**
+給他發郵件。
-如果您有修復å¯åˆ©ç”¨å®‰å…¨æ¼æ´žçš„補ä¸ï¼Œè«‹å°‡è©²è£œä¸ç™¼é€åˆ° security@kernel.org。å°æ–¼
-åš´é‡çš„bug,å¯ä»¥è€ƒæ…®çŸ­æœŸæš«åœä»¥å…許分銷商å‘用戶發布補ä¸ï¼›åœ¨é€™ç¨®æƒ…æ³ä¸‹ï¼Œé¡¯ç„¶ä¸æ‡‰
-將補ä¸ç™¼é€åˆ°ä»»ä½•å…¬å…±åˆ—表。
+如果您有修復å¯åˆ©ç”¨å®‰å…¨æ¼æ´žçš„補ä¸ï¼Œè«‹å°‡è©²è£œä¸ç™¼é€åˆ° security@kernel.org 。å°æ–¼
+åš´é‡çš„bug,å¯ä»¥è€ƒæ…®çŸ­æœŸç¦ä»¤ä»¥å…許分銷商(有時間)å‘用戶發佈補ä¸ï¼›åœ¨é€™ç¨®æƒ…æ³ä¸‹ï¼Œ
+顯然ä¸æ‡‰å°‡è£œä¸ç™¼é€åˆ°ä»»ä½•å…¬å…±åˆ—表。
+åƒè¦‹ Documentation/translations/zh_CN/admin-guide/security-bugs.rst 。
-修復已發布內核中嚴é‡éŒ¯èª¤çš„補ä¸ç¨‹åºæ‡‰è©²æŒ‡å‘穩定版維護人員,方法是放這樣的一行::
+修復已發佈內核中嚴é‡éŒ¯èª¤çš„補ä¸ç¨‹åºæ‡‰è©²æŠ„é€çµ¦ç©©å®šç‰ˆç¶­è­·äººå“¡ï¼Œæ–¹æ³•æ˜¯æŠŠä»¥ä¸‹åˆ—è¡Œ
+放進補ä¸çš„籤準å€ï¼ˆæ³¨æ„,ä¸æ˜¯é›»å­éƒµä»¶æ”¶ä»¶äººï¼‰::
- Cc: stable@vger.kernel.org
+ Cc: stable@vger.kernel.org
-進入補ä¸çš„簽准å€ï¼ˆæ³¨æ„,ä¸æ˜¯é›»å­éƒµä»¶æ”¶ä»¶äººï¼‰ã€‚除了這個文件之外,您還應該閱讀
-:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
+除了本文件之外,您還應該閱讀
+Documentation/translations/zh_CN/process/stable-kernel-rules.rst 。
-但是,請注æ„,一些å­ç³»çµ±ç¶­è­·äººå“¡å¸Œæœ›å¾—出他們自己的çµè«–,å³å“ªäº›è£œä¸æ‡‰è©²è¢«æ”¾åˆ°
-穩定的樹上。尤其是網絡維護人員,ä¸å¸Œæœ›çœ‹åˆ°å–®å€‹é–‹ç™¼äººå“¡åœ¨è£œä¸ä¸­æ·»åŠ åƒä¸Šé¢é€™æ¨£
-的行。
-
-如果更改影響到用戶和內核接å£ï¼Œè«‹å‘手冊é ç¶­è­·äººå“¡ï¼ˆå¦‚維護人員文件中所列)發é€
+如果更改影響到用戶å´å…§æ ¸æŽ¥å£ï¼Œè«‹å‘手冊é ç¶­è­·äººå“¡ï¼ˆå¦‚維護人員文件中所列)發é€
手冊é è£œä¸ï¼Œæˆ–至少發é€æ›´æ”¹é€šçŸ¥ï¼Œä»¥ä¾¿ä¸€äº›ä¿¡æ¯é€²å…¥æ‰‹å†Šé ã€‚還應將用戶空間API
-更改複製到 linux-api@vger.kernel.org。
+更改抄é€åˆ° linux-api@vger.kernel.org 。
+
-6) 沒有 MIME 編碼,沒有連çµï¼Œæ²’有壓縮,沒有附件,åªæœ‰ç´”文本
------------------------------------------------------------
+ä¸è¦MIME編碼,ä¸è¦éˆæŽ¥ï¼Œä¸è¦å£“縮,ä¸è¦é™„件,åªè¦ç´”文本
+------------------------------------------------------
Linus 和其他的內核開發者需è¦é–±è®€å’Œè©•è«–ä½ æ交的改動。å°æ–¼å…§æ ¸é–‹ç™¼è€…來說
-,å¯ä»¥ã€Œå¼•ç”¨ã€ä½ çš„改動很é‡è¦ï¼Œä½¿ç”¨ä¸€èˆ¬çš„ e-mail 工具,他們就å¯ä»¥åœ¨ä½ çš„
+,å¯ä»¥â€œå¼•ç”¨â€ä½ çš„改動很é‡è¦ï¼Œä½¿ç”¨ä¸€èˆ¬çš„郵件工具,他們就å¯ä»¥åœ¨ä½ çš„
代碼的任何ä½ç½®æ·»åŠ è©•è«–。
-因爲這個原因,所有的æ交的補ä¸éƒ½æ˜¯ e-mail 中「內嵌ã€çš„。
+因爲這個原因,所有的æ交的補ä¸éƒ½æ˜¯éƒµä»¶ä¸­â€œå…§åµŒâ€çš„。最簡單(和推薦)的方法就
+是使用 ``git send-email`` 。https://git-send-email.io 有 ``git send-email``
+的交互å¼æ•™ç¨‹ã€‚
+
+如果你é¸æ“‡ä¸ç”¨ ``git send-email`` :
.. warning::
- 如果你使用剪切-粘貼你的補ä¸ï¼Œå°å¿ƒä½ çš„編輯器的自動æ›è¡ŒåŠŸèƒ½ç ´å£žä½ çš„補ä¸
-ä¸è¦å°‡è£œä¸ä½œçˆ² MIME 編碼的附件,ä¸ç®¡æ˜¯å¦å£“縮。很多æµè¡Œçš„ e-mail 軟體ä¸
-是任何時候都將 MIME 編碼的附件當作純文本發é€çš„,這會使得別人無法在你的
-代碼中加評論。å¦å¤–,MIME 編碼的附件會讓 Linus 多花一點時間來處ç†ï¼Œé€™å°±
-é™ä½Žäº†ä½ çš„改動被接å—çš„å¯èƒ½æ€§ã€‚
+ 如果你使用剪切-粘貼你的補ä¸ï¼Œå°å¿ƒä½ çš„編輯器的自動æ›è¡ŒåŠŸèƒ½ç ´å£žä½ çš„補ä¸
-例外:如果你的郵éžå“¡å¼„壞了補ä¸ï¼Œé‚£éº¼æœ‰äººå¯èƒ½æœƒè¦æ±‚你使用mimeé‡æ–°ç™¼é€è£œä¸
+ä¸è¦å°‡è£œä¸ä½œçˆ²MIME編碼的附件,ä¸ç®¡æ˜¯å¦å£“縮。很多æµè¡Œçš„郵件軟件ä¸
+是任何時候都將MIME編碼的附件當作純文本發é€çš„,這會使得別人無法在你的
+代碼中加評論。å¦å¤–,MIME編碼的附件會讓Linus多花一點時間來處ç†ï¼Œé€™å°±
+é™ä½Žäº†ä½ çš„改動被接å—çš„å¯èƒ½æ€§ã€‚
-è«‹åƒé–± :ref:`Documentation/translations/zh_TW/process/email-clients.rst <tw_email_clients>`
-以ç²å–有關é…置電å­éƒµä»¶å®¢æˆ¶ç«¯ä»¥ä½¿å…¶ä¸å—影響地發é€ä¿®è£œç¨‹åºçš„æ示。
+例外:如果你的郵路æ壞了補ä¸ï¼Œé‚£éº¼æœ‰äººå¯èƒ½æœƒè¦æ±‚你使用MIMEé‡æ–°ç™¼é€è£œä¸ã€‚
-7) e-mail 的大å°
-----------------
+è«‹åƒé–± Documentation/translations/zh_CN/process/email-clients.rst
+以ç²å–有關é…置電å­éƒµä»¶å®¢æˆ¶ç«¯ä»¥ä½¿å…¶ä¸å—影響地發é€è£œä¸çš„æ示。
-大的改動å°éƒµä»¶åˆ—表ä¸åˆé©ï¼Œå°æŸäº›ç¶­è­·è€…也ä¸åˆé©ã€‚如果你的補ä¸ï¼Œåœ¨ä¸å£“縮
-的情æ³ä¸‹ï¼Œè¶…éŽäº†300kB,那麼你最好將補ä¸æ”¾åœ¨ä¸€å€‹èƒ½é€šéŽ internet 訪å•çš„æœ
-務器上,然後用指å‘你的補ä¸çš„ URL 替代。但是請注æ„,如果您的補ä¸è¶…éŽäº†
-300kb,那麼它幾乎肯定需è¦è¢«ç ´å£žã€‚
+回覆審閱æ„見
+------------
-8)回複評審æ„見
----------------
+你的補ä¸å¹¾ä¹Žè‚¯å®šæœƒå¾—到審閱者å°è£œä¸æ”¹é€²æ–¹æ³•çš„評論(以回覆郵件的形å¼ï¼‰ã€‚您必須
+å°é€™äº›è©•è«–作出回應;讓補ä¸è¢«å¿½ç•¥çš„一個好辦法就是忽略審閱者的æ„見。直接回復郵
+件來回應æ„見å³å¯ã€‚ä¸æœƒå°Žè‡´ä»£ç¢¼æ›´æ”¹çš„æ„見或å•é¡Œå¹¾ä¹Žè‚¯å®šæœƒå¸¶ä¾†è¨»é‡‹æˆ–變更日誌的
+改變,以便下一個審閱者更好地瞭解正在發生的事情。
-你的補ä¸å¹¾ä¹Žè‚¯å®šæœƒå¾—到評審者å°è£œä¸æ”¹é€²æ–¹æ³•çš„評論。您必須å°é€™äº›è©•è«–作出
-回應;讓補ä¸è¢«å¿½ç•¥çš„一個好辦法就是忽略審閱者的æ„見。ä¸æœƒå°Žè‡´ä»£ç¢¼æ›´æ”¹çš„
-æ„見或å•é¡Œå¹¾ä¹Žè‚¯å®šæœƒå¸¶ä¾†æ³¨é‡‹æˆ–變更日誌的改變,以便下一個評審者更好地了解
-正在發生的事情。
+一定è¦å‘Šè¨´å¯©é–±è€…你在åšä»€éº¼æ”¹è®Šï¼Œä¸¦æ„Ÿè¬ä»–們的時間。代碼審閱是一個累人且耗時的
+éŽç¨‹ï¼Œå¯©é–±è€…有時會變得暴èºã€‚å³ä½¿åœ¨é€™ç¨®æƒ…æ³ä¸‹ï¼Œä¹Ÿè¦ç¦®è²Œåœ°å›žæ‡‰ä¸¦è§£æ±ºä»–們指出的
+å•é¡Œã€‚當發é€ä¸‹ä¸€ç‰ˆæ™‚,在å°é¢éƒµä»¶æˆ–ç¨ç«‹è£œä¸é‡ŒåŠ ä¸Š ``patch changelog`` 說明與
+å‰ä¸€ç‰ˆæœ¬çš„ä¸åŒä¹‹è™•ï¼ˆåƒè¦‹ :ref:`zh_the_canonical_patch_format` )。
-一定è¦å‘Šè¨´å¯©ç¨¿äººä½ åœ¨åšä»€éº¼æ”¹è®Šï¼Œä¸¦æ„Ÿè¬ä»–們的時間。代碼審查是一個累人且
-耗時的éŽç¨‹ï¼Œå¯©æŸ¥äººå“¡æœ‰æ™‚會變得暴èºã€‚å³ä½¿åœ¨é€™ç¨®æƒ…æ³ä¸‹ï¼Œä¹Ÿè¦ç¦®è²Œåœ°å›žæ‡‰ä¸¦
-解決他們指出的å•é¡Œã€‚
+.. _tw_resend_reminders:
-9)ä¸è¦æ´©æ°£æˆ–ä¸è€ç…©
--------------------
+ä¸è¦æ³„氣或ä¸è€ç…©
+----------------
-æ交更改後,請è€å¿ƒç­‰å¾…。審閱者是忙碌的人,å¯èƒ½ç„¡æ³•ç«‹å³è¨ªå•æ‚¨çš„修補程åºã€‚
+æ交更改後,請è€å¿ƒç­‰å¾…。審閱者是大忙人,å¯èƒ½ç„¡æ³•ç«‹å³å¯©é–±æ‚¨çš„補ä¸ã€‚
-曾幾何時,補ä¸æ›¾åœ¨æ²’有評論的情æ³ä¸‹æ¶ˆå¤±åœ¨ç©ºç™½ä¸­ï¼Œä½†é–‹ç™¼éŽç¨‹æ¯”ç¾åœ¨æ›´åŠ é †åˆ©ã€‚
-您應該在一周左å³çš„時間內收到評論;如果沒有收到評論,請確ä¿æ‚¨å·²å°‡è£œä¸ç™¼é€
-到正確的ä½ç½®ã€‚在é‡æ–°æ交或è¯ç¹«å¯©é–±è€…之å‰è‡³å°‘等待一周-在諸如åˆä½µçª—å£ä¹‹é¡žçš„
+曾幾何時,補ä¸æ›¾åœ¨æ²’收到評論的情æ³ä¸‹æ¶ˆå¤±åœ¨è™›ç©ºä¸­ï¼Œä½†ç¾åœ¨é–‹ç™¼éŽç¨‹æ‡‰è©²æ›´åŠ é †åˆ©äº†ã€‚
+您應該在一週左å³çš„時間內收到評論;如果沒有收到評論,請確ä¿æ‚¨å·²å°‡è£œä¸ç™¼é€
+到正確的ä½ç½®ã€‚在é‡æ–°æ交或è¯ç¹«å¯©é–±è€…之å‰è‡³å°‘等待一週——在諸如åˆä½µçª—å£ä¹‹é¡žçš„
ç¹å¿™æ™‚é–“å¯èƒ½æ›´é•·ã€‚
-10ï¼‰ä¸»é¡Œä¸­åŒ…å« PATCH
---------------------
-
-由於到linuså’Œlinux內核的電å­éƒµä»¶æµé‡å¾ˆé«˜ï¼Œé€šå¸¸æœƒåœ¨ä¸»é¡Œè¡Œå‰é¢åŠ ä¸Š[PATCH]
-å‰ç¶´. 這使Linus和其他內核開發人員更容易將補ä¸èˆ‡å…¶ä»–é›»å­éƒµä»¶è¨Žè«–å€åˆ†é–‹ã€‚
+在等了幾個星期後,用帶RESEND的主題é‡ç™¼è£œä¸ä¹Ÿæ˜¯å¯ä»¥çš„::
-11)簽署你的作å“-開發者原始èªè­‰
--------------------------------
+ [PATCH Vx RESEND] sub/sys: Condensed patch summary
-爲了加強å°èª°åšäº†ä½•äº‹çš„追蹤,尤其是å°é‚£äº›é€éŽå¥½å¹¾å±¤çš„維護者的補ä¸ï¼Œæˆ‘們
-建議在發é€å‡ºåŽ»çš„補ä¸ä¸ŠåŠ ä¸€å€‹ 「sign-off〠的éŽç¨‹ã€‚
+當你發佈補ä¸ï¼ˆç³»åˆ—)修改版的時候,ä¸è¦åŠ ä¸Šâ€œRESENDâ€â€”—“RESENDâ€åªé©ç”¨æ–¼é‡
+æ–°æ交之å‰æœªç¶“修改的補ä¸ï¼ˆç³»åˆ—)。
-"sign-off" 是在補ä¸çš„注釋的最後的簡單的一行文字,èªè­‰ä½ ç·¨å¯«äº†å®ƒæˆ–者其他
-人有權力將它作爲開放原始碼的補ä¸å‚³éžã€‚è¦å‰‡å¾ˆç°¡å–®ï¼šå¦‚果你能èªè­‰å¦‚下信æ¯:
-
-開發者來æºè­‰æ›¸ 1.1
-^^^^^^^^^^^^^^^^^^
-
-å°æ–¼æœ¬é …目的貢ç»ï¼Œæˆ‘èªè­‰å¦‚下信æ¯ï¼š
+ä¸»é¡Œä¸­åŒ…å« PATCH
+----------------
- (a)這些貢ç»æ˜¯å®Œå…¨æˆ–者部分的由我創建,我有權利以文件中指出
- 的開放原始碼許å¯è­‰æ交它;或者
- (b)這些貢ç»åŸºæ–¼ä»¥å‰çš„工作,據我所知,這些以å‰çš„工作å—æ°ç•¶çš„開放
- 原始碼許å¯è­‰ä¿è­·ï¼Œè€Œä¸”,根據許å¯è­‰ï¼Œæˆ‘有權æ交修改後的貢ç»ï¼Œ
- 無論是完全還是部分由我創造,這些貢ç»éƒ½ä½¿ç”¨åŒä¸€å€‹é–‹æ”¾åŽŸå§‹ç¢¼è¨±å¯è­‰
- (除éžæˆ‘被å…許用其它的許å¯è­‰ï¼‰ï¼Œæ­£å¦‚文件中指出的;或者
- (c)這些貢ç»ç”±èªè­‰ï¼ˆa),(b)或者(c)的人直接æ供給我,而
- 且我沒有修改它。
- (d)我ç†è§£ä¸¦åŒæ„這個項目和貢ç»æ˜¯å…¬é–‹çš„,貢ç»çš„記錄(包括我
- 一起æ交的個人記錄,包括 sign-off )被永久維護並且å¯ä»¥å’Œé€™å€‹é …ç›®
- 或者開放原始碼的許å¯è­‰åŒæ­¥åœ°å†ç™¼è¡Œã€‚
+由於到Linuså’Œlinux-kernelçš„é›»å­éƒµä»¶æµé‡å¾ˆé«˜ï¼Œé€šå¸¸æœƒåœ¨ä¸»é¡Œè¡Œå‰é¢åŠ ä¸Š[PATCH]
+å‰ç¶´ã€‚這使Linus和其他內核開發人員更容易將補ä¸èˆ‡å…¶ä»–é›»å­éƒµä»¶è¨Žè«–å€åˆ†é–‹ã€‚
-那麼加入這樣一行::
+``git send-email`` 會自動爲你加上。
- Signed-off-by: Random J Developer <random@developer.example.org>
+簽署你的作å“——開發者來æºèªè­‰
+------------------------------
-使用你的真å(抱歉,ä¸èƒ½ä½¿ç”¨å‡å或者匿å。)
+爲了加強å°èª°åšäº†ä½•äº‹çš„追蹤,尤其是å°é‚£äº›é€éŽå¥½å¹¾å±¤ç¶­è­·è€…æ‰æœ€çµ‚到é”的補ä¸ï¼Œæˆ‘
+們在通éŽéƒµä»¶ç™¼é€çš„補ä¸ä¸Šå¼•å…¥äº†â€œç°½ç½²ï¼ˆsign-off)â€æµç¨‹ã€‚
-有人在最後加上標籤。ç¾åœ¨é€™äº›æ±è¥¿æœƒè¢«å¿½ç•¥ï¼Œä½†æ˜¯ä½ å¯ä»¥é€™æ¨£åšï¼Œä¾†æ¨™è¨˜å…¬å¸
-內部的éŽç¨‹ï¼Œæˆ–者åªæ˜¯æŒ‡å‡ºé—œæ–¼ sign-off 的一些特殊細節。
+“簽署â€æ˜¯åœ¨è£œä¸è¨»é‡‹æœ€å¾Œçš„一行簡單文字,èªè­‰ä½ ç·¨å¯«äº†å®ƒæˆ–者其他
+人有權力將它作爲開放æºä»£ç¢¼çš„補ä¸å‚³éžã€‚è¦å‰‡å¾ˆç°¡å–®ï¼šå¦‚果你能èªè­‰å¦‚下信æ¯:
-如果您是å­ç³»çµ±æˆ–分支維護人員,有時需è¦ç¨å¾®ä¿®æ”¹æ”¶åˆ°çš„補ä¸ï¼Œä»¥ä¾¿åˆä½µå®ƒå€‘,
-因爲樹和æ交者中的代碼ä¸å®Œå…¨ç›¸åŒã€‚如果你嚴格éµå®ˆè¦å‰‡ï¼ˆc),你應該è¦æ±‚æ交者
-é‡æ–°ç™¼å¸ƒï¼Œä½†é€™å®Œå…¨æ˜¯åœ¨æµªè²»æ™‚間和精力。è¦å‰‡ï¼ˆb)å…許您調整代碼,但是更改一個
-æ交者的代碼並讓他èªå¯æ‚¨çš„錯誤是éžå¸¸ä¸ç¦®è²Œçš„。è¦è§£æ±ºæ­¤å•é¡Œï¼Œå»ºè­°åœ¨æœ€å¾Œä¸€å€‹
-由簽å行和您的行之間添加一行,指示更改的性質。雖然這並ä¸æ˜¯å¼·åˆ¶æ€§çš„,但似乎
-在æè¿°å‰åŠ ä¸Šæ‚¨çš„郵件和/或姓å(全部用方括號括起來),這足以讓人注æ„到您å°æœ€
-後一分é˜çš„更改負有責任。例如::
+開發者來æºèªè­‰ 1.1
+^^^^^^^^^^^^^^^^^^
- Signed-off-by: Random J Developer <random@developer.example.org>
- [lucky@maintainer.example.org: struct foo moved from foo.c to foo.h]
- Signed-off-by: Lucky K Maintainer <lucky@maintainer.example.org>
+å°æ–¼æœ¬é …目的貢ç»ï¼Œæˆ‘èªè­‰å¦‚下信æ¯ï¼š
-如果您維護一個穩定的分支機構,åŒæ™‚希望å°ä½œè€…進行致è¬ã€è·Ÿè¹¤æ›´æ”¹ã€åˆä½µä¿®å¾©ä¸¦
-ä¿è­·æ交者ä¸å—投訴,那麼這種åšæ³•å°¤å…¶æœ‰ç”¨ã€‚請注æ„,在任何情æ³ä¸‹éƒ½ä¸èƒ½æ›´æ”¹ä½œè€…
-çš„ID(From 頭),因爲它是出ç¾åœ¨æ›´æ”¹æ—¥èªŒä¸­çš„標識。
+ (a) 這些貢ç»æ˜¯å®Œå…¨æˆ–者部分的由我創建,我有權利以文件中指出
+ 的開放æºä»£ç¢¼è¨±å¯è­‰æ交它;或者
-å°å›žåˆï¼ˆback-porters)的特別說明:在æ交消æ¯çš„頂部(主題行之後)æ’入一個補ä¸
-çš„èµ·æºæŒ‡ç¤ºä¼¼ä¹Žæ˜¯ä¸€ç¨®å¸¸è¦‹ä¸”有用的實è¸ï¼Œä»¥ä¾¿æ–¼è·Ÿè¹¤ã€‚例如,下é¢æ˜¯æˆ‘們在3.x穩定
-版本中看到的內容::
+ (b) 這些貢ç»åŸºæ–¼ä»¥å‰çš„工作,據我所知,這些以å‰çš„工作å—æ°ç•¶çš„開放
+ æºä»£ç¢¼è¨±å¯è­‰ä¿è­·ï¼Œè€Œä¸”,根據文件中指出的許å¯è­‰ï¼Œæˆ‘有權æ交修改後的貢ç»ï¼Œ
+ 無論是完全還是部分由我創造,這些貢ç»éƒ½ä½¿ç”¨åŒä¸€å€‹é–‹æ”¾æºä»£ç¢¼è¨±å¯è­‰
+ (除éžæˆ‘被å…許用其它的許å¯è­‰ï¼‰ï¼›æˆ–者
- Date: Tue Oct 7 07:26:38 2014 -0400
+ (c) 這些貢ç»ç”±èªè­‰ï¼ˆa),(b)或者(c)的人直接æ供給我,而
+ 且我沒有修改它。
- libata: Un-break ATA blacklist
+ (d) 我ç†è§£ä¸¦åŒæ„這個項目和貢ç»æ˜¯å…¬é–‹çš„,貢ç»çš„記錄(包括我
+ 一起æ交的個人記錄,包括sign-off)被永久維護並且å¯ä»¥å’Œé€™å€‹é …ç›®
+ 或者開放æºä»£ç¢¼çš„許å¯è­‰åŒæ­¥åœ°å†ç™¼è¡Œã€‚
- commit 1c40279960bcd7d52dbdf1d466b20d24b99176c8 upstream.
+那麼加入這樣一行::
-還有, 這裡是一個舊版內核中的一個回åˆè£œä¸::
+ Signed-off-by: Random J Developer <random@developer.example.org>
- Date: Tue May 13 22:12:27 2008 +0200
+使用你的真å(抱歉,ä¸èƒ½ä½¿ç”¨å‡å或者匿å。)如果使用 ``git commit -s`` 的話
+將會自動完æˆã€‚撤銷也應當包å«â€œSigned-off-byâ€ï¼Œ ``git revert -s`` 會幫你æžå®šã€‚
- wireless, airo: waitbusy() won't delay
+有些人會在最後加上é¡å¤–的標籤。ç¾åœ¨é€™äº›æ±è¥¿æœƒè¢«å¿½ç•¥ï¼Œä½†æ˜¯ä½ å¯ä»¥é€™æ¨£åšï¼Œä¾†æ¨™è¨˜
+å…¬å¸å…§éƒ¨çš„éŽç¨‹ï¼Œæˆ–者åªæ˜¯æŒ‡å‡ºé—œæ–¼ç°½ç½²çš„一些特殊細節。
- [backport of 2.6 commit b7acbdfbd1f277c1eb23f344f899cfa4cd0bf36a]
+作者簽署之後的任何其他簽署(Signed-off-by:'s)å‡ä¾†è‡ªè™•ç†å’Œå‚³éžè£œä¸çš„人員,但
+未åƒèˆ‡å…¶é–‹ç™¼ã€‚簽署éˆæ‡‰ç•¶å映補ä¸å‚³æ’­åˆ°ç¶­è­·è€…並最終傳播到Linus所經éŽçš„ **真實**
+路徑,首個簽署指明單個作者的主è¦ä½œè€…身份。
-12)何時使用Acked-by:,CC:,和Co-Developed by:
-----------------------------------------------
+何時使用Acked-by:,CC:,和Co-Developed by:
+------------------------------------------
-Singed-off-by: 標記表示簽å者åƒèˆ‡äº†è£œä¸çš„開發,或者他/她在補ä¸çš„傳éžè·¯å¾‘中。
+Singed-off-by: 標籤表示簽å者åƒèˆ‡äº†è£œä¸çš„開發,或者他/她在補ä¸çš„傳éžè·¯å¾‘中。
-如果一個人沒有直接åƒèˆ‡è£œä¸çš„準備或處ç†ï¼Œä½†å¸Œæœ›è¡¨ç¤ºä¸¦è¨˜éŒ„他們å°è£œä¸çš„批准,
-那麼他們å¯ä»¥è¦æ±‚在補ä¸çš„變更日誌中添加一個 Acked-by:
+如果一個人沒有直接åƒèˆ‡è£œä¸çš„準備或處ç†ï¼Œä½†å¸Œæœ›è¡¨ç¤ºä¸¦è¨˜éŒ„他們å°è£œä¸çš„批准/è´Šæˆï¼Œ
+那麼他們å¯ä»¥è¦æ±‚在補ä¸çš„變更日誌中添加一個Acked-by:。
-Acked-by:通常由å—影響代碼的維護者使用,當該維護者既沒有貢ç»ä¹Ÿæ²’有轉發補ä¸æ™‚。
+Acked-by: 通常由å—影響代碼的維護者使用,當該維護者既沒有貢ç»ä¹Ÿæ²’有轉發補ä¸æ™‚。
-Acked-by: ä¸åƒç°½å­—人那樣正å¼ã€‚這是一個記錄,確èªäººè‡³å°‘審查了補ä¸ï¼Œä¸¦è¡¨ç¤ºæŽ¥å—。
-因此,補ä¸åˆä½µæœ‰æ™‚會手動將Acker的「Yep,looks good to meã€è½‰æ›çˆ² Acked-By:(但
+Acked-by: ä¸åƒç°½ç½²é‚£æ¨£æ­£å¼ã€‚這是一個記錄,確èªäººè‡³å°‘審閱了補ä¸ï¼Œä¸¦è¡¨ç¤ºæŽ¥å—。
+因此,補ä¸åˆä½µæœ‰æ™‚會手動將Acker的“Yep,looks good to meâ€è½‰æ›çˆ² Acked-By:(但
請注æ„,通常最好è¦æ±‚一個明確的Ack)。
Acked-by:ä¸ä¸€å®šè¡¨ç¤ºå°æ•´å€‹è£œä¸çš„確èªã€‚例如,如果一個補ä¸å½±éŸ¿å¤šå€‹å­ç³»çµ±ï¼Œä¸¦ä¸”
-有一個:來自一個å­ç³»çµ±ç¶­è­·è€…,那麼這通常表示åªç¢ºèªå½±éŸ¿ç¶­è­·è€…代碼的部分。這裡
-應該仔細判斷。如有疑å•ï¼Œæ‡‰åƒè€ƒéƒµä»¶åˆ—表檔案中的原始討論。
+有一個來自æŸå€‹å­ç³»çµ±ç¶­è­·è€…çš„Acked-By:,那麼這通常表示åªç¢ºèªå½±éŸ¿ç¶­è­·è€…代碼的部
+分。這è£æ‡‰è©²ä»”細判斷。如有疑å•ï¼Œæ‡‰åƒè€ƒéƒµä»¶åˆ—表存檔中的原始討論。
-如果æŸäººæœ‰æ©Ÿæœƒå°è£œä¸é€²è¡Œè©•è«–,但沒有æ供此類評論,您å¯ä»¥é¸æ“‡åœ¨è£œä¸ä¸­æ·»åŠ  ``Cc:``
-這是唯一一個標籤,它å¯ä»¥åœ¨æ²’有被它命å的人顯å¼æ“作的情æ³ä¸‹æ·»åŠ ï¼Œä½†å®ƒæ‡‰è©²è¡¨æ˜Ž
-這個人是在補ä¸ä¸ŠæŠ„é€çš„。討論中包å«äº†æ½›åœ¨åˆ©ç›Šç›¸é—œæ–¹ã€‚
+如果æŸäººæœ¬æ‡‰æœ‰æ©Ÿæœƒå°è£œä¸é€²è¡Œè©•è«–,但沒有æ供此類評論,您å¯ä»¥é¸æ“‡åœ¨è£œä¸ä¸­æ·»åŠ 
+``Cc:`` 這是唯一å¯ä»¥åœ¨æ²’有被該人明確åŒæ„的情æ³ä¸‹æ·»åŠ çš„標籤——但它應該表明
+這個人是在補ä¸ä¸ŠæŠ„é€çš„。此標籤記錄了討論中包å«çš„潛在利益相關方。
Co-developed-by: è²æ˜Žè£œä¸æ˜¯ç”±å¤šå€‹é–‹ç™¼äººå“¡å…±åŒå‰µå»ºçš„;當幾個人在一個補ä¸ä¸Šå·¥
-作時,它用於將屬性賦予共åŒä½œè€…(除了 From: 所賦予的作者之外)。因爲
-Co-developed-by: 表示作者身份,所以æ¯å€‹å…±åŒé–‹ç™¼äººï¼šå¿…須緊跟在相關åˆä½œä½œè€…çš„
-ç°½å之後。標準的簽核程åºè¦æ±‚:標記的簽核順åºæ‡‰å„˜å¯èƒ½å映補ä¸çš„時間歷å²ï¼Œè€Œä¸
-ç®¡ä½œè€…æ˜¯é€šéŽ From :還是由 Co-developed-by: å…±åŒé–‹ç™¼çš„。值得注æ„的是,最後一
-個簽字人:必須始終是æ交補ä¸çš„開發人員。
+作時,它用於給出共åŒä½œè€…(除了From:所給出的作者之外)。因爲Co-developed-by:
+表示作者身份,所以æ¯å€‹Co-developed-by:必須緊跟在相關åˆä½œä½œè€…的簽署之後。標準
+簽署程åºè¦æ±‚Singed-off-by:標籤的順åºæ‡‰å„˜å¯èƒ½å映補ä¸çš„時間歷å²ï¼Œç„¡è«–作者是通
+éŽFrom:還是Co-developed-by:表明。值得注æ„的是,最後一個Singed-off-by:必須是
+æ交補ä¸çš„開發人員。
-注æ„,當作者也是電å­éƒµä»¶æ¨™é¡Œã€Œç™¼ä»¶äººï¼šã€è¡Œä¸­åˆ—出的人時,「From: 〠標記是å¯é¸çš„。
+注æ„,如果From:作者也是電å­éƒµä»¶æ¨™é¡Œçš„From:行中列出的人,則From:標籤是å¯é¸çš„。
-作者æ交的補ä¸ç¨‹åºç¤ºä¾‹::
+被From:作者æ交的補ä¸ç¤ºä¾‹::
<changelog>
@@ -423,7 +375,7 @@ Co-developed-by: 表示作者身份,所以æ¯å€‹å…±åŒé–‹ç™¼äººï¼šå¿…須緊跟
Signed-off-by: Second Co-Author <second@coauthor.example.org>
Signed-off-by: From Author <from@author.example.org>
-åˆä½œé–‹ç™¼è€…æ交的補ä¸ç¤ºä¾‹::
+被åˆä½œé–‹ç™¼è€…æ交的補ä¸ç¤ºä¾‹::
From: From Author <from@author.example.org>
@@ -436,106 +388,115 @@ Co-developed-by: 表示作者身份,所以æ¯å€‹å…±åŒé–‹ç™¼äººï¼šå¿…須緊跟
Signed-off-by: Submitting Co-Author <sub@coauthor.example.org>
-13)使用報告人:ã€æ¸¬è©¦äººï¼šã€å¯©æ ¸äººï¼šã€å»ºè­°äººï¼šã€ä¿®å¾©äººï¼š
---------------------------------------------------------
+使用Reported-by:ã€Tested-by:ã€Reviewed-by:ã€Suggested-by:å’ŒFixes:
+-----------------------------------------------------------------
Reported-by: 給那些發ç¾éŒ¯èª¤ä¸¦å ±å‘ŠéŒ¯èª¤çš„人致è¬ï¼Œå®ƒå¸Œæœ›æ¿€å‹µä»–們在將來å†æ¬¡å¹«åŠ©
-我們。請注æ„,如果bug是以ç§æœ‰æ–¹å¼å ±å‘Šçš„,那麼在使用Reported-by標記之å‰ï¼Œè«‹
-先請求權é™ã€‚
+我們。請注æ„,如果bug是以ç§æœ‰æ–¹å¼å ±å‘Šçš„,那麼在使用Reported-by標籤之å‰ï¼Œè«‹
+先請求許å¯ã€‚此標籤是爲Bug設計的;請ä¸è¦å°‡å…¶ç”¨æ–¼æ„Ÿè¬åŠŸèƒ½è«‹æ±‚。
-Tested-by: 標記表示補ä¸å·²ç”±æŒ‡å®šçš„人(在æŸäº›ç’°å¢ƒä¸­ï¼‰æˆåŠŸæ¸¬è©¦ã€‚這個標籤通知
-維護人員已經執行了一些測試,爲將來的補ä¸æ供了一種定ä½æ¸¬è©¦äººå“¡çš„方法,並確
-ä¿æ¸¬è©¦äººå“¡çš„信譽。
+Tested-by: 標籤表示補ä¸å·²ç”±æŒ‡å®šçš„人(在æŸäº›ç’°å¢ƒä¸­ï¼‰æˆåŠŸæ¸¬è©¦ã€‚這個標籤通知
+維護人員已經執行了一些測試,爲將來的補ä¸æ供了一種定ä½æ¸¬è©¦äººå“¡çš„方法,並彰顯測試人員的功勞。
-Reviewed-by:相å,根據審查人的è²æ˜Žï¼Œè¡¨æ˜Žè©²è£œä¸å·²è¢«å¯©æŸ¥ä¸¦è¢«èªçˆ²æ˜¯å¯æŽ¥å—的:
+Reviewed-by:根據審閱者的監ç£è²æ˜Žï¼Œè¡¨æ˜Žè©²è£œä¸å·²è¢«å¯©é–±ä¸¦è¢«èªçˆ²æ˜¯å¯æŽ¥å—的:
-審查人的監ç£è²æ˜Ž
+審閱者的監ç£è²æ˜Ž
^^^^^^^^^^^^^^^^
-通éŽæ供我的 Reviewed-by,我è²æ˜Žï¼š
+通éŽæ供我的Reviewed-by:標籤,我è²æ˜Žï¼š
- (a) 我已經å°é€™å€‹è£œä¸é€²è¡Œäº†ä¸€æ¬¡æŠ€è¡“審查,以評估它是å¦é©åˆè¢«åŒ…å«åˆ°
+ (a) 我已經å°é€™å€‹è£œä¸é€²è¡Œäº†ä¸€æ¬¡æŠ€è¡“審閱,以評估它是å¦é©åˆè¢«åŒ…å«åˆ°
主線內核中。
(b) 與補ä¸ç›¸é—œçš„任何å•é¡Œã€é¡§æ…®æˆ–å•é¡Œéƒ½å·²å饋給æ交者。我å°æ交者å°
我的評論的回應感到滿æ„。
- (c) 雖然這一æ交å¯èƒ½æœƒæ”¹é€²ä¸€äº›æ±è¥¿ï¼Œä½†æˆ‘相信,此時,(1)å°å…§æ ¸
+ (c) 雖然這一æ交å¯èƒ½ä»å¯è¢«æ”¹é€²ï¼Œä½†æˆ‘相信,此時,(1)å°å…§æ ¸
進行了有價值的修改,(2)沒有包å«çˆ­è«–中涉åŠçš„已知å•é¡Œã€‚
- (d) 雖然我已經審查了補ä¸ä¸¦èªçˆ²å®ƒæ˜¯å¥å…¨çš„,但我ä¸æœƒï¼ˆé™¤éžå¦æœ‰æ˜Žç¢º
- 說明)作出任何ä¿è­‰æˆ–ä¿è­‰å®ƒå°‡åœ¨ä»»ä½•çµ¦å®šæƒ…æ³ä¸‹å¯¦ç¾å…¶è¦å®šçš„目的
+ (d) 雖然我已經審閱了補ä¸ä¸¦èªçˆ²å®ƒæ˜¯å¥å…¨çš„,但我ä¸æœƒï¼ˆé™¤éžå¦æœ‰æ˜Žç¢º
+ 說明)作出任何ä¿è­‰æˆ–æ“”ä¿å®ƒæœƒåœ¨ä»»ä½•çµ¦å®šæƒ…æ³ä¸‹å¯¦ç¾å…¶è¦å®šçš„目的
或正常é‹è¡Œã€‚
-Reviewed-by 是一種觀點è²æ˜Žï¼Œå³è£œä¸æ˜¯å°å…§æ ¸çš„é©ç•¶ä¿®æ”¹ï¼Œæ²’有任何éºç•™çš„åš´é‡æŠ€è¡“
-å•é¡Œã€‚任何感興趣的審閱者(完æˆå·¥ä½œçš„人)都å¯ä»¥çˆ²ä¸€å€‹è£œä¸æ供一個 Review-by
-標籤。此標籤用於å‘審閱者æ供致è¬ï¼Œä¸¦é€šçŸ¥ç¶­è­·è€…已在修補程åºä¸Šå®Œæˆçš„審閱程度。
-Reviewed-by: 當由已知了解主題å€åŸŸä¸¦åŸ·è¡Œå¾¹åº•æª¢æŸ¥çš„審閱者æ供時,通常會增加
+Reviewed-by是一種觀點è²æ˜Žï¼Œå³è£œä¸æ˜¯å°å…§æ ¸çš„é©ç•¶ä¿®æ”¹ï¼Œæ²’有任何éºç•™çš„åš´é‡æŠ€è¡“
+å•é¡Œã€‚任何感興趣的審閱者(完æˆå·¥ä½œçš„人)都å¯ä»¥çˆ²ä¸€å€‹è£œä¸æ供一個Reviewed-by
+標籤。此標籤用於å‘審閱者æ供致è¬ï¼Œä¸¦é€šçŸ¥ç¶­è­·è€…補ä¸çš„審閱進度。
+當Reviewed-by:標籤由已知了解主題å€åŸŸä¸¦åŸ·è¡Œå¾¹åº•æª¢æŸ¥çš„審閱者æ供時,通常會增加
補ä¸é€²å…¥å…§æ ¸çš„å¯èƒ½æ€§ã€‚
+一旦從測試人員或審閱者的“Tested-byâ€å’Œâ€œReviewed-byâ€æ¨™ç±¤å‡ºç¾åœ¨éƒµä»¶åˆ—表中,
+作者應在發é€ä¸‹ä¸€å€‹ç‰ˆæœ¬æ™‚將其添加到é©ç”¨çš„補ä¸ä¸­ã€‚但是,如果補ä¸åœ¨ä»¥ä¸‹ç‰ˆæœ¬ä¸­ç™¼
+生了實質性更改,這些標籤å¯èƒ½ä¸å†é©ç”¨ï¼Œå› æ­¤æ‡‰è©²åˆªé™¤ã€‚通常,在補ä¸æ›´æ”¹æ—¥èªŒä¸­
+(在 ``---`` 分隔符之後)應該æ到刪除æŸäººçš„測試者或審閱者標籤。
+
Suggested-by: 表示補ä¸çš„想法是由指定的人æ出的,並確ä¿å°‡æ­¤æƒ³æ³•æ­¸åŠŸæ–¼æŒ‡å®šçš„
-人。請注æ„,未經許å¯ï¼Œä¸å¾—添加此標籤,特別是如果該想法未在公共論壇上發布。
-這就是說,如果我們勤快地致è¬æˆ‘們的創æ„者,他們很有希望在未來得到鼓舞,å†æ¬¡
+人。請注æ„,未經許å¯ï¼Œä¸å¾—添加此標籤,特別是如果該想法未在公共論壇上發佈。
+也就是說,如果我們勤快地致è¬å‰µæ„æ供者,他們將å—到鼓舞,很有希望在未來å†æ¬¡
幫助我們。
-Fixes: 指示補ä¸åœ¨ä»¥å‰çš„æ交中修復了一個å•é¡Œã€‚它å¯ä»¥å¾ˆå®¹æ˜“地確定錯誤的來æºï¼Œ
-這有助於檢查錯誤修復。這個標記還幫助穩定內核團隊確定應該接收修復的穩定內核
-版本。這是指示補ä¸ä¿®å¾©çš„錯誤的首é¸æ–¹æ³•ã€‚è«‹åƒé–± :ref:`tw_describe_changes`
-æ述您的更改以了解更多詳細信æ¯ã€‚
+Fixes: 指示補ä¸ä¿®å¾©äº†ä¹‹å‰æ交的一個å•é¡Œã€‚它å¯ä»¥ä¾¿æ–¼ç¢ºå®šéŒ¯èª¤çš„來æºï¼Œé€™æœ‰åŠ©æ–¼
+檢查錯誤修復。這個標籤還幫助穩定內核團隊確定應該接收修復的穩定內核版本。這是
+指示補ä¸ä¿®å¾©çš„錯誤的首é¸æ–¹æ³•ã€‚è«‹åƒé–± :ref:`zh_describe_changes` 瞭解更多信æ¯ã€‚
+
+.. note::
+
+ 附加Fixes:標籤ä¸æœƒæ”¹è®Šç©©å®šå…§æ ¸è¦å‰‡æµç¨‹ï¼Œä¹Ÿä¸æ”¹è®Šæ‰€æœ‰ç©©å®šç‰ˆè£œä¸æŠ„é€
+ stable@vger.kernel.orgçš„è¦æ±‚。有關更多信æ¯ï¼Œè«‹é–±è®€
+ Documentation/translations/zh_CN/process/stable-kernel-rules.rst 。
.. _tw_the_canonical_patch_format:
-12)標準補ä¸æ ¼å¼
-----------------
+標準補ä¸æ ¼å¼
+------------
本節æ述如何格å¼åŒ–補ä¸æœ¬èº«ã€‚請注æ„,如果您的補ä¸å­˜å„²åœ¨ ``Git`` 存儲庫中,則
-å¯ä»¥ä½¿ç”¨ ``git format-patch`` 進行正確的補ä¸æ ¼å¼è¨­ç½®ã€‚但是,這些工具無法創建
+å¯ä»¥ä½¿ç”¨ ``git format-patch`` 進行正確的補ä¸æ ¼å¼åŒ–。但是,這些工具無法創建
å¿…è¦çš„文本,因此請務必閱讀下é¢çš„說明。
-標準的補ä¸ï¼Œæ¨™é¡Œè¡Œæ˜¯::
+標準的補ä¸æ¨™é¡Œè¡Œæ˜¯::
Subject: [PATCH 001/123] å­ç³»çµ±:一å¥è©±æ¦‚è¿°
-標準補ä¸çš„信體存在如下部分:
+標準補ä¸çš„信體包å«å¦‚下部分:
- - 一個 "from" 行指出補ä¸ä½œè€…。後跟空行(僅當發é€ä¿®è£œç¨‹åºçš„人ä¸æ˜¯ä½œè€…時æ‰éœ€è¦ï¼‰ã€‚
+ - 一個 ``from`` 行指出補ä¸ä½œè€…。後跟空行(僅當發é€è£œä¸çš„人ä¸æ˜¯ä½œè€…時æ‰éœ€è¦ï¼‰ã€‚
- - 解釋的正文,行以75列包è£ï¼Œé€™å°‡è¢«è¤‡è£½åˆ°æ°¸ä¹…變更日誌來æ述這個補ä¸ã€‚
+ - 說明文字,æ¯è¡Œæœ€é•·75列,這將被複制到永久變更日誌來æ述這個補ä¸ã€‚
- 一個空行
- - 上é¢æ述的「Signed-off-by〠行,也將出ç¾åœ¨æ›´æ”¹æ—¥èªŒä¸­ã€‚
+ - 上述的 ``Signed-off-by:`` 行,也將出ç¾åœ¨æ›´æ”¹æ—¥èªŒä¸­ã€‚
- åªåŒ…å« ``---`` 的標記線。
- - 任何其他ä¸é©åˆæ”¾åœ¨è®Šæ›´æ—¥èªŒçš„注釋。
+ - 任何其他ä¸é©åˆæ”¾åœ¨è®Šæ›´æ—¥èªŒçš„註釋。
- 實際補ä¸ï¼ˆ ``diff`` 輸出)。
-標題行的格å¼ï¼Œä½¿å¾—å°æ¨™é¡Œè¡ŒæŒ‰å­—æ¯åºæŽ’åºéžå¸¸çš„容易 - 很多 e-mail 客戶端都
-å¯ä»¥æ”¯æŒ - 因爲åºåˆ—號是用零填充的,所以按數字排åºå’ŒæŒ‰å­—æ¯æŽ’åºæ˜¯ä¸€æ¨£çš„。
+標題行的格å¼ï¼Œä½¿å¾—å°æ¨™é¡Œè¡ŒæŒ‰å­—æ¯åºæŽ’åºéžå¸¸çš„容易——很多郵件客戶端都
+å¯ä»¥æ”¯æŒâ€”—因爲åºåˆ—號是用零填充的,所以按數字排åºå’ŒæŒ‰å­—æ¯æŽ’åºæ˜¯ä¸€æ¨£çš„。
-e-mail 標題中的「å­ç³»çµ±ã€æ¨™è­˜å“ªå€‹å…§æ ¸å­ç³»çµ±å°‡è¢«æ‰“補ä¸ã€‚
+郵件標題中的“å­ç³»çµ±â€æ¨™è­˜å“ªå€‹å…§æ ¸å­ç³»çµ±å°‡è¢«æ‰“補ä¸ã€‚
-e-mail 標題中的「一å¥è©±æ¦‚è¿°ã€æ‰¼è¦çš„æè¿° e-mail 中的補ä¸ã€‚「一å¥è©±æ¦‚è¿°ã€
-ä¸æ‡‰è©²æ˜¯ä¸€å€‹æ–‡ä»¶å。å°æ–¼ä¸€å€‹è£œä¸ç³»åˆ—(「補ä¸ç³»åˆ—ã€æŒ‡ä¸€ç³»åˆ—的多個相關補
-ä¸ï¼‰ï¼Œä¸è¦å°æ¯å€‹è£œä¸éƒ½ä½¿ç”¨åŒæ¨£çš„「一å¥è©±æ¦‚è¿°ã€ã€‚
+郵件標題中的“一å¥è©±æ¦‚è¿°â€æ‰¼è¦çš„æ述郵件中的補ä¸ã€‚“一å¥è©±æ¦‚è¿°â€
+ä¸æ‡‰è©²æ˜¯ä¸€å€‹æ–‡ä»¶å。å°æ–¼ä¸€å€‹è£œä¸ç³»åˆ—(“補ä¸ç³»åˆ—â€æŒ‡ä¸€ç³»åˆ—的多個相關補
+ä¸ï¼‰ï¼Œä¸è¦å°æ¯å€‹è£œä¸éƒ½ä½¿ç”¨åŒæ¨£çš„“一å¥è©±æ¦‚è¿°â€ã€‚
-è¨˜ä½ e-mail 的「一å¥è©±æ¦‚è¿°ã€æœƒæˆçˆ²è©²è£œä¸çš„全局唯一標識。它會蔓延到 git
-的改動記錄里。然後「一å¥è©±æ¦‚è¿°ã€æœƒè¢«ç”¨åœ¨é–‹ç™¼è€…的討論里,用來指代這個補
-ä¸ã€‚ç”¨æˆ¶å°‡å¸Œæœ›é€šéŽ google 來æœç´¢"一å¥è©±æ¦‚è¿°"來找到那些討論這個補ä¸çš„æ–‡
+記ä½éƒµä»¶çš„“一å¥è©±æ¦‚è¿°â€æœƒæˆçˆ²è©²è£œä¸çš„全局唯一標識。它會進入 ``git``
+的改動記錄è£ã€‚然後“一å¥è©±æ¦‚è¿°â€æœƒè¢«ç”¨åœ¨é–‹ç™¼è€…的討論è£ï¼Œç”¨ä¾†æŒ‡ä»£é€™å€‹è£œ
+ä¸ã€‚用戶將希望通éŽæœç´¢å¼•æ“Žæœç´¢â€œä¸€å¥è©±æ¦‚è¿°â€ä¾†æ‰¾åˆ°é‚£äº›è¨Žè«–這個補ä¸çš„æ–‡
章。當人們在兩三個月後使用諸如 ``gitk`` 或 ``git log --oneline`` 之類
的工具查看數åƒå€‹è£œä¸æ™‚,也會很快看到它。
出於這些原因,概述必須ä¸è¶…éŽ70-75個字符,並且必須æ述補ä¸çš„更改以åŠçˆ²
-什麼需è¦è£œä¸ã€‚æ—¢è¦ç°¡æ½”åˆè¦æ述性很有挑戰性,但寫得好的概述應該這樣åšã€‚
+什麼需è¦è£œä¸ã€‚æ—¢è¦ç°¡æ½”åˆè¦æ述性很有挑戰性,但寫得好的概述應該這樣。
-概述的å‰ç¶´å¯ä»¥ç”¨æ–¹æ‹¬è™Ÿæ‹¬èµ·ä¾†ï¼šã€ŒSubject: [PATCH <tag>...] <概述>ã€ã€‚標記
+概述的å‰ç¶´å¯ä»¥ç”¨æ–¹æ‹¬è™Ÿæ‹¬èµ·ä¾†ï¼šâ€œSubject: [PATCH <tag>...] <概述>â€ã€‚標記
ä¸è¢«è¦–爲概述的一部分,而是æ述應該如何處ç†è£œä¸ã€‚如果補ä¸çš„多個版本已發
-é€å‡ºä¾†ä»¥éŸ¿æ‡‰è©•å¯©ï¼ˆå³ã€Œv1,v2,v3ã€ï¼‰æˆ–「rfcã€ï¼Œä»¥æŒ‡ç¤ºè©•å¯©è«‹æ±‚,那麼通用標記
-å¯èƒ½åŒ…括版本æ述符。如果一個補ä¸ç³»åˆ—中有四個補ä¸ï¼Œé‚£éº¼å„個補ä¸å¯ä»¥é€™æ¨£
-編號:1/4ã€2/4ã€3/4ã€4/4。這å¯ä»¥ç¢ºä¿é–‹ç™¼äººå“¡äº†è§£è£œä¸æ‡‰ç”¨çš„é †åºï¼Œä¸¦ä¸”他們
+é€å‡ºä¾†ä»¥éŸ¿æ‡‰è©•å¯©ï¼ˆå³â€œv1,v2,v3â€ï¼‰å‰‡å¿…須包å«ç‰ˆæœ¬è™Ÿï¼Œæˆ–包å«â€œRFCâ€ä»¥æŒ‡ç¤º
+評審請求。如果一個補ä¸ç³»åˆ—中有四個補ä¸ï¼Œé‚£éº¼å„個補ä¸å¯ä»¥é€™æ¨£ç·¨è™Ÿï¼š1/4ã€2/4ã€
+3/4ã€4/4。這å¯ä»¥ç¢ºä¿é–‹ç™¼äººå“¡çž­è§£è£œä¸æ‡‰ç”¨çš„é †åºï¼Œä¸”
已經查看或應用了補ä¸ç³»åˆ—中的所有補ä¸ã€‚
一些標題的例å­::
@@ -543,95 +504,134 @@ e-mail 標題中的「一å¥è©±æ¦‚è¿°ã€æ‰¼è¦çš„æè¿° e-mail 中的補ä¸ã€‚ã€
Subject: [patch 2/5] ext2: improve scalability of bitmap searching
Subject: [PATCHv2 001/207] x86: fix eflags tracking
-"From" 行是信體裡的最上é¢ä¸€è¡Œï¼Œå…·æœ‰å¦‚下格å¼ï¼š
+``From`` 行是信體è£çš„最上é¢ä¸€è¡Œï¼Œå…·æœ‰å¦‚下格å¼::
+
From: Patch Author <author@example.com>
-"From" 行指明在永久改動日誌里,誰會被確èªçˆ²ä½œè€…。如果沒有 "From" 行,那
-麼郵件頭裡的 "From: " 行會被用來決定改動日誌中的作者。
+``From`` 行指明在永久改動日誌è£ï¼Œèª°æœƒè¢«ç¢ºèªçˆ²ä½œè€…。如果沒有 ``From`` 行,那
+麼郵件頭è£çš„ ``From:`` 行會被用來決定改動日誌中的作者。
-說明的主題將會被æ交到永久的原始碼改動日誌里,因此å°é‚£äº›æ—©å·²ç¶“ä¸è¨˜å¾—å’Œ
-這個補ä¸ç›¸é—œçš„討論細節的有能力的讀者來說,是有æ„義的。包括補ä¸ç¨‹åºå®šä½
-錯誤的(內核日誌消æ¯ã€OOPS消æ¯ç­‰ï¼‰ç—‡ç‹€ï¼Œå°æ–¼æœç´¢æ交日誌以尋找é©ç”¨è£œä¸çš„人
-尤其有用。如果一個補ä¸ä¿®å¾©äº†ä¸€å€‹ç·¨è­¯å¤±æ•—,那麼å¯èƒ½ä¸éœ€è¦åŒ…å«æ‰€æœ‰ç·¨è­¯å¤±æ•—ï¼›
+說明文字將會被æ交到永久的æºä»£ç¢¼æ”¹å‹•æ—¥èªŒè£ï¼Œå› æ­¤æ‡‰é‡å°é‚£äº›æ—©å·²ç¶“ä¸è¨˜å¾—和這
+個補ä¸ç›¸é—œçš„討論細節的讀者。包括補ä¸è™•ç†çš„故障症狀(內核日誌消æ¯ã€oops消æ¯
+等),這å°æ–¼å¯èƒ½æ­£åœ¨æœç´¢æ交日誌以查找é©ç”¨è£œä¸çš„人特別有用。文本應該寫得如
+此詳細,以便在數週ã€æ•¸æœˆç”šè‡³æ•¸å¹´å¾Œé–±è®€æ™‚,能夠爲讀者æ供所需的細節信æ¯ï¼Œä»¥
+掌æ¡å‰µå»ºè£œä¸çš„ **原因** 。
+
+如果一個補ä¸ä¿®å¾©äº†ä¸€å€‹ç·¨è­¯å¤±æ•—,那麼å¯èƒ½ä¸éœ€è¦åŒ…å« *所有* 編譯失敗;
åªè¦è¶³å¤ è®“æœç´¢è£œä¸çš„人能夠找到它就行了。與概述一樣,既è¦ç°¡æ½”åˆè¦æ述性。
-"---" 標記行å°æ–¼è£œä¸è™•ç†å·¥å…·è¦æ‰¾åˆ°å“ªè£¡æ˜¯æ”¹å‹•æ—¥èªŒä¿¡æ¯çš„çµæŸï¼Œæ˜¯ä¸å¯ç¼ºå°‘
+``---`` 標記行å°æ–¼è£œä¸è™•ç†å·¥å…·è¦æ‰¾åˆ°å“ªè£æ˜¯æ”¹å‹•æ—¥èªŒä¿¡æ¯çš„çµæŸï¼Œæ˜¯ä¸å¯ç¼ºå°‘
的。
-å°æ–¼ "---" 標記之後的é¡å¤–註解,一個好的用途就是用來寫 diffstat,用來顯
-示修改了什麼文件和æ¯å€‹æ–‡ä»¶éƒ½å¢žåŠ å’Œåˆªé™¤äº†å¤šå°‘行。diffstat å°æ–¼æ¯”較大的補
-ä¸ç‰¹åˆ¥æœ‰ç”¨ã€‚其餘那些åªæ˜¯å’Œæ™‚刻或者開發者相關的註解,ä¸åˆé©æ”¾åˆ°æ°¸ä¹…的改
-動日誌里的,也應該放這裡。
-使用 diffstatçš„é¸é … "-p 1 -w 70" 這樣文件å就會從內核原始碼樹的目錄開始
-,ä¸æœƒå ç”¨å¤ªå¯¬çš„空間(很容易é©åˆ80列的寬度,也許會有一些縮進。)
+å°æ–¼ ``---`` 標記之後的é¡å¤–註解,一個好的用途就是用來寫 ``diffstat`` ,用來顯
+示修改了什麼文件和æ¯å€‹æ–‡ä»¶éƒ½å¢žåŠ å’Œåˆªé™¤äº†å¤šå°‘行。 ``diffstat`` å°æ–¼æ¯”較大的補
+ä¸ç‰¹åˆ¥æœ‰ç”¨ã€‚
+使用 ``diffstat`` çš„é¸é … ``-p 1 -w 70`` 這樣文件å就會從內核æºä»£ç¢¼æ¨¹çš„目錄開始
+,ä¸æœƒä½”用太寬的空間(很容易é©åˆ80列的寬度,也許會有一些縮進。)
+( ``git`` 默èªæœƒç”Ÿæˆåˆé©çš„diffstat。)
-在後é¢çš„åƒè€ƒè³‡æ–™ä¸­èƒ½çœ‹åˆ°é©ç•¶çš„補ä¸æ ¼å¼çš„更多細節。
+其餘那些åªé©ç”¨æ–¼ç•¶æ™‚或者與維護者相關的註解,ä¸åˆé©æ”¾åˆ°æ°¸ä¹…的改動日誌è£çš„,也
+應該放這è£ã€‚較好的例å­å°±æ˜¯ ``補ä¸æ›´æ”¹è¨˜éŒ„`` ,記錄了v1å’Œv2版本補ä¸ä¹‹é–“的差異。
-.. _tw_explicit_in_reply_to:
+請將此信æ¯æ”¾åœ¨å°‡è®Šæ›´æ—¥èªŒèˆ‡è£œä¸çš„其餘部分分隔開的 ``---`` è¡Œ **之後** 。版本
+ä¿¡æ¯ä¸æ˜¯æ交到git樹的變更日誌的一部分。åªæ˜¯ä¾›å¯©é–±äººå“¡ä½¿ç”¨çš„附加信æ¯ã€‚如果將
+其放置在æ交標記上方,則需è¦æ‰‹å‹•äº¤äº’æ‰èƒ½å°‡å…¶åˆªé™¤ã€‚如果它ä½æ–¼åˆ†éš”線以下,則在
+應用補ä¸æ™‚會自動å‰é›¢::
-15) 明確回覆郵件頭(In-Reply-To)
--------------------------------
+ <commit message>
+ ...
+ Signed-off-by: Author <author@mail>
+ ---
+ V2 -> V3: Removed redundant helper function
+ V1 -> V2: Cleaned up coding style and addressed review comments
-手動添加回復補ä¸çš„的標題頭(In-Reply_To:) 是有幫助的(例如,使用 ``git send-email`` )
-將補ä¸èˆ‡ä»¥å‰çš„相關討論關è¯èµ·ä¾†ï¼Œä¾‹å¦‚,將bug修復程åºé€£çµåˆ°é›»å­éƒµä»¶å’Œbug報告。
-但是,å°æ–¼å¤šè£œä¸ç³»åˆ—,最好é¿å…在回復時使用連çµåˆ°è©²ç³»åˆ—的舊版本。這樣,
-補ä¸çš„多個版本就ä¸æœƒæˆçˆ²é›»å­éƒµä»¶å®¢æˆ¶ç«¯ä¸­ç„¡æ³•ç®¡ç†çš„引用åºåˆ—。如果連çµæœ‰ç”¨ï¼Œ
-å¯ä»¥ä½¿ç”¨ https://lore.kernel.org/ é‡å®šå‘器(例如,在å°é¢é›»å­éƒµä»¶æ–‡æœ¬ä¸­ï¼‰
-連çµåˆ°è£œä¸ç³»åˆ—的早期版本。
+ path/to/file | 5+++--
+ ...
+
+在後é¢çš„åƒè€ƒè³‡æ–™ä¸­èƒ½çœ‹åˆ°æ­£ç¢ºè£œä¸æ ¼å¼çš„更多細節。
-16) 發é€git pull請求
---------------------
+.. _tw_backtraces:
-如果您有一系列補ä¸ï¼Œé‚£éº¼è®“維護人員通éŽgit pullæ“作將它們直接拉入å­ç³»çµ±å­˜å„²
-庫å¯èƒ½æ˜¯æœ€æ–¹ä¾¿çš„。但是,請注æ„,從開發人員那裡ç²å–補ä¸æ¯”從郵件列表中ç²å–補
-ä¸éœ€è¦æ›´é«˜çš„信任度。因此,許多å­ç³»çµ±ç¶­è­·äººå“¡ä¸é¡˜æ„接å—請求,特別是來自新的
-未知開發人員的請求。如果有疑å•ï¼Œæ‚¨å¯ä»¥åœ¨å°é¢éƒµä»¶ä¸­ä½¿ç”¨pull 請求作爲補ä¸ç³»åˆ—
-正常發布的一個é¸é …,讓維護人員å¯ä»¥é¸æ“‡ä½¿ç”¨å…¶ä¸­ä¹‹ä¸€ã€‚
+æ交消æ¯ä¸­çš„回溯(Backtraces)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+回溯有助於記錄導致å•é¡Œçš„調用éˆã€‚然而,並éžæ‰€æœ‰å›žæº¯éƒ½æœ‰å¹«åŠ©ã€‚例如,早期引導調
+用éˆæ˜¯ç¨ç‰¹è€Œæ˜Žé¡¯çš„。而é€å­—複製完整的dmesg輸出則會增加時間戳ã€æ¨¡å¡Šåˆ—表ã€å¯„å­˜
+器和堆棧轉儲等分散注æ„力的信æ¯ã€‚
+
+因此,最有用的回溯應該從轉儲中æå–相關信æ¯ï¼Œä»¥æ›´å®¹æ˜“集中在真實å•é¡Œä¸Šã€‚下é¢æ˜¯
+一個剪è£è‰¯å¥½çš„回溯示例::
+
+ unchecked MSR access error: WRMSR to 0xd51 (tried to write 0x0000000000000064)
+ at rIP: 0xffffffffae059994 (native_write_msr+0x4/0x20)
+ Call Trace:
+ mba_wrmsr
+ update_domains
+ rdtgroup_mkdir
+
+.. _tw_explicit_in_reply_to:
+
+明確回覆郵件頭(In-Reply-To)
+-----------------------------
+
+手動添加回復補ä¸çš„的郵件頭(In-Reply_To:)是有用的(例如,使用 ``git send-email`` ),
+å¯ä»¥å°‡è£œä¸èˆ‡ä»¥å‰çš„相關討論關è¯èµ·ä¾†ï¼Œä¾‹å¦‚,將bug補ä¸éˆæŽ¥åˆ°é›»å­éƒµä»¶å’Œbug報告。
+但是,å°æ–¼å¤šè£œä¸ç³»åˆ—,最好é¿å…在回覆時使用éˆæŽ¥åˆ°è©²ç³»åˆ—的舊版本。這樣,
+補ä¸çš„多個版本就ä¸æœƒæˆçˆ²é›»å­éƒµä»¶å®¢æˆ¶ç«¯ä¸­ç„¡æ³•ç®¡ç†çš„引用樹。如果éˆæŽ¥æœ‰ç”¨ï¼Œ
+å¯ä»¥ä½¿ç”¨ https://lore.kernel.org/ é‡å®šå‘器(例如,在å°é¢é›»å­éƒµä»¶æ–‡æœ¬ä¸­ï¼‰
+éˆæŽ¥åˆ°è£œä¸ç³»åˆ—的早期版本。
-pull 請求的主題行中應該有[Git Pull]。請求本身應該在一行中包å«å­˜å„²åº«å稱和
-感興趣的分支;它應該看起來åƒ::
+給出基礎樹信æ¯
+--------------
- Please pull from
+當其他開發人員收到您的補ä¸ä¸¦é–‹å§‹å¯©é–±æ™‚,知é“應該將您的工作放到代碼樹歷å²è¨˜éŒ„
+中的什麼ä½ç½®é€šå¸¸å¾ˆæœ‰ç”¨ã€‚這å°æ–¼è‡ªå‹•åŒ–æŒçºŒé›†æˆæµæ°´ï¼ˆCI)特別有用,這些æµæ°´ç·šè©¦
+圖é‹è¡Œä¸€ç³»åˆ—測試,以便在維護人員開始審閱之å‰ç¢ºå®šæ交的質é‡ã€‚
- git://jdelvare.pck.nerim.net/jdelvare-2.6 i2c-for-linus
+如果您使用 ``git format-patch`` 生æˆè£œä¸ï¼Œå‰‡å¯ä»¥é€šéŽ ``--base`` 標誌在æ交中
+自動包å«åŸºç¤Žæ¨¹ä¿¡æ¯ã€‚使用此é¸é …最簡單ã€æœ€æ–¹ä¾¿çš„方法是é…åˆä¸»é¡Œåˆ†æ”¯::
- to get these changes:
+ $ git checkout -t -b my-topical-branch master
+ Branch 'my-topical-branch' set up to track local branch 'master'.
+ Switched to a new branch 'my-topical-branch'
+ [perform your edits and commits]
-pull 請求還應該包å«ä¸€æ¢æ•´é«”消æ¯ï¼Œèªªæ˜Žè«‹æ±‚中將包å«ä»€éº¼ï¼Œä¸€å€‹è£œä¸æœ¬èº«çš„ ``Git shortlog``
-以åŠä¸€å€‹é¡¯ç¤ºè£œä¸ç³»åˆ—整體效果的 ``diffstat`` 。當然,將所有這些信æ¯æ”¶é›†åœ¨ä¸€èµ·
-的最簡單方法是讓 ``git`` 使用 ``git request-pull`` 命令爲您完æˆé€™äº›å·¥ä½œã€‚
+ $ git format-patch --base=auto --cover-letter -o outgoing/ master
+ outgoing/0000-cover-letter.patch
+ outgoing/0001-First-Commit.patch
+ outgoing/...
-一些維護人員(包括Linus)希望看到來自已簽åæ交的請求;這增加了他們å°ä½ çš„
-請求信心。特別是,在沒有簽å標籤的情æ³ä¸‹ï¼ŒLinus ä¸æœƒå¾žåƒ Github 這樣的公共
-託管站點拉請求。
+當你編輯 ``outgoing/0000-cover-letter.patch`` 時,您會注æ„到在它的最底部有一
+è¡Œ ``base-commit:`` 尾註,它爲審閱者和CI工具æ供了足夠的信æ¯ä»¥æ­£ç¢ºåŸ·è¡Œ
+``git am`` 而ä¸å¿…擔心è¡çª::
-創建此類簽å的第一步是生æˆä¸€å€‹ GNRPG 密鑰,並由一個或多個核心內核開發人員å°
-其進行簽å。這一步å°æ–°é–‹ç™¼äººå“¡ä¾†èªªå¯èƒ½å¾ˆå›°é›£ï¼Œä½†æ²’有辦法繞éŽå®ƒã€‚åƒåŠ æœƒè­°æ˜¯
-找到å¯ä»¥ç°½ç½²æ‚¨çš„密鑰的開發人員的好方法。
+ $ git checkout -b patch-review [base-commit-id]
+ Switched to a new branch 'patch-review'
+ $ git am patches.mbox
+ Applying: First Commit
+ Applying: ...
-一旦您在Git 中準備了一個您希望有人拉的補ä¸ç³»åˆ—,就用 ``git tag -s`` 創建一
-個簽å標記。這將創建一個新標記,標識該系列中的最後一次æ交,並包å«ç”¨æ‚¨çš„ç§
-鑰創建的簽å。您還å¯ä»¥å°‡changelog樣å¼çš„消æ¯æ·»åŠ åˆ°æ¨™è¨˜ä¸­ï¼›é€™æ˜¯ä¸€å€‹æ述拉請求
-整體效果的ç†æƒ³ä½ç½®ã€‚
+有關此é¸é …的更多信æ¯ï¼Œè«‹åƒé–± ``man git-format-patch`` 。
-如果維護人員將è¦å¾žä¸­æå–的樹ä¸æ˜¯æ‚¨æ­£åœ¨ä½¿ç”¨çš„存儲庫,請ä¸è¦å¿˜è¨˜å°‡å·²ç°½å的標記
-顯å¼æŽ¨é€åˆ°å…¬å…±æ¨¹ã€‚
+.. note::
-生æˆæ‹‰è«‹æ±‚時,請使用已簽å的標記作爲目標。這樣的命令å¯ä»¥å¯¦ç¾::
+ ``--base`` 功能是在2.9.0版git中引入的。
- git request-pull master git://my.public.tree/linux.git my-signed-tag
+如果您ä¸ä½¿ç”¨gitæ ¼å¼åŒ–補ä¸ï¼Œä»ç„¶å¯ä»¥åŒ…å«ç›¸åŒçš„ ``base-commit`` 尾註,以指示您
+的工作所基於的樹的æ交哈希。你應該在å°é¢éƒµä»¶æˆ–系列的第一個補ä¸ä¸­æ·»åŠ å®ƒï¼Œå®ƒæ‡‰
+該放在 ``---`` 行的下é¢æˆ–所有其他內容之後,å³åªåœ¨ä½ çš„é›»å­éƒµä»¶ç°½å之å‰ã€‚
åƒè€ƒæ–‡ç»
--------
-Andrew Morton, "The perfect patch" (tpp).
+Andrew Morton,“完美的補ä¸â€ï¼ˆtpp)
<https://www.ozlabs.org/~akpm/stuff/tpp.txt>
-Jeff Garzik, "Linux kernel patch submission format".
+Jeff Garzik,“Linux內核補ä¸æ交格å¼â€
<https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html>
-Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer".
+Greg Kroah-Hartman,“如何惹惱內核å­ç³»çµ±ç¶­è­·äººå“¡â€
<http://www.kroah.com/log/linux/maintainer.html>
<http://www.kroah.com/log/linux/maintainer-02.html>
@@ -644,17 +644,16 @@ Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer".
<http://www.kroah.com/log/linux/maintainer-06.html>
-NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people!
+ä¸ï¼ï¼ï¼åˆ¥å†ç™¼å·¨åž‹è£œä¸ç‚¸å½ˆçµ¦linux-kernel@vger.kernel.org的人們了ï¼
<https://lore.kernel.org/r/20050711.125305.08322243.davem@davemloft.net>
-Kernel Documentation/process/coding-style.rst:
- :ref:`Documentation/translations/zh_TW/process/coding-style.rst <tw_codingstyle>`
+內核 Documentation/translations/zh_CN/process/coding-style.rst
-Linus Torvalds's mail on the canonical patch format:
+Linus Torvalds關於標準補ä¸æ ¼å¼çš„郵件
<https://lore.kernel.org/r/Pine.LNX.4.58.0504071023190.28951@ppc970.osdl.org>
-Andi Kleen, "On submitting kernel patches"
- Some strategies to get difficult or controversial changes in.
+Andi Kleen,“æ交補ä¸ä¹‹è·¯â€
+ 一些幫助åˆå…¥å›°é›£æˆ–有爭議的變更的策略。
http://halobates.de/on-submitting-patches.pdf
diff --git a/Documentation/translations/zh_TW/process/volatile-considered-harmful.rst b/Documentation/translations/zh_TW/process/volatile-considered-harmful.rst
index 469cb5b3a07c..a609620affb0 100644
--- a/Documentation/translations/zh_TW/process/volatile-considered-harmful.rst
+++ b/Documentation/translations/zh_TW/process/volatile-considered-harmful.rst
@@ -19,20 +19,20 @@
時奎亮 Alex Shi <alex.shi@linux.alibaba.com>
胡皓文 Hu Haowen <src.res.211@gmail.com>
-爲什麼ä¸æ‡‰è©²ä½¿ç”¨ã€Œvolatileã€é¡žåž‹
-================================
+爲什麼ä¸æ‡‰è©²ä½¿ç”¨â€œvolatileâ€é¡žåž‹
+==============================
-C程å¼è¨­è¨ˆå¸«é€šå¸¸èªçˆ²volatile表示æŸå€‹è®Šé‡å¯ä»¥åœ¨ç•¶å‰åŸ·è¡Œçš„線程之外被改變;因此,在內核
-中用到共享數據çµæ§‹æ™‚,常常會有C程å¼è¨­è¨ˆå¸«å–œæ­¡ä½¿ç”¨volatile這類變é‡ã€‚æ›å¥è©±èªªï¼Œä»–們經
+C程åºå“¡é€šå¸¸èªçˆ²volatile表示æŸå€‹è®Šé‡å¯ä»¥åœ¨ç•¶å‰åŸ·è¡Œçš„線程之外被改變;因此,在內核
+中用到共享數據çµæ§‹æ™‚,常常會有C程åºå“¡å–œæ­¡ä½¿ç”¨volatile這類變é‡ã€‚æ›å¥è©±èªªï¼Œä»–們經
常會把volatile類型看æˆæŸç¨®ç°¡æ˜“的原å­è®Šé‡ï¼Œç•¶ç„¶å®ƒå€‘ä¸æ˜¯ã€‚在內核中使用volatileå¹¾
乎總是錯誤的;本文檔將解釋爲什麼這樣。
ç†è§£volatileçš„é—œéµæ˜¯çŸ¥é“它的目的是用來消除優化,實際上很少有人真正需è¦é€™æ¨£çš„應
-用。在內核中,程å¼è¨­è¨ˆå¸«å¿…須防止æ„外的並發訪å•ç ´å£žå…±äº«çš„數據çµæ§‹ï¼Œé€™å…¶å¯¦æ˜¯ä¸€å€‹å®Œå…¨
-ä¸åŒçš„任務。用來防止æ„外並發訪å•çš„ä¿è­·æŽªæ–½ï¼Œå¯ä»¥æ›´åŠ é«˜æ•ˆçš„é¿å…大多數優化相關的
+用。在內核中,程åºå“¡å¿…須防止æ„外的併發訪å•ç ´å£žå…±äº«çš„數據çµæ§‹ï¼Œé€™å…¶å¯¦æ˜¯ä¸€å€‹å®Œå…¨
+ä¸åŒçš„任務。用來防止æ„外併發訪å•çš„ä¿è­·æŽªæ–½ï¼Œå¯ä»¥æ›´åŠ é«˜æ•ˆçš„é¿å…大多數優化相關的
å•é¡Œã€‚
-åƒvolatile一樣,內核æ供了很多原語來ä¿è­‰ä¸¦ç™¼è¨ªå•æ™‚的數據安全(自旋鎖, 互斥é‡,å…§
+åƒvolatile一樣,內核æ供了很多原語來ä¿è­‰ä½µç™¼è¨ªå•æ™‚的數據安全(自旋鎖, 互斥é‡,å…§
å­˜å±éšœç­‰ç­‰ï¼‰ï¼ŒåŒæ¨£å¯ä»¥é˜²æ­¢æ„外的優化。如果å¯ä»¥æ­£ç¢ºä½¿ç”¨é€™äº›å…§æ ¸åŽŸèªžï¼Œé‚£éº¼å°±æ²’有
å¿…è¦å†ä½¿ç”¨volatile。如果ä»ç„¶å¿…須使用volatile,那麼幾乎å¯ä»¥è‚¯å®šåœ¨ä»£ç¢¼çš„æŸè™•æœ‰ä¸€
個bug。在正確設計的內核代碼中,volatile能帶來的僅僅是使事情變慢。
@@ -46,8 +46,8 @@ C程å¼è¨­è¨ˆå¸«é€šå¸¸èªçˆ²volatile表示æŸå€‹è®Šé‡å¯ä»¥åœ¨ç•¶å‰åŸ·è¡Œçš„ç·
如果所有的代碼都éµå¾ªåŠ éŽ–è¦å‰‡ï¼Œç•¶æŒæœ‰the_lock的時候,ä¸å¯èƒ½æ„外的改變shared_dataçš„
值。任何å¯èƒ½è¨ªå•è©²æ•¸æ“šçš„其他代碼都會在這個鎖上等待。自旋鎖原語跟內存å±éšœä¸€æ¨£â€”— 它
-們顯å¼çš„用來書寫æˆé€™æ¨£ —— æ„味著數據訪å•ä¸æœƒè·¨è¶Šå®ƒå€‘而被優化。所以本來編譯器èªçˆ²
-它知é“在shared_data裡é¢å°‡æœ‰ä»€éº¼ï¼Œä½†æ˜¯å› çˆ²spin_lock()調用跟內存å±éšœä¸€æ¨£ï¼Œæœƒå¼·åˆ¶ç·¨
+們顯å¼çš„用來書寫æˆé€™æ¨£ —— æ„味ç€æ•¸æ“šè¨ªå•ä¸æœƒè·¨è¶Šå®ƒå€‘而被優化。所以本來編譯器èªçˆ²
+它知é“在shared_dataè£é¢å°‡æœ‰ä»€éº¼ï¼Œä½†æ˜¯å› çˆ²spin_lock()調用跟內存å±éšœä¸€æ¨£ï¼Œæœƒå¼·åˆ¶ç·¨
譯器忘記它所知é“的一切。那麼在訪å•é€™äº›æ•¸æ“šæ™‚ä¸æœƒæœ‰å„ªåŒ–çš„å•é¡Œã€‚
如果shared_data被è²å爲volatile,鎖æ“作將ä»ç„¶æ˜¯å¿…須的。就算我們知é“沒有其他人正在
@@ -55,13 +55,13 @@ C程å¼è¨­è¨ˆå¸«é€šå¸¸èªçˆ²volatile表示æŸå€‹è®Šé‡å¯ä»¥åœ¨ç•¶å‰åŸ·è¡Œçš„ç·
shared_dataä¸æ˜¯volatile的。在處ç†å…±äº«æ•¸æ“šçš„時候,é©ç•¶çš„鎖æ“作å¯ä»¥ä¸å†éœ€è¦
volatile —— 並且是有潛在å±å®³çš„。
-volatile的存儲類型最åˆæ˜¯çˆ²é‚£äº›å…§å­˜æ˜ å°„çš„I/O寄存器而定義。在內核里,寄存器訪å•ä¹Ÿæ‡‰
-該被鎖ä¿è­·ï¼Œä½†æ˜¯äººå€‘也ä¸å¸Œæœ›ç·¨è­¯å™¨ã€Œå„ªåŒ–ã€è‡¨ç•Œå€å…§çš„寄存器訪å•ã€‚內核里I/O的內存訪å•
+volatile的存儲類型最åˆæ˜¯çˆ²é‚£äº›å…§å­˜æ˜ å°„çš„I/O寄存器而定義。在內核è£ï¼Œå¯„存器訪å•ä¹Ÿæ‡‰
+該被鎖ä¿è­·ï¼Œä½†æ˜¯äººå€‘也ä¸å¸Œæœ›ç·¨è­¯å™¨â€œå„ªåŒ–â€è‡¨ç•Œå€å…§çš„寄存器訪å•ã€‚內核è£I/O的內存訪å•
是通éŽè¨ªå•å‡½æ•¸å®Œæˆçš„ï¼›ä¸è´Šæˆé€šéŽæŒ‡é‡å°I/O內存的直接訪å•ï¼Œä¸¦ä¸”ä¸æ˜¯åœ¨æ‰€æœ‰é«”系架構上
都能工作。那些訪å•å‡½æ•¸æ­£æ˜¯çˆ²äº†é˜²æ­¢æ„外優化而寫的,因此,å†èªªä¸€æ¬¡ï¼Œvolatileé¡žåž‹ä¸
是必需的。
-å¦ä¸€ç¨®å¼•èµ·ç”¨æˆ¶å¯èƒ½ä½¿ç”¨volatile的情æ³æ˜¯ç•¶è™•ç†å™¨æ­£å¿™è‘—等待一個變é‡çš„值。正確執行一
+å¦ä¸€ç¨®å¼•èµ·ç”¨æˆ¶å¯èƒ½ä½¿ç”¨volatile的情æ³æ˜¯ç•¶è™•ç†å™¨æ­£å¿™ç€ç­‰å¾…一個變é‡çš„值。正確執行一
個忙等待的方法是::
while (my_variable != what_i_want)
@@ -74,14 +74,14 @@ cpu_relax()調用會é™ä½ŽCPU的能é‡æ¶ˆè€—或者讓ä½æ–¼è¶…線程雙處ç†å™¨
- 在一些體系架構的系統上,å…許直接的I/0內存訪å•ï¼Œé‚£éº¼å‰é¢æ到的訪å•å‡½æ•¸å¯ä»¥ä½¿ç”¨
volatile。基本上,æ¯ä¸€å€‹è¨ªå•å‡½æ•¸èª¿ç”¨å®ƒè‡ªå·±éƒ½æ˜¯ä¸€å€‹å°çš„臨界å€åŸŸä¸¦ä¸”ä¿è­‰äº†æŒ‰ç…§
- 程å¼è¨­è¨ˆå¸«æœŸæœ›çš„那樣發生訪å•æ“作。
+ 程åºå“¡æœŸæœ›çš„那樣發生訪å•æ“作。
- æŸäº›æœƒæ”¹è®Šå…§å­˜çš„å…§è¯å½™ç·¨ä»£ç¢¼é›–然沒有什麼其他明顯的附作用,但是有被GCC刪除的å¯
能性。在彙編è²æ˜Žä¸­åŠ ä¸Švolatileé—œéµå­—å¯ä»¥é˜²æ­¢é€™ç¨®åˆªé™¤æ“作。
- Jiffies變é‡æ˜¯ä¸€ç¨®ç‰¹æ®Šæƒ…æ³ï¼Œé›–然æ¯æ¬¡å¼•ç”¨å®ƒçš„時候都å¯ä»¥æœ‰ä¸åŒçš„值,但讀jiffies
變é‡æ™‚ä¸éœ€è¦ä»»ä½•ç‰¹æ®Šçš„加鎖ä¿è­·ã€‚所以jiffies變é‡å¯ä»¥ä½¿ç”¨volatile,但是ä¸è´Šæˆ
- 其他跟jiffies相åŒé¡žåž‹è®Šé‡ä½¿ç”¨volatile。Jiffies被èªçˆ²æ˜¯ä¸€ç¨®ã€Œæ„šè ¢çš„éºç•™ç‰©"
+ 其他跟jiffies相åŒé¡žåž‹è®Šé‡ä½¿ç”¨volatile。Jiffies被èªçˆ²æ˜¯ä¸€ç¨®â€œæ„šè ¢çš„éºç•™ç‰©"
(Linus的話)因爲解決這個å•é¡Œæ¯”ä¿æŒç¾ç‹€è¦éº»ç…©çš„多。
- 由於æŸäº›I/0設備å¯èƒ½æœƒä¿®æ”¹é€£çºŒä¸€è‡´çš„內存,所以有時,指å‘連續一致內存的數據çµæ§‹
@@ -92,9 +92,9 @@ cpu_relax()調用會é™ä½ŽCPU的能é‡æ¶ˆè€—或者讓ä½æ–¼è¶…線程雙處ç†å™¨
bug並且需è¦å°é€™æ¨£çš„代碼é¡å¤–仔細檢查。那些試圖使用volatile的開發人員需è¦é€€ä¸€æ­¥æƒ³æƒ³
他們真正想實ç¾çš„是什麼。
-éžå¸¸æ­¡è¿Žåˆªé™¤volatile變é‡çš„è£œä¸ ï¼ åªè¦è­‰æ˜Žé€™äº›è£œä¸å®Œæ•´çš„考慮了並發å•é¡Œã€‚
+éžå¸¸æ­¡è¿Žåˆªé™¤volatile變é‡çš„è£œä¸ ï¼ åªè¦è­‰æ˜Žé€™äº›è£œä¸å®Œæ•´çš„考慮了併發å•é¡Œã€‚
-注釋
+註釋
----
[1] https://lwn.net/Articles/233481/
diff --git a/Documentation/usb/gadget_uvc.rst b/Documentation/usb/gadget_uvc.rst
index 80a1f031b593..bf78fba3ce23 100644
--- a/Documentation/usb/gadget_uvc.rst
+++ b/Documentation/usb/gadget_uvc.rst
@@ -126,7 +126,7 @@ might do:
create_frame 1920 1080 uncompressed yuyv
The only uncompressed format currently supported is YUYV, which is detailed at
-Documentation/userspace-api/media/v4l/pixfmt-packed.yuv.rst.
+Documentation/userspace-api/media/v4l/pixfmt-packed-yuv.rst.
Color Matching Descriptors
~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/MAINTAINERS b/MAINTAINERS
index 8b7d80146d4a..dc56b0e1b994 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1798,7 +1798,7 @@ F: drivers/irqchip/irq-owl-sirq.c
F: drivers/mmc/host/owl-mmc.c
F: drivers/net/ethernet/actions/
F: drivers/pinctrl/actions/*
-F: drivers/soc/actions/
+F: drivers/pmdomain/actions/
F: include/dt-bindings/power/owl-*
F: include/dt-bindings/reset/actions,*
F: include/linux/soc/actions/
@@ -1826,6 +1826,13 @@ N: allwinner
N: sun[x456789]i
N: sun[25]0i
+ARM/AMD PENSANDO ARM64 ARCHITECTURE
+M: Brad Larson <blarson@amd.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Supported
+F: Documentation/devicetree/bindings/*/amd,pensando*
+F: arch/arm64/boot/dts/amd/elba*
+
ARM/Amlogic Meson SoC CLOCK FRAMEWORK
M: Neil Armstrong <neil.armstrong@linaro.org>
M: Jerome Brunet <jbrunet@baylibre.com>
@@ -5244,6 +5251,12 @@ S: Orphan
W: http://accessrunner.sourceforge.net/
F: drivers/usb/atm/cxacru.c
+CONFIDENTIAL COMPUTING THREAT MODEL FOR X86 VIRTUALIZATION (SNP/TDX)
+M: Elena Reshetova <elena.reshetova@intel.com>
+M: Carlos Bilbao <carlos.bilbao@amd.com>
+S: Maintained
+F: Documentation/security/snp-tdx-threat-model.rst
+
CONFIGFS
M: Joel Becker <jlbec@evilplan.org>
M: Christoph Hellwig <hch@lst.de>
@@ -5641,7 +5654,7 @@ M: Andrew Donnellan <ajd@linux.ibm.com>
L: linuxppc-dev@lists.ozlabs.org
S: Supported
F: Documentation/ABI/testing/sysfs-class-cxl
-F: Documentation/powerpc/cxl.rst
+F: Documentation/arch/powerpc/cxl.rst
F: arch/powerpc/platforms/powernv/pci-cxl.c
F: drivers/misc/cxl/
F: include/misc/cxl*
@@ -5653,7 +5666,7 @@ M: Matthew R. Ochs <mrochs@linux.ibm.com>
M: Uma Krishnan <ukrishn@linux.ibm.com>
L: linux-scsi@vger.kernel.org
S: Supported
-F: Documentation/powerpc/cxlflash.rst
+F: Documentation/arch/powerpc/cxlflash.rst
F: drivers/scsi/cxlflash/
F: include/uapi/scsi/cxlflash_ioctl.h
@@ -6028,6 +6041,7 @@ F: include/linux/devm-helpers.h
DEVICE-MAPPER (LVM)
M: Alasdair Kergon <agk@redhat.com>
M: Mike Snitzer <snitzer@kernel.org>
+M: Mikulas Patocka <mpatocka@redhat.com>
M: dm-devel@lists.linux.dev
L: dm-devel@lists.linux.dev
S: Maintained
@@ -10021,12 +10035,6 @@ F: Documentation/driver-api/i3c
F: drivers/i3c/
F: include/linux/i3c/
-IA64 (Itanium) PLATFORM
-L: linux-ia64@vger.kernel.org
-S: Orphan
-F: Documentation/arch/ia64/
-F: arch/ia64/
-
IBM Operation Panel Input Driver
M: Eddie James <eajames@linux.ibm.com>
L: linux-input@vger.kernel.org
@@ -12169,7 +12177,7 @@ F: Documentation/ABI/stable/sysfs-firmware-opal-*
F: Documentation/devicetree/bindings/i2c/i2c-opal.txt
F: Documentation/devicetree/bindings/powerpc/
F: Documentation/devicetree/bindings/rtc/rtc-opal.txt
-F: Documentation/powerpc/
+F: Documentation/arch/powerpc/
F: arch/powerpc/
F: drivers/*/*/*pasemi*
F: drivers/*/*pasemi*
@@ -14109,7 +14117,7 @@ F: Documentation/devicetree/bindings/iio/adc/microchip,mcp3911.yaml
F: drivers/iio/adc/mcp3911.c
MICROCHIP MMC/SD/SDIO MCI DRIVER
-M: Ludovic Desroches <ludovic.desroches@microchip.com>
+M: Aubin Constans <aubin.constans@microchip.com>
S: Maintained
F: drivers/mmc/host/atmel-mci.c
@@ -15551,6 +15559,13 @@ F: include/linux/objagg.h
F: lib/objagg.c
F: lib/test_objagg.c
+OBJPOOL
+M: Matt Wu <wuqiang.matt@bytedance.com>
+S: Supported
+F: include/linux/objpool.h
+F: lib/objpool.c
+F: lib/test_objpool.c
+
OBJTOOL
M: Josh Poimboeuf <jpoimboe@kernel.org>
M: Peter Zijlstra <peterz@infradead.org>
@@ -16361,11 +16376,6 @@ L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/muxes/i2c-mux-pca9541.c
-PCDP - PRIMARY CONSOLE AND DEBUG PORT
-M: Khalid Aziz <khalid@gonehiking.org>
-S: Maintained
-F: drivers/firmware/pcdp.*
-
PCI DRIVER FOR AARDVARK (Marvell Armada 3700)
M: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
M: Pali Rohár <pali@kernel.org>
@@ -16583,7 +16593,7 @@ R: Oliver O'Halloran <oohall@gmail.com>
L: linuxppc-dev@lists.ozlabs.org
S: Supported
F: Documentation/PCI/pci-error-recovery.rst
-F: Documentation/powerpc/eeh-pci-error-recovery.rst
+F: Documentation/arch/powerpc/eeh-pci-error-recovery.rst
F: arch/powerpc/include/*/eeh*.h
F: arch/powerpc/kernel/eeh*.c
F: arch/powerpc/platforms/*/eeh*.c
@@ -17893,6 +17903,18 @@ S: Maintained
F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
F: drivers/mtd/nand/raw/qcom_nandc.c
+QUALCOMM QSEECOM DRIVER
+M: Maximilian Luz <luzmaximilian@gmail.com>
+L: linux-arm-msm@vger.kernel.org
+S: Maintained
+F: drivers/firmware/qcom/qcom_qseecom.c
+
+QUALCOMM QSEECOM UEFISECAPP DRIVER
+M: Maximilian Luz <luzmaximilian@gmail.com>
+L: linux-arm-msm@vger.kernel.org
+S: Maintained
+F: drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+
QUALCOMM RMNET DRIVER
M: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com>
M: Sean Tranchetti <quic_stranche@quicinc.com>
@@ -18509,7 +18531,7 @@ L: linux-riscv@lists.infradead.org
S: Supported
Q: https://patchwork.kernel.org/project/linux-riscv/list/
C: irc://irc.libera.chat/riscv
-P: Documentation/riscv/patch-acceptance.rst
+P: Documentation/arch/riscv/patch-acceptance.rst
T: git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git
F: arch/riscv/
N: riscv
@@ -19334,7 +19356,8 @@ F: Documentation/devicetree/bindings/mmc/sdhci-common.yaml
F: drivers/mmc/host/sdhci*
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) MICROCHIP DRIVER
-M: Eugen Hristev <eugen.hristev@microchip.com>
+M: Aubin Constans <aubin.constans@microchip.com>
+R: Eugen Hristev <eugen.hristev@collabora.com>
L: linux-mmc@vger.kernel.org
S: Supported
F: drivers/mmc/host/sdhci-of-at91.c
@@ -20153,6 +20176,13 @@ F: drivers/char/sonypi.c
F: drivers/platform/x86/sony-laptop.c
F: include/linux/sony-laptop.h
+SOPHGO DEVICETREES
+M: Chao Wei <chao.wei@sophgo.com>
+M: Chen Wang <unicorn_wang@outlook.com>
+S: Maintained
+F: arch/riscv/boot/dts/sophgo/
+F: Documentation/devicetree/bindings/riscv/sophgo.yaml
+
SOUND
M: Jaroslav Kysela <perex@perex.cz>
M: Takashi Iwai <tiwai@suse.com>
@@ -20603,9 +20633,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c
STARFIVE JH71XX PMU CONTROLLER DRIVER
M: Walker Chen <walker.chen@starfivetech.com>
+M: Changhuang Liang <changhuang.liang@starfivetech.com>
S: Supported
F: Documentation/devicetree/bindings/power/starfive*
-F: drivers/pmdomain/starfive/jh71xx-pmu.c
+F: drivers/pmdomain/starfive/
F: include/dt-bindings/power/starfive,jh7110-pmu.h
STARFIVE SOC DRIVERS
@@ -20613,7 +20644,6 @@ M: Conor Dooley <conor@kernel.org>
S: Maintained
T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
F: Documentation/devicetree/bindings/soc/starfive/
-F: drivers/soc/starfive/
STARFIVE TRNG DRIVER
M: Jia Jie Ho <jiajie.ho@starfivetech.com>
@@ -20994,6 +21024,7 @@ F: drivers/clk/clk-sc[mp]i.c
F: drivers/cpufreq/sc[mp]i-cpufreq.c
F: drivers/firmware/arm_scmi/
F: drivers/firmware/arm_scpi.c
+F: drivers/pmdomain/arm/
F: drivers/powercap/arm_scmi_powercap.c
F: drivers/regulator/scmi-regulator.c
F: drivers/reset/reset-scmi.c
@@ -21921,9 +21952,11 @@ W: https://www.tq-group.com/en/products/tq-embedded/
F: arch/arm/boot/dts/imx*mba*.dts*
F: arch/arm/boot/dts/imx*tqma*.dts*
F: arch/arm/boot/dts/mba*.dtsi
+F: arch/arm64/boot/dts/freescale/fsl-*tqml*.dts*
F: arch/arm64/boot/dts/freescale/imx*mba*.dts*
F: arch/arm64/boot/dts/freescale/imx*tqma*.dts*
F: arch/arm64/boot/dts/freescale/mba*.dtsi
+F: arch/arm64/boot/dts/freescale/tqml*.dts*
F: drivers/gpio/gpio-tqmx86.c
F: drivers/mfd/tqmx86.c
F: drivers/watchdog/tqmx86_wdt.c
diff --git a/Makefile b/Makefile
index 5c418efbe89b..a1e931ff7eb0 100644
--- a/Makefile
+++ b/Makefile
@@ -378,7 +378,7 @@ include $(srctree)/scripts/subarch.include
# When performing cross compilation for other architectures ARCH shall be set
# to the target architecture. (See arch/* for the possibilities).
# ARCH can be set during invocation of make:
-# make ARCH=ia64
+# make ARCH=arm64
# Another way is to have ARCH set in the environment.
# The default ARCH is the host where make is executed.
@@ -386,7 +386,7 @@ include $(srctree)/scripts/subarch.include
# during compilation. Only gcc and related bin-utils executables
# are prefixed with $(CROSS_COMPILE).
# CROSS_COMPILE can be set on the command line
-# make CROSS_COMPILE=ia64-linux-
+# make CROSS_COMPILE=aarch64-linux-gnu-
# Alternatively CROSS_COMPILE can be set in the environment.
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
@@ -1367,8 +1367,8 @@ kselftest-%: headers FORCE
PHONY += kselftest-merge
kselftest-merge:
$(if $(wildcard $(objtree)/.config),, $(error No .config exists, config your kernel first!))
- $(Q)find $(srctree)/tools/testing/selftests -name config | \
- xargs $(srctree)/scripts/kconfig/merge_config.sh -m $(objtree)/.config
+ $(Q)find $(srctree)/tools/testing/selftests -name config -o -name config.$(UTS_MACHINE) | \
+ xargs $(srctree)/scripts/kconfig/merge_config.sh -y -m $(objtree)/.config
$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
# ---------------------------------------------------------------------------
diff --git a/arch/Kconfig b/arch/Kconfig
index 12d51495caec..f4b210ab0612 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1088,7 +1088,6 @@ config HAVE_ARCH_COMPAT_MMAP_BASES
config PAGE_SIZE_LESS_THAN_64KB
def_bool y
depends on !ARM64_64K_PAGES
- depends on !IA64_PAGE_SIZE_64KB
depends on !PAGE_SIZE_64KB
depends on !PARISC_PAGE_SIZE_64KB
depends on PAGE_SIZE_LESS_THAN_256KB
diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index b68f1f56b836..18c842ca6c32 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl
@@ -334,7 +334,7 @@
401 common io_submit sys_io_submit
402 common io_cancel sys_io_cancel
405 common exit_group sys_exit_group
-406 common lookup_dcookie sys_lookup_dcookie
+406 common lookup_dcookie sys_ni_syscall
407 common epoll_create sys_epoll_create
408 common epoll_ctl sys_epoll_ctl
409 common epoll_wait sys_epoll_wait
@@ -492,7 +492,7 @@
560 common set_mempolicy_home_node sys_ni_syscall
561 common cachestat sys_cachestat
562 common fchmodat2 sys_fchmodat2
-# 563 reserved for map_shadow_stack
+563 common map_shadow_stack sys_map_shadow_stack
564 common futex_wake sys_futex_wake
565 common futex_wait sys_futex_wait
566 common futex_requeue sys_futex_requeue
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9557808e8937..f8567e95f98b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -8,6 +8,7 @@ config ARM
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL if MMU
+ select ARCH_HAS_DMA_ALLOC if MMU
select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index b407b7b9b715..fc2b41d41447 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -1593,10 +1593,8 @@ config DEBUG_UART_PHYS
default 0x48020000 if DEBUG_OMAP4UART3 || DEBUG_TI81XXUART1
default 0x48022000 if DEBUG_TI81XXUART2
default 0x48024000 if DEBUG_TI81XXUART3
- default 0x4806a000 if DEBUG_OMAP2UART1 || DEBUG_OMAP3UART1 || \
- DEBUG_OMAP4UART1 || DEBUG_OMAP5UART1
- default 0x4806c000 if DEBUG_OMAP2UART2 || DEBUG_OMAP3UART2 || \
- DEBUG_OMAP4UART2 || DEBUG_OMAP5UART2
+ default 0x4806a000 if DEBUG_OMAP2UART1
+ default 0x4806c000 if DEBUG_OMAP2UART2
default 0x4806e000 if DEBUG_OMAP2UART3 || DEBUG_OMAP4UART4
default 0x49020000 if DEBUG_OMAP3UART3
default 0x49042000 if DEBUG_OMAP3UART4
@@ -1719,10 +1717,8 @@ config DEBUG_UART_VIRT
default 0xfa020000 if DEBUG_OMAP4UART3 || DEBUG_TI81XXUART1
default 0xfa022000 if DEBUG_TI81XXUART2
default 0xfa024000 if DEBUG_TI81XXUART3
- default 0xfa06a000 if DEBUG_OMAP2UART1 || DEBUG_OMAP3UART1 || \
- DEBUG_OMAP4UART1 || DEBUG_OMAP5UART1
- default 0xfa06c000 if DEBUG_OMAP2UART2 || DEBUG_OMAP3UART2 || \
- DEBUG_OMAP4UART2 || DEBUG_OMAP5UART2
+ default 0xfa06a000 if DEBUG_OMAP2UART1
+ default 0xfa06c000 if DEBUG_OMAP2UART2
default 0xfa06e000 if DEBUG_OMAP2UART3 || DEBUG_OMAP4UART4
default 0xfa71e000 if DEBUG_QCOM_UARTDM
default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
diff --git a/arch/arm/boot/dts/allwinner/Makefile b/arch/arm/boot/dts/allwinner/Makefile
index eebb5a0c873a..2d26c3397f14 100644
--- a/arch/arm/boot/dts/allwinner/Makefile
+++ b/arch/arm/boot/dts/allwinner/Makefile
@@ -256,6 +256,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-t113s-mangopi-mq-r-t113.dtb \
sun8i-t3-cqa3t-bv3.dtb \
sun8i-v3-sl631-imx179.dtb \
+ sun8i-v3s-anbernic-rg-nano.dtb \
sun8i-v3s-licheepi-zero.dtb \
sun8i-v3s-licheepi-zero-dock.dtb \
sun8i-v40-bananapi-m2-berry.dtb
diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi b/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi
index 4ef26d8f5340..a5b1f1e3900d 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi
@@ -338,6 +338,8 @@
resets = <&ccu RST_BUS_VE>;
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
allwinner,sram = <&ve_sram 1>;
+ interconnects = <&mbus 4>;
+ interconnect-names = "dma-mem";
};
mmc0: mmc@1c0f000 {
diff --git a/arch/arm/boot/dts/allwinner/sun8i-v3s-anbernic-rg-nano.dts b/arch/arm/boot/dts/allwinner/sun8i-v3s-anbernic-rg-nano.dts
new file mode 100644
index 000000000000..f34dfdf1566d
--- /dev/null
+++ b/arch/arm/boot/dts/allwinner/sun8i-v3s-anbernic-rg-nano.dts
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+#include <dt-bindings/input/linux-event-codes.h>
+#include "sun8i-v3s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+/ {
+ model = "Anbernic RG Nano";
+ compatible = "anbernic,rg-nano", "allwinner,sun8i-v3s";
+
+ aliases {
+ rtc0 = &pcf8563;
+ rtc1 = &rtc;
+ serial0 = &uart0;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ brightness-levels = <0 1 2 3 8 14 21 32 46 60 80 100>;
+ default-brightness-level = <11>;
+ power-supply = <&reg_vcc5v0>;
+ pwms = <&pwm 0 40000 1>;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+
+ button-a {
+ gpios = <&gpio_expander 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "BTN-A";
+ linux,code = <BTN_EAST>;
+ };
+
+ button-b {
+ gpios = <&gpio_expander 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "BTN-B";
+ linux,code = <BTN_SOUTH>;
+ };
+
+ button-down {
+ gpios = <&gpio_expander 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "DPAD-DOWN";
+ linux,code = <BTN_DPAD_DOWN>;
+ };
+
+ button-left {
+ gpios = <&gpio_expander 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "DPAD-LEFT";
+ linux,code = <BTN_DPAD_LEFT>;
+ };
+
+ button-right {
+ gpios = <&gpio_expander 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "DPAD-RIGHT";
+ linux,code = <BTN_DPAD_RIGHT>;
+ };
+
+ button-se {
+ gpios = <&gpio_expander 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "BTN-SELECT";
+ linux,code = <BTN_SELECT>;
+ };
+
+ button-st {
+ gpios = <&gpio_expander 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "BTN-START";
+ linux,code = <BTN_START>;
+ };
+
+ button-tl {
+ gpios = <&gpio_expander 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "BTN-L";
+ linux,code = <BTN_TL>;
+ };
+
+ button-tr {
+ gpios = <&gpio_expander 15 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "BTN-R";
+ linux,code = <BTN_TR>;
+ };
+
+ button-up {
+ gpios = <&gpio_expander 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "DPAD-UP";
+ linux,code = <BTN_DPAD_UP>;
+ };
+
+ button-x {
+ gpios = <&gpio_expander 11 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "BTN-X";
+ linux,code = <BTN_NORTH>;
+ };
+
+ button-y {
+ gpios = <&gpio_expander 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ label = "BTN-Y";
+ linux,code = <BTN_WEST>;
+ };
+ };
+};
+
+&codec {
+ allwinner,audio-routing = "Speaker", "HP",
+ "MIC1", "Mic",
+ "Mic", "HBIAS";
+ allwinner,pa-gpios = <&pio 5 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* PF6 */
+ status = "okay";
+};
+
+&ehci {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ gpio_expander: gpio@20 {
+ compatible = "nxp,pcal6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupt-parent = <&pio>;
+ interrupts = <1 3 IRQ_TYPE_EDGE_BOTH>; /* PB3/EINT3 */
+ vcc-supply = <&reg_vcc3v3>;
+ };
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupt-parent = <&pio>;
+ interrupts = <1 5 IRQ_TYPE_EDGE_FALLING>; /* PB5/EINT5 */
+ };
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&battery_power_supply {
+ status = "okay";
+};
+
+&mmc0 {
+ broken-cd;
+ bus-width = <4>;
+ disable-wp;
+ vmmc-supply = <&reg_vcc3v3>;
+ vqmmc-supply = <&reg_vcc3v3>;
+ status = "okay";
+};
+
+&ohci {
+ status = "okay";
+};
+
+&pio {
+ vcc-pb-supply = <&reg_vcc3v3>;
+ vcc-pc-supply = <&reg_vcc3v3>;
+ vcc-pf-supply = <&reg_vcc3v3>;
+ vcc-pg-supply = <&reg_vcc3v3>;
+
+ spi0_no_miso_pins: spi0-no-miso-pins {
+ pins = "PC1", "PC2", "PC3";
+ function = "spi0";
+ };
+};
+
+&pwm {
+ pinctrl-0 = <&pwm0_pin>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+/* DCDC2 wired into vdd-cpu, vdd-sys, and vdd-ephy. */
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-max-microvolt = <1250000>;
+ regulator-min-microvolt = <1250000>;
+ regulator-name = "vdd-cpu";
+};
+
+/* DCDC3 wired into every 3.3v input that isn't the RTC. */
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "vcc-io";
+};
+
+/* LDO1 wired into RTC, voltage is hard-wired at 3.3v. */
+&reg_ldo1 {
+ regulator-always-on;
+ regulator-name = "vcc-rtc";
+};
+
+/* LDO2 wired into VCC-PLL and audio codec. */
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-max-microvolt = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ regulator-name = "vcc-pll";
+};
+
+/* LDO3, LDO4, and LDO5 unused. */
+&reg_ldo3 {
+ status = "disabled";
+};
+
+&reg_ldo4 {
+ status = "disabled";
+};
+
+/* RTC uses internal oscillator */
+&rtc {
+ /delete-property/ clocks;
+};
+
+&spi0 {
+ pinctrl-0 = <&spi0_no_miso_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ display@0 {
+ compatible = "saef,sftc154b", "panel-mipi-dbi-spi";
+ reg = <0>;
+ backlight = <&backlight>;
+ dc-gpios = <&pio 2 0 GPIO_ACTIVE_HIGH>; /* PC0 */
+ reset-gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2 */
+ spi-max-frequency = <100000000>;
+
+ height-mm = <39>;
+ width-mm = <39>;
+
+ /* Set hb-porch to compensate for non-visible area */
+ panel-timing {
+ hactive = <240>;
+ vactive = <240>;
+ hback-porch = <80>;
+ vback-porch = <0>;
+ clock-frequency = <0>;
+ hfront-porch = <0>;
+ hsync-len = <0>;
+ vfront-porch = <0>;
+ vsync-len = <0>;
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-0 = <&uart0_pb_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
+&usbphy {
+ usb0_id_det-gpios = <&pio 6 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PG5 */
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi b/arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi
index 3b9a282c2746..e8a04476b776 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi
@@ -319,6 +319,29 @@
#phy-cells = <1>;
};
+ ehci: usb@1c1a000 {
+ compatible = "allwinner,sun8i-v3s-ehci", "generic-ehci";
+ reg = <0x01c1a000 0x100>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>;
+ resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
+ phys = <&usbphy 0>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ ohci: usb@1c1a400 {
+ compatible = "allwinner,sun8i-v3s-ohci", "generic-ohci";
+ reg = <0x01c1a400 0x100>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>,
+ <&ccu CLK_USB_OHCI0>;
+ resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
+ phys = <&usbphy 0>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
ccu: clock@1c20000 {
compatible = "allwinner,sun8i-v3s-ccu";
reg = <0x01c20000 0x400>;
@@ -414,6 +437,18 @@
bias-pull-up;
};
+ /omit-if-no-ref/
+ pwm0_pin: pwm0-pin {
+ pins = "PB4";
+ function = "pwm0";
+ };
+
+ /omit-if-no-ref/
+ pwm1_pin: pwm1-pin {
+ pins = "PB5";
+ function = "pwm1";
+ };
+
spi0_pins: spi0-pins {
pins = "PC0", "PC1", "PC2", "PC3";
function = "spi0";
diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
index 23cbc7203a8e..d3ac20e316d0 100644
--- a/arch/arm/boot/dts/aspeed/Makefile
+++ b/arch/arm/boot/dts/aspeed/Makefile
@@ -19,6 +19,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
aspeed-bmc-facebook-fuji.dtb \
aspeed-bmc-facebook-galaxy100.dtb \
aspeed-bmc-facebook-greatlakes.dtb \
+ aspeed-bmc-facebook-minerva-cmc.dtb \
aspeed-bmc-facebook-minipack.dtb \
aspeed-bmc-facebook-tiogapass.dtb \
aspeed-bmc-facebook-wedge40.dtb \
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtjade.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtjade.dts
index 0a51d2e32fab..8ab5f301f926 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtjade.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtjade.dts
@@ -760,49 +760,63 @@
&gpio {
gpio-line-names =
- /*A0-A7*/ "","","","S0_BMC_SPECIAL_BOOT","","","","",
- /*B0-B7*/ "BMC_SELECT_EEPROM","","","",
- "POWER_BUTTON","","","",
+ /*A0-A7*/ "","","","host0-special-boot","","","","",
+ /*B0-B7*/ "i2c-backup-sel","","","",
+ "power-button","presence-cpu0","","",
/*C0-C7*/ "","","","","","","","",
/*D0-D7*/ "","","","","","","","",
/*E0-E7*/ "","","","","","","","",
- /*F0-F7*/ "","","BMC_SYS_PSON_L","S0_DDR_SAVE","PGOOD",
- "S1_DDR_SAVE","","",
- /*G0-G7*/ "host0-ready","SHD_REQ_L","","S0_OVERTEMP_L","","",
- "","",
- /*H0-H7*/ "","","","","PSU1_VIN_GOOD","PSU2_VIN_GOOD","","",
- /*I0-I7*/ "PSU1_PRESENT","PSU2_PRESENT","S1_BMC_SPECIAL_BOOT",
- "","","","","",
- /*J0-J7*/ "S0_HIGHTEMP_L","S0_FAULT_L","S0_SCP_AUTH_FAIL_L","",
- "","","","",
+ /*F0-F7*/ "ps0-pgood","ps1-pgood","power-chassis-control","s0-ddr-save",
+ "power-chassis-good", "s1-ddr-save","","",
+ /*G0-G7*/ "host0-ready","host0-shd-req-n","host0-shd-ack-n",
+ "s0-overtemp-n","","","","",
+ /*H0-H7*/ "uart1-mode1","uart2-mode1","uart3-mode1","uart4-mode1",
+ "ps0-vin-good","ps1-vin-good","","i2c6-reset-n",
+ /*I0-I7*/ "presence-ps0","presence-ps1","s1-special-boot","","","","","",
+ /*J0-J7*/ "s0-hightemp-n","s0-fault-alert","s0-sys-auth-failure-n",
+ "host0-reboot-ack-n","","","","",
/*K0-K7*/ "","","","","","","","",
- /*L0-L7*/ "","","","BMC_SYSRESET_L","SPI_AUTH_FAIL_L","","","",
- /*M0-M7*/ "","","","","","","","",
+ /*L0-L7*/ "","","","host0-sysreset-n","s0-spi-auth-fail-n","","","",
+ /*M0-M7*/ "","","","","s0-i2c9-alert-n","s1-i2c9-alert-n","","",
/*N0-N7*/ "","","","","","","","",
/*O0-O7*/ "","","","","","","","",
/*P0-P7*/ "","","","","","","","",
- /*Q0-Q7*/ "","","","","","UID_BUTTON","","",
- /*R0-R7*/ "","","BMC_EXT_HIGHTEMP_L","OCP_AUX_PWREN",
- "OCP_MAIN_PWREN","RESET_BUTTON","","",
- /*S0-S7*/ "","","","","rtc-battery-voltage-read-enable","","","",
+ /*Q0-Q7*/ "","","","","","identify-button","led-identify","",
+ /*R0-R7*/ "","","ext-hightemp-n","","ocp-main-pwren","reset-button","","",
+ /*S0-S7*/ "s0-vr-hot-n","s1-vr-hot-n","","",
+ "rtc-battery-voltage-read-enable","vr-pmbus-sel-n","","",
/*T0-T7*/ "","","","","","","","",
/*U0-U7*/ "","","","","","","","",
/*V0-V7*/ "","","","","","","","",
/*W0-W7*/ "","","","","","","","",
/*X0-X7*/ "","","","","","","","",
- /*Y0-Y7*/ "","","","","","","","",
- /*Z0-Z7*/ "S0_BMC_PLIMIT","S1_FAULT_L","S1_FW_BOOT_OK","","",
- "S1_SCP_AUTH_FAIL_L","S1_OVERTEMP_L","",
+ /*Y0-Y7*/ "","","","bmc-vga-en-n","","","","",
+ /*Z0-Z7*/ "s0-plimit","s1-fault-alert","s1-fw-boot-ok","s0-rtc-lock","",
+ "s1-sys-auth-failure-n","s1-overtemp-n","",
/*AA0-AA7*/ "","","","","","","","",
- /*AB0-AB7*/ "S1_HIGHTEMP_L","S1_BMC_PLIMIT","S0_BMC_DDR_ADDR",
- "S1_BMC_DDR_ADR","","","","",
- /*AC0-AC7*/ "SYS_PWR_GD","","","","","BMC_READY","SLAVE_PRESENT_L",
- "BMC_OCP_PG";
+ /*AB0-AB7*/ "s1-hightemp-n","s1-plimit","s0-ddr-addr","s1-ddr-addr","","",
+ "","",
+ /*AC0-AC7*/ "sys-pwr-gd","","spi0-program-sel","spi0-backup-sel","bmc-ok",
+ "","presence-cpu1","ocp-pgood";
i2c4-o-en-hog {
gpio-hog;
gpios = <ASPEED_GPIO(Y, 2) GPIO_ACTIVE_HIGH>;
output-high;
- line-name = "BMC_I2C4_O_EN";
+ line-name = "i2c4-o-en";
+ };
+
+ ocp-aux-pwren-hog {
+ gpio-hog;
+ gpios = <ASPEED_GPIO(R, 3) GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "ocp-aux-pwren";
+ };
+
+ bmc-ready {
+ gpio-hog;
+ gpios = <ASPEED_GPIO(AC, 5) GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "bmc-ready";
};
};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts
index 0715cb9ab30c..7b540880cef9 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ampere-mtmitchell.dts
@@ -14,6 +14,42 @@
aliases {
serial7 = &uart8;
serial8 = &uart9;
+
+ /*
+ * I2C NVMe alias port
+ */
+ i2c100 = &backplane_0;
+ i2c48 = &nvmeslot_0;
+ i2c49 = &nvmeslot_1;
+ i2c50 = &nvmeslot_2;
+ i2c51 = &nvmeslot_3;
+ i2c52 = &nvmeslot_4;
+ i2c53 = &nvmeslot_5;
+ i2c54 = &nvmeslot_6;
+ i2c55 = &nvmeslot_7;
+
+ i2c101 = &backplane_1;
+ i2c56 = &nvmeslot_8;
+ i2c57 = &nvmeslot_9;
+ i2c58 = &nvmeslot_10;
+ i2c59 = &nvmeslot_11;
+ i2c60 = &nvmeslot_12;
+ i2c61 = &nvmeslot_13;
+ i2c62 = &nvmeslot_14;
+ i2c63 = &nvmeslot_15;
+
+ i2c102 = &backplane_2;
+ i2c64 = &nvmeslot_16;
+ i2c65 = &nvmeslot_17;
+ i2c66 = &nvmeslot_18;
+ i2c67 = &nvmeslot_19;
+ i2c68 = &nvmeslot_20;
+ i2c69 = &nvmeslot_21;
+ i2c70 = &nvmeslot_22;
+ i2c71 = &nvmeslot_23;
+
+ i2c80 = &nvme_m2_0;
+ i2c81 = &nvme_m2_1;
};
chosen {
@@ -497,6 +533,11 @@
&i2c8 {
status = "okay";
+ temperature-sensor@48 {
+ compatible = "ti,tmp112";
+ reg = <0x48>;
+ };
+
gpio@77 {
compatible = "nxp,pca9539";
reg = <0x77>;
@@ -516,6 +557,237 @@
&i2c9 {
status = "okay";
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+ i2c-mux-idle-disconnect;
+
+ backplane_1: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ pagesize = <32>;
+ };
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x71>;
+ i2c-mux-idle-disconnect;
+
+ nvmeslot_8: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+ };
+ nvmeslot_9: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1>;
+ };
+ nvmeslot_10: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+ };
+ nvmeslot_11: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+ };
+ nvmeslot_12: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4>;
+ };
+ nvmeslot_13: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x5>;
+ };
+ nvmeslot_14: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x6>;
+ };
+ nvmeslot_15: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x7>;
+ };
+ };
+
+ tmp432@4c {
+ compatible = "ti,tmp75";
+ reg = <0x4c>;
+ };
+ };
+
+ backplane_2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+
+ eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ pagesize = <32>;
+ };
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x71>;
+ i2c-mux-idle-disconnect;
+
+ nvmeslot_16: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+ };
+ nvmeslot_17: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1>;
+ };
+ nvmeslot_18: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+ };
+ nvmeslot_19: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+ };
+ nvmeslot_20: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4>;
+ };
+ nvmeslot_21: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x5>;
+ };
+ nvmeslot_22: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x6>;
+ };
+ nvmeslot_23: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x7>;
+ };
+ };
+
+ tmp432@4c {
+ compatible = "ti,tmp75";
+ reg = <0x4c>;
+ };
+ };
+
+ backplane_0: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4>;
+
+ eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ pagesize = <32>;
+ };
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x71>;
+ i2c-mux-idle-disconnect;
+
+ nvmeslot_0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+ };
+ nvmeslot_1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1>;
+ };
+ nvmeslot_2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+ };
+ nvmeslot_3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+ };
+ nvmeslot_4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4>;
+ };
+ nvmeslot_5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x5>;
+ };
+ nvmeslot_6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x6>;
+ };
+ nvmeslot_7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x7>;
+ };
+ };
+
+ tmp432@4c {
+ compatible = "ti,tmp75";
+ reg = <0x4c>;
+ };
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x7>;
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9546";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x71>;
+ i2c-mux-idle-disconnect;
+
+ nvme_m2_0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+ };
+
+ nvme_m2_1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1>;
+ };
+ };
+ };
+ };
};
&i2c11 {
@@ -546,20 +818,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
- &pinctrl_adc2_default &pinctrl_adc3_default
- &pinctrl_adc4_default &pinctrl_adc5_default
- &pinctrl_adc6_default &pinctrl_adc7_default>;
-};
-
-&adc1 {
- ref_voltage = <2500>;
- status = "okay";
-
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc9_default
- &pinctrl_adc10_default &pinctrl_adc11_default
- &pinctrl_adc12_default &pinctrl_adc13_default
- &pinctrl_adc14_default &pinctrl_adc15_default>;
+ &pinctrl_adc2_default>;
};
&vhub {
@@ -575,16 +834,17 @@
gpio-line-names =
/*A0-A7*/ "","","","","","i2c2-reset-n","i2c6-reset-n","i2c4-reset-n",
/*B0-B7*/ "","","","","host0-sysreset-n","host0-pmin-n","","",
- /*C0-C7*/ "s0-vrd-fault-n","s1-vrd-fault-n","","",
+ /*C0-C7*/ "s0-vrd-fault-n","s1-vrd-fault-n","bmc-debug-mode","",
"irq-n","","vrd-sel","spd-sel",
/*D0-D7*/ "presence-ps0","presence-ps1","hsc-12vmain-alt2-n","ext-high-temp-n",
"","bmc-ncsi-txen","","",
- /*E0-E7*/ "","","clk50m-bmc-ncsi","","","","","",
+ /*E0-E7*/ "","eth-phy-int-n","clk50m-bmc-ncsi","","","","","",
/*F0-F7*/ "s0-pcp-oc-warn-n","s1-pcp-oc-warn-n","power-chassis-control",
"cpu-bios-recover","s0-heartbeat","hs-csout-prochot",
"s0-vr-hot-n","s1-vr-hot-n",
/*G0-G7*/ "","","hsc-12vmain-alt1-n","","","","","",
- /*H0-H7*/ "","","wd-disable-n","power-chassis-good","","","","",
+ /*H0-H7*/ "jtag-program-sel","fpga-program-b","wd-disable-n",
+ "power-chassis-good","","","","",
/*I0-I7*/ "","","","","","adc-sw","power-button","rtc-battery-voltage-read-enable",
/*J0-J7*/ "","","","","","","","",
/*K0-K7*/ "","","","","","","","",
@@ -599,17 +859,17 @@
/*Q0-Q7*/ "","","","","","","","",
/*R0-R7*/ "","","","","","","","",
/*S0-S7*/ "","","identify-button","led-identify",
- "s1-ddr-save","spi-nor-access","sys-pgood","presence-cpu1",
+ "s1-ddr-save","spi-nor-access","host0-ready","presence-cpu1",
/*T0-T7*/ "","","","","","","","",
/*U0-U7*/ "","","","","","","","",
/*V0-V7*/ "s0-hightemp-n","s0-fault-alert","s0-sys-auth-failure-n",
- "host0-reboot-ack-n","host0-ready","host0-shd-req-n",
+ "host0-reboot-ack-n","s0-fw-boot-ok","host0-shd-req-n",
"host0-shd-ack-n","s0-overtemp-n",
- /*W0-W7*/ "","ocp-main-pwren","ocp-pgood","",
+ /*W0-W7*/ "ocp-aux-pwren","ocp-main-pwren","ocp-pgood","s1-pcp-pgood",
"bmc-ok","bmc-ready","spi0-program-sel","spi0-backup-sel",
/*X0-X7*/ "i2c-backup-sel","s1-fault-alert","s1-fw-boot-ok",
"s1-hightemp-n","s0-spi-auth-fail-n","s1-sys-auth-failure-n",
- "s1-overtemp-n","s1-spi-auth-fail-n",
+ "s1-overtemp-n","cpld-s1-spi-auth-fail-n",
/*Y0-Y7*/ "","","","","","","","host0-special-boot",
/*Z0-Z7*/ "reset-button","ps0-pgood","ps1-pgood","","","","","";
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva-cmc.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva-cmc.dts
new file mode 100644
index 000000000000..f04ef9063520
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva-cmc.dts
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2023 Facebook Inc.
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+
+/ {
+ model = "Facebook Minerva CMC";
+ compatible = "facebook,minerva-cmc", "aspeed,ast2600";
+
+ aliases {
+ serial5 = &uart5;
+ };
+
+ chosen {
+ stdout-path = "serial5:57600n8";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+ <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+ <&adc1 2>;
+ };
+};
+
+&uart6 {
+ status = "okay";
+};
+
+&wdt1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdtrst1_default>;
+ aspeed,reset-type = "soc";
+ aspeed,external-signal;
+ aspeed,ext-push-pull;
+ aspeed,ext-active-high;
+ aspeed,ext-pulse-duration = <256>;
+};
+
+&mac3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii4_default>;
+ use-ncsi;
+ mlx,multi-host;
+};
+
+&fmc {
+ status = "okay";
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-128.dtsi"
+ };
+ flash@1 {
+ status = "okay";
+ m25p,fast-read;
+ label = "alt-bmc";
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sgpiom1 {
+ status = "okay";
+ ngpios = <128>;
+ bus-frequency = <2000000>;
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+
+ temperature-sensor@4b {
+ compatible = "ti,tmp75";
+ reg = <0x4B>;
+ };
+
+ eeprom@51 {
+ compatible = "atmel,24c128";
+ reg = <0x51>;
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&i2c6 {
+ status = "okay";
+};
+
+&i2c7 {
+ status = "okay";
+};
+
+&i2c8 {
+ status = "okay";
+};
+
+&i2c9 {
+ status = "okay";
+};
+
+&i2c10 {
+ status = "okay";
+};
+
+&i2c11 {
+ status = "okay";
+};
+
+&i2c12 {
+ status = "okay";
+};
+
+&i2c13 {
+ status = "okay";
+};
+
+&i2c14 {
+ status = "okay";
+ multi-master;
+
+ ipmb@10 {
+ compatible = "ipmb-dev";
+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+ i2c-protocol;
+ };
+};
+
+&i2c15 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+};
+
+&adc0 {
+ aspeed,int-vref-microvolt = <2500000>;
+ status = "okay";
+ pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
+ &pinctrl_adc2_default &pinctrl_adc3_default
+ &pinctrl_adc4_default &pinctrl_adc5_default
+ &pinctrl_adc6_default &pinctrl_adc7_default>;
+};
+
+&adc1 {
+ aspeed,int-vref-microvolt = <2500000>;
+ status = "okay";
+ pinctrl-0 = <&pinctrl_adc10_default>;
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&uhci {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts
index d47ce4edc67c..cad1b9aac97b 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts
@@ -34,6 +34,11 @@
#size-cells = <1>;
ranges;
+ event_log: tcg_event_log@b3d00000 {
+ no-map;
+ reg = <0xb3d00000 0x100000>;
+ };
+
ramoops@b3e00000 {
compatible = "ramoops";
reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */
@@ -454,8 +459,9 @@
status = "okay";
tpm@2e {
- compatible = "nuvoton,npct75x";
+ compatible = "nuvoton,npct75x", "tcg,tpm-tis-i2c";
reg = <0x2e>;
+ memory-region = <&event_log>;
};
eeprom@50 {
diff --git a/arch/arm/boot/dts/broadcom/bcm-ns.dtsi b/arch/arm/boot/dts/broadcom/bcm-ns.dtsi
index 88fda18af1f8..d0d5f7e52a91 100644
--- a/arch/arm/boot/dts/broadcom/bcm-ns.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm-ns.dtsi
@@ -14,6 +14,13 @@
#address-cells = <1>;
#size-cells = <1>;
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts =
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
chipcommon-a-bus@18000000 {
compatible = "simple-bus";
ranges = <0x00000000 0x18000000 0x00001000>;
@@ -320,6 +327,29 @@
#address-cells = <1>;
};
+ mdio-mux@18003000 {
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ mdio-parent-bus = <&mdio>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x18003000 0x4>;
+ mux-mask = <0x200>;
+
+ mdio@0 {
+ reg = <0x0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_phy: usb3-phy@10 {
+ compatible = "brcm,ns-ax-usb3-phy";
+ reg = <0x10>;
+ usb3-dmp-syscon = <&usb3_dmp>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+ };
+
rng: rng@18004000 {
compatible = "brcm,bcm5301x-rng";
reg = <0x18004000 0x14>;
@@ -460,6 +490,10 @@
brcm,nand-has-wp;
};
+ usb3_dmp: syscon@18105000 {
+ reg = <0x18105000 0x1000>;
+ };
+
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <0>;
diff --git a/arch/arm/boot/dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi b/arch/arm/boot/dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi
index 42bcbf10957c..9f9084269ef5 100644
--- a/arch/arm/boot/dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi
@@ -181,5 +181,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts b/arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts
index e04d2e5ea51a..72e960c888ac 100644
--- a/arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts
+++ b/arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts
@@ -85,5 +85,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts b/arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts
index a399800139d9..750e17482371 100644
--- a/arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts
+++ b/arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts
@@ -88,5 +88,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts
index fad3473810a2..2bdbc7d18b0e 100644
--- a/arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts
+++ b/arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts
@@ -122,5 +122,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts b/arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts
index 5b2b7b8b3b12..b226bef3369c 100644
--- a/arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts
+++ b/arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts
@@ -145,6 +145,14 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts b/arch/arm/boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts
index d0a26b643b82..192b8db5a89c 100644
--- a/arch/arm/boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts
@@ -145,5 +145,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts b/arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts
index 9f21d6d6d35b..0198b5f9e4a7 100644
--- a/arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts
@@ -81,5 +81,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts b/arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts
index 256107291702..73ff1694a4a0 100644
--- a/arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts
@@ -148,5 +148,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac87u.dts
index 4f44cb4df704..59400217f8c3 100644
--- a/arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac87u.dts
+++ b/arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac87u.dts
@@ -25,6 +25,12 @@
<0x88000000 0x08000000>;
};
+ nvram@1c080000 {
+ et1macaddr: et1macaddr {
+ #nvmem-cell-cells = <1>;
+ };
+ };
+
leds {
compatible = "gpio-leds";
@@ -62,6 +68,11 @@
};
};
+&gmac0 {
+ nvmem-cells = <&et1macaddr 0>;
+ nvmem-cell-names = "mac-address";
+};
+
&usb3_phy {
status = "okay";
};
diff --git a/arch/arm/boot/dts/broadcom/bcm4709-linksys-ea9200.dts b/arch/arm/boot/dts/broadcom/bcm4709-linksys-ea9200.dts
index 99253fd7adb3..2ba5adf2b7e7 100644
--- a/arch/arm/boot/dts/broadcom/bcm4709-linksys-ea9200.dts
+++ b/arch/arm/boot/dts/broadcom/bcm4709-linksys-ea9200.dts
@@ -47,3 +47,41 @@
&usb3_phy {
status = "okay";
};
+
+&srab {
+ status = "okay";
+
+ ports {
+ port@0 {
+ label = "lan1";
+ };
+
+ port@1 {
+ label = "lan2";
+ };
+
+ port@2 {
+ label = "lan3";
+ };
+
+ port@3 {
+ label = "lan4";
+ };
+
+ port@4 {
+ label = "wan";
+ };
+
+ port@5 {
+ status = "disabled";
+ };
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ label = "cpu";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts
index 707c561703ed..127ca8741220 100644
--- a/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts
+++ b/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts
@@ -227,6 +227,24 @@
label = "wan";
};
+ port@5 {
+ status = "disabled";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ port@7 {
+ status = "disabled";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
port@8 {
label = "cpu";
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts
index c914569ddd5e..c5099defe9f9 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts
@@ -25,6 +25,15 @@
<0x88000000 0x08000000>;
};
+ nvram@1e3f0000 {
+ compatible = "brcm,nvram";
+ reg = <0x1e3f0000 0x10000>;
+
+ et2macaddr: et2macaddr {
+ #nvmem-cell-cells = <1>;
+ };
+ };
+
nand_controller: nand-controller@18028000 {
nand@0 {
partitions {
@@ -112,6 +121,11 @@
vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
};
+&gmac0 {
+ nvmem-cells = <&et2macaddr 0>;
+ nvmem-cell-names = "mac-address";
+};
+
&spi_nor {
status = "okay";
};
@@ -142,6 +156,16 @@
port@4 {
label = "wan";
+ nvmem-cells = <&et2macaddr 3>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ port@5 {
+ status = "disabled";
+ };
+
+ port@7 {
+ status = "disabled";
};
port@8 {
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts b/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts
index f050acbea0b2..3124dfd01b94 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts
@@ -192,6 +192,14 @@
label = "wan";
};
+ port@5 {
+ status = "disabled";
+ };
+
+ port@7 {
+ status = "disabled";
+ };
+
port@8 {
label = "cpu";
phy-mode = "rgmii";
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts
index e8991d4e248c..e374062eb5b7 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts
@@ -107,5 +107,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts
index afc635c8cdeb..badafa024d24 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts
@@ -120,5 +120,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts
index 7cfa4607ef31..cf95af9db1e6 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts
@@ -107,5 +107,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts
index d55e10095eae..992c19e1cfa1 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts
@@ -75,5 +75,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts
index ccf031c0e276..4d0ba315a204 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts
@@ -147,5 +147,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts
index e28f7a350117..83c429afc297 100644
--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts
+++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts
@@ -158,5 +158,13 @@
port@5 {
label = "cpu";
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts b/arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts
index 03ad614e6b72..0bf5106f7012 100644
--- a/arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts
+++ b/arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts
@@ -124,6 +124,14 @@
full-duplex;
};
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts
index 26c12bfb0bdd..25eeacf6a248 100644
--- a/arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts
+++ b/arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts
@@ -185,6 +185,14 @@
full-duplex;
};
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm5301x.dtsi b/arch/arm/boot/dts/broadcom/bcm5301x.dtsi
index 600a1b54f2ae..f06a178a9240 100644
--- a/arch/arm/boot/dts/broadcom/bcm5301x.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm5301x.dtsi
@@ -26,13 +26,6 @@
};
};
- pmu {
- compatible = "arm,cortex-a9-pmu";
- interrupts =
- <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
- };
-
clocks {
#address-cells = <1>;
#size-cells = <1>;
@@ -69,33 +62,6 @@
};
};
- mdio-mux@18003000 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
- mdio-parent-bus = <&mdio>;
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x18003000 0x4>;
- mux-mask = <0x200>;
-
- mdio@0 {
- reg = <0x0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_phy: usb3-phy@10 {
- compatible = "brcm,ns-ax-usb3-phy";
- reg = <0x10>;
- usb3-dmp-syscon = <&usb3_dmp>;
- #phy-cells = <0>;
- status = "disabled";
- };
- };
- };
-
- usb3_dmp: syscon@18105000 {
- reg = <0x18105000 0x1000>;
- };
-
i2c0: i2c@18009000 {
compatible = "brcm,iproc-i2c";
reg = <0x18009000 0x50>;
diff --git a/arch/arm/boot/dts/broadcom/bcm953012er.dts b/arch/arm/boot/dts/broadcom/bcm953012er.dts
index 4fe3b3653376..d939ec9f4a9e 100644
--- a/arch/arm/boot/dts/broadcom/bcm953012er.dts
+++ b/arch/arm/boot/dts/broadcom/bcm953012er.dts
@@ -84,6 +84,14 @@
label = "cpu";
ethernet = <&gmac0>;
};
+
+ port@7 {
+ status = "disabled";
+ };
+
+ port@8 {
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/intel/ixp/Makefile b/arch/arm/boot/dts/intel/ixp/Makefile
index 1a25ce3cf84f..ab8525f1ea1d 100644
--- a/arch/arm/boot/dts/intel/ixp/Makefile
+++ b/arch/arm/boot/dts/intel/ixp/Makefile
@@ -16,4 +16,5 @@ dtb-$(CONFIG_ARCH_IXP4XX) += \
intel-ixp43x-gateworks-gw2358.dtb \
intel-ixp42x-netgear-wg302v1.dtb \
intel-ixp42x-arcom-vulcan.dtb \
- intel-ixp42x-gateway-7001.dtb
+ intel-ixp42x-gateway-7001.dtb \
+ intel-ixp42x-usrobotics-usr8200.dtb
diff --git a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-dlink-dsm-g600.dts b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-dlink-dsm-g600.dts
index b9d46eb06507..fa133c913606 100644
--- a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-dlink-dsm-g600.dts
+++ b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-dlink-dsm-g600.dts
@@ -57,7 +57,7 @@
button-reset {
wakeup-source;
- linux,code = <KEY_ESC>;
+ linux,code = <KEY_RESTART>;
label = "reset";
gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-freecom-fsg-3.dts b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-freecom-fsg-3.dts
index 5a5e16cc7335..73d3c11dd0d4 100644
--- a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-freecom-fsg-3.dts
+++ b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-freecom-fsg-3.dts
@@ -44,7 +44,7 @@
};
button-reset {
wakeup-source;
- linux,code = <KEY_ESC>;
+ linux,code = <KEY_RESTART>;
label = "reset";
gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-iomega-nas100d.dts b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-iomega-nas100d.dts
index 8da6823e1dbe..26f02dad6a54 100644
--- a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-iomega-nas100d.dts
+++ b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-iomega-nas100d.dts
@@ -63,7 +63,7 @@
};
button-reset {
wakeup-source;
- linux,code = <KEY_ESC>;
+ linux,code = <KEY_RESTART>;
label = "reset";
gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts
index da1e93212b86..2eec5f63d399 100644
--- a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts
+++ b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-nslu2.dts
@@ -65,7 +65,7 @@
};
button-reset {
wakeup-source;
- linux,code = <KEY_ESC>;
+ linux,code = <KEY_RESTART>;
label = "reset";
gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
};
@@ -101,6 +101,8 @@
flash@0,0 {
compatible = "intel,ixp4xx-flash", "cfi-flash";
bank-width = <2>;
+ /* Enable writes on the expansion bus */
+ intel,ixp4xx-eb-write-enable = <1>;
/*
* 8 MB of Flash in 0x20000 byte blocks
* mapped in at CS0.
diff --git a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-wrv54g.dts b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-wrv54g.dts
index 4aba9e0214a0..98275a363c57 100644
--- a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-wrv54g.dts
+++ b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-linksys-wrv54g.dts
@@ -13,7 +13,7 @@
/ {
model = "Linksys WRV54G / Gemtek GTWX5715";
- compatible = "linksys,wrv54g", "gemtek,gtwx5715", "intel,ixp42x";
+ compatible = "linksys,wrv54g", "intel,ixp42x";
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-usrobotics-usr8200.dts b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-usrobotics-usr8200.dts
new file mode 100644
index 000000000000..90fd51b36e7d
--- /dev/null
+++ b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-usrobotics-usr8200.dts
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Device Tree file for the USRobotics USR8200 firewall
+ * VPN and NAS. Based on know-how from Peter Denison.
+ *
+ * This machine is based on IXP422, the USR internal codename
+ * is "Jeeves".
+ */
+
+/dts-v1/;
+
+#include "intel-ixp42x.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "USRobotics USR8200";
+ compatible = "usr,usr8200", "intel,ixp42x";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x00000000 0x4000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = "uart1:115200n8";
+ };
+
+ aliases {
+ /* These are switched around */
+ serial0 = &uart1;
+ serial1 = &uart0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ ieee1394_led: led-1394 {
+ label = "usr8200:green:1394";
+ gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ usb1_led: led-usb1 {
+ label = "usr8200:green:usb1";
+ gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ usb2_led: led-usb2 {
+ label = "usr8200:green:usb2";
+ gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ wireless_led: led-wireless {
+ /*
+ * This LED is mounted inside the case but cannot be
+ * seen from the outside: probably USR planned at one
+ * point for the device to have a wireless card, then
+ * changed their mind and didn't mount it, leaving the
+ * LED in place.
+ */
+ label = "usr8200:green:wireless";
+ gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ pwr_led: led-pwr {
+ label = "usr8200:green:pwr";
+ gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ button-reset {
+ wakeup-source;
+ linux,code = <KEY_RESTART>;
+ label = "reset";
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ soc {
+ bus@c4000000 {
+ flash@0,0 {
+ compatible = "intel,ixp4xx-flash", "cfi-flash";
+ bank-width = <2>;
+ /* Enable writes on the expansion bus */
+ intel,ixp4xx-eb-write-enable = <1>;
+ /* 16 MB of Flash mapped in at CS0 */
+ reg = <0 0x00000000 0x1000000>;
+
+ partitions {
+ compatible = "redboot-fis";
+ /* Eraseblock at 0x0fe0000 */
+ fis-index-block = <0x7f>;
+ };
+ };
+ rtc@2,0 {
+ /* EPSON RTC7301 DG DIL-capsule */
+ compatible = "epson,rtc7301dg";
+ /*
+ * These timing settings were found in the boardfile patch:
+ * IXP4XX_EXP_CS2 = 0x3fff000 | IXP4XX_EXP_BUS_SIZE(0) | IXP4XX_EXP_BUS_WR_EN |
+ * IXP4XX_EXP_BUS_CS_EN | IXP4XX_EXP_BUS_BYTE_EN;
+ */
+ intel,ixp4xx-eb-t1 = <0>; // no cycles extra address phase
+ intel,ixp4xx-eb-t2 = <0>; // no cycles extra setup phase
+ intel,ixp4xx-eb-t3 = <15>; // 15 cycles extra strobe phase
+ intel,ixp4xx-eb-t4 = <3>; // 3 cycles extra hold phase
+ intel,ixp4xx-eb-t5 = <15>; // 15 cycles extra recovery phase
+ intel,ixp4xx-eb-cycle-type = <0>; // Intel cycle
+ intel,ixp4xx-eb-byte-access-on-halfword = <0>;
+ intel,ixp4xx-eb-mux-address-and-data = <0>;
+ intel,ixp4xx-eb-ahb-split-transfers = <0>;
+ intel,ixp4xx-eb-write-enable = <1>;
+ intel,ixp4xx-eb-byte-access = <1>;
+ /* 512 bytes at CS2 */
+ reg = <2 0x00000000 0x0000200>;
+ reg-io-width = <1>;
+ native-endian;
+ /* FIXME: try to check if there is an IRQ for the RTC? */
+ };
+ };
+
+ pci@c0000000 {
+ status = "okay";
+
+ /*
+ * Taken from USR8200 boardfile from OpenWrt
+ *
+ * We have 3 slots (IDSEL) with partly swizzled IRQs on slot 16.
+ * We assume the same IRQ for all pins on the remaining slots, that
+ * is what the boardfile was doing.
+ */
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map =
+ /* IDSEL 14 used for "Wireless" in the board file */
+ <0x7000 0 0 1 &gpio0 7 IRQ_TYPE_LEVEL_LOW>, /* INT A on slot 14 is irq 7 */
+ /* IDSEL 15 used for VIA VT6307 IEEE 1394 Firewire */
+ <0x7800 0 0 1 &gpio0 8 IRQ_TYPE_LEVEL_LOW>, /* INT A on slot 15 is irq 8 */
+ /* IDSEL 16 used for VIA VT6202 USB 2.0 4+1 */
+ <0x8000 0 0 1 &gpio0 11 IRQ_TYPE_LEVEL_LOW>, /* INT A on slot 16 is irq 11 */
+ <0x8000 0 0 2 &gpio0 10 IRQ_TYPE_LEVEL_LOW>, /* INT B on slot 16 is irq 10 */
+ <0x8000 0 0 3 &gpio0 9 IRQ_TYPE_LEVEL_LOW>; /* INT C on slot 16 is irq 9 */
+ };
+
+ gpio@c8004000 {
+ /* Enable clock out on GPIO 15 */
+ intel,ixp4xx-gpio15-clkout;
+ };
+
+ /* EthB WAN */
+ ethernet@c8009000 {
+ status = "okay";
+ queue-rx = <&qmgr 3>;
+ queue-txready = <&qmgr 20>;
+ phy-mode = "rgmii";
+ phy-handle = <&phy9>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy9: ethernet-phy@9 {
+ reg = <9>;
+ };
+
+ /* The switch uses MDIO addresses 16 thru 31 */
+ switch@16 {
+ compatible = "marvell,mv88e6060";
+ reg = <16>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+ };
+
+ port@5 {
+ /* Port 5 is the CPU port according to the MV88E6060 datasheet */
+ reg = <5>;
+ phy-mode = "rgmii-id";
+ ethernet = <&ethc>;
+ label = "cpu";
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+ };
+ };
+ };
+ };
+ };
+
+ /* EthC LAN connected to the Marvell DSA Switch */
+ ethc: ethernet@c800a000 {
+ status = "okay";
+ queue-rx = <&qmgr 4>;
+ queue-txready = <&qmgr 21>;
+ phy-mode = "rgmii";
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/mediatek/mt2701-evb.dts b/arch/arm/boot/dts/mediatek/mt2701-evb.dts
index d1535f385f36..9c7325f18933 100644
--- a/arch/arm/boot/dts/mediatek/mt2701-evb.dts
+++ b/arch/arm/boot/dts/mediatek/mt2701-evb.dts
@@ -244,7 +244,7 @@
&usb2 {
status = "okay";
usb-role-switch;
- connector{
+ connector {
compatible = "gpio-usb-b-connector", "usb-b-connector";
type = "micro";
id-gpios = <&pio 44 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/mediatek/mt6323.dtsi b/arch/arm/boot/dts/mediatek/mt6323.dtsi
index 7fda40ab5fe8..c230c865116d 100644
--- a/arch/arm/boot/dts/mediatek/mt6323.dtsi
+++ b/arch/arm/boot/dts/mediatek/mt6323.dtsi
@@ -21,10 +21,10 @@
status = "disabled";
};
- mt6323regulator: mt6323regulator{
+ mt6323regulator: mt6323regulator {
compatible = "mediatek,mt6323-regulator";
- mt6323_vproc_reg: buck_vproc{
+ mt6323_vproc_reg: buck_vproc {
regulator-name = "vproc";
regulator-min-microvolt = < 700000>;
regulator-max-microvolt = <1350000>;
@@ -33,7 +33,7 @@
regulator-boot-on;
};
- mt6323_vsys_reg: buck_vsys{
+ mt6323_vsys_reg: buck_vsys {
regulator-name = "vsys";
regulator-min-microvolt = <1400000>;
regulator-max-microvolt = <2987500>;
@@ -42,13 +42,13 @@
regulator-boot-on;
};
- mt6323_vpa_reg: buck_vpa{
+ mt6323_vpa_reg: buck_vpa {
regulator-name = "vpa";
regulator-min-microvolt = < 500000>;
regulator-max-microvolt = <3650000>;
};
- mt6323_vtcxo_reg: ldo_vtcxo{
+ mt6323_vtcxo_reg: ldo_vtcxo {
regulator-name = "vtcxo";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
@@ -57,28 +57,28 @@
regulator-boot-on;
};
- mt6323_vcn28_reg: ldo_vcn28{
+ mt6323_vcn28_reg: ldo_vcn28 {
regulator-name = "vcn28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <185>;
};
- mt6323_vcn33_bt_reg: ldo_vcn33_bt{
+ mt6323_vcn33_bt_reg: ldo_vcn33_bt {
regulator-name = "vcn33_bt";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3600000>;
regulator-enable-ramp-delay = <185>;
};
- mt6323_vcn33_wifi_reg: ldo_vcn33_wifi{
+ mt6323_vcn33_wifi_reg: ldo_vcn33_wifi {
regulator-name = "vcn33_wifi";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3600000>;
regulator-enable-ramp-delay = <185>;
};
- mt6323_va_reg: ldo_va{
+ mt6323_va_reg: ldo_va {
regulator-name = "va";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
@@ -87,14 +87,14 @@
regulator-boot-on;
};
- mt6323_vcama_reg: ldo_vcama{
+ mt6323_vcama_reg: ldo_vcama {
regulator-name = "vcama";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <216>;
};
- mt6323_vio28_reg: ldo_vio28{
+ mt6323_vio28_reg: ldo_vio28 {
regulator-name = "vio28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
@@ -103,7 +103,7 @@
regulator-boot-on;
};
- mt6323_vusb_reg: ldo_vusb{
+ mt6323_vusb_reg: ldo_vusb {
regulator-name = "vusb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
@@ -111,7 +111,7 @@
regulator-boot-on;
};
- mt6323_vmc_reg: ldo_vmc{
+ mt6323_vmc_reg: ldo_vmc {
regulator-name = "vmc";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
@@ -119,7 +119,7 @@
regulator-boot-on;
};
- mt6323_vmch_reg: ldo_vmch{
+ mt6323_vmch_reg: ldo_vmch {
regulator-name = "vmch";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3300000>;
@@ -127,7 +127,7 @@
regulator-boot-on;
};
- mt6323_vemc3v3_reg: ldo_vemc3v3{
+ mt6323_vemc3v3_reg: ldo_vemc3v3 {
regulator-name = "vemc3v3";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3300000>;
@@ -135,49 +135,49 @@
regulator-boot-on;
};
- mt6323_vgp1_reg: ldo_vgp1{
+ mt6323_vgp1_reg: ldo_vgp1 {
regulator-name = "vgp1";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <216>;
};
- mt6323_vgp2_reg: ldo_vgp2{
+ mt6323_vgp2_reg: ldo_vgp2 {
regulator-name = "vgp2";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3000000>;
regulator-enable-ramp-delay = <216>;
};
- mt6323_vgp3_reg: ldo_vgp3{
+ mt6323_vgp3_reg: ldo_vgp3 {
regulator-name = "vgp3";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <216>;
};
- mt6323_vcn18_reg: ldo_vcn18{
+ mt6323_vcn18_reg: ldo_vcn18 {
regulator-name = "vcn18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <216>;
};
- mt6323_vsim1_reg: ldo_vsim1{
+ mt6323_vsim1_reg: ldo_vsim1 {
regulator-name = "vsim1";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
regulator-enable-ramp-delay = <216>;
};
- mt6323_vsim2_reg: ldo_vsim2{
+ mt6323_vsim2_reg: ldo_vsim2 {
regulator-name = "vsim2";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
regulator-enable-ramp-delay = <216>;
};
- mt6323_vrtc_reg: ldo_vrtc{
+ mt6323_vrtc_reg: ldo_vrtc {
regulator-name = "vrtc";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
@@ -185,28 +185,28 @@
regulator-boot-on;
};
- mt6323_vcamaf_reg: ldo_vcamaf{
+ mt6323_vcamaf_reg: ldo_vcamaf {
regulator-name = "vcamaf";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <216>;
};
- mt6323_vibr_reg: ldo_vibr{
+ mt6323_vibr_reg: ldo_vibr {
regulator-name = "vibr";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <36>;
};
- mt6323_vrf18_reg: ldo_vrf18{
+ mt6323_vrf18_reg: ldo_vrf18 {
regulator-name = "vrf18";
regulator-min-microvolt = <1825000>;
regulator-max-microvolt = <1825000>;
regulator-enable-ramp-delay = <187>;
};
- mt6323_vm_reg: ldo_vm{
+ mt6323_vm_reg: ldo_vm {
regulator-name = "vm";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1800000>;
@@ -215,7 +215,7 @@
regulator-boot-on;
};
- mt6323_vio18_reg: ldo_vio18{
+ mt6323_vio18_reg: ldo_vio18 {
regulator-name = "vio18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@@ -224,14 +224,14 @@
regulator-boot-on;
};
- mt6323_vcamd_reg: ldo_vcamd{
+ mt6323_vcamd_reg: ldo_vcamd {
regulator-name = "vcamd";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <216>;
};
- mt6323_vcamio_reg: ldo_vcamio{
+ mt6323_vcamio_reg: ldo_vcamio {
regulator-name = "vcamio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
diff --git a/arch/arm/boot/dts/mediatek/mt7623n.dtsi b/arch/arm/boot/dts/mediatek/mt7623n.dtsi
index 3adab5cd1fef..3e5cabf19cde 100644
--- a/arch/arm/boot/dts/mediatek/mt7623n.dtsi
+++ b/arch/arm/boot/dts/mediatek/mt7623n.dtsi
@@ -116,8 +116,8 @@
"mediatek,mt2701-jpgdec";
reg = <0 0x15004000 0 0x1000>;
interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&imgsys CLK_IMG_JPGDEC_SMI>,
- <&imgsys CLK_IMG_JPGDEC>;
+ clocks = <&imgsys CLK_IMG_JPGDEC_SMI>,
+ <&imgsys CLK_IMG_JPGDEC>;
clock-names = "jpgdec-smi",
"jpgdec";
power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
diff --git a/arch/arm/boot/dts/mediatek/mt7629-rfb.dts b/arch/arm/boot/dts/mediatek/mt7629-rfb.dts
index 84e14bee7235..f24ebc20732a 100644
--- a/arch/arm/boot/dts/mediatek/mt7629-rfb.dts
+++ b/arch/arm/boot/dts/mediatek/mt7629-rfb.dts
@@ -168,7 +168,7 @@
i2c_pins: i2c-pins {
mux {
function = "i2c";
- groups = "i2c_0";
+ groups = "i2c_0";
};
conf {
diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
index 31e03747cdf4..efde9546c8f4 100644
--- a/arch/arm/boot/dts/microchip/Makefile
+++ b/arch/arm/boot/dts/microchip/Makefile
@@ -4,6 +4,7 @@ DTC_FLAGS_at91-sam9x60_curiosity := -@
DTC_FLAGS_at91-sam9x60ek := -@
DTC_FLAGS_at91-sama5d27_som1_ek := -@
DTC_FLAGS_at91-sama5d27_wlsom1_ek := -@
+DTC_FLAGS_at91-sama5d29_curiosity := -@
DTC_FLAGS_at91-sama5d2_icp := -@
DTC_FLAGS_at91-sama5d2_ptc_ek := -@
DTC_FLAGS_at91-sama5d2_xplained := -@
@@ -64,6 +65,7 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
at91-nattis-2-natte-2.dtb \
at91-sama5d27_som1_ek.dtb \
at91-sama5d27_wlsom1_ek.dtb \
+ at91-sama5d29_curiosity.dtb \
at91-sama5d2_icp.dtb \
at91-sama5d2_ptc_ek.dtb \
at91-sama5d2_xplained.dtb \
diff --git a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
index cb86a3a170ce..83372c1f291b 100644
--- a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
+++ b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
@@ -439,6 +439,10 @@
status = "okay";
};
+&rtt {
+ atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
+};
+
&sdmmc0 {
bus-width = <4>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
new file mode 100644
index 000000000000..6b02b7bcfd49
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
@@ -0,0 +1,600 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sama5d29_curiosity.dts - Device Tree file for SAMA5D29 Curiosity board
+ *
+ * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Mihai Sain <mihai.sain@microchip.com>
+ *
+ */
+/dts-v1/;
+#include "sama5d29.dtsi"
+#include "sama5d2-pinfunc.h"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+
+/ {
+ model = "Microchip SAMA5D29 Curiosity";
+ compatible = "microchip,sama5d29-curiosity", "atmel,sama5d29", "atmel,sama5d2", "atmel,sama5";
+
+ aliases {
+ serial0 = &uart0; // debug
+ serial1 = &uart1; // RPi
+ serial2 = &uart3; // mikro BUS 2
+ serial3 = &uart4; // mikro BUS 1
+ serial4 = &uart6; // flx1 Bluetooth
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait";
+ stdout-path = "serial0:115200n8";
+ };
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <24000000>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_key_gpio_default>;
+
+ button-1 {
+ label = "USER BUTTON";
+ gpios = <&pioA PIN_PA17 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_led_gpio_default>;
+ status = "okay";
+
+ led-red {
+ label = "red";
+ gpios = <&pioA PIN_PA7 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-green {
+ label = "green";
+ gpios = <&pioA PIN_PA8 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-blue {
+ label = "blue";
+ gpios = <&pioA PIN_PA9 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ memory@20000000 {
+ device_type = "memory";
+ reg = <0x20000000 0x20000000>;
+ };
+};
+
+&adc {
+ vddana-supply = <&vdd_3v3>;
+ vref-supply = <&vdd_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc_default &pinctrl_adtrg_default>;
+ status = "okay";
+};
+
+&can0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can0_default>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1_default>;
+ status = "okay";
+};
+
+&flx1 {
+ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+ status = "okay";
+
+ uart6: serial@200 {
+ pinctrl-0 = <&pinctrl_flx1_default>;
+ pinctrl-names = "default";
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "okay";
+ };
+};
+
+&flx4 {
+ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_SPI>;
+ status = "okay";
+
+ spi6: spi@400 {
+ dmas = <0>, <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rpi_spi>;
+ status = "okay";
+ };
+};
+
+&i2c0 {
+ dmas = <0>, <0>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+ pinctrl-1 = <&pinctrl_i2c0_gpio>;
+ sda-gpios = <&pioA PIN_PB31 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&pioA PIN_PC0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-sda-hold-time-ns = <350>;
+ status = "okay";
+
+ mcp16502@5b {
+ compatible = "microchip,mcp16502";
+ reg = <0x5b>;
+ status = "okay";
+ lpm-gpios = <&pioBU 0 GPIO_ACTIVE_LOW>;
+
+ regulators {
+ vdd_3v3: VDD_IO {
+ regulator-name = "VDD_IO";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <2>;
+ regulator-allowed-modes = <2>, <4>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ regulator-mode = <4>;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-mode = <4>;
+ };
+ };
+
+ vddio_ddr: VDD_DDR {
+ regulator-name = "VDD_DDR";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <2>;
+ regulator-allowed-modes = <2>, <4>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1200000>;
+ regulator-changeable-in-suspend;
+ regulator-mode = <4>;
+ };
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1200000>;
+ regulator-changeable-in-suspend;
+ regulator-mode = <4>;
+ };
+ };
+
+ vdd_core: VDD_CORE {
+ regulator-name = "VDD_CORE";
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-initial-mode = <2>;
+ regulator-allowed-modes = <2>, <4>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ regulator-mode = <4>;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-mode = <4>;
+ };
+ };
+
+ vdd_ddr: VDD_OTHER {
+ regulator-name = "VDD_OTHER";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <2>;
+ regulator-allowed-modes = <2>, <4>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ regulator-changeable-in-suspend;
+ regulator-mode = <4>;
+ };
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ regulator-changeable-in-suspend;
+ regulator-mode = <4>;
+ };
+ };
+
+ LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&i2c1 {
+ dmas = <0>, <0>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1_default>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ i2c-analog-filter;
+ i2c-digital-filter;
+ i2c-digital-filter-width-ns = <35>;
+ sda-gpios = <&pioA PIN_PD4 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&pioA PIN_PD5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+&pioA {
+ pinctrl_adc_default: adc-default {
+ pinmux = <PIN_PD25__GPIO>,
+ <PIN_PD26__GPIO>;
+ bias-disable;
+ };
+
+ pinctrl_adtrg_default: adtrg-default {
+ pinmux = <PIN_PD31__ADTRG>;
+ bias-pull-up;
+ };
+
+ pinctrl_can0_default: can0-default {
+ pinmux = <PIN_PC10__CANTX0>,
+ <PIN_PC11__CANRX0>;
+ bias-disable;
+ };
+
+ pinctrl_can1_default: can1-default {
+ pinmux = <PIN_PC26__CANTX1>,
+ <PIN_PC27__CANRX1>;
+ bias-disable;
+ };
+
+ pinctrl_debug_uart: debug-uart {
+ pinmux = <PIN_PB26__URXD0>,
+ <PIN_PB27__UTXD0>;
+ bias-disable;
+ };
+
+ pinctrl_flx1_default: flx1-default {
+ pinmux = <PIN_PA24__FLEXCOM1_IO0>,
+ <PIN_PA23__FLEXCOM1_IO1>,
+ <PIN_PA25__FLEXCOM1_IO3>,
+ <PIN_PA26__FLEXCOM1_IO4>;
+ bias-disable;
+ };
+
+ pinctrl_i2c0_default: i2c0-default {
+ pinmux = <PIN_PB31__TWD0>,
+ <PIN_PC0__TWCK0>;
+ bias-disable;
+ };
+
+ pinctrl_i2c0_gpio: i2c0-gpio-default {
+ pinmux = <PIN_PB31__GPIO>,
+ <PIN_PC0__GPIO>;
+ bias-disable;
+ };
+
+ pinctrl_i2c1_default: i2c1-default {
+ pinmux = <PIN_PD4__TWD1>,
+ <PIN_PD5__TWCK1>;
+ bias-disable;
+ };
+
+ pinctrl_i2c1_gpio: i2c1-gpio-default {
+ pinmux = <PIN_PD4__GPIO>,
+ <PIN_PD5__GPIO>;
+ bias-disable;
+ };
+
+ pinctrl_key_gpio_default: key-gpio-default {
+ pinmux = <PIN_PA17__GPIO>;
+ bias-pull-up;
+ };
+
+ pinctrl_led_gpio_default: led-gpio-default {
+ pinmux = <PIN_PA7__GPIO>,
+ <PIN_PA8__GPIO>,
+ <PIN_PA9__GPIO>;
+ bias-pull-up;
+ };
+
+ pinctrl_mikrobus1_pwm: mikrobus1-pwm {
+ pinmux = <PIN_PA31__PWML0>;
+ bias-disable;
+ };
+
+ pinctrl_mikrobus2_pwm: mikrobus2-pwm {
+ pinmux = <PIN_PB0__PWMH1>;
+ bias-disable;
+ };
+
+ pinctrl_mikrobus1_uart: mikrobus1-uart {
+ pinmux = <PIN_PB3__URXD4>,
+ <PIN_PB4__UTXD4>;
+ bias-disable;
+ };
+
+ pinctrl_mikrobus2_uart: mikrobus2-uart {
+ pinmux = <PIN_PB11__URXD3>,
+ <PIN_PB12__UTXD3>;
+ bias-disable;
+ };
+
+ pinctrl_qspi1_default: qspi1-default {
+ pinmux = <PIN_PB5__QSPI1_SCK>,
+ <PIN_PB6__QSPI1_CS>,
+ <PIN_PB7__QSPI1_IO0>,
+ <PIN_PB8__QSPI1_IO1>,
+ <PIN_PB9__QSPI1_IO2>,
+ <PIN_PB10__QSPI1_IO3>;
+ bias-disable;
+ };
+
+ pinctrl_rpi_spi: rpi-spi {
+ pinmux = <PIN_PD12__FLEXCOM4_IO0>,
+ <PIN_PD13__FLEXCOM4_IO1>,
+ <PIN_PD14__FLEXCOM4_IO2>,
+ <PIN_PD15__FLEXCOM4_IO3>,
+ <PIN_PD16__FLEXCOM4_IO4>;
+ bias-disable;
+ };
+
+ pinctrl_rpi_uart: rpi-uart {
+ pinmux = <PIN_PD2__URXD1>,
+ <PIN_PD3__UTXD1>;
+ bias-disable;
+ };
+
+ pinctrl_sdmmc0_default: sdmmc0-default {
+ pinmux = <PIN_PA0__SDMMC0_CK>,
+ <PIN_PA1__SDMMC0_CMD>,
+ <PIN_PA2__SDMMC0_DAT0>,
+ <PIN_PA3__SDMMC0_DAT1>,
+ <PIN_PA4__SDMMC0_DAT2>,
+ <PIN_PA5__SDMMC0_DAT3>,
+ <PIN_PA11__SDMMC0_VDDSEL>,
+ <PIN_PA13__SDMMC0_CD>;
+ bias-disable;
+ };
+
+ pinctrl_sdmmc1_default: sdmmc1-default {
+ pinmux = <PIN_PA18__SDMMC1_DAT0>,
+ <PIN_PA19__SDMMC1_DAT1>,
+ <PIN_PA20__SDMMC1_DAT2>,
+ <PIN_PA21__SDMMC1_DAT3>,
+ <PIN_PA22__SDMMC1_CK>,
+ <PIN_PA28__SDMMC1_CMD>,
+ <PIN_PA30__SDMMC1_CD>;
+ bias-disable;
+ };
+
+ pinctrl_spi1_default: spi1-default {
+ pinmux = <PIN_PC1__SPI1_SPCK>,
+ <PIN_PC2__SPI1_MOSI>,
+ <PIN_PC3__SPI1_MISO>,
+ <PIN_PC4__SPI1_NPCS0>,
+ <PIN_PC5__SPI1_NPCS1>,
+ <PIN_PC6__SPI1_NPCS2>,
+ <PIN_PC7__SPI1_NPCS3>;
+ bias-disable;
+ };
+
+ pinctrl_usb_default: usb-default {
+ pinmux = <PIN_PA6__GPIO>;
+ bias-disable;
+ };
+
+ pinctrl_usba_vbus: usba-vbus {
+ pinmux = <PIN_PB13__GPIO>;
+ bias-disable;
+ };
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mikrobus1_pwm &pinctrl_mikrobus2_pwm>;
+ status = "okay";
+};
+
+&qspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi1_default>;
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <80000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ m25p,fast-read;
+ label = "atmel_qspi1";
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader@40000 {
+ label = "bootloader";
+ reg = <0x40000 0xc0000>;
+ };
+
+ bootloaderenvred@100000 {
+ label = "bootloader env redundant";
+ reg = <0x100000 0x40000>;
+ };
+
+ bootloaderenv@140000 {
+ label = "bootloader env";
+ reg = <0x140000 0x40000>;
+ };
+
+ dtb@180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel@200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+ };
+};
+
+&sdmmc0 {
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdmmc0_default>;
+ disable-wp;
+ status = "okay";
+};
+
+&sdmmc1 {
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdmmc1_default>;
+ disable-wp;
+ status = "okay";
+};
+
+&shutdown_controller {
+ debounce-delay-us = <976>;
+ atmel,wakeup-rtc-timer;
+
+ input@0 {
+ reg = <0>;
+ };
+};
+
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1_default>;
+ status = "okay";
+};
+
+&tcb0 {
+ timer0: timer@0 {
+ compatible = "atmel,tcb-timer";
+ reg = <0>;
+ };
+
+ timer1: timer@1 {
+ compatible = "atmel,tcb-timer";
+ reg = <1>;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_debug_uart>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rpi_uart>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mikrobus2_uart>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mikrobus1_uart>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "okay";
+};
+
+&usb0 {
+ atmel,vbus-gpio = <&pioA PIN_PB13 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ status = "okay";
+};
+
+&usb1 {
+ num-ports = <3>;
+ atmel,vbus-gpio = <0
+ &pioA PIN_PA6 GPIO_ACTIVE_HIGH
+ 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_default>;
+ status = "okay";
+};
+
+&usb2 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/microchip/sama5d4.dtsi b/arch/arm/boot/dts/microchip/sama5d4.dtsi
index 50650e2f4267..58ceed997889 100644
--- a/arch/arm/boot/dts/microchip/sama5d4.dtsi
+++ b/arch/arm/boot/dts/microchip/sama5d4.dtsi
@@ -694,7 +694,7 @@
clock-names = "aes_clk";
};
- tdes: crpyto@fc04c000 {
+ tdes: crypto@fc04c000 {
compatible = "atmel,at91sam9g46-tdes";
reg = <0xfc04c000 0x100>;
interrupts = <14 IRQ_TYPE_LEVEL_HIGH 0>;
diff --git a/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-gsj.dts b/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-gsj.dts
index 9b1cc7f4adf0..cd7843339c24 100644
--- a/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-gsj.dts
+++ b/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-gsj.dts
@@ -146,7 +146,7 @@
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
- bmc@0{
+ bmc@0 {
label = "bmc";
reg = <0x000000 0x2000000>;
};
@@ -155,7 +155,7 @@
reg = <0x0000000 0x80000>;
read-only;
};
- u-boot-env@100000{
+ u-boot-env@100000 {
label = "u-boot-env";
reg = <0x00100000 0x40000>;
};
diff --git a/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts b/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts
index 58329adbd918..5787ae95d3b4 100644
--- a/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts
+++ b/arch/arm/boot/dts/nuvoton/nuvoton-npcm730-kudo.dts
@@ -397,7 +397,7 @@
reg = <0x0000000 0xC0000>;
read-only;
};
- u-boot-env@100000{
+ u-boot-env@100000 {
label = "u-boot-env";
reg = <0x00100000 0x40000>;
};
diff --git a/arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts b/arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts
index 209fa3400317..baa39d0c1032 100644
--- a/arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts
+++ b/arch/arm/boot/dts/nuvoton/nuvoton-npcm750-runbmc-olympus.dts
@@ -111,7 +111,7 @@
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
- bmc@0{
+ bmc@0 {
label = "bmc";
reg = <0x000000 0x2000000>;
};
@@ -120,7 +120,7 @@
reg = <0x0000000 0x80000>;
read-only;
};
- u-boot-env@100000{
+ u-boot-env@100000 {
label = "u-boot-env";
reg = <0x00100000 0x40000>;
};
diff --git a/arch/arm/boot/dts/nvidia/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/nvidia/tegra20-acer-a500-picasso.dts
index 486fd244291e..a619ea83ed3b 100644
--- a/arch/arm/boot/dts/nvidia/tegra20-acer-a500-picasso.dts
+++ b/arch/arm/boot/dts/nvidia/tegra20-acer-a500-picasso.dts
@@ -65,7 +65,7 @@
rgb {
status = "okay";
- port@0 {
+ port {
lcd_output: endpoint {
remote-endpoint = <&lvds_encoder_input>;
bus-width = <18>;
diff --git a/arch/arm/boot/dts/nvidia/tegra20-asus-tf101.dts b/arch/arm/boot/dts/nvidia/tegra20-asus-tf101.dts
index a3757b7daeda..e118809dc6d9 100644
--- a/arch/arm/boot/dts/nvidia/tegra20-asus-tf101.dts
+++ b/arch/arm/boot/dts/nvidia/tegra20-asus-tf101.dts
@@ -66,7 +66,7 @@
rgb {
status = "okay";
- port@0 {
+ port {
lcd_output: endpoint {
remote-endpoint = <&lvds_encoder_input>;
bus-width = <18>;
diff --git a/arch/arm/boot/dts/nvidia/tegra30-asus-lvds-display.dtsi b/arch/arm/boot/dts/nvidia/tegra30-asus-lvds-display.dtsi
index bae09d82594d..680edff0f26f 100644
--- a/arch/arm/boot/dts/nvidia/tegra30-asus-lvds-display.dtsi
+++ b/arch/arm/boot/dts/nvidia/tegra30-asus-lvds-display.dtsi
@@ -10,7 +10,7 @@
rgb {
status = "okay";
- port@0 {
+ port {
dpi_output: endpoint {
remote-endpoint = <&bridge_input>;
bus-width = <24>;
diff --git a/arch/arm/boot/dts/nvidia/tegra30-asus-tf700t.dts b/arch/arm/boot/dts/nvidia/tegra30-asus-tf700t.dts
index efde7dad718a..9c480fde2e76 100644
--- a/arch/arm/boot/dts/nvidia/tegra30-asus-tf700t.dts
+++ b/arch/arm/boot/dts/nvidia/tegra30-asus-tf700t.dts
@@ -15,7 +15,7 @@
rgb {
status = "okay";
- port@0 {
+ port {
dpi_output: endpoint {
remote-endpoint = <&bridge_input>;
bus-width = <24>;
diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
index 3629e343d322..a724d1a7a9a0 100644
--- a/arch/arm/boot/dts/nxp/imx/Makefile
+++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -47,6 +47,8 @@ dtb-$(CONFIG_SOC_IMX53) += \
imx53-qsb.dtb \
imx53-qsrb.dtb \
imx53-sk-imx53.dtb \
+ imx53-sk-imx53-atm0700d4-lvds.dtb \
+ imx53-sk-imx53-atm0700d4-rgb.dtb \
imx53-smd.dtb \
imx53-tx53-x03x.dtb \
imx53-tx53-x13x.dtb \
@@ -244,6 +246,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6q-udoo.dtb \
imx6q-utilite-pro.dtb \
imx6q-var-dt6customboard.dtb \
+ imx6q-var-mx6customboard.dtb \
imx6q-vicut1.dtb \
imx6q-wandboard.dtb \
imx6q-wandboard-revb1.dtb \
diff --git a/arch/arm/boot/dts/nxp/imx/imx25.dtsi b/arch/arm/boot/dts/nxp/imx/imx25.dtsi
index 5f90d72b840b..534c70b8d79d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx25.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx25.dtsi
@@ -529,7 +529,6 @@
compatible = "fsl,imx25-wdt", "fsl,imx21-wdt";
reg = <0x53fdc000 0x4000>;
clocks = <&clks 126>;
- clock-names = "";
interrupts = <55>;
};
@@ -583,10 +582,9 @@
};
dryice@53ffc000 {
- compatible = "fsl,imx25-dryice", "fsl,imx25-rtc";
+ compatible = "fsl,imx25-rtc";
reg = <0x53ffc000 0x4000>;
clocks = <&clks 81>;
- clock-names = "ipg";
interrupts = <25 56>;
};
};
@@ -594,6 +592,9 @@
iram: sram@78000000 {
compatible = "mmio-sram";
reg = <0x78000000 0x20000>;
+ ranges = <0 0x78000000 0x20000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
};
emi@80000000 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
index 303f920201c5..abc9233c5a1b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
@@ -34,7 +34,7 @@
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
- at24@52 {
+ eeprom@52 {
compatible = "atmel,24c32";
pagesize = <32>;
reg = <0x52>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi
index 7191e10712b9..7b2ea4cdae58 100644
--- a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi
@@ -180,7 +180,7 @@
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
- at24@52 {
+ eeprom@52 {
compatible = "atmel,24c32";
pagesize = <32>;
reg = <0x52>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
index 5d4b29d76585..7cd17b43b4b2 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
@@ -119,8 +119,8 @@
compatible = "i2c-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_swi2c>;
- gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>, /* sda */
- <&gpio3 4 GPIO_ACTIVE_HIGH>; /* scl */
+ sda-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>;
i2c-gpio,delay-us = <50>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx51.dtsi b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
index 2b3195f5e32c..c96d6311dfa7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
@@ -651,7 +651,7 @@
};
sahara: crypto@83ff8000 {
- compatible = "fsl,imx53-sahara", "fsl,imx51-sahara";
+ compatible = "fsl,imx53-sahara";
reg = <0x83ff8000 0x4000>;
interrupts = <19 20>;
clocks = <&clks IMX5_CLK_SAHARA_IPG_GATE>,
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4-lvds.dts b/arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4-lvds.dts
new file mode 100644
index 000000000000..b1c1e7c759b3
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4-lvds.dts
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2023 Linaro Ltd.
+
+/dts-v1/;
+
+#include <dt-bindings/pwm/pwm.h>
+#include "imx53-sk-imx53-atm0700d4.dtsi"
+
+/ {
+ lvds-decoder {
+ compatible = "ti,sn65lvds94", "lvds-decoder";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ lvds_decoder_in: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lvds_decoder_out: endpoint {
+ remote-endpoint = <&panel_rgb_in>;
+ };
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl_lvds0: lvds0grp {
+ /* LVDS pins only have pin mux configuration */
+ fsl,pins = <
+ MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 0x80000000
+ MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 0x80000000
+ MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 0x80000000
+ MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 0x80000000
+ MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 0x80000000
+ >;
+ };
+
+ pinctrl_spi_gpio: spigrp {
+ fsl,pins = <
+ MX53_PAD_EIM_A22__GPIO2_16 0x1f4
+ MX53_PAD_EIM_A21__GPIO2_17 0x1f4
+ MX53_PAD_EIM_A16__GPIO2_22 0x1f4
+ MX53_PAD_EIM_A18__GPIO2_20 0x1f4
+ >;
+ };
+};
+
+&ldb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds0>;
+ status = "okay";
+
+ lvds0: lvds-channel@0 {
+ reg = <0>;
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@2 {
+ reg = <2>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&lvds_decoder_in>;
+ };
+ };
+ };
+};
+
+&panel_rgb_in {
+ remote-endpoint = <&lvds_decoder_out>;
+};
+
+&spi_ts {
+ pinctrl-0 = <&pinctrl_spi_gpio>;
+ pinctrl-names = "default";
+
+ sck-gpios = <&gpio2 16 GPIO_ACTIVE_HIGH>;
+ miso-gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>;
+ mosi-gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>;
+ cs-gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+};
+
+&touchscreen {
+ interrupts-extended = <&gpio3 22 IRQ_TYPE_EDGE_BOTH>;
+ pendown-gpio = <&gpio3 22 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4-rgb.dts b/arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4-rgb.dts
new file mode 100644
index 000000000000..2559ada7e401
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4-rgb.dts
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2023 Linaro Ltd.
+
+/dts-v1/;
+
+#include <dt-bindings/pwm/pwm.h>
+#include "imx53-sk-imx53-atm0700d4.dtsi"
+
+/ {
+ display: disp0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-0 = <&pinctrl_rgb24>;
+ pinctrl-names = "default";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ display0_in: endpoint {
+ remote-endpoint = <&ipu_di0_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ display_out: endpoint {
+ remote-endpoint = <&panel_rgb_in>;
+ };
+ };
+ };
+
+};
+
+&iomuxc {
+ pinctrl_rgb24: rgb24grp {
+ fsl,pins = <
+ MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 0x5
+ MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 0x5
+ MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 0x5
+ MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 0x5
+ MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 0x5
+ MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 0x5
+ MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 0x5
+ MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 0x5
+ MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 0x5
+ MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 0x5
+ MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 0x5
+ MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 0x5
+ MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 0x5
+ MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 0x5
+ MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 0x5
+ MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 0x5
+ MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 0x5
+ MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 0x5
+ MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 0x5
+ MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 0x5
+ MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 0x5
+ MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 0x5
+ MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 0x5
+ MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 0x5
+ MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 0x5
+ MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 0x5
+ MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 0x5
+ MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 0x5
+ >;
+ };
+
+ pinctrl_spi_gpio: spigrp {
+ fsl,pins = <
+ MX53_PAD_SD1_DATA1__GPIO1_17 0x1f4
+ MX53_PAD_GPIO_7__GPIO1_7 0x1f4
+ MX53_PAD_PATA_DATA3__GPIO2_3 0x1f4
+ MX53_PAD_PATA_DATA8__GPIO2_8 0x1f4
+ >;
+ };
+};
+
+&ipu_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&panel {
+ enable-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+};
+
+&panel_rgb_in {
+ remote-endpoint = <&display_out>;
+};
+
+&pwm1 {
+ status = "disabled";
+};
+
+&spi_ts {
+ pinctrl-0 = <&pinctrl_spi_gpio>;
+ pinctrl-names = "default";
+
+ sck-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ mosi-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+ miso-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+ cs-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
+};
+
+&touchscreen {
+ interrupts-extended = <&gpio2 6 IRQ_TYPE_EDGE_BOTH>;
+ pendown-gpio = <&gpio2 6 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4.dtsi b/arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4.dtsi
new file mode 100644
index 000000000000..e395004e80e6
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx53-sk-imx53-atm0700d4.dtsi
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2023 Linaro Ltd.
+
+/dts-v1/;
+
+#include <dt-bindings/pwm/pwm.h>
+#include "imx53-sk-imx53.dts"
+
+/ {
+ panel: panel-rgb {
+ compatible = "powertip,ph800480t013-idf02";
+
+ port {
+ panel_rgb_in: endpoint {
+ };
+ };
+ };
+
+ spi_ts: spi {
+ compatible = "spi-gpio";
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+
+ num-chipselects = <1>;
+
+ touchscreen: touchscreen@0 {
+ reg = <0>;
+ compatible = "ti,ads7843";
+ spi-max-frequency = <300000>;
+
+ ti,vref-mv = /bits/ 16 <3300>;
+ ti,x-plate-ohms = /bits/ 16 <450>;
+ ti,y-plate-ohms = /bits/ 16 <250>;
+ ti,debounce-tol = /bits/ 16 <10>;
+ ti,debounce-rep = /bits/ 16 <0>;
+ touchscreen-size-x = <4096>;
+ touchscreen-size-y = <4096>;
+ touchscreen-swapped-x-y;
+ touchscreen-max-pressure = <100>;
+
+ wakeup-source;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx53.dtsi b/arch/arm/boot/dts/nxp/imx/imx53.dtsi
index 0ebc35e6e985..07658e477095 100644
--- a/arch/arm/boot/dts/nxp/imx/imx53.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx53.dtsi
@@ -275,7 +275,7 @@
ecspi1: spi@50010000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+ compatible = "fsl,imx53-ecspi";
reg = <0x50010000 0x4000>;
interrupts = <36>;
clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
@@ -701,7 +701,7 @@
ecspi2: spi@63fac000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+ compatible = "fsl,imx53-ecspi";
reg = <0x63fac000 0x4000>;
interrupts = <37>;
clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-b650v3.dts b/arch/arm/boot/dts/nxp/imx/imx6q-b650v3.dts
index fa1a1df37cde..b0d345f5d071 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-b650v3.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-b650v3.dts
@@ -98,8 +98,8 @@
};
&usbphy1 {
- fsl,tx-cal-45-dn-ohms = <55>;
- fsl,tx-cal-45-dp-ohms = <55>;
+ fsl,tx-cal-45-dn-ohms = <54>;
+ fsl,tx-cal-45-dp-ohms = <54>;
fsl,tx-d-cal = <100>;
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts b/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts
index fb9f320103c6..46c6b96d8073 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts
@@ -637,11 +637,11 @@
};
&usbphy1 {
- fsl,tx-d-cal = <0x5>;
+ fsl,tx-d-cal = <79>;
};
&usbphy2 {
- fsl,tx-d-cal = <0x5>;
+ fsl,tx-d-cal = <79>;
};
&usdhc1 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-var-mx6customboard.dts b/arch/arm/boot/dts/nxp/imx/imx6q-var-mx6customboard.dts
new file mode 100644
index 000000000000..6f9d094dd6d0
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-var-mx6customboard.dts
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Support for Variscite MX6 Carrier-board
+ *
+ * Copyright 2016 Variscite, Ltd. All Rights Reserved
+ * Copyright 2022 Bootlin
+ */
+
+/dts-v1/;
+
+#include "imx6qdl-var-som.dtsi"
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "Variscite i.MX6 QUAD/DUAL VAR-SOM-MX6 Custom Board";
+ compatible = "variscite,mx6customboard", "variscite,var-som-imx6q", "fsl,imx6q";
+
+ panel0: lvds-panel0 {
+ compatible = "panel-lvds";
+ backlight = <&backlight_lvds>;
+ width-mm = <152>;
+ height-mm = <91>;
+ label = "etm070001adh6";
+ data-mapping = "jeida-18";
+
+ panel-timing {
+ clock-frequency = <32000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <39>;
+ hfront-porch = <39>;
+ vback-porch = <29>;
+ vfront-porch = <13>;
+ hsync-len = <47>;
+ vsync-len = <2>;
+ };
+
+ port {
+ panel_in_lvds0: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+
+ panel1: lvds-panel1 {
+ compatible = "panel-lvds";
+ width-mm = <152>;
+ height-mm = <91>;
+ data-mapping = "jeida-18";
+
+ panel-timing {
+ clock-frequency = <38251000>;
+ hactive = <800>;
+ vactive = <600>;
+ hback-porch = <112>;
+ hfront-porch = <32>;
+ vback-porch = <3>;
+ vfront-porch = <17>;
+ hsync-len = <80>;
+ vsync-len = <4>;
+ };
+
+ port {
+ panel_in_lvds1: endpoint {
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+
+ backlight_lvds: backlight-lvds {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 50000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 248>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_3p3v>;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ touchscreen@24 {
+ compatible = "cypress,tt21000";
+ reg = <0x24>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&reg_3p3v>;
+ touchscreen-size-x = <880>;
+ touchscreen-size-y = <1280>;
+ };
+
+ touchscreen@38 {
+ compatible = "edt,edt-ft5306";
+ reg = <0x38>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+ touchscreen-size-x = <1800>;
+ touchscreen-size-y = <1000>;
+ };
+};
+
+&iomuxc {
+ pinctrl_camera: cameragrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x1b0b0
+ MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x1b0b0
+ MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x1b0b0
+ MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x1b0b0
+ MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
+ MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
+ >;
+ };
+
+ pinctrl_ipu1: ipu1grp {
+ fsl,pins = <
+ MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+ MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
+ MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
+ MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
+ MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x10
+ MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
+ MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
+ MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
+ MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
+ MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
+ MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
+ MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
+ MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
+ MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
+ MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
+ MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
+ MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
+ MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
+ MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
+ MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
+ MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
+ MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
+ MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
+ MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
+ MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
+ MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
+ MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
+ MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
+ MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg_var: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17071
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ >;
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@4 {
+ reg = <4>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&panel_in_lvds0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@4 {
+ reg = <4>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&panel_in_lvds1>;
+ };
+ };
+ };
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ cd-gpios = <&gpio4 14 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi
index 9594bc5745ed..1e723807ab4c 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi
@@ -52,6 +52,11 @@
/ {
/* these are used by bootloader for disabling nodes */
aliases {
+ ethernet0 = &fec;
+ ethernet1 = &lan1;
+ ethernet2 = &lan2;
+ ethernet3 = &lan3;
+ ethernet4 = &lan4;
led0 = &led0;
led1 = &led1;
led2 = &led2;
@@ -212,28 +217,61 @@
compatible = "marvell,mv88e6085";
reg = <0>;
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sw_phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ sw_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+
+ sw_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+
+ sw_phy3: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+ };
+
ports {
#address-cells = <1>;
#size-cells = <0>;
- port@0 {
+ lan4: port@0 {
reg = <0>;
label = "lan4";
+ phy-handle = <&sw_phy0>;
+ phy-mode = "internal";
+ local-mac-address = [00 00 00 00 00 00];
};
- port@1 {
+ lan3: port@1 {
reg = <1>;
label = "lan3";
+ phy-handle = <&sw_phy1>;
+ phy-mode = "internal";
+ local-mac-address = [00 00 00 00 00 00];
};
- port@2 {
+ lan2: port@2 {
reg = <2>;
label = "lan2";
+ phy-handle = <&sw_phy2>;
+ phy-mode = "internal";
+ local-mac-address = [00 00 00 00 00 00];
};
- port@3 {
+ lan1: port@3 {
reg = <3>;
label = "lan1";
+ phy-handle = <&sw_phy3>;
+ phy-mode = "internal";
+ local-mac-address = [00 00 00 00 00 00];
};
port@5 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5910.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5910.dtsi
index 218d6e667ed2..424dc7fcd533 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5910.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5910.dtsi
@@ -326,7 +326,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio7>;
interrupts = <13 0>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5912.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5912.dtsi
index de5983cf7810..49ea25c71967 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5912.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5912.dtsi
@@ -307,7 +307,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio7>;
interrupts = <13 0>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi
index 763831dc0e24..32a110a35b02 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi
@@ -15,7 +15,7 @@
reg = <0x10000000 0xF0000000>;
};
- reg_1p8v: regulator@0 {
+ reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "1P8V";
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi
new file mode 100644
index 000000000000..a1ea33c4eeb7
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi
@@ -0,0 +1,569 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Support for Variscite VAR-SOM-MX6 Module
+ *
+ * Copyright 2011 Linaro Ltd.
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2016 Variscite, Ltd.
+ * Author: Donio Ron <ron.d@variscite.com>
+ * Copyright 2022 Bootlin
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include <dt-bindings/clock/imx6qdl-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/sound/fsl-imx-audmux.h>
+
+/ {
+ model = "Variscite VAR-SOM-MX6 module";
+ compatible = "variscite,var-som-imx6q", "fsl,imx6q";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory@10000000 {
+ device_type = "memory";
+ reg = <0x10000000 0x40000000>;
+ };
+
+ reg_usb_otg_vbus: regulator-usb-otg-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usb_h1_vbus: regulator-usb-h1-vbud {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_wl18xx_vmmc: regulator-wl18xx {
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1807";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio7 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ startup-delay-us = <70000>;
+ };
+
+ sound: sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "var-som-audio";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&sound_codec>;
+ simple-audio-card,frame-master = <&sound_codec>;
+ simple-audio-card,widgets = "Headphone", "Headphone Jack",
+ "Line", "Line In", "Microphone", "Mic Jack";
+ simple-audio-card,routing = "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "LINE1L", "Line In",
+ "LINE1R", "Line In";
+
+ sound_cpu: simple-audio-card,cpu {
+ sound-dai = <&ssi2>;
+ };
+
+ sound_codec: simple-audio-card,codec {
+ sound-dai = <&tlv320aic3106>;
+ clocks = <&clks IMX6QDL_CLK_CKO>;
+ };
+ };
+
+ rfkill {
+ compatible = "rfkill-gpio";
+ name = "rfkill";
+ radio-type = "bluetooth";
+ shutdown-gpios = <&gpio6 18 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+
+ mux-ssi2 {
+ fsl,audmux-port = <1>;
+ fsl,port-config = <
+ (IMX_AUDMUX_V2_PTCR_SYN |
+ IMX_AUDMUX_V2_PTCR_TFSDIR |
+ IMX_AUDMUX_V2_PTCR_TFSEL(2) |
+ IMX_AUDMUX_V2_PTCR_TCLKDIR |
+ IMX_AUDMUX_V2_PTCR_TCSEL(2))
+ IMX_AUDMUX_V2_PDCR_RXDSEL(2)
+ >;
+ };
+
+ mux-aud3 {
+ fsl,audmux-port = <2>;
+ fsl,port-config = <
+ IMX_AUDMUX_V2_PTCR_SYN
+ IMX_AUDMUX_V2_PDCR_RXDSEL(1)
+ >;
+ };
+};
+
+&ecspi3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-handle = <&rgmii_phy>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rgmii_phy: ethernet-phy@7 {
+ reg = <7>;
+ reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ };
+ };
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic@8 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+
+ tlv320aic3106: audio-codec@1b {
+ compatible = "ti,tlv320aic3106";
+ reg = <0x1b>;
+ #sound-dai-cells = <0>;
+ DRVDD-supply = <&reg_3p3v>;
+ AVDD-supply = <&reg_3p3v>;
+ IOVDD-supply = <&reg_3p3v>;
+ DVDD-supply = <&reg_1p8v>;
+ ai3x-ocmv = <0>;
+ reset-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
+ ai3x-gpio-func = <
+ 0 /* AIC3X_GPIO1_FUNC_DISABLED */
+ 5 /* AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT */
+ >;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
+ MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
+ MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
+ MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
+ /* Audio Clock */
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
+ >;
+ };
+
+ pinctrl_bt: btgrp {
+ fsl,pins = <
+ /* Bluetooth/wifi enable */
+ MX6QDL_PAD_SD3_DAT6__GPIO6_IO18 0x1b0b1
+ /* Wifi Slow Clock */
+ MX6QDL_PAD_ENET_RXD0__OSC32K_32K_OUT 0x000b0
+ >;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
+ MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
+ MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ >;
+ };
+
+ pinctrl_enet_irq: enetirqgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ >;
+ };
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /* CTW6120 IRQ */
+ MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0xb0b1
+ /* SDMMC2 CD/WP */
+ MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x1b0b0
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+ MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ /* PMIC INT */
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
+ >;
+ };
+
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT9__PWM2_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT4__UART2_RX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT5__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D28__UART2_CTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_D29__UART2_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17069
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10069
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17069
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17069
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17069
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17069
+ /* WL_EN */
+ MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x13059
+ /* WL_IRQ */
+ MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x13059
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhzgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170B9
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100B9
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170B9
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170B9
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170B9
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170B9
+ /* WL_EN */
+ MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x130B9
+ /* WL_IRQ */
+ MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x130B9
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhzgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170F9
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100F9
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170F9
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170F9
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170F9
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170F9
+ /* WL_EN */
+ MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x130F9
+ /* WL_IRQ */
+ MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x130F9
+ >;
+ };
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>;
+ status = "okay";
+};
+
+&reg_arm {
+ vin-supply = <&sw1a_reg>;
+};
+
+&reg_pu {
+ vin-supply = <&sw1c_reg>;
+};
+
+&reg_soc {
+ vin-supply = <&sw1c_reg>;
+};
+
+&reg_vdd1p1 {
+ vin-supply = <&vgen5_reg>;
+};
+
+&reg_vdd2p5 {
+ vin-supply = <&vgen5_reg>;
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2 &pinctrl_bt>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg_var>;
+ disable-over-current;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy1 {
+ fsl,tx-d-cal = <0x5>;
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <0x5>;
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ non-removable;
+ keep-power-in-suspend;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_wl18xx_vmmc>;
+ non-removable;
+ wakeup-source;
+ keep-power-in-suspend;
+ cap-power-off-card;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ wifi: wifi@2 {
+ compatible = "ti,wl1835";
+ reg = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <17 IRQ_TYPE_EDGE_RISING>;
+ ref-clock-frequency = <38400000>;
+ };
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi
index 6bd90473050b..1db146ac1c17 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi
@@ -114,10 +114,8 @@
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c_gpio>;
- gpios = <
- &gpio5 1 GPIO_ACTIVE_HIGH /* SDA */
- &gpio5 0 GPIO_ACTIVE_HIGH /* SCL */
- >;
+ sda-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&gpio5 0 GPIO_ACTIVE_HIGH>;
clock-frequency = <400000>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-aster.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-aster.dts
index 919c0464d6cb..b2cdf4877718 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-aster.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-aster.dts
@@ -12,6 +12,5 @@
model = "Toradex Colibri iMX6ULL 1GB (eMMC) on Colibri Aster";
compatible = "toradex,colibri-imx6ull-emmc-aster",
"toradex,colibri-imx6ull-emmc",
- "toradex,colibri-imx6ull",
"fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-eval-v3.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-eval-v3.dts
index 61b93cb040c7..2dc16c54fc78 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-eval-v3.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-eval-v3.dts
@@ -12,6 +12,5 @@
model = "Toradex Colibri iMX6ULL 1GB (eMMC) on Colibri Evaluation Board V3";
compatible = "toradex,colibri-imx6ull-emmc-eval",
"toradex,colibri-imx6ull-emmc",
- "toradex,colibri-imx6ull",
"fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris-v2.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris-v2.dts
index b9060c2f7977..9bae08fb7f85 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris-v2.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris-v2.dts
@@ -10,8 +10,7 @@
/ {
model = "Toradex Colibri iMX6ULL 1G (eMMC) on Colibri Iris V2";
- compatible = "toradex,colibri-imx6ull-iris-v2",
+ compatible = "toradex,colibri-imx6ull-emmc-iris-v2",
"toradex,colibri-imx6ull-emmc",
- "toradex,colibri-imx6ull",
"fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris.dts
index 0ab71f2f5daa..0b1603ff9420 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-emmc-iris.dts
@@ -12,6 +12,5 @@
model = "Toradex Colibri iMX6ULL 1GB (eMMC) on Colibri Iris";
compatible = "toradex,colibri-imx6ull-emmc-iris",
"toradex,colibri-imx6ull-emmc",
- "toradex,colibri-imx6ull",
"fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-eval-v3.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-eval-v3.dts
index d6da984e518d..c5bc255b21e1 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-eval-v3.dts
@@ -10,7 +10,7 @@
/ {
model = "Toradex Colibri iMX6ULL 256/512MB on Colibri Evaluation Board V3";
- compatible = "toradex,colibri-imx6ull-eval", "fsl,imx6ull";
+ compatible = "toradex,colibri-imx6ull-eval", "toradex,colibri-imx6ull", "fsl,imx6ull";
};
&ad7879_ts {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-aster.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-aster.dts
index c7da5b41966f..d3bbd05da293 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-aster.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-aster.dts
@@ -11,7 +11,7 @@
/ {
model = "Toradex Colibri iMX6ULL 512MB on Colibri Aster";
compatible = "toradex,colibri-imx6ull-wifi-aster",
- "toradex,colibri-imx6ull",
+ "toradex,colibri-imx6ull-wifi",
"fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-eval-v3.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-eval-v3.dts
index 917f5dbe64ba..0ac306c9cef2 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-eval-v3.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-eval-v3.dts
@@ -10,7 +10,7 @@
/ {
model = "Toradex Colibri iMX6ULL 512MB on Colibri Evaluation Board V3";
- compatible = "toradex,colibri-imx6ull-wifi-eval", "fsl,imx6ull";
+ compatible = "toradex,colibri-imx6ull-wifi-eval", "toradex,colibri-imx6ull-wifi", "fsl,imx6ull";
};
&ad7879_ts {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris-v2.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris-v2.dts
index 488da6df56fa..38cd52c45496 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris-v2.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris-v2.dts
@@ -11,7 +11,7 @@
/ {
model = "Toradex Colibri iMX6ULL 512MB on Colibri Iris V2";
compatible = "toradex,colibri-imx6ull-wifi-iris-v2",
- "toradex,colibri-imx6ull",
+ "toradex,colibri-imx6ull-wifi",
"fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris.dts
index e63253254754..5f60df64f173 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri-wifi-iris.dts
@@ -11,7 +11,7 @@
/ {
model = "Toradex Colibri iMX6ULL 512MB on Colibri Iris";
compatible = "toradex,colibri-imx6ull-wifi-iris",
- "toradex,colibri-imx6ull",
+ "toradex,colibri-imx6ull-wifi",
"fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-emmc.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-emmc.dts
index 14adb87da911..1610f3892d9e 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-emmc.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-emmc.dts
@@ -9,8 +9,8 @@
/ {
model = "PHYTEC phyGate-Tauri i.MX6 UltraLite";
- compatible = "phytec,imx6ull-phygate-tauri",
- "phytec,imx6ull-phygate-tauri-emmc",
+ compatible = "phytec,imx6ull-phygate-tauri-emmc",
+ "phytec,imx6ull-phygate-tauri",
"phytec,imx6ull-pcl063", "fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-nand.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-nand.dts
index ae396ac63443..92e7d38d5637 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-nand.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri-nand.dts
@@ -9,8 +9,8 @@
/ {
model = "PHYTEC phyGate-Tauri i.MX6 UltraLite";
- compatible = "phytec,imx6ull-phygate-tauri",
- "phytec,imx6ull-phygate-tauri-nand",
+ compatible = "phytec,imx6ull-phygate-tauri-nand",
+ "phytec,imx6ull-phygate-tauri",
"phytec,imx6ull-pcl063", "fsl,imx6ull";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi
index ea627638e40c..44cc4ff1d0df 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi
@@ -9,11 +9,6 @@
#include "imx6ull-phytec-phycore-som.dtsi"
/ {
-
- model = "PHYTEC phyGate-Tauri i.MX6 UltraLite";
- compatible = "phytec,imx6ull-phygate-tauri",
- "phytec,imx6ull-pcl063", "fsl,imx6ull";
-
aliases {
rtc0 = &i2c_rtc;
rtc1 = &snvs_rtc;
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-aster.dts b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-aster.dts
index d9c7045a55ba..212e0685585d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-aster.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-aster.dts
@@ -12,7 +12,6 @@
model = "Toradex Colibri iMX7D 1GB (eMMC) on Aster Carrier Board";
compatible = "toradex,colibri-imx7d-emmc-aster",
"toradex,colibri-imx7d-emmc",
- "toradex,colibri-imx7d",
"fsl,imx7d";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-eval-v3.dts b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-eval-v3.dts
index 96b599439dde..1deece7e7129 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-eval-v3.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-eval-v3.dts
@@ -11,7 +11,6 @@
model = "Toradex Colibri iMX7D 1GB (eMMC) on Colibri Evaluation Board V3";
compatible = "toradex,colibri-imx7d-emmc-eval-v3",
"toradex,colibri-imx7d-emmc",
- "toradex,colibri-imx7d",
"fsl,imx7d";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris-v2.dts b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris-v2.dts
index 5eccb837b158..22e7863c2e80 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris-v2.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris-v2.dts
@@ -11,7 +11,6 @@
model = "Toradex Colibri iMX7D 1GB on Iris V2 Carrier Board";
compatible = "toradex,colibri-imx7d-emmc-iris-v2",
"toradex,colibri-imx7d-emmc",
- "toradex,colibri-imx7d",
"fsl,imx7d";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris.dts b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris.dts
index ae10e8a66ff1..a3cf8f50e3dc 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-iris.dts
@@ -11,7 +11,6 @@
model = "Toradex Colibri iMX7D 1GB on Iris Carrier Board";
compatible = "toradex,colibri-imx7d-emmc-iris",
"toradex,colibri-imx7d-emmc",
- "toradex,colibri-imx7d",
"fsl,imx7d";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-pico-pi.dts b/arch/arm/boot/dts/nxp/imx/imx7d-pico-pi.dts
index f263e391e24c..62221131336f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-pico-pi.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-pico-pi.dts
@@ -61,6 +61,10 @@
};
};
+&usdhc1 {
+ status = "disabled";
+};
+
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
index e152d08f27d4..29b8fd03567a 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
@@ -658,7 +658,6 @@
interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <3>;
interrupt-parent = <&intc>;
- #power-domain-cells = <1>;
pgc {
#address-cells = <1>;
@@ -800,10 +799,8 @@
compatible = "fsl,imx7-csi";
reg = <0x30710000 0x10000>;
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_CLK_DUMMY>,
- <&clks IMX7D_CSI_MCLK_ROOT_CLK>,
- <&clks IMX7D_CLK_DUMMY>;
- clock-names = "axi", "mclk", "dcic";
+ clocks = <&clks IMX7D_CSI_MCLK_ROOT_CLK>;
+ clock-names = "mclk";
status = "disabled";
port {
diff --git a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
index b01ddda7bd9e..ac338320ac1d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7ulp.dtsi
@@ -209,7 +209,7 @@
};
usbphy1: usb-phy@40350000 {
- compatible = "fsl,imx7ulp-usbphy", "fsl,imx6ul-usbphy";
+ compatible = "fsl,imx7ulp-usbphy";
reg = <0x40350000 0x1000>;
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&pcc2 IMX7ULP_CLK_USB_PHY>;
diff --git a/arch/arm/boot/dts/nxp/imx/mba6ulx.dtsi b/arch/arm/boot/dts/nxp/imx/mba6ulx.dtsi
index ebf97fcdd8ea..5a8b867d7d79 100644
--- a/arch/arm/boot/dts/nxp/imx/mba6ulx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/mba6ulx.dtsi
@@ -35,22 +35,25 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_buttons>;
- button1 {
+ button-1 {
label = "s14";
linux,code = <KEY_1>;
gpios = <&expander_in0 0 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
- button2 {
+ button-2 {
label = "s6";
linux,code = <KEY_2>;
gpios = <&expander_in0 1 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
- button3 {
+ button-3 {
label = "s7";
linux,code = <KEY_3>;
gpios = <&expander_in0 2 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
power-button {
diff --git a/arch/arm/boot/dts/nxp/mxs/imx23-evk.dts b/arch/arm/boot/dts/nxp/mxs/imx23-evk.dts
index 3b609d987d88..7365fe4581a3 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx23-evk.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx23-evk.dts
@@ -137,7 +137,7 @@
backlight_display: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 2 5000000>;
+ pwms = <&pwm 2 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts b/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts
index 46057d9bf555..636cf09a2b37 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts
@@ -166,7 +166,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 2 5000000>;
+ pwms = <&pwm 2 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx23-xfi3.dts b/arch/arm/boot/dts/nxp/mxs/imx23-xfi3.dts
index b1d8210f3ecc..28341d8315c2 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx23-xfi3.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx23-xfi3.dts
@@ -153,7 +153,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 2 5000000>;
+ pwms = <&pwm 2 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx23.dtsi b/arch/arm/boot/dts/nxp/mxs/imx23.dtsi
index 5eca942a52fd..fdf18b7cb2f6 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx23.dtsi
+++ b/arch/arm/boot/dts/nxp/mxs/imx23.dtsi
@@ -561,7 +561,7 @@
compatible = "fsl,imx23-pwm";
reg = <0x80064000 0x2000>;
clocks = <&clks 30>;
- #pwm-cells = <2>;
+ #pwm-cells = <3>;
fsl,pwm-number = <5>;
status = "disabled";
};
@@ -598,7 +598,7 @@
reg = <0x80070000 0x2000>;
interrupts = <0>;
clocks = <&clks 32>, <&clks 16>;
- clock-names = "uart", "apb_pclk";
+ clock-names = "uartclk", "apb_pclk";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-apf28dev.dts b/arch/arm/boot/dts/nxp/mxs/imx28-apf28dev.dts
index fd6fee63ad2f..6c87266eb135 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-apf28dev.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-apf28dev.dts
@@ -39,7 +39,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 3 191000>;
+ pwms = <&pwm 3 191000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-cfa10049.dts b/arch/arm/boot/dts/nxp/mxs/imx28-cfa10049.dts
index 953e3162d2d2..f0ce897b9d5c 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-cfa10049.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-cfa10049.dts
@@ -173,7 +173,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 3 5000000>;
+ pwms = <&pwm 3 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-cfa10055.dts b/arch/arm/boot/dts/nxp/mxs/imx28-cfa10055.dts
index 70e225a99fbe..cb68edd6101b 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-cfa10055.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-cfa10055.dts
@@ -39,7 +39,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 3 5000000>;
+ pwms = <&pwm 3 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-cfa10057.dts b/arch/arm/boot/dts/nxp/mxs/imx28-cfa10057.dts
index 0be7356941ee..5875c3d7ba97 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-cfa10057.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-cfa10057.dts
@@ -26,7 +26,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 4 5000000>;
+ pwms = <&pwm 4 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-cfa10058.dts b/arch/arm/boot/dts/nxp/mxs/imx28-cfa10058.dts
index aae0f1801461..b414e67ef379 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-cfa10058.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-cfa10058.dts
@@ -26,7 +26,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 3 5000000>;
+ pwms = <&pwm 3 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-eukrea-mbmx28lc.dtsi b/arch/arm/boot/dts/nxp/mxs/imx28-eukrea-mbmx28lc.dtsi
index 6633cde305e5..652fc9e57a55 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-eukrea-mbmx28lc.dtsi
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-eukrea-mbmx28lc.dtsi
@@ -14,7 +14,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 4 1000000>;
+ pwms = <&pwm 4 1000000 0>;
brightness-levels = <0 25 50 75 100 125 150 175 200 225 255>;
default-brightness-level = <10>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts b/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts
index 783abb82b2a8..9ebb7371e235 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts
@@ -117,7 +117,7 @@
backlight_display: backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 2 5000000>;
+ pwms = <&pwm 2 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-m28cu3.dts b/arch/arm/boot/dts/nxp/mxs/imx28-m28cu3.dts
index 8241c2d159fa..34b4d3246db1 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-m28cu3.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-m28cu3.dts
@@ -17,7 +17,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 3 5000000>;
+ pwms = <&pwm 3 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-m28evk.dts b/arch/arm/boot/dts/nxp/mxs/imx28-m28evk.dts
index 6bf26f386a5e..13070ca08cff 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-m28evk.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-m28evk.dts
@@ -13,7 +13,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 4 5000000>;
+ pwms = <&pwm 4 5000000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts b/arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts
index 23ad7cd0a1de..153e4017951d 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-tx28.dts
@@ -131,7 +131,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 0 500000>;
+ pwms = <&pwm 0 500000 0>;
/*
* a silly way to create a 1:1 relationship between the
* PWM value and the actual duty cycle
@@ -652,6 +652,7 @@
vbus-supply = <&reg_usb0_vbus>;
disable-over-current;
dr_mode = "peripheral";
+ phy_type = "utmi";
status = "okay";
};
@@ -659,19 +660,18 @@
vbus-supply = <&reg_usb1_vbus>;
disable-over-current;
dr_mode = "host";
+ phy_type = "utmi";
status = "okay";
};
&usbphy0 {
pinctrl-names = "default";
pinctrl-0 = <&tx28_usbphy0_pins>;
- phy_type = "utmi";
status = "okay";
};
&usbphy1 {
pinctrl-names = "default";
pinctrl-0 = <&tx28_usbphy1_pins>;
- phy_type = "utmi";
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28.dtsi b/arch/arm/boot/dts/nxp/mxs/imx28.dtsi
index 763adeb995ee..6932d23fb29d 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28.dtsi
+++ b/arch/arm/boot/dts/nxp/mxs/imx28.dtsi
@@ -1003,7 +1003,7 @@
};
dcp: crypto@80028000 {
- compatible = "fsl,imx28-dcp", "fsl,imx23-dcp";
+ compatible = "fsl,imx28-dcp";
reg = <0x80028000 0x2000>;
interrupts = <52>, <53>, <54>;
status = "okay";
@@ -1185,7 +1185,7 @@
compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
reg = <0x80064000 0x2000>;
clocks = <&clks 44>;
- #pwm-cells = <2>;
+ #pwm-cells = <3>;
fsl,pwm-number = <8>;
status = "disabled";
};
@@ -1252,7 +1252,7 @@
reg = <0x80074000 0x1000>;
interrupts = <47>;
clocks = <&clks 45>, <&clks 26>;
- clock-names = "uart", "apb_pclk";
+ clock-names = "uartclk", "apb_pclk";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/nxp/vf/vfxxx.dtsi b/arch/arm/boot/dts/nxp/vf/vfxxx.dtsi
index d1095b700c56..acccf9a3c898 100644
--- a/arch/arm/boot/dts/nxp/vf/vfxxx.dtsi
+++ b/arch/arm/boot/dts/nxp/vf/vfxxx.dtsi
@@ -111,8 +111,7 @@
interrupts = <61 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_UART0>;
clock-names = "ipg";
- dmas = <&edma0 0 2>,
- <&edma0 0 3>;
+ dmas = <&edma0 0 2>, <&edma0 0 3>;
dma-names = "rx","tx";
status = "disabled";
};
@@ -123,8 +122,7 @@
interrupts = <62 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_UART1>;
clock-names = "ipg";
- dmas = <&edma0 0 4>,
- <&edma0 0 5>;
+ dmas = <&edma0 0 4>, <&edma0 0 5>;
dma-names = "rx","tx";
status = "disabled";
};
@@ -135,8 +133,7 @@
interrupts = <63 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_UART2>;
clock-names = "ipg";
- dmas = <&edma0 0 6>,
- <&edma0 0 7>;
+ dmas = <&edma0 0 6>, <&edma0 0 7>;
dma-names = "rx","tx";
status = "disabled";
};
@@ -147,8 +144,7 @@
interrupts = <64 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_UART3>;
clock-names = "ipg";
- dmas = <&edma0 0 8>,
- <&edma0 0 9>;
+ dmas = <&edma0 0 8>, <&edma0 0 9>;
dma-names = "rx","tx";
status = "disabled";
};
@@ -162,8 +158,7 @@
clocks = <&clks VF610_CLK_DSPI0>;
clock-names = "dspi";
spi-num-chipselects = <6>;
- dmas = <&edma1 1 12>,
- <&edma1 1 13>;
+ dmas = <&edma1 1 12>, <&edma1 1 13>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -177,8 +172,7 @@
clocks = <&clks VF610_CLK_DSPI1>;
clock-names = "dspi";
spi-num-chipselects = <4>;
- dmas = <&edma1 1 14>,
- <&edma1 1 15>;
+ dmas = <&edma1 1 14>, <&edma1 1 15>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -426,8 +420,7 @@
interrupts = <72 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_I2C1>;
clock-names = "ipg";
- dmas = <&edma0 0 52>,
- <&edma0 0 53>;
+ dmas = <&edma0 0 52>, <&edma0 0 53>;
dma-names = "rx","tx";
status = "disabled";
};
@@ -551,8 +544,7 @@
clocks = <&clks VF610_CLK_DSPI3>;
clock-names = "dspi";
spi-num-chipselects = <2>;
- dmas = <&edma1 0 12>,
- <&edma1 0 13>;
+ dmas = <&edma1 0 12>, <&edma1 0 13>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -719,8 +711,7 @@
interrupts = <74 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_I2C3>;
clock-names = "ipg";
- dmas = <&edma0 1 38>,
- <&edma0 1 39>;
+ dmas = <&edma0 1 38>, <&edma0 1 39>;
dma-names = "rx","tx";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts
index 884d99297d4c..f516e0426bb9 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts
+++ b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts
@@ -45,11 +45,11 @@
event-hall-sensor {
label = "Hall Effect Sensor";
- gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>;
- interrupts = <&tlmm 110 IRQ_TYPE_EDGE_FALLING>;
+ gpios = <&tlmm 110 GPIO_ACTIVE_LOW>;
linux,input-type = <EV_SW>;
linux,code = <SW_LID>;
debounce-interval = <15>;
+ linux,can-disable;
wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts b/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts
index db4c791b2e2f..569cbf0d8df8 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts
@@ -24,7 +24,6 @@
regulator-min-microvolt = <3700000>;
regulator-max-microvolt = <3700000>;
regulator-name = "VPH";
- regulator-type = "voltage";
regulator-always-on;
regulator-boot-on;
};
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064-asus-nexus7-flo.dts b/arch/arm/boot/dts/qcom/qcom-apq8064-asus-nexus7-flo.dts
index c57c27cd8a20..c0dd6399f597 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8064-asus-nexus7-flo.dts
+++ b/arch/arm/boot/dts/qcom/qcom-apq8064-asus-nexus7-flo.dts
@@ -36,7 +36,6 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "ext_3p3v";
- regulator-type = "voltage";
startup-delay-us = <0>;
gpio = <&tlmm_pinmux 77 GPIO_ACTIVE_HIGH>;
enable-active-high;
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom/qcom-apq8064-ifc6410.dts
index 96307550523a..b0c5e7bd5e74 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8064-ifc6410.dts
+++ b/arch/arm/boot/dts/qcom/qcom-apq8064-ifc6410.dts
@@ -58,7 +58,6 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "ext_3p3v";
- regulator-type = "voltage";
startup-delay-us = <0>;
gpio = <&tlmm_pinmux 77 GPIO_ACTIVE_HIGH>;
enable-active-high;
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
index 516f0d2495e2..59fd86b9fb47 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
@@ -1270,7 +1270,6 @@
dsi0: dsi@4700000 {
compatible = "qcom,apq8064-dsi-ctrl",
"qcom,mdss-dsi-ctrl";
- label = "MDSS DSI CTRL->0";
#address-cells = <1>;
#size-cells = <0>;
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/qcom/qcom-ipq8064-rb3011.dts b/arch/arm/boot/dts/qcom/qcom-ipq8064-rb3011.dts
index 1796ded31d17..12e806adcda8 100644
--- a/arch/arm/boot/dts/qcom/qcom-ipq8064-rb3011.dts
+++ b/arch/arm/boot/dts/qcom/qcom-ipq8064-rb3011.dts
@@ -20,6 +20,33 @@
stdout-path = "serial0:115200n8";
};
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&buttons_pins>;
+ pinctrl-names = "default";
+
+ button {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&qcom_pinmux 66 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ debounce-interval = <60>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&leds_pins>;
+ pinctrl-names = "default";
+
+ led-0 {
+ label = "rb3011:green:user";
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&qcom_pinmux 33 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
memory@42000000 {
reg = <0x42000000 0x3e000000>;
device_type = "memory";
@@ -302,34 +329,6 @@
};
};
};
-
- gpio-keys {
- compatible = "gpio-keys";
- pinctrl-0 = <&buttons_pins>;
- pinctrl-names = "default";
-
- button {
- label = "reset";
- linux,code = <KEY_RESTART>;
- gpios = <&qcom_pinmux 66 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- debounce-interval = <60>;
- };
- };
-
- leds {
- compatible = "gpio-leds";
- pinctrl-0 = <&leds_pins>;
- pinctrl-names = "default";
-
- led-0 {
- label = "rb3011:green:user";
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&qcom_pinmux 33 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
- };
-
};
};
diff --git a/arch/arm/boot/dts/qcom/qcom-ipq8064-v1.0.dtsi b/arch/arm/boot/dts/qcom/qcom-ipq8064-v1.0.dtsi
index 17f65e140e02..49de9752632f 100644
--- a/arch/arm/boot/dts/qcom/qcom-ipq8064-v1.0.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-ipq8064-v1.0.dtsi
@@ -14,6 +14,67 @@
stdout-path = "serial0:115200n8";
};
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&buttons_pins>;
+ pinctrl-names = "default";
+
+ button-1 {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&qcom_pinmux 54 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ debounce-interval = <60>;
+ };
+ button-2 {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&qcom_pinmux 65 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ debounce-interval = <60>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&leds_pins>;
+ pinctrl-names = "default";
+
+ led-0 {
+ label = "led_usb1";
+ gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "usbdev";
+ default-state = "off";
+ };
+
+ led-1 {
+ label = "led_usb3";
+ gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "usbdev";
+ default-state = "off";
+ };
+
+ led-2 {
+ label = "status_led_fail";
+ function = LED_FUNCTION_STATUS;
+ gpios = <&qcom_pinmux 9 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-3 {
+ label = "sata_led";
+ gpios = <&qcom_pinmux 26 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-4 {
+ label = "status_led_pass";
+ function = LED_FUNCTION_STATUS;
+ gpios = <&qcom_pinmux 53 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
soc {
gsbi@16300000 {
qcom,mode = <GSBI_PROT_I2C_UART>;
@@ -64,66 +125,5 @@
ports-implemented = <0x1>;
status = "okay";
};
-
- gpio-keys {
- compatible = "gpio-keys";
- pinctrl-0 = <&buttons_pins>;
- pinctrl-names = "default";
-
- button-1 {
- label = "reset";
- linux,code = <KEY_RESTART>;
- gpios = <&qcom_pinmux 54 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- debounce-interval = <60>;
- };
- button-2 {
- label = "wps";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&qcom_pinmux 65 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- debounce-interval = <60>;
- };
- };
-
- leds {
- compatible = "gpio-leds";
- pinctrl-0 = <&leds_pins>;
- pinctrl-names = "default";
-
- led-0 {
- label = "led_usb1";
- gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "usbdev";
- default-state = "off";
- };
-
- led-1 {
- label = "led_usb3";
- gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "usbdev";
- default-state = "off";
- };
-
- led-2 {
- label = "status_led_fail";
- function = LED_FUNCTION_STATUS;
- gpios = <&qcom_pinmux 9 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
-
- led-3 {
- label = "sata_led";
- gpios = <&qcom_pinmux 26 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
-
- led-4 {
- label = "status_led_pass";
- function = LED_FUNCTION_STATUS;
- gpios = <&qcom_pinmux 53 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
- };
};
};
diff --git a/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi
index fc4f52f9e9f7..63e21aa23642 100644
--- a/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi
@@ -47,14 +47,12 @@
};
};
- regulators {
- vsdcc_fixed: vsdcc-regulator {
- compatible = "regulator-fixed";
- regulator-name = "SDCC Power";
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <2700000>;
- regulator-always-on;
- };
+ vsdcc_fixed: vsdcc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "SDCC Power";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ regulator-always-on;
};
soc: soc {
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi
index 44f3f0127fd7..98cc5ea637e1 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi
@@ -56,6 +56,18 @@
rpm: remoteproc {
compatible = "qcom,msm8226-rpm-proc", "qcom,rpm-proc";
+ master-stats {
+ compatible = "qcom,rpm-master-stats";
+ qcom,rpm-msg-ram = <&apss_master_stats>,
+ <&mpss_master_stats>,
+ <&lpss_master_stats>,
+ <&pronto_master_stats>;
+ qcom,master-names = "APSS",
+ "MPSS",
+ "LPSS",
+ "PRONTO";
+ };
+
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
qcom,ipc = <&apcs 8 0>;
@@ -742,6 +754,26 @@
rpm_msg_ram: sram@fc428000 {
compatible = "qcom,rpm-msg-ram";
reg = <0xfc428000 0x4000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0xfc428000 0x4000>;
+
+ apss_master_stats: sram@150 {
+ reg = <0x150 0x14>;
+ };
+
+ mpss_master_stats: sram@b50 {
+ reg = <0xb50 0x14>;
+ };
+
+ lpss_master_stats: sram@1550 {
+ reg = <0x1550 0x14>;
+ };
+
+ pronto_master_stats: sram@1f50 {
+ reg = <0x1f50 0x14>;
+ };
};
tcsr_mutex: hwlock@fd484000 {
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
index 706fef53767e..0bc2e66d15b1 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
@@ -116,6 +116,18 @@
rpm: remoteproc {
compatible = "qcom,msm8974-rpm-proc", "qcom,rpm-proc";
+ master-stats {
+ compatible = "qcom,rpm-master-stats";
+ qcom,rpm-msg-ram = <&apss_master_stats>,
+ <&mpss_master_stats>,
+ <&lpss_master_stats>,
+ <&pronto_master_stats>;
+ qcom,master-names = "APSS",
+ "MPSS",
+ "LPSS",
+ "PRONTO";
+ };
+
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
qcom,ipc = <&apcs 8 0>;
@@ -1067,6 +1079,26 @@
rpm_msg_ram: sram@fc428000 {
compatible = "qcom,rpm-msg-ram";
reg = <0xfc428000 0x4000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0xfc428000 0x4000>;
+
+ apss_master_stats: sram@150 {
+ reg = <0x150 0x14>;
+ };
+
+ mpss_master_stats: sram@b50 {
+ reg = <0xb50 0x14>;
+ };
+
+ lpss_master_stats: sram@1550 {
+ reg = <0x1550 0x14>;
+ };
+
+ pronto_master_stats: sram@1f50 {
+ reg = <0x1f50 0x14>;
+ };
};
bimc: interconnect@fc380000 {
diff --git a/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
index 55ce87b75253..2aa5089a8513 100644
--- a/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
@@ -379,7 +379,7 @@
power-domains = <&gcc PCIE_GDSC>;
- phys = <&pcie_lane>;
+ phys = <&pcie_phy>;
phy-names = "pciephy";
status = "disabled";
@@ -428,7 +428,7 @@
resets = <&gcc GCC_PCIE_BCR>;
reset-names = "core";
power-domains = <&gcc PCIE_GDSC>;
- phys = <&pcie_lane>;
+ phys = <&pcie_phy>;
phy-names = "pciephy";
max-link-speed = <3>;
num-lanes = <2>;
@@ -438,18 +438,25 @@
pcie_phy: phy@1c07000 {
compatible = "qcom,sdx55-qmp-pcie-phy";
- reg = <0x01c07000 0x1c4>;
+ reg = <0x01c07000 0x2000>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
clocks = <&gcc GCC_PCIE_AUX_PHY_CLK_SRC>,
<&gcc GCC_PCIE_CFG_AHB_CLK>,
<&gcc GCC_PCIE_0_CLKREF_CLK>,
- <&gcc GCC_PCIE_RCHNG_PHY_CLK>;
+ <&gcc GCC_PCIE_RCHNG_PHY_CLK>,
+ <&gcc GCC_PCIE_PIPE_CLK>;
clock-names = "aux",
"cfg_ahb",
"ref",
- "refgen";
+ "refgen",
+ "pipe";
+
+ clock-output-names = "pcie_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_PHY_BCR>;
reset-names = "phy";
@@ -458,20 +465,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie_lane: lanes@1c06000 {
- reg = <0x01c06000 0x104>, /* tx0 */
- <0x01c06200 0x328>, /* rx0 */
- <0x01c07200 0x1e8>, /* pcs */
- <0x01c06800 0x104>, /* tx1 */
- <0x01c06a00 0x328>, /* rx1 */
- <0x01c07600 0x800>; /* pcs_misc */
- clocks = <&gcc GCC_PCIE_PIPE_CLK>;
- clock-names = "pipe0";
-
- #phy-cells = <0>;
- clock-output-names = "pcie_pipe_clk";
- };
};
ipa: ipa@1e40000 {
@@ -645,7 +638,6 @@
#size-cells = <0>;
interrupt-controller;
#interrupt-cells = <4>;
- cell-index = <0>;
};
tlmm: pinctrl@f100000 {
diff --git a/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts b/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts
index fcf1c51c5e7a..9649c859a2c3 100644
--- a/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts
+++ b/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts
@@ -4,6 +4,10 @@
*/
/dts-v1/;
+/* PM7250B is configured to use SID2/3 */
+#define PM7250B_SID 2
+#define PM7250B_SID1 3
+
#include "qcom-sdx65.dtsi"
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include <arm64/qcom/pmk8350.dtsi>
diff --git a/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi b/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi
index 1a3583029a64..e559adaaeee7 100644
--- a/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi
@@ -466,9 +466,9 @@
interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hc_irq", "pwr_irq";
- clocks = <&gcc GCC_SDCC1_APPS_CLK>,
- <&gcc GCC_SDCC1_AHB_CLK>;
- clock-names = "core", "iface";
+ clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+ <&gcc GCC_SDCC1_APPS_CLK>;
+ clock-names = "iface", "core";
status = "disabled";
};
@@ -544,7 +544,6 @@
#interrupt-cells = <4>;
#address-cells = <2>;
#size-cells = <0>;
- cell-index = <0>;
qcom,channel = <0>;
qcom,ee = <0>;
};
diff --git a/arch/arm/boot/dts/renesas/r7s72100-genmai.dts b/arch/arm/boot/dts/renesas/r7s72100-genmai.dts
index 1e8447176b10..29ba098f5dd5 100644
--- a/arch/arm/boot/dts/renesas/r7s72100-genmai.dts
+++ b/arch/arm/boot/dts/renesas/r7s72100-genmai.dts
@@ -29,9 +29,33 @@
reg = <0x08000000 0x08000000>;
};
- lbsc {
+ flash@18000000 {
+ compatible = "mtd-rom";
+ reg = <0x18000000 0x08000000>;
+ bank-width = <4>;
+ device-width = <1>;
+
+ clocks = <&mstp9_clks R7S72100_CLK_SPIBSC0>;
+ power-domains = <&cpg_clocks>;
+
#address-cells = <1>;
#size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "user";
+ reg = <0x00000000 0x04000000>;
+ };
+
+ partition@4000000 {
+ label = "user1";
+ reg = <0x04000000 0x40000000>;
+ };
+ };
};
leds {
@@ -87,6 +111,62 @@
clock-frequency = <13330000>;
};
+&bsc {
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0x00000000 0x04000000>;
+ bank-width = <2>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x00000000 0x00040000>;
+ };
+
+ partition@40000 {
+ label = "uboot-env";
+ reg = <0x00040000 0x00020000>;
+ };
+
+ partition@60000 {
+ label = "flash";
+ reg = <0x00060000 0x03fa0000>;
+ };
+ };
+ };
+
+ flash@4000000 {
+ compatible = "cfi-flash";
+ reg = <0x04000000 0x04000000>;
+ bank-width = <2>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "uboot1";
+ reg = <0x00000000 0x00040000>;
+ };
+
+ partition@40000 {
+ label = "uboot-env1";
+ reg = <0x00040000 0x00020000>;
+ };
+
+ partition@60000 {
+ label = "flash1";
+ reg = <0x00060000 0x03fa0000>;
+ };
+ };
+ };
+};
+
&usb_x1_clk {
clock-frequency = <48000000>;
};
diff --git a/arch/arm/boot/dts/renesas/r7s72100-gr-peach.dts b/arch/arm/boot/dts/renesas/r7s72100-gr-peach.dts
index 105f9c71f9fd..9d29861f23f1 100644
--- a/arch/arm/boot/dts/renesas/r7s72100-gr-peach.dts
+++ b/arch/arm/boot/dts/renesas/r7s72100-gr-peach.dts
@@ -29,14 +29,8 @@
reg = <0x20000000 0x00a00000>;
};
- lbsc {
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
flash@18000000 {
compatible = "mtd-rom";
- probe-type = "map_rom";
reg = <0x18000000 0x00800000>;
bank-width = <4>;
device-width = <1>;
diff --git a/arch/arm/boot/dts/renesas/r7s72100-rskrza1.dts b/arch/arm/boot/dts/renesas/r7s72100-rskrza1.dts
index 1c5acf694407..b547216d4801 100644
--- a/arch/arm/boot/dts/renesas/r7s72100-rskrza1.dts
+++ b/arch/arm/boot/dts/renesas/r7s72100-rskrza1.dts
@@ -29,6 +29,48 @@
reg = <0x08000000 0x02000000>;
};
+ flash@18000000 {
+ compatible = "mtd-rom";
+ reg = <0x18000000 0x08000000>;
+ clocks = <&mstp9_clks R7S72100_CLK_SPIBSC0>;
+ power-domains = <&cpg_clocks>;
+ bank-width = <4>;
+ device-width = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x00000000 0x00080000>;
+ };
+
+ partition@80000 {
+ label = "uboot-env";
+ reg = <0x00080000 0x00040000>;
+ };
+
+ partition@c0000 {
+ label = "dt";
+ reg = <0x000c0000 0x00040000>;
+ };
+
+ partition@100000 {
+ label = "kernel";
+ reg = <0x00100000 0x00280000>;
+ };
+
+ partition@400000 {
+ label = "rootfs";
+ reg = <0x00400000 0x01c00000>;
+ };
+ };
+ };
+
keyboard {
compatible = "gpio-keys";
@@ -60,11 +102,6 @@
};
};
- lbsc {
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
leds {
compatible = "gpio-leds";
@@ -118,6 +155,30 @@
};
};
+&bsc {
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0x00000000 0x4000000>;
+ bank-width = <2>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "apps";
+ reg = <0x00000000 0x01000000>;
+ };
+
+ partition@1000000 {
+ label = "data";
+ reg = <0x01000000 0x03000000>;
+ };
+ };
+ };
+};
+
&usb_x1_clk {
clock-frequency = <48000000>;
};
diff --git a/arch/arm/boot/dts/renesas/r7s72100.dtsi b/arch/arm/boot/dts/renesas/r7s72100.dtsi
index b07b71307f24..e6d8da6faffb 100644
--- a/arch/arm/boot/dts/renesas/r7s72100.dtsi
+++ b/arch/arm/boot/dts/renesas/r7s72100.dtsi
@@ -36,6 +36,13 @@
clock-div = <3>;
};
+ bsc: bsc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0x18000000>;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/renesas/r7s9210-rza2mevb.dts b/arch/arm/boot/dts/renesas/r7s9210-rza2mevb.dts
index 69a5a44b8a2f..cd2324b8e8ff 100644
--- a/arch/arm/boot/dts/renesas/r7s9210-rza2mevb.dts
+++ b/arch/arm/boot/dts/renesas/r7s9210-rza2mevb.dts
@@ -63,11 +63,6 @@
};
};
- lbsc {
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
leds {
compatible = "gpio-leds";
diff --git a/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts
index e81a7213d304..ed75c01dbee1 100644
--- a/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts
+++ b/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts
@@ -164,7 +164,7 @@
&bsc {
flash@0 {
- compatible = "cfi-flash", "mtd-rom";
+ compatible = "cfi-flash";
reg = <0x0 0x08000000>;
bank-width = <2>;
diff --git a/arch/arm/boot/dts/renesas/r8a7778-bockw.dts b/arch/arm/boot/dts/renesas/r8a7778-bockw.dts
index 9b65d246e583..a3f9d74e8877 100644
--- a/arch/arm/boot/dts/renesas/r8a7778-bockw.dts
+++ b/arch/arm/boot/dts/renesas/r8a7778-bockw.dts
@@ -62,6 +62,35 @@
};
&bsc {
+ flash@0 {
+ compatible = "cfi-flash";
+ reg = <0x0 0x04000000>;
+ pinctrl-0 = <&flash_pins>;
+ pinctrl-names = "default";
+ bank-width = <2>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x00000000 0x00040000>;
+ read-only;
+ };
+ partition@40000 {
+ label = "uboot-env";
+ reg = <0x00040000 0x00040000>;
+ read-only;
+ };
+ partition@80000 {
+ label = "flash";
+ reg = <0x00080000 0x03f80000>;
+ };
+ };
+ };
+
ethernet@18300000 {
compatible = "smsc,lan89218", "smsc,lan9115";
reg = <0x18300000 0x1000>;
@@ -126,6 +155,11 @@
pinctrl-0 = <&scif_clk_pins>;
pinctrl-names = "default";
+ flash_pins: flash {
+ groups = "lbsc_cs0";
+ function = "lbsc";
+ };
+
scif0_pins: scif0 {
groups = "scif0_data_a", "scif0_ctrl";
function = "scif0";
diff --git a/arch/arm/boot/dts/renesas/r8a7779-marzen.dts b/arch/arm/boot/dts/renesas/r8a7779-marzen.dts
index fd40890bd77b..08ea149b1ee6 100644
--- a/arch/arm/boot/dts/renesas/r8a7779-marzen.dts
+++ b/arch/arm/boot/dts/renesas/r8a7779-marzen.dts
@@ -52,21 +52,6 @@
states = <3300000 1>, <1800000 0>;
};
- ethernet@18000000 {
- compatible = "smsc,lan89218", "smsc,lan9115";
- reg = <0x18000000 0x100>;
- pinctrl-0 = <&ethernet_pins>;
- pinctrl-names = "default";
-
- phy-mode = "mii";
- interrupt-parent = <&irqpin0>;
- interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
- smsc,irq-push-pull;
- reg-io-width = <4>;
- vddvario-supply = <&fixedregulator3v3>;
- vdd33a-supply = <&fixedregulator3v3>;
- };
-
keyboard-irq {
compatible = "gpio-keys";
@@ -229,6 +214,23 @@
clock-frequency = <31250000>;
};
+&lbsc {
+ ethernet@18000000 {
+ compatible = "smsc,lan89218", "smsc,lan9115";
+ reg = <0x18000000 0x100>;
+ pinctrl-0 = <&ethernet_pins>;
+ pinctrl-names = "default";
+
+ phy-mode = "mii";
+ interrupt-parent = <&irqpin0>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ smsc,irq-push-pull;
+ reg-io-width = <4>;
+ vddvario-supply = <&fixedregulator3v3>;
+ vdd33a-supply = <&fixedregulator3v3>;
+ };
+};
+
&tmu0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/renesas/r8a7779.dtsi b/arch/arm/boot/dts/renesas/r8a7779.dtsi
index 97b767d81d92..7743af5e2a6f 100644
--- a/arch/arm/boot/dts/renesas/r8a7779.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7779.dtsi
@@ -699,6 +699,13 @@
};
};
+ lbsc: lbsc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0x1c000000>;
+ };
+
prr: chipid@ff000044 {
compatible = "renesas,prr";
reg = <0xff000044 4>;
diff --git a/arch/arm/boot/dts/renesas/r8a7790-lager.dts b/arch/arm/boot/dts/renesas/r8a7790-lager.dts
index 5ad5349a50dc..4d666ad8b114 100644
--- a/arch/arm/boot/dts/renesas/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/renesas/r8a7790-lager.dts
@@ -73,11 +73,6 @@
reg = <1 0x40000000 0 0xc0000000>;
};
- lbsc {
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
keyboard {
compatible = "gpio-keys";
diff --git a/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts b/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts
index 26a40782cc89..545515b41ea3 100644
--- a/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts
@@ -73,11 +73,6 @@
reg = <2 0x00000000 0 0x40000000>;
};
- lbsc {
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
keyboard {
compatible = "gpio-keys";
diff --git a/arch/arm/boot/dts/renesas/r8a7792-blanche.dts b/arch/arm/boot/dts/renesas/r8a7792-blanche.dts
index c66de9dd12df..e793134f32a3 100644
--- a/arch/arm/boot/dts/renesas/r8a7792-blanche.dts
+++ b/arch/arm/boot/dts/renesas/r8a7792-blanche.dts
@@ -39,21 +39,6 @@
regulator-always-on;
};
- ethernet@18000000 {
- compatible = "smsc,lan89218", "smsc,lan9115";
- reg = <0 0x18000000 0 0x100>;
- phy-mode = "mii";
- interrupt-parent = <&irqc>;
- interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
- smsc,irq-push-pull;
- reg-io-width = <4>;
- vddvario-supply = <&d3_3v>;
- vdd33a-supply = <&d3_3v>;
-
- pinctrl-0 = <&lan89218_pins>;
- pinctrl-names = "default";
- };
-
vga-encoder {
compatible = "adi,adv7123";
@@ -196,6 +181,23 @@
clock-frequency = <48000000>;
};
+&lbsc {
+ ethernet@18000000 {
+ compatible = "smsc,lan89218", "smsc,lan9115";
+ reg = <0x18000000 0x100>;
+ phy-mode = "mii";
+ interrupt-parent = <&irqc>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+ smsc,irq-push-pull;
+ reg-io-width = <4>;
+ vddvario-supply = <&d3_3v>;
+ vdd33a-supply = <&d3_3v>;
+
+ pinctrl-0 = <&lan89218_pins>;
+ pinctrl-names = "default";
+ };
+};
+
&pfc {
scif0_pins: scif0 {
groups = "scif0_data";
@@ -239,7 +241,7 @@
};
keyboard_pins: keyboard {
- pins = "GP_3_10", "GP_3_11", "GP_3_12", "GP_3_15", "GP_11_02";
+ pins = "GP_3_10", "GP_3_11", "GP_3_12", "GP_3_15", "GP_11_2";
bias-pull-up;
};
diff --git a/arch/arm/boot/dts/renesas/r8a7792-wheat.dts b/arch/arm/boot/dts/renesas/r8a7792-wheat.dts
index 434e4655be9d..f87e78fe3f6e 100644
--- a/arch/arm/boot/dts/renesas/r8a7792-wheat.dts
+++ b/arch/arm/boot/dts/renesas/r8a7792-wheat.dts
@@ -38,22 +38,6 @@
regulator-always-on;
};
- ethernet@18000000 {
- compatible = "smsc,lan89218", "smsc,lan9115";
- reg = <0 0x18000000 0 0x100>;
- phy-mode = "mii";
- interrupt-parent = <&irqc>;
- interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
- smsc,irq-push-pull;
- smsc,save-mac-address;
- reg-io-width = <4>;
- vddvario-supply = <&d3_3v>;
- vdd33a-supply = <&d3_3v>;
-
- pinctrl-0 = <&lan89218_pins>;
- pinctrl-names = "default";
- };
-
keyboard {
compatible = "gpio-keys";
@@ -117,6 +101,24 @@
clock-frequency = <20000000>;
};
+&lbsc {
+ ethernet@18000000 {
+ compatible = "smsc,lan89218", "smsc,lan9115";
+ reg = <0x18000000 0x100>;
+ phy-mode = "mii";
+ interrupt-parent = <&irqc>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+ smsc,irq-push-pull;
+ smsc,save-mac-address;
+ reg-io-width = <4>;
+ vddvario-supply = <&d3_3v>;
+ vdd33a-supply = <&d3_3v>;
+
+ pinctrl-0 = <&lan89218_pins>;
+ pinctrl-names = "default";
+ };
+};
+
&pfc {
scif0_pins: scif0 {
groups = "scif0_data";
diff --git a/arch/arm/boot/dts/renesas/r8a7792.dtsi b/arch/arm/boot/dts/renesas/r8a7792.dtsi
index a6d9367f8fa0..ecfab3ff59e8 100644
--- a/arch/arm/boot/dts/renesas/r8a7792.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7792.dtsi
@@ -84,6 +84,13 @@
clock-frequency = <0>;
};
+ lbsc: lbsc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0x1c000000>;
+ };
+
pmu {
compatible = "arm,cortex-a15-pmu";
interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm/boot/dts/renesas/r8a7794-alt.dts b/arch/arm/boot/dts/renesas/r8a7794-alt.dts
index 4d93319674c6..08df031bc27c 100644
--- a/arch/arm/boot/dts/renesas/r8a7794-alt.dts
+++ b/arch/arm/boot/dts/renesas/r8a7794-alt.dts
@@ -90,11 +90,6 @@
states = <3300000 1>, <1800000 0>;
};
- lbsc {
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
keyboard {
compatible = "gpio-keys";
diff --git a/arch/arm/boot/dts/rockchip/rk3128.dtsi b/arch/arm/boot/dts/rockchip/rk3128.dtsi
index 88a4b0d6d928..7bf557c99561 100644
--- a/arch/arm/boot/dts/rockchip/rk3128.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3128.dtsi
@@ -27,6 +27,7 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
+ enable-method = "rockchip,rk3036-smp";
cpu0: cpu@f00 {
device_type = "cpu";
@@ -34,10 +35,8 @@
reg = <0xf00>;
clock-latency = <40000>;
clocks = <&cru ARMCLK>;
- operating-points = <
- /* KHz uV */
- 816000 1000000
- >;
+ resets = <&cru SRST_CORE0>;
+ operating-points-v2 = <&cpu_opp_table>;
#cooling-cells = <2>; /* min followed by max */
};
@@ -45,18 +44,59 @@
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0xf01>;
+ resets = <&cru SRST_CORE1>;
+ operating-points-v2 = <&cpu_opp_table>;
};
cpu2: cpu@f02 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0xf02>;
+ resets = <&cru SRST_CORE2>;
+ operating-points-v2 = <&cpu_opp_table>;
};
cpu3: cpu@f03 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0xf03>;
+ resets = <&cru SRST_CORE3>;
+ operating-points-v2 = <&cpu_opp_table>;
+ };
+ };
+
+ cpu_opp_table: opp-table-0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-216000000 {
+ opp-hz = /bits/ 64 <216000000>;
+ opp-microvolt = <950000 950000 1325000>;
+ };
+ opp-408000000 {
+ opp-hz = /bits/ 64 <408000000>;
+ opp-microvolt = <950000 950000 1325000>;
+ };
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <950000 950000 1325000>;
+ };
+ opp-696000000 {
+ opp-hz = /bits/ 64 <696000000>;
+ opp-microvolt = <975000 975000 1325000>;
+ };
+ opp-816000000 {
+ opp-hz = /bits/ 64 <816000000>;
+ opp-microvolt = <1075000 1075000 1325000>;
+ opp-suspend;
+ };
+ opp-1008000000 {
+ opp-hz = /bits/ 64 <1008000000>;
+ opp-microvolt = <1200000 1200000 1325000>;
+ };
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1325000 1325000 1325000>;
};
};
@@ -77,6 +117,19 @@
#clock-cells = <0>;
};
+ imem: sram@10080000 {
+ compatible = "mmio-sram";
+ reg = <0x10080000 0x2000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x10080000 0x2000>;
+
+ smp-sram@0 {
+ compatible = "rockchip,rk3066-smp-sram";
+ reg = <0x00 0x10>;
+ };
+ };
+
pmu: syscon@100a0000 {
compatible = "rockchip,rk3128-pmu", "syscon", "simple-mfd";
reg = <0x100a0000 0x1000>;
diff --git a/arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts b/arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts
index 3d587602e13a..f09be8405964 100644
--- a/arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts
+++ b/arch/arm/boot/dts/rockchip/rv1126-edgeble-neu2-io.dts
@@ -88,6 +88,10 @@
};
};
+&pwm11 {
+ status = "okay";
+};
+
&sdmmc {
bus-width = <4>;
cap-mmc-highspeed;
diff --git a/arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi b/arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi
index 554353e0a758..bb34b0c9cb4a 100644
--- a/arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi
+++ b/arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi
@@ -87,6 +87,22 @@
<0 RK_PB5 1 &pcfg_pull_none_drv_level_0_smt>;
};
};
+ pwm2 {
+ /omit-if-no-ref/
+ pwm2m0_pins: pwm2m0-pins {
+ rockchip,pins =
+ /* pwm2_pin_m0 */
+ <0 RK_PC0 3 &pcfg_pull_none>;
+ };
+ };
+ pwm11 {
+ /omit-if-no-ref/
+ pwm11m0_pins: pwm11m0-pins {
+ rockchip,pins =
+ /* pwm11_pin_m0 */
+ <3 RK_PA7 6 &pcfg_pull_none>;
+ };
+ };
rgmii {
/omit-if-no-ref/
rgmiim1_pins: rgmiim1-pins {
diff --git a/arch/arm/boot/dts/rockchip/rv1126.dtsi b/arch/arm/boot/dts/rockchip/rv1126.dtsi
index 9c918420ecd5..9ccd1bad6229 100644
--- a/arch/arm/boot/dts/rockchip/rv1126.dtsi
+++ b/arch/arm/boot/dts/rockchip/rv1126.dtsi
@@ -247,6 +247,17 @@
status = "disabled";
};
+ pwm2: pwm@ff430020 {
+ compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
+ reg = <0xff430020 0x10>;
+ clock-names = "pwm", "pclk";
+ clocks = <&pmucru CLK_PWM0>, <&pmucru PCLK_PWM0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2m0_pins>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
pmucru: clock-controller@ff480000 {
compatible = "rockchip,rv1126-pmucru";
reg = <0xff480000 0x1000>;
@@ -276,6 +287,17 @@
clock-names = "apb_pclk";
};
+ pwm11: pwm@ff550030 {
+ compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
+ reg = <0xff550030 0x10>;
+ clock-names = "pwm", "pclk";
+ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+ pinctrl-0 = <&pwm11m0_pins>;
+ pinctrl-names = "default";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
uart0: serial@ff560000 {
compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart";
reg = <0xff560000 0x100>;
diff --git a/arch/arm/boot/dts/samsung/exynos4210.dtsi b/arch/arm/boot/dts/samsung/exynos4210.dtsi
index 0e27c3375e2e..510e8665d1a2 100644
--- a/arch/arm/boot/dts/samsung/exynos4210.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4210.dtsi
@@ -391,8 +391,16 @@
};
&cpu_thermal {
- polling-delay-passive = <0>;
- polling-delay = <0>;
+ /*
+ * Exynos 4210 supports thermal interrupts, but only for the rising
+ * threshold. This means that polling is not needed for preventing
+ * overheating, but only for decreasing cooling when possible. Hence we
+ * poll with a high delay. Ideally, we would disable polling for the
+ * first trip point, but this isn't really possible without outrageous
+ * hacks.
+ */
+ polling-delay-passive = <5000>;
+ polling-delay = <5000>;
};
&gic {
diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
index ce81e42bf5eb..d7954ff466b4 100644
--- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
@@ -300,34 +300,33 @@
mic-bias-supply = <&mic_bias_reg>;
submic-bias-supply = <&submic_bias_reg>;
- samsung,audio-routing =
- "HP", "HPOUT1L",
- "HP", "HPOUT1R",
+ audio-routing = "HP", "HPOUT1L",
+ "HP", "HPOUT1R",
- "SPK", "SPKOUTLN",
- "SPK", "SPKOUTLP",
- "SPK", "SPKOUTRN",
- "SPK", "SPKOUTRP",
+ "SPK", "SPKOUTLN",
+ "SPK", "SPKOUTLP",
+ "SPK", "SPKOUTRN",
+ "SPK", "SPKOUTRP",
- "RCV", "HPOUT2N",
- "RCV", "HPOUT2P",
+ "RCV", "HPOUT2N",
+ "RCV", "HPOUT2P",
- "LINE", "LINEOUT2N",
- "LINE", "LINEOUT2P",
+ "LINE", "LINEOUT2N",
+ "LINE", "LINEOUT2P",
- "HDMI", "LINEOUT1N",
- "HDMI", "LINEOUT1P",
+ "HDMI", "LINEOUT1N",
+ "HDMI", "LINEOUT1P",
- "IN2LP:VXRN", "MICBIAS1",
- "IN2LN", "MICBIAS1",
- "Main Mic", "MICBIAS1",
+ "IN2LP:VXRN", "MICBIAS1",
+ "IN2LN", "MICBIAS1",
+ "Main Mic", "MICBIAS1",
- "IN1RP", "MICBIAS2",
- "IN1RN", "MICBIAS2",
- "Sub Mic", "MICBIAS2",
+ "IN1RP", "MICBIAS2",
+ "IN1RN", "MICBIAS2",
+ "Sub Mic", "MICBIAS2",
- "IN1LP", "Headset Mic",
- "IN1LN", "Headset Mic";
+ "IN1LP", "Headset Mic",
+ "IN1LN", "Headset Mic";
cpu {
sound-dai = <&i2s0 0>;
diff --git a/arch/arm/boot/dts/samsung/exynos4412-galaxy-s3.dtsi b/arch/arm/boot/dts/samsung/exynos4412-galaxy-s3.dtsi
index 94122e9c6625..54e1a57ae886 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-galaxy-s3.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4412-galaxy-s3.dtsi
@@ -173,36 +173,35 @@
};
&sound {
- samsung,audio-routing =
- "HP", "HPOUT1L",
- "HP", "HPOUT1R",
+ audio-routing = "HP", "HPOUT1L",
+ "HP", "HPOUT1R",
- "SPK", "SPKOUTLN",
- "SPK", "SPKOUTLP",
- "SPK", "SPKOUTRN",
- "SPK", "SPKOUTRP",
+ "SPK", "SPKOUTLN",
+ "SPK", "SPKOUTLP",
+ "SPK", "SPKOUTRN",
+ "SPK", "SPKOUTRP",
- "RCV", "HPOUT2N",
- "RCV", "HPOUT2P",
+ "RCV", "HPOUT2N",
+ "RCV", "HPOUT2P",
- "HDMI", "LINEOUT1N",
- "HDMI", "LINEOUT1P",
+ "HDMI", "LINEOUT1N",
+ "HDMI", "LINEOUT1P",
- "LINE", "LINEOUT2N",
- "LINE", "LINEOUT2P",
+ "LINE", "LINEOUT2N",
+ "LINE", "LINEOUT2P",
- "IN1LP", "MICBIAS1",
- "IN1LN", "MICBIAS1",
- "Main Mic", "MICBIAS1",
+ "IN1LP", "MICBIAS1",
+ "IN1LN", "MICBIAS1",
+ "Main Mic", "MICBIAS1",
- "IN1RP", "Sub Mic",
- "IN1RN", "Sub Mic",
+ "IN1RP", "Sub Mic",
+ "IN1RN", "Sub Mic",
- "IN2LP:VXRN", "MICBIAS2",
- "Headset Mic", "MICBIAS2",
+ "IN2LP:VXRN", "MICBIAS2",
+ "Headset Mic", "MICBIAS2",
- "IN2RN", "FM In",
- "IN2RP:VXRP", "FM In";
+ "IN2RN", "FM In",
+ "IN2RP:VXRP", "FM In";
};
&submic_bias_reg {
diff --git a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi
index 7daf25865551..3d5aace668dc 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi
@@ -137,21 +137,21 @@
key-down {
gpios = <&gpx3 3 GPIO_ACTIVE_LOW>;
- linux,code = <114>;
+ linux,code = <KEY_VOLUMEDOWN>;
label = "volume down";
debounce-interval = <10>;
};
key-up {
gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
- linux,code = <115>;
+ linux,code = <KEY_VOLUMEUP>;
label = "volume up";
debounce-interval = <10>;
};
key-power {
gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
- linux,code = <116>;
+ linux,code = <KEY_POWER>;
label = "power";
debounce-interval = <10>;
wakeup-source;
@@ -159,7 +159,7 @@
key-ok {
gpios = <&gpx0 1 GPIO_ACTIVE_LOW>;
- linux,code = <139>;
+ linux,code = <KEY_OK>;
label = "ok";
debounce-interval = <10>;
wakeup-source;
diff --git a/arch/arm/boot/dts/samsung/exynos4412-n710x.dts b/arch/arm/boot/dts/samsung/exynos4412-n710x.dts
index 9ae05b0d684c..0a151437fc73 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-n710x.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-n710x.dts
@@ -76,34 +76,33 @@
};
&sound {
- samsung,audio-routing =
- "HP", "HPOUT1L",
- "HP", "HPOUT1R",
+ audio-routing = "HP", "HPOUT1L",
+ "HP", "HPOUT1R",
- "SPK", "SPKOUTLN",
- "SPK", "SPKOUTLP",
+ "SPK", "SPKOUTLN",
+ "SPK", "SPKOUTLP",
- "RCV", "HPOUT2N",
- "RCV", "HPOUT2P",
+ "RCV", "HPOUT2N",
+ "RCV", "HPOUT2P",
- "HDMI", "LINEOUT1N",
- "HDMI", "LINEOUT1P",
+ "HDMI", "LINEOUT1N",
+ "HDMI", "LINEOUT1P",
- "LINE", "LINEOUT2N",
- "LINE", "LINEOUT2P",
+ "LINE", "LINEOUT2N",
+ "LINE", "LINEOUT2P",
- "IN1LP", "MICBIAS2",
- "IN1LN", "MICBIAS2",
- "Headset Mic", "MICBIAS2",
+ "IN1LP", "MICBIAS2",
+ "IN1LN", "MICBIAS2",
+ "Headset Mic", "MICBIAS2",
- "IN1RP", "Sub Mic",
- "IN1RN", "Sub Mic",
+ "IN1RP", "Sub Mic",
+ "IN1RN", "Sub Mic",
- "IN2LP:VXRN", "Main Mic",
- "IN2LN", "Main Mic",
+ "IN2LP:VXRN", "Main Mic",
+ "IN2LN", "Main Mic",
- "IN2RN", "FM In",
- "IN2RP:VXRP", "FM In";
+ "IN2RN", "FM In",
+ "IN2RP:VXRP", "FM In";
};
&submic_bias_reg {
diff --git a/arch/arm/boot/dts/samsung/exynos4412-odroidu3.dts b/arch/arm/boot/dts/samsung/exynos4412-odroidu3.dts
index 42812da1f882..b1b0916b1505 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-odroidu3.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-odroidu3.dts
@@ -138,13 +138,12 @@
samsung,audio-widgets =
"Headphone", "Headphone Jack",
"Speakers", "Speakers";
- samsung,audio-routing =
- "Headphone Jack", "HPL",
- "Headphone Jack", "HPR",
- "Headphone Jack", "MICBIAS",
- "IN1", "Headphone Jack",
- "Speakers", "SPKL",
- "Speakers", "SPKR";
+ audio-routing = "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "Headphone Jack", "MICBIAS",
+ "IN1", "Headphone Jack",
+ "Speakers", "SPKL",
+ "Speakers", "SPKR";
};
&spi_1 {
diff --git a/arch/arm/boot/dts/samsung/exynos4412-odroidx.dts b/arch/arm/boot/dts/samsung/exynos4412-odroidx.dts
index d5316cf2fbb6..0eb8a2680a20 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-odroidx.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-odroidx.dts
@@ -135,9 +135,8 @@
"Headphone", "Headphone Jack",
"Microphone", "Mic Jack",
"Microphone", "DMIC";
- samsung,audio-routing =
- "Headphone Jack", "HPL",
- "Headphone Jack", "HPR",
- "IN1", "Mic Jack",
- "Mic Jack", "MICBIAS";
+ audio-routing = "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "IN1", "Mic Jack",
+ "Mic Jack", "MICBIAS";
};
diff --git a/arch/arm/boot/dts/samsung/exynos5422-odroidxu3-audio.dtsi b/arch/arm/boot/dts/samsung/exynos5422-odroidxu3-audio.dtsi
index 86b96f9706db..52a1d8fd5452 100644
--- a/arch/arm/boot/dts/samsung/exynos5422-odroidxu3-audio.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos5422-odroidxu3-audio.dtsi
@@ -18,16 +18,15 @@
samsung,audio-widgets =
"Headphone", "Headphone Jack",
"Speakers", "Speakers";
- samsung,audio-routing =
- "Headphone Jack", "HPL",
- "Headphone Jack", "HPR",
- "Headphone Jack", "MICBIAS",
- "IN12", "Headphone Jack",
- "Speakers", "SPKL",
- "Speakers", "SPKR",
- "I2S Playback", "Mixer DAI TX",
- "HiFi Playback", "Mixer DAI TX",
- "Mixer DAI RX", "HiFi Capture";
+ audio-routing = "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "Headphone Jack", "MICBIAS",
+ "IN12", "Headphone Jack",
+ "Speakers", "SPKL",
+ "Speakers", "SPKR",
+ "I2S Playback", "Mixer DAI TX",
+ "HiFi Playback", "Mixer DAI TX",
+ "Mixer DAI RX", "HiFi Capture";
cpu {
sound-dai = <&i2s0 0>, <&i2s0 1>;
diff --git a/arch/arm/boot/dts/samsung/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/samsung/exynos5422-odroidxu4.dts
index f5fb617f46bd..363786f032cc 100644
--- a/arch/arm/boot/dts/samsung/exynos5422-odroidxu4.dts
+++ b/arch/arm/boot/dts/samsung/exynos5422-odroidxu4.dts
@@ -35,7 +35,7 @@
compatible = "samsung,odroid-xu3-audio";
model = "Odroid-XU4";
- samsung,audio-routing = "I2S Playback", "Mixer DAI TX";
+ audio-routing = "I2S Playback", "Mixer DAI TX";
cpu {
sound-dai = <&i2s0 0>, <&i2s0 1>;
diff --git a/arch/arm/boot/dts/samsung/s5pv210-fascinate4g.dts b/arch/arm/boot/dts/samsung/s5pv210-fascinate4g.dts
index eaa7c4f0e257..149e488f8e74 100644
--- a/arch/arm/boot/dts/samsung/s5pv210-fascinate4g.dts
+++ b/arch/arm/boot/dts/samsung/s5pv210-fascinate4g.dts
@@ -74,30 +74,29 @@
headset-detect-gpios = <&gph0 6 GPIO_ACTIVE_HIGH>;
headset-key-gpios = <&gph3 6 GPIO_ACTIVE_HIGH>;
- samsung,audio-routing =
- "HP", "HPOUT1L",
- "HP", "HPOUT1R",
+ audio-routing = "HP", "HPOUT1L",
+ "HP", "HPOUT1R",
- "SPK", "SPKOUTLN",
- "SPK", "SPKOUTLP",
+ "SPK", "SPKOUTLN",
+ "SPK", "SPKOUTLP",
- "RCV", "HPOUT2N",
- "RCV", "HPOUT2P",
+ "RCV", "HPOUT2N",
+ "RCV", "HPOUT2P",
- "LINE", "LINEOUT2N",
- "LINE", "LINEOUT2P",
+ "LINE", "LINEOUT2N",
+ "LINE", "LINEOUT2P",
- "IN1LP", "Main Mic",
- "IN1LN", "Main Mic",
+ "IN1LP", "Main Mic",
+ "IN1LN", "Main Mic",
- "IN1RP", "Headset Mic",
- "IN1RN", "Headset Mic",
+ "IN1RP", "Headset Mic",
+ "IN1RN", "Headset Mic",
- "Modem Out", "Modem TX",
- "Modem RX", "Modem In",
+ "Modem Out", "Modem TX",
+ "Modem RX", "Modem In",
- "Bluetooth SPK", "TX",
- "RX", "Bluetooth Mic";
+ "Bluetooth SPK", "TX",
+ "RX", "Bluetooth Mic";
pinctrl-names = "default";
pinctrl-0 = <&headset_det &earpath_sel>;
diff --git a/arch/arm/boot/dts/samsung/s5pv210-galaxys.dts b/arch/arm/boot/dts/samsung/s5pv210-galaxys.dts
index 532d3f5bceb1..879294412381 100644
--- a/arch/arm/boot/dts/samsung/s5pv210-galaxys.dts
+++ b/arch/arm/boot/dts/samsung/s5pv210-galaxys.dts
@@ -101,33 +101,32 @@
headset-detect-gpios = <&gph0 6 GPIO_ACTIVE_LOW>;
headset-key-gpios = <&gph3 6 GPIO_ACTIVE_HIGH>;
- samsung,audio-routing =
- "HP", "HPOUT1L",
- "HP", "HPOUT1R",
+ audio-routing = "HP", "HPOUT1L",
+ "HP", "HPOUT1R",
- "SPK", "SPKOUTLN",
- "SPK", "SPKOUTLP",
+ "SPK", "SPKOUTLN",
+ "SPK", "SPKOUTLP",
- "RCV", "HPOUT2N",
- "RCV", "HPOUT2P",
+ "RCV", "HPOUT2N",
+ "RCV", "HPOUT2P",
- "LINE", "LINEOUT2N",
- "LINE", "LINEOUT2P",
+ "LINE", "LINEOUT2N",
+ "LINE", "LINEOUT2P",
- "IN1LP", "Main Mic",
- "IN1LN", "Main Mic",
+ "IN1LP", "Main Mic",
+ "IN1LN", "Main Mic",
- "IN1RP", "Headset Mic",
- "IN1RN", "Headset Mic",
+ "IN1RP", "Headset Mic",
+ "IN1RN", "Headset Mic",
- "IN2LN", "FM In",
- "IN2RN", "FM In",
+ "IN2LN", "FM In",
+ "IN2RN", "FM In",
- "Modem Out", "Modem TX",
- "Modem RX", "Modem In",
+ "Modem Out", "Modem TX",
+ "Modem RX", "Modem In",
- "Bluetooth SPK", "TX",
- "RX", "Bluetooth Mic";
+ "Bluetooth SPK", "TX",
+ "RX", "Bluetooth Mic";
pinctrl-names = "default";
pinctrl-0 = <&headset_det &earpath_sel>;
diff --git a/arch/arm/boot/dts/st/Makefile b/arch/arm/boot/dts/st/Makefile
index 44b264c399ec..7892ad69b441 100644
--- a/arch/arm/boot/dts/st/Makefile
+++ b/arch/arm/boot/dts/st/Makefile
@@ -59,6 +59,7 @@ dtb-$(CONFIG_ARCH_STM32) += \
stm32mp157c-lxa-tac-gen1.dtb \
stm32mp157c-lxa-tac-gen2.dtb \
stm32mp157c-odyssey.dtb \
+ stm32mp157c-osd32mp1-red.dtb \
stm32mp157c-phycore-stm32mp1-3.dtb
dtb-$(CONFIG_ARCH_U8500) += \
ste-snowball.dtb \
diff --git a/arch/arm/boot/dts/st/spear1310-evb.dts b/arch/arm/boot/dts/st/spear1310-evb.dts
index 05408df38203..18191a87f07c 100644
--- a/arch/arm/boot/dts/st/spear1310-evb.dts
+++ b/arch/arm/boot/dts/st/spear1310-evb.dts
@@ -352,7 +352,6 @@
#size-cells = <0>;
spi-max-frequency = <1000000>;
spi-cpha;
- pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,slave-tx-disable;
pl022,com-mode = <0>;
@@ -385,7 +384,6 @@
spi-max-frequency = <12000000>;
spi-cpol;
spi-cpha;
- pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,slave-tx-disable;
pl022,com-mode = <0x2>;
diff --git a/arch/arm/boot/dts/st/spear1340-evb.dts b/arch/arm/boot/dts/st/spear1340-evb.dts
index 7700f2afc128..cea624fc745c 100644
--- a/arch/arm/boot/dts/st/spear1340-evb.dts
+++ b/arch/arm/boot/dts/st/spear1340-evb.dts
@@ -445,7 +445,6 @@
spi-max-frequency = <12000000>;
spi-cpol;
spi-cpha;
- pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,slave-tx-disable;
pl022,com-mode = <0x2>;
@@ -461,7 +460,6 @@
spi-max-frequency = <1000000>;
spi-cpha;
reg = <1>;
- pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,slave-tx-disable;
pl022,com-mode = <0>;
diff --git a/arch/arm/boot/dts/st/ste-href-tvk1281618-r2.dtsi b/arch/arm/boot/dts/st/ste-href-tvk1281618-r2.dtsi
index 37e59403c01f..7448135e25f6 100644
--- a/arch/arm/boot/dts/st/ste-href-tvk1281618-r2.dtsi
+++ b/arch/arm/boot/dts/st/ste-href-tvk1281618-r2.dtsi
@@ -192,7 +192,7 @@
#size-cells = <0>;
reg = <0x4b>;
vdd-supply = <&ab8500_ldo_aux1_reg>;
- vddio-supply = <&db8500_vsmps2_reg>;
+ vio-supply = <&db8500_vsmps2_reg>;
pinctrl-names = "default";
pinctrl-0 = <&synaptics_tvk_mode>;
interrupt-parent = <&gpio2>;
@@ -200,7 +200,7 @@
rmi4-f01@1 {
reg = <0x1>;
- syna,nosleep = <1>;
+ syna,nosleep-mode = <1>;
};
rmi4-f11@11 {
reg = <0x11>;
diff --git a/arch/arm/boot/dts/st/stih407-family.dtsi b/arch/arm/boot/dts/st/stih407-family.dtsi
index 3f58383a7b59..29302e74aa1d 100644
--- a/arch/arm/boot/dts/st/stih407-family.dtsi
+++ b/arch/arm/boot/dts/st/stih407-family.dtsi
@@ -111,7 +111,6 @@
regulator-min-microvolt = <784000>;
regulator-max-microvolt = <1299000>;
regulator-always-on;
- max-duty-cycle = <255>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/st/stih418-b2264.dts b/arch/arm/boot/dts/st/stih418-b2264.dts
index fc32a03073b6..fdc16e9f5822 100644
--- a/arch/arm/boot/dts/st/stih418-b2264.dts
+++ b/arch/arm/boot/dts/st/stih418-b2264.dts
@@ -69,19 +69,19 @@
};
aliases {
- ttyAS0 = &sbc_serial0;
+ serial0 = &sbc_serial0;
ethernet0 = &ethernet0;
};
- soc {
- leds {
- compatible = "gpio-leds";
- led-green {
- gpios = <&pio1 3 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
+ leds {
+ compatible = "gpio-leds";
+ led-green {
+ gpios = <&pio1 3 GPIO_ACTIVE_LOW>;
+ default-state = "off";
};
+ };
+ soc {
pin-controller-sbc@961f080 {
gmac1 {
rgmii1-0 {
diff --git a/arch/arm/boot/dts/st/stm32746g-eval.dts b/arch/arm/boot/dts/st/stm32746g-eval.dts
index a293e65141c6..e9ac37b6eca0 100644
--- a/arch/arm/boot/dts/st/stm32746g-eval.dts
+++ b/arch/arm/boot/dts/st/stm32746g-eval.dts
@@ -188,9 +188,10 @@
status = "okay";
vmmc-supply = <&mmc_vcard>;
broken-cd;
- pinctrl-names = "default", "opendrain";
+ pinctrl-names = "default", "opendrain", "sleep";
pinctrl-0 = <&sdio_pins_a>;
pinctrl-1 = <&sdio_pins_od_a>;
+ pinctrl-2 = <&sdio_pins_sleep_a>;
bus-width = <4>;
};
diff --git a/arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi b/arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi
index 65480a9f5cc4..97fc3fb5a9ca 100644
--- a/arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi
@@ -263,6 +263,17 @@
};
};
+ sdio_pins_sleep_a: sdio-pins-sleep-a-0 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1 D0 */
+ <STM32_PINMUX('C', 9, ANALOG)>, /* SDMMC1 D1 */
+ <STM32_PINMUX('C', 10, ANALOG)>, /* SDMMC1 D2 */
+ <STM32_PINMUX('C', 11, ANALOG)>, /* SDMMC1 D3 */
+ <STM32_PINMUX('C', 12, ANALOG)>, /* SDMMC1 CLK */
+ <STM32_PINMUX('D', 2, ANALOG)>; /* SDMMC1 CMD */
+ };
+ };
+
sdio_pins_b: sdio-pins-b-0 {
pins {
pinmux = <STM32_PINMUX('G', 9, AF11)>, /* SDMMC2 D0 */
@@ -294,6 +305,17 @@
};
};
+ sdio_pins_sleep_b: sdio-pins-sleep-b-0 {
+ pins {
+ pinmux = <STM32_PINMUX('G', 9, ANALOG)>, /* SDMMC2 D0 */
+ <STM32_PINMUX('G', 10, ANALOG)>, /* SDMMC2 D1 */
+ <STM32_PINMUX('B', 3, ANALOG)>, /* SDMMC2 D2 */
+ <STM32_PINMUX('B', 4, ANALOG)>, /* SDMMC2 D3 */
+ <STM32_PINMUX('D', 6, ANALOG)>, /* SDMMC2 CLK */
+ <STM32_PINMUX('D', 7, ANALOG)>; /* SDMMC2 CMD */
+ };
+ };
+
can1_pins_a: can1-0 {
pins1 {
pinmux = <STM32_PINMUX('A', 12, AF9)>; /* CAN1_TX */
@@ -376,7 +398,6 @@
};
};
-
ltdc_pins_a: ltdc-0 {
pins {
pinmux = <STM32_PINMUX('E', 4, AF14)>, /* LCD_B0 */
diff --git a/arch/arm/boot/dts/st/stm32f746-disco.dts b/arch/arm/boot/dts/st/stm32f746-disco.dts
index 37e3a905fc3c..087de6f09629 100644
--- a/arch/arm/boot/dts/st/stm32f746-disco.dts
+++ b/arch/arm/boot/dts/st/stm32f746-disco.dts
@@ -164,9 +164,10 @@
status = "okay";
vmmc-supply = <&vcc_3v3>;
cd-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>;
- pinctrl-names = "default", "opendrain";
+ pinctrl-names = "default", "opendrain", "sleep";
pinctrl-0 = <&sdio_pins_a>;
pinctrl-1 = <&sdio_pins_od_a>;
+ pinctrl-2 = <&sdio_pins_sleep_a>;
bus-width = <4>;
};
diff --git a/arch/arm/boot/dts/st/stm32f769-disco.dts b/arch/arm/boot/dts/st/stm32f769-disco.dts
index b038d0ed39e8..5d12ae25b327 100644
--- a/arch/arm/boot/dts/st/stm32f769-disco.dts
+++ b/arch/arm/boot/dts/st/stm32f769-disco.dts
@@ -131,9 +131,10 @@
vmmc-supply = <&mmc_vcard>;
cd-gpios = <&gpioi 15 GPIO_ACTIVE_LOW>;
broken-cd;
- pinctrl-names = "default", "opendrain";
+ pinctrl-names = "default", "opendrain", "sleep";
pinctrl-0 = <&sdio_pins_b>;
pinctrl-1 = <&sdio_pins_od_b>;
+ pinctrl-2 = <&sdio_pins_sleep_b>;
bus-width = <4>;
};
diff --git a/arch/arm/boot/dts/st/stm32mp131.dtsi b/arch/arm/boot/dts/st/stm32mp131.dtsi
index ac90fcbf0c09..b04d24c939c3 100644
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -1210,6 +1210,25 @@
};
};
+ hash: hash@54003000 {
+ compatible = "st,stm32mp13-hash";
+ reg = <0x54003000 0x400>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc HASH1>;
+ resets = <&rcc HASH1_R>;
+ dmas = <&mdma 30 0x2 0x1000a02 0x0 0x0>;
+ dma-names = "in";
+ status = "disabled";
+ };
+
+ rng: rng@54004000 {
+ compatible = "st,stm32mp13-rng";
+ reg = <0x54004000 0x400>;
+ clocks = <&rcc RNG1_K>;
+ resets = <&rcc RNG1_R>;
+ status = "disabled";
+ };
+
mdma: dma-controller@58000000 {
compatible = "st,stm32h7-mdma";
reg = <0x58000000 0x1000>;
diff --git a/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi
index 098153ee99a3..ae83e7b10232 100644
--- a/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
&pinctrl {
+ /omit-if-no-ref/
adc1_ain_pins_a: adc1-ain-0 {
pins {
pinmux = <STM32_PINMUX('F', 11, ANALOG)>, /* ADC1_INP2 */
@@ -17,12 +18,14 @@
};
};
+ /omit-if-no-ref/
adc1_in6_pins_a: adc1-in6-0 {
pins {
pinmux = <STM32_PINMUX('F', 12, ANALOG)>;
};
};
+ /omit-if-no-ref/
adc12_ain_pins_a: adc12-ain-0 {
pins {
pinmux = <STM32_PINMUX('C', 3, ANALOG)>, /* ADC1 in13 */
@@ -32,6 +35,7 @@
};
};
+ /omit-if-no-ref/
adc12_ain_pins_b: adc12-ain-1 {
pins {
pinmux = <STM32_PINMUX('F', 12, ANALOG)>, /* ADC1 in6 */
@@ -39,6 +43,7 @@
};
};
+ /omit-if-no-ref/
adc12_usb_cc_pins_a: adc12-usb-cc-pins-0 {
pins {
pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* ADC12 in18 */
@@ -46,6 +51,7 @@
};
};
+ /omit-if-no-ref/
cec_pins_a: cec-0 {
pins {
pinmux = <STM32_PINMUX('A', 15, AF4)>;
@@ -55,12 +61,14 @@
};
};
+ /omit-if-no-ref/
cec_sleep_pins_a: cec-sleep-0 {
pins {
pinmux = <STM32_PINMUX('A', 15, ANALOG)>; /* HDMI_CEC */
};
};
+ /omit-if-no-ref/
cec_pins_b: cec-1 {
pins {
pinmux = <STM32_PINMUX('B', 6, AF5)>;
@@ -70,24 +78,28 @@
};
};
+ /omit-if-no-ref/
cec_sleep_pins_b: cec-sleep-1 {
pins {
pinmux = <STM32_PINMUX('B', 6, ANALOG)>; /* HDMI_CEC */
};
};
+ /omit-if-no-ref/
dac_ch1_pins_a: dac-ch1-0 {
pins {
pinmux = <STM32_PINMUX('A', 4, ANALOG)>;
};
};
+ /omit-if-no-ref/
dac_ch2_pins_a: dac-ch2-0 {
pins {
pinmux = <STM32_PINMUX('A', 5, ANALOG)>;
};
};
+ /omit-if-no-ref/
dcmi_pins_a: dcmi-0 {
pins {
pinmux = <STM32_PINMUX('H', 8, AF13)>,/* DCMI_HSYNC */
@@ -109,6 +121,7 @@
};
};
+ /omit-if-no-ref/
dcmi_sleep_pins_a: dcmi-sleep-0 {
pins {
pinmux = <STM32_PINMUX('H', 8, ANALOG)>,/* DCMI_HSYNC */
@@ -129,6 +142,7 @@
};
};
+ /omit-if-no-ref/
dcmi_pins_b: dcmi-1 {
pins {
pinmux = <STM32_PINMUX('A', 4, AF13)>,/* DCMI_HSYNC */
@@ -146,6 +160,7 @@
};
};
+ /omit-if-no-ref/
dcmi_sleep_pins_b: dcmi-sleep-1 {
pins {
pinmux = <STM32_PINMUX('A', 4, ANALOG)>,/* DCMI_HSYNC */
@@ -162,6 +177,7 @@
};
};
+ /omit-if-no-ref/
dcmi_pins_c: dcmi-2 {
pins {
pinmux = <STM32_PINMUX('A', 4, AF13)>,/* DCMI_HSYNC */
@@ -181,6 +197,7 @@
};
};
+ /omit-if-no-ref/
dcmi_sleep_pins_c: dcmi-sleep-2 {
pins {
pinmux = <STM32_PINMUX('A', 4, ANALOG)>,/* DCMI_HSYNC */
@@ -199,6 +216,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_pins_a: rgmii-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
@@ -230,6 +248,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_sleep_pins_a: rgmii-sleep-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
@@ -250,6 +269,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_pins_b: rgmii-1 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
@@ -281,6 +301,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_sleep_pins_b: rgmii-sleep-1 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
@@ -301,6 +322,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_pins_c: rgmii-2 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
@@ -332,6 +354,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_sleep_pins_c: rgmii-sleep-2 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
@@ -352,6 +375,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_pins_d: rgmii-3 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
@@ -382,6 +406,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_sleep_pins_d: rgmii-sleep-3 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
@@ -402,6 +427,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_pins_e: rgmii-4 {
pins1 {
pinmux = <STM32_PINMUX('G', 4, AF11)>, /* ETH_RGMII_GTX_CLK */
@@ -425,6 +451,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rgmii_sleep_pins_e: rgmii-sleep-4 {
pins1 {
pinmux = <STM32_PINMUX('G', 4, ANALOG)>, /* ETH_RGMII_GTX_CLK */
@@ -442,6 +469,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rmii_pins_a: rmii-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH1_RMII_TXD0 */
@@ -462,6 +490,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rmii_sleep_pins_a: rmii-sleep-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH1_RMII_TXD0 */
@@ -476,6 +505,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rmii_pins_b: rmii-1 {
pins1 {
pinmux = <STM32_PINMUX('B', 5, AF0)>, /* ETH1_CLK */
@@ -503,6 +533,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rmii_sleep_pins_b: rmii-sleep-1 {
pins1 {
pinmux = <STM32_PINMUX('A', 2, ANALOG)>, /* ETH1_MDIO */
@@ -517,6 +548,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rmii_pins_c: rmii-2 {
pins1 {
pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH1_RMII_TXD0 */
@@ -537,6 +569,7 @@
};
};
+ /omit-if-no-ref/
ethernet0_rmii_sleep_pins_c: rmii-sleep-2 {
pins1 {
pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH1_RMII_TXD0 */
@@ -551,6 +584,7 @@
};
};
+ /omit-if-no-ref/
fmc_pins_a: fmc-0 {
pins1 {
pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
@@ -576,6 +610,7 @@
};
};
+ /omit-if-no-ref/
fmc_sleep_pins_a: fmc-sleep-0 {
pins {
pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* FMC_NOE */
@@ -595,6 +630,7 @@
};
};
+ /omit-if-no-ref/
fmc_pins_b: fmc-1 {
pins {
pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
@@ -624,6 +660,7 @@
};
};
+ /omit-if-no-ref/
fmc_sleep_pins_b: fmc-sleep-1 {
pins {
pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* FMC_NOE */
@@ -650,6 +687,7 @@
};
};
+ /omit-if-no-ref/
i2c1_pins_a: i2c1-0 {
pins {
pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
@@ -660,6 +698,7 @@
};
};
+ /omit-if-no-ref/
i2c1_sleep_pins_a: i2c1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('D', 12, ANALOG)>, /* I2C1_SCL */
@@ -667,6 +706,7 @@
};
};
+ /omit-if-no-ref/
i2c1_pins_b: i2c1-1 {
pins {
pinmux = <STM32_PINMUX('F', 14, AF5)>, /* I2C1_SCL */
@@ -677,6 +717,7 @@
};
};
+ /omit-if-no-ref/
i2c1_sleep_pins_b: i2c1-sleep-1 {
pins {
pinmux = <STM32_PINMUX('F', 14, ANALOG)>, /* I2C1_SCL */
@@ -684,6 +725,7 @@
};
};
+ /omit-if-no-ref/
i2c2_pins_a: i2c2-0 {
pins {
pinmux = <STM32_PINMUX('H', 4, AF4)>, /* I2C2_SCL */
@@ -694,6 +736,7 @@
};
};
+ /omit-if-no-ref/
i2c2_sleep_pins_a: i2c2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('H', 4, ANALOG)>, /* I2C2_SCL */
@@ -701,6 +744,7 @@
};
};
+ /omit-if-no-ref/
i2c2_pins_b1: i2c2-1 {
pins {
pinmux = <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
@@ -710,12 +754,14 @@
};
};
+ /omit-if-no-ref/
i2c2_sleep_pins_b1: i2c2-sleep-1 {
pins {
pinmux = <STM32_PINMUX('H', 5, ANALOG)>; /* I2C2_SDA */
};
};
+ /omit-if-no-ref/
i2c2_pins_c: i2c2-2 {
pins {
pinmux = <STM32_PINMUX('F', 1, AF4)>, /* I2C2_SCL */
@@ -726,6 +772,7 @@
};
};
+ /omit-if-no-ref/
i2c2_pins_sleep_c: i2c2-sleep-2 {
pins {
pinmux = <STM32_PINMUX('F', 1, ANALOG)>, /* I2C2_SCL */
@@ -733,6 +780,7 @@
};
};
+ /omit-if-no-ref/
i2c5_pins_a: i2c5-0 {
pins {
pinmux = <STM32_PINMUX('A', 11, AF4)>, /* I2C5_SCL */
@@ -743,6 +791,7 @@
};
};
+ /omit-if-no-ref/
i2c5_sleep_pins_a: i2c5-sleep-0 {
pins {
pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* I2C5_SCL */
@@ -751,6 +800,7 @@
};
};
+ /omit-if-no-ref/
i2c5_pins_b: i2c5-1 {
pins {
pinmux = <STM32_PINMUX('D', 0, AF4)>, /* I2C5_SCL */
@@ -761,6 +811,7 @@
};
};
+ /omit-if-no-ref/
i2c5_sleep_pins_b: i2c5-sleep-1 {
pins {
pinmux = <STM32_PINMUX('D', 0, ANALOG)>, /* I2C5_SCL */
@@ -768,6 +819,7 @@
};
};
+ /omit-if-no-ref/
i2s2_pins_a: i2s2-0 {
pins {
pinmux = <STM32_PINMUX('I', 3, AF5)>, /* I2S2_SDO */
@@ -779,6 +831,7 @@
};
};
+ /omit-if-no-ref/
i2s2_sleep_pins_a: i2s2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('I', 3, ANALOG)>, /* I2S2_SDO */
@@ -787,6 +840,28 @@
};
};
+ /omit-if-no-ref/
+ i2s2_pins_b: i2s2-1 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 3, AF5)>, /* I2S2_SDO */
+ <STM32_PINMUX('B', 12, AF5)>, /* I2S2_WS */
+ <STM32_PINMUX('B', 13, AF5)>; /* I2S2_CK */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ };
+
+ /omit-if-no-ref/
+ i2s2_sleep_pins_b: i2s2-sleep-1 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 3, ANALOG)>, /* I2S2_SDO */
+ <STM32_PINMUX('B', 12, ANALOG)>, /* I2S2_WS */
+ <STM32_PINMUX('B', 13, ANALOG)>; /* I2S2_CK */
+ };
+ };
+
+ /omit-if-no-ref/
ltdc_pins_a: ltdc-0 {
pins {
pinmux = <STM32_PINMUX('G', 7, AF14)>, /* LCD_CLK */
@@ -823,6 +898,7 @@
};
};
+ /omit-if-no-ref/
ltdc_sleep_pins_a: ltdc-sleep-0 {
pins {
pinmux = <STM32_PINMUX('G', 7, ANALOG)>, /* LCD_CLK */
@@ -856,6 +932,7 @@
};
};
+ /omit-if-no-ref/
ltdc_pins_b: ltdc-1 {
pins {
pinmux = <STM32_PINMUX('I', 14, AF14)>, /* LCD_CLK */
@@ -892,6 +969,7 @@
};
};
+ /omit-if-no-ref/
ltdc_sleep_pins_b: ltdc-sleep-1 {
pins {
pinmux = <STM32_PINMUX('I', 14, ANALOG)>, /* LCD_CLK */
@@ -925,6 +1003,7 @@
};
};
+ /omit-if-no-ref/
ltdc_pins_c: ltdc-2 {
pins1 {
pinmux = <STM32_PINMUX('B', 1, AF9)>, /* LTDC_R6 */
@@ -960,6 +1039,7 @@
};
};
+ /omit-if-no-ref/
ltdc_sleep_pins_c: ltdc-sleep-2 {
pins1 {
pinmux = <STM32_PINMUX('B', 1, ANALOG)>, /* LTDC_R6 */
@@ -987,6 +1067,7 @@
};
};
+ /omit-if-no-ref/
ltdc_pins_d: ltdc-3 {
pins1 {
pinmux = <STM32_PINMUX('G', 7, AF14)>; /* LCD_CLK */
@@ -1028,6 +1109,7 @@
};
};
+ /omit-if-no-ref/
ltdc_sleep_pins_d: ltdc-sleep-3 {
pins {
pinmux = <STM32_PINMUX('G', 7, ANALOG)>, /* LCD_CLK */
@@ -1061,6 +1143,84 @@
};
};
+ /omit-if-no-ref/
+ ltdc_pins_e: ltdc-4 {
+ pins1 {
+ pinmux = <STM32_PINMUX('H', 2, AF14)>, /* LTDC_R0 */
+ <STM32_PINMUX('H', 3, AF14)>, /* LTDC_R1 */
+ <STM32_PINMUX('H', 8, AF14)>, /* LTDC_R2 */
+ <STM32_PINMUX('H', 9, AF14)>, /* LTDC_R3 */
+ <STM32_PINMUX('H', 10, AF14)>, /* LTDC_R4 */
+ <STM32_PINMUX('C', 0, AF14)>, /* LTDC_R5 */
+ <STM32_PINMUX('H', 12, AF14)>, /* LTDC_R6 */
+ <STM32_PINMUX('E', 15, AF14)>, /* LTDC_R7 */
+ <STM32_PINMUX('E', 14, AF13)>, /* LTDC_G0 */
+ <STM32_PINMUX('E', 6, AF14)>, /* LTDC_G1 */
+ <STM32_PINMUX('H', 13, AF14)>, /* LTDC_G2 */
+ <STM32_PINMUX('H', 14, AF14)>, /* LTDC_G3 */
+ <STM32_PINMUX('H', 4, AF14)>, /* LTDC_G4 */
+ <STM32_PINMUX('I', 0, AF14)>, /* LTDC_G5 */
+ <STM32_PINMUX('I', 1, AF14)>, /* LTDC_G6 */
+ <STM32_PINMUX('I', 2, AF14)>, /* LTDC_G7 */
+ <STM32_PINMUX('D', 9, AF14)>, /* LTDC_B0 */
+ <STM32_PINMUX('G', 12, AF14)>, /* LTDC_B1 */
+ <STM32_PINMUX('G', 10, AF14)>, /* LTDC_B2 */
+ <STM32_PINMUX('D', 10, AF14)>, /* LTDC_B3 */
+ <STM32_PINMUX('E', 12, AF14)>, /* LTDC_B4 */
+ <STM32_PINMUX('A', 3, AF14)>, /* LTDC_B5 */
+ <STM32_PINMUX('B', 8, AF14)>, /* LTDC_B6 */
+ <STM32_PINMUX('D', 8, AF14)>, /* LTDC_B7 */
+ <STM32_PINMUX('F', 10, AF14)>, /* LTDC_DE */
+ <STM32_PINMUX('I', 9, AF14)>, /* LTDC_VSYNC */
+ <STM32_PINMUX('I', 10, AF14)>; /* LTDC_HSYNC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('G', 7, AF14)>; /* LTDC_CLK */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ };
+
+ /omit-if-no-ref/
+ ltdc_sleep_pins_e: ltdc-sleep-4 {
+ pins {
+ pinmux = <STM32_PINMUX('H', 2, ANALOG)>, /* LTDC_R0 */
+ <STM32_PINMUX('H', 3, ANALOG)>, /* LTDC_R1 */
+ <STM32_PINMUX('H', 8, ANALOG)>, /* LTDC_R2 */
+ <STM32_PINMUX('H', 9, ANALOG)>, /* LTDC_R3 */
+ <STM32_PINMUX('H', 10, ANALOG)>, /* LTDC_R4 */
+ <STM32_PINMUX('C', 0, ANALOG)>, /* LTDC_R5 */
+ <STM32_PINMUX('H', 12, ANALOG)>, /* LTDC_R6 */
+ <STM32_PINMUX('E', 15, ANALOG)>, /* LTDC_R7 */
+ <STM32_PINMUX('D', 9, ANALOG)>, /* LTDC_B0 */
+ <STM32_PINMUX('G', 12, ANALOG)>, /* LTDC_B1 */
+ <STM32_PINMUX('G', 10, ANALOG)>, /* LTDC_B2 */
+ <STM32_PINMUX('D', 10, ANALOG)>, /* LTDC_B3 */
+ <STM32_PINMUX('E', 12, ANALOG)>, /* LTDC_B4 */
+ <STM32_PINMUX('A', 3, ANALOG)>, /* LTDC_B5 */
+ <STM32_PINMUX('B', 8, ANALOG)>, /* LTDC_B6 */
+ <STM32_PINMUX('D', 8, ANALOG)>, /* LTDC_B7 */
+ <STM32_PINMUX('E', 14, ANALOG)>, /* LTDC_G0 */
+ <STM32_PINMUX('E', 6, ANALOG)>, /* LTDC_G1 */
+ <STM32_PINMUX('H', 13, ANALOG)>, /* LTDC_G2 */
+ <STM32_PINMUX('H', 14, ANALOG)>, /* LTDC_G3 */
+ <STM32_PINMUX('H', 4, ANALOG)>, /* LTDC_G4 */
+ <STM32_PINMUX('I', 0, ANALOG)>, /* LTDC_G5 */
+ <STM32_PINMUX('I', 1, ANALOG)>, /* LTDC_G6 */
+ <STM32_PINMUX('I', 2, ANALOG)>, /* LTDC_G7 */
+ <STM32_PINMUX('F', 10, ANALOG)>, /* LTDC_DE */
+ <STM32_PINMUX('I', 9, ANALOG)>, /* LTDC_VSYNC */
+ <STM32_PINMUX('I', 10, ANALOG)>, /* LTDC_HSYNC */
+ <STM32_PINMUX('G', 7, ANALOG)>; /* LTDC_CLK */
+ };
+ };
+
+ /omit-if-no-ref/
mco1_pins_a: mco1-0 {
pins {
pinmux = <STM32_PINMUX('A', 13, AF2)>; /* MCO1 */
@@ -1070,12 +1230,14 @@
};
};
+ /omit-if-no-ref/
mco1_sleep_pins_a: mco1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('A', 13, ANALOG)>; /* MCO1 */
};
};
+ /omit-if-no-ref/
mco2_pins_a: mco2-0 {
pins {
pinmux = <STM32_PINMUX('G', 2, AF1)>; /* MCO2 */
@@ -1085,12 +1247,14 @@
};
};
+ /omit-if-no-ref/
mco2_sleep_pins_a: mco2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('G', 2, ANALOG)>; /* MCO2 */
};
};
+ /omit-if-no-ref/
m_can1_pins_a: m-can1-0 {
pins1 {
pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
@@ -1104,6 +1268,7 @@
};
};
+ /omit-if-no-ref/
m_can1_sleep_pins_a: m_can1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('H', 13, ANALOG)>, /* CAN1_TX */
@@ -1111,6 +1276,7 @@
};
};
+ /omit-if-no-ref/
m_can1_pins_b: m-can1-1 {
pins1 {
pinmux = <STM32_PINMUX('A', 12, AF9)>; /* CAN1_TX */
@@ -1124,6 +1290,7 @@
};
};
+ /omit-if-no-ref/
m_can1_sleep_pins_b: m_can1-sleep-1 {
pins {
pinmux = <STM32_PINMUX('A', 12, ANALOG)>, /* CAN1_TX */
@@ -1131,6 +1298,7 @@
};
};
+ /omit-if-no-ref/
m_can1_pins_c: m-can1-2 {
pins1 {
pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
@@ -1144,6 +1312,7 @@
};
};
+ /omit-if-no-ref/
m_can1_sleep_pins_c: m_can1-sleep-2 {
pins {
pinmux = <STM32_PINMUX('H', 13, ANALOG)>, /* CAN1_TX */
@@ -1151,6 +1320,29 @@
};
};
+ /omit-if-no-ref/
+ m_can1_pins_d: m-can1-3 {
+ pins1 {
+ pinmux = <STM32_PINMUX('D', 1, AF9)>; /* CAN1_TX */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-disable;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 0, AF9)>; /* CAN1_RX */
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
+ m_can1_sleep_pins_d: m_can1-sleep-3 {
+ pins {
+ pinmux = <STM32_PINMUX('D', 1, ANALOG)>, /* CAN1_TX */
+ <STM32_PINMUX('D', 0, ANALOG)>; /* CAN1_RX */
+ };
+ };
+
+ /omit-if-no-ref/
m_can2_pins_a: m-can2-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 13, AF9)>; /* CAN2_TX */
@@ -1164,6 +1356,7 @@
};
};
+ /omit-if-no-ref/
m_can2_sleep_pins_a: m_can2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('B', 13, ANALOG)>, /* CAN2_TX */
@@ -1171,6 +1364,7 @@
};
};
+ /omit-if-no-ref/
pwm1_pins_a: pwm1-0 {
pins {
pinmux = <STM32_PINMUX('E', 9, AF1)>, /* TIM1_CH1 */
@@ -1182,6 +1376,7 @@
};
};
+ /omit-if-no-ref/
pwm1_sleep_pins_a: pwm1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('E', 9, ANALOG)>, /* TIM1_CH1 */
@@ -1190,6 +1385,7 @@
};
};
+ /omit-if-no-ref/
pwm1_pins_b: pwm1-1 {
pins {
pinmux = <STM32_PINMUX('E', 9, AF1)>; /* TIM1_CH1 */
@@ -1199,12 +1395,14 @@
};
};
+ /omit-if-no-ref/
pwm1_sleep_pins_b: pwm1-sleep-1 {
pins {
pinmux = <STM32_PINMUX('E', 9, ANALOG)>; /* TIM1_CH1 */
};
};
+ /omit-if-no-ref/
pwm1_pins_c: pwm1-2 {
pins {
pinmux = <STM32_PINMUX('E', 11, AF1)>; /* TIM1_CH2 */
@@ -1213,12 +1411,14 @@
};
};
+ /omit-if-no-ref/
pwm1_sleep_pins_c: pwm1-sleep-2 {
pins {
pinmux = <STM32_PINMUX('E', 11, ANALOG)>; /* TIM1_CH2 */
};
};
+ /omit-if-no-ref/
pwm2_pins_a: pwm2-0 {
pins {
pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */
@@ -1228,12 +1428,14 @@
};
};
+ /omit-if-no-ref/
pwm2_sleep_pins_a: pwm2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('A', 3, ANALOG)>; /* TIM2_CH4 */
};
};
+ /omit-if-no-ref/
pwm3_pins_a: pwm3-0 {
pins {
pinmux = <STM32_PINMUX('C', 7, AF2)>; /* TIM3_CH2 */
@@ -1243,12 +1445,14 @@
};
};
+ /omit-if-no-ref/
pwm3_sleep_pins_a: pwm3-sleep-0 {
pins {
pinmux = <STM32_PINMUX('C', 7, ANALOG)>; /* TIM3_CH2 */
};
};
+ /omit-if-no-ref/
pwm3_pins_b: pwm3-1 {
pins {
pinmux = <STM32_PINMUX('B', 5, AF2)>; /* TIM3_CH2 */
@@ -1258,12 +1462,14 @@
};
};
+ /omit-if-no-ref/
pwm3_sleep_pins_b: pwm3-sleep-1 {
pins {
pinmux = <STM32_PINMUX('B', 5, ANALOG)>; /* TIM3_CH2 */
};
};
+ /omit-if-no-ref/
pwm4_pins_a: pwm4-0 {
pins {
pinmux = <STM32_PINMUX('D', 14, AF2)>, /* TIM4_CH3 */
@@ -1274,6 +1480,7 @@
};
};
+ /omit-if-no-ref/
pwm4_sleep_pins_a: pwm4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('D', 14, ANALOG)>, /* TIM4_CH3 */
@@ -1281,6 +1488,7 @@
};
};
+ /omit-if-no-ref/
pwm4_pins_b: pwm4-1 {
pins {
pinmux = <STM32_PINMUX('D', 13, AF2)>; /* TIM4_CH2 */
@@ -1290,12 +1498,14 @@
};
};
+ /omit-if-no-ref/
pwm4_sleep_pins_b: pwm4-sleep-1 {
pins {
pinmux = <STM32_PINMUX('D', 13, ANALOG)>; /* TIM4_CH2 */
};
};
+ /omit-if-no-ref/
pwm5_pins_a: pwm5-0 {
pins {
pinmux = <STM32_PINMUX('H', 11, AF2)>; /* TIM5_CH2 */
@@ -1305,12 +1515,14 @@
};
};
+ /omit-if-no-ref/
pwm5_sleep_pins_a: pwm5-sleep-0 {
pins {
pinmux = <STM32_PINMUX('H', 11, ANALOG)>; /* TIM5_CH2 */
};
};
+ /omit-if-no-ref/
pwm5_pins_b: pwm5-1 {
pins {
pinmux = <STM32_PINMUX('H', 11, AF2)>, /* TIM5_CH2 */
@@ -1322,6 +1534,7 @@
};
};
+ /omit-if-no-ref/
pwm5_sleep_pins_b: pwm5-sleep-1 {
pins {
pinmux = <STM32_PINMUX('H', 11, ANALOG)>, /* TIM5_CH2 */
@@ -1330,6 +1543,7 @@
};
};
+ /omit-if-no-ref/
pwm8_pins_a: pwm8-0 {
pins {
pinmux = <STM32_PINMUX('I', 2, AF3)>; /* TIM8_CH4 */
@@ -1339,12 +1553,14 @@
};
};
+ /omit-if-no-ref/
pwm8_sleep_pins_a: pwm8-sleep-0 {
pins {
pinmux = <STM32_PINMUX('I', 2, ANALOG)>; /* TIM8_CH4 */
};
};
+ /omit-if-no-ref/
pwm8_pins_b: pwm8-1 {
pins {
pinmux = <STM32_PINMUX('I', 5, AF3)>, /* TIM8_CH1 */
@@ -1356,6 +1572,7 @@
};
};
+ /omit-if-no-ref/
pwm8_sleep_pins_b: pwm8-sleep-1 {
pins {
pinmux = <STM32_PINMUX('I', 5, ANALOG)>, /* TIM8_CH1 */
@@ -1365,6 +1582,7 @@
};
};
+ /omit-if-no-ref/
pwm12_pins_a: pwm12-0 {
pins {
pinmux = <STM32_PINMUX('H', 6, AF2)>; /* TIM12_CH1 */
@@ -1374,12 +1592,14 @@
};
};
+ /omit-if-no-ref/
pwm12_sleep_pins_a: pwm12-sleep-0 {
pins {
pinmux = <STM32_PINMUX('H', 6, ANALOG)>; /* TIM12_CH1 */
};
};
+ /omit-if-no-ref/
qspi_clk_pins_a: qspi-clk-0 {
pins {
pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
@@ -1389,12 +1609,14 @@
};
};
+ /omit-if-no-ref/
qspi_clk_sleep_pins_a: qspi-clk-sleep-0 {
pins {
pinmux = <STM32_PINMUX('F', 10, ANALOG)>; /* QSPI_CLK */
};
};
+ /omit-if-no-ref/
qspi_bk1_pins_a: qspi-bk1-0 {
pins {
pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
@@ -1407,6 +1629,7 @@
};
};
+ /omit-if-no-ref/
qspi_bk1_sleep_pins_a: qspi-bk1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('F', 8, ANALOG)>, /* QSPI_BK1_IO0 */
@@ -1416,6 +1639,7 @@
};
};
+ /omit-if-no-ref/
qspi_bk2_pins_a: qspi-bk2-0 {
pins {
pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
@@ -1428,6 +1652,7 @@
};
};
+ /omit-if-no-ref/
qspi_bk2_sleep_pins_a: qspi-bk2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('H', 2, ANALOG)>, /* QSPI_BK2_IO0 */
@@ -1437,6 +1662,7 @@
};
};
+ /omit-if-no-ref/
qspi_cs1_pins_a: qspi-cs1-0 {
pins {
pinmux = <STM32_PINMUX('B', 6, AF10)>; /* QSPI_BK1_NCS */
@@ -1446,12 +1672,14 @@
};
};
+ /omit-if-no-ref/
qspi_cs1_sleep_pins_a: qspi-cs1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('B', 6, ANALOG)>; /* QSPI_BK1_NCS */
};
};
+ /omit-if-no-ref/
qspi_cs2_pins_a: qspi-cs2-0 {
pins {
pinmux = <STM32_PINMUX('C', 0, AF10)>; /* QSPI_BK2_NCS */
@@ -1461,12 +1689,14 @@
};
};
+ /omit-if-no-ref/
qspi_cs2_sleep_pins_a: qspi-cs2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('C', 0, ANALOG)>; /* QSPI_BK2_NCS */
};
};
+ /omit-if-no-ref/
sai2a_pins_a: sai2a-0 {
pins {
pinmux = <STM32_PINMUX('I', 5, AF10)>, /* SAI2_SCK_A */
@@ -1479,6 +1709,7 @@
};
};
+ /omit-if-no-ref/
sai2a_sleep_pins_a: sai2a-sleep-0 {
pins {
pinmux = <STM32_PINMUX('I', 5, ANALOG)>, /* SAI2_SCK_A */
@@ -1488,6 +1719,7 @@
};
};
+ /omit-if-no-ref/
sai2a_pins_b: sai2a-1 {
pins1 {
pinmux = <STM32_PINMUX('I', 6, AF10)>, /* SAI2_SD_A */
@@ -1499,6 +1731,7 @@
};
};
+ /omit-if-no-ref/
sai2a_sleep_pins_b: sai2a-sleep-1 {
pins {
pinmux = <STM32_PINMUX('I', 6, ANALOG)>, /* SAI2_SD_A */
@@ -1507,6 +1740,7 @@
};
};
+ /omit-if-no-ref/
sai2a_pins_c: sai2a-2 {
pins {
pinmux = <STM32_PINMUX('D', 13, AF10)>, /* SAI2_SCK_A */
@@ -1518,6 +1752,7 @@
};
};
+ /omit-if-no-ref/
sai2a_sleep_pins_c: sai2a-sleep-2 {
pins {
pinmux = <STM32_PINMUX('D', 13, ANALOG)>, /* SAI2_SCK_A */
@@ -1526,6 +1761,7 @@
};
};
+ /omit-if-no-ref/
sai2b_pins_a: sai2b-0 {
pins1 {
pinmux = <STM32_PINMUX('E', 12, AF10)>, /* SAI2_SCK_B */
@@ -1541,6 +1777,7 @@
};
};
+ /omit-if-no-ref/
sai2b_sleep_pins_a: sai2b-sleep-0 {
pins {
pinmux = <STM32_PINMUX('F', 11, ANALOG)>, /* SAI2_SD_B */
@@ -1550,6 +1787,7 @@
};
};
+ /omit-if-no-ref/
sai2b_pins_b: sai2b-1 {
pins {
pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
@@ -1557,12 +1795,14 @@
};
};
+ /omit-if-no-ref/
sai2b_sleep_pins_b: sai2b-sleep-1 {
pins {
pinmux = <STM32_PINMUX('F', 11, ANALOG)>; /* SAI2_SD_B */
};
};
+ /omit-if-no-ref/
sai2b_pins_c: sai2b-2 {
pins1 {
pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
@@ -1570,12 +1810,14 @@
};
};
+ /omit-if-no-ref/
sai2b_sleep_pins_c: sai2b-sleep-2 {
pins {
pinmux = <STM32_PINMUX('F', 11, ANALOG)>; /* SAI2_SD_B */
};
};
+ /omit-if-no-ref/
sai2b_pins_d: sai2b-3 {
pins1 {
pinmux = <STM32_PINMUX('H', 2, AF10)>, /* SAI2_SCK_B */
@@ -1591,6 +1833,7 @@
};
};
+ /omit-if-no-ref/
sai2b_sleep_pins_d: sai2b-sleep-3 {
pins1 {
pinmux = <STM32_PINMUX('H', 2, ANALOG)>, /* SAI2_SCK_B */
@@ -1600,6 +1843,7 @@
};
};
+ /omit-if-no-ref/
sai4a_pins_a: sai4a-0 {
pins {
pinmux = <STM32_PINMUX('B', 5, AF10)>; /* SAI4_SD_A */
@@ -1609,12 +1853,14 @@
};
};
+ /omit-if-no-ref/
sai4a_sleep_pins_a: sai4a-sleep-0 {
pins {
pinmux = <STM32_PINMUX('B', 5, ANALOG)>; /* SAI4_SD_A */
};
};
+ /omit-if-no-ref/
sdmmc1_b4_pins_a: sdmmc1-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
@@ -1634,6 +1880,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
pins1 {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
@@ -1658,6 +1905,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_b4_init_pins_a: sdmmc1-b4-init-0 {
pins1 {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
@@ -1670,6 +1918,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1_D0 */
@@ -1681,6 +1930,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_b4_pins_b: sdmmc1-b4-1 {
pins1 {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
@@ -1700,6 +1950,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_b4_od_pins_b: sdmmc1-b4-od-1 {
pins1 {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
@@ -1724,6 +1975,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_b4_sleep_pins_b: sdmmc1-b4-sleep-1 {
pins {
pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1_D0 */
@@ -1735,6 +1987,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_dir_pins_a: sdmmc1-dir-0 {
pins1 {
pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
@@ -1750,6 +2003,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_dir_init_pins_a: sdmmc1-dir-init-0 {
pins1 {
pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
@@ -1761,6 +2015,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_dir_sleep_pins_a: sdmmc1-dir-sleep-0 {
pins {
pinmux = <STM32_PINMUX('F', 2, ANALOG)>, /* SDMMC1_D0DIR */
@@ -1770,6 +2025,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_dir_pins_b: sdmmc1-dir-1 {
pins1 {
pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
@@ -1785,6 +2041,7 @@
};
};
+ /omit-if-no-ref/
sdmmc1_dir_sleep_pins_b: sdmmc1-dir-sleep-1 {
pins {
pinmux = <STM32_PINMUX('F', 2, ANALOG)>, /* SDMMC1_D0DIR */
@@ -1794,6 +2051,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_b4_pins_a: sdmmc2-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
@@ -1813,6 +2071,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
@@ -1837,6 +2096,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('B', 14, ANALOG)>, /* SDMMC2_D0 */
@@ -1848,6 +2108,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_b4_pins_b: sdmmc2-b4-1 {
pins1 {
pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
@@ -1867,6 +2128,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_b4_od_pins_b: sdmmc2-b4-od-1 {
pins1 {
pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
@@ -1891,6 +2153,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_pins_a: sdmmc2-d47-0 {
pins {
pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
@@ -1903,6 +2166,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 {
pins {
pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */
@@ -1912,6 +2176,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_pins_b: sdmmc2-d47-1 {
pins {
pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
@@ -1924,6 +2189,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_sleep_pins_b: sdmmc2-d47-sleep-1 {
pins {
pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */
@@ -1933,6 +2199,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_pins_c: sdmmc2-d47-2 {
pins {
pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
@@ -1945,6 +2212,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_sleep_pins_c: sdmmc2-d47-sleep-2 {
pins {
pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */
@@ -1954,6 +2222,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_pins_d: sdmmc2-d47-3 {
pins {
pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
@@ -1963,6 +2232,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_sleep_pins_d: sdmmc2-d47-sleep-3 {
pins {
pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */
@@ -1972,6 +2242,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_pins_e: sdmmc2-d47-4 {
pins {
pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
@@ -1984,6 +2255,7 @@
};
};
+ /omit-if-no-ref/
sdmmc2_d47_sleep_pins_e: sdmmc2-d47-sleep-4 {
pins {
pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */
@@ -1993,6 +2265,7 @@
};
};
+ /omit-if-no-ref/
sdmmc3_b4_pins_a: sdmmc3-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
@@ -2012,6 +2285,7 @@
};
};
+ /omit-if-no-ref/
sdmmc3_b4_od_pins_a: sdmmc3-b4-od-0 {
pins1 {
pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
@@ -2036,6 +2310,7 @@
};
};
+ /omit-if-no-ref/
sdmmc3_b4_sleep_pins_a: sdmmc3-b4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('F', 0, ANALOG)>, /* SDMMC3_D0 */
@@ -2047,6 +2322,7 @@
};
};
+ /omit-if-no-ref/
sdmmc3_b4_pins_b: sdmmc3-b4-1 {
pins1 {
pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
@@ -2066,6 +2342,7 @@
};
};
+ /omit-if-no-ref/
sdmmc3_b4_od_pins_b: sdmmc3-b4-od-1 {
pins1 {
pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
@@ -2090,6 +2367,7 @@
};
};
+ /omit-if-no-ref/
sdmmc3_b4_sleep_pins_b: sdmmc3-b4-sleep-1 {
pins {
pinmux = <STM32_PINMUX('F', 0, ANALOG)>, /* SDMMC3_D0 */
@@ -2101,6 +2379,7 @@
};
};
+ /omit-if-no-ref/
spdifrx_pins_a: spdifrx-0 {
pins {
pinmux = <STM32_PINMUX('G', 12, AF8)>; /* SPDIF_IN1 */
@@ -2108,12 +2387,14 @@
};
};
+ /omit-if-no-ref/
spdifrx_sleep_pins_a: spdifrx-sleep-0 {
pins {
pinmux = <STM32_PINMUX('G', 12, ANALOG)>; /* SPDIF_IN1 */
};
};
+ /omit-if-no-ref/
spi1_pins_b: spi1-1 {
pins1 {
pinmux = <STM32_PINMUX('A', 5, AF5)>, /* SPI1_SCK */
@@ -2129,6 +2410,7 @@
};
};
+ /omit-if-no-ref/
spi2_pins_a: spi2-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF5)>, /* SPI2_SCK */
@@ -2144,6 +2426,7 @@
};
};
+ /omit-if-no-ref/
spi2_pins_b: spi2-1 {
pins1 {
pinmux = <STM32_PINMUX('I', 1, AF5)>, /* SPI2_SCK */
@@ -2159,6 +2442,7 @@
};
};
+ /omit-if-no-ref/
spi2_pins_c: spi2-2 {
pins1 {
pinmux = <STM32_PINMUX('I', 1, AF5)>, /* SPI2_SCK */
@@ -2173,6 +2457,7 @@
};
};
+ /omit-if-no-ref/
spi4_pins_a: spi4-0 {
pins {
pinmux = <STM32_PINMUX('E', 12, AF5)>, /* SPI4_SCK */
@@ -2187,6 +2472,7 @@
};
};
+ /omit-if-no-ref/
spi5_pins_a: spi5-0 {
pins1 {
pinmux = <STM32_PINMUX('F', 7, AF5)>, /* SPI5_SCK */
@@ -2202,6 +2488,7 @@
};
};
+ /omit-if-no-ref/
stusb1600_pins_a: stusb1600-0 {
pins {
pinmux = <STM32_PINMUX('I', 11, GPIO)>;
@@ -2209,6 +2496,7 @@
};
};
+ /omit-if-no-ref/
uart4_pins_a: uart4-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
@@ -2222,6 +2510,7 @@
};
};
+ /omit-if-no-ref/
uart4_idle_pins_a: uart4-idle-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 11, ANALOG)>; /* UART4_TX */
@@ -2232,6 +2521,7 @@
};
};
+ /omit-if-no-ref/
uart4_sleep_pins_a: uart4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('G', 11, ANALOG)>, /* UART4_TX */
@@ -2239,6 +2529,7 @@
};
};
+ /omit-if-no-ref/
uart4_pins_b: uart4-1 {
pins1 {
pinmux = <STM32_PINMUX('D', 1, AF8)>; /* UART4_TX */
@@ -2252,6 +2543,7 @@
};
};
+ /omit-if-no-ref/
uart4_pins_c: uart4-2 {
pins1 {
pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
@@ -2265,6 +2557,7 @@
};
};
+ /omit-if-no-ref/
uart4_pins_d: uart4-3 {
pins1 {
pinmux = <STM32_PINMUX('A', 13, AF8)>; /* UART4_TX */
@@ -2278,6 +2571,7 @@
};
};
+ /omit-if-no-ref/
uart4_idle_pins_d: uart4-idle-3 {
pins1 {
pinmux = <STM32_PINMUX('A', 13, ANALOG)>; /* UART4_TX */
@@ -2288,6 +2582,7 @@
};
};
+ /omit-if-no-ref/
uart4_sleep_pins_d: uart4-sleep-3 {
pins {
pinmux = <STM32_PINMUX('A', 13, ANALOG)>, /* UART4_TX */
@@ -2295,6 +2590,7 @@
};
};
+ /omit-if-no-ref/
uart5_pins_a: uart5-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 13, AF14)>; /* UART5_TX */
@@ -2308,6 +2604,7 @@
};
};
+ /omit-if-no-ref/
uart7_pins_a: uart7-0 {
pins1 {
pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART7_TX */
@@ -2323,6 +2620,7 @@
};
};
+ /omit-if-no-ref/
uart7_pins_b: uart7-1 {
pins1 {
pinmux = <STM32_PINMUX('F', 7, AF7)>; /* UART7_TX */
@@ -2336,6 +2634,7 @@
};
};
+ /omit-if-no-ref/
uart7_pins_c: uart7-2 {
pins1 {
pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART7_TX */
@@ -2349,6 +2648,7 @@
};
};
+ /omit-if-no-ref/
uart7_idle_pins_c: uart7-idle-2 {
pins1 {
pinmux = <STM32_PINMUX('E', 8, ANALOG)>; /* UART7_TX */
@@ -2359,6 +2659,7 @@
};
};
+ /omit-if-no-ref/
uart7_sleep_pins_c: uart7-sleep-2 {
pins {
pinmux = <STM32_PINMUX('E', 8, ANALOG)>, /* UART7_TX */
@@ -2366,6 +2667,7 @@
};
};
+ /omit-if-no-ref/
uart8_pins_a: uart8-0 {
pins1 {
pinmux = <STM32_PINMUX('E', 1, AF8)>; /* UART8_TX */
@@ -2379,6 +2681,7 @@
};
};
+ /omit-if-no-ref/
uart8_rtscts_pins_a: uart8rtscts-0 {
pins {
pinmux = <STM32_PINMUX('G', 7, AF8)>, /* UART8_RTS */
@@ -2387,6 +2690,7 @@
};
};
+ /omit-if-no-ref/
usart1_pins_a: usart1-0 {
pins1 {
pinmux = <STM32_PINMUX('A', 12, AF7)>; /* USART1_RTS */
@@ -2400,6 +2704,7 @@
};
};
+ /omit-if-no-ref/
usart1_idle_pins_a: usart1-idle-0 {
pins1 {
pinmux = <STM32_PINMUX('A', 12, ANALOG)>, /* USART1_RTS */
@@ -2407,6 +2712,7 @@
};
};
+ /omit-if-no-ref/
usart1_sleep_pins_a: usart1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('A', 12, ANALOG)>, /* USART1_RTS */
@@ -2414,6 +2720,7 @@
};
};
+ /omit-if-no-ref/
usart2_pins_a: usart2-0 {
pins1 {
pinmux = <STM32_PINMUX('F', 5, AF7)>, /* USART2_TX */
@@ -2429,6 +2736,7 @@
};
};
+ /omit-if-no-ref/
usart2_sleep_pins_a: usart2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('F', 5, ANALOG)>, /* USART2_TX */
@@ -2438,6 +2746,7 @@
};
};
+ /omit-if-no-ref/
usart2_pins_b: usart2-1 {
pins1 {
pinmux = <STM32_PINMUX('F', 5, AF7)>, /* USART2_TX */
@@ -2453,6 +2762,7 @@
};
};
+ /omit-if-no-ref/
usart2_sleep_pins_b: usart2-sleep-1 {
pins {
pinmux = <STM32_PINMUX('F', 5, ANALOG)>, /* USART2_TX */
@@ -2462,6 +2772,7 @@
};
};
+ /omit-if-no-ref/
usart2_pins_c: usart2-2 {
pins1 {
pinmux = <STM32_PINMUX('D', 5, AF7)>, /* USART2_TX */
@@ -2477,6 +2788,7 @@
};
};
+ /omit-if-no-ref/
usart2_idle_pins_c: usart2-idle-2 {
pins1 {
pinmux = <STM32_PINMUX('D', 5, ANALOG)>, /* USART2_TX */
@@ -2494,6 +2806,7 @@
};
};
+ /omit-if-no-ref/
usart2_sleep_pins_c: usart2-sleep-2 {
pins {
pinmux = <STM32_PINMUX('D', 5, ANALOG)>, /* USART2_TX */
@@ -2503,6 +2816,7 @@
};
};
+ /omit-if-no-ref/
usart3_pins_a: usart3-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>; /* USART3_TX */
@@ -2516,6 +2830,7 @@
};
};
+ /omit-if-no-ref/
usart3_idle_pins_a: usart3-idle-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>; /* USART3_TX */
@@ -2526,6 +2841,7 @@
};
};
+ /omit-if-no-ref/
usart3_sleep_pins_a: usart3-sleep-0 {
pins {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
@@ -2533,6 +2849,7 @@
};
};
+ /omit-if-no-ref/
usart3_pins_b: usart3-1 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
@@ -2548,6 +2865,7 @@
};
};
+ /omit-if-no-ref/
usart3_idle_pins_b: usart3-idle-1 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
@@ -2565,6 +2883,7 @@
};
};
+ /omit-if-no-ref/
usart3_sleep_pins_b: usart3-sleep-1 {
pins {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
@@ -2574,6 +2893,7 @@
};
};
+ /omit-if-no-ref/
usart3_pins_c: usart3-2 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
@@ -2589,6 +2909,7 @@
};
};
+ /omit-if-no-ref/
usart3_idle_pins_c: usart3-idle-2 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
@@ -2606,6 +2927,7 @@
};
};
+ /omit-if-no-ref/
usart3_sleep_pins_c: usart3-sleep-2 {
pins {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
@@ -2615,6 +2937,7 @@
};
};
+ /omit-if-no-ref/
usart3_pins_d: usart3-3 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
@@ -2630,6 +2953,7 @@
};
};
+ /omit-if-no-ref/
usart3_idle_pins_d: usart3-idle-3 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
@@ -2642,6 +2966,7 @@
};
};
+ /omit-if-no-ref/
usart3_sleep_pins_d: usart3-sleep-3 {
pins {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
@@ -2651,6 +2976,7 @@
};
};
+ /omit-if-no-ref/
usart3_pins_e: usart3-4 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
@@ -2666,6 +2992,7 @@
};
};
+ /omit-if-no-ref/
usart3_idle_pins_e: usart3-idle-4 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
@@ -2683,6 +3010,7 @@
};
};
+ /omit-if-no-ref/
usart3_sleep_pins_e: usart3-sleep-4 {
pins {
pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
@@ -2692,6 +3020,7 @@
};
};
+ /omit-if-no-ref/
usart3_pins_f: usart3-5 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
@@ -2707,12 +3036,14 @@
};
};
+ /omit-if-no-ref/
usbotg_hs_pins_a: usbotg-hs-0 {
pins {
pinmux = <STM32_PINMUX('A', 10, ANALOG)>; /* OTG_ID */
};
};
+ /omit-if-no-ref/
usbotg_fs_dp_dm_pins_a: usbotg-fs-dp-dm-0 {
pins {
pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* OTG_FS_DM */
@@ -2722,6 +3053,7 @@
};
&pinctrl_z {
+ /omit-if-no-ref/
i2c2_pins_b2: i2c2-0 {
pins {
pinmux = <STM32_PINMUX('Z', 0, AF3)>; /* I2C2_SCL */
@@ -2731,12 +3063,14 @@
};
};
+ /omit-if-no-ref/
i2c2_sleep_pins_b2: i2c2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('Z', 0, ANALOG)>; /* I2C2_SCL */
};
};
+ /omit-if-no-ref/
i2c4_pins_a: i2c4-0 {
pins {
pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
@@ -2747,6 +3081,7 @@
};
};
+ /omit-if-no-ref/
i2c4_sleep_pins_a: i2c4-sleep-0 {
pins {
pinmux = <STM32_PINMUX('Z', 4, ANALOG)>, /* I2C4_SCL */
@@ -2754,6 +3089,7 @@
};
};
+ /omit-if-no-ref/
i2c6_pins_a: i2c6-0 {
pins {
pinmux = <STM32_PINMUX('Z', 6, AF2)>, /* I2C6_SCL */
@@ -2764,6 +3100,7 @@
};
};
+ /omit-if-no-ref/
i2c6_sleep_pins_a: i2c6-sleep-0 {
pins {
pinmux = <STM32_PINMUX('Z', 6, ANALOG)>, /* I2C6_SCL */
@@ -2771,6 +3108,7 @@
};
};
+ /omit-if-no-ref/
spi1_pins_a: spi1-0 {
pins1 {
pinmux = <STM32_PINMUX('Z', 0, AF5)>, /* SPI1_SCK */
@@ -2786,6 +3124,7 @@
};
};
+ /omit-if-no-ref/
spi1_sleep_pins_a: spi1-sleep-0 {
pins {
pinmux = <STM32_PINMUX('Z', 0, ANALOG)>, /* SPI1_SCK */
@@ -2794,6 +3133,7 @@
};
};
+ /omit-if-no-ref/
usart1_pins_b: usart1-1 {
pins1 {
pinmux = <STM32_PINMUX('Z', 7, AF7)>; /* USART1_TX */
@@ -2807,6 +3147,7 @@
};
};
+ /omit-if-no-ref/
usart1_idle_pins_b: usart1-idle-1 {
pins1 {
pinmux = <STM32_PINMUX('Z', 7, ANALOG)>; /* USART1_TX */
@@ -2817,6 +3158,7 @@
};
};
+ /omit-if-no-ref/
usart1_sleep_pins_b: usart1-sleep-1 {
pins {
pinmux = <STM32_PINMUX('Z', 7, ANALOG)>, /* USART1_TX */
diff --git a/arch/arm/boot/dts/st/stm32mp157c-osd32mp1-red.dts b/arch/arm/boot/dts/st/stm32mp157c-osd32mp1-red.dts
new file mode 100644
index 000000000000..bd67a1db9122
--- /dev/null
+++ b/arch/arm/boot/dts/st/stm32mp157c-osd32mp1-red.dts
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) Geanix ApS 2023 - All Rights Reserved
+ * Author: Sean Nyekjaer <sean@geanix.com>
+ */
+
+/dts-v1/;
+
+#include "stm32mp157.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15xx-osd32.dtsi"
+#include "stm32mp15xxac-pinctrl.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/stm32-pinfunc.h>
+
+/ {
+ model = "Octavo OSD32MP1 RED board";
+ compatible = "oct,stm32mp157c-osd32-red", "oct,stm32mp15xx-osd32", "st,stm32mp157";
+
+ aliases {
+ serial0 = &uart4;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ led-controller-0 {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "heartbeat";
+ gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+&crc1 {
+ status = "okay";
+};
+
+&dts {
+ status = "okay";
+};
+
+&ethernet0 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&ethernet0_rgmii_pins_a>;
+ pinctrl-1 = <&ethernet0_rgmii_sleep_pins_a>;
+ phy-mode = "rgmii-id";
+ max-speed = <1000>;
+ phy-handle = <&phy0>;
+ st,eth-clk-sel;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy0: ethernet-phy@3 {
+ reg = <3>;
+ };
+ };
+};
+
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c1_pins_a>;
+ pinctrl-1 = <&i2c1_sleep_pins_a>;
+ status = "okay";
+ i2c-scl-rising-time-ns = <100>;
+ i2c-scl-falling-time-ns = <7>;
+ /* spare dmas for other usage */
+ /delete-property/dmas;
+ /delete-property/dma-names;
+
+ hdmi-transmitter@39 {
+ compatible = "sil,sii9022";
+ reg = <0x39>;
+ reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-parent = <&gpiog>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&ltdc_pins_e>;
+ pinctrl-1 = <&ltdc_sleep_pins_e>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ sii9022_in: endpoint {
+ remote-endpoint = <&ltdc_ep0_out>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ sii9022_tx_endpoint: endpoint {
+ remote-endpoint = <&i2s2_endpoint>;
+ };
+ };
+ };
+ };
+};
+
+&i2s2 {
+ clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc CK_PER>, <&rcc PLL3_R>;
+ clock-names = "pclk", "i2sclk", "x8k", "x11k";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2s2_pins_b>;
+ pinctrl-1 = <&i2s2_sleep_pins_b>;
+ status = "okay";
+
+ i2s2_port: port {
+ i2s2_endpoint: endpoint {
+ remote-endpoint = <&sii9022_tx_endpoint>;
+ dai-format = "i2s";
+ mclk-fs = <256>;
+ };
+ };
+};
+
+&ltdc {
+ status = "okay";
+
+ port {
+ ltdc_ep0_out: endpoint {
+ remote-endpoint = <&sii9022_in>;
+ };
+ };
+};
+
+&m_can1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&m_can1_pins_d>;
+ pinctrl-1 = <&m_can1_sleep_pins_d>;
+ status = "okay";
+};
+
+&pwr_regulators {
+ vdd-supply = <&vdd>;
+ vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sdmmc1 {
+ pinctrl-names = "default", "opendrain", "sleep";
+ pinctrl-0 = <&sdmmc1_b4_pins_a>;
+ pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
+ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
+ cd-gpios = <&gpioe 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ disable-wp;
+ st,neg-edge;
+ bus-width = <4>;
+ vmmc-supply = <&v3v3>;
+ status = "okay";
+};
+
+&sdmmc2 {
+ pinctrl-names = "default", "opendrain", "sleep";
+ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_d>;
+ pinctrl-1 = <&sdmmc2_b4_od_pins_a>;
+ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_d>;
+ non-removable;
+ no-sd;
+ no-sdio;
+ st,neg-edge;
+ bus-width = <8>;
+ vmmc-supply = <&v3v3>;
+ vqmmc-supply = <&vdd>;
+ mmc-ddr-3_3v;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default", "sleep", "idle";
+ pinctrl-0 = <&uart4_pins_a>;
+ pinctrl-1 = <&uart4_sleep_pins_a>;
+ pinctrl-2 = <&uart4_idle_pins_a>;
+ /* spare dmas for other usage */
+ /delete-property/dmas;
+ /delete-property/dma-names;
+ status = "okay";
+};
+
+&usbh_ehci {
+ phys = <&usbphyc_port0>;
+ phy-names = "usb";
+ status = "okay";
+};
+
+&usbh_ohci {
+ phys = <&usbphyc_port0>;
+ phy-names = "usb";
+ status = "okay";
+};
+
+&usbotg_hs {
+ vbus-supply = <&vbus_otg>;
+};
+
+&usbphyc {
+ status = "okay";
+};
+
+&usbphyc_port0 {
+ phy-supply = <&vdd_usb>;
+};
+
+&usbphyc_port1 {
+ phy-supply = <&vdd_usb>;
+};
diff --git a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
index 184b8bb4ebbf..f09b7c384bd9 100644
--- a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
@@ -597,10 +597,6 @@ baseboard_eeprom: &sip_eeprom {
phy-supply = <&vdd_usb>;
};
-&v3v3_hdmi {
- /delete-property/regulator-always-on;
-};
-
&vrefbuf {
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
diff --git a/arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi
index a43965c86fe8..aeb71c41a734 100644
--- a/arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xx-osd32.dtsi
@@ -117,18 +117,14 @@
regulator-name = "v1v8_audio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- regulator-always-on;
interrupts = <IT_CURLIM_LDO1 0>;
-
};
v3v3_hdmi: ldo2 {
regulator-name = "v3v3_hdmi";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- regulator-always-on;
interrupts = <IT_CURLIM_LDO2 0>;
-
};
vtt_ddr: ldo3 {
@@ -156,9 +152,7 @@
regulator-name = "v1v2_hdmi";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
- regulator-always-on;
interrupts = <IT_CURLIM_LDO6 0>;
-
};
vref_ddr: vref_ddr {
diff --git a/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts b/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts
index 5dfe4d4bab93..78ce860e59b3 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts
@@ -8,6 +8,7 @@
#include "am33xx.dtsi"
#include "am335x-osd335x-common.dtsi"
+#include <dt-bindings/leds/common.h>
/ {
model = "TI AM335x PocketBeagle";
@@ -25,6 +26,8 @@
led-usr0 {
label = "beaglebone:green:usr0";
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_HEARTBEAT;
gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
default-state = "off";
@@ -32,6 +35,8 @@
led-usr1 {
label = "beaglebone:green:usr1";
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_DISK_ACTIVITY;
gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "mmc0";
default-state = "off";
@@ -39,6 +44,8 @@
led-usr2 {
label = "beaglebone:green:usr2";
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_CPU;
gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "cpu0";
default-state = "off";
@@ -46,6 +53,8 @@
led-usr3 {
label = "beaglebone:green:usr3";
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_INDICATOR;
gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
@@ -112,7 +121,7 @@
"P2.24",
"P2.33",
"P2.22",
- "P2.18",
+ "P2.18 [PRU0.15i]",
"NC",
"NC",
"P2.01 [PWM1A]",
@@ -208,11 +217,6 @@
compatible = "pinconf-single";
pinctrl-names = "default";
- pinctrl-0 = < &P2_03_gpio &P1_34_gpio &P2_19_gpio &P2_24_gpio
- &P2_33_gpio &P2_22_gpio &P2_18_gpio &P2_10_gpio
- &P2_06_gpio &P2_04_gpio &P2_02_gpio &P2_08_gpio
- &P2_17_gpio >;
-
/* P2_03 (ZCZ ball T10) gpio0_23 0x824 PIN 9 */
P2_03_gpio: P2-03-gpio-pins {
pinctrl-single,pins = <
@@ -267,10 +271,10 @@
pinctrl-single,bias-pulldown = < 0x10 0x00 0x10 0x18>;
};
- /* P2_18 (ZCZ ball U13) gpio1_15 0x83c PIN 15 */
- P2_18_gpio: P2-18-gpio-pins {
+ /* P2_20 (ZCZ ball T13) gpio2_00 0x888 */
+ P2_20_gpio: P2-20-gpio-pins {
pinctrl-single,pins = <
- AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_INPUT_PULLUP, MUX_MODE7)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_CSN3, PIN_INPUT_PULLUP, MUX_MODE7)
>;
pinctrl-single,bias-pullup = < 0x10 0x10 0x00 0x18>;
pinctrl-single,bias-pulldown = < 0x10 0x00 0x10 0x18>;
@@ -401,6 +405,27 @@
AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_OUTPUT_PULLDOWN, MUX_MODE6) /* (U17) gpmc_wpn.uart4_txd */
>;
};
+
+ pru0_pins: pinmux-pru0-pins {
+ pinctrl-single,pins = <
+ AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR1, PIN_INPUT_PULLUP, MUX_MODE5)/* (D14) xdma_event_intr1.pr1_pru0_pru_r31_16 */
+ AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKX, PIN_OUTPUT_PULLDOWN, MUX_MODE5)/* (A14) mcasp0_ahclkx.pr1_pru0_pru_r30_7 */
+ AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKR, PIN_OUTPUT_PULLDOWN, MUX_MODE5) /* (B12) mcasp0_acklr.pr1_pru0_pru_r30_4 */
+ AM33XX_PADCONF(AM335X_PIN_MCASP0_FSX, PIN_OUTPUT_PULLDOWN, MUX_MODE5) /* (B13) mcasp0_fsx.pr1_pru0_pru_r30_1 */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_INPUT_PULLUP, MUX_MODE6) /* (U13) gpmc_ad15.pr1_pru0_pru_r31_15 */
+ AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR1, PIN_OUTPUT_PULLDOWN, MUX_MODE5) /* (D13) mcasp0_axr1.pr1_pru0_pru_r30_6 */
+ AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKR, PIN_OUTPUT_PULLDOWN, MUX_MODE5)/* (C12) mcasp0_ahclkr.pr1_pru0_pru_r30_3 */
+ AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_OUTPUT_PULLDOWN, MUX_MODE5) /* (D12) mcasp0_axr0.pr1_pru0_pru_r30_2 */
+ AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_OUTPUT_PULLDOWN, MUX_MODE5) /* (C13) mcasp0_fsr.pr1_pru0_pru_r30_5 */
+ >;
+ };
+
+ pru1_pins: pinmux-pru1-pins {
+ pinctrl-single,pins = <
+ AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE5)/*(R6) lcd_ac_bias_en.pr1_pru1_pru_r30_11 */
+ AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT_PULLDOWN, MUX_MODE5) /* (V5) lcd_pclk.pr1_pru1_pru_r30_10 */
+ >;
+ };
};
&epwmss0 {
@@ -482,3 +507,17 @@
&usb1 {
dr_mode = "host";
};
+
+&pruss_tm {
+ status = "okay";
+};
+
+&pru0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pru0_pins>;
+};
+
+&pru1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pru1_pins>;
+};
diff --git a/arch/arm/boot/dts/ti/omap/am3517-evm.dts b/arch/arm/boot/dts/ti/omap/am3517-evm.dts
index af9df15274be..40f15da81043 100644
--- a/arch/arm/boot/dts/ti/omap/am3517-evm.dts
+++ b/arch/arm/boot/dts/ti/omap/am3517-evm.dts
@@ -172,11 +172,24 @@
&davinci_emac {
pinctrl-names = "default";
pinctrl-0 = <&ethernet_pins>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
status = "okay";
};
&davinci_mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&enet_phy_pins>;
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>; /* gpio_58 */
+ };
};
&dss {
@@ -257,6 +270,12 @@
>;
};
+ enet_phy_pins: ethernet-phy-pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20bc, PIN_INPUT | MUX_MODE4) /* gpmc_ncs7.gpio_57 */
+ >;
+ };
+
i2c2_pins: i2c2-pins {
pinctrl-single,pins = <
OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */
@@ -271,13 +290,6 @@
>;
};
- leds_pins: leds-pins {
- pinctrl-single,pins = <
- OMAP3_WKUP_IOPAD(0x2a24, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu0.gpio_11 */
- OMAP3_WKUP_IOPAD(0x2a26, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu1.gpio_31 */
- >;
- };
-
mmc1_pins: mmc1-pins {
pinctrl-single,pins = <
OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
@@ -355,3 +367,12 @@
>;
};
};
+
+&omap3_pmx_wkup {
+ leds_pins: leds-pins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a24, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu0.gpio_11 */
+ OMAP3_WKUP_IOPAD(0x2a26, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu1.gpio_31 */
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/ti/omap/am3517.dtsi b/arch/arm/boot/dts/ti/omap/am3517.dtsi
index fbfc956f4e4d..77e58e686fb1 100644
--- a/arch/arm/boot/dts/ti/omap/am3517.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am3517.dtsi
@@ -15,6 +15,7 @@
aliases {
serial3 = &uart4;
can = &hecc;
+ ethernet = &davinci_emac;
};
cpus {
diff --git a/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi
index d2d516d113ba..a2bb3609c94f 100644
--- a/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi
+++ b/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi
@@ -67,7 +67,8 @@
fsusb1_phy: usb-phy@1 {
compatible = "motorola,mapphone-mdm6600";
pinctrl-0 = <&usb_mdm6600_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&usb_mdm6600_sleep_pins>;
+ pinctrl-names = "default", "sleep";
enable-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; /* gpio_95 */
power-gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>; /* gpio_54 */
reset-gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>; /* gpio_49 */
@@ -476,6 +477,23 @@
>;
};
+ /* Modem sleep pins to keep gpio_49 high with internal pull */
+ usb_mdm6600_sleep_pins: usb-mdm6600-sleep-pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x0d8, PIN_INPUT | MUX_MODE3)
+ OMAP4_IOPAD(0x07c, PIN_OUTPUT | MUX_MODE3)
+ OMAP4_IOPAD(0x072, PIN_INPUT_PULLUP | MUX_MODE7) /* Keep gpio_49 reset high */
+ OMAP4_IOPAD(0x14e, PIN_OUTPUT | MUX_MODE3)
+ OMAP4_IOPAD(0x150, PIN_OFF_OUTPUT_LOW | PIN_INPUT | MUX_MODE3)
+ OMAP4_IOPAD(0x07e, PIN_INPUT | MUX_MODE3)
+ OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3)
+ OMAP4_IOPAD(0x078, PIN_INPUT | MUX_MODE3)
+ OMAP4_IOPAD(0x094, PIN_OUTPUT | MUX_MODE3)
+ OMAP4_IOPAD(0x096, PIN_OUTPUT | MUX_MODE3)
+ OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE3)
+ >;
+ };
+
usb_ulpi_pins: usb-ulpi-pins {
pinctrl-single,pins = <
OMAP4_IOPAD(0x196, MUX_MODE7)
diff --git a/arch/arm/boot/dts/ti/omap/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/ti/omap/omap3-devkit8000-common.dtsi
index 3b9838f1bb6b..07d5894ebb74 100644
--- a/arch/arm/boot/dts/ti/omap/omap3-devkit8000-common.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap3-devkit8000-common.dtsi
@@ -275,8 +275,8 @@
ethernet@6,0 {
compatible = "davicom,dm9000";
- reg = <6 0x000 2
- 6 0x400 2>; /* CS6, offset 0 and 0x400, IO size 2 */
+ reg = <6 0x000 2>,
+ <6 0x400 2>; /* CS6, offset 0 and 0x400, IO size 2 */
bank-width = <2>;
interrupt-parent = <&gpio1>;
interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
diff --git a/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi b/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi
index b6b27e93857f..3661340009e7 100644
--- a/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi
@@ -11,7 +11,7 @@
/ {
model = "OMAP3 GTA04";
- compatible = "goldelico,gta04", "ti,omap3630", "ti,omap36xx", "ti,omap3";
+ compatible = "goldelico,gta04", "ti,omap3630", "ti,omap3";
cpus {
cpu@0 {
cpu0-supply = <&vcc>;
diff --git a/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts b/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts
index e119e2cccc4e..01d783826d5f 100644
--- a/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts
+++ b/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts
@@ -4,6 +4,7 @@
*/
/dts-v1/;
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/input/input.h>
#include "omap4460.dtsi"
@@ -188,15 +189,6 @@
pinctrl-0 = <&mpu9150h_pins>;
interrupt-parent = <&gpio2>;
interrupt = <19 IRQ_TYPE_LEVEL_HIGH>;
-
- i2c-gate {
- #address-cells = <1>;
- #size-cells = <0>;
- magnetometer@c {
- compatible = "asahi-kasei,ak8975";
- reg = <0x0c>;
- };
- };
};
};
@@ -206,7 +198,31 @@
clock-frequency = <100000>;
- /* TODO: BD2606MVV at 0x66 */
+ led-controller@66 {
+ compatible = "rohm,bd2606mvv";
+ reg = <0x66>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_STATUS;
+ };
+
+ led@4 {
+ reg = <4>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ };
+ };
};
&i2c4 {
@@ -227,7 +243,16 @@
reset-gpios = <&gpio2 23 GPIO_ACTIVE_LOW>;
};
- /* TODO: mpu9150 at control unit, seems to require quirks */
+ mpu9150: imu@68 {
+ compatible = "invensense,mpu9150";
+ reg = <0x68>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mpu9150_pins>;
+ interrupt-parent = <&gpio2>;
+ interrupt = <7 IRQ_TYPE_LEVEL_HIGH>;
+ invensense,level-shifter;
+ };
};
&keypad {
@@ -362,6 +387,12 @@
>;
};
+ mpu9150_pins: pinmux-mpu9150-pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x5e, PIN_INPUT_PULLUP | MUX_MODE3)
+ >;
+ };
+
mpu9150h_pins: pinmux-mpu9150h-pins {
pinctrl-single,pins = <
OMAP4_IOPAD(0x76, PIN_INPUT_PULLUP | MUX_MODE3)
@@ -410,7 +441,7 @@
>;
};
- wl12xx_gpio: pinmux-wl12xx-gpio {
+ wl12xx_gpio: pinmux-wl12xx-gpio-pins {
pinctrl-single,pins = <
OMAP4_IOPAD(0x1c8, PIN_OUTPUT | MUX_MODE3) /* gpio_24 / WLAN_EN */
>;
diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig
index ed66a2958912..9d1b297c432e 100644
--- a/arch/arm/configs/aspeed_g4_defconfig
+++ b/arch/arm/configs/aspeed_g4_defconfig
@@ -58,7 +58,6 @@ CONFIG_NET_NCSI=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_FIRMWARE_MEMMAP=y
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_PARTITIONED_MASTER=y
diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig
index b6487a4b45c0..b55f8f539c5f 100644
--- a/arch/arm/configs/aspeed_g5_defconfig
+++ b/arch/arm/configs/aspeed_g5_defconfig
@@ -70,7 +70,6 @@ CONFIG_MCTP=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_FIRMWARE_MEMMAP=y
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_PARTITIONED_MASTER=y
@@ -81,6 +80,8 @@ CONFIG_MTD_UBI_FASTMAP=y
CONFIG_MTD_UBI_BLOCK=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
+CONFIG_SMPRO_ERRMON=y
+CONFIG_SMPRO_MISC=y
CONFIG_EEPROM_AT24=y
CONFIG_EEPROM_AT25=y
CONFIG_SCSI=y
@@ -150,6 +151,7 @@ CONFIG_ASPEED_KCS_IPMI_BMC=y
CONFIG_IPMI_KCS_BMC_CDEV_IPMI=y
CONFIG_IPMI_KCS_BMC_SERIO=y
CONFIG_ASPEED_BT_IPMI_BMC=y
+CONFIG_SSIF_IPMI_BMC=y
CONFIG_HW_RANDOM_TIMERIOMEM=y
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS_I2C=y
@@ -173,6 +175,7 @@ CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_W1=y
CONFIG_W1_MASTER_GPIO=y
CONFIG_W1_SLAVE_THERM=y
+CONFIG_SENSORS_SMPRO=y
CONFIG_SENSORS_ADT7475=y
CONFIG_SENSORS_ASPEED=y
CONFIG_SENSORS_IIO_HWMON=y
@@ -194,6 +197,7 @@ CONFIG_SENSORS_SBTSI=y
CONFIG_SENSORS_TMP421=y
CONFIG_SENSORS_W83773G=y
CONFIG_WATCHDOG_SYSFS=y
+CONFIG_MFD_SMPRO=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_SUPPORT_FILTER=y
CONFIG_MEDIA_PLATFORM_SUPPORT=y
@@ -251,9 +255,11 @@ CONFIG_FSI_MASTER_GPIO=y
CONFIG_FSI_MASTER_HUB=y
CONFIG_FSI_MASTER_AST_CF=y
CONFIG_FSI_MASTER_ASPEED=y
+CONFIG_FSI_MASTER_I2CR=y
CONFIG_FSI_SCOM=y
CONFIG_FSI_SBEFIFO=y
CONFIG_FSI_OCC=y
+CONFIG_I2CR_SCOM=y
CONFIG_PECI=y
CONFIG_PECI_CPU=y
CONFIG_PECI_ASPEED=y
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 53b1d41b4a8b..c98d5ff8a1ed 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -93,7 +93,7 @@ CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_ATA=y
# CONFIG_SATA_PMP is not set
-CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_DWC=y
# CONFIG_ATA_SFF is not set
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
@@ -322,6 +322,7 @@ CONFIG_EXYNOS_ADC=y
CONFIG_STMPE_ADC=y
CONFIG_CM36651=y
CONFIG_AK8975=y
+CONFIG_SENSORS_ISL29018=y
CONFIG_PWM=y
CONFIG_PWM_SAMSUNG=y
CONFIG_PHY_EXYNOS5250_SATA=y
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index d95686d19401..59c4835ffc97 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -98,7 +98,6 @@ CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_MANGLE=y
-CONFIG_IP_NF_TARGET_CLUSTERIP=y
CONFIG_IP_NF_TARGET_ECN=y
CONFIG_IP_NF_TARGET_TTL=y
CONFIG_IP_NF_RAW=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 23fc49f23d25..bb9f0e5b0b63 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -237,6 +237,7 @@ CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_AHCI_BRCM=y
CONFIG_AHCI_DM816=y
+CONFIG_AHCI_DWC=m
CONFIG_AHCI_ST=y
CONFIG_AHCI_IMX=y
CONFIG_AHCI_SUNXI=y
@@ -314,6 +315,7 @@ CONFIG_KEYBOARD_PXA27x=m
CONFIG_KEYBOARD_SAMSUNG=m
CONFIG_KEYBOARD_ST_KEYSCAN=y
CONFIG_KEYBOARD_SPEAR=y
+CONFIG_KEYBOARD_TM2_TOUCHKEY=m
CONFIG_KEYBOARD_CROS_EC=m
CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_MOUSE_CYAPA=m
@@ -691,6 +693,8 @@ CONFIG_VIDEO_STI_HVA=m
CONFIG_VIDEO_STM32_DCMI=m
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIVID=m
+CONFIG_VIDEO_S5C73M3=m
+CONFIG_VIDEO_S5K6A3=m
CONFIG_VIDEO_ADV7180=m
CONFIG_VIDEO_ADV7604=m
CONFIG_VIDEO_ADV7604_CEC=y
@@ -857,7 +861,6 @@ CONFIG_USB_MUSB_HDRC=m
CONFIG_USB_MUSB_SUNXI=m
CONFIG_USB_MUSB_TUSB6010=m
CONFIG_USB_MUSB_OMAP2PLUS=m
-CONFIG_USB_MUSB_AM35X=m
CONFIG_USB_MUSB_DSPS=m
CONFIG_USB_MUSB_UX500=m
CONFIG_USB_UX500_DMA=y
@@ -1203,6 +1206,8 @@ CONFIG_PHY_QCOM_USB_HS=y
CONFIG_PHY_RCAR_GEN2=m
CONFIG_PHY_ROCKCHIP_DP=m
CONFIG_PHY_ROCKCHIP_USB=y
+CONFIG_PHY_EXYNOS_DP_VIDEO=m
+CONFIG_PHY_EXYNOS_MIPI_VIDEO=m
CONFIG_PHY_SAMSUNG_USB2=m
CONFIG_PHY_EXYNOS5250_SATA=m
CONFIG_PHY_UNIPHIER_USB2=y
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index b685018dcf54..b2f0862f4bd9 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -78,7 +78,6 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NETFILTER=y
CONFIG_NF_CONNTRACK=m
-CONFIG_NF_LOG_NETDEV=m
CONFIG_NF_CONNTRACK_ZONES=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
@@ -92,7 +91,6 @@ CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -100,7 +98,6 @@ CONFIG_NFT_MASQ=m
CONFIG_NFT_REDIR=m
CONFIG_NFT_NAT=m
CONFIG_NFT_TUNNEL=m
-CONFIG_NFT_OBJREF=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_QUOTA=m
CONFIG_NFT_REJECT=m
@@ -179,7 +176,6 @@ CONFIG_NETFILTER_XT_MATCH_TIME=m
CONFIG_NETFILTER_XT_MATCH_U32=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m
@@ -193,14 +189,12 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_SECURITY=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -225,7 +219,6 @@ CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NFT_BRIDGE_META=m
CONFIG_NFT_BRIDGE_REJECT=m
-CONFIG_NF_LOG_BRIDGE=m
CONFIG_BRIDGE=m
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_VLAN_8021Q=m
@@ -560,7 +553,6 @@ CONFIG_USB_STORAGE=m
CONFIG_USB_MUSB_HDRC=m
CONFIG_USB_MUSB_TUSB6010=m
CONFIG_USB_MUSB_OMAP2PLUS=m
-CONFIG_USB_MUSB_AM35X=m
CONFIG_USB_MUSB_DSPS=m
CONFIG_USB_INVENTRA_DMA=y
CONFIG_USB_TI_CPPI41_DMA=y
diff --git a/arch/arm/configs/s5pv210_defconfig b/arch/arm/configs/s5pv210_defconfig
index 72df854878f8..d280169081bd 100644
--- a/arch/arm/configs/s5pv210_defconfig
+++ b/arch/arm/configs/s5pv210_defconfig
@@ -97,6 +97,7 @@ CONFIG_MMC_SDHCI_S3C_DMA=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_MAX8998=m
CONFIG_DMADEVICES=y
+CONFIG_IIO=y
CONFIG_PWM=y
CONFIG_PWM_SAMSUNG=y
CONFIG_PHY_SAMSUNG_USB2=m
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 22205ef0f376..dfdea295c4af 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -6,6 +6,7 @@ CONFIG_CGROUPS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PERF_EVENTS=y
+CONFIG_KEXEC=y
CONFIG_ARCH_RENESAS=y
CONFIG_PL310_ERRATA_588369=y
CONFIG_SMP=y
@@ -13,7 +14,6 @@ CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8
CONFIG_HIGHMEM=y
CONFIG_ARM_APPENDED_DTB=y
-CONFIG_KEXEC=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c
index 20218876bef2..905b1b191546 100644
--- a/arch/arm/kernel/isa.c
+++ b/arch/arm/kernel/isa.c
@@ -16,7 +16,7 @@
static unsigned int isa_membase, isa_portbase, isa_portshift;
-static struct ctl_table ctl_isa_vars[4] = {
+static struct ctl_table ctl_isa_vars[] = {
{
.procname = "membase",
.data = &isa_membase,
@@ -35,7 +35,7 @@ static struct ctl_table ctl_isa_vars[4] = {
.maxlen = sizeof(isa_portshift),
.mode = 0444,
.proc_handler = proc_dointvec,
- }, {}
+ },
};
static struct ctl_table_header *isa_sysctl_header;
diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c
index 672081405a7e..907a4f8c5aed 100644
--- a/arch/arm/mach-shmobile/pm-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c
@@ -46,15 +46,16 @@ void __init rcar_gen2_pm_init(void)
{
void __iomem *p;
u32 bar;
- static int once;
struct device_node *np;
bool has_a7 = false;
bool has_a15 = false;
struct resource res;
int error;
- if (once++)
+ if (!request_mem_region(0, SZ_256K, "Boot Area")) {
+ pr_err("Failed to request boot area\n");
return;
+ }
for_each_of_cpu_node(np) {
if (of_device_is_compatible(np, "arm,cortex-a15"))
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index 1bc609986c16..474c325323a3 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -38,7 +38,14 @@ static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)
{
- void __iomem *base = ioremap(HPBREG_BASE, 0x1000);
+ void __iomem *base;
+
+ if (!request_mem_region(0, SZ_4K, "Boot Area")) {
+ pr_err("Failed to request boot area\n");
+ return;
+ }
+
+ base = ioremap(HPBREG_BASE, 0x1000);
/* Map the reset vector (in headsmp-scu.S, headsmp.S) */
writel(__pa(shmobile_boot_vector), base + AVECR);
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index 453d48865029..9196b37ea292 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -44,10 +44,16 @@ static int sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
{
- void __iomem *ap = ioremap(AP_BASE, PAGE_SIZE);
- void __iomem *sysc = ioremap(SYSC_BASE, PAGE_SIZE);
+ void __iomem *ap, *sysc;
+
+ if (!request_mem_region(0, SZ_4K, "Boot Area")) {
+ pr_err("Failed to request boot area\n");
+ return;
+ }
/* Map the reset vector (in headsmp.S) */
+ ap = ioremap(AP_BASE, PAGE_SIZE);
+ sysc = ioremap(SYSC_BASE, PAGE_SIZE);
writel(0, ap + APARMBAREA); /* 4k */
writel(__pa(shmobile_boot_vector), sysc + SBAR);
iounmap(sysc);
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index 93d0d46cbb15..584f9528c996 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -263,7 +263,7 @@
246 common io_submit sys_io_submit
247 common io_cancel sys_io_cancel
248 common exit_group sys_exit_group
-249 common lookup_dcookie sys_lookup_dcookie
+249 common lookup_dcookie sys_ni_syscall
250 common epoll_create sys_epoll_create
251 common epoll_ctl sys_epoll_ctl sys_oabi_epoll_ctl
252 common epoll_wait sys_epoll_wait
@@ -466,6 +466,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index c392e18f1e43..9afdc4c4a5dc 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -164,9 +164,6 @@ static int xen_starting_cpu(unsigned int cpu)
BUG_ON(err);
per_cpu(xen_vcpu, cpu) = vcpup;
- if (!xen_kernel_unmapped_at_usr())
- xen_setup_runstate_info(cpu);
-
after_register_vcpu_info:
enable_percpu_irq(xen_events_irq, 0);
return 0;
@@ -523,9 +520,6 @@ static int __init xen_guest_init(void)
return -EINVAL;
}
- if (!xen_kernel_unmapped_at_usr())
- xen_time_setup_guest();
-
if (xen_initial_domain())
pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier);
@@ -535,7 +529,13 @@ static int __init xen_guest_init(void)
}
early_initcall(xen_guest_init);
-static int __init xen_pm_init(void)
+static int xen_starting_runstate_cpu(unsigned int cpu)
+{
+ xen_setup_runstate_info(cpu);
+ return 0;
+}
+
+static int __init xen_late_init(void)
{
if (!xen_domain())
return -ENODEV;
@@ -548,9 +548,16 @@ static int __init xen_pm_init(void)
do_settimeofday64(&ts);
}
- return 0;
+ if (xen_kernel_unmapped_at_usr())
+ return 0;
+
+ xen_time_setup_guest();
+
+ return cpuhp_setup_state(CPUHP_AP_ARM_XEN_RUNSTATE_STARTING,
+ "arm/xen_runstate:starting",
+ xen_starting_runstate_cpu, NULL);
}
-late_initcall(xen_pm_init);
+late_initcall(xen_late_init);
/* empty stubs */
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 78f20e632712..6062a52a084f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1368,6 +1368,8 @@ choice
config CPU_BIG_ENDIAN
bool "Build big-endian kernel"
depends on !LD_IS_LLD || LLD_VERSION >= 130000
+ # https://github.com/llvm/llvm-project/commit/1379b150991f70a5782e9a143c2ba5308da1161c
+ depends on AS_IS_GNU || AS_VERSION >= 150000
help
Say Y if you plan on running a kernel with a big-endian userspace.
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 6069120199bb..24335565bad5 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -244,6 +244,18 @@ config ARCH_NPCM
General support for NPCM8xx BMC (Arbel).
Nuvoton NPCM8xx BMC based on the Cortex A35.
+config ARCH_PENSANDO
+ bool "AMD Pensando Platforms"
+ help
+ This enables support for the ARMv8 based AMD Pensando SoC
+ family to include the Elba SoC.
+
+ AMD Pensando SoCs support a range of Distributed Services
+ Cards in PCIe format installed into servers. The Elba
+ SoC includes 16 Cortex A-72 CPU cores, 144 P4-programmable
+ cores for a minimal latency/jitter datapath, and network
+ interfaces up to 200 Gb/s.
+
config ARCH_QCOM
bool "Qualcomm Platforms"
select GPIOLIB
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 3b0ad5406238..3aca6787a167 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -38,6 +38,8 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64-model-b.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6-mini.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
new file mode 100644
index 000000000000..dbce61b355d6
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2023 Martin Botka <martin.botka@somainline.org>.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616-bigtreetech-cb1.dtsi"
+
+/ {
+ model = "BigTreeTech CB1";
+ compatible = "bigtreetech,cb1-manta", "bigtreetech,cb1", "allwinner,sun50i-h616";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_ph_pins>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
new file mode 100644
index 000000000000..1fed2b46cfe8
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2023 Martin Botka <martin.botka@somainline.org>.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ aliases {
+ ethernet0 = &rtl8189ftv;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+ };
+ };
+
+ reg_vcc5v: regulator-vcc5v {
+ /* board wide 5V supply from carrier boards */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_vcc33_wifi: vcc33-wifi {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc33-wifi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ vin-supply = <&reg_vcc5v>;
+ };
+
+ reg_vcc_wifi_io: vcc-wifi-io {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-wifi-io";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ vin-supply = <&reg_vcc33_wifi>;
+ };
+
+ wifi_pwrseq: wifi-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rtc 1>;
+ clock-names = "ext_clock";
+ reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
+ post-power-on-delay-ms = <200>;
+ };
+};
+
+&mmc0 {
+ vmmc-supply = <&reg_dldo1>;
+ /* Card detection pin is not connected */
+ broken-cd;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&mmc1 {
+ vmmc-supply = <&reg_vcc33_wifi>;
+ vqmmc-supply = <&reg_vcc_wifi_io>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ mmc-ddr-1_8v;
+ status = "okay";
+
+ rtl8189ftv: wifi@1 {
+ reg = <1>;
+ };
+};
+
+&r_i2c {
+ status = "okay";
+
+ axp313a: pmic@36 {
+ compatible = "x-powers,axp313a";
+ reg = <0x36>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ regulators{
+ reg_dcdc1: dcdc1 {
+ regulator-name = "vdd-gpu-sys";
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <990000>;
+ regulator-always-on;
+ };
+
+ reg_dcdc2: dcdc2 {
+ regulator-name = "vdd-cpu";
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-ramp-delay = <200>;
+ regulator-always-on;
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-name = "vcc-dram";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+
+ reg_aldo1: aldo1 {
+ regulator-name = "vcc-1v8-pll";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_dldo1: dldo1 {
+ regulator-name = "vcc-3v3-io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
new file mode 100644
index 000000000000..832f08b2b260
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2023 Martin Botka <martin@biqu3d.com>.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616-bigtreetech-cb1.dtsi"
+
+/ {
+ model = "BigTreeTech Pi";
+ compatible = "bigtreetech,pi", "allwinner,sun50i-h616";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ehci2 {
+ status = "okay";
+};
+
+&ehci3 {
+ status = "okay";
+};
+
+&ir {
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&ohci2 {
+ status = "okay";
+};
+
+&ohci3 {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_ph_pins>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index 74aed0d232a9..d549d277d972 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -133,6 +133,13 @@
#reset-cells = <1>;
};
+ sid: efuse@3006000 {
+ compatible = "allwinner,sun50i-h616-sid", "allwinner,sun50i-a64-sid";
+ reg = <0x03006000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
watchdog: watchdog@30090a0 {
compatible = "allwinner,sun50i-h616-wdt",
"allwinner,sun6i-a31-wdt";
diff --git a/arch/arm64/boot/dts/amd/Makefile b/arch/arm64/boot/dts/amd/Makefile
index 68103a8b0ef5..8502cc2afbc5 100644
--- a/arch/arm64/boot/dts/amd/Makefile
+++ b/arch/arm64/boot/dts/amd/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_PENSANDO) += elba-asic.dtb
dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive-rev-b0.dtb amd-overdrive-rev-b1.dtb
diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts
index 21149acb6b31..1a65f1ec183d 100644
--- a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts
+++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts
@@ -64,7 +64,6 @@
reg = <0>;
spi-max-frequency = <20000000>;
voltage-ranges = <3200 3400>;
- pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,com-mode = <0x0>;
pl022,rx-level-trig = <0>;
diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts
index 99205ae1b46b..52f8d36295a8 100644
--- a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts
+++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts
@@ -76,7 +76,6 @@
reg = <0>;
spi-max-frequency = <20000000>;
voltage-ranges = <3200 3400>;
- pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,com-mode = <0x0>;
pl022,rx-level-trig = <0>;
diff --git a/arch/arm64/boot/dts/amd/elba-16core.dtsi b/arch/arm64/boot/dts/amd/elba-16core.dtsi
new file mode 100644
index 000000000000..568bcc39ce9f
--- /dev/null
+++ b/arch/arm64/boot/dts/amd/elba-16core.dtsi
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+/*
+ * Copyright 2020-2023 Advanced Micro Devices, Inc.
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 { cpu = <&cpu0>; };
+ core1 { cpu = <&cpu1>; };
+ core2 { cpu = <&cpu2>; };
+ core3 { cpu = <&cpu3>; };
+ };
+
+ cluster1 {
+ core0 { cpu = <&cpu4>; };
+ core1 { cpu = <&cpu5>; };
+ core2 { cpu = <&cpu6>; };
+ core3 { cpu = <&cpu7>; };
+ };
+
+ cluster2 {
+ core0 { cpu = <&cpu8>; };
+ core1 { cpu = <&cpu9>; };
+ core2 { cpu = <&cpu10>; };
+ core3 { cpu = <&cpu11>; };
+ };
+
+ cluster3 {
+ core0 { cpu = <&cpu12>; };
+ core1 { cpu = <&cpu13>; };
+ core2 { cpu = <&cpu14>; };
+ core3 { cpu = <&cpu15>; };
+ };
+ };
+
+ /* CLUSTER 0 */
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0>;
+ next-level-cache = <&l2_0>;
+ enable-method = "psci";
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x1>;
+ next-level-cache = <&l2_0>;
+ enable-method = "psci";
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x2>;
+ next-level-cache = <&l2_0>;
+ enable-method = "psci";
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x3>;
+ next-level-cache = <&l2_0>;
+ enable-method = "psci";
+ };
+
+ l2_0: l2-cache0 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ /* CLUSTER 1 */
+ cpu4: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x100>;
+ next-level-cache = <&l2_1>;
+ enable-method = "psci";
+ };
+
+ cpu5: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x101>;
+ next-level-cache = <&l2_1>;
+ enable-method = "psci";
+ };
+
+ cpu6: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x102>;
+ next-level-cache = <&l2_1>;
+ enable-method = "psci";
+ };
+
+ cpu7: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x103>;
+ next-level-cache = <&l2_1>;
+ enable-method = "psci";
+ };
+
+ l2_1: l2-cache1 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ /* CLUSTER 2 */
+ cpu8: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x200>;
+ next-level-cache = <&l2_2>;
+ enable-method = "psci";
+ };
+
+ cpu9: cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x201>;
+ next-level-cache = <&l2_2>;
+ enable-method = "psci";
+ };
+
+ cpu10: cpu@202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x202>;
+ next-level-cache = <&l2_2>;
+ enable-method = "psci";
+ };
+
+ cpu11: cpu@203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x203>;
+ next-level-cache = <&l2_2>;
+ enable-method = "psci";
+ };
+
+ l2_2: l2-cache2 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ /* CLUSTER 3 */
+ cpu12: cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x300>;
+ next-level-cache = <&l2_3>;
+ enable-method = "psci";
+ };
+
+ cpu13: cpu@301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x301>;
+ next-level-cache = <&l2_3>;
+ enable-method = "psci";
+ };
+
+ cpu14: cpu@302 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x302>;
+ next-level-cache = <&l2_3>;
+ enable-method = "psci";
+ };
+
+ cpu15: cpu@303 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x303>;
+ next-level-cache = <&l2_3>;
+ enable-method = "psci";
+ };
+
+ l2_3: l2-cache3 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amd/elba-asic-common.dtsi b/arch/arm64/boot/dts/amd/elba-asic-common.dtsi
new file mode 100644
index 000000000000..46b6c6783f58
--- /dev/null
+++ b/arch/arm64/boot/dts/amd/elba-asic-common.dtsi
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+/*
+ * Copyright 2020-2022 Advanced Micro Devices, Inc.
+ */
+
+&ahb_clk {
+ clock-frequency = <400000000>;
+};
+
+&emmc_clk {
+ clock-frequency = <200000000>;
+};
+
+&flash_clk {
+ clock-frequency = <400000000>;
+};
+
+&ref_clk {
+ clock-frequency = <156250000>;
+};
+
+&qspi {
+ status = "okay";
+
+ flash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+ spi-rx-bus-width = <2>;
+ m25p,fast-read;
+ cdns,read-delay = <0>;
+ cdns,tshsl-ns = <0>;
+ cdns,tsd2d-ns = <0>;
+ cdns,tchsh-ns = <0>;
+ cdns,tslch-ns = <0>;
+ };
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&emmc {
+ bus-width = <8>;
+ cap-mmc-hw-reset;
+ status = "okay";
+};
+
+&wdt0 {
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <100000>;
+ status = "okay";
+
+ rtc@51 {
+ compatible = "nxp,pcf85263";
+ reg = <0x51>;
+ };
+};
+
+&spi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ num-cs = <4>;
+ cs-gpios = <0>, <0>, <&porta 1 GPIO_ACTIVE_LOW>,
+ <&porta 7 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amd/elba-asic.dts b/arch/arm64/boot/dts/amd/elba-asic.dts
new file mode 100644
index 000000000000..c3f4da2f7449
--- /dev/null
+++ b/arch/arm64/boot/dts/amd/elba-asic.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+/*
+ * Device Tree file for AMD Pensando Elba Board.
+ *
+ * Copyright 2020-2022 Advanced Micro Devices, Inc.
+ */
+
+/dts-v1/;
+
+#include "elba.dtsi"
+#include "elba-16core.dtsi"
+#include "elba-asic-common.dtsi"
+#include "elba-flash-parts.dtsi"
+
+/ {
+ model = "AMD Pensando Elba Board";
+ compatible = "amd,pensando-elba-ortano", "amd,pensando-elba";
+
+ aliases {
+ serial0 = &uart0;
+ spi0 = &spi0;
+ spi1 = &qspi;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
diff --git a/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi b/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi
new file mode 100644
index 000000000000..cf761a05a81f
--- /dev/null
+++ b/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+/*
+ * Copyright 2020-2023 Advanced Micro Devices, Inc.
+ */
+
+&flash0 {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "rsvd";
+ reg = <0x0 0x10000>;
+ read-only;
+ };
+
+ partition@10000 {
+ label = "flash";
+ reg = <0x10000 0xfff0000>;
+ };
+
+ partition@f0000 {
+ label = "golduenv";
+ reg = <0xf0000 0x10000>;
+ };
+
+ partition@100000 {
+ label = "boot0";
+ reg = <0x100000 0x80000>;
+ };
+
+ partition@180000 {
+ label = "golduboot";
+ reg = <0x180000 0x200000>;
+ };
+
+ partition@380000 {
+ label = "brdcfg0";
+ reg = <0x380000 0x10000>;
+ };
+
+ partition@390000 {
+ label = "brdcfg1";
+ reg = <0x390000 0x10000>;
+ };
+
+ partition@400000 {
+ label = "goldfw";
+ reg = <0x400000 0x3c00000>;
+ };
+
+ partition@4010000 {
+ label = "fwmap";
+ reg = <0x4010000 0x20000>;
+ };
+
+ partition@4030000 {
+ label = "fwsel";
+ reg = <0x4030000 0x20000>;
+ };
+
+ partition@4090000 {
+ label = "bootlog";
+ reg = <0x4090000 0x20000>;
+ };
+
+ partition@40b0000 {
+ label = "panicbuf";
+ reg = <0x40b0000 0x20000>;
+ };
+
+ partition@40d0000 {
+ label = "uservars";
+ reg = <0x40d0000 0x20000>;
+ };
+
+ partition@4200000 {
+ label = "uboota";
+ reg = <0x4200000 0x400000>;
+ };
+
+ partition@4600000 {
+ label = "ubootb";
+ reg = <0x4600000 0x400000>;
+ };
+
+ partition@4a00000 {
+ label = "mainfwa";
+ reg = <0x4a00000 0x1000000>;
+ };
+
+ partition@5a00000 {
+ label = "mainfwb";
+ reg = <0x5a00000 0x1000000>;
+ };
+
+ partition@6a00000 {
+ label = "diaguboot";
+ reg = <0x6a00000 0x400000>;
+ };
+
+ partition@6e00000 {
+ label = "spare";
+ reg = <0x6e00000 0x1200000>;
+ };
+
+ partition@8000000 {
+ label = "diagfw";
+ reg = <0x8000000 0x7fe0000>;
+ };
+
+ partition@ffe0000 {
+ label = "ubootenv";
+ reg = <0xffe0000 0x10000>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amd/elba.dtsi b/arch/arm64/boot/dts/amd/elba.dtsi
new file mode 100644
index 000000000000..674890cf2a34
--- /dev/null
+++ b/arch/arm64/boot/dts/amd/elba.dtsi
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+/*
+ * Copyright 2020-2022 Advanced Micro Devices, Inc.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include "dt-bindings/interrupt-controller/arm-gic.h"
+
+/ {
+ model = "Elba ASIC Board";
+ compatible = "amd,pensando-elba";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ dma-coherent;
+
+ ahb_clk: oscillator0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ };
+
+ emmc_clk: oscillator2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ };
+
+ flash_clk: oscillator3 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ };
+
+ ref_clk: oscillator4 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a72-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ i2c0: i2c@400 {
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x400 0x0 0x100>;
+ clocks = <&ahb_clk>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-sda-hold-time-ns = <480>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ wdt0: watchdog@1400 {
+ compatible = "snps,dw-wdt";
+ reg = <0x0 0x1400 0x0 0x100>;
+ clocks = <&ahb_clk>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ qspi: spi@2400 {
+ compatible = "amd,pensando-elba-qspi", "cdns,qspi-nor";
+ reg = <0x0 0x2400 0x0 0x400>,
+ <0x0 0x7fff0000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&flash_clk>;
+ cdns,fifo-depth = <1024>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x7fff0000>;
+ status = "disabled";
+ };
+
+ spi0: spi@2800 {
+ compatible = "amd,pensando-elba-spi";
+ reg = <0x0 0x2800 0x0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ amd,pensando-elba-syscon = <&syscon>;
+ clocks = <&ahb_clk>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ num-cs = <2>;
+ status = "disabled";
+ };
+
+ gpio0: gpio@4000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0 0x4000 0x0 0x78>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ porta: gpio-port@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ reg = <0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ };
+
+ portb: gpio-port@1 {
+ compatible = "snps,dw-apb-gpio-port";
+ reg = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ };
+ };
+
+ uart0: serial@4800 {
+ compatible = "ns16550a";
+ reg = <0x0 0x4800 0x0 0x100>;
+ clocks = <&ref_clk>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ gic: interrupt-controller@800000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x800000 0x0 0x200000>, /* GICD */
+ <0x0 0xa00000 0x0 0x200000>, /* GICR */
+ <0x0 0x60000000 0x0 0x2000>, /* GICC */
+ <0x0 0x60010000 0x0 0x1000>, /* GICH */
+ <0x0 0x60020000 0x0 0x2000>; /* GICV */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ #interrupt-cells = <3>;
+ ranges;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+ /*
+ * Elba specific pre-ITS is enabled using the
+ * existing property socionext,synquacer-pre-its
+ */
+ gic_its: msi-controller@820000 {
+ compatible = "arm,gic-v3-its";
+ reg = <0x0 0x820000 0x0 0x10000>;
+ msi-controller;
+ #msi-cells = <1>;
+ socionext,synquacer-pre-its =
+ <0xc00000 0x1000000>;
+ };
+ };
+
+ emmc: mmc@30440000 {
+ compatible = "amd,pensando-elba-sd4hc", "cdns,sd4hc";
+ reg = <0x0 0x30440000 0x0 0x10000>,
+ <0x0 0x30480044 0x0 0x4>; /* byte-lane ctrl */
+ clocks = <&emmc_clk>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ cdns,phy-input-delay-sd-highspeed = <0x4>;
+ cdns,phy-input-delay-legacy = <0x4>;
+ cdns,phy-input-delay-sd-uhs-sdr50 = <0x6>;
+ cdns,phy-input-delay-sd-uhs-ddr50 = <0x16>;
+ mmc-ddr-1_8v;
+ status = "disabled";
+ };
+
+ syscon: syscon@307c0000 {
+ compatible = "amd,pensando-elba-syscon", "syscon";
+ reg = <0x0 0x307c0000 0x0 0x3000>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 8b6f57a94863..cc8b34bd583d 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_MESON) += amlogic-c3-c302x-aw409.dtb
dtb-$(CONFIG_ARCH_MESON) += amlogic-t7-a311d2-an400.dtb
dtb-$(CONFIG_ARCH_MESON) += amlogic-t7-a311d2-khadas-vim4.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad402.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-axg-jethome-jethub-j100.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-axg-jethome-jethub-j110-rev-2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-axg-jethome-jethub-j110-rev-3.dtb
@@ -17,6 +18,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-cm4io.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gsking-x.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking-pro.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-libretech-cc.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-go-ultra.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2-plus.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb
@@ -72,6 +74,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m2-pro.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-h96-max.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-s905d3-libretech-cc.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index 1423d4a79156..a03c7667d2b6 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/amlogic,t7-pwrc.h>
/ {
interrupt-parent = <&gic>;
@@ -118,6 +119,11 @@
sm: secure-monitor {
compatible = "amlogic,meson-gxbb-sm";
+
+ pwrc: power-controller {
+ compatible = "amlogic,t7-pwrc";
+ #power-domain-cells = <1>;
+ };
};
soc {
@@ -143,6 +149,28 @@
#size-cells = <2>;
ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
+ watchdog@2100 {
+ compatible = "amlogic,t7-wdt";
+ reg = <0x0 0x2100 0x0 0x10>;
+ clocks = <&xtal>;
+ };
+
+ periphs_pinctrl: pinctrl@4000 {
+ compatible = "amlogic,t7-periphs-pinctrl";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio: bank@4000 {
+ reg = <0x0 0x4000 0x0 0x0064>,
+ <0x0 0x40c0 0x0 0x0220>;
+ reg-names = "mux", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&periphs_pinctrl 0 0 157>;
+ };
+ };
+
uart_a: serial@78000 {
compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
reg = <0x0 0x78000 0x0 0x18>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
new file mode 100644
index 000000000000..1c20516fa653
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 SberDevices
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+/dts-v1/;
+
+#include "meson-a1.dtsi"
+
+/ {
+ compatible = "amlogic,ad402", "amlogic,a1";
+ model = "Amlogic Meson A1 AD402 Development Board";
+
+ aliases {
+ serial0 = &uart_AO_B;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x8000000>;
+ };
+
+ reserved-memory {
+ /* 3 MiB reserved for Amlogic Trust OS (BL32) */
+ secos_reserved: secos@3d00000 {
+ reg = <0x0 0x03d00000 0x0 0x300000>;
+ no-map;
+ };
+ };
+
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+ };
+
+ battery_4v2: regulator-battery-4v2 {
+ compatible = "regulator-fixed";
+ regulator-name = "4V2";
+ regulator-min-microvolt = <4200000>;
+ regulator-max-microvolt = <4200000>;
+ regulator-always-on;
+ };
+
+ vddq_1v35: regulator-vddq-1v35 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDQ_1V35";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ vin-supply = <&battery_4v2>;
+ regulator-always-on;
+ };
+
+ vddao_3v3: regulator-vddao-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&battery_4v2>;
+ regulator-always-on;
+ };
+
+ vcc_3v3: regulator-vcc-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+
+ vddio_1v8: regulator-vddio-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+};
+
+/* Bluetooth HCI H4 */
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+ pinctrl-names = "default";
+};
+
+&uart_AO_B {
+ status = "okay";
+};
+
+&saradc {
+ status = "okay";
+ vref-supply = <&vddio_1v8>;
+};
+
+&spifc {
+ status = "okay";
+ pinctrl-0 = <&spifc_pins>;
+ pinctrl-names = "default";
+
+ spi_nand@0 {
+ compatible = "spi-nand";
+ status = "okay";
+ reg = <0>;
+ spi-max-frequency = <96000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ };
+};
+
+&usb2_phy1 {
+ phy-supply = <&vcc_3v3>;
+};
+
+&usb {
+ status = "okay";
+ dr_mode = "peripheral";
+};
+
+&sd_emmc {
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ sd-uhs-sdr104;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_1v8>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
index 96225c421194..648e7f49424f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
@@ -3,9 +3,13 @@
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>
+#include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
#include <dt-bindings/gpio/meson-a1-gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/power/meson-a1-power.h>
+#include <dt-bindings/reset/amlogic,meson-a1-reset.h>
/ {
compatible = "amlogic,a1";
@@ -41,6 +45,15 @@
};
};
+ efuse: efuse {
+ compatible = "amlogic,meson-gxbb-efuse";
+ clocks = <&clkc_periphs CLKID_OTP>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ secure-monitor = <&sm>;
+ power-domains = <&pwrc PWRC_OTP_ID>;
+ };
+
psci {
compatible = "arm,psci-1.0";
method = "smc";
@@ -66,7 +79,6 @@
pwrc: power-controller {
compatible = "amlogic,meson-a1-pwrc";
#power-domain-cells = <1>;
- status = "okay";
};
};
@@ -76,6 +88,16 @@
#size-cells = <2>;
ranges;
+ spifc: spi@fd000400 {
+ compatible = "amlogic,a1-spifc";
+ reg = <0x0 0xfd000400 0x0 0x290>;
+ clocks = <&clkc_periphs CLKID_SPIFC>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&pwrc PWRC_SPIFC_ID>;
+ status = "disabled";
+ };
+
apb: bus@fe000000 {
compatible = "simple-bus";
reg = <0x0 0xfe000000 0x0 0x1000000>;
@@ -83,7 +105,6 @@
#size-cells = <2>;
ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x1000000>;
-
reset: reset-controller@0 {
compatible = "amlogic,meson-a1-reset";
reg = <0x0 0x0 0x0 0x8c>;
@@ -105,6 +126,196 @@
gpio-ranges = <&periphs_pinctrl 0 0 62>;
};
+ i2c0_f11_pins: i2c0-f11 {
+ mux {
+ groups = "i2c0_sck_f11",
+ "i2c0_sda_f12";
+ function = "i2c0";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ i2c0_f9_pins: i2c0-f9 {
+ mux {
+ groups = "i2c0_sck_f9",
+ "i2c0_sda_f10";
+ function = "i2c0";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ i2c1_x_pins: i2c1-x {
+ mux {
+ groups = "i2c1_sck_x",
+ "i2c1_sda_x";
+ function = "i2c1";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ i2c1_a_pins: i2c1-a {
+ mux {
+ groups = "i2c1_sck_a",
+ "i2c1_sda_a";
+ function = "i2c1";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ i2c2_x0_pins: i2c2-x0 {
+ mux {
+ groups = "i2c2_sck_x0",
+ "i2c2_sda_x1";
+ function = "i2c2";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ i2c2_x15_pins: i2c2-x15 {
+ mux {
+ groups = "i2c2_sck_x15",
+ "i2c2_sda_x16";
+ function = "i2c2";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ i2c2_a4_pins: i2c2-a4 {
+ mux {
+ groups = "i2c2_sck_a4",
+ "i2c2_sda_a5";
+ function = "i2c2";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ i2c2_a8_pins: i2c2-a8 {
+ mux {
+ groups = "i2c2_sck_a8",
+ "i2c2_sda_a9";
+ function = "i2c2";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ i2c3_x_pins: i2c3-x {
+ mux {
+ groups = "i2c3_sck_x",
+ "i2c3_sda_x";
+ function = "i2c3";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ i2c3_f_pins: i2c3-f {
+ mux {
+ groups = "i2c3_sck_f",
+ "i2c3_sda_f";
+ function = "i2c3";
+ bias-pull-up;
+ drive-strength-microamp = <3000>;
+ };
+ };
+
+ uart_a_pins: uart-a {
+ mux {
+ groups = "uart_a_tx",
+ "uart_a_rx";
+ function = "uart_a";
+ };
+ };
+
+ uart_a_cts_rts_pins: uart-a-cts-rts {
+ mux {
+ groups = "uart_a_cts",
+ "uart_a_rts";
+ function = "uart_a";
+ bias-pull-down;
+ };
+ };
+
+ sdio_pins: sdio {
+ mux0 {
+ groups = "sdcard_d0_x",
+ "sdcard_d1_x",
+ "sdcard_d2_x",
+ "sdcard_d3_x",
+ "sdcard_cmd_x";
+ function = "sdcard";
+ bias-pull-up;
+ };
+
+ mux1 {
+ groups = "sdcard_clk_x";
+ function = "sdcard";
+ bias-disable;
+ };
+ };
+
+ sdio_clk_gate_pins: sdio-clk-gate {
+ mux {
+ groups = "sdcard_clk_x";
+ function = "sdcard";
+ bias-pull-down;
+ };
+ };
+
+ spifc_pins: spifc {
+ mux {
+ groups = "spif_mo",
+ "spif_mi",
+ "spif_clk",
+ "spif_cs",
+ "spif_hold_n",
+ "spif_wp_n";
+ function = "spif";
+ };
+ };
+ };
+
+ gpio_intc: interrupt-controller@440 {
+ compatible = "amlogic,meson-a1-gpio-intc",
+ "amlogic,meson-gpio-intc";
+ reg = <0x0 0x0440 0x0 0x14>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ amlogic,channel-interrupts =
+ <49 50 51 52 53 54 55 56>;
+ };
+
+ clkc_periphs: clock-controller@800 {
+ compatible = "amlogic,a1-peripherals-clkc";
+ reg = <0 0x800 0 0x104>;
+ #clock-cells = <1>;
+ clocks = <&clkc_pll CLKID_FCLK_DIV2>,
+ <&clkc_pll CLKID_FCLK_DIV3>,
+ <&clkc_pll CLKID_FCLK_DIV5>,
+ <&clkc_pll CLKID_FCLK_DIV7>,
+ <&clkc_pll CLKID_HIFI_PLL>,
+ <&xtal>;
+ clock-names = "fclk_div2", "fclk_div3",
+ "fclk_div5", "fclk_div7",
+ "hifi_pll", "xtal";
+ };
+
+ i2c0: i2c@1400 {
+ compatible = "amlogic,meson-axg-i2c";
+ status = "disabled";
+ reg = <0x0 0x1400 0x0 0x20>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkc_periphs CLKID_I2C_M_A>;
+ power-domains = <&pwrc PWRC_I2C_ID>;
};
uart_AO: serial@1c00 {
@@ -127,14 +338,148 @@
status = "disabled";
};
- gpio_intc: interrupt-controller@0440 {
- compatible = "amlogic,meson-a1-gpio-intc",
- "amlogic,meson-gpio-intc";
- reg = <0x0 0x0440 0x0 0x14>;
- interrupt-controller;
- #interrupt-cells = <2>;
- amlogic,channel-interrupts =
- <49 50 51 52 53 54 55 56>;
+ saradc: adc@2c00 {
+ compatible = "amlogic,meson-g12a-saradc",
+ "amlogic,meson-saradc";
+ reg = <0x0 0x2c00 0x0 0x48>;
+ #io-channel-cells = <1>;
+ power-domains = <&pwrc PWRC_I2C_ID>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>,
+ <&clkc_periphs CLKID_SARADC_EN>,
+ <&clkc_periphs CLKID_SARADC>,
+ <&clkc_periphs CLKID_SARADC_SEL>;
+ clock-names = "clkin", "core",
+ "adc_clk", "adc_sel";
+ status = "disabled";
+ };
+
+ i2c1: i2c@5c00 {
+ compatible = "amlogic,meson-axg-i2c";
+ status = "disabled";
+ reg = <0x0 0x5c00 0x0 0x20>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkc_periphs CLKID_I2C_M_B>;
+ power-domains = <&pwrc PWRC_I2C_ID>;
+ };
+
+ i2c2: i2c@6800 {
+ compatible = "amlogic,meson-axg-i2c";
+ status = "disabled";
+ reg = <0x0 0x6800 0x0 0x20>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkc_periphs CLKID_I2C_M_C>;
+ power-domains = <&pwrc PWRC_I2C_ID>;
+ };
+
+ i2c3: i2c@6c00 {
+ compatible = "amlogic,meson-axg-i2c";
+ status = "disabled";
+ reg = <0x0 0x6c00 0x0 0x20>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkc_periphs CLKID_I2C_M_D>;
+ power-domains = <&pwrc PWRC_I2C_ID>;
+ };
+
+ usb2_phy1: phy@4000 {
+ compatible = "amlogic,a1-usb2-phy";
+ clocks = <&clkc_periphs CLKID_USB_PHY_IN>;
+ clock-names = "xtal";
+ reg = <0x0 0x4000 0x0 0x60>;
+ resets = <&reset RESET_USBPHY>;
+ reset-names = "phy";
+ #phy-cells = <0>;
+ power-domains = <&pwrc PWRC_USB_ID>;
+ };
+
+ hwrng: rng@5118 {
+ compatible = "amlogic,meson-rng";
+ reg = <0x0 0x5118 0x0 0x4>;
+ power-domains = <&pwrc PWRC_OTP_ID>;
+ };
+
+ sec_AO: ao-secure@5a20 {
+ compatible = "amlogic,meson-gx-ao-secure", "syscon";
+ reg = <0x0 0x5a20 0x0 0x140>;
+ amlogic,has-chip-id;
+ };
+
+ clkc_pll: pll-clock-controller@7c80 {
+ compatible = "amlogic,a1-pll-clkc";
+ reg = <0 0x7c80 0 0x18c>;
+ #clock-cells = <1>;
+ clocks = <&clkc_periphs CLKID_FIXPLL_IN>,
+ <&clkc_periphs CLKID_HIFIPLL_IN>;
+ clock-names = "fixpll_in", "hifipll_in";
+ };
+
+ sd_emmc: sd@10000 {
+ compatible = "amlogic,meson-axg-mmc";
+ reg = <0x0 0x10000 0x0 0x800>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc_periphs CLKID_SD_EMMC_A>,
+ <&clkc_periphs CLKID_SD_EMMC>,
+ <&clkc_pll CLKID_FCLK_DIV2>;
+ clock-names = "core",
+ "clkin0",
+ "clkin1";
+ assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_SEL2>;
+ assigned-clock-parents = <&xtal>;
+ resets = <&reset RESET_SD_EMMC_A>;
+ power-domains = <&pwrc PWRC_SD_EMMC_ID>;
+ status = "disabled";
+ };
+ };
+
+ usb: usb@fe004400 {
+ status = "disabled";
+ compatible = "amlogic,meson-a1-usb-ctrl";
+ reg = <0x0 0xfe004400 0x0 0xa0>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks = <&clkc_periphs CLKID_USB_CTRL>,
+ <&clkc_periphs CLKID_USB_BUS>,
+ <&clkc_periphs CLKID_USB_CTRL_IN>;
+ clock-names = "usb_ctrl", "usb_bus", "xtal_usb_ctrl";
+ resets = <&reset RESET_USBCTRL>;
+ reset-name = "usb_ctrl";
+
+ dr_mode = "otg";
+
+ phys = <&usb2_phy1>;
+ phy-names = "usb2-phy1";
+
+ dwc3: usb@ff400000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0xff400000 0x0 0x100000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ snps,dis_u2_susphy_quirk;
+ snps,quirk-frame-length-adjustment = <0x20>;
+ snps,parkmode-disable-ss-quirk;
+ };
+
+ dwc2: usb@ff500000 {
+ compatible = "amlogic,meson-a1-usb", "snps,dwc2";
+ reg = <0x0 0xff500000 0x0 0x40000>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb2_phy1>;
+ phy-names = "usb2-phy";
+ clocks = <&clkc_periphs CLKID_USB_PHY>;
+ clock-names = "otg";
+ dr_mode = "peripheral";
+ g-rx-fifo-size = <192>;
+ g-np-tx-fifo-size = <128>;
+ g-tx-fifo-size = <128 128 16 16 16>;
};
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 768d0ed78dbe..a49aa62e3f9f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -1908,6 +1908,19 @@
resets = <&reset RESET_SD_EMMC_C>;
};
+ nfc: nand-controller@7800 {
+ compatible = "amlogic,meson-axg-nfc";
+ reg = <0x0 0x7800 0x0 0x100>,
+ <0x0 0x7000 0x0 0x800>;
+ reg-names = "nfc", "emmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_SD_EMMC_C>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "device";
+ };
+
usb2_phy1: phy@9020 {
compatible = "amlogic,meson-gxl-usb2-phy";
#phy-cells = <0>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
index 6a1f4dcf6488..e732df3f3114 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
@@ -15,10 +15,10 @@
compatible = "amlogic,axg-tdm-iface";
#sound-dai-cells = <0>;
sound-name-prefix = "TDM_A";
- clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
- <&clkc_audio AUD_CLKID_MST_A_SCLK>,
- <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
- clock-names = "mclk", "sclk", "lrclk";
+ clocks = <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_A_LRCLK>,
+ <&clkc_audio AUD_CLKID_MST_A_MCLK>;
+ clock-names = "sclk", "lrclk", "mclk";
status = "disabled";
};
@@ -26,10 +26,10 @@
compatible = "amlogic,axg-tdm-iface";
#sound-dai-cells = <0>;
sound-name-prefix = "TDM_B";
- clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
- <&clkc_audio AUD_CLKID_MST_B_SCLK>,
- <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
- clock-names = "mclk", "sclk", "lrclk";
+ clocks = <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_LRCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_MCLK>;
+ clock-names = "sclk", "lrclk", "mclk";
status = "disabled";
};
@@ -37,10 +37,10 @@
compatible = "amlogic,axg-tdm-iface";
#sound-dai-cells = <0>;
sound-name-prefix = "TDM_C";
- clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
- <&clkc_audio AUD_CLKID_MST_C_SCLK>,
- <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
- clock-names = "mclk", "sclk", "lrclk";
+ clocks = <&clkc_audio AUD_CLKID_MST_C_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_C_LRCLK>,
+ <&clkc_audio AUD_CLKID_MST_C_MCLK>;
+ clock-names = "sclk", "lrclk", "mclk";
status = "disabled";
};
};
@@ -195,8 +195,7 @@
};
tdmin_a: audio-controller@300 {
- compatible = "amlogic,g12a-tdmin",
- "amlogic,axg-tdmin";
+ compatible = "amlogic,g12a-tdmin";
reg = <0x0 0x300 0x0 0x40>;
sound-name-prefix = "TDMIN_A";
resets = <&clkc_audio AUD_RESET_TDMIN_A>;
@@ -211,8 +210,7 @@
};
tdmin_b: audio-controller@340 {
- compatible = "amlogic,g12a-tdmin",
- "amlogic,axg-tdmin";
+ compatible = "amlogic,g12a-tdmin";
reg = <0x0 0x340 0x0 0x40>;
sound-name-prefix = "TDMIN_B";
resets = <&clkc_audio AUD_RESET_TDMIN_B>;
@@ -227,8 +225,7 @@
};
tdmin_c: audio-controller@380 {
- compatible = "amlogic,g12a-tdmin",
- "amlogic,axg-tdmin";
+ compatible = "amlogic,g12a-tdmin";
reg = <0x0 0x380 0x0 0x40>;
sound-name-prefix = "TDMIN_C";
resets = <&clkc_audio AUD_RESET_TDMIN_C>;
@@ -243,8 +240,7 @@
};
tdmin_lb: audio-controller@3c0 {
- compatible = "amlogic,g12a-tdmin",
- "amlogic,axg-tdmin";
+ compatible = "amlogic,g12a-tdmin";
reg = <0x0 0x3c0 0x0 0x40>;
sound-name-prefix = "TDMIN_LB";
resets = <&clkc_audio AUD_RESET_TDMIN_LB>;
@@ -272,12 +268,12 @@
status = "disabled";
};
- spdifout: audio-controller@480 {
+ spdifout_a: audio-controller@480 {
compatible = "amlogic,g12a-spdifout",
"amlogic,axg-spdifout";
reg = <0x0 0x480 0x0 0x50>;
#sound-dai-cells = <0>;
- sound-name-prefix = "SPDIFOUT";
+ sound-name-prefix = "SPDIFOUT_A";
clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
clock-names = "pclk", "mclk";
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
index 4b5d11e56364..8355ddd7e9ae 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
@@ -8,6 +8,8 @@
#include "meson-g12a.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+#include <dt-bindings/sound/meson-g12a-toacodec.h>
/ {
compatible = "amlogic,u200", "amlogic,g12a";
@@ -18,6 +20,26 @@
ethernet0 = &ethmac;
};
+ dioo2133: audio-amplifier-0 {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
+ VCC-supply = <&vcc_5v>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "10U2";
+ };
+
+ spdif_dir: audio-codec-0 {
+ compatible = "linux,spdif-dir";
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "DIR";
+ };
+
+ spdif_dit: audio-codec-1 {
+ compatible = "linux,spdif-dit";
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "DIT";
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
@@ -147,6 +169,216 @@
regulator-boot-on;
regulator-always-on;
};
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "U200";
+ audio-widgets = "Line", "Lineout";
+ audio-aux-devs = <&tdmout_a>, <&tdmout_b>, <&tdmout_c>,
+ <&tdmin_a>, <&tdmin_b>, <&tdmin_c>,
+ <&tdmin_lb>, <&dioo2133>;
+ audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0",
+ "TDMOUT_A IN 1", "FRDDR_B OUT 0",
+ "TDMOUT_A IN 2", "FRDDR_C OUT 0",
+ "TDM_A Playback", "TDMOUT_A OUT",
+ "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+ "TDM_B Playback", "TDMOUT_B OUT",
+ "TDMOUT_C IN 0", "FRDDR_A OUT 2",
+ "TDMOUT_C IN 1", "FRDDR_B OUT 2",
+ "TDMOUT_C IN 2", "FRDDR_C OUT 2",
+ "TDM_C Playback", "TDMOUT_C OUT",
+ "SPDIFOUT_A IN 0", "FRDDR_A OUT 3",
+ "SPDIFOUT_A IN 1", "FRDDR_B OUT 3",
+ "SPDIFOUT_A IN 2", "FRDDR_C OUT 3",
+ "SPDIFOUT_B IN 0", "FRDDR_A OUT 4",
+ "SPDIFOUT_B IN 1", "FRDDR_B OUT 4",
+ "SPDIFOUT_B IN 2", "FRDDR_C OUT 4",
+ "TDMIN_A IN 0", "TDM_A Capture",
+ "TDMIN_A IN 1", "TDM_B Capture",
+ "TDMIN_A IN 2", "TDM_C Capture",
+ "TDMIN_A IN 3", "TDM_A Loopback",
+ "TDMIN_A IN 4", "TDM_B Loopback",
+ "TDMIN_A IN 5", "TDM_C Loopback",
+ "TDMIN_B IN 0", "TDM_A Capture",
+ "TDMIN_B IN 1", "TDM_B Capture",
+ "TDMIN_B IN 2", "TDM_C Capture",
+ "TDMIN_B IN 3", "TDM_A Loopback",
+ "TDMIN_B IN 4", "TDM_B Loopback",
+ "TDMIN_B IN 5", "TDM_C Loopback",
+ "TDMIN_C IN 0", "TDM_A Capture",
+ "TDMIN_C IN 1", "TDM_B Capture",
+ "TDMIN_C IN 2", "TDM_C Capture",
+ "TDMIN_C IN 3", "TDM_A Loopback",
+ "TDMIN_C IN 4", "TDM_B Loopback",
+ "TDMIN_C IN 5", "TDM_C Loopback",
+ "TDMIN_LB IN 3", "TDM_A Capture",
+ "TDMIN_LB IN 4", "TDM_B Capture",
+ "TDMIN_LB IN 5", "TDM_C Capture",
+ "TDMIN_LB IN 0", "TDM_A Loopback",
+ "TDMIN_LB IN 1", "TDM_B Loopback",
+ "TDMIN_LB IN 2", "TDM_C Loopback",
+ "TODDR_A IN 0", "TDMIN_A OUT",
+ "TODDR_B IN 0", "TDMIN_A OUT",
+ "TODDR_C IN 0", "TDMIN_A OUT",
+ "TODDR_A IN 1", "TDMIN_B OUT",
+ "TODDR_B IN 1", "TDMIN_B OUT",
+ "TODDR_C IN 1", "TDMIN_B OUT",
+ "TODDR_A IN 2", "TDMIN_C OUT",
+ "TODDR_B IN 2", "TDMIN_C OUT",
+ "TODDR_C IN 2", "TDMIN_C OUT",
+ "TODDR_A IN 3", "SPDIFIN Capture",
+ "TODDR_B IN 3", "SPDIFIN Capture",
+ "TODDR_C IN 3", "SPDIFIN Capture",
+ "TODDR_A IN 6", "TDMIN_LB OUT",
+ "TODDR_B IN 6", "TDMIN_LB OUT",
+ "TODDR_C IN 6", "TDMIN_LB OUT",
+ "10U2 INL", "ACODEC LOLP",
+ "10U2 INR", "ACODEC LORP",
+ "Lineout", "10U2 OUTL",
+ "Lineout", "10U2 OUTR";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ dai-link-3 {
+ sound-dai = <&toddr_a>;
+ };
+
+ dai-link-4 {
+ sound-dai = <&toddr_b>;
+ };
+
+ dai-link-5 {
+ sound-dai = <&toddr_c>;
+ };
+
+ /* Connected to the WIFI/BT chip */
+ dai-link-6 {
+ sound-dai = <&tdmif_a>;
+ dai-format = "dsp_a";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ mclk-fs = <256>;
+
+ codec-0 {
+ sound-dai = <&toacodec TOACODEC_IN_A>;
+ };
+
+ codec-1 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>;
+ };
+ };
+
+ /* Connected to the onboard AD82584F DAC */
+ dai-link-7 {
+ sound-dai = <&tdmif_b>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ mclk-fs = <256>;
+
+ codec-0 {
+ sound-dai = <&toacodec TOACODEC_IN_B>;
+ };
+
+ codec-1 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+ };
+ };
+
+ /* 8ch HDMI interface */
+ dai-link-8 {
+ sound-dai = <&tdmif_c>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ dai-tdm-slot-tx-mask-1 = <1 1>;
+ dai-tdm-slot-tx-mask-2 = <1 1>;
+ dai-tdm-slot-tx-mask-3 = <1 1>;
+ mclk-fs = <256>;
+
+ codec-0 {
+ sound-dai = <&toacodec TOACODEC_IN_C>;
+ };
+
+ codec-1 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_C>;
+ };
+ };
+
+ /* spdif hdmi and coax output */
+ dai-link-9 {
+ sound-dai = <&spdifout_a>;
+
+ codec-0 {
+ sound-dai = <&spdif_dit>;
+ };
+
+ codec-1 {
+ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_A>;
+ };
+ };
+
+ /* spdif hdmi interface */
+ dai-link-10 {
+ sound-dai = <&spdifout_b>;
+
+ codec {
+ sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_B>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-11 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+
+ /* internal codec glue */
+ dai-link-12 {
+ sound-dai = <&toacodec TOACODEC_OUT>;
+
+ codec {
+ sound-dai = <&acodec>;
+ };
+ };
+
+ /* spdif coax input */
+ dai-link-13 {
+ sound-dai = <&spdifin>;
+
+ codec {
+ sound-dai = <&spdif_dir>;
+ };
+ };
+ };
+};
+
+&acodec {
+ status = "okay";
+};
+
+&arb {
+ status = "okay";
};
&cec_AO {
@@ -163,6 +395,10 @@
hdmi-phandle = <&hdmi_tx>;
};
+&clkc_audio {
+ status = "okay";
+};
+
&cpu0 {
cpu-supply = <&vddcpu>;
operating-points-v2 = <&cpu_opp_table>;
@@ -191,6 +427,10 @@
clock-latency = <50000>;
};
+&clkc_audio {
+ status = "okay";
+};
+
&cvbs_vdac_port {
cvbs_vdac_out: endpoint {
remote-endpoint = <&cvbs_connector_in>;
@@ -203,6 +443,18 @@
phy-mode = "rmii";
};
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
&hdmi_tx {
status = "okay";
pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
@@ -288,6 +540,95 @@
vqmmc-supply = <&flash_1v8>;
};
+&spdifin {
+ pinctrl-0 = <&spdif_in_h_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&spdifout_a {
+ pinctrl-0 = <&spdif_ao_out_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&spdifout_b {
+ status = "okay";
+};
+
+&tdmif_a {
+ pinctrl-0 = <&tdm_a_fs_pins>, <&tdm_a_sclk_pins>, <&tdm_a_dout0_pins> ;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&tdmif_b {
+ pinctrl-0 = <&mclk0_a_pins>, <&tdm_b_fs_pins>, <&tdm_b_sclk_pins>,
+ <&tdm_b_dout0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ assigned-clocks = <&clkc_audio AUD_CLKID_TDM_MCLK_PAD0>,
+ <&clkc_audio AUD_CLKID_TDM_SCLK_PAD1>,
+ <&clkc_audio AUD_CLKID_TDM_LRCLK_PAD1>;
+ assigned-clock-parents = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
+ assigned-clock-rates = <0>, <0>, <0>;
+};
+
+&tdmif_c {
+ status = "okay";
+};
+
+&tdmin_a {
+ status = "okay";
+};
+
+&tdmin_b {
+ status = "okay";
+};
+
+&tdmin_c {
+ status = "okay";
+};
+
+&tdmin_lb {
+ status = "okay";
+};
+
+&tdmout_a {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tdmout_c {
+ status = "okay";
+};
+
+&toacodec {
+ status = "okay";
+};
+
+&toddr_a {
+ status = "okay";
+};
+
+&toddr_b {
+ status = "okay";
+};
+
+&toddr_c {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
+
&uart_AO {
status = "okay";
pinctrl-0 = <&uart_ao_a_pins>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
index 7ca904f5acbb..4969a76460fa 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
@@ -155,9 +155,9 @@
"TDMOUT_B IN 1", "FRDDR_B OUT 1",
"TDMOUT_B IN 2", "FRDDR_C OUT 1",
"TDM_B Playback", "TDMOUT_B OUT",
- "SPDIFOUT IN 0", "FRDDR_A OUT 3",
- "SPDIFOUT IN 1", "FRDDR_B OUT 3",
- "SPDIFOUT IN 2", "FRDDR_C OUT 3";
+ "SPDIFOUT_A IN 0", "FRDDR_A OUT 3",
+ "SPDIFOUT_A IN 1", "FRDDR_B OUT 3",
+ "SPDIFOUT_A IN 2", "FRDDR_C OUT 3";
assigned-clocks = <&clkc CLKID_MPLL2>,
<&clkc CLKID_MPLL0>,
@@ -196,7 +196,7 @@
/* spdif hdmi or toslink interface */
dai-link-4 {
- sound-dai = <&spdifout>;
+ sound-dai = <&spdifout_a>;
codec-0 {
sound-dai = <&spdif_dit>;
@@ -456,7 +456,7 @@
vqmmc-supply = <&flash_1v8>;
};
-&spdifout {
+&spdifout_a {
pinctrl-0 = <&spdif_out_h_pins>;
pinctrl-names = "default";
status = "okay";
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-libretech-cc.dts
new file mode 100644
index 000000000000..65b963d794cd
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-libretech-cc.dts
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/clock/g12a-clkc.h>
+#include "meson-g12b-a311d.dtsi"
+#include "meson-libretech-cottonwood.dtsi"
+
+/ {
+ compatible = "libretech,aml-a311d-cc", "amlogic,a311d", "amlogic,g12b";
+ model = "Libre Computer AML-A311D-CC Alta";
+
+ vddcpu_a: regulator-vddcpu-a {
+ compatible = "pwm-regulator";
+ regulator-name = "VDDCPU_A";
+ regulator-min-microvolt = <730000>;
+ regulator-max-microvolt = <1011000>;
+ regulator-boot-on;
+ regulator-always-on;
+ pwm-supply = <&dc_in>;
+ pwms = <&pwm_ab 0 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+ };
+
+ sound {
+ model = "LC-ALTA";
+ audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0",
+ "TDMOUT_A IN 1", "FRDDR_B OUT 0",
+ "TDMOUT_A IN 2", "FRDDR_C OUT 0",
+ "TDM_A Playback", "TDMOUT_A OUT",
+ "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+ "TDM_B Playback", "TDMOUT_B OUT",
+ "TDMOUT_C IN 0", "FRDDR_A OUT 2",
+ "TDMOUT_C IN 1", "FRDDR_B OUT 2",
+ "TDMOUT_C IN 2", "FRDDR_C OUT 2",
+ "TDM_C Playback", "TDMOUT_C OUT",
+ "TDMIN_A IN 0", "TDM_A Capture",
+ "TDMIN_B IN 0", "TDM_A Capture",
+ "TDMIN_C IN 0", "TDM_A Capture",
+ "TDMIN_A IN 3", "TDM_A Loopback",
+ "TDMIN_B IN 3", "TDM_A Loopback",
+ "TDMIN_C IN 3", "TDM_A Loopback",
+ "TDMIN_A IN 1", "TDM_B Capture",
+ "TDMIN_B IN 1", "TDM_B Capture",
+ "TDMIN_C IN 1", "TDM_B Capture",
+ "TDMIN_A IN 4", "TDM_B Loopback",
+ "TDMIN_B IN 4", "TDM_B Loopback",
+ "TDMIN_C IN 4", "TDM_B Loopback",
+ "TDMIN_A IN 2", "TDM_C Capture",
+ "TDMIN_B IN 2", "TDM_C Capture",
+ "TDMIN_C IN 2", "TDM_C Capture",
+ "TDMIN_A IN 5", "TDM_C Loopback",
+ "TDMIN_B IN 5", "TDM_C Loopback",
+ "TDMIN_C IN 5", "TDM_C Loopback",
+ "TODDR_A IN 0", "TDMIN_A OUT",
+ "TODDR_B IN 0", "TDMIN_A OUT",
+ "TODDR_C IN 0", "TDMIN_A OUT",
+ "TODDR_A IN 1", "TDMIN_B OUT",
+ "TODDR_B IN 1", "TDMIN_B OUT",
+ "TODDR_C IN 1", "TDMIN_B OUT",
+ "TODDR_A IN 2", "TDMIN_C OUT",
+ "TODDR_B IN 2", "TDMIN_C OUT",
+ "TODDR_C IN 2", "TDMIN_C OUT",
+ "Lineout", "ACODEC LOLP",
+ "Lineout", "ACODEC LORP";
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu100 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu101 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu102 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu103 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&pwm_ab {
+ pinctrl-0 = <&pwm_a_e_pins>, <&pwm_b_x7_pins>;
+ clocks = <&xtal>, <&xtal>;
+ clock-names = "clkin0", "clkin1";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
index 3e826095e792..8fc2e143cb54 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
@@ -34,9 +34,9 @@
"TDMOUT_B IN 1", "FRDDR_B OUT 1",
"TDMOUT_B IN 2", "FRDDR_C OUT 1",
"TDM_B Playback", "TDMOUT_B OUT",
- "SPDIFOUT IN 0", "FRDDR_A OUT 3",
- "SPDIFOUT IN 1", "FRDDR_B OUT 3",
- "SPDIFOUT IN 2", "FRDDR_C OUT 3";
+ "SPDIFOUT_A IN 0", "FRDDR_A OUT 3",
+ "SPDIFOUT_A IN 1", "FRDDR_B OUT 3",
+ "SPDIFOUT_A IN 2", "FRDDR_C OUT 3";
assigned-clocks = <&clkc CLKID_MPLL2>,
<&clkc CLKID_MPLL0>,
@@ -75,7 +75,7 @@
/* spdif hdmi or toslink interface */
dai-link-4 {
- sound-dai = <&spdifout>;
+ sound-dai = <&spdifout_a>;
codec-0 {
sound-dai = <&spdif_dit>;
@@ -139,7 +139,7 @@
};
};
-&spdifout {
+&spdifout_a {
pinctrl-0 = <&spdif_out_h_pins>;
pinctrl-names = "default";
status = "okay";
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts
index 098a3af6d381..ce548b373296 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts
@@ -29,9 +29,9 @@
"TDMOUT_B IN 1", "FRDDR_B OUT 1",
"TDMOUT_B IN 2", "FRDDR_C OUT 1",
"TDM_B Playback", "TDMOUT_B OUT",
- "SPDIFOUT IN 0", "FRDDR_A OUT 3",
- "SPDIFOUT IN 1", "FRDDR_B OUT 3",
- "SPDIFOUT IN 2", "FRDDR_C OUT 3";
+ "SPDIFOUT_A IN 0", "FRDDR_A OUT 3",
+ "SPDIFOUT_A IN 1", "FRDDR_B OUT 3",
+ "SPDIFOUT_A IN 2", "FRDDR_C OUT 3";
assigned-clocks = <&clkc CLKID_MPLL2>,
<&clkc CLKID_MPLL0>,
@@ -70,7 +70,7 @@
/* spdif hdmi or toslink interface */
dai-link-4 {
- sound-dai = <&spdifout>;
+ sound-dai = <&spdifout_a>;
codec-0 {
sound-dai = <&spdif_dit>;
@@ -125,7 +125,7 @@
linux,rc-map-name = "rc-khadas";
};
-&spdifout {
+&spdifout_a {
pinctrl-0 = <&spdif_out_h_pins>;
pinctrl-names = "default";
status = "okay";
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
index 3c93d1898b40..292c718ee19c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
@@ -9,11 +9,19 @@
#include "meson-gxbb-p20x.dtsi"
#include <dt-bindings/input/input.h>
+#include <dt-bindings/sound/meson-aiu.h>
/ {
compatible = "amlogic,p200", "amlogic,meson-gxbb";
model = "Amlogic Meson GXBB P200 Development Board";
+ spdif_dit: audio-codec-0 {
+ #sound-dai-cells = <0>;
+ compatible = "linux,spdif-dit";
+ status = "okay";
+ sound-name-prefix = "DIT";
+ };
+
avdd18_usb_adc: regulator-avdd18_usb_adc {
compatible = "regulator-fixed";
regulator-name = "AVDD18_USB_ADC";
@@ -57,6 +65,58 @@
press-threshold-microvolt = <0>; /* 0% */
};
};
+
+ sound {
+ compatible = "amlogic,gx-sound-card";
+ model = "P200";
+ assigned-clocks = <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>,
+ <&clkc CLKID_MPLL2>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+
+ dai-link-0 {
+ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
+ dai-format = "i2s";
+ mclk-fs = <256>;
+
+ codec-0 {
+ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
+ };
+ };
+
+ dai-link-3 {
+ sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
+
+ codec-0 {
+ sound-dai = <&spdif_dit>;
+ };
+ };
+
+ dai-link-4 {
+ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
+
+ codec-0 {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&aiu {
+ status = "okay";
+ pinctrl-0 = <&spdif_out_y_pins>;
+ pinctrl-names = "default";
};
&ethmac {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
index 150a82f3b2d7..6f81eed83bec 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
@@ -8,10 +8,49 @@
/dts-v1/;
#include "meson-gxbb-p20x.dtsi"
+#include <dt-bindings/sound/meson-aiu.h>
/ {
compatible = "amlogic,p201", "amlogic,meson-gxbb";
model = "Amlogic Meson GXBB P201 Development Board";
+
+ sound {
+ compatible = "amlogic,gx-sound-card";
+ model = "P201";
+ assigned-clocks = <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>,
+ <&clkc CLKID_MPLL2>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+
+ dai-link-0 {
+ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
+ dai-format = "i2s";
+ mclk-fs = <256>;
+
+ codec-0 {
+ sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
+ };
+ };
+
+ dai-link-2 {
+ sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
+
+ codec-0 {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&aiu {
+ status = "okay";
};
&ethmac {
diff --git a/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi b/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
new file mode 100644
index 000000000000..35e8f5bae990
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
@@ -0,0 +1,614 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#include <dt-bindings/clock/g12a-clkc.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-toacodec.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ aliases {
+ serial0 = &uart_AO;
+ ethernet0 = &ethmac;
+ spi0 = &spifc;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ dioo2133: audio-amplifier-0 {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio GPIOX_0 GPIO_ACTIVE_HIGH>;
+ VCC-supply = <&vcc_5v>;
+ sound-name-prefix = "10U2";
+ };
+
+ /* TOFIX: handle CVBS_DET on SARADC channel 0 */
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+
+ led-blue {
+ compatible = "pwm-leds";
+
+ led {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_ACTIVITY;
+ linux,default-trigger = "heartbeat";
+ max-brightness = <255>;
+ pwms = <&pwm_ab 1 1250 0>;
+ active-low;
+ };
+ };
+
+ led-green {
+ compatible = "pwm-leds";
+
+ led {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ linux,default-trigger = "default-on";
+ max-brightness = <255>;
+ pwms = <&pwm_cd 1 1250 0>;
+ active-low;
+ };
+ };
+
+ led-orange {
+ compatible = "gpio-leds";
+
+ led {
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_STANDBY;
+ gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ panic-indicator;
+ };
+ };
+
+ dc_in: regulator-dc-in {
+ compatible = "regulator-fixed";
+ regulator-name = "5V_IN";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ flash_1v8: regulator-flash-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "FLASH_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ vin-supply = <&vcc_3v3>;
+ };
+
+ vcc_card: regulator-vcc-card {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_CARD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vddao_3v3>;
+ gpio = <&gpio GPIOX_2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ enable-active-high;
+ gpio-open-drain;
+ };
+
+ vcc_3v3: regulator-vcc-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ vin-supply = <&vddao_3v3>;
+
+ /* FIXME: controlled by TEST_N */
+ };
+
+ vcc_5v: regulator-vcc-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&dc_in>;
+ gpio = <&gpio GPIOH_8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ enable-active-high;
+ gpio-open-drain;
+ };
+
+ vddao_3v3: regulator-vddao_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ vin-supply = <&dc_in>;
+ };
+
+ vddcpu_b: regulator-vddcpu-b {
+ compatible = "pwm-regulator";
+ regulator-name = "VDDCPU_B";
+ regulator-min-microvolt = <730000>;
+ regulator-max-microvolt = <1011000>;
+ regulator-boot-on;
+ regulator-always-on;
+ pwm-supply = <&dc_in>;
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+ };
+
+ vddio_ao18: regulator-vddio_ao18 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_AO18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ vin-supply = <&vddao_3v3>;
+ };
+
+ vddio_c: regulator-vddio_c {
+ compatible = "regulator-gpio";
+ regulator-name = "VDDIO_C";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-settling-time-up-us = <200>;
+ regulator-settling-time-down-us = <50000>;
+ vin-supply = <&vddao_3v3>;
+ gpios = <&gpio GPIOX_4 GPIO_ACTIVE_HIGH>;
+ states = <3300000 0>,
+ <1800000 1>;
+ };
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ audio-widgets = "Line", "Lineout";
+ audio-aux-devs = <&tdmout_a>, <&tdmout_b>, <&tdmout_c>,
+ <&tdmin_a>, <&tdmin_b>, <&tdmin_c>,
+ <&dioo2133>;
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ dai-link-3 {
+ sound-dai = <&toddr_a>;
+ };
+
+ dai-link-4 {
+ sound-dai = <&toddr_b>;
+ };
+
+ dai-link-5 {
+ sound-dai = <&toddr_c>;
+ };
+
+ /*
+ * Audio setup: The 40 pins header provides access to 2 TDMs,
+ * SPDIF In/Out and PDM inputs.
+ * - TDM A: 2 lanes
+ * D0: 40/X9
+ * D1: 38/X8
+ * BCLK: 12/X11
+ * FS: 35/X10
+ * - TDM B: 4 lanes
+ * D0: 37/A3
+ * D1: 16/A4
+ * D2: 18/A5 or 7/AO6
+ * D3: 22/A6 or 21/H5
+ * BCLK: 29/A1 or 8/AO8
+ * FS: 31/A2 or 11/AO7
+ * - 2 Master Clocks:
+ * MCLK0: 15/A0 or 10/AO9
+ * MCLK1: 33/X15
+ * - SPDIF:
+ * OUT: 32/A11
+ * IN: 21/H5
+ * - PDM Input:
+ * DO: 13/A8
+ * D1: 26/A9
+ * D2: 22/A6
+ * D3: 18/A5
+ * DCLK: 36/A7
+ *
+ * TDM C is not usable on the 40 pins connector so it is
+ * setup for the HDMI 4 lanes i2s.
+ *
+ * No pinctrl is enabled by default to preserve the
+ * genericity of the 40 pins header. Many configurations are
+ * possible based on the desired use case. Please adjust TDM
+ * masks, clock setups and pinctrl accordingly.
+ */
+
+ dai-link-6 {
+ sound-dai = <&tdmif_a>;
+ dai-format = "dsp_a";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ mclk-fs = <256>;
+
+ codec-0 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>;
+ };
+
+ codec-1 {
+ sound-dai = <&toacodec TOACODEC_IN_A>;
+ };
+ };
+
+ dai-link-7 {
+ sound-dai = <&tdmif_b>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ dai-tdm-slot-rx-mask-1 = <1 1>;
+ mclk-fs = <256>;
+
+ codec-0 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+ };
+
+ codec-1 {
+ sound-dai = <&toacodec TOACODEC_IN_B>;
+ };
+ };
+
+ dai-link-8 {
+ sound-dai = <&tdmif_c>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ dai-tdm-slot-tx-mask-1 = <1 1>;
+ dai-tdm-slot-tx-mask-2 = <1 1>;
+ dai-tdm-slot-tx-mask-3 = <1 1>;
+ mclk-fs = <256>;
+
+ codec-0 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_C>;
+ };
+
+ codec-1 {
+ sound-dai = <&toacodec TOACODEC_IN_C>;
+ };
+ };
+
+ dai-link-9 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+
+ dai-link-10 {
+ sound-dai = <&toacodec TOACODEC_OUT>;
+
+ codec {
+ sound-dai = <&acodec>;
+ };
+ };
+ };
+};
+
+&acodec {
+ status = "okay";
+ AVDD-supply = <&vddio_ao18>;
+};
+
+&arb {
+ status = "okay";
+};
+
+&cecb_AO {
+ status = "okay";
+ pinctrl-0 = <&cec_ao_b_h_pins>;
+ pinctrl-names = "default";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
+};
+
+&dwc3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hub: hub@1 {
+ compatible = "usb5e3,626";
+ reg = <1>;
+ reset-gpios = <&gpio GPIOC_7 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+ vdd-supply = <&vcc_5v>;
+ };
+};
+
+&ethmac {
+ pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>, <&eth_phy_irq_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy-mode = "rgmii";
+ phy-handle = <&external_phy>;
+ amlogic,tx-delay-ns = <2>;
+};
+
+&ext_mdio {
+ external_phy: ethernet-phy@0 {
+ /* Realtek RTL8211F (0x001cc916) */
+ reg = <0>;
+ max-speed = <1000>;
+
+ reset-assert-us = <100000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+ interrupt-parent = <&gpio_intc>;
+ /* MAC_INTR on GPIOZ_14 */
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+ pinctrl-names = "default";
+ hdmi-supply = <&vcc_5v>;
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+&periphs_pinctrl {
+ spi_cs_disable_pins: spi-cs-disable {
+ mux {
+ groups = "BOOT_14";
+ function = "gpio_periphs";
+ bias-disable;
+ output-high;
+ };
+ };
+
+ eth_phy_irq_pins: eth-phy-irq {
+ mux {
+ groups = "GPIOZ_14";
+ function = "gpio_periphs";
+ bias-pull-up;
+ output-disable;
+ };
+ };
+};
+
+&pwm_AO_cd {
+ status = "okay";
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+};
+
+&pwm_ab {
+ status = "okay";
+ pinctrl-0 = <&pwm_b_x7_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+};
+
+&pwm_cd {
+ status = "okay";
+ pinctrl-0 = <&pwm_d_x3_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+};
+
+&saradc {
+ status = "okay";
+ vref-supply = <&vddio_ao18>;
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_c_pins>;
+ pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ max-frequency = <200000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&vcc_card>;
+ vqmmc-supply = <&vddio_c>;
+};
+
+/*
+ * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR CS
+ * and eMMC Data 4 to 7 pins.
+ * Replace emmc_data_8b_pins to emmc_data_4b_pins from sd_emmc_c pinctrl-0,
+ * and change bus-width to 4 then spifc can be enabled.
+ */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>,
+ <&spi_cs_disable_pins>;
+ pinctrl-1 = <&emmc_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-hs200-1_8v;
+ max-frequency = <200000000>;
+ disable-wp;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&flash_1v8>;
+};
+
+&spifc {
+ status = "disabled";
+ pinctrl-0 = <&nor_pins>;
+ pinctrl-names = "default";
+ cs-gpios = <&gpio BOOT_14 GPIO_ACTIVE_LOW>;
+
+ w25lq128d: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <80000000>;
+ };
+};
+
+&tdmif_a {
+ status = "okay";
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmif_c {
+ status = "okay";
+};
+
+&tdmin_a {
+ status = "okay";
+};
+
+&tdmin_b {
+ status = "okay";
+};
+
+&tdmin_c {
+ status = "okay";
+};
+
+&tdmout_a {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tdmout_c {
+ status = "okay";
+};
+
+&toacodec {
+ status = "okay";
+};
+
+&toddr_a {
+ status = "okay";
+};
+
+&toddr_b {
+ status = "okay";
+};
+
+&toddr_c {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&usb2_phy1 {
+ phy-supply = <&dc_in>;
+};
+
+&usb3_pcie_phy {
+ phy-supply = <&vcc_5v>;
+};
+
+&usb {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
index 8ffbcb2b1ac5..c1f322c73982 100644
--- a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
@@ -28,3 +28,9 @@
&uart_B {
status = "okay";
};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_pins>;
+ pinctrl-names = "default";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
index f24460186d3d..e0cfc54ebccb 100644
--- a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -106,6 +106,14 @@
#gpio-cells = <2>;
gpio-ranges = <&periphs_pinctrl 0 0 82>;
};
+
+ remote_pins: remote-pin {
+ mux {
+ groups = "remote_in";
+ function = "remote_in";
+ bias-disable;
+ };
+ };
};
gpio_intc: interrupt-controller@4080 {
@@ -133,6 +141,18 @@
reg = <0x0 0x2000 0x0 0x98>;
#reset-cells = <1>;
};
+
+ ir: ir@84040 {
+ compatible = "amlogic,meson-s4-ir";
+ reg = <0x0 0x84040 0x0 0x30>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ hwrng: rng@440788 {
+ compatible = "amlogic,meson-s4-rng";
+ reg = <0x0 0x440788 0x0 0x0c>;
+ };
};
};
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-s905d3-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-s905d3-libretech-cc.dts
new file mode 100644
index 000000000000..537370db360f
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-s905d3-libretech-cc.dts
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/clock/g12a-clkc.h>
+#include "meson-sm1.dtsi"
+#include "meson-libretech-cottonwood.dtsi"
+
+/ {
+ compatible = "libretech,aml-s905d3-cc", "amlogic,sm1";
+ model = "Libre Computer AML-S905D3-CC Solitude";
+
+ sound {
+ model = "LC-SOLITUDE";
+ audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0",
+ "TDMOUT_A IN 1", "FRDDR_B OUT 0",
+ "TDMOUT_A IN 2", "FRDDR_C OUT 0",
+ "TDM_A Playback", "TDMOUT_A OUT",
+ "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+ "TDM_B Playback", "TDMOUT_B OUT",
+ "TDMOUT_C IN 0", "FRDDR_A OUT 2",
+ "TDMOUT_C IN 1", "FRDDR_B OUT 2",
+ "TDMOUT_C IN 2", "FRDDR_C OUT 2",
+ "TDM_C Playback", "TDMOUT_C OUT",
+ "TDMIN_A IN 0", "TDM_A Capture",
+ "TDMIN_B IN 0", "TDM_A Capture",
+ "TDMIN_C IN 0", "TDM_A Capture",
+ "TDMIN_A IN 13", "TDM_A Loopback",
+ "TDMIN_B IN 13", "TDM_A Loopback",
+ "TDMIN_C IN 13", "TDM_A Loopback",
+ "TDMIN_A IN 1", "TDM_B Capture",
+ "TDMIN_B IN 1", "TDM_B Capture",
+ "TDMIN_C IN 1", "TDM_B Capture",
+ "TDMIN_A IN 14", "TDM_B Loopback",
+ "TDMIN_B IN 14", "TDM_B Loopback",
+ "TDMIN_C IN 14", "TDM_B Loopback",
+ "TDMIN_A IN 2", "TDM_C Capture",
+ "TDMIN_B IN 2", "TDM_C Capture",
+ "TDMIN_C IN 2", "TDM_C Capture",
+ "TDMIN_A IN 15", "TDM_C Loopback",
+ "TDMIN_B IN 15", "TDM_C Loopback",
+ "TDMIN_C IN 15", "TDM_C Loopback",
+ "TODDR_A IN 0", "TDMIN_A OUT",
+ "TODDR_B IN 0", "TDMIN_A OUT",
+ "TODDR_C IN 0", "TDMIN_A OUT",
+ "TODDR_A IN 1", "TDMIN_B OUT",
+ "TODDR_B IN 1", "TDMIN_B OUT",
+ "TODDR_C IN 1", "TDMIN_B OUT",
+ "TODDR_A IN 2", "TDMIN_C OUT",
+ "TODDR_B IN 2", "TDMIN_C OUT",
+ "TODDR_C IN 2", "TDMIN_C OUT",
+ "Lineout", "ACODEC LOLP",
+ "Lineout", "ACODEC LORP";
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU1_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu2 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU2_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu3 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU3_CLK>;
+ clock-latency = <50000>;
+};
diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
index 377660d705d1..65ebac3082e2 100644
--- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
@@ -728,7 +728,7 @@
};
};
- sbgpio: gpio@17001000{
+ sbgpio: gpio@17001000 {
compatible = "apm,xgene-gpio-sb";
reg = <0x0 0x17001000 0x0 0x400>;
#gpio-cells = <2>;
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index efa79209f4b2..988928c60f15 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -946,7 +946,7 @@
dr_mode = "host";
};
- sbgpio: gpio@17001000{
+ sbgpio: gpio@17001000 {
compatible = "apm,xgene-gpio-sb";
reg = <0x0 0x17001000 0x0 0x400>;
#gpio-cells = <2>;
diff --git a/arch/arm64/boot/dts/bitmain/bm1880.dtsi b/arch/arm64/boot/dts/bitmain/bm1880.dtsi
index 53a9b76057aa..22a200fb07d2 100644
--- a/arch/arm64/boot/dts/bitmain/bm1880.dtsi
+++ b/arch/arm64/boot/dts/bitmain/bm1880.dtsi
@@ -184,7 +184,7 @@
status = "disabled";
};
- uart1: serial@5801A000 {
+ uart1: serial@5801a000 {
compatible = "snps,dw-apb-uart";
reg = <0x0 0x5801a000 0x0 0x2000>;
clocks = <&clk BM1880_CLK_UART_500M>,
@@ -197,7 +197,7 @@
status = "disabled";
};
- uart2: serial@5801C000 {
+ uart2: serial@5801c000 {
compatible = "snps,dw-apb-uart";
reg = <0x0 0x5801c000 0x0 0x2000>;
clocks = <&clk BM1880_CLK_UART_500M>,
@@ -210,7 +210,7 @@
status = "disabled";
};
- uart3: serial@5801E000 {
+ uart3: serial@5801e000 {
compatible = "snps,dw-apb-uart";
reg = <0x0 0x5801e000 0x0 0x2000>;
clocks = <&clk BM1880_CLK_UART_500M>,
diff --git a/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
index fbf0392b8371..dec5a110f1e8 100644
--- a/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
@@ -113,7 +113,6 @@
spi-max-frequency = <5000000>;
spi-cpha;
spi-cpol;
- pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,slave-tx-disable = <0>;
pl022,com-mode = <0>;
@@ -137,7 +136,6 @@
at25,page-size = <64>;
spi-cpha;
spi-cpol;
- pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,slave-tx-disable = <0>;
pl022,com-mode = <0>;
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
index d163891cd399..8f02de8480b6 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
@@ -124,19 +124,18 @@
audio-amplifier = <&max98504>;
mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
model = "wm5110";
- samsung,audio-routing =
- /* Headphone */
- "HP", "HPOUT1L",
- "HP", "HPOUT1R",
-
- /* Speaker */
- "SPK", "SPKOUT",
- "SPKOUT", "HPOUT2L",
- "SPKOUT", "HPOUT2R",
-
- /* Receiver */
- "RCV", "HPOUT3L",
- "RCV", "HPOUT3R";
+ audio-routing = /* Headphone */
+ "HP", "HPOUT1L",
+ "HP", "HPOUT1R",
+
+ /* Speaker */
+ "SPK", "SPKOUT",
+ "SPKOUT", "HPOUT2L",
+ "SPKOUT", "HPOUT2R",
+
+ /* Receiver */
+ "RCV", "HPOUT3L",
+ "RCV", "HPOUT3R";
};
};
@@ -1103,7 +1102,7 @@
te_irq: te-irq-pins {
samsung,pins = "gpf1-3";
- samsung,pin-function = <0xf>;
+ samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
};
};
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index 54ed5167d0f6..6ed80ddf3369 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -25,7 +25,6 @@
pinctrl6 = &pinctrl_fsys0;
pinctrl7 = &pinctrl_fsys1;
pinctrl8 = &pinctrl_bus1;
- tmuctrl0 = &tmuctrl_0;
};
arm-pmu {
diff --git a/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts b/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
index 6ed38912507f..f074df8982b3 100644
--- a/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
+++ b/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
@@ -29,6 +29,22 @@
stdout-path = &serial_0;
};
+ connector {
+ compatible = "gpio-usb-b-connector", "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+ vbus-supply = <&reg_usb_host_vbus>;
+ id-gpios = <&gpa0 0 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&micro_usb_det_pins>;
+
+ port {
+ usb_dr_connector: endpoint {
+ remote-endpoint = <&usb1_drd_sw>;
+ };
+ };
+ };
+
/*
* RAM: 4 GiB (eMCP):
* - 2 GiB at 0x80000000
@@ -111,6 +127,35 @@
};
};
+ /* TODO: Remove this once PMIC is implemented */
+ reg_dummy: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "dummy_reg";
+ };
+
+ reg_usb_host_vbus: regulator-1 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_host_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpa3 5 GPIO_ACTIVE_LOW>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+
+ ramoops@f0000000 {
+ compatible = "ramoops";
+ reg = <0x0 0xf0000000 0x200000>;
+ record-size = <0x20000>;
+ console-size = <0x20000>;
+ ftrace-size = <0x100000>;
+ pmsg-size = <0x20000>;
+ };
+ };
+
/*
* RTC clock (XrtcXTI); external, must be 32.768 kHz.
*
@@ -172,6 +217,12 @@
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
+
+ micro_usb_det_pins: micro-usb-det-pins {
+ samsung,pins = "gpa0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
};
&rtc {
@@ -186,6 +237,28 @@
pinctrl-0 = <&uart1_pins>;
};
+&usbdrd {
+ status = "okay";
+ vdd10-supply = <&reg_dummy>;
+ vdd33-supply = <&reg_dummy>;
+};
+
+&usbdrd_dwc3 {
+ dr_mode = "otg";
+ usb-role-switch;
+ role-switch-default-mode = "host";
+
+ port {
+ usb1_drd_sw: endpoint {
+ remote-endpoint = <&usb_dr_connector>;
+ };
+ };
+};
+
+&usbdrd_phy {
+ status = "okay";
+};
+
&usi_uart {
samsung,clkreq-on; /* needed for UART mode */
status = "okay";
diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
index aa077008b3be..53104e65b9c6 100644
--- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -570,6 +570,36 @@
clocks = <&cmu_cmgp CLK_GOUT_SYSREG_CMGP_PCLK>;
};
+ usbdrd: usb@13600000 {
+ compatible = "samsung,exynos850-dwusb3";
+ ranges = <0x0 0x13600000 0x10000>;
+ clocks = <&cmu_hsi CLK_GOUT_USB_BUS_EARLY_CLK>,
+ <&cmu_hsi CLK_GOUT_USB_REF_CLK>;
+ clock-names = "bus_early", "ref";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+
+ usbdrd_dwc3: usb@0 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x10000>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usbdrd_phy 0>;
+ phy-names = "usb2-phy";
+ };
+ };
+
+ usbdrd_phy: phy@135d0000 {
+ compatible = "samsung,exynos850-usbdrd-phy";
+ reg = <0x135d0000 0x100>;
+ clocks = <&cmu_hsi CLK_GOUT_USB_PHY_ACLK>,
+ <&cmu_hsi CLK_GOUT_USB_PHY_REF_CLK>;
+ clock-names = "phy", "ref";
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
usi_uart: usi@138200c0 {
compatible = "samsung,exynos850-usi";
reg = <0x138200c0 0x20>;
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 89aee6c92576..300049037eb0 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -15,12 +15,15 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-tqmls1043a-mbls10xxa.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-frwy.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-tqmls1046a-mbls10xxa.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-rdb.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-ten64.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-tqmls1088a-mbls10xxa.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2081a-rdb.dtb
@@ -33,6 +36,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-clearfog-cx.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-honeycomb.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2162a-clearfog.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2162a-qds.dtb
fsl-ls1028a-qds-13bb-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-13bb.dtbo
@@ -66,6 +70,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-mx8menlo.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-phg.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-phygate-tauri-l.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-prt8mm.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-tqma8mqml-mba8mx.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb
@@ -83,6 +88,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-nonwifi-yavia.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dahlia.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dev.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-yavia.dtb
+
+imx8mm-tqma8mqml-mba8mx-lvds-tm070jvhg33-dtbs += imx8mm-tqma8mqml-mba8mx.dtb imx8mm-tqma8mqml-mba8mx-lvds-tm070jvhg33.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-tqma8mqml-mba8mx-lvds-tm070jvhg33.dtb
+
dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2pro.dtb
@@ -92,6 +101,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mn-ddr4-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mn-tqma8mqnl-mba8mx.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mn-var-som-symphony.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mn-venice-gw7902.dtb
+
+imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33-dtbs += imx8mn-tqma8mqnl-mba8mx.dtb imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtb
+
dtb-$(CONFIG_ARCH_MXC) += imx8mp-beacon-kit.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-data-modul-edm-sbc.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-debix-model-a.dtb
@@ -133,6 +146,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mq-pico-pi.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mq-thor96.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mq-zii-ultra-rmb3.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mq-zii-ultra-zest.dtb
+
+imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33-dtbs += imx8mq-tqma8mq-mba8mx.dtb imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33.dtb
+
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-eval.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-ixora-v1.1.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-v1.1-eval.dtb
@@ -159,6 +176,7 @@ imx8mm-venice-gw73xx-0x-rpidsi-dtbs := imx8mm-venice-gw73xx-0x.dtb imx8mm-venice
imx8mm-venice-gw73xx-0x-rs232-rts-dtbs := imx8mm-venice-gw73xx-0x.dtb imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
imx8mm-venice-gw73xx-0x-rs422-dtbs := imx8mm-venice-gw73xx-0x.dtb imx8mm-venice-gw73xx-0x-rs422.dtbo
imx8mm-venice-gw73xx-0x-rs485-dtbs := imx8mm-venice-gw73xx-0x.dtb imx8mm-venice-gw73xx-0x-rs485.dtbo
+imx8mp-venice-gw74xx-imx219-dtbs := imx8mp-venice-gw74xx.dtb imx8mp-venice-gw74xx-imx219.dtbo
imx8mp-venice-gw74xx-rpidsi-dtbs := imx8mp-venice-gw74xx.dtb imx8mp-venice-gw74xx-rpidsi.dtbo
dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-imx219.dtb
@@ -171,6 +189,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rpidsi.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw74xx-imx219.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw74xx-rpidsi.dtb
dtb-$(CONFIG_ARCH_S32) += s32g274a-evb.dtb
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-tqmls1043a-mbls10xxa.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-tqmls1043a-mbls10xxa.dts
new file mode 100644
index 000000000000..03748a7f657b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-tqmls1043a-mbls10xxa.dts
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "fsl-ls1043a-tqmls1043a.dtsi"
+#include "tqmls10xxa-mbls10xxa.dtsi"
+
+/ {
+ model = "TQ-Systems GmbH LS1043A TQMLS1043A SoM on MBLS10xxA board";
+ compatible = "tq,ls1043a-tqmls1043a-mbls10xxa", "tq,ls1043a-tqmls1043a",
+ "fsl,ls1043a";
+
+ aliases {
+ qsgmii-s1-p1 = &qsgmii1_phy1;
+ qsgmii-s1-p2 = &qsgmii1_phy2;
+ qsgmii-s1-p3 = &qsgmii1_phy3;
+ qsgmii-s1-p4 = &qsgmii1_phy4;
+ qsgmii-s2-p1 = &qsgmii2_phy1;
+ qsgmii-s2-p2 = &qsgmii2_phy2;
+ qsgmii-s2-p3 = &qsgmii2_phy3;
+ qsgmii-s2-p4 = &qsgmii2_phy4;
+ serial0 = &duart0;
+ serial1 = &duart1;
+ };
+
+ chosen {
+ stdout-path = &duart1;
+ };
+};
+
+&esdhc {
+ cd-gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+};
+
+&usb2 {
+ status = "okay";
+};
+
+#include "fsl-ls1043-post.dtsi"
+#include "tqmls104xa-mbls10xxa-fman.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-tqmls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a-tqmls1043a.dtsi
new file mode 100644
index 000000000000..12d5f3938e5d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-tqmls1043a.dtsi
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ *
+ * Device Tree Include file for LS1043A based SoM of TQ
+ */
+
+#include "fsl-ls1043a.dtsi"
+#include "tqmls10xxa.dtsi"
+
+&qspi {
+ num-cs = <2>;
+ status = "okay";
+
+ qflash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <62500000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
index f8acbefc805b..229bb4bebe42 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -526,20 +526,6 @@
status = "disabled";
};
- dspi1: spi@2110000 {
- compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x0 0x2110000 0x0 0x10000>;
- interrupts = <0 65 0x4>;
- clock-names = "dspi";
- clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
- QORIQ_CLK_PLL_DIV(1)>;
- spi-num-chipselects = <5>;
- big-endian;
- status = "disabled";
- };
-
i2c0: i2c@2180000 {
compatible = "fsl,ls1043a-i2c", "fsl,vf610-i2c";
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-tqmls1046a-mbls10xxa.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-tqmls1046a-mbls10xxa.dts
new file mode 100644
index 000000000000..37834ae3deac
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-tqmls1046a-mbls10xxa.dts
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "fsl-ls1046a-tqmls1046a.dtsi"
+#include "tqmls10xxa-mbls10xxa.dtsi"
+
+/ {
+ model = "TQ-Systems GmbH LS1046A TQMLS1046A SoM on MBLS10xxA board";
+ compatible = "tq,ls1046a-tqmls1046a-mbls10xxa", "tq,ls1046a-tqmls1046a",
+ "fsl,ls1046a";
+
+ aliases {
+ qsgmii-s1-p1 = &qsgmii1_phy1;
+ qsgmii-s1-p2 = &qsgmii1_phy2;
+ qsgmii-s1-p3 = &qsgmii1_phy3;
+ qsgmii-s1-p4 = &qsgmii1_phy4;
+ qsgmii-s2-p1 = &qsgmii2_phy1;
+ qsgmii-s2-p2 = &qsgmii2_phy2;
+ qsgmii-s2-p3 = &qsgmii2_phy3;
+ qsgmii-s2-p4 = &qsgmii2_phy4;
+ serial0 = &duart0;
+ serial1 = &duart1;
+ };
+
+ chosen {
+ stdout-path = &duart1;
+ };
+};
+
+&dspi {
+ status = "okay";
+};
+
+&esdhc {
+ cd-gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+};
+
+&usb2 {
+ status = "okay";
+};
+
+#include "fsl-ls1046-post.dtsi"
+#include "tqmls104xa-mbls10xxa-fman.dtsi"
+
+&enet7 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-tqmls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a-tqmls1046a.dtsi
new file mode 100644
index 000000000000..4a8f8bc688f5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-tqmls1046a.dtsi
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ *
+ * Device Tree Include file for LS1046A based SoM of TQ
+ */
+
+#include "fsl-ls1046a.dtsi"
+#include "tqmls10xxa.dtsi"
+
+&qspi {
+ num-cs = <2>;
+ status = "okay";
+
+ qflash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <62500000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+
+ qflash1: flash@1 {
+ compatible = "jedec,spi-nor";
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <62500000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-tqmls1088a-mbls10xxa.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-tqmls1088a-mbls10xxa.dts
new file mode 100644
index 000000000000..e567918f6afc
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-tqmls1088a-mbls10xxa.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "fsl-ls1088a-tqmls1088a.dtsi"
+#include "tqmls10xxa-mbls10xxa.dtsi"
+
+/ {
+ model = "TQ-Systems GmbH LS1088A TQMLS1088A SoM on MBLS10xxA board";
+ compatible = "tq,ls1088a-tqmls1088a-mbls10xxa", "tq,ls1088a-tqmls1088a",
+ "fsl,ls1088a";
+
+ aliases {
+ dpmac1 = &dpmac1;
+ dpmac2 = &dpmac2;
+ dpmac3 = &dpmac3;
+ dpmac4 = &dpmac4;
+ dpmac5 = &dpmac5;
+ dpmac6 = &dpmac6;
+ dpmac7 = &dpmac7;
+ dpmac8 = &dpmac8;
+ dpmac9 = &dpmac9;
+ dpmac10 = &dpmac10;
+ qsgmii-s1-p1 = &qsgmii1_phy1;
+ qsgmii-s1-p2 = &qsgmii1_phy2;
+ qsgmii-s1-p3 = &qsgmii1_phy3;
+ qsgmii-s1-p4 = &qsgmii1_phy4;
+ qsgmii-s2-p1 = &qsgmii2_phy1;
+ qsgmii-s2-p2 = &qsgmii2_phy2;
+ qsgmii-s2-p3 = &qsgmii2_phy3;
+ qsgmii-s2-p4 = &qsgmii2_phy4;
+ rgmii-s1 = &rgmii_phy1;
+ rgmii-s2 = &rgmii_phy2;
+ serial0 = &duart0;
+ serial1 = &duart1;
+ };
+
+ chosen {
+ stdout-path = &duart1;
+ };
+};
+
+&esdhc {
+ cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+};
+
+&sfp1_i2c {
+ status = "okay";
+};
+
+&sfp2_i2c {
+ status = "okay";
+};
+
+#include "tqmls1088a-mbls10xxa-mc.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-tqmls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a-tqmls1088a.dtsi
new file mode 100644
index 000000000000..9a0f21484be9
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-tqmls1088a.dtsi
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ *
+ * Device Tree Include file for LS1088A based SoM of TQ
+ */
+
+#include "fsl-ls1088a.dtsi"
+#include "tqmls10xxa.dtsi"
+
+&qspi {
+ num-cs = <2>;
+ status = "okay";
+
+ qflash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <62500000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+
+ qflash1: flash@1 {
+ compatible = "jedec,spi-nor";
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <62500000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
index d2f5345d0560..717288bbdb8b 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
@@ -1186,26 +1186,34 @@
dma-coherent;
};
- usb0: usb@3100000 {
- status = "disabled";
- compatible = "snps,dwc3";
- reg = <0x0 0x3100000 0x0 0x10000>;
- interrupts = <0 80 0x4>; /* Level high type */
- dr_mode = "host";
- snps,quirk-frame-length-adjustment = <0x20>;
- snps,dis_rxdet_inp3_quirk;
- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
- };
+ bus: bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+ dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>;
+
+ usb0: usb@3100000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x3100000 0x0 0x10000>;
+ interrupts = <0 80 0x4>; /* Level high type */
+ dr_mode = "host";
+ snps,quirk-frame-length-adjustment = <0x20>;
+ snps,dis_rxdet_inp3_quirk;
+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
+ status = "disabled";
+ };
- usb1: usb@3110000 {
- status = "disabled";
- compatible = "snps,dwc3";
- reg = <0x0 0x3110000 0x0 0x10000>;
- interrupts = <0 81 0x4>; /* Level high type */
- dr_mode = "host";
- snps,quirk-frame-length-adjustment = <0x20>;
- snps,dis_rxdet_inp3_quirk;
- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
+ usb1: usb@3110000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x3110000 0x0 0x10000>;
+ interrupts = <0 81 0x4>; /* Level high type */
+ dr_mode = "host";
+ snps,quirk-frame-length-adjustment = <0x20>;
+ snps,dis_rxdet_inp3_quirk;
+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
+ status = "disabled";
+ };
};
ccn@4000000 {
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index ea6a94b57aeb..f176ca2e244e 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -626,6 +626,13 @@
#phy-cells = <1>;
};
+ serdes_2: phy@1eb0000 {
+ compatible = "fsl,lynx-28g";
+ reg = <0x0 0x1eb0000 0x0 0x1e30>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
crypto: crypto@8000000 {
compatible = "fsl,sec-v5.0", "fsl,sec-v4.0";
fsl,sec-era = <10>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts b/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
new file mode 100644
index 000000000000..9f88583aa25e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Device Tree file for LX2162A Clearfog
+//
+// Copyright 2023 Josua Mayer <josua@solid-run.com>
+
+/dts-v1/;
+
+#include "fsl-lx2160a.dtsi"
+#include "fsl-lx2162a-sr-som.dtsi"
+
+/ {
+ model = "SolidRun LX2162A Clearfog";
+ compatible = "solidrun,lx2162a-clearfog", "solidrun,lx2162a-som", "fsl,lx2160a";
+
+ aliases {
+ crypto = &crypto;
+ i2c0 = &i2c0;
+ i2c1 = &i2c2;
+ i2c2 = &i2c4;
+ i2c3 = &sfp_i2c0;
+ i2c4 = &sfp_i2c1;
+ i2c5 = &sfp_i2c2;
+ i2c6 = &sfp_i2c3;
+ i2c7 = &mpcie1_i2c;
+ i2c8 = &mpcie0_i2c;
+ i2c9 = &pcieclk_i2c;
+ mmc0 = &esdhc0;
+ mmc1 = &esdhc1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_sfp_at: led-sfp-at {
+ gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; /* PROC_IRQ5 */
+ default-state = "off";
+ };
+
+ led_sfp_ab: led-sfp-ab {
+ gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>; /* PROC_IRQ11 */
+ default-state = "off";
+ };
+
+ led_sfp_bt: led-sfp-bt {
+ gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>; /* EVT1_B */
+ default-state = "off";
+ };
+
+ led_sfp_bb: led-sfp-bb {
+ gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>; /* EVT2_B */
+ default-state = "off";
+ };
+ };
+
+ sfp_at: sfp-at {
+ compatible = "sff,sfp";
+ i2c-bus = <&sfp_i2c0>;
+ mod-def0-gpios = <&gpio2 16 GPIO_ACTIVE_LOW>; /* EVT4_B */
+ maximum-power-milliwatt = <2000>;
+ };
+
+ sfp_ab: sfp-ab {
+ compatible = "sff,sfp";
+ i2c-bus = <&sfp_i2c1>;
+ mod-def0-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; /* PROC_IRQ1 */
+ maximum-power-milliwatt = <2000>;
+ };
+
+ sfp_bt: sfp-bt {
+ compatible = "sff,sfp";
+ i2c-bus = <&sfp_i2c2>;
+ mod-def0-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; /* PROC_IRQ10 */
+ maximum-power-milliwatt = <2000>;
+ };
+
+ sfp_bb: sfp-bb {
+ compatible = "sff,sfp";
+ i2c-bus = <&sfp_i2c3>;
+ mod-def0-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>; /* EVT3_B */
+ maximum-power-milliwatt = <2000>;
+ };
+};
+
+&dpmac3 {
+ sfp = <&sfp_at>;
+ managed = "in-band-status";
+ phys = <&serdes_1 7>;
+};
+
+&dpmac4 {
+ sfp = <&sfp_ab>;
+ managed = "in-band-status";
+ phys = <&serdes_1 6>;
+};
+
+&dpmac5 {
+ sfp = <&sfp_bt>;
+ managed = "in-band-status";
+ phys = <&serdes_1 5>;
+};
+
+&dpmac6 {
+ sfp = <&sfp_bb>;
+ managed = "in-band-status";
+ phys = <&serdes_1 4>;
+};
+
+&dpmac11 {
+ phys = <&serdes_2 0>;
+ phy-handle = <&ethernet_phy3>;
+ phy-connection-type = "sgmii";
+ status = "okay";
+};
+
+&dpmac12 {
+ phys = <&serdes_2 1>;
+ phy-handle = <&ethernet_phy1>;
+ phy-connection-type = "sgmii";
+ status = "okay";
+};
+
+&dpmac13 {
+ phys = <&serdes_2 6>;
+ phy-handle = <&ethernet_phy6>;
+ phy-connection-type = "sgmii";
+ status = "okay";
+};
+
+&dpmac14 {
+ phys = <&serdes_2 7>;
+ phy-handle = <&ethernet_phy8>;
+ phy-connection-type = "sgmii";
+ status = "okay";
+};
+
+&dpmac15 {
+ phys = <&serdes_2 4>;
+ phy-handle = <&ethernet_phy4>;
+ phy-connection-type = "sgmii";
+ status = "okay";
+};
+
+&dpmac16 {
+ phys = <&serdes_2 5>;
+ phy-handle = <&ethernet_phy2>;
+ phy-connection-type = "sgmii";
+ status = "okay";
+};
+
+&dpmac17 {
+ /* override connection to on-SoM phy */
+ /delete-property/ phy-handle;
+ /delete-property/ phy-connection-type;
+
+ phys = <&serdes_2 2>;
+ phy-handle = <&ethernet_phy5>;
+ phy-connection-type = "sgmii";
+ status = "okay";
+};
+
+&dpmac18 {
+ phys = <&serdes_2 3>;
+ phy-handle = <&ethernet_phy7>;
+ phy-connection-type = "sgmii";
+ status = "okay";
+};
+
+&emdio1 {
+ ethernet_phy1: ethernet-phy@8 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <8>;
+ max-speed = <1000>;
+ };
+
+ ethernet_phy2: ethernet-phy@9 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <9>;
+ max-speed = <1000>;
+ };
+
+ ethernet_phy3: ethernet-phy@10 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <10>;
+ max-speed = <1000>;
+ };
+
+ ethernet_phy4: ethernet-phy@11 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <11>;
+ max-speed = <1000>;
+ };
+
+ ethernet_phy5: ethernet-phy@12 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <12>;
+ max-speed = <1000>;
+ };
+
+ ethernet_phy6: ethernet-phy@13 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <13>;
+ max-speed = <1000>;
+ };
+
+ ethernet_phy7: ethernet-phy@14 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <14>;
+ max-speed = <1000>;
+ };
+
+ ethernet_phy8: ethernet-phy@15 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <15>;
+ max-speed = <1000>;
+ };
+};
+
+&esdhc0 {
+ sd-uhs-sdr104;
+ sd-uhs-sdr50;
+ sd-uhs-sdr25;
+ sd-uhs-sdr12;
+ status = "okay";
+};
+
+&ethernet_phy0 {
+ /*
+ * SoM has a phy at address 1 connected to SoC Ethernet Controller 1.
+ * It competes for WRIOP MAC17, and no connector has been wired.
+ */
+ status = "disabled";
+};
+
+&i2c2 {
+ status = "okay";
+
+ /* retimer@18 */
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9546";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ sfp_i2c0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ sfp_i2c1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ sfp_i2c2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ sfp_i2c3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9546";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ mpcie1_i2c: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ mpcie0_i2c: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ pcieclk_i2c: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ /* clock-controller@6b */
+ };
+ };
+};
+
+&pcie3 {
+ status = "disabled";
+};
+
+&pcie4 {
+ status = "disabled";
+};
+
+&pcs_mdio3 {
+ status = "okay";
+};
+
+&pcs_mdio4 {
+ status = "okay";
+};
+
+&pcs_mdio5 {
+ status = "okay";
+};
+
+&pcs_mdio6 {
+ status = "okay";
+};
+
+&pcs_mdio11 {
+ status = "okay";
+};
+
+&pcs_mdio12 {
+ status = "okay";
+};
+
+&pcs_mdio13 {
+ status = "okay";
+};
+
+&pcs_mdio14 {
+ status = "okay";
+};
+
+&pcs_mdio15 {
+ status = "okay";
+};
+
+&pcs_mdio16 {
+ status = "okay";
+};
+
+&pcs_mdio17 {
+ status = "okay";
+};
+
+&pcs_mdio18 {
+ status = "okay";
+};
+
+&serdes_1 {
+ status = "okay";
+};
+
+&serdes_2 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi
new file mode 100644
index 000000000000..0580ea30cfbc
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Device Tree file for LX2162A-SOM
+//
+// Copyright 2021 Rabeeh Khoury <rabeeh@solid-run.com>
+// Copyright 2023 Josua Mayer <josua@solid-run.com>
+
+&crypto {
+ status = "okay";
+};
+
+&dpmac17 {
+ phy-handle = <&ethernet_phy0>;
+ phy-connection-type = "rgmii-id";
+};
+
+&emdio1 {
+ status = "okay";
+
+ ethernet_phy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&esdhc1 {
+ bus-width = <8>;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ status = "okay";
+};
+
+&fspi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ m25p,fast-read;
+ spi-max-frequency = <50000000>;
+ /* The following setting enables 1-1-8 (CMD-ADDR-DATA) mode */
+ spi-rx-bus-width = <8>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ fan-controller@18 {
+ compatible = "ti,amc6821";
+ reg = <0x18>;
+ };
+
+ ddr_spd: eeprom@51 {
+ compatible = "st,24c02", "atmel,24c02";
+ reg = <0x51>;
+ read-only;
+ };
+
+ config_eeprom: eeprom@57 {
+ compatible = "st,24c02", "atmel,24c02";
+ reg = <0x57>;
+ };
+};
+
+&i2c4 {
+ status = "okay";
+
+ variable_eeprom: eeprom@54 {
+ compatible = "st,24c2048", "atmel,24c2048";
+ reg = <0x54>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi
index c6d51f116298..5438923a905c 100644
--- a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi
@@ -165,7 +165,6 @@
"gpio5-24", "UART24-FORCEOFF", "gpio5-26",
"LED-4-GREEN", "gpio5-28", "LED-4-RED", "gpio5-30",
"gpio5-31";
- ngpios = <32>;
};
/* Apalis PWM3, MXM3 pin 6 */
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi
index 40067ab8aa74..72136c436a70 100644
--- a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi
@@ -212,7 +212,6 @@
"gpio5-24", "UART24-FORCEOFF", "gpio5-26",
"LED-4-GREEN", "gpio5-28", "LED-4-RED", "gpio5-30",
"gpio5-31";
- ngpios = <32>;
};
/* Apalis PWM3, MXM3 pin 6 */
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
index 9b1b522517f8..5ce5fbf2b38e 100644
--- a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
@@ -264,7 +264,7 @@
reset-assert-us = <2>;
reset-deassert-us = <2>;
reset-gpios = <&lsio_gpio1 11 GPIO_ACTIVE_LOW>;
- reset-names = "phy-reset";
+ reset-names = "phy";
};
};
};
@@ -503,15 +503,6 @@
"MXM3_185",
"MXM3_187";
- /*
- * Add GPIO2_20 as a wakeup source:
- * Pin: 101 SC_P_SPI3_CS0 (MXM3_37/WAKE1_MICO)
- * Type: 5 SC_PAD_WAKEUP_FALL_EDGE
- * Line: 20
- */
- pad-wakeup = <IMX8QM_SPI3_CS0 5 20>;
- pad-wakeup-num = <1>;
-
pcie-wifi-hog {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie_wifi_refclk>;
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
index 6c8d75ef9250..9d75ce467569 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
@@ -7,17 +7,74 @@
#include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/firmware/imx/rsrc.h>
+audio_ipg_clk: clock-audio-ipg {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <120000000>;
+ clock-output-names = "audio_ipg_clk";
+};
+
audio_subsys: bus@59000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x59000000 0x0 0x59000000 0x1000000>;
- audio_ipg_clk: clock-audio-ipg {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <120000000>;
- clock-output-names = "audio_ipg_clk";
+ edma0: dma-controller@591f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x591f0000 0x190000>;
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <24>;
+ dma-channel-mask = <0x5c0c00>;
+ interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>, /* 0 asrc 0 */
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>, /* 1 */
+ <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>, /* 2 */
+ <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>, /* 3 */
+ <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>, /* 4 */
+ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>, /* 5 */
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>, /* 6 esai0 */
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>, /* 7 */
+ <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, /* 8 spdif0 */
+ <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>, /* 9 */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* 10 unused */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* 11 unused */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* 12 sai0 */
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, /* 13 */
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, /* 14 sai1 */
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, /* 15 */
+ <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>, /* 16 sai2 */
+ <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* 17 sai3 */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* 18 unused */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* 19 unused */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* 20 unused */
+ <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH>, /* 21 */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* 22 unused */
+ <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>; /* 23 unused */
+ power-domains = <&pd IMX_SC_R_DMA_0_CH0>,
+ <&pd IMX_SC_R_DMA_0_CH1>,
+ <&pd IMX_SC_R_DMA_0_CH2>,
+ <&pd IMX_SC_R_DMA_0_CH3>,
+ <&pd IMX_SC_R_DMA_0_CH4>,
+ <&pd IMX_SC_R_DMA_0_CH5>,
+ <&pd IMX_SC_R_DMA_0_CH6>,
+ <&pd IMX_SC_R_DMA_0_CH7>,
+ <&pd IMX_SC_R_DMA_0_CH8>,
+ <&pd IMX_SC_R_DMA_0_CH9>,
+ <&pd IMX_SC_R_DMA_0_CH10>,
+ <&pd IMX_SC_R_DMA_0_CH11>,
+ <&pd IMX_SC_R_DMA_0_CH12>,
+ <&pd IMX_SC_R_DMA_0_CH13>,
+ <&pd IMX_SC_R_DMA_0_CH14>,
+ <&pd IMX_SC_R_DMA_0_CH15>,
+ <&pd IMX_SC_R_DMA_0_CH16>,
+ <&pd IMX_SC_R_DMA_0_CH17>,
+ <&pd IMX_SC_R_DMA_0_CH18>,
+ <&pd IMX_SC_R_DMA_0_CH19>,
+ <&pd IMX_SC_R_DMA_0_CH20>,
+ <&pd IMX_SC_R_DMA_0_CH21>,
+ <&pd IMX_SC_R_DMA_0_CH22>,
+ <&pd IMX_SC_R_DMA_0_CH23>;
};
dsp_lpcg: clock-controller@59580000 {
@@ -65,4 +122,35 @@ audio_subsys: bus@59000000 {
memory-region = <&dsp_reserved>;
status = "disabled";
};
+
+ edma1: dma-controller@599f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x599f0000 0xc0000>;
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <11>;
+ dma-channel-mask = <0xc0>;
+ interrupts = <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>, /* 0 asrc 1 */
+ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>, /* 1 */
+ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>, /* 2 */
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>, /* 3 */
+ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>, /* 4 */
+ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>, /* 5 */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* 6 unused */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* 7 unused */
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* sai4 */
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>; /* sai5 */
+ power-domains = <&pd IMX_SC_R_DMA_1_CH0>,
+ <&pd IMX_SC_R_DMA_1_CH1>,
+ <&pd IMX_SC_R_DMA_1_CH2>,
+ <&pd IMX_SC_R_DMA_1_CH3>,
+ <&pd IMX_SC_R_DMA_1_CH4>,
+ <&pd IMX_SC_R_DMA_1_CH5>,
+ <&pd IMX_SC_R_DMA_1_CH6>,
+ <&pd IMX_SC_R_DMA_1_CH7>,
+ <&pd IMX_SC_R_DMA_1_CH8>,
+ <&pd IMX_SC_R_DMA_1_CH9>,
+ <&pd IMX_SC_R_DMA_1_CH10>;
+ };
};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
index fc1a5d34382b..3c42240e78e2 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
@@ -7,33 +7,33 @@
#include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/firmware/imx/rsrc.h>
+conn_axi_clk: clock-conn-axi {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <333333333>;
+ clock-output-names = "conn_axi_clk";
+};
+
+conn_ahb_clk: clock-conn-ahb {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <166666666>;
+ clock-output-names = "conn_ahb_clk";
+};
+
+conn_ipg_clk: clock-conn-ipg {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <83333333>;
+ clock-output-names = "conn_ipg_clk";
+};
+
conn_subsys: bus@5b000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x5b000000 0x0 0x5b000000 0x1000000>;
- conn_axi_clk: clock-conn-axi {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <333333333>;
- clock-output-names = "conn_axi_clk";
- };
-
- conn_ahb_clk: clock-conn-ahb {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <166666666>;
- clock-output-names = "conn_ahb_clk";
- };
-
- conn_ipg_clk: clock-conn-ipg {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <83333333>;
- clock-output-names = "conn_ipg_clk";
- };
-
usbotg1: usb@5b0d0000 {
compatible = "fsl,imx7ulp-usb", "fsl,imx6ul-usb", "fsl,imx27-usb";
reg = <0x5b0d0000 0x200>;
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
index adb98a72bdfd..ce66d30a4839 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
@@ -7,19 +7,19 @@
#include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/firmware/imx/rsrc.h>
+dma_ipg_clk: clock-dma-ipg {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <120000000>;
+ clock-output-names = "dma_ipg_clk";
+};
+
dma_subsys: bus@5a000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x5a000000 0x0 0x5a000000 0x1000000>;
- dma_ipg_clk: clock-dma-ipg {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <120000000>;
- clock-output-names = "dma_ipg_clk";
- };
-
lpspi0: spi@5a000000 {
compatible = "fsl,imx7ulp-spi";
reg = <0x5a000000 0x10000>;
@@ -86,52 +86,135 @@ dma_subsys: bus@5a000000 {
lpuart0: serial@5a060000 {
reg = <0x5a060000 0x1000>;
- interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&uart0_lpcg IMX_LPCG_CLK_4>,
<&uart0_lpcg IMX_LPCG_CLK_0>;
clock-names = "ipg", "baud";
assigned-clocks = <&clk IMX_SC_R_UART_0 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <80000000>;
power-domains = <&pd IMX_SC_R_UART_0>;
+ dma-names = "tx","rx";
+ dmas = <&edma2 9 0 0>, <&edma2 8 0 1>;
status = "disabled";
};
lpuart1: serial@5a070000 {
reg = <0x5a070000 0x1000>;
- interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&uart1_lpcg IMX_LPCG_CLK_4>,
<&uart1_lpcg IMX_LPCG_CLK_0>;
clock-names = "ipg", "baud";
assigned-clocks = <&clk IMX_SC_R_UART_1 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <80000000>;
power-domains = <&pd IMX_SC_R_UART_1>;
+ dma-names = "tx","rx";
+ dmas = <&edma2 11 0 0>, <&edma2 10 0 1>;
status = "disabled";
};
lpuart2: serial@5a080000 {
reg = <0x5a080000 0x1000>;
- interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&uart2_lpcg IMX_LPCG_CLK_4>,
<&uart2_lpcg IMX_LPCG_CLK_0>;
clock-names = "ipg", "baud";
assigned-clocks = <&clk IMX_SC_R_UART_2 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <80000000>;
power-domains = <&pd IMX_SC_R_UART_2>;
+ dma-names = "tx","rx";
+ dmas = <&edma2 13 0 0>, <&edma2 12 0 1>;
status = "disabled";
};
lpuart3: serial@5a090000 {
reg = <0x5a090000 0x1000>;
- interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&uart3_lpcg IMX_LPCG_CLK_4>,
<&uart3_lpcg IMX_LPCG_CLK_0>;
clock-names = "ipg", "baud";
assigned-clocks = <&clk IMX_SC_R_UART_3 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <80000000>;
power-domains = <&pd IMX_SC_R_UART_3>;
+ dma-names = "tx","rx";
+ dmas = <&edma2 15 0 0>, <&edma2 14 0 1>;
status = "disabled";
};
+ adma_pwm: pwm@5a190000 {
+ compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
+ reg = <0x5a190000 0x1000>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&adma_pwm_lpcg 1>,
+ <&adma_pwm_lpcg 0>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX_SC_R_LCD_0_PWM_0 IMX_SC_PM_CLK_PER>;
+ assigned-clock-rates = <24000000>;
+ #pwm-cells = <2>;
+ power-domains = <&pd IMX_SC_R_LCD_0_PWM_0>;
+ };
+
+ edma2: dma-controller@5a1f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x5a1f0000 0x170000>;
+ #dma-cells = <3>;
+ dma-channels = <16>;
+ interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd IMX_SC_R_DMA_2_CH0>,
+ <&pd IMX_SC_R_DMA_2_CH1>,
+ <&pd IMX_SC_R_DMA_2_CH2>,
+ <&pd IMX_SC_R_DMA_2_CH3>,
+ <&pd IMX_SC_R_DMA_2_CH4>,
+ <&pd IMX_SC_R_DMA_2_CH5>,
+ <&pd IMX_SC_R_DMA_2_CH6>,
+ <&pd IMX_SC_R_DMA_2_CH7>,
+ <&pd IMX_SC_R_DMA_2_CH8>,
+ <&pd IMX_SC_R_DMA_2_CH9>,
+ <&pd IMX_SC_R_DMA_2_CH10>,
+ <&pd IMX_SC_R_DMA_2_CH11>,
+ <&pd IMX_SC_R_DMA_2_CH12>,
+ <&pd IMX_SC_R_DMA_2_CH13>,
+ <&pd IMX_SC_R_DMA_2_CH14>,
+ <&pd IMX_SC_R_DMA_2_CH15>;
+ };
+
+ edma3: dma-controller@5a9f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x5a9f0000 0x90000>;
+ #dma-cells = <3>;
+ dma-channels = <8>;
+ interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd IMX_SC_R_DMA_3_CH0>,
+ <&pd IMX_SC_R_DMA_3_CH1>,
+ <&pd IMX_SC_R_DMA_3_CH2>,
+ <&pd IMX_SC_R_DMA_3_CH3>,
+ <&pd IMX_SC_R_DMA_3_CH4>,
+ <&pd IMX_SC_R_DMA_3_CH5>,
+ <&pd IMX_SC_R_DMA_3_CH6>,
+ <&pd IMX_SC_R_DMA_3_CH7>;
+ };
+
spi0_lpcg: clock-controller@5a400000 {
compatible = "fsl,imx8qxp-lpcg";
reg = <0x5a400000 0x10000>;
@@ -228,6 +311,18 @@ dma_subsys: bus@5a000000 {
power-domains = <&pd IMX_SC_R_UART_3>;
};
+ adma_pwm_lpcg: clock-controller@5a590000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x5a590000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_LCD_0_PWM_0 IMX_SC_PM_CLK_PER>,
+ <&dma_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "adma_pwm_lpcg_clk",
+ "adma_pwm_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_LCD_0_PWM_0>;
+ };
+
i2c0: i2c@5a800000 {
reg = <0x5a800000 0x4000>;
interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
index a90654155a88..e7783cc2d830 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
@@ -3,25 +3,22 @@
* Copyright 2019-2021 NXP
* Zhou Guoniu <guoniu.zhou@nxp.com>
*/
+img_ipg_clk: clock-img-ipg {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <200000000>;
+ clock-output-names = "img_ipg_clk";
+};
+
img_subsys: bus@58000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x58000000 0x0 0x58000000 0x1000000>;
- img_ipg_clk: clock-img-ipg {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- clock-output-names = "img_ipg_clk";
- };
-
jpegdec: jpegdec@58400000 {
reg = <0x58400000 0x00050000>;
- interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&img_jpeg_dec_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>;
clock-names = "per", "ipg";
@@ -29,18 +26,13 @@ img_subsys: bus@58000000 {
<&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>;
assigned-clock-rates = <200000000>, <200000000>;
power-domains = <&pd IMX_SC_R_MJPEG_DEC_MP>,
- <&pd IMX_SC_R_MJPEG_DEC_S0>,
- <&pd IMX_SC_R_MJPEG_DEC_S1>,
- <&pd IMX_SC_R_MJPEG_DEC_S2>,
- <&pd IMX_SC_R_MJPEG_DEC_S3>;
+ <&pd IMX_SC_R_MJPEG_DEC_S0>;
+ slot = <0>;
};
jpegenc: jpegenc@58450000 {
reg = <0x58450000 0x00050000>;
- interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&img_jpeg_enc_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_enc_lpcg IMX_LPCG_CLK_4>;
clock-names = "per", "ipg";
@@ -48,10 +40,8 @@ img_subsys: bus@58000000 {
<&img_jpeg_enc_lpcg IMX_LPCG_CLK_4>;
assigned-clock-rates = <200000000>, <200000000>;
power-domains = <&pd IMX_SC_R_MJPEG_ENC_MP>,
- <&pd IMX_SC_R_MJPEG_ENC_S0>,
- <&pd IMX_SC_R_MJPEG_ENC_S1>,
- <&pd IMX_SC_R_MJPEG_ENC_S2>,
- <&pd IMX_SC_R_MJPEG_ENC_S3>;
+ <&pd IMX_SC_R_MJPEG_ENC_S0>;
+ slot = <0>;
};
img_jpeg_dec_lpcg: clock-controller@585d0000 {
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
index ea8c93757521..49ad3413db94 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
@@ -7,6 +7,13 @@
#include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/firmware/imx/rsrc.h>
+lsio_bus_clk: clock-lsio-bus {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "lsio_bus_clk";
+};
+
lsio_subsys: bus@5d000000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -14,20 +21,6 @@ lsio_subsys: bus@5d000000 {
ranges = <0x5d000000 0x0 0x5d000000 0x1000000>,
<0x08000000 0x0 0x08000000 0x10000000>;
- lsio_mem_clk: clock-lsio-mem {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- clock-output-names = "lsio_mem_clk";
- };
-
- lsio_bus_clk: clock-lsio-bus {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <100000000>;
- clock-output-names = "lsio_bus_clk";
- };
-
lsio_pwm0: pwm@5d000000 {
compatible = "fsl,imx27-pwm";
reg = <0x5d000000 0x10000>;
@@ -37,6 +30,7 @@ lsio_subsys: bus@5d000000 {
assigned-clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <24000000>;
#pwm-cells = <2>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -49,6 +43,7 @@ lsio_subsys: bus@5d000000 {
assigned-clocks = <&clk IMX_SC_R_PWM_1 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <24000000>;
#pwm-cells = <2>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -61,6 +56,7 @@ lsio_subsys: bus@5d000000 {
assigned-clocks = <&clk IMX_SC_R_PWM_2 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <24000000>;
#pwm-cells = <2>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -73,6 +69,7 @@ lsio_subsys: bus@5d000000 {
assigned-clocks = <&clk IMX_SC_R_PWM_3 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <24000000>;
#pwm-cells = <2>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
index b9157ca08b03..b972658efb17 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
@@ -186,7 +186,6 @@
&flexspi0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexspi0>;
- nxp,fspi-dll-slvdly = <4>;
status = "okay";
mt35xu512aba0: flash@0 {
@@ -365,7 +364,6 @@
fsl,spi-only-use-cs1-sel;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lpspi3>;
- pinctrl-assert-gpios = <&pca6416_1 7 GPIO_ACTIVE_HIGH>;
status = "okay";
spidev0: spi@0 {
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
index e2eeddf38aa3..0a477f6318f1 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
@@ -15,23 +15,53 @@
interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
};
+&edma2 {
+ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 291 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 294 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 295 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&edma3 {
+ interrupts = <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 301 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>;
+};
+
&i2c0 {
- compatible = "fsl,imx8dxl-lpi2c", "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+ compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
};
&i2c1 {
- compatible = "fsl,imx8dxl-lpi2c", "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+ compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
};
&i2c2 {
- compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+ compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
};
&i2c3 {
- compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+ compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
index 652493ae4bb5..a414df645351 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
@@ -6,14 +6,16 @@
/delete-node/ &enet1_lpcg;
/delete-node/ &fec2;
-&conn_subsys {
+/ {
conn_enet0_root_clk: clock-conn-enet0-root {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <250000000>;
clock-output-names = "conn_enet0_root_clk";
};
+};
+&conn_subsys {
eqos: ethernet@5b050000 {
compatible = "nxp,imx8dxl-dwmac-eqos", "snps,dwmac-5.10a";
reg = <0x5b050000 0x10000>;
@@ -116,7 +118,7 @@
};
&fec1 {
- compatible = "fsl,imx8qm-fec";
+ compatible = "fsl,imx8dxl-fec", "fsl,imx8qm-fec", "fsl,imx6sx-fec";
interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
index 792b7224ca5b..f580eb6db9a6 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
@@ -122,10 +122,8 @@
&lsio_mu1 3 3>;
pd: power-controller {
- compatible = "fsl,scu-pd";
+ compatible = "fsl,imx8dl-scu-pd", "fsl,scu-pd";
#power-domain-cells = <1>;
- wakeup-irq = <160 163 235 236 237 228 229 230 231 238
- 239 240 166 169>;
};
clk: clock-controller {
@@ -168,12 +166,12 @@
};
watchdog {
- compatible = "fsl,imx-sc-wdt";
+ compatible = "fsl,imx8dxl-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>;
};
tsens: thermal-sensor {
- compatible = "fsl,imx-sc-thermal";
+ compatible = "fsl,imx8dxl-sc-thermal", "fsl,imx-sc-thermal";
#thermal-sensor-cells = <1>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
index b10e2a703a44..6086dae2e5fb 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
@@ -6,6 +6,13 @@
#include <dt-bindings/phy/phy-imx8-pcie.h>
/ {
+
+ dmic_codec: dmic-codec {
+ compatible = "dmic-codec";
+ num-channels = <1>;
+ #sound-dai-cells = <0>;
+ };
+
leds {
compatible = "gpio-leds";
@@ -98,18 +105,46 @@
enable-active-high;
};
- sound {
- compatible = "fsl,imx-audio-wm8962";
- model = "wm8962-audio";
- audio-cpu = <&sai3>;
- audio-codec = <&wm8962>;
- audio-routing =
- "Headphone Jack", "HPOUTL",
- "Headphone Jack", "HPOUTR",
- "Ext Spk", "SPKOUTL",
- "Ext Spk", "SPKOUTR",
- "AMIC", "MICBIAS",
- "IN3R", "AMIC";
+ sound-dmic {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "dmic";
+ simple-audio-card,format = "pdm";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,frame-master = <&dailink_master>;
+
+ dailink_master: simple-audio-card,cpu {
+ sound-dai = <&micfil>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&dmic_codec>;
+ };
+ };
+
+ sound-wm8962 {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "wm8962";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,widgets = "Headphone", "Headphones",
+ "Microphone", "Headset Mic",
+ "Speaker", "Speaker";
+ simple-audio-card,routing = "Headphones", "HPOUTL",
+ "Headphones", "HPOUTR",
+ "Speaker", "SPKOUTL",
+ "Speaker", "SPKOUTR",
+ "Headset Mic", "MICBIAS",
+ "IN3R", "Headset Mic";
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai3>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&wm8962>;
+ clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
+ frame-master;
+ bitclock-master;
+ };
};
};
@@ -192,6 +227,7 @@
0x0000 /* 4:FN_DMICCDAT */
0x0000 /* 5:Default */
>;
+ #sound-dai-cells = <0>;
};
pca6416_0: gpio@20 {
@@ -215,6 +251,15 @@
};
};
+&micfil {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdm>;
+ assigned-clocks = <&clk IMX8MM_CLK_PDM>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <49152000>;
+ status = "okay";
+};
+
&mipi_csi {
status = "okay";
ports {
@@ -352,6 +397,13 @@
>;
};
+ pinctrl_pdm: pdmgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXC_PDM_CLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXD0_PDM_DATA0 0xd6
+ >;
+ };
+
pinctrl_reg_usb_otg1: usbotg1grp {
fsl,pins = <
MX8MM_IOMUXC_SAI3_RXC_GPIO4_IO29 0x19
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dts
index 010e836ebe5c..27848cee1670 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dts
@@ -23,7 +23,6 @@
&gpmi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>;
- nand-on-flash-bbt;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phg.dts b/arch/arm64/boot/dts/freescale/imx8mm-phg.dts
index 606a4f4d5f15..75bbedc6164c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phg.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phg.dts
@@ -111,6 +111,11 @@
};
};
+/* QSPI is not populated on the SoM */
+&flexspi {
+ status = "disabled";
+};
+
&ecspi1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
new file mode 100644
index 000000000000..968f475b9a96
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
@@ -0,0 +1,489 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2023 PHYTEC Messtechnik GmbH
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
+#include "imx8mm-phycore-som.dtsi"
+
+/ {
+ model = "PHYTEC phyGATE-Tauri-L-iMX8MM";
+ compatible = "phytec,imx8mm-phygate-tauri-l",
+ "phytec,imx8mm-phycore-som", "fsl,imx8mm";
+
+ chosen {
+ stdout-path = &uart3;
+ };
+
+ can_osc_40m: clock-can {
+ compatible = "fixed-clock";
+ clock-frequency = <40000000>;
+ clock-output-names = "can_osc_40m";
+ #clock-cells = <0>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+
+ key {
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ label = "KEY-A";
+ linux,code = <KEY_A>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds>;
+
+ led-1 {
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio5 5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "none";
+ };
+
+ led-2 {
+ color = <LED_COLOR_ID_YELLOW>;
+ gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "none";
+ };
+ };
+
+ usdhc1_pwrseq: pwr-seq {
+ compatible = "mmc-pwrseq-simple";
+ post-power-on-delay-ms = <100>;
+ power-off-delay-us = <60>;
+ reset-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_usb_hub_vbus: regulator-hub-otg1 {
+ compatible = "regulator-fixed";
+ gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbhubpwr>;
+ regulator-name = "usb_hub_vbus";
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ };
+
+ reg_usb_otg1_vbus: regulator-usb-otg1 {
+ compatible = "regulator-fixed";
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1pwr>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ off-on-delay-us = <20000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "VSD_3V3";
+ };
+};
+
+&ecspi1 {
+ cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>,
+ <&gpio5 13 GPIO_ACTIVE_LOW>,
+ <&gpio5 2 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ /* CAN MCP251XFD */
+ can0: can@0 {
+ compatible = "microchip,mcp251xfd";
+ reg = <0>;
+ clocks = <&can_osc_40m>;
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-parent = <&gpio1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can_int>;
+ spi-max-frequency = <10000000>;
+ };
+
+ tpm: tpm@1 {
+ compatible = "tcg,tpm_tis-spi";
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-parent = <&gpio2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tpm>;
+ reg = <1>;
+ spi-max-frequency = <38000000>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_gpio>;
+ scl-gpios = <&gpio5 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ temp_sense0: temperature-sensor@49 {
+ compatible = "ti,tmp102";
+ reg = <0x49>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tempsense>;
+ #thermal-sensor-cells = <1>;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_gpio>;
+ scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ pinctrl-1 = <&pinctrl_i2c4_gpio>;
+ scl-gpios = <&gpio5 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+/* PCIe */
+&pcie0 {
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_PHY>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_100M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ assigned-clock-rates = <10000000>, <100000000>, <250000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio3 22 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+/* RTC */
+&rv3028 {
+ trickle-resistor-ohms = <3000>;
+};
+
+&uart1 {
+ assigned-clocks = <&clk IMX8MM_CLK_UART1>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+/* UART2 - RS232 */
+&uart2 {
+ assigned-clocks = <&clk IMX8MM_CLK_UART2>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+/* UART - console */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+/* USB */
+&usbotg1 {
+ adp-disable;
+ dr_mode = "otg";
+ over-current-active-low;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ status = "okay";
+};
+
+&usbotg2 {
+ disable-over-current;
+ dr_mode = "host";
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ vbus-supply = <&reg_usb_hub_vbus>;
+ status = "okay";
+};
+
+/* SD-Card */
+&usdhc2 {
+ assigned-clocks = <&clk IMX8MM_CLK_USDHC2>;
+ assigned-clock-rates = <200000000>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ vqmmc-supply = <&reg_nvcc_sd2>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_can_int: can-intgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x00
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x82
+ MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x82
+ MX8MM_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x82
+ >;
+ };
+
+ pinctrl_ecspi1_cs: ecspi1csgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x00
+ MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x00
+ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x00
+ >;
+ };
+
+ pinctrl_gpiokeys: keygrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x00
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c2
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c2_gpio: i2c2gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SDA_GPIO5_IO17 0x1e0
+ MX8MM_IOMUXC_I2C2_SCL_GPIO5_IO16 0x1e0
+ >;
+ };
+
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c2
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c3_gpio: i2c3gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19 0x1e0
+ MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18 0x1e0
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c2
+ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c4_gpio: i2c4gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0x1e0
+ MX8MM_IOMUXC_I2C4_SCL_GPIO5_IO20 0x1e0
+ >;
+ };
+
+ pinctrl_leds: leds1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_RXD_GPIO4_IO30 0x00
+ MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x00
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ /* COEX2 */
+ MX8MM_IOMUXC_SAI5_RXD1_GPIO3_IO22 0x00
+ /* COEX1 */
+ MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x12
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO01_PWM1_OUT 0x40
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_TX_PWM3_OUT 0x40
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO15_PWM4_OUT 0x40
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x40
+ >;
+ };
+
+ pinctrl_tempsense: tempsensegrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31 0x00
+ >;
+ };
+
+ pinctrl_tpm: tpmgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11 0x140
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x00
+ MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x00
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x00
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x00
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140
+ MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_usbhubpwr: usbhubpwrgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x00
+ >;
+ };
+
+ pinctrl_usbotg1pwr: usbotg1pwrgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x00
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x80
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x182
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0xc6
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc6
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc6
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc6
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc6
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x40
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x192
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d2
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d2
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d2
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d2
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d2
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2100mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2200mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx-lvds-tm070jvhg33.dtso b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx-lvds-tm070jvhg33.dtso
new file mode 100644
index 000000000000..e44249c6d8a0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx-lvds-tm070jvhg33.dtso
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2022-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ compatible = "tq,imx8mm-tqma8mqml-mba8mx", "tq,imx8mm-tqma8mqml", "fsl,imx8mm";
+};
+
+&backlight_lvds {
+ status = "okay";
+};
+
+&dsi_lvds_bridge {
+ status = "okay";
+};
+
+&expander0 {
+ dsi-mux-oe-hog {
+ gpio-hog;
+ gpios = <10 GPIO_ACTIVE_LOW>;
+ output-high;
+ line-name = "DSI_MUX_OE#";
+ };
+};
+
+&lcdif {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+};
+
+&panel {
+ compatible = "tianma,tm070jvhg33";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
index b4466a26d838..8c0c6e715924 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
@@ -230,6 +230,11 @@
};
};
+&mipi_dsi {
+ vddcore-supply = <&ldo4_reg>;
+ vddio-supply = <&ldo3_reg>;
+};
+
&pcie_phy {
fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
fsl,clkreq-unsupported;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
index 0ce60ad9c7d5..6425773f68e0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
@@ -96,7 +96,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio4>;
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi
index 570992a52b75..3a0a10e835a2 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi
@@ -118,7 +118,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio4>;
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi
index 1800c6a4b1fc..d79fe9f62b95 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi
@@ -104,8 +104,15 @@
&ecspi2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi2>;
- cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>,
+ <&gpio1 10 GPIO_ACTIVE_LOW>;
status = "okay";
+
+ tpm@1 {
+ compatible = "tcg,tpm_tis-spi";
+ reg = <0x1>;
+ spi-max-frequency = <36000000>;
+ };
};
&gpio1 {
@@ -138,7 +145,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio4>;
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
@@ -362,6 +368,7 @@
MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0xd6
MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0xd6
MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0xd6
+ MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0xd6
>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
index ed46d4f3e66f..87b80e2412cb 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
@@ -357,6 +357,8 @@
interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
@@ -642,7 +644,6 @@
pinctrl-0 = <&pinctrl_ksz>;
interrupt-parent = <&gpio4>;
interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
- phy-mode = "rgmii-id";
ports {
#address-cells = <1>;
@@ -678,7 +679,6 @@
port@5 {
reg = <5>;
- label = "cpu";
ethernet = <&fec1>;
phy-mode = "rgmii-id";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
index b318c2d08038..06a394a41d7c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
@@ -314,6 +314,8 @@
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
@@ -585,7 +587,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio1>;
interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
index 0e102a12bca4..db1737bf637d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
@@ -280,6 +280,8 @@
interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
@@ -541,7 +543,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio1>;
interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts
index 6afbabc89c02..05489a31e7fd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts
@@ -330,6 +330,8 @@
interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
@@ -585,7 +587,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio1>;
interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 236fe44f779d..738024baaa57 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -399,6 +399,7 @@
"pll8k", "pll11k", "clkext3";
dmas = <&sdma2 24 25 0x80000000>;
dma-names = "rx";
+ #sound-dai-cells = <0>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-baseboard.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-beacon-baseboard.dtsi
index 16761975f56e..20018ee2c803 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-baseboard.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-baseboard.dtsi
@@ -4,6 +4,12 @@
*/
/ {
+ dmic_codec: dmic-codec {
+ compatible = "dmic-codec";
+ num-channels = <1>;
+ #sound-dai-cells = <0>;
+ };
+
leds {
compatible = "gpio-leds";
@@ -74,6 +80,22 @@
enable-active-high;
};
+ sound-dmic {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "dmic";
+ simple-audio-card,format = "pdm";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,frame-master = <&dailink_master>;
+
+ dailink_master: simple-audio-card,cpu {
+ sound-dai = <&micfil>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&dmic_codec>;
+ };
+ };
+
sound-wm8962 {
compatible = "simple-audio-card";
simple-audio-card,name = "wm8962";
@@ -221,6 +243,15 @@
};
};
+&micfil {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdm>;
+ assigned-clocks = <&clk IMX8MN_CLK_PDM>;
+ assigned-clock-parents = <&clk IMX8MN_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <49152000>;
+ status = "okay";
+};
+
&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
@@ -311,6 +342,13 @@
>;
};
+ pinctrl_pdm: pdmgrp {
+ fsl,pins = <
+ MX8MN_IOMUXC_SAI5_RXC_PDM_CLK 0xd6
+ MX8MN_IOMUXC_SAI5_RXD0_PDM_BIT_STREAM0 0xd6
+ >;
+ };
+
pinctrl_reg_usb_otg: reg-otggrp {
fsl,pins = <
MX8MN_IOMUXC_SAI3_RXC_GPIO4_IO29 0x19
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2.dts b/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2.dts
index 7acc5a960dd9..11a1ba5bfdb7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2.dts
@@ -21,7 +21,6 @@
&gpmi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>;
- nand-on-flash-bbt;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
index 0e60995a5727..3f6a19839c9e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
@@ -71,8 +71,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_wlf>;
wlf,mute-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>;
- clocks = <&clk IMX8MN_CLK_SAI3_ROOT>;
- clock-names = "mclk";
};
sound-bt-sco {
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtso b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtso
new file mode 100644
index 000000000000..29235e390a5d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtso
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2022-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ compatible = "tq,imx8mn-tqma8mqnl-mba8mx", "tq,imx8mn-tqma8mqnl", "fsl,imx8mn";
+};
+
+&backlight_lvds {
+ status = "okay";
+};
+
+&dsi_lvds_bridge {
+ status = "okay";
+};
+
+&expander0 {
+ dsi-mux-oe-hog {
+ gpio-hog;
+ gpios = <10 GPIO_ACTIVE_LOW>;
+ output-high;
+ line-name = "DSI_MUX_OE#";
+ };
+};
+
+&lcdif {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+};
+
+&panel {
+ compatible = "tianma,tm070jvhg33";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
index 391ca5516e4c..fb24b9aa1b93 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
@@ -219,6 +219,11 @@
};
};
+&mipi_dsi {
+ vddcore-supply = <&ldo4_reg>;
+ vddio-supply = <&ldo3_reg>;
+};
+
&usdhc3 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc3>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
index 08746fb82561..0b1fa04f1d67 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
@@ -312,6 +312,8 @@
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
adc {
compatible = "gw,gsc-adc";
@@ -583,7 +585,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio1>;
interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index aa38dd6dc9ba..1bb1d0c1bae4 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -371,6 +371,7 @@
"pll8k", "pll11k", "clkext3";
dmas = <&sdma2 24 25 0x80000000>;
dma-names = "rx";
+ #sound-dai-cells = <0>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
index acd265d8b58e..0bea0798d2db 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
@@ -23,6 +23,12 @@
stdout-path = &uart2;
};
+ clk_xtal25: clock-xtal25 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
connector {
compatible = "usb-c-connector";
label = "USB-C";
@@ -49,6 +55,12 @@
};
};
+ dmic_codec: dmic-codec {
+ compatible = "dmic-codec";
+ num-channels = <1>;
+ #sound-dai-cells = <0>;
+ };
+
gpio-keys {
compatible = "gpio-keys";
autorepeat;
@@ -112,12 +124,6 @@
};
};
- pcie0_refclk: clock-pcie {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <100000000>;
- };
-
reg_audio: regulator-wm8962 {
compatible = "regulator-fixed";
regulator-name = "3v3_aud";
@@ -147,6 +153,22 @@
enable-active-high;
};
+ sound-dmic {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "sound-pdm";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,frame-master = <&dailink_master>;
+
+ dailink_master: simple-audio-card,cpu {
+ sound-dai = <&micfil>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&dmic_codec>;
+ };
+ };
+
sound-wm8962 {
compatible = "simple-audio-card";
simple-audio-card,name = "wm8962";
@@ -174,6 +196,11 @@
};
};
+&audio_blk_ctrl {
+ assigned-clocks = <&clk IMX8MP_AUDIO_PLL1>, <&clk IMX8MP_AUDIO_PLL2>;
+ assigned-clock-rates = <393216000>, <135475200>;
+};
+
&ecspi2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi2>;
@@ -246,6 +273,13 @@
interrupt-controller;
#interrupt-cells = <2>;
};
+
+ pcieclk: clock-generator@68 {
+ compatible = "renesas,9fgv0241";
+ reg = <0x68>;
+ clocks = <&clk_xtal25>;
+ #clock-cells = <1>;
+ };
};
&i2c3 {
@@ -364,6 +398,15 @@
};
};
+&micfil {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdm>;
+ assigned-clocks = <&clk IMX8MP_CLK_PDM>;
+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <49152000>;
+ status = "okay";
+};
+
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie>;
@@ -372,8 +415,9 @@
};
&pcie_phy {
+ fsl,clkreq-unsupported;
fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
- clocks = <&pcie0_refclk>;
+ clocks = <&pcieclk 1>;
clock-names = "ref";
status = "okay";
};
@@ -545,6 +589,13 @@
>;
};
+ pinctrl_pdm: pdmgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_PDM_CLK 0xd6
+ MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_PDM_BIT_STREAM00 0xd6
+ >;
+ };
+
pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
fsl,pins = <
MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x40
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
index 13674dc64be9..d98a040860a4 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
@@ -362,6 +362,8 @@
};
buck2: BUCK2 { /* VDD_ARM */
+ nxp,dvs-run-voltage = <950000>;
+ nxp,dvs-standby-voltage = <850000>;
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1000000>;
regulator-ramp-delay = <3125>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
index 28db9349ed62..267ceffc02d8 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
@@ -284,7 +284,6 @@
usb_hub_2_x: hub@1 {
compatible = "usbbda,5411";
reg = <1>;
- reset-gpios = <&gpio4 25 GPIO_ACTIVE_LOW>;
vdd-supply = <&reg_usb_hub>;
peer-hub = <&usb_hub_3_x>;
};
@@ -293,7 +292,6 @@
usb_hub_3_x: hub@2 {
compatible = "usbbda,411";
reg = <2>;
- reset-gpios = <&gpio4 25 GPIO_ACTIVE_LOW>;
vdd-supply = <&reg_usb_hub>;
peer-hub = <&usb_hub_2_x>;
};
@@ -443,7 +441,6 @@
pinctrl_usb1: usb1grp {
fsl,pins = <
MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR 0x10
- MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x19
>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
index 0b0c95432bdc..0afd90224a59 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
@@ -220,7 +220,7 @@
reg = <0x52>;
pagesize = <16>;
#address-cells = <1>;
- #size-cells = <0>;
+ #size-cells = <1>;
/* MACs stored in ASCII */
ethmac1: mac-address@0 {
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts
index e9fb5f7f39b5..3b1c940860e0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts
@@ -186,9 +186,9 @@
&pcie_phy {
clock-names = "ref";
- clocks = <&clk IMX8MP_SYS_PLL2_100M>;
+ clocks = <&hsio_blk_ctrl>;
fsl,clkreq-unsupported;
- fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_UNUSED>;
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts
index 31d85d5871c9..b749e28e5ede 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts
@@ -35,33 +35,6 @@
clock-frequency = <25000000>;
};
- connector {
- compatible = "usb-c-connector";
- label = "USB-C";
- data-role = "dual";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- usb_c_0_hs_ep: endpoint {
- remote-endpoint = <&dwc3_0_hs_ep>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- usb_c_0_ss_ep: endpoint {
- remote-endpoint = <&ptn5150_in_ep>;
- };
- };
- };
- };
-
gpio-keys {
compatible = "gpio-keys";
@@ -202,33 +175,19 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ptn5150>;
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
+ port {
- port@0 {
- reg = <0>;
-
- ptn5150_in_ep: endpoint {
- remote-endpoint = <&usb_c_0_ss_ep>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- ptn5150_out_ep: endpoint {
- remote-endpoint = <&dwc3_0_ss_ep>;
- };
+ ptn5150_out_ep: endpoint {
+ remote-endpoint = <&dwc3_0_ep>;
};
};
};
power-sensor@40 {
- compatible = "ti,ina238";
- reg = <0x40>;
- shunt-resistor = <20000>; /* 0.02 R */
- ti,shunt-gain = <1>; /* Drop cca. 40mV */
+ compatible = "ti,ina238";
+ reg = <0x40>;
+ shunt-resistor = <20000>; /* 0.02 R */
+ ti,shunt-gain = <1>; /* Drop cca. 40mV */
};
eeprom_board: eeprom@54 {
@@ -253,10 +212,6 @@
};
};
-&ethphy0g {
- reg = <7>;
-};
-
&fec { /* Second ethernet */
pinctrl-0 = <&pinctrl_fec_rgmii>;
phy-handle = <&ethphypdk>;
@@ -310,16 +265,7 @@
usb-role-switch;
port {
- #address-cells = <1>;
- #size-cells = <0>;
-
- dwc3_0_hs_ep: endpoint@0 {
- reg = <0>;
- remote-endpoint = <&usb_c_0_hs_ep>;
- };
-
- dwc3_0_ss_ep: endpoint@1 {
- reg = <1>;
+ dwc3_0_ep: endpoint {
remote-endpoint = <&ptn5150_out_ep>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
index cb1953d14aa9..d8963f32ec84 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
@@ -25,9 +25,7 @@
reg_eth_vio: regulator-eth-vio {
compatible = "regulator-fixed";
- gpio = <&gpio2 10 GPIO_ACTIVE_LOW>;
- pinctrl-0 = <&pinctrl_enet_vio>;
- pinctrl-names = "default";
+ gpio = <&ioexp 2 GPIO_ACTIVE_LOW>;
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
@@ -57,6 +55,11 @@
regulator-max-microvolt = <3300000>;
regulator-name = "VDD_3P3V_AWO";
};
+
+ wlan_pwrseq: wifi-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&ioexp 1 GPIO_ACTIVE_LOW>;
+ };
};
&A53_0 {
@@ -112,7 +115,7 @@
reg = <0>;
reset-assert-us = <1000>;
reset-deassert-us = <1000>;
- reset-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&ioexp 4 GPIO_ACTIVE_LOW>;
/* Non-default PHY population option. */
status = "disabled";
};
@@ -128,7 +131,7 @@
reg = <5>;
reset-assert-us = <1000>;
reset-deassert-us = <1000>;
- reset-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&ioexp 4 GPIO_ACTIVE_LOW>;
/* Default PHY population option. */
status = "okay";
};
@@ -293,6 +296,8 @@
};
buck2: BUCK2 { /* VDD_ARM */
+ nxp,dvs-run-voltage = <950000>;
+ nxp,dvs-standby-voltage = <850000>;
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1000000>;
regulator-ramp-delay = <3125>;
@@ -348,8 +353,9 @@
};
adc@48 {
- compatible = "ti,tla2024";
+ compatible = "ti,ads1015";
reg = <0x48>;
+ interrupts-extended = <&ioexp 7 IRQ_TYPE_EDGE_FALLING>;
#address-cells = <1>;
#size-cells = <0>;
@@ -396,24 +402,42 @@
};
eeprom0: eeprom@50 { /* EEPROM with EQoS MAC address */
- compatible = "atmel,24c02";
- pagesize = <16>;
+ compatible = "atmel,24c32"; /* M24C32-D */
+ pagesize = <32>;
reg = <0x50>;
};
rv3032: rtc@51 {
compatible = "microcrystal,rv3032";
reg = <0x51>;
- interrupts-extended = <&gpio5 5 IRQ_TYPE_LEVEL_LOW>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_rtc>;
+ interrupts-extended = <&ioexp 3 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
};
eeprom1: eeprom@53 { /* EEPROM with FEC MAC address */
- compatible = "atmel,24c02";
- pagesize = <16>;
+ compatible = "atmel,24c32"; /* M24C32-D */
+ pagesize = <32>;
reg = <0x53>;
};
+
+ ioexp: gpio@74 {
+ compatible = "nxp,pca9539";
+ reg = <0x74>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts-extended = <&gpio3 20 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ioexp>;
+ wakeup-source;
+
+ gpio-line-names =
+ "BT_REG_EN", "WL_REG_EN", "VIO_SWITCHED_#EN", "RTC_#INT",
+ "ENET_QOS_#RST", "RGB_OSZ_ENABLE", "USB1_ID", "ADC_ALTER_RDY",
+ "DHCOM-W", "DHCOM-V", "DHCOM-U", "DHCOM-T",
+ "BT_HOST_WAKE", "BT_DEV_WAKE", "", "";
+ };
};
&i2c4 {
@@ -463,6 +487,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
status = "okay";
+ wakeup-source;
};
&uart2 {
@@ -484,10 +509,8 @@
assigned-clock-rates = <80000000>;
bluetooth {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2_bt>;
compatible = "cypress,cyw4373a0-bt";
- shutdown-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&ioexp 0 GPIO_ACTIVE_HIGH>;
max-speed = <4000000>;
};
};
@@ -514,8 +537,6 @@
};
&usb_dwc3_0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb0_vbus>;
dr_mode = "otg";
status = "okay";
};
@@ -541,6 +562,7 @@
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ mmc-pwrseq = <&wlan_pwrseq>;
vmmc-supply = <&buck4>;
bus-width = <4>;
non-removable;
@@ -559,7 +581,6 @@
* connected to the SoC, but can be connected on to
* SoC pin on the carrier board.
*/
- reset-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
};
};
@@ -601,8 +622,9 @@
&pinctrl_dhcom_d &pinctrl_dhcom_e &pinctrl_dhcom_f
&pinctrl_dhcom_g &pinctrl_dhcom_h &pinctrl_dhcom_i
&pinctrl_dhcom_j &pinctrl_dhcom_k &pinctrl_dhcom_l
- /* GPIO_M is connected to CLKOUT1 */
- &pinctrl_dhcom_int>;
+ &pinctrl_dhcom_m &pinctrl_dhcom_n &pinctrl_dhcom_o
+ &pinctrl_dhcom_p &pinctrl_dhcom_q &pinctrl_dhcom_r
+ &pinctrl_dhcom_s &pinctrl_dhcom_int>;
pinctrl-names = "default";
pinctrl_dhcom_a: dhcom-a-grp {
@@ -689,6 +711,55 @@
>;
};
+ pinctrl_dhcom_m: dhcom-m-grp {
+ fsl,pins = <
+ /* CSIx_MCLK */
+ MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x2
+ >;
+ };
+
+ pinctrl_dhcom_n: dhcom-n-grp {
+ fsl,pins = <
+ /* CSI2_D3- */
+ MX8MP_IOMUXC_SD1_DATA7__GPIO2_IO09 0x2
+ >;
+ };
+
+ pinctrl_dhcom_o: dhcom-o-grp {
+ fsl,pins = <
+ /* CSI2_D3+ */
+ MX8MP_IOMUXC_SD1_DATA6__GPIO2_IO08 0x2
+ >;
+ };
+
+ pinctrl_dhcom_p: dhcom-p-grp {
+ fsl,pins = <
+ /* CSI2_D2- */
+ MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x2
+ >;
+ };
+
+ pinctrl_dhcom_q: dhcom-q-grp {
+ fsl,pins = <
+ /* CSI2_D2+ */
+ MX8MP_IOMUXC_GPIO1_IO13__GPIO1_IO13 0x2
+ >;
+ };
+
+ pinctrl_dhcom_r: dhcom-r-grp {
+ fsl,pins = <
+ /* CSI2_D1- */
+ MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x2
+ >;
+ };
+
+ pinctrl_dhcom_s: dhcom-s-grp {
+ fsl,pins = <
+ /* CSI2_D1+ */
+ MX8MP_IOMUXC_GPIO1_IO10__GPIO1_IO10 0x2
+ >;
+ };
+
pinctrl_dhcom_int: dhcom-int-grp {
fsl,pins = <
/* INT_HIGHEST_PRIO */
@@ -762,16 +833,8 @@
>;
};
- pinctrl_enet_vio: dhcom-enet-vio-grp {
- fsl,pins = <
- MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x22
- >;
- };
-
pinctrl_ethphy0: dhcom-ethphy0-grp {
fsl,pins = <
- /* ENET_QOS_#RST Reset */
- MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20 0x22
/* ENET_QOS_#INT Interrupt */
MX8MP_IOMUXC_SAI5_RXFS__GPIO3_IO19 0x22
>;
@@ -897,6 +960,13 @@
>;
};
+ pinctrl_ioexp: dhcom-ioexp-grp {
+ fsl,pins = <
+ /* #GPIO_EXP_INT */
+ MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20 0x22
+ >;
+ };
+
pinctrl_pmic: dhcom-pmic-grp {
fsl,pins = <
/* PMIC_nINT */
@@ -910,13 +980,6 @@
>;
};
- pinctrl_rtc: dhcom-rtc-grp {
- fsl,pins = <
- /* RTC_#INT Interrupt */
- MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x40000080
- >;
- };
-
pinctrl_tc9595: dhcom-tc9595-grp {
fsl,pins = <
/* RESET_DSIBRIDGE */
@@ -962,13 +1025,6 @@
>;
};
- pinctrl_uart2_bt: dhcom-uart2-bt-grp {
- fsl,pins = <
- /* BT_REG_EN */
- MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x144
- >;
- };
-
pinctrl_uart3: dhcom-uart3-grp {
fsl,pins = <
MX8MP_IOMUXC_ECSPI1_SCLK__UART3_DCE_RX 0x49
@@ -985,12 +1041,6 @@
>;
};
- pinctrl_usb0_vbus: dhcom-usb0-grp {
- fsl,pins = <
- MX8MP_IOMUXC_GPIO1_IO10__USB1_OTG_ID 0x0
- >;
- };
-
pinctrl_usb1_vbus: dhcom-usb1-grp {
fsl,pins = <
MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR 0x6
@@ -1006,8 +1056,6 @@
MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0
MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0
MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0
- /* WL_REG_EN */
- MX8MP_IOMUXC_GPIO1_IO13__GPIO1_IO13 0x144
>;
};
@@ -1019,8 +1067,6 @@
MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d4
MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d4
MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d4
- /* WL_REG_EN */
- MX8MP_IOMUXC_GPIO1_IO13__GPIO1_IO13 0x144
>;
};
@@ -1032,8 +1078,6 @@
MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d6
MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d6
MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d6
- /* WL_REG_EN */
- MX8MP_IOMUXC_GPIO1_IO13__GPIO1_IO13 0x144
>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index 1e14c4cd3128..c8640cac3edc 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -19,6 +19,36 @@
stdout-path = &uart1;
};
+ reg_can1_stby: regulator-can1-stby {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1_reg>;
+ gpio = <&gpio3 20 GPIO_ACTIVE_LOW>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "can1-stby";
+ };
+
+ reg_can2_stby: regulator-can2-stby {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2_reg>;
+ gpio = <&gpio3 21 GPIO_ACTIVE_LOW>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "can2-stby";
+ };
+
+ reg_usb1_vbus: regulator-usb1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1_vbus>;
+ gpio = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-name = "usb1_host_vbus";
+ };
+
reg_usdhc2_vmmc: regulator-usdhc2 {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -57,6 +87,21 @@
};
};
+/* CAN FD */
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_can1_stby>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can2_stby>;
+ status = "okay";
+};
+
&i2c2 {
clock-frequency = <400000>;
pinctrl-names = "default", "gpio";
@@ -101,6 +146,47 @@
status = "okay";
};
+/* USB1 Host mode Type-A */
+&usb3_phy0 {
+ vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
+
+&usb3_0 {
+ status = "okay";
+};
+
+&usb_dwc3_0 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* USB2 4-port USB3.0 HUB */
+&usb3_phy1 {
+ status = "okay";
+};
+
+&usb3_1 {
+ fsl,permanently-attached;
+ fsl,disable-port-power-control;
+ status = "okay";
+};
+
+&usb_dwc3_1 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* RS232/RS485 */
+&uart2 {
+ assigned-clocks = <&clk IMX8MP_CLK_UART2>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
/* SD-Card */
&usdhc2 {
assigned-clocks = <&clk IMX8MP_CLK_USDHC2>;
@@ -115,6 +201,33 @@
status = "okay";
};
+&gpio1 {
+ gpio-line-names = "", "", "X_PMIC_WDOG_B", "",
+ "PMIC_SD_VSEL", "", "", "", "", "",
+ "", "", "USB1_OTG_PWR", "", "", "X_nETHPHY_INT";
+};
+
+&gpio2 {
+ gpio-line-names = "", "", "", "",
+ "", "", "", "", "", "",
+ "", "", "X_SD2_CD_B", "", "", "",
+ "", "", "", "SD2_RESET_B";
+};
+
+&gpio3 {
+ gpio-line-names = "", "", "", "",
+ "", "", "", "", "", "",
+ "", "", "", "", "", "",
+ "", "", "", "", "nCAN1_EN", "nCAN2_EN";
+};
+
+&gpio4 {
+ gpio-line-names = "", "", "", "",
+ "", "", "", "", "", "",
+ "", "", "", "", "", "",
+ "", "", "X_PMIC_IRQ_B", "", "nENET0_INT_PWDN";
+};
+
&iomuxc {
pinctrl_eqos: eqosgrp {
fsl,pins = <
@@ -136,6 +249,32 @@
>;
};
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_RXD2__CAN1_RX 0x154
+ MX8MP_IOMUXC_SAI5_RXD1__CAN1_TX 0x154
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_MCLK__CAN2_RX 0x154
+ MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX 0x154
+ >;
+ };
+
+ pinctrl_flexcan1_reg: flexcan1reggrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20 0x154
+ >;
+ };
+
+ pinctrl_flexcan2_reg: flexcan2reggrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI5_RXD0__GPIO3_IO21 0x154
+ >;
+ };
+
pinctrl_i2c2: i2c2grp {
fsl,pins = <
MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2
@@ -163,6 +302,21 @@
>;
};
+ pinctrl_usb1_vbus: usb1vbusgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x10
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140
+ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140
+ MX8MP_IOMUXC_SAI3_RXC__UART2_DCE_CTS 0x140
+ MX8MP_IOMUXC_SAI3_RXD__UART2_DCE_RTS 0x140
+ >;
+ };
+
pinctrl_usdhc2_pins: usdhc2-gpiogrp {
fsl,pins = <
MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x1c4
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
index d8df97060e8f..c976c3b6cbc6 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
@@ -199,6 +199,19 @@
status = "okay";
};
+&gpio1 {
+ gpio-line-names = "", "", "X_PMIC_WDOG_B", "",
+ "", "", "", "", "", "",
+ "", "", "", "", "", "X_nETHPHY_INT";
+};
+
+&gpio4 {
+ gpio-line-names = "", "", "", "",
+ "", "", "", "", "", "",
+ "", "", "", "", "", "",
+ "", "", "X_PMIC_IRQ_B";
+};
+
&iomuxc {
pinctrl_fec: fecgrp {
fsl,pins = <
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
index c531564c7ebb..bf47b5e9dd8c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
@@ -78,7 +78,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio4>;
interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi
index f3bab22d5e68..f942e949084b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi
@@ -113,7 +113,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio4>;
interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi
index 68c62def4c06..b0d42b18c5ce 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi
@@ -95,8 +95,15 @@
&ecspi2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi2>;
- cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>,
+ <&gpio1 10 GPIO_ACTIVE_LOW>;
status = "okay";
+
+ tpm@1 {
+ compatible = "tcg,tpm_tis-spi";
+ reg = <0x1>;
+ spi-max-frequency = <36000000>;
+ };
};
&gpio4 {
@@ -125,7 +132,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio4>;
interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso
new file mode 100644
index 000000000000..270a9114da97
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2023 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mp-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "gw,imx8mp-gw74xx", "fsl,imx8mp";
+
+ reg_cam: regulator-cam {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_cam>;
+ compatible = "regulator-fixed";
+ regulator-name = "reg_cam";
+ gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ cam24m: cam24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "cam24m";
+ };
+};
+
+&i2c4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ imx219: sensor@10 {
+ compatible = "sony,imx219";
+ reg = <0x10>;
+ clocks = <&cam24m>;
+ VDIG-supply = <&reg_cam>;
+
+ port {
+ /* MIPI CSI-2 bus endpoint */
+ imx219_to_mipi_csi2: endpoint {
+ remote-endpoint = <&mipi_csi_0_in>;
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ link-frequencies = /bits/ 64 <456000000>;
+ };
+ };
+ };
+};
+
+&isi_0 {
+ status = "okay";
+};
+
+&mipi_csi_0 {
+ status = "okay";
+
+ ports {
+ port@0 {
+ mipi_csi_0_in: endpoint {
+ remote-endpoint = <&imx219_to_mipi_csi2>;
+ data-lanes = <1 2>;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl_reg_cam: regcamgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO04__GPIO1_IO04 0x41
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
index faa370a5885f..2ab9f4cc12cc 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
@@ -461,7 +461,6 @@
st,drdy-int-pin = <1>;
interrupt-parent = <&gpio1>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "INT1";
};
switch: switch@5f {
@@ -512,7 +511,6 @@
port@5 {
reg = <5>;
- label = "cpu";
ethernet = <&fec>;
phy-mode = "rgmii-id";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
index e9e4fcb562f1..04f2083c4ab2 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
@@ -184,7 +184,6 @@
&eqos {
phy-handle = <&ethphy0>;
phy-mode = "rgmii-id";
- phy-supply = <&reg_module_eth1phy>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_eqos>;
snps,force_thresh_dma_mode;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 83d907294fbc..c9a610ba4836 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -202,6 +202,60 @@
clock-output-names = "clk_ext4";
};
+ funnel {
+ /*
+ * non-configurable funnel don't show up on the AMBA
+ * bus. As such no need to add "arm,primecell".
+ */
+ compatible = "arm,coresight-static-funnel";
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ ca_funnel_in_port0: endpoint {
+ remote-endpoint = <&etm0_out_port>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ ca_funnel_in_port1: endpoint {
+ remote-endpoint = <&etm1_out_port>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ ca_funnel_in_port2: endpoint {
+ remote-endpoint = <&etm2_out_port>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ ca_funnel_in_port3: endpoint {
+ remote-endpoint = <&etm3_out_port>;
+ };
+ };
+ };
+
+ out-ports {
+ port {
+
+ ca_funnel_out_port0: endpoint {
+ remote-endpoint = <&hugo_funnel_in_port0>;
+ };
+ };
+ };
+ };
+
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
@@ -368,59 +422,6 @@
};
};
- funnel {
- /*
- * non-configurable funnel don't show up on the AMBA
- * bus. As such no need to add "arm,primecell".
- */
- compatible = "arm,coresight-static-funnel";
-
- in-ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- ca_funnel_in_port0: endpoint {
- remote-endpoint = <&etm0_out_port>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- ca_funnel_in_port1: endpoint {
- remote-endpoint = <&etm1_out_port>;
- };
- };
-
- port@2 {
- reg = <2>;
-
- ca_funnel_in_port2: endpoint {
- remote-endpoint = <&etm2_out_port>;
- };
- };
-
- port@3 {
- reg = <3>;
-
- ca_funnel_in_port3: endpoint {
- remote-endpoint = <&etm3_out_port>;
- };
- };
- };
-
- out-ports {
- port {
- ca_funnel_out_port0: endpoint {
- remote-endpoint = <&hugo_funnel_in_port0>;
- };
- };
- };
- };
-
funnel@28c03000 {
compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
reg = <0x28c03000 0x1000>;
@@ -1459,6 +1460,47 @@
interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
+
+ easrc: easrc@30c90000 {
+ compatible = "fsl,imx8mp-easrc", "fsl,imx8mn-easrc";
+ reg = <0x30c90000 0x10000>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_ASRC_IPG>;
+ clock-names = "mem";
+ dmas = <&sdma2 16 23 0> , <&sdma2 17 23 0>,
+ <&sdma2 18 23 0> , <&sdma2 19 23 0>,
+ <&sdma2 20 23 0> , <&sdma2 21 23 0>,
+ <&sdma2 22 23 0> , <&sdma2 23 23 0>;
+ dma-names = "ctx0_rx", "ctx0_tx",
+ "ctx1_rx", "ctx1_tx",
+ "ctx2_rx", "ctx2_tx",
+ "ctx3_rx", "ctx3_tx";
+ firmware-name = "imx/easrc/easrc-imx8mn.bin";
+ fsl,asrc-rate = <8000>;
+ fsl,asrc-format = <2>;
+ status = "disabled";
+ };
+
+ micfil: audio-controller@30ca0000 {
+ compatible = "fsl,imx8mp-micfil";
+ reg = <0x30ca0000 0x10000>;
+ #sound-dai-cells = <0>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_PDM_IPG>,
+ <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_PDM_SEL>,
+ <&clk IMX8MP_AUDIO_PLL1_OUT>,
+ <&clk IMX8MP_AUDIO_PLL2_OUT>,
+ <&clk IMX8MP_CLK_EXT3>;
+ clock-names = "ipg_clk", "ipg_clk_app",
+ "pll8k", "pll11k", "clkext3";
+ dmas = <&sdma2 24 25 0x80000000>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
};
sdma3: dma-controller@30e00000 {
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
index 138a4d36a7ef..ffb5fe61630d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
@@ -381,7 +381,7 @@
gpio-hog;
gpios = <1 GPIO_ACTIVE_HIGH>;
input;
- lane-mapping = "pmic-5v";
+ line-name = "pmic-5v";
};
};
@@ -1001,7 +1001,7 @@
};
regulator@3e {
- compatible = "tps65132";
+ compatible = "ti,tps65132";
reg = <0x3e>;
reg_lcd_avdd: outp {
@@ -1154,15 +1154,12 @@
pinctrl-0 = <&pinctrl_charger_in>;
interrupt-parent = <&gpio3>;
interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
- phys = <&usb3_phy0>;
ti,battery-regulation-voltage = <4208000>; /* uV */
ti,termination-current = <128000>; /* uA */
ti,precharge-current = <128000>; /* uA */
ti,minimum-sys-voltage = <3700000>; /* uV */
ti,boost-voltage = <5000000>; /* uV */
ti,boost-max-current = <1500000>; /* uA */
- ti,use-vinmin-threshold = <1>; /* enable VINDPM */
- ti,vinmin-threshold = <3900000>; /* uV */
monitored-battery = <&bat>;
power-supplies = <&typec_pd>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts b/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts
index 8614c18b5998..767819cce886 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts
@@ -142,7 +142,7 @@
#address-cells = <1>;
#size-cells = <0>;
- i2c1a: i2c1@0 {
+ i2c1a: i2c@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
@@ -159,7 +159,7 @@
};
};
- i2c1b: i2c1@1 {
+ i2c1b: i2c@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
@@ -176,7 +176,7 @@
};
};
- i2c1c: i2c1@2 {
+ i2c1c: i2c@2 {
reg = <2>;
#address-cells = <1>;
#size-cells = <0>;
@@ -193,7 +193,7 @@
};
};
- i2c1d: i2c1@3 {
+ i2c1d: i2c@3 {
reg = <3>;
#address-cells = <1>;
#size-cells = <0>;
@@ -222,7 +222,7 @@
#address-cells = <1>;
#size-cells = <0>;
- i2c4@0 {
+ i2c@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
@@ -257,14 +257,14 @@
};
};
- ddc_i2c_bus: i2c4@1 {
+ ddc_i2c_bus: i2c@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <100000>;
};
- i2c4@3 {
+ i2c@3 {
reg = <3>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts b/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts
index 89cbec5c41b2..ec89b5adeb93 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts
@@ -67,12 +67,12 @@
compatible = "rohm,bd71837";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pmic>;
+ #clock-cells = <0>;
clocks = <&pmic_osc>;
clock-names = "osc";
clock-output-names = "pmic_clk";
interrupt-parent = <&gpio1>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "irq";
regulators {
buck1: BUCK1 {
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts b/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts
index 6e6182709d22..eaa9d0c0fcc1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts
@@ -107,7 +107,7 @@
compatible = "mmc-pwrseq-simple";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_wifi_reg_on>;
- gpio = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33.dtso b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33.dtso
new file mode 100644
index 000000000000..306977d6ba0c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33.dtso
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2019-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ compatible = "tq,imx8mq-tqma8mq-mba8mx", "tq,imx8mq-tqma8mq", "fsl,imx8mq";
+};
+
+&backlight_lvds {
+ status = "okay";
+};
+
+&dphy {
+ status = "okay";
+};
+
+&dsi_lvds_bridge {
+ status = "okay";
+};
+
+&expander0 {
+ dsi-mux-oe-hog {
+ gpio-hog;
+ gpios = <10 GPIO_ACTIVE_LOW>;
+ output-high;
+ line-name = "DSI_MUX_OE#";
+ };
+};
+
+&lcdif {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+};
+
+&panel {
+ compatible = "tianma,tm070jvhg33";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi
index cb777b47baf9..0c960efd9b3d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi
@@ -15,7 +15,7 @@
stdout-path = &uart1;
};
- mdio0: bitbang-mdio {
+ mdio0: mdio {
compatible = "virtual,mdio-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mdio_bitbang>, <&pinctrl_fec1_phy_reset>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 35f07dfb4ca8..4b1ce9fc1758 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -225,6 +225,59 @@
};
};
+ funnel {
+ /*
+ * non-configurable funnel don't show up on the AMBA
+ * bus. As such no need to add "arm,primecell".
+ */
+ compatible = "arm,coresight-static-funnel";
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ ca_funnel_in_port0: endpoint {
+ remote-endpoint = <&etm0_out_port>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ ca_funnel_in_port1: endpoint {
+ remote-endpoint = <&etm1_out_port>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ ca_funnel_in_port2: endpoint {
+ remote-endpoint = <&etm2_out_port>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ ca_funnel_in_port3: endpoint {
+ remote-endpoint = <&etm3_out_port>;
+ };
+ };
+ };
+
+ out-ports {
+ port {
+ ca_funnel_out_port0: endpoint {
+ remote-endpoint = <&hugo_funnel_in_port0>;
+ };
+ };
+ };
+ };
+
pmu {
compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
@@ -394,59 +447,6 @@
};
};
- funnel {
- /*
- * non-configurable funnel don't show up on the AMBA
- * bus. As such no need to add "arm,primecell".
- */
- compatible = "arm,coresight-static-funnel";
-
- in-ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- ca_funnel_in_port0: endpoint {
- remote-endpoint = <&etm0_out_port>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- ca_funnel_in_port1: endpoint {
- remote-endpoint = <&etm1_out_port>;
- };
- };
-
- port@2 {
- reg = <2>;
-
- ca_funnel_in_port2: endpoint {
- remote-endpoint = <&etm2_out_port>;
- };
- };
-
- port@3 {
- reg = <3>;
-
- ca_funnel_in_port3: endpoint {
- remote-endpoint = <&etm3_out_port>;
- };
- };
- };
-
- out-ports {
- port {
- ca_funnel_out_port0: endpoint {
- remote-endpoint = <&hugo_funnel_in_port0>;
- };
- };
- };
- };
-
funnel@28c03000 {
compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
reg = <0x28c03000 0x1000>;
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi
index 1c6af9f549a8..4d6427fbe875 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi
@@ -21,7 +21,6 @@
* this PHY model. Use delay on MAC side instead.
*/
&fec1 {
- fsl,rgmii_txc_dly;
phy-mode = "rgmii-rxid";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
index 0b34cc2250e1..6d50838ad17d 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
@@ -47,6 +47,18 @@
status = "okay";
};
+&lpuart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ status = "okay";
+};
+
+&lpuart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>;
+ status = "okay";
+};
+
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec1>;
@@ -118,6 +130,20 @@
>;
};
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <
+ IMX8QM_UART0_RTS_B_DMA_UART2_RX 0x06000020
+ IMX8QM_UART0_CTS_B_DMA_UART2_TX 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <
+ IMX8QM_M41_GPIO0_00_DMA_UART3_RX 0x06000020
+ IMX8QM_M41_GPIO0_01_DMA_UART3_TX 0x06000020
+ >;
+ };
+
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
IMX8QM_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
index e9b198c13b2f..01539df335f8 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
@@ -44,6 +44,58 @@
};
};
+&edma2 {
+ reg = <0x5a1f0000 0x170000>;
+ #dma-cells = <3>;
+ dma-channels = <22>;
+ dma-channel-mask = <0xf00>;
+ interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* unused */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* unused */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* unused */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, /* unused */
+ <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd IMX_SC_R_DMA_0_CH0>,
+ <&pd IMX_SC_R_DMA_0_CH1>,
+ <&pd IMX_SC_R_DMA_0_CH2>,
+ <&pd IMX_SC_R_DMA_0_CH3>,
+ <&pd IMX_SC_R_DMA_0_CH4>,
+ <&pd IMX_SC_R_DMA_0_CH5>,
+ <&pd IMX_SC_R_DMA_0_CH6>,
+ <&pd IMX_SC_R_DMA_0_CH7>,
+ <&pd IMX_SC_R_DMA_0_CH8>,
+ <&pd IMX_SC_R_DMA_0_CH9>,
+ <&pd IMX_SC_R_DMA_0_CH10>,
+ <&pd IMX_SC_R_DMA_0_CH11>,
+ <&pd IMX_SC_R_DMA_0_CH12>,
+ <&pd IMX_SC_R_DMA_0_CH13>,
+ <&pd IMX_SC_R_DMA_0_CH14>,
+ <&pd IMX_SC_R_DMA_0_CH15>,
+ <&pd IMX_SC_R_DMA_0_CH16>,
+ <&pd IMX_SC_R_DMA_0_CH17>,
+ <&pd IMX_SC_R_DMA_0_CH18>,
+ <&pd IMX_SC_R_DMA_0_CH19>,
+ <&pd IMX_SC_R_DMA_0_CH20>,
+ <&pd IMX_SC_R_DMA_0_CH21>;
+ status = "okay";
+};
+
&flexcan1 {
fsl,clk-source = /bits/ 8 <1>;
};
@@ -64,18 +116,22 @@
&lpuart0 {
compatible = "fsl,imx8qm-lpuart", "fsl,imx8qxp-lpuart";
+ dmas = <&edma2 13 0 0>, <&edma2 12 0 1>;
};
&lpuart1 {
compatible = "fsl,imx8qm-lpuart", "fsl,imx8qxp-lpuart";
+ dmas = <&edma2 15 0 0>, <&edma2 14 0 1>;
};
&lpuart2 {
compatible = "fsl,imx8qm-lpuart", "fsl,imx8qxp-lpuart";
+ dmas = <&edma2 17 0 0>, <&edma2 16 0 1>;
};
&lpuart3 {
compatible = "fsl,imx8qm-lpuart", "fsl,imx8qxp-lpuart";
+ dmas = <&edma2 19 0 0>, <&edma2 18 0 1>;
};
&i2c0 {
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi
index 7764b4146e0a..2bbdacb1313f 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi
@@ -8,5 +8,5 @@
};
&jpegenc {
- compatible = "nxp,imx8qm-jpgdec", "nxp,imx8qxp-jpgenc";
+ compatible = "nxp,imx8qm-jpgenc", "nxp,imx8qxp-jpgenc";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 7924b0969ad8..99611729943c 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -187,6 +187,18 @@
status = "okay";
};
+&lpuart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ status = "okay";
+};
+
+&lpuart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>;
+ status = "okay";
+};
+
&mu_m0 {
status = "okay";
};
@@ -340,6 +352,20 @@
>;
};
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <
+ IMX8QXP_UART2_TX_ADMA_UART2_TX 0x06000020
+ IMX8QXP_UART2_RX_ADMA_UART2_RX 0x06000020
+ >;
+ };
+
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <
+ IMX8QXP_FLEXCAN2_TX_ADMA_UART3_TX 0x06000020
+ IMX8QXP_FLEXCAN2_RX_ADMA_UART3_RX 0x06000020
+ >;
+ };
+
pinctrl_typec: typecgrp {
fsl,pins = <
IMX8QXP_SPI2_SCK_LSIO_GPIO1_IO03 0x06000021
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index 8a6596d5a581..f22c1ac391c9 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -360,7 +360,7 @@
interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&pcc4 IMX8ULP_CLK_FLEXSPI2>,
<&pcc4 IMX8ULP_CLK_FLEXSPI2>;
- clock-names = "fspi", "fspi_en";
+ clock-names = "fspi_en", "fspi";
assigned-clocks = <&pcc4 IMX8ULP_CLK_FLEXSPI2>;
assigned-clock-parents = <&cgc1 IMX8ULP_CLK_SPLL3_PFD3_DIV2>;
status = "disabled";
@@ -484,11 +484,12 @@
};
gpioe: gpio@2d000080 {
- compatible = "fsl,imx8ulp-gpio", "fsl,imx7ulp-gpio";
- reg = <0x2d000080 0x1000>, <0x2d000040 0x40>;
+ compatible = "fsl,imx8ulp-gpio";
+ reg = <0x2d000000 0x1000>;
gpio-controller;
#gpio-cells = <2>;
- interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&pcc4 IMX8ULP_CLK_RGPIOE>,
@@ -498,11 +499,12 @@
};
gpiof: gpio@2d010080 {
- compatible = "fsl,imx8ulp-gpio", "fsl,imx7ulp-gpio";
- reg = <0x2d010080 0x1000>, <0x2d010040 0x40>;
+ compatible = "fsl,imx8ulp-gpio";
+ reg = <0x2d010000 0x1000>;
gpio-controller;
#gpio-cells = <2>;
- interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&pcc4 IMX8ULP_CLK_RGPIOF>,
@@ -533,11 +535,12 @@
};
gpiod: gpio@2e200080 {
- compatible = "fsl,imx8ulp-gpio", "fsl,imx7ulp-gpio";
- reg = <0x2e200080 0x1000>, <0x2e200040 0x40>;
+ compatible = "fsl,imx8ulp-gpio";
+ reg = <0x2e200000 0x1000>;
gpio-controller;
#gpio-cells = <2>;
- interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&pcc5 IMX8ULP_CLK_RGPIOD>,
diff --git a/arch/arm64/boot/dts/freescale/imx8x-colibri-iris-v2.dtsi b/arch/arm64/boot/dts/freescale/imx8x-colibri-iris-v2.dtsi
index 98202a437040..58ec0b399c4f 100644
--- a/arch/arm64/boot/dts/freescale/imx8x-colibri-iris-v2.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8x-colibri-iris-v2.dtsi
@@ -23,11 +23,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lvds_converter &pinctrl_gpio_iris>;
- pinctrl_enable_3v3_vmmc: enable_3v3_vmmc {
+ pinctrl_enable_3v3_vmmc: enable-3v3-vmmc-grp {
fsl,pins = <IMX8QXP_SAI1_RXFS_LSIO_GPIO0_IO31 0x20>; /* SODIMM 100 */
};
- pinctrl_lvds_converter: lcd-lvds {
+ pinctrl_lvds_converter: lvds-converter-grp {
fsl,pins = <IMX8QXP_FLEXCAN1_TX_LSIO_GPIO1_IO18 0x20>, /* SODIMM 55 */
/* 6B/8B mode. Select LOW - 8B mode (24bit) */
<IMX8QXP_FLEXCAN1_RX_LSIO_GPIO1_IO17 0x20>, /* SODIMM 63 */
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index cafd39130eb8..2b9d47716f75 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -149,6 +149,12 @@
status = "okay";
};
+&lpuart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "okay";
+};
+
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
@@ -222,6 +228,15 @@
>;
};
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX93_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x31e
+ MX93_PAD_DAP_TDI__LPUART5_RX 0x31e
+ MX93_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x31e
+ MX93_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x31e
+ >;
+ };
+
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe
diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
index dcf6e4846ac9..ceccf4766440 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -185,6 +185,46 @@
#size-cells = <1>;
ranges;
+ edma1: dma-controller@44000000 {
+ compatible = "fsl,imx93-edma3";
+ reg = <0x44000000 0x200000>;
+ #dma-cells = <3>;
+ dma-channels = <31>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, // 0: Reserved
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, // 1: CANFD1
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, // 2: Reserved
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, // 3: GPIO1 CH0
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, // 4: GPIO1 CH1
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, // 5: I3C1 TO Bus
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, // 6: I3C1 From Bus
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, // 7: LPI2C1 M TX
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, // 8: LPI2C1 S TX
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, // 9: LPI2C2 M RX
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>, // 10: LPI2C2 S RX
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>, // 11: LPSPI1 TX
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>, // 12: LPSPI1 RX
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, // 13: LPSPI2 TX
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, // 14: LPSPI2 RX
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, // 15: LPTMR1
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, // 16: LPUART1 TX
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>, // 17: LPUART1 RX
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, // 18: LPUART2 TX
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, // 19: LPUART2 RX
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, // 20: S400
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, // 21: SAI TX
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, // 22: SAI RX
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, // 23: TPM1 CH0/CH2
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, // 24: TPM1 CH1/CH3
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, // 25: TPM1 Overflow
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, // 26: TMP2 CH0/CH2
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, // 27: TMP2 CH1/CH3
+ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, // 28: TMP2 Overflow
+ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, // 29: PDM
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; // 30: ADC1
+ clocks = <&clk IMX93_CLK_EDMA1_GATE>;
+ clock-names = "dma";
+ };
+
aonmix_ns_gpr: syscon@44210000 {
compatible = "fsl,imx93-aonmix-ns-syscfg", "syscon";
reg = <0x44210000 0x1000>;
@@ -296,6 +336,8 @@
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART1_GATE>;
clock-names = "ipg";
+ dmas = <&edma1 17 0 1>, <&edma1 16 0 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -305,6 +347,8 @@
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART2_GATE>;
clock-names = "ipg";
+ dmas = <&edma1 19 0 1>, <&edma1 18 0 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -386,6 +430,7 @@
tmu: tmu@44482000 {
compatible = "fsl,qoriq-tmu";
reg = <0x44482000 0x1000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_TMC_GATE>;
little-endian;
fsl,tmu-range = <0x800000da 0x800000e9
@@ -424,6 +469,80 @@
#size-cells = <1>;
ranges;
+ edma2: dma-controller@42000000 {
+ compatible = "fsl,imx93-edma4";
+ reg = <0x42000000 0x210000>;
+ #dma-cells = <3>;
+ shared-interrupt;
+ dma-channels = <64>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX93_CLK_EDMA2_GATE>;
+ clock-names = "dma";
+ };
+
wakeupmix_gpr: syscon@42420000 {
compatible = "fsl,imx93-wakeupmix-syscfg", "syscon";
reg = <0x42420000 0x1000>;
@@ -551,6 +670,8 @@
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART3_GATE>;
clock-names = "ipg";
+ dmas = <&edma2 18 0 1>, <&edma2 17 0 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -560,6 +681,8 @@
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART4_GATE>;
clock-names = "ipg";
+ dmas = <&edma2 20 0 1>, <&edma2 19 0 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -569,6 +692,8 @@
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART5_GATE>;
clock-names = "ipg";
+ dmas = <&edma2 22 0 1>, <&edma2 21 0 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -578,6 +703,8 @@
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART6_GATE>;
clock-names = "ipg";
+ dmas = <&edma2 24 0 1>, <&edma2 23 0 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -617,6 +744,8 @@
interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART7_GATE>;
clock-names = "ipg";
+ dmas = <&edma2 88 0 1>, <&edma2 87 0 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -626,6 +755,8 @@
interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART8_GATE>;
clock-names = "ipg";
+ dmas = <&edma2 90 0 1>, <&edma2 89 0 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -827,11 +958,12 @@
};
gpio2: gpio@43810080 {
- compatible = "fsl,imx93-gpio", "fsl,imx7ulp-gpio";
- reg = <0x43810080 0x1000>, <0x43810040 0x40>;
+ compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
+ reg = <0x43810000 0x1000>;
gpio-controller;
#gpio-cells = <2>;
- interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&clk IMX93_CLK_GPIO2_GATE>,
@@ -841,11 +973,12 @@
};
gpio3: gpio@43820080 {
- compatible = "fsl,imx93-gpio", "fsl,imx7ulp-gpio";
- reg = <0x43820080 0x1000>, <0x43820040 0x40>;
+ compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
+ reg = <0x43820000 0x1000>;
gpio-controller;
#gpio-cells = <2>;
- interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&clk IMX93_CLK_GPIO3_GATE>,
@@ -856,11 +989,12 @@
};
gpio4: gpio@43830080 {
- compatible = "fsl,imx93-gpio", "fsl,imx7ulp-gpio";
- reg = <0x43830080 0x1000>, <0x43830040 0x40>;
+ compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
+ reg = <0x43830000 0x1000>;
gpio-controller;
#gpio-cells = <2>;
- interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&clk IMX93_CLK_GPIO4_GATE>,
@@ -870,11 +1004,12 @@
};
gpio1: gpio@47400080 {
- compatible = "fsl,imx93-gpio", "fsl,imx7ulp-gpio";
- reg = <0x47400080 0x1000>, <0x47400040 0x40>;
+ compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
+ reg = <0x47400000 0x1000>;
gpio-controller;
#gpio-cells = <2>;
- interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&clk IMX93_CLK_GPIO1_GATE>,
diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
index 8a9fe5cdcc98..e2bc53b8d39a 100644
--- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
@@ -8,6 +8,16 @@
/* TQ-Systems GmbH MBa8Mx baseboard */
/ {
+ backlight_lvds: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm3 0 5000000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_12v>;
+ enable-gpios = <&expander2 2 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
beeper {
compatible = "pwm-beeper";
pwms = <&pwm4 0 250000 0>;
@@ -65,12 +75,45 @@
};
};
+ gpio_delays: gpio-delays {
+ compatible = "gpio-delay";
+ #gpio-cells = <3>;
+ gpio-controller;
+ gpios = <&expander0 6 GPIO_ACTIVE_HIGH>;
+ gpio-line-names = "LVDS_BRIDGE_EN_1V8";
+ };
+
+ panel: panel-lvds {
+ /*
+ * Display is not fixed, so compatible has to be added from
+ * DT overlay
+ */
+ backlight = <&backlight_lvds>;
+ power-supply = <&reg_vcc_3v3>;
+ status = "disabled";
+
+ port {
+ panel_in_lvds: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&lvds_bridge_out>;
+ };
+ };
+ };
+
pcie0_refclk: pcie0-refclk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <100000000>;
};
+ reg_12v: regulator-12v {
+ compatible = "regulator-fixed";
+ regulator-name = "MBA8MX_12V";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ };
+
reg_hub_vbus: regulator-hub-vbus {
compatible = "regulator-fixed";
regulator-name = "MBA8MX_HUB_VBUS";
@@ -157,6 +200,10 @@
interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <2>;
+ gpio-line-names = "", "", "", "",
+ "", "", "LVDS_BRIDGE_EN", "",
+ "", "", "", "",
+ "", "", "", "";
sd-mux-oe-hog {
gpio-hog;
@@ -227,6 +274,52 @@
scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "okay";
+
+ dsi_lvds_bridge: bridge@2d {
+ compatible = "ti,sn65dsi84";
+ reg = <0x2d>;
+ enable-gpios = <&gpio_delays 0 130000 0>;
+ vcc-supply = <&reg_sn65dsi83_1v8>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ lvds_bridge_in: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&mipi_dsi_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ lvds_bridge_out: endpoint {
+ remote-endpoint = <&panel_in_lvds>;
+ };
+ };
+ };
+ };
+};
+
+&mipi_dsi {
+ samsung,burst-clock-frequency = <891000000>;
+ samsung,esc-clock-frequency = <20000000>;
+
+ ports {
+ port@1 {
+ reg = <1>;
+
+ mipi_dsi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&lvds_bridge_in>;
+ };
+ };
+ };
};
&pwm3 {
diff --git a/arch/arm64/boot/dts/freescale/tqmls104xa-mbls10xxa-fman.dtsi b/arch/arm64/boot/dts/freescale/tqmls104xa-mbls10xxa-fman.dtsi
new file mode 100644
index 000000000000..4c38dd541143
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/tqmls104xa-mbls10xxa-fman.dtsi
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2019,2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ *
+ * Device Tree Include file for MBLS10xxA from TQ (FMAN related sections)
+ */
+
+#include <dt-bindings/net/ti-dp83867.h>
+
+&enet0 {
+ status = "disabled";
+};
+
+&enet1 {
+ status = "disabled";
+};
+
+&enet2 {
+ phy-handle = <&rgmii_phy1>;
+ phy-connection-type = "rgmii";
+ phy-mode = "rgmii-id";
+ status = "okay";
+};
+
+&enet3 {
+ phy-handle = <&rgmii_phy2>;
+ phy-connection-type = "rgmii";
+ phy-mode = "rgmii-id";
+ status = "okay";
+};
+
+&enet4 {
+ status = "disabled";
+};
+
+&enet5 {
+ status = "disabled";
+};
+
+&enet6 {
+ status = "disabled";
+};
+
+&mdio0 {
+ status = "okay";
+
+ qsgmii2_phy1: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x00>;
+ };
+
+ qsgmii2_phy2: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x01>;
+ };
+
+ qsgmii2_phy3: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x02>;
+ };
+
+ qsgmii2_phy4: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x03>;
+ };
+
+ rgmii_phy2: ethernet-phy@c {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0c>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+ };
+
+ rgmii_phy1: ethernet-phy@e {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0e>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+ };
+
+ qsgmii1_phy1: ethernet-phy@1c {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1c>;
+ };
+
+ qsgmii1_phy2: ethernet-phy@1d {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1d>;
+ };
+
+ qsgmii1_phy3: ethernet-phy@1e {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1e>;
+ };
+
+ qsgmii1_phy4: ethernet-phy@1f {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1f>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/tqmls1088a-mbls10xxa-mc.dtsi b/arch/arm64/boot/dts/freescale/tqmls1088a-mbls10xxa-mc.dtsi
new file mode 100644
index 000000000000..2471bb109e8e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/tqmls1088a-mbls10xxa-mc.dtsi
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ *
+ * Device Tree Include file for MBLS10xxA from TQ (MC related sections)
+ */
+
+#include <dt-bindings/net/ti-dp83867.h>
+
+/ {
+ sfp1: sfp1 {
+ compatible = "sff,sfp";
+ i2c-bus = <&sfp1_i2c>;
+ mod-def0-gpios = <&gpioexp2 2 GPIO_ACTIVE_LOW>;
+ los-gpios = <&gpioexp2 3 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpios = <&gpioexp2 0 GPIO_ACTIVE_HIGH>;
+ tx-disable-gpios = <&gpioexp2 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ sfp2: sfp2 {
+ compatible = "sff,sfp";
+ i2c-bus = <&sfp2_i2c>;
+ mod-def0-gpios = <&gpioexp2 10 GPIO_ACTIVE_LOW>;
+ los-gpios = <&gpioexp2 11 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpios = <&gpioexp2 8 GPIO_ACTIVE_HIGH>;
+ tx-disable-gpios = <&gpioexp2 9 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&dpmac1 {
+ pcs-handle = <&pcs1>;
+};
+
+&dpmac2 {
+ pcs-handle = <&pcs2>;
+};
+
+&dpmac3 {
+ pcs-handle = <&pcs3_0>;
+};
+
+&dpmac4 {
+ pcs-handle = <&pcs3_1>;
+};
+
+&dpmac5 {
+ pcs-handle = <&pcs3_2>;
+};
+
+&dpmac6 {
+ pcs-handle = <&pcs3_3>;
+};
+
+&dpmac7 {
+ pcs-handle = <&pcs7_0>;
+};
+
+&dpmac8 {
+ pcs-handle = <&pcs7_1>;
+};
+
+&dpmac9 {
+ pcs-handle = <&pcs7_2>;
+};
+
+&dpmac10 {
+ pcs-handle = <&pcs7_3>;
+};
+
+&emdio1 {
+ status = "okay";
+
+ qsgmii2_phy1: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x00>;
+ };
+
+ qsgmii2_phy2: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x01>;
+ };
+
+ qsgmii2_phy3: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x02>;
+ };
+
+ qsgmii2_phy4: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x03>;
+ };
+
+ rgmii_phy2: ethernet-phy@c {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0c>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+ };
+
+ rgmii_phy1: ethernet-phy@e {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0e>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+ };
+
+ qsgmii1_phy1: ethernet-phy@1c {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1c>;
+ };
+
+ qsgmii1_phy2: ethernet-phy@1d {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1d>;
+ };
+
+ qsgmii1_phy3: ethernet-phy@1e {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1e>;
+ };
+
+ qsgmii1_phy4: ethernet-phy@1f {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1f>;
+ };
+};
+
+&pcs_mdio1 {
+ status = "okay";
+};
+
+&pcs_mdio2 {
+ status = "okay";
+};
+
+&pcs_mdio3 {
+ status = "okay";
+};
+
+&pcs_mdio7 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/tqmls10xxa-mbls10xxa.dtsi b/arch/arm64/boot/dts/freescale/tqmls10xxa-mbls10xxa.dtsi
new file mode 100644
index 000000000000..65b4ed28a3d4
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/tqmls10xxa-mbls10xxa.dtsi
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ *
+ * Device Tree Include file for MBLS10xxA from TQ
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ gpio-keys-polled {
+ compatible = "gpio-keys-polled";
+ poll-interval = <100>;
+ autorepeat;
+
+ button-0 {
+ label = "button0";
+ gpios = <&gpioexp3 5 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_F1>;
+ };
+
+ button-1 {
+ label = "button1";
+ gpios = <&gpioexp3 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_F2>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-user {
+ gpios = <&gpioexp3 13 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_HEARTBEAT;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3_MB";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&duart0 {
+ status = "okay";
+};
+
+&duart1 {
+ status = "okay";
+};
+
+&esdhc {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9544";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ reg = <0x0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpioexp1: gpio@20 {
+ compatible = "nxp,pca9555";
+ reg = <0x20>;
+ vcc-supply = <&reg_3v3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpioexp2: gpio@21 {
+ compatible = "nxp,pca9555";
+ reg = <0x21>;
+ vcc-supply = <&reg_3v3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpioexp3: gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ vcc-supply = <&reg_3v3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ sfp1_i2c: i2c@1 {
+ reg = <0x1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ sfp2_i2c: i2c@2 {
+ reg = <0x2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c@3 {
+ reg = <0x3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&sata {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ dr_mode = "otg";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/tqmls10xxa.dtsi b/arch/arm64/boot/dts/freescale/tqmls10xxa.dtsi
new file mode 100644
index 000000000000..138f8778afde
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/tqmls10xxa.dtsi
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Gregor Herburger, Timo Herbrecher
+ *
+ * Device Tree Include file for TQMLs10xxA SoM of TQ
+ */
+
+/ {
+ reg_vcc3v3: regulator-vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ temperature-sensor@18 {
+ compatible = "nxp,se97b", "jedec,jc-42.4-temp";
+ reg = <0x18>;
+ };
+
+ eeprom@50 {
+ compatible = "nxp,se97b", "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ vcc-supply = <&reg_vcc3v3>;
+ read-only;
+ };
+
+ rtc@51 {
+ compatible = "nxp,pcf85063a";
+ reg = <0x51>;
+ };
+
+ eeprom@57 {
+ compatible = "atmel,24c64";
+ reg = <0x57>;
+ pagesize = <32>;
+ vcc-supply = <&reg_vcc3v3>;
+ };
+};
+
+&esdhc {
+ /* eSDHC or eMMC: set by bootloader */
+ non-removable;
+ disable-wp;
+ mmc-hs200-1_8v;
+ sd-uhs-sdr104;
+ sd-uhs-sdr50;
+ sd-uhs-sdr25;
+ sd-uhs-sdr12;
+};
diff --git a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
index 62d03ffa9485..b5e042b8e929 100644
--- a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
@@ -144,7 +144,7 @@
clocks = <&cnm_clock>;
clock-names = "core";
interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
- clock-frequency=<100000>;
+ clock-frequency = <100000>;
pinctrl-names = "default", "gpio";
pinctrl-0 = <&i2c0_pins>;
@@ -163,7 +163,7 @@
clocks = <&cnm_clock>;
clock-names = "core";
interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
- clock-frequency=<100000>;
+ clock-frequency = <100000>;
pinctrl-names = "default", "gpio";
pinctrl-0 = <&i2c1_pins>;
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts b/arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts
index 57fc698e55d0..d6d37a1f6f38 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts
@@ -12,3 +12,50 @@
&eth0 {
phy-mode = "2500base-x";
};
+
+/*
+ * External MV88E6361 switch is only available on v2 of the board.
+ * U-Boot will enable the MDIO bus and switch nodes.
+ */
+&mdio {
+ status = "disabled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smi_pins>;
+
+ /* Actual device is MV88E6361 */
+ switch: switch@0 {
+ compatible = "marvell,mv88e6190";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "cpu";
+ phy-mode = "2500base-x";
+ managed = "in-band-status";
+ ethernet = <&eth0>;
+ };
+
+ port@9 {
+ reg = <9>;
+ label = "downlink";
+ phy-mode = "2500base-x";
+ managed = "in-band-status";
+ };
+
+ port@a {
+ reg = <10>;
+ label = "uplink";
+ phy-mode = "2500base-x";
+ managed = "in-band-status";
+ sfp = <&sfp_eth1>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi
index 3f79923376fb..3a9b6907185d 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi
@@ -61,10 +61,10 @@
sfp_eth1: sfp-eth1 {
compatible = "sff,sfp";
i2c-bus = <&i2c1>;
- los-gpio = <&gpiosb 7 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>;
+ los-gpios = <&gpiosb 7 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&gpiosb 8 GPIO_ACTIVE_LOW>;
+ tx-disable-gpios = <&gpiosb 9 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpios = <&gpiosb 10 GPIO_ACTIVE_HIGH>;
maximum-power-milliwatt = <3000>;
};
};
diff --git a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
index 32cfb3e2efc3..47d45ff3d6f5 100644
--- a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
+++ b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
@@ -120,7 +120,7 @@
"mpp59", "mpp60", "mpp61";
marvell,function = "sdio";
};
- cp0_spi0_pins: cp0-spi-pins-0 {
+ cp0_spi1_pins: cp0-spi-pins-1 {
marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
marvell,function = "spi1";
};
@@ -170,7 +170,7 @@
&cp0_spi1 {
pinctrl-names = "default";
- pinctrl-0 = <&cp0_spi0_pins>;
+ pinctrl-0 = <&cp0_spi1_pins>;
reg = <0x700680 0x50>, /* control */
<0x2000000 0x1000000>; /* CS0 */
status = "okay";
diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
index c7de1ea0d470..6eb6a175de38 100644
--- a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
+++ b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
@@ -307,7 +307,7 @@
&cp0_spi1 {
status = "disabled";
pinctrl-names = "default";
- pinctrl-0 = <&cp0_spi0_pins>;
+ pinctrl-0 = <&cp0_spi1_pins>;
reg = <0x700680 0x50>;
flash@0 {
@@ -371,7 +371,7 @@
"mpp59", "mpp60", "mpp61";
marvell,function = "sdio";
};
- cp0_spi0_pins: cp0-spi-pins-0 {
+ cp0_spi1_pins: cp0-spi-pins-1 {
marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
marvell,function = "spi1";
};
diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index c99c3372a4b5..e6e7592a3645 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -45,7 +45,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-hayato-r1.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-hayato-r5-sku2.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-spherion-r0.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-spherion-r4.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r1.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r2.dtb
@@ -53,4 +55,5 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r3.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts b/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts
index b5746e6d0b15..7364c7278276 100644
--- a/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts
+++ b/arch/arm64/boot/dts/mediatek/mt6795-sony-xperia-m5.dts
@@ -22,6 +22,23 @@
serial1 = &uart1;
};
+ backlight_lcd0: backlight {
+ compatible = "led-backlight";
+ leds = <&disp_led_pwm>, <&pmic_bl_led>;
+
+ default-brightness-level = <300>;
+ };
+
+ led-controller-display {
+ compatible = "pwm-leds";
+
+ disp_led_pwm: led-0 {
+ label = "backlight-pwm";
+ pwms = <&pwm0 0 500000>;
+ max-brightness = <1024>;
+ };
+ };
+
memory@40000000 {
device_type = "memory";
reg = <0 0x40000000 0 0x1e800000>;
@@ -49,6 +66,65 @@
no-map;
};
};
+
+ vreg_disp_avdd: regulator-disp-avdd {
+ compatible = "regulator-fixed";
+ regulator-name = "disp_avdd";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&pio 138 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vreg_disp_avee: regulator-disp-avee {
+ compatible = "regulator-fixed";
+ regulator-name = "disp_avee";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&pio 139 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vreg_disp_vddh: regulator-disp-vddh {
+ compatible = "regulator-fixed";
+ regulator-name = "disp_vddh";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&dsi0 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel: panel@0 {
+ compatible = "sharp,ls060t1sx01";
+ reg = <0>;
+ avdd-supply = <&vreg_disp_avdd>;
+ avee-supply = <&vreg_disp_avee>;
+ vddi-supply = <&mt6331_vgp3_reg>;
+ vddh-supply = <&vreg_disp_vddh>;
+ reset-gpios = <&pio 106 GPIO_ACTIVE_LOW>;
+ backlight = <&backlight_lcd0>;
+
+ pinctrl-0 = <&disp_rst_pins>;
+ pinctrl-names = "default";
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dsi0_out>;
+ };
+ };
+ };
+
+ port {
+ dsi0_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
};
&fhctl {
@@ -163,7 +239,17 @@
status = "okay";
};
+&mt6331_vgp3_reg {
+ regulator-min-microvolt = <1800000>;
+};
+
&pio {
+ disp_rst_pins: lcm-pins {
+ pins-rst {
+ pinmux = <PINMUX_GPIO106__FUNC_GPIO106>;
+ };
+ };
+
mmc0_pins_default: emmc-sdr-pins {
pins-cmd-dat {
pinmux = <PINMUX_GPIO154__FUNC_MSDC0_DAT0>,
@@ -338,6 +424,21 @@
* an interrupt on the companion, so we use the MT6332 IRQ GPIO.
*/
interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>;
+
+ mt6332-led {
+ compatible = "mediatek,mt6332-led";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic_bl_led: led@0 {
+ reg = <0>;
+ label = "backlight-pmic";
+ };
+ };
+};
+
+&pwm0 {
+ status = "okay";
};
&uart0 {
diff --git a/arch/arm64/boot/dts/mediatek/mt6795.dtsi b/arch/arm64/boot/dts/mediatek/mt6795.dtsi
index 597bce2fed72..e5e269a660b1 100644
--- a/arch/arm64/boot/dts/mediatek/mt6795.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6795.dtsi
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015 MediaTek Inc.
- * Author: Mars.C <mars.cheng@mediatek.com>
+ * Copyright (C) 2023 Collabora Ltd.
+ * Authors: Mars.C <mars.cheng@mediatek.com>
+ * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
*/
#include <dt-bindings/interrupt-controller/irq.h>
@@ -19,6 +21,23 @@
#address-cells = <2>;
#size-cells = <2>;
+ aliases {
+ ovl0 = &ovl0;
+ ovl1 = &ovl1;
+ rdma0 = &rdma0;
+ rdma1 = &rdma1;
+ rdma2 = &rdma2;
+ wdma0 = &wdma0;
+ wdma1 = &wdma1;
+ color0 = &color0;
+ color1 = &color1;
+ split0 = &split0;
+ split1 = &split1;
+ dpi0 = &dpi0;
+ dsi0 = &dsi0;
+ dsi1 = &dsi1;
+ };
+
psci {
compatible = "arm,psci-0.2";
method = "smc";
@@ -434,6 +453,26 @@
#mbox-cells = <2>;
};
+ mipi_tx0: dsi-phy@10215000 {
+ compatible = "mediatek,mt8173-mipi-tx";
+ reg = <0 0x10215000 0 0x1000>;
+ clocks = <&clk26m>;
+ clock-output-names = "mipi_tx0_pll";
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ mipi_tx1: dsi-phy@10216000 {
+ compatible = "mediatek,mt8173-mipi-tx";
+ reg = <0 0x10216000 0 0x1000>;
+ clocks = <&clk26m>;
+ clock-output-names = "mipi_tx1_pll";
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@10221000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
@@ -690,6 +729,211 @@
mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
};
+ ovl0: ovl@1400c000 {
+ compatible = "mediatek,mt6795-disp-ovl", "mediatek,mt8173-disp-ovl";
+ reg = <0 0x1400c000 0 0x1000>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_OVL0>;
+ iommus = <&iommu M4U_PORT_DISP_OVL0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
+ };
+
+ ovl1: ovl@1400d000 {
+ compatible = "mediatek,mt6795-disp-ovl", "mediatek,mt8173-disp-ovl";
+ reg = <0 0x1400d000 0 0x1000>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_OVL1>;
+ iommus = <&iommu M4U_PORT_DISP_OVL1>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xd000 0x1000>;
+ };
+
+ rdma0: rdma@1400e000 {
+ compatible = "mediatek,mt6795-disp-rdma", "mediatek,mt8173-disp-rdma";
+ reg = <0 0x1400e000 0 0x1000>;
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_RDMA0>;
+ iommus = <&iommu M4U_PORT_DISP_RDMA0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
+ };
+
+ rdma1: rdma@1400f000 {
+ compatible = "mediatek,mt6795-disp-rdma", "mediatek,mt8173-disp-rdma";
+ reg = <0 0x1400f000 0 0x1000>;
+ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_RDMA1>;
+ iommus = <&iommu M4U_PORT_DISP_RDMA1>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+ };
+
+ rdma2: rdma@14010000 {
+ compatible = "mediatek,mt6795-disp-rdma", "mediatek,mt8173-disp-rdma";
+ reg = <0 0x14010000 0 0x1000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_RDMA2>;
+ iommus = <&iommu M4U_PORT_DISP_RDMA2>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0 0x1000>;
+ };
+
+ wdma0: wdma@14011000 {
+ compatible = "mediatek,mt6795-disp-wdma", "mediatek,mt8173-disp-wdma";
+ reg = <0 0x14011000 0 0x1000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+ iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+ };
+
+ wdma1: wdma@14012000 {
+ compatible = "mediatek,mt6795-disp-wdma", "mediatek,mt8173-disp-wdma";
+ reg = <0 0x14012000 0 0x1000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_WDMA1>;
+ iommus = <&iommu M4U_PORT_DISP_WDMA1>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
+ };
+
+ color0: color@14013000 {
+ compatible = "mediatek,mt6795-disp-color", "mediatek,mt8173-disp-color";
+ reg = <0 0x14013000 0 0x1000>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_COLOR0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
+ };
+
+ color1: color@14014000 {
+ compatible = "mediatek,mt6795-disp-color", "mediatek,mt8173-disp-color";
+ reg = <0 0x14014000 0 0x1000>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_COLOR1>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x4000 0x1000>;
+ };
+
+ aal@14015000 {
+ compatible = "mediatek,mt6795-disp-aal", "mediatek,mt8173-disp-aal";
+ reg = <0 0x14015000 0 0x1000>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_AAL>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
+ };
+
+ gamma@14016000 {
+ compatible = "mediatek,mt6795-disp-gamma", "mediatek,mt8173-disp-gamma";
+ reg = <0 0x14016000 0 0x1000>;
+ interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_GAMMA>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
+ };
+
+ merge@14017000 {
+ compatible = "mediatek,mt6795-disp-merge", "mediatek,mt8173-disp-merge";
+ reg = <0 0x14017000 0 0x1000>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_MERGE>;
+ };
+
+ split0: split@14018000 {
+ compatible = "mediatek,mt6795-disp-split", "mediatek,mt8173-disp-split";
+ reg = <0 0x14018000 0 0x1000>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_SPLIT0>;
+ };
+
+ split1: split@14019000 {
+ compatible = "mediatek,mt6795-disp-split", "mediatek,mt8173-disp-split";
+ reg = <0 0x14019000 0 0x1000>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_SPLIT1>;
+ };
+
+ ufoe@1401a000 {
+ compatible = "mediatek,mt6795-disp-ufoe", "mediatek,mt8173-disp-ufoe";
+ reg = <0 0x1401a000 0 0x1000>;
+ interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_UFOE>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xa000 0x1000>;
+ };
+
+ dsi0: dsi@1401b000 {
+ compatible = "mediatek,mt6795-dsi", "mediatek,mt8173-dsi";
+ reg = <0 0x1401b000 0 0x1000>;
+ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DSI0_ENGINE>,
+ <&mmsys CLK_MM_DSI0_DIGITAL>,
+ <&mipi_tx0>;
+ clock-names = "engine", "digital", "hs";
+ phys = <&mipi_tx0>;
+ phy-names = "dphy";
+ status = "disabled";
+ };
+
+ dsi1: dsi@1401c000 {
+ compatible = "mediatek,mt6795-dsi", "mediatek,mt8173-dsi";
+ reg = <0 0x1401c000 0 0x1000>;
+ interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DSI1_ENGINE>,
+ <&mmsys CLK_MM_DSI1_DIGITAL>,
+ <&mipi_tx1>;
+ clock-names = "engine", "digital", "hs";
+ phys = <&mipi_tx1>;
+ phy-names = "dphy";
+ status = "disabled";
+ };
+
+ dpi0: dpi@1401d000 {
+ compatible = "mediatek,mt6795-dpi", "mediatek,mt8183-dpi";
+ reg = <0 0x1401d000 0 0x1000>;
+ interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DPI_PIXEL>,
+ <&mmsys CLK_MM_DPI_ENGINE>,
+ <&apmixedsys CLK_APMIXED_TVDPLL>;
+ clock-names = "pixel", "engine", "pll";
+ status = "disabled";
+ };
+
+ pwm0: pwm@1401e000 {
+ compatible = "mediatek,mt6795-disp-pwm", "mediatek,mt8173-disp-pwm";
+ reg = <0 0x1401e000 0 0x1000>;
+ #pwm-cells = <2>;
+ clocks = <&mmsys CLK_MM_DISP_PWM026M>, <&mmsys CLK_MM_DISP_PWM0MM>;
+ clock-names = "main", "mm";
+ status = "disabled";
+ };
+
+ pwm1: pwm@1401f000 {
+ compatible = "mediatek,mt6795-disp-pwm", "mediatek,mt8173-disp-pwm";
+ reg = <0 0x1401f000 0 0x1000>;
+ #pwm-cells = <2>;
+ clocks = <&mmsys CLK_MM_DISP_PWM126M>, <&mmsys CLK_MM_DISP_PWM1MM>;
+ clock-names = "main", "mm";
+ status = "disabled";
+ };
+
+ mutex: mutex@14020000 {
+ compatible = "mediatek,mt8173-disp-mutex";
+ reg = <0 0x14020000 0 0x1000>;
+ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT6795_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_MUTEX_32K>;
+ mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
+ <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1402XXXX 0 0x1000>;
+ };
+
larb0: larb@14021000 {
compatible = "mediatek,mt6795-smi-larb";
reg = <0 0x14021000 0 0x1000>;
@@ -708,6 +952,13 @@
clock-names = "apb", "smi";
};
+ od@14023000 {
+ compatible = "mediatek,mt6795-disp-od", "mediatek,mt8173-disp-od";
+ reg = <0 0x14023000 0 0x1000>;
+ clocks = <&mmsys CLK_MM_DISP_OD>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1402XXXX 0x3000 0x1000>;
+ };
+
larb2: larb@15001000 {
compatible = "mediatek,mt6795-smi-larb";
reg = <0 0x15001000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
index 86cedb0bf1a9..3b7a176b7904 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -385,9 +385,9 @@
i2s1_pins: i2s1-pins {
mux {
function = "i2s";
- groups = "i2s_out_mclk_bclk_ws",
- "i2s1_in_data",
- "i2s1_out_data";
+ groups = "i2s_out_mclk_bclk_ws",
+ "i2s1_in_data",
+ "i2s1_out_data";
};
conf {
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index dad8e683aac5..a885a3fbe456 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -311,9 +311,9 @@
i2s1_pins: i2s1-pins {
mux {
function = "i2s";
- groups = "i2s_out_mclk_bclk_ws",
- "i2s1_in_data",
- "i2s1_out_data";
+ groups = "i2s_out_mclk_bclk_ws",
+ "i2s1_in_data",
+ "i2s1_out_data";
};
conf {
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
index d8bd51807683..ce336a48c897 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
@@ -155,8 +155,8 @@
};
&pio {
- i2c_pins_0: i2c0{
- pins_i2c{
+ i2c_pins_0: i2c0 {
+ pins_i2c {
pinmux = <PINMUX_GPIO82__FUNC_SDA0>,
<PINMUX_GPIO83__FUNC_SCL0>;
mediatek,pull-up-adv = <3>;
@@ -164,8 +164,8 @@
};
};
- i2c_pins_1: i2c1{
- pins_i2c{
+ i2c_pins_1: i2c1 {
+ pins_i2c {
pinmux = <PINMUX_GPIO81__FUNC_SDA1>,
<PINMUX_GPIO84__FUNC_SCL1>;
mediatek,pull-up-adv = <3>;
@@ -173,8 +173,8 @@
};
};
- i2c_pins_2: i2c2{
- pins_i2c{
+ i2c_pins_2: i2c2 {
+ pins_i2c {
pinmux = <PINMUX_GPIO103__FUNC_SCL2>,
<PINMUX_GPIO104__FUNC_SDA2>;
mediatek,pull-up-adv = <3>;
@@ -182,8 +182,8 @@
};
};
- i2c_pins_3: i2c3{
- pins_i2c{
+ i2c_pins_3: i2c3 {
+ pins_i2c {
pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
<PINMUX_GPIO51__FUNC_SDA3>;
mediatek,pull-up-adv = <3>;
@@ -191,8 +191,8 @@
};
};
- i2c_pins_4: i2c4{
- pins_i2c{
+ i2c_pins_4: i2c4 {
+ pins_i2c {
pinmux = <PINMUX_GPIO105__FUNC_SCL4>,
<PINMUX_GPIO106__FUNC_SDA4>;
mediatek,pull-up-adv = <3>;
@@ -200,8 +200,8 @@
};
};
- i2c_pins_5: i2c5{
- pins_i2c{
+ i2c_pins_5: i2c5 {
+ pins_i2c {
pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
<PINMUX_GPIO49__FUNC_SDA5>;
mediatek,pull-up-adv = <3>;
@@ -209,8 +209,8 @@
};
};
- spi_pins_0: spi0{
- pins_spi{
+ spi_pins_0: spi0 {
+ pins_spi {
pinmux = <PINMUX_GPIO85__FUNC_SPI0_MI>,
<PINMUX_GPIO86__FUNC_SPI0_CSB>,
<PINMUX_GPIO87__FUNC_SPI0_MO>,
@@ -324,8 +324,8 @@
};
};
- spi_pins_1: spi1{
- pins_spi{
+ spi_pins_1: spi1 {
+ pins_spi {
pinmux = <PINMUX_GPIO161__FUNC_SPI1_A_MI>,
<PINMUX_GPIO162__FUNC_SPI1_A_CSB>,
<PINMUX_GPIO163__FUNC_SPI1_A_MO>,
@@ -334,8 +334,8 @@
};
};
- spi_pins_2: spi2{
- pins_spi{
+ spi_pins_2: spi2 {
+ pins_spi {
pinmux = <PINMUX_GPIO0__FUNC_SPI2_CSB>,
<PINMUX_GPIO1__FUNC_SPI2_MO>,
<PINMUX_GPIO2__FUNC_SPI2_CLK>,
@@ -344,8 +344,8 @@
};
};
- spi_pins_3: spi3{
- pins_spi{
+ spi_pins_3: spi3 {
+ pins_spi {
pinmux = <PINMUX_GPIO21__FUNC_SPI3_MI>,
<PINMUX_GPIO22__FUNC_SPI3_CSB>,
<PINMUX_GPIO23__FUNC_SPI3_MO>,
@@ -354,8 +354,8 @@
};
};
- spi_pins_4: spi4{
- pins_spi{
+ spi_pins_4: spi4 {
+ pins_spi {
pinmux = <PINMUX_GPIO17__FUNC_SPI4_MI>,
<PINMUX_GPIO18__FUNC_SPI4_CSB>,
<PINMUX_GPIO19__FUNC_SPI4_MO>,
@@ -364,8 +364,8 @@
};
};
- spi_pins_5: spi5{
- pins_spi{
+ spi_pins_5: spi5 {
+ pins_spi {
pinmux = <PINMUX_GPIO13__FUNC_SPI5_MI>,
<PINMUX_GPIO14__FUNC_SPI5_CSB>,
<PINMUX_GPIO15__FUNC_SPI5_MO>,
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
index 6ce16a265e05..4a74f3b6d775 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -103,6 +103,14 @@
regulator-max-microvolt = <3300000>;
};
+ /* system wide semi-regulated power rail from charger */
+ reg_vsys: regulator-vsys {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
reserved_memory: reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
@@ -404,6 +412,26 @@
Avdd-supply = <&mt6358_vaud28_reg>;
};
+&mt6358regulator {
+ vsys-ldo1-supply = <&reg_vsys>;
+ vsys-ldo2-supply = <&reg_vsys>;
+ vsys-ldo3-supply = <&reg_vsys>;
+ vsys-vcore-supply = <&reg_vsys>;
+ vsys-vdram1-supply = <&reg_vsys>;
+ vsys-vgpu-supply = <&reg_vsys>;
+ vsys-vmodem-supply = <&reg_vsys>;
+ vsys-vpa-supply = <&reg_vsys>;
+ vsys-vproc11-supply = <&reg_vsys>;
+ vsys-vproc12-supply = <&reg_vsys>;
+ vsys-vs1-supply = <&reg_vsys>;
+ vsys-vs2-supply = <&reg_vsys>;
+ vs1-ldo1-supply = <&mt6358_vs1_reg>;
+ vs2-ldo1-supply = <&mt6358_vdram1_reg>;
+ vs2-ldo2-supply = <&mt6358_vs2_reg>;
+ vs2-ldo3-supply = <&mt6358_vs2_reg>;
+ vs2-ldo4-supply = <&mt6358_vs2_reg>;
+};
+
&mt6358_vgpu_reg {
regulator-min-microvolt = <625000>;
regulator-max-microvolt = <900000>;
@@ -692,7 +720,7 @@
};
spi0_pins: spi0 {
- pins_spi{
+ pins_spi {
pinmux = <PINMUX_GPIO85__FUNC_SPI0_MI>,
<PINMUX_GPIO86__FUNC_GPIO86>,
<PINMUX_GPIO87__FUNC_SPI0_MO>,
@@ -702,7 +730,7 @@
};
spi1_pins: spi1 {
- pins_spi{
+ pins_spi {
pinmux = <PINMUX_GPIO161__FUNC_SPI1_A_MI>,
<PINMUX_GPIO162__FUNC_SPI1_A_CSB>,
<PINMUX_GPIO163__FUNC_SPI1_A_MO>,
@@ -712,7 +740,7 @@
};
spi2_pins: spi2 {
- pins_spi{
+ pins_spi {
pinmux = <PINMUX_GPIO0__FUNC_SPI2_CSB>,
<PINMUX_GPIO1__FUNC_SPI2_MO>,
<PINMUX_GPIO2__FUNC_SPI2_CLK>;
@@ -725,7 +753,7 @@
};
spi3_pins: spi3 {
- pins_spi{
+ pins_spi {
pinmux = <PINMUX_GPIO21__FUNC_SPI3_MI>,
<PINMUX_GPIO22__FUNC_SPI3_CSB>,
<PINMUX_GPIO23__FUNC_SPI3_MO>,
@@ -735,7 +763,7 @@
};
spi4_pins: spi4 {
- pins_spi{
+ pins_spi {
pinmux = <PINMUX_GPIO17__FUNC_SPI4_MI>,
<PINMUX_GPIO18__FUNC_SPI4_CSB>,
<PINMUX_GPIO19__FUNC_SPI4_MO>,
@@ -745,7 +773,7 @@
};
spi5_pins: spi5 {
- pins_spi{
+ pins_spi {
pinmux = <PINMUX_GPIO13__FUNC_SPI5_MI>,
<PINMUX_GPIO14__FUNC_SPI5_CSB>,
<PINMUX_GPIO15__FUNC_SPI5_MO>,
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
index 526bcae7a3f8..b5784a60c315 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
@@ -193,7 +193,7 @@
&pio {
i2c_pins_0: i2c0 {
- pins_i2c{
+ pins_i2c {
pinmux = <PINMUX_GPIO82__FUNC_SDA0>,
<PINMUX_GPIO83__FUNC_SCL0>;
mediatek,pull-up-adv = <3>;
@@ -202,7 +202,7 @@
};
i2c_pins_1: i2c1 {
- pins_i2c{
+ pins_i2c {
pinmux = <PINMUX_GPIO81__FUNC_SDA1>,
<PINMUX_GPIO84__FUNC_SCL1>;
mediatek,pull-up-adv = <3>;
@@ -211,7 +211,7 @@
};
i2c_pins_2: i2c2 {
- pins_i2c{
+ pins_i2c {
pinmux = <PINMUX_GPIO103__FUNC_SCL2>,
<PINMUX_GPIO104__FUNC_SDA2>;
mediatek,pull-up-adv = <3>;
@@ -220,7 +220,7 @@
};
i2c_pins_3: i2c3 {
- pins_i2c{
+ pins_i2c {
pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
<PINMUX_GPIO51__FUNC_SDA3>;
mediatek,pull-up-adv = <3>;
@@ -229,7 +229,7 @@
};
i2c_pins_4: i2c4 {
- pins_i2c{
+ pins_i2c {
pinmux = <PINMUX_GPIO105__FUNC_SCL4>,
<PINMUX_GPIO106__FUNC_SDA4>;
mediatek,pull-up-adv = <3>;
@@ -238,7 +238,7 @@
};
i2c_pins_5: i2c5 {
- pins_i2c{
+ pins_i2c {
pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
<PINMUX_GPIO49__FUNC_SDA5>;
mediatek,pull-up-adv = <3>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt1015p-rt5682.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt1015p-rt5682.dtsi
deleted file mode 100644
index f521f50d448f..000000000000
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt1015p-rt5682.dtsi
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright 2020 Google LLC
- */
-
-#include "mt8192-asurada-audio-rt5682.dtsi"
-#include "mt8192-asurada-audio-rt1015p.dtsi"
-
-&sound {
- compatible = "mediatek,mt8192_mt6359_rt1015p_rt5682";
-
- speaker-codecs {
- sound-dai = <&rt1015p>;
- };
-
- headset-codec {
- sound-dai = <&rt5682 0>;
- };
-};
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt1015p.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt1015p.dtsi
deleted file mode 100644
index e5743789934e..000000000000
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt1015p.dtsi
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- */
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/pinctrl/mt8192-pinfunc.h>
-
-/ {
- rt1015p: audio-codec {
- compatible = "realtek,rt1015p";
- pinctrl-names = "default";
- pinctrl-0 = <&rt1015p_pins>;
- sdb-gpios = <&pio 147 GPIO_ACTIVE_HIGH>;
- #sound-dai-cells = <0>;
- };
-};
-
-&pio {
- rt1015p_pins: rt1015p-default-pins {
- pins {
- pinmux = <PINMUX_GPIO147__FUNC_GPIO147>;
- output-low;
- };
- };
-};
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt5682.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt5682.dtsi
deleted file mode 100644
index 05e48b870a92..000000000000
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada-audio-rt5682.dtsi
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- */
-
-&i2c1 {
- rt5682: audio-codec@1a {
- compatible = "realtek,rt5682i";
- reg = <0x1a>;
- interrupts-extended = <&pio 18 IRQ_TYPE_LEVEL_LOW>;
- realtek,jd-src = <1>;
- realtek,btndet-delay = <16>;
- #sound-dai-cells = <1>;
-
- AVDD-supply = <&mt6359_vio18_ldo_reg>;
- DBVDD-supply = <&mt6359_vio18_ldo_reg>;
- LDO1-IN-supply = <&mt6359_vio18_ldo_reg>;
- MICVDD-supply = <&pp3300_g>;
- VBAT-supply = <&pp3300_ldo_z>;
- };
-};
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts b/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts
index 6e23428a3ed2..fd2cb8765a15 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dts
@@ -4,7 +4,6 @@
*/
/dts-v1/;
#include "mt8192-asurada.dtsi"
-#include "mt8192-asurada-audio-rt1015p-rt5682.dtsi"
/ {
model = "Google Hayato rev1";
@@ -101,6 +100,24 @@
};
};
+&rt5682 {
+ compatible = "realtek,rt5682i";
+ realtek,btndet-delay = <16>;
+ VBAT-supply = <&pp3300_ldo_z>;
+};
+
+&sound {
+ compatible = "mediatek,mt8192_mt6359_rt1015p_rt5682";
+
+ speaker-codecs {
+ sound-dai = <&rt1015p>;
+ };
+
+ headset-codec {
+ sound-dai = <&rt5682 0>;
+ };
+};
+
&touchscreen {
compatible = "hid-over-i2c";
post-power-on-delay-ms = <10>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r5-sku2.dts b/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r5-sku2.dts
new file mode 100644
index 000000000000..3127ee5f6172
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r5-sku2.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+/dts-v1/;
+#include "mt8192-asurada.dtsi"
+
+/ {
+ model = "Google Hayato rev5";
+ compatible = "google,hayato-rev5-sku2", "google,hayato-sku2",
+ "google,hayato", "mediatek,mt8192";
+};
+
+&keyboard_controller {
+ function-row-physmap = <
+ MATRIX_KEY(0x00, 0x02, 0) /* T1 */
+ MATRIX_KEY(0x03, 0x02, 0) /* T2 */
+ MATRIX_KEY(0x02, 0x02, 0) /* T3 */
+ MATRIX_KEY(0x01, 0x02, 0) /* T4 */
+ MATRIX_KEY(0x03, 0x04, 0) /* T5 */
+ MATRIX_KEY(0x02, 0x04, 0) /* T6 */
+ MATRIX_KEY(0x01, 0x04, 0) /* T7 */
+ MATRIX_KEY(0x02, 0x09, 0) /* T8 */
+ MATRIX_KEY(0x01, 0x09, 0) /* T9 */
+ MATRIX_KEY(0x00, 0x04, 0) /* T10 */
+ >;
+ linux,keymap = <
+ MATRIX_KEY(0x00, 0x02, KEY_BACK)
+ MATRIX_KEY(0x03, 0x02, KEY_FORWARD)
+ MATRIX_KEY(0x02, 0x02, KEY_REFRESH)
+ MATRIX_KEY(0x01, 0x02, KEY_FULL_SCREEN)
+ MATRIX_KEY(0x03, 0x04, KEY_SCALE)
+ MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN)
+ MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP)
+ MATRIX_KEY(0x02, 0x09, KEY_MUTE)
+ MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP)
+
+ CROS_STD_MAIN_KEYMAP
+ >;
+};
+
+&rt5682 {
+ compatible = "realtek,rt5682s";
+};
+
+&sound {
+ compatible = "mediatek,mt8192_mt6359_rt1015p_rt5682s";
+
+ speaker-codecs {
+ sound-dai = <&rt1015p>;
+ };
+
+ headset-codec {
+ sound-dai = <&rt5682 0>;
+ };
+};
+
+&touchscreen {
+ compatible = "hid-over-i2c";
+ post-power-on-delay-ms = <10>;
+ hid-descr-addr = <0x0001>;
+ vdd-supply = <&pp3300_u>;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts b/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts
index c6ad10cec95e..bc88866ab2f5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dts
@@ -4,7 +4,6 @@
*/
/dts-v1/;
#include "mt8192-asurada.dtsi"
-#include "mt8192-asurada-audio-rt1015p-rt5682.dtsi"
#include <dt-bindings/leds/common.h>
/ {
@@ -58,6 +57,24 @@
>;
};
+&rt5682 {
+ compatible = "realtek,rt5682i";
+ realtek,btndet-delay = <16>;
+ VBAT-supply = <&pp3300_ldo_z>;
+};
+
+&sound {
+ compatible = "mediatek,mt8192_mt6359_rt1015p_rt5682";
+
+ speaker-codecs {
+ sound-dai = <&rt1015p>;
+ };
+
+ headset-codec {
+ sound-dai = <&rt5682 0>;
+ };
+};
+
&touchscreen {
compatible = "elan,ekth3500";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r4.dts b/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r4.dts
new file mode 100644
index 000000000000..0039158c9e60
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r4.dts
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+/dts-v1/;
+#include "mt8192-asurada.dtsi"
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Google Spherion (rev4)";
+ compatible = "google,spherion-rev4", "google,spherion",
+ "mediatek,mt8192";
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ led {
+ function = LED_FUNCTION_KBD_BACKLIGHT;
+ color = <LED_COLOR_ID_WHITE>;
+ pwms = <&cros_ec_pwm 0>;
+ max-brightness = <1023>;
+ };
+ };
+};
+
+&cros_ec_pwm {
+ status = "okay";
+};
+
+&keyboard_controller {
+ function-row-physmap = <
+ MATRIX_KEY(0x00, 0x02, 0) /* T1 */
+ MATRIX_KEY(0x03, 0x02, 0) /* T2 */
+ MATRIX_KEY(0x02, 0x02, 0) /* T3 */
+ MATRIX_KEY(0x01, 0x02, 0) /* T4 */
+ MATRIX_KEY(0x03, 0x04, 0) /* T5 */
+ MATRIX_KEY(0x02, 0x04, 0) /* T6 */
+ MATRIX_KEY(0x01, 0x04, 0) /* T7 */
+ MATRIX_KEY(0x02, 0x09, 0) /* T8 */
+ MATRIX_KEY(0x01, 0x09, 0) /* T9 */
+ MATRIX_KEY(0x00, 0x04, 0) /* T10 */
+ >;
+ linux,keymap = <
+ MATRIX_KEY(0x00, 0x02, KEY_BACK)
+ MATRIX_KEY(0x03, 0x02, KEY_REFRESH)
+ MATRIX_KEY(0x02, 0x02, KEY_FULL_SCREEN)
+ MATRIX_KEY(0x01, 0x02, KEY_SCALE)
+ MATRIX_KEY(0x03, 0x04, KEY_SYSRQ)
+ MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN)
+ MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP)
+ MATRIX_KEY(0x02, 0x09, KEY_MUTE)
+ MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP)
+
+ CROS_STD_MAIN_KEYMAP
+ >;
+};
+
+&rt5682 {
+ compatible = "realtek,rt5682s";
+};
+
+&sound {
+ compatible = "mediatek,mt8192_mt6359_rt1015p_rt5682s";
+
+ speaker-codecs {
+ sound-dai = <&rt1015p>;
+ };
+
+ headset-codec {
+ sound-dai = <&rt5682 0>;
+ };
+};
+
+&touchscreen {
+ compatible = "elan,ekth3500";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index 0e8b34117090..1447eed0ea36 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -210,6 +210,14 @@
};
};
+ rt1015p: audio-codec {
+ compatible = "realtek,rt1015p";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rt1015p_pins>;
+ sdb-gpios = <&pio 147 GPIO_ACTIVE_HIGH>;
+ #sound-dai-cells = <0>;
+ };
+
sound: sound {
mediatek,platform = <&afe>;
pinctrl-names = "aud_clk_mosi_off",
@@ -305,6 +313,19 @@
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
+
+ rt5682: audio-codec@1a {
+ /* Realtek RT5682i or RT5682s, sharing the same configuration */
+ reg = <0x1a>;
+ interrupts-extended = <&pio 18 IRQ_TYPE_LEVEL_LOW>;
+ realtek,jd-src = <1>;
+ #sound-dai-cells = <1>;
+
+ AVDD-supply = <&mt6359_vio18_ldo_reg>;
+ DBVDD-supply = <&mt6359_vio18_ldo_reg>;
+ LDO1-IN-supply = <&mt6359_vio18_ldo_reg>;
+ MICVDD-supply = <&pp3300_g>;
+ };
};
&i2c2 {
@@ -1184,6 +1205,13 @@
};
};
+ rt1015p_pins: rt1015p-default-pins {
+ pins {
+ pinmux = <PINMUX_GPIO147__FUNC_GPIO147>;
+ output-low;
+ };
+ };
+
scp_pins: scp-pins {
pins-vreq-vao {
pinmux = <PINMUX_GPIO195__FUNC_SCP_VREQ_VAO>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index 37a3e9de90ff..dd5b89b73190 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -47,6 +47,19 @@
reg = <0 0x40000000 0 0x80000000>;
};
+ pp3300_disp_x: regulator-pp3300-disp-x {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_disp_x";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <2500>;
+ enable-active-high;
+ gpio = <&pio 55 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&panel_fixed_pins>;
+ vin-supply = <&pp3300_z2>;
+ };
+
/* system wide LDO 3.3V power rail */
pp3300_z5: regulator-pp3300-ldo-z5 {
compatible = "regulator-fixed";
@@ -217,6 +230,20 @@
reg = <1>;
edp_out: endpoint {
data-lanes = <0 1 2 3>;
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+
+ aux-bus {
+ panel {
+ compatible = "edp-panel";
+ power-supply = <&pp3300_disp_x>;
+ backlight = <&backlight_lcd0>;
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&edp_out>;
+ };
};
};
};
@@ -881,6 +908,12 @@
};
};
+ panel_fixed_pins: panel-pwr-default-pins {
+ pins-vreg-en {
+ pinmux = <PINMUX_GPIO55__FUNC_GPIO55>;
+ };
+ };
+
pio_default: pio-default-pins {
pins-wifi-enable {
pinmux = <PINMUX_GPIO58__FUNC_GPIO58>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
index 5d635085fe3f..69c7f3954ae5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
@@ -102,7 +102,7 @@
};
&eth {
- phy-mode ="rgmii-id";
+ phy-mode = "rgmii-id";
phy-handle = <&ethernet_phy0>;
snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>;
snps,reset-delays-us = <0 10000 80000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8365.dtsi b/arch/arm64/boot/dts/mediatek/mt8365.dtsi
index 413496c92069..24581f7410aa 100644
--- a/arch/arm64/boot/dts/mediatek/mt8365.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8365.dtsi
@@ -9,6 +9,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/power/mediatek,mt8365-power.h>
/ {
compatible = "mediatek,mt8365";
@@ -298,6 +299,119 @@
reg = <0 0x10005000 0 0x1000>;
};
+ scpsys: syscon@10006000 {
+ compatible = "mediatek,mt8365-syscfg", "syscon", "simple-mfd";
+ reg = <0 0x10006000 0 0x1000>;
+ #power-domain-cells = <1>;
+
+ /* System Power Manager */
+ spm: power-controller {
+ compatible = "mediatek,mt8365-power-controller";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ /* power domains of the SoC */
+ power-domain@MT8365_POWER_DOMAIN_MM {
+ reg = <MT8365_POWER_DOMAIN_MM>;
+ clocks = <&topckgen CLK_TOP_MM_SEL>,
+ <&mmsys CLK_MM_MM_SMI_COMMON>,
+ <&mmsys CLK_MM_MM_SMI_COMM0>,
+ <&mmsys CLK_MM_MM_SMI_COMM1>,
+ <&mmsys CLK_MM_MM_SMI_LARB0>;
+ clock-names = "mm", "mm-0", "mm-1",
+ "mm-2", "mm-3";
+ #power-domain-cells = <0>;
+ mediatek,infracfg = <&infracfg>;
+ mediatek,infracfg-nao = <&infracfg_nao>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ power-domain@MT8365_POWER_DOMAIN_CAM {
+ reg = <MT8365_POWER_DOMAIN_CAM>;
+ clocks = <&camsys CLK_CAM_LARB2>,
+ <&camsys CLK_CAM_SENIF>,
+ <&camsys CLK_CAMSV0>,
+ <&camsys CLK_CAMSV1>,
+ <&camsys CLK_CAM_FDVT>,
+ <&camsys CLK_CAM_WPE>;
+ clock-names = "cam-0", "cam-1",
+ "cam-2", "cam-3",
+ "cam-4", "cam-5";
+ #power-domain-cells = <0>;
+ mediatek,infracfg = <&infracfg>;
+ mediatek,smi = <&smi_common>;
+ };
+
+ power-domain@MT8365_POWER_DOMAIN_VDEC {
+ reg = <MT8365_POWER_DOMAIN_VDEC>;
+ #power-domain-cells = <0>;
+ mediatek,smi = <&smi_common>;
+ };
+
+ power-domain@MT8365_POWER_DOMAIN_VENC {
+ reg = <MT8365_POWER_DOMAIN_VENC>;
+ #power-domain-cells = <0>;
+ mediatek,smi = <&smi_common>;
+ };
+
+ power-domain@MT8365_POWER_DOMAIN_APU {
+ reg = <MT8365_POWER_DOMAIN_APU>;
+ clocks = <&infracfg CLK_IFR_APU_AXI>,
+ <&apu CLK_APU_IPU_CK>,
+ <&apu CLK_APU_AXI>,
+ <&apu CLK_APU_JTAG>,
+ <&apu CLK_APU_IF_CK>,
+ <&apu CLK_APU_EDMA>,
+ <&apu CLK_APU_AHB>;
+ clock-names = "apu", "apu-0",
+ "apu-1", "apu-2",
+ "apu-3", "apu-4",
+ "apu-5";
+ #power-domain-cells = <0>;
+ mediatek,infracfg = <&infracfg>;
+ mediatek,smi = <&smi_common>;
+ };
+ };
+
+ power-domain@MT8365_POWER_DOMAIN_CONN {
+ reg = <MT8365_POWER_DOMAIN_CONN>;
+ clocks = <&topckgen CLK_TOP_CONN_32K>,
+ <&topckgen CLK_TOP_CONN_26M>;
+ clock-names = "conn", "conn1";
+ #power-domain-cells = <0>;
+ mediatek,infracfg = <&infracfg>;
+ };
+
+ power-domain@MT8365_POWER_DOMAIN_MFG {
+ reg = <MT8365_POWER_DOMAIN_MFG>;
+ clocks = <&topckgen CLK_TOP_MFG_SEL>;
+ clock-names = "mfg";
+ #power-domain-cells = <0>;
+ mediatek,infracfg = <&infracfg>;
+ };
+
+ power-domain@MT8365_POWER_DOMAIN_AUDIO {
+ reg = <MT8365_POWER_DOMAIN_AUDIO>;
+ clocks = <&topckgen CLK_TOP_AUD_INTBUS_SEL>,
+ <&infracfg CLK_IFR_AUDIO>,
+ <&infracfg CLK_IFR_AUD_26M_BK>;
+ clock-names = "audio", "audio1", "audio2";
+ #power-domain-cells = <0>;
+ mediatek,infracfg = <&infracfg>;
+ };
+
+ power-domain@MT8365_POWER_DOMAIN_DSP {
+ reg = <MT8365_POWER_DOMAIN_DSP>;
+ clocks = <&topckgen CLK_TOP_DSP_SEL>,
+ <&topckgen CLK_TOP_DSP_26M>;
+ clock-names = "dsp", "dsp1";
+ #power-domain-cells = <0>;
+ mediatek,infracfg = <&infracfg>;
+ };
+ };
+ };
+
watchdog: watchdog@10007000 {
compatible = "mediatek,mt8365-wdt", "mediatek,mt6589-wdt";
reg = <0 0x10007000 0 0x100>;
@@ -357,6 +471,14 @@
reg = <0 0x10200a80 0 0x20>;
};
+ iommu: iommu@10205000 {
+ compatible = "mediatek,mt8365-m4u";
+ reg = <0 0x10205000 0 0x1000>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_LOW>;
+ mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>;
+ #iommu-cells = <1>;
+ };
+
infracfg_nao: infracfg@1020e000 {
compatible = "mediatek,mt8365-infracfg", "syscon";
reg = <0 0x1020e000 0 0x1000>;
@@ -603,6 +725,94 @@
#phy-cells = <1>;
};
};
+
+ mmsys: syscon@14000000 {
+ compatible = "mediatek,mt8365-mmsys", "syscon";
+ reg = <0 0x14000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ smi_common: smi@14002000 {
+ compatible = "mediatek,mt8365-smi-common";
+ reg = <0 0x14002000 0 0x1000>;
+ clocks = <&mmsys CLK_MM_MM_SMI_COMMON>,
+ <&mmsys CLK_MM_MM_SMI_COMMON>,
+ <&mmsys CLK_MM_MM_SMI_COMM0>,
+ <&mmsys CLK_MM_MM_SMI_COMM1>;
+ clock-names = "apb", "smi", "gals0", "gals1";
+ power-domains = <&spm MT8365_POWER_DOMAIN_MM>;
+ };
+
+ larb0: larb@14003000 {
+ compatible = "mediatek,mt8365-smi-larb",
+ "mediatek,mt8186-smi-larb";
+ reg = <0 0x14003000 0 0x1000>;
+ mediatek,smi = <&smi_common>;
+ clocks = <&mmsys CLK_MM_MM_SMI_LARB0>,
+ <&mmsys CLK_MM_MM_SMI_LARB0>;
+ clock-names = "apb", "smi";
+ power-domains = <&spm MT8365_POWER_DOMAIN_MM>;
+ mediatek,larb-id = <0>;
+ };
+
+ camsys: syscon@15000000 {
+ compatible = "mediatek,mt8365-imgsys", "syscon";
+ reg = <0 0x15000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ larb2: larb@15001000 {
+ compatible = "mediatek,mt8365-smi-larb",
+ "mediatek,mt8186-smi-larb";
+ reg = <0 0x15001000 0 0x1000>;
+ mediatek,smi = <&smi_common>;
+ clocks = <&mmsys CLK_MM_MM_SMI_IMG>,
+ <&camsys CLK_CAM_LARB2>;
+ clock-names = "apb", "smi";
+ power-domains = <&spm MT8365_POWER_DOMAIN_CAM>;
+ mediatek,larb-id = <2>;
+ };
+
+ vdecsys: syscon@16000000 {
+ compatible = "mediatek,mt8365-vdecsys", "syscon";
+ reg = <0 0x16000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ larb3: larb@16010000 {
+ compatible = "mediatek,mt8365-smi-larb",
+ "mediatek,mt8186-smi-larb";
+ reg = <0 0x16010000 0 0x1000>;
+ mediatek,smi = <&smi_common>;
+ clocks = <&vdecsys CLK_VDEC_LARB1>,
+ <&vdecsys CLK_VDEC_LARB1>;
+ clock-names = "apb", "smi";
+ power-domains = <&spm MT8365_POWER_DOMAIN_VDEC>;
+ mediatek,larb-id = <3>;
+ };
+
+ vencsys: syscon@17000000 {
+ compatible = "mediatek,mt8365-vencsys", "syscon";
+ reg = <0 0x17000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ larb1: larb@17010000 {
+ compatible = "mediatek,mt8365-smi-larb",
+ "mediatek,mt8186-smi-larb";
+ reg = <0 0x17010000 0 0x1000>;
+ mediatek,smi = <&smi_common>;
+ clocks = <&vencsys CLK_VENC>, <&vencsys CLK_VENC>;
+ clock-names = "apb", "smi";
+ power-domains = <&spm MT8365_POWER_DOMAIN_VENC>;
+ mediatek,larb-id = <1>;
+ };
+
+ apu: syscon@19020000 {
+ compatible = "mediatek,mt8365-apu", "syscon";
+ reg = <0 0x19020000 0 0x1000>;
+ #clock-cells = <1>;
+ };
};
timer {
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
new file mode 100644
index 000000000000..70b465f7c6a7
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
@@ -0,0 +1,901 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ * Author: Ben Lok <ben.lok@mediatek.com>
+ * Macpaul Lin <macpaul.lin@mediatek.com>
+ */
+/dts-v1/;
+
+#include "mt8195.dtsi"
+#include "mt6359.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/usb/pd.h>
+
+/ {
+ model = "MediaTek Genio 1200 EVK-P1V2-EMMC";
+ compatible = "mediatek,mt8395-evk", "mediatek,mt8395",
+ "mediatek,mt8195";
+
+ aliases {
+ serial0 = &uart0;
+ ethernet0 = &eth;
+ };
+
+ chosen {
+ stdout-path = "serial0:921600n8";
+ };
+
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0x2 0x00000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /*
+ * 12 MiB reserved for OP-TEE (BL32)
+ * +-----------------------+ 0x43e0_0000
+ * | SHMEM 2MiB |
+ * +-----------------------+ 0x43c0_0000
+ * | | TA_RAM 8MiB |
+ * + TZDRAM +--------------+ 0x4340_0000
+ * | | TEE_RAM 2MiB |
+ * +-----------------------+ 0x4320_0000
+ */
+ optee_reserved: optee@43200000 {
+ no-map;
+ reg = <0 0x43200000 0 0x00c00000>;
+ };
+
+ scp_mem: memory@50000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x50000000 0 0x2900000>;
+ no-map;
+ };
+
+ vpu_mem: memory@53000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x53000000 0 0x1400000>; /* 20 MB */
+ };
+
+ /* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+ bl31_secmon_mem: memory@54600000 {
+ no-map;
+ reg = <0 0x54600000 0x0 0x200000>;
+ };
+
+ snd_dma_mem: memory@60000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x60000000 0 0x1100000>;
+ no-map;
+ };
+
+ apu_mem: memory@62000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x62000000 0 0x1400000>; /* 20 MB */
+ };
+ };
+
+ backlight_lcd0: backlight-lcd0 {
+ compatible = "pwm-backlight";
+ pwms = <&disp_pwm0 0 500000>;
+ enable-gpios = <&pio 47 GPIO_ACTIVE_HIGH>;
+ brightness-levels = <0 1023>;
+ num-interpolated-steps = <1023>;
+ default-brightness-level = <576>;
+ };
+
+ backlight_lcd1: backlight-lcd1 {
+ compatible = "pwm-backlight";
+ pwms = <&disp_pwm1 0 500000>;
+ enable-gpios = <&pio 46 GPIO_ACTIVE_HIGH>;
+ brightness-levels = <0 1023>;
+ num-interpolated-steps = <1023>;
+ default-brightness-level = <576>;
+ };
+
+ can_clk: can-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <20000000>;
+ clock-output-names = "can-clk";
+ };
+
+ edp_panel_fixed_3v3: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "edp_panel_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&edp_panel_3v3_en_pins>;
+ };
+
+ edp_panel_fixed_12v: regulator-1 {
+ compatible = "regulator-fixed";
+ regulator-name = "edp_backlight_12v";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ enable-active-high;
+ gpio = <&pio 96 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&edp_panel_12v_en_pins>;
+ };
+
+ keys: gpio-keys {
+ compatible = "gpio-keys";
+
+ button-volume-up {
+ wakeup-source;
+ debounce-interval = <100>;
+ gpios = <&pio 106 GPIO_ACTIVE_LOW>;
+ label = "volume_up";
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
+ wifi_fixed_3v3: regulator-2 {
+ compatible = "regulator-fixed";
+ regulator-name = "wifi_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 135 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+};
+
+&disp_pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_default_pins>;
+ status = "okay";
+};
+
+&dmic_codec {
+ wakeup-delay-ms = <200>;
+};
+
+&eth {
+ phy-mode ="rgmii-rxid";
+ phy-handle = <&eth_phy0>;
+ snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>;
+ snps,reset-delays-us = <0 10000 10000>;
+ mediatek,tx-delay-ps = <2030>;
+ mediatek,mac-wol;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&eth_default_pins>;
+ pinctrl-1 = <&eth_sleep_pins>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ eth_phy0: eth-phy0@1 {
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0x1>;
+ };
+ };
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ touchscreen@5d {
+ compatible = "goodix,gt9271";
+ reg = <0x5d>;
+ interrupt-parent = <&pio>;
+ interrupts = <132 IRQ_TYPE_EDGE_RISING>;
+ irq-gpios = <&pio 132 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&pio 133 GPIO_ACTIVE_HIGH>;
+ AVDD28-supply = <&mt6360_ldo1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touch_pins>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2c6 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c6_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ mt6360: pmic@34 {
+ compatible = "mediatek,mt6360";
+ reg = <0x34>;
+ interrupts = <128 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-names = "IRQB";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ pinctrl-0 = <&mt6360_pins>;
+
+ charger {
+ compatible = "mediatek,mt6360-chg";
+ richtek,vinovp-microvolt = <14500000>;
+
+ otg_vbus_regulator: usb-otg-vbus-regulator {
+ regulator-name = "usb-otg-vbus";
+ regulator-min-microvolt = <4425000>;
+ regulator-max-microvolt = <5825000>;
+ };
+ };
+
+ regulator {
+ compatible = "mediatek,mt6360-regulator";
+ LDO_VIN3-supply = <&mt6360_buck2>;
+
+ mt6360_buck1: buck1 {
+ regulator-name = "emi_vdd2";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP
+ MT6360_OPMODE_ULP>;
+ regulator-always-on;
+ };
+
+ mt6360_buck2: buck2 {
+ regulator-name = "emi_vddq";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP
+ MT6360_OPMODE_ULP>;
+ regulator-always-on;
+ };
+
+ mt6360_ldo1: ldo1 {
+ regulator-name = "tp1_p3v0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ regulator-always-on;
+ };
+
+ mt6360_ldo2: ldo2 {
+ regulator-name = "panel1_p1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ };
+
+ mt6360_ldo3: ldo3 {
+ regulator-name = "vmc_pmu";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ };
+
+ mt6360_ldo5: ldo5 {
+ regulator-name = "vmch_pmu";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ };
+
+ /* This is a measure point, which name is mt6360_ldo1 on schematic */
+ mt6360_ldo6: ldo6 {
+ regulator-name = "mt6360_ldo1";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2100000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ };
+
+ mt6360_ldo7: ldo7 {
+ regulator-name = "emi_vmddr_en";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2100000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&mfg0 {
+ domain-supply = <&mt6315_7_vbuck1>;
+};
+
+&mmc0 {
+ status = "okay";
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc0_default_pins>;
+ pinctrl-1 = <&mmc0_uhs_pins>;
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ cap-mmc-highspeed;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ cap-mmc-hw-reset;
+ no-sdio;
+ no-sd;
+ hs400-ds-delay = <0x14c11>;
+ vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
+ vqmmc-supply = <&mt6359_vufs_ldo_reg>;
+ non-removable;
+};
+
+&mmc1 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc1_default_pins>;
+ pinctrl-1 = <&mmc1_uhs_pins>;
+ bus-width = <4>;
+ max-frequency = <200000000>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ no-mmc;
+ no-sdio;
+ vmmc-supply = <&mt6360_ldo5>;
+ vqmmc-supply = <&mt6360_ldo3>;
+ status = "okay";
+ non-removable;
+};
+
+&mt6359_vaud18_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vbbck_ldo_reg {
+ regulator-always-on;
+};
+
+/* For USB Hub */
+&mt6359_vcamio_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vcn33_2_bt_ldo_reg {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+};
+
+&mt6359_vcore_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vgpu11_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vpu_buck_reg {
+ regulator-always-on;
+};
+
+&mt6359_vrf12_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359codec {
+ mediatek,mic-type-0 = <1>; /* ACC */
+ mediatek,mic-type-1 = <3>; /* DCC */
+ mediatek,mic-type-2 = <1>; /* ACC */
+};
+
+&pcie0 {
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&pcie0_default_pins>;
+ pinctrl-1 = <&pcie0_idle_pins>;
+ status = "okay";
+};
+
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_default_pins>;
+ status = "disabled";
+};
+
+&pciephy {
+ status = "okay";
+};
+
+&pio {
+ audio_default_pins: audio-default-pins {
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO61__FUNC_DMIC1_CLK>,
+ <PINMUX_GPIO62__FUNC_DMIC1_DAT>,
+ <PINMUX_GPIO65__FUNC_PCM_DO>,
+ <PINMUX_GPIO66__FUNC_PCM_CLK>,
+ <PINMUX_GPIO67__FUNC_PCM_DI>,
+ <PINMUX_GPIO68__FUNC_PCM_SYNC>,
+ <PINMUX_GPIO69__FUNC_AUD_CLK_MOSI>,
+ <PINMUX_GPIO70__FUNC_AUD_SYNC_MOSI>,
+ <PINMUX_GPIO71__FUNC_AUD_DAT_MOSI0>,
+ <PINMUX_GPIO72__FUNC_AUD_DAT_MOSI1>,
+ <PINMUX_GPIO73__FUNC_AUD_DAT_MISO0>,
+ <PINMUX_GPIO74__FUNC_AUD_DAT_MISO1>,
+ <PINMUX_GPIO75__FUNC_AUD_DAT_MISO2>;
+ };
+ };
+
+ disp_pwm1_default_pins: disp-pwm1-default-pins {
+ pins1 {
+ pinmux = <PINMUX_GPIO104__FUNC_DISP_PWM1>;
+ };
+ };
+
+ edp_panel_12v_en_pins: edp-panel-12v-en-pins {
+ pins1 {
+ pinmux = <PINMUX_GPIO96__FUNC_GPIO96>;
+ output-high;
+ };
+ };
+
+ edp_panel_3v3_en_pins: edp-panel-3v3-en-pins {
+ pins1 {
+ pinmux = <PINMUX_GPIO6__FUNC_GPIO6>;
+ output-high;
+ };
+ };
+
+ eth_default_pins: eth-default-pins {
+ pins-cc {
+ pinmux = <PINMUX_GPIO85__FUNC_GBE_TXC>,
+ <PINMUX_GPIO86__FUNC_GBE_RXC>,
+ <PINMUX_GPIO87__FUNC_GBE_RXDV>,
+ <PINMUX_GPIO88__FUNC_GBE_TXEN>;
+ drive-strength = <MTK_DRIVE_8mA>;
+ };
+
+ pins-mdio {
+ pinmux = <PINMUX_GPIO89__FUNC_GBE_MDC>,
+ <PINMUX_GPIO90__FUNC_GBE_MDIO>;
+ input-enable;
+ };
+
+ pins-power {
+ pinmux = <PINMUX_GPIO91__FUNC_GPIO91>,
+ <PINMUX_GPIO92__FUNC_GPIO92>;
+ output-high;
+ };
+
+ pins-rxd {
+ pinmux = <PINMUX_GPIO81__FUNC_GBE_RXD3>,
+ <PINMUX_GPIO82__FUNC_GBE_RXD2>,
+ <PINMUX_GPIO83__FUNC_GBE_RXD1>,
+ <PINMUX_GPIO84__FUNC_GBE_RXD0>;
+ };
+
+ pins-txd {
+ pinmux = <PINMUX_GPIO77__FUNC_GBE_TXD3>,
+ <PINMUX_GPIO78__FUNC_GBE_TXD2>,
+ <PINMUX_GPIO79__FUNC_GBE_TXD1>,
+ <PINMUX_GPIO80__FUNC_GBE_TXD0>;
+ drive-strength = <MTK_DRIVE_8mA>;
+ };
+ };
+
+ eth_sleep_pins: eth-sleep-pins {
+ pins-cc {
+ pinmux = <PINMUX_GPIO85__FUNC_GPIO85>,
+ <PINMUX_GPIO86__FUNC_GPIO86>,
+ <PINMUX_GPIO87__FUNC_GPIO87>,
+ <PINMUX_GPIO88__FUNC_GPIO88>;
+ };
+
+ pins-mdio {
+ pinmux = <PINMUX_GPIO89__FUNC_GPIO89>,
+ <PINMUX_GPIO90__FUNC_GPIO90>;
+ input-disable;
+ bias-disable;
+ };
+
+ pins-rxd {
+ pinmux = <PINMUX_GPIO81__FUNC_GPIO81>,
+ <PINMUX_GPIO82__FUNC_GPIO82>,
+ <PINMUX_GPIO83__FUNC_GPIO83>,
+ <PINMUX_GPIO84__FUNC_GPIO84>;
+ };
+
+ pins-txd {
+ pinmux = <PINMUX_GPIO77__FUNC_GPIO77>,
+ <PINMUX_GPIO78__FUNC_GPIO78>,
+ <PINMUX_GPIO79__FUNC_GPIO79>,
+ <PINMUX_GPIO80__FUNC_GPIO80>;
+ };
+ };
+
+ gpio_key_pins: gpio-keys-pins {
+ pins {
+ pinmux = <PINMUX_GPIO106__FUNC_GPIO106>;
+ bias-pull-up;
+ input-enable;
+ };
+ };
+
+ i2c0_pins: i2c0-pins {
+ pins {
+ pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
+ <PINMUX_GPIO9__FUNC_SCL0>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c1_pins: i2c1-pins {
+ pins {
+ pinmux = <PINMUX_GPIO10__FUNC_SDA1>,
+ <PINMUX_GPIO11__FUNC_SCL1>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c2_pins: i2c2-pins {
+ pins {
+ pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
+ <PINMUX_GPIO13__FUNC_SCL2>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ drive-strength = <MTK_DRIVE_6mA>;
+ };
+ };
+
+ i2c6_pins: i2c6-pins {
+ pins {
+ pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
+ <PINMUX_GPIO26__FUNC_SCL6>;
+ bias-pull-up;
+ };
+ };
+
+ mmc0_default_pins: mmc0-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+ <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+ <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+ <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+ <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+ <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+ <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+ <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+ <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+ input-enable;
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc0_uhs_pins: mmc0-uhs-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+ <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+ <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+ <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+ <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+ <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+ <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+ <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+ <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+ input-enable;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-ds {
+ pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc1_default_pins: mmc1-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
+ <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
+ <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
+ <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
+ <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
+ input-enable;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc1_uhs_pins: mmc1-uhs-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
+ <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
+ <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
+ <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
+ <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
+ input-enable;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mt6360_pins: mt6360-pins {
+ pins {
+ pinmux = <PINMUX_GPIO17__FUNC_GPIO17>,
+ <PINMUX_GPIO128__FUNC_GPIO128>;
+ input-enable;
+ bias-pull-up;
+ };
+ };
+
+ pcie0_default_pins: pcie0-default-pins {
+ pins {
+ pinmux = <PINMUX_GPIO19__FUNC_WAKEN>,
+ <PINMUX_GPIO20__FUNC_PERSTN>,
+ <PINMUX_GPIO21__FUNC_CLKREQN>;
+ bias-pull-up;
+ };
+ };
+
+ pcie0_idle_pins: pcie0-idle-pins {
+ pins {
+ pinmux = <PINMUX_GPIO20__FUNC_GPIO20>;
+ bias-disable;
+ output-low;
+ };
+ };
+
+ pcie1_default_pins: pcie1-default-pins {
+ pins {
+ pinmux = <PINMUX_GPIO22__FUNC_PERSTN_1>,
+ <PINMUX_GPIO23__FUNC_CLKREQN_1>,
+ <PINMUX_GPIO24__FUNC_WAKEN_1>;
+ bias-pull-up;
+ };
+ };
+
+ pwm0_default_pins: pwm0-default-pins {
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO97__FUNC_DISP_PWM0>;
+ };
+ };
+
+ spi1_pins: spi1-pins {
+ pins {
+ pinmux = <PINMUX_GPIO136__FUNC_SPIM1_CSB>,
+ <PINMUX_GPIO137__FUNC_SPIM1_CLK>,
+ <PINMUX_GPIO138__FUNC_SPIM1_MO>,
+ <PINMUX_GPIO139__FUNC_SPIM1_MI>;
+ bias-disable;
+ };
+ };
+
+ spi2_pins: spi-pins {
+ pins {
+ pinmux = <PINMUX_GPIO140__FUNC_SPIM2_CSB>,
+ <PINMUX_GPIO141__FUNC_SPIM2_CLK>,
+ <PINMUX_GPIO142__FUNC_SPIM2_MO>,
+ <PINMUX_GPIO143__FUNC_SPIM2_MI>;
+ bias-disable;
+ };
+ };
+
+ touch_pins: touch-pins {
+ pins-irq {
+ pinmux = <PINMUX_GPIO132__FUNC_GPIO132>;
+ input-enable;
+ bias-disable;
+ };
+
+ pins-reset {
+ pinmux = <PINMUX_GPIO133__FUNC_GPIO133>;
+ output-high;
+ };
+ };
+
+ uart0_pins: uart0-pins {
+ pins {
+ pinmux = <PINMUX_GPIO98__FUNC_UTXD0>,
+ <PINMUX_GPIO99__FUNC_URXD0>;
+ };
+ };
+
+ uart1_pins: uart1-pins {
+ pins {
+ pinmux = <PINMUX_GPIO100__FUNC_URTS1>,
+ <PINMUX_GPIO101__FUNC_UCTS1>,
+ <PINMUX_GPIO102__FUNC_UTXD1>,
+ <PINMUX_GPIO103__FUNC_URXD1>;
+ };
+ };
+};
+
+&pmic {
+ interrupt-parent = <&pio>;
+ interrupts = <222 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&scp {
+ memory-region = <&scp_mem>;
+ status = "okay";
+};
+
+&spi1 {
+ pinctrl-0 = <&spi1_pins>;
+ pinctrl-names = "default";
+ mediatek,pad-select = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ cs-gpios = <&pio 64 GPIO_ACTIVE_LOW>;
+
+ can0: can@0 {
+ compatible = "microchip,mcp2518fd";
+ reg = <0>;
+ clocks = <&can_clk>;
+ spi-max-frequency = <20000000>;
+ interrupts-extended = <&pio 16 IRQ_TYPE_LEVEL_LOW>;
+ vdd-supply = <&mt6359_vcn33_2_bt_ldo_reg>;
+ xceiver-supply = <&mt6359_vcn33_2_bt_ldo_reg>;
+ };
+};
+
+&spi2 {
+ pinctrl-0 = <&spi2_pins>;
+ pinctrl-names = "default";
+ mediatek,pad-select = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+};
+
+&spmi {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ mt6315_6: pmic@6 {
+ compatible = "mediatek,mt6315-regulator";
+ reg = <0x6 SPMI_USID>;
+
+ regulators {
+ mt6315_6_vbuck1: vbuck1 {
+ regulator-compatible = "vbuck1";
+ regulator-name = "Vbcpu";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-allowed-modes = <0 1 2>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ mt6315_7: pmic@7 {
+ compatible = "mediatek,mt6315-regulator";
+ reg = <0x7 SPMI_USID>;
+
+ regulators {
+ mt6315_7_vbuck1: vbuck1 {
+ regulator-compatible = "vbuck1";
+ regulator-name = "Vgpu";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-allowed-modes = <0 1 2>;
+ };
+ };
+ };
+};
+
+&u3phy0 {
+ status = "okay";
+};
+
+&u3phy1 {
+ status = "okay";
+};
+
+&u3phy2 {
+ status = "okay";
+};
+
+&u3phy3 {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-0 = <&uart0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&ufsphy {
+ status = "disabled";
+};
+
+&xhci0 {
+ status = "okay";
+};
+
+&xhci1 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&xhci2 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&xhci3 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
index 8b78be8f4f9d..7e24a212c7e4 100644
--- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
@@ -93,6 +93,8 @@
resets = <&tegra_car 28>;
reset-names = "host1x";
+ iommus = <&mc TEGRA_SWGROUP_HC>;
+
#address-cells = <2>;
#size-cells = <2>;
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
index 53805555dd2d..9ebb7369256e 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
@@ -31,6 +31,33 @@
};
host1x@50000000 {
+ dsia: dsi@54300000 {
+ avdd-dsi-csi-supply = <&vdd_dsi_csi>;
+ status = "okay";
+
+ link2: panel@0 {
+ compatible = "jdi,lpm102a188a";
+ reg = <0>;
+ };
+ };
+
+ dsib: dsi@54400000 {
+ avdd-dsi-csi-supply = <&vdd_dsi_csi>;
+ nvidia,ganged-mode = <&dsia>;
+ status = "okay";
+
+ link1: panel@0 {
+ compatible = "jdi,lpm102a188a";
+ reg = <0>;
+ power-supply = <&pplcd_vdd>;
+ ddi-supply = <&pp1800_lcdio>;
+ enable-gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+ link2 = <&link2>;
+ backlight = <&backlight>;
+ };
+ };
+
dpaux: dpaux@545c0000 {
status = "okay";
};
@@ -1651,6 +1678,37 @@
status = "okay";
};
+ backlight: backlight@2c {
+ compatible = "ti,lp8557";
+ reg = <0x2c>;
+ power-supply = <&pplcd_vdd>;
+ enable-supply = <&pp1800_lcdio>;
+ bl-name = "lp8557-backlight";
+ dev-ctrl = /bits/ 8 <0x01>;
+ init-brt = /bits/ 8 <0x80>;
+
+ /* Full scale current, 20mA */
+ rom-11h {
+ rom-addr = /bits/ 8 <0x11>;
+ rom-val = /bits/ 8 <0x05>;
+ };
+ /* Frequency = 4.9kHz, magic undocumented val */
+ rom-12h {
+ rom-addr = /bits/ 8 <0x12>;
+ rom-val = /bits/ 8 <0x29>;
+ };
+ /* Boost freq = 1MHz, BComp option = 1 */
+ rom-13h {
+ rom-addr = /bits/ 8 <0x13>;
+ rom-val = /bits/ 8 <0x03>;
+ };
+ /* 4V OV, 6 output LED string enabled */
+ rom-14h {
+ rom-addr = /bits/ 8 <0x14>;
+ rom-val = /bits/ 8 <0xbf>;
+ };
+ };
+
audio-codec@2d {
compatible = "realtek,rt5677";
reg = <0x2d>;
@@ -1932,4 +1990,12 @@
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
+
+ vdd_dsi_csi: regulator-vdd-dsi-csi {
+ compatible = "regulator-fixed";
+ regulator-name = "AVDD_DSI_CSI_1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ vin-supply = <&pp1200_avdd>;
+ };
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi
index 62c4fdad0b60..553fa4ba1cd4 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi
@@ -44,6 +44,39 @@
status = "okay";
};
+ i2c@c250000 {
+ power-sensor@41 {
+ compatible = "ti,ina3221";
+ reg = <0x41>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ input@0 {
+ reg = <0x0>;
+ label = "CVB_ATX_12V";
+ shunt-resistor-micro-ohms = <2000>;
+ };
+
+ input@1 {
+ reg = <0x1>;
+ label = "CVB_ATX_3V3";
+ shunt-resistor-micro-ohms = <2000>;
+ };
+
+ input@2 {
+ reg = <0x2>;
+ label = "CVB_ATX_5V";
+ shunt-resistor-micro-ohms = <2000>;
+ };
+ };
+
+ power-sensor@44 {
+ compatible = "ti,ina219";
+ reg = <0x44>;
+ shunt-resistor = <2000>;
+ };
+ };
+
rtc@c2a0000 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi
index 5e7797df50c2..db6ef711674a 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi
@@ -1987,5 +1987,58 @@
status = "okay";
};
};
+
+ i2c@c240000 {
+ status = "okay";
+
+ power-sensor@40 {
+ compatible = "ti,ina3221";
+ reg = <0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ input@0 {
+ reg = <0x0>;
+ label = "VDD_GPU_SOC";
+ shunt-resistor-micro-ohms = <2000>;
+ };
+
+ input@1 {
+ reg = <0x1>;
+ label = "VDD_CPU_CV";
+ shunt-resistor-micro-ohms = <2000>;
+ };
+
+ input@2 {
+ reg = <0x2>;
+ label = "VIN_SYS_5V0";
+ shunt-resistor-micro-ohms = <2000>;
+ ti,summation-disable;
+ };
+ };
+
+ power-sensor@41 {
+ compatible = "ti,ina3221";
+ reg = <0x41>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ input@0 {
+ reg = <0x0>;
+ status = "disabled";
+ };
+
+ input@1 {
+ reg = <0x1>;
+ label = "VDDQ_VDD2_1V8AO";
+ shunt-resistor-micro-ohms = <2000>;
+ };
+
+ input@2 {
+ reg = <0x2>;
+ status = "disabled";
+ };
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
index 4413a9b6da87..ea13c4a7027c 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
@@ -30,6 +30,7 @@
};
serial@31d0000 {
+ current-speed = <115200>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi
index 5f592f1d81e2..59c14ded5e9f 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi
@@ -28,7 +28,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <136000000>;
+ spi-max-frequency = <102000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
};
@@ -42,7 +42,7 @@
mmc@3400000 {
status = "okay";
bus-width = <4>;
- cd-gpios = <&gpio TEGRA234_MAIN_GPIO(G, 7) GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio TEGRA234_MAIN_GPIO(G, 7) GPIO_ACTIVE_LOW>;
disable-wp;
};
@@ -55,6 +55,35 @@
avdd-usb-supply = <&vdd_3v3_ao>;
};
+ i2c@c240000 {
+ status = "okay";
+
+ power-sensor@40 {
+ compatible = "ti,ina3221";
+ reg = <0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ input@0 {
+ reg = <0x0>;
+ label = "VDD_IN";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+
+ input@1 {
+ reg = <0x1>;
+ label = "VDD_CPU_GPU_CV";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+
+ input@2 {
+ reg = <0x2>;
+ label = "VDD_SOC";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ };
+ };
+
rtc@c2a0000 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts
index e9460aedd47c..61b0e69d3d20 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts
@@ -12,15 +12,10 @@
model = "NVIDIA Jetson Orin NX Engineering Reference Developer Kit";
aliases {
- serial0 = &tcu;
serial1 = &uarta;
serial2 = &uarte;
};
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
bus@0 {
serial@3100000 {
compatible = "nvidia,tegra194-hsuart";
@@ -34,10 +29,6 @@
status = "okay";
};
- serial@31d0000 {
- status = "okay";
- };
-
pwm@32a0000 {
assigned-clocks = <&bpmp TEGRA234_CLK_PWM3>;
assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
@@ -94,10 +85,6 @@
enable-active-high;
};
- serial {
- status = "okay";
- };
-
thermal-zones {
tj-thermal {
cooling-maps {
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi
index 39110c1232e0..5d0298b6c30d 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi
@@ -29,6 +29,7 @@
};
serial@31d0000 {
+ current-speed = <115200>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
index 95524e5bce82..3f16595d099c 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
@@ -43,12 +43,12 @@
<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
status = "okay";
};
@@ -694,6 +694,8 @@
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA234_CLK_UARTE>;
resets = <&bpmp TEGRA234_RESET_UARTE>;
+ dmas = <&gpcdma 20>, <&gpcdma 20>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -705,8 +707,8 @@
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <400000>;
- clocks = <&bpmp TEGRA234_CLK_I2C1
- &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clocks = <&bpmp TEGRA234_CLK_I2C1>,
+ <&bpmp TEGRA234_CLK_PLLP_OUT0>;
assigned-clocks = <&bpmp TEGRA234_CLK_I2C1>;
assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
clock-names = "div-clk", "parent";
@@ -724,8 +726,8 @@
#size-cells = <0>;
status = "disabled";
clock-frequency = <400000>;
- clocks = <&bpmp TEGRA234_CLK_I2C3
- &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clocks = <&bpmp TEGRA234_CLK_I2C3>,
+ <&bpmp TEGRA234_CLK_PLLP_OUT0>;
assigned-clocks = <&bpmp TEGRA234_CLK_I2C3>;
assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
clock-names = "div-clk", "parent";
@@ -743,8 +745,8 @@
#size-cells = <0>;
status = "disabled";
clock-frequency = <100000>;
- clocks = <&bpmp TEGRA234_CLK_I2C4
- &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clocks = <&bpmp TEGRA234_CLK_I2C4>,
+ <&bpmp TEGRA234_CLK_PLLP_OUT0>;
assigned-clocks = <&bpmp TEGRA234_CLK_I2C4>;
assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
clock-names = "div-clk", "parent";
@@ -762,8 +764,8 @@
#size-cells = <0>;
status = "disabled";
clock-frequency = <100000>;
- clocks = <&bpmp TEGRA234_CLK_I2C6
- &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clocks = <&bpmp TEGRA234_CLK_I2C6>,
+ <&bpmp TEGRA234_CLK_PLLP_OUT0>;
assigned-clocks = <&bpmp TEGRA234_CLK_I2C6>;
assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
clock-names = "div-clk", "parent";
@@ -781,8 +783,8 @@
#size-cells = <0>;
status = "disabled";
clock-frequency = <100000>;
- clocks = <&bpmp TEGRA234_CLK_I2C7
- &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clocks = <&bpmp TEGRA234_CLK_I2C7>,
+ <&bpmp TEGRA234_CLK_PLLP_OUT0>;
assigned-clocks = <&bpmp TEGRA234_CLK_I2C7>;
assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
clock-names = "div-clk", "parent";
@@ -807,8 +809,8 @@
#size-cells = <0>;
status = "disabled";
clock-frequency = <100000>;
- clocks = <&bpmp TEGRA234_CLK_I2C9
- &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clocks = <&bpmp TEGRA234_CLK_I2C9>,
+ <&bpmp TEGRA234_CLK_PLLP_OUT0>;
assigned-clocks = <&bpmp TEGRA234_CLK_I2C9>;
assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
clock-names = "div-clk", "parent";
@@ -819,7 +821,7 @@
};
spi@3210000 {
- compatible = "nvidia,tegra210-spi";
+ compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
reg = <0x0 0x03210000 0x0 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
@@ -838,7 +840,7 @@
};
spi@3230000 {
- compatible = "nvidia,tegra210-spi";
+ compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
reg = <0x0 0x03230000 0x0 0x1000>;
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
@@ -1751,8 +1753,8 @@
#size-cells = <0>;
status = "disabled";
clock-frequency = <100000>;
- clocks = <&bpmp TEGRA234_CLK_I2C2
- &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clocks = <&bpmp TEGRA234_CLK_I2C2>,
+ <&bpmp TEGRA234_CLK_PLLP_OUT0>;
clock-names = "div-clk", "parent";
assigned-clocks = <&bpmp TEGRA234_CLK_I2C2>;
assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
@@ -1770,8 +1772,8 @@
#size-cells = <0>;
status = "disabled";
clock-frequency = <400000>;
- clocks = <&bpmp TEGRA234_CLK_I2C8
- &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clocks = <&bpmp TEGRA234_CLK_I2C8>,
+ <&bpmp TEGRA234_CLK_PLLP_OUT0>;
clock-names = "div-clk", "parent";
assigned-clocks = <&bpmp TEGRA234_CLK_I2C8>;
assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
@@ -1782,7 +1784,7 @@
};
spi@c260000 {
- compatible = "nvidia,tegra210-spi";
+ compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
reg = <0x0 0x0c260000 0x0 0x1000>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 2cca20563a1d..d6cb840b7050 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -1,5 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb
+
+apq8016-sbc-usb-host-dtbs := apq8016-sbc.dtb apq8016-sbc-usb-host.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc-usb-host.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc-d3-camera-mezzanine.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8039-t2.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8094-sony-xperia-kitakami-karin_windy.dtb
@@ -41,6 +45,7 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8916-thwc-uf896.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-thwc-ufi001c.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-wingtech-wt88047.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-yiming-uz801v3.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8939-longcheer-l9100.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8939-samsung-a7.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8939-sony-xperia-kanuti-tulip.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8953-motorola-potter.dtb
@@ -81,6 +86,7 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-lilac.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-maple.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-poplar.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8998-xiaomi-sagit.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcm6490-fairphone-fp5.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb
dtb-$(CONFIG_ARCH_QCOM) += qdu1000-idp.dtb
@@ -112,11 +118,16 @@ dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r3-lte.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r9.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r9-kb.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r9-lte.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r10.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r10-kb.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r10-lte.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-limozeen-r4.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-limozeen-r9.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-limozeen-r10.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-limozeen-nots-r4.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-limozeen-nots-r5.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-limozeen-nots-r9.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-limozeen-nots-r10.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-pazquel-lte-parade.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-pazquel-lte-ti.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-pazquel-parade.dtb
@@ -196,6 +207,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm6125-sony-xperia-seine-pdx201.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6125-xiaomi-laurel-sprout.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6350-sony-xperia-lena-pdx213.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6375-sony-xperia-murray-pdx225.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm7125-xiaomi-joyeuse.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm7225-fairphone-fp4.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8150-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8150-microsoft-surface-duo.dtb
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-usb-host.dtso b/arch/arm64/boot/dts/qcom/apq8016-sbc-usb-host.dtso
new file mode 100644
index 000000000000..a82c26b7eae8
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-usb-host.dtso
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+/plugin/;
+
+&usb {
+ dr_mode = "host";
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
index 4f5541e9be0e..9ffad7d1f2b6 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
@@ -172,6 +172,9 @@
pd-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
avdd-supply = <&pm8916_l6>;
+ a2vdd-supply = <&pm8916_l6>;
+ dvdd-supply = <&pm8916_l6>;
+ pvdd-supply = <&pm8916_l6>;
v1p2-supply = <&pm8916_l6>;
v3p3-supply = <&pm8916_l17>;
@@ -230,6 +233,10 @@
status = "okay";
};
+&gpu {
+ status = "okay";
+};
+
&lpass {
status = "okay";
};
@@ -238,6 +245,10 @@
status = "okay";
};
+&mba_mem {
+ status = "okay";
+};
+
&mdss {
status = "okay";
};
@@ -253,10 +264,13 @@
firmware-name = "qcom/apq8016/mba.mbn", "qcom/apq8016/modem.mbn";
};
+&mpss_mem {
+ status = "okay";
+ reg = <0x0 0x86800000 0x0 0x2b00000>;
+};
+
&pm8916_codec {
status = "okay";
- clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
- clock-names = "mclk";
qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
};
@@ -364,6 +378,14 @@
extcon = <&usb_id>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
firmware-name = "qcom/apq8016/wcnss.mbn";
@@ -377,6 +399,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
/* Enable CoreSight */
&cti0 { status = "okay"; };
&cti1 { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/apq8039-t2.dts b/arch/arm64/boot/dts/qcom/apq8039-t2.dts
index 027d1da7e81d..4f82bb668616 100644
--- a/arch/arm64/boot/dts/qcom/apq8039-t2.dts
+++ b/arch/arm64/boot/dts/qcom/apq8039-t2.dts
@@ -131,6 +131,10 @@
status = "okay";
};
+&gpu {
+ status = "okay";
+};
+
&lpass {
status = "okay";
};
@@ -391,3 +395,7 @@
&wcnss_iris {
compatible = "qcom,wcn3680";
};
+
+&wcnss_mem {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
index 3067a4091a7a..e8148b3d6c50 100644
--- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
@@ -1089,7 +1089,6 @@
vdda-phy-supply = <&vreg_l28a_0p925>;
vdda-pll-supply = <&vreg_l12a_1p8>;
- vddp-ref-clk-supply = <&vreg_l25a_1p2>;
};
&ufshc {
@@ -1098,6 +1097,7 @@
vcc-supply = <&vreg_l20a_2p95>;
vccq-supply = <&vreg_l25a_1p2>;
vccq2-supply = <&vreg_s4a_1p8>;
+ vdd-hba-supply = <&vreg_l25a_1p2>;
vcc-max-microamp = <600000>;
vccq-max-microamp = <450000>;
diff --git a/arch/arm64/boot/dts/qcom/ipq5018.dtsi b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
index 9f13d2dcdfd5..38ffdc3cbdcd 100644
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -57,6 +57,7 @@
firmware {
scm {
compatible = "qcom,scm-ipq5018", "qcom,scm";
+ qcom,sdi-enabled;
};
};
@@ -181,6 +182,13 @@
};
};
+ watchdog: watchdog@b017000 {
+ compatible = "qcom,apss-wdt-ipq5018", "qcom,kpss-wdt";
+ reg = <0x0b017000 0x40>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&sleep_clk>;
+ };
+
timer@b120000 {
compatible = "arm,armv7-timer-mem";
reg = <0x0b120000 0x1000>;
diff --git a/arch/arm64/boot/dts/qcom/ipq5332-rdp468.dts b/arch/arm64/boot/dts/qcom/ipq5332-rdp468.dts
index f96b0c8c908b..c224ffc65b08 100644
--- a/arch/arm64/boot/dts/qcom/ipq5332-rdp468.dts
+++ b/arch/arm64/boot/dts/qcom/ipq5332-rdp468.dts
@@ -12,6 +12,15 @@
/ {
model = "Qualcomm Technologies, Inc. IPQ5332 MI01.6";
compatible = "qcom,ipq5332-ap-mi01.6", "qcom,ipq5332";
+
+ regulator_fixed_5p0: regulator-s0500 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-name = "fixed_5p0";
+ };
};
&blsp1_spi0 {
@@ -79,3 +88,17 @@
bias-pull-up;
};
};
+
+&usb {
+ status = "okay";
+};
+
+&usb_dwc {
+ dr_mode = "host";
+};
+
+&usbphy0 {
+ vdd-supply = <&regulator_fixed_5p0>;
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/ipq5332.dtsi b/arch/arm64/boot/dts/qcom/ipq5332.dtsi
index 8bfc2db44624..d3fef2f80a81 100644
--- a/arch/arm64/boot/dts/qcom/ipq5332.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5332.dtsi
@@ -135,7 +135,7 @@
reg = <0x0 0x4a800000 0x0 0x100000>;
no-map;
- hwlocks = <&tcsr_mutex 0>;
+ hwlocks = <&tcsr_mutex 3>;
};
};
@@ -145,6 +145,19 @@
#size-cells = <1>;
ranges = <0 0 0 0xffffffff>;
+ usbphy0: phy@7b000 {
+ compatible = "qcom,ipq5332-usb-hsphy";
+ reg = <0x0007b000 0x12c>;
+
+ clocks = <&gcc GCC_USB0_PHY_CFG_AHB_CLK>;
+
+ resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
+
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
+
qfprom: efuse@a4000 {
compatible = "qcom,ipq5332-qfprom", "qcom,qfprom";
reg = <0x000a4000 0x721>;
@@ -290,6 +303,48 @@
status = "disabled";
};
+ usb: usb@8af8800 {
+ compatible = "qcom,ipq5332-dwc3", "qcom,dwc3";
+ reg = <0x08af8800 0x400>;
+
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hs_phy_irq";
+
+ clocks = <&gcc GCC_USB0_MASTER_CLK>,
+ <&gcc GCC_SNOC_USB_CLK>,
+ <&gcc GCC_USB0_SLEEP_CLK>,
+ <&gcc GCC_USB0_MOCK_UTMI_CLK>;
+ clock-names = "core",
+ "iface",
+ "sleep",
+ "mock_utmi";
+
+ resets = <&gcc GCC_USB_BCR>;
+
+ qcom,select-utmi-as-pipe-clk;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ status = "disabled";
+
+ usb_dwc: usb@8a00000 {
+ compatible = "snps,dwc3";
+ reg = <0x08a00000 0xe000>;
+ clocks = <&gcc GCC_USB0_MOCK_UTMI_CLK>;
+ clock-names = "ref";
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ phy-names = "usb2-phy";
+ phys = <&usbphy0>;
+ tx-fifo-resize;
+ snps,is-utmi-l1-suspend;
+ snps,hird-threshold = /bits/ 8 <0x0>;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_u3_susphy_quirk;
+ };
+ };
+
intc: interrupt-controller@b000000 {
compatible = "qcom,msm-qgic2";
reg = <0x0b000000 0x1000>, /* GICD */
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 47b8b1d6730a..e59b9df96c7e 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -211,7 +211,7 @@
smem {
compatible = "qcom,smem";
memory-region = <&smem_region>;
- hwlocks = <&tcsr_mutex 0>;
+ hwlocks = <&tcsr_mutex 3>;
};
soc: soc@0 {
@@ -278,33 +278,25 @@
pcie_phy: phy@84000 {
compatible = "qcom,ipq6018-qmp-pcie-phy";
- reg = <0x0 0x00084000 0x0 0x1bc>; /* Serdes PLL */
+ reg = <0x0 0x00084000 0x0 0x1000>;
status = "disabled";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
clocks = <&gcc GCC_PCIE0_AUX_CLK>,
- <&gcc GCC_PCIE0_AHB_CLK>;
- clock-names = "aux", "cfg_ahb";
+ <&gcc GCC_PCIE0_AHB_CLK>,
+ <&gcc GCC_PCIE0_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "pipe";
+
+ clock-output-names = "gcc_pcie0_pipe_clk_src";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE0_PHY_BCR>,
<&gcc GCC_PCIE0PHY_PHY_BCR>;
reset-names = "phy",
"common";
-
- pcie_phy0: phy@84200 {
- reg = <0x0 0x00084200 0x0 0x16c>, /* Serdes Tx */
- <0x0 0x00084400 0x0 0x200>, /* Serdes Rx */
- <0x0 0x00084800 0x0 0x1f0>, /* PCS: Lane0, COM, PCIE */
- <0x0 0x00084c00 0x0 0xf4>; /* pcs_misc */
- #phy-cells = <0>;
-
- clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "gcc_pcie0_pipe_clk_src";
- #clock-cells = <0>;
- };
};
mdio: mdio@90000 {
@@ -393,7 +385,7 @@
tcsr_mutex: hwlock@1905000 {
compatible = "qcom,ipq6018-tcsr-mutex", "qcom,tcsr-mutex";
- reg = <0x0 0x01905000 0x0 0x1000>;
+ reg = <0x0 0x01905000 0x0 0x20000>;
#hwlock-cells = <1>;
};
@@ -756,7 +748,7 @@
#address-cells = <3>;
#size-cells = <2>;
- phys = <&pcie_phy0>;
+ phys = <&pcie_phy>;
phy-names = "pciephy";
ranges = <0x81000000 0x0 0x00000000 0x0 0x20200000 0x0 0x10000>,
diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
index 00ed71936b47..2f275c84e566 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -101,7 +101,7 @@
reg = <0x0 0x4ab00000 0x0 0x100000>;
no-map;
- hwlocks = <&tcsr_mutex 0>;
+ hwlocks = <&tcsr_mutex 3>;
};
memory@4ac00000 {
@@ -211,59 +211,48 @@
pcie_qmp0: phy@84000 {
compatible = "qcom,ipq8074-qmp-gen3-pcie-phy";
- reg = <0x00084000 0x1bc>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
+ reg = <0x00084000 0x1000>;
clocks = <&gcc GCC_PCIE0_AUX_CLK>,
- <&gcc GCC_PCIE0_AHB_CLK>;
- clock-names = "aux", "cfg_ahb";
+ <&gcc GCC_PCIE0_AHB_CLK>,
+ <&gcc GCC_PCIE0_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "pipe";
+
+ clock-output-names = "pcie20_phy0_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
+
resets = <&gcc GCC_PCIE0_PHY_BCR>,
- <&gcc GCC_PCIE0PHY_PHY_BCR>;
+ <&gcc GCC_PCIE0PHY_PHY_BCR>;
reset-names = "phy",
"common";
status = "disabled";
-
- pcie_phy0: phy@84200 {
- reg = <0x84200 0x16c>,
- <0x84400 0x200>,
- <0x84800 0x1f0>,
- <0x84c00 0xf4>;
- #phy-cells = <0>;
- #clock-cells = <0>;
- clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "pcie20_phy0_pipe_clk";
- };
};
pcie_qmp1: phy@8e000 {
compatible = "qcom,ipq8074-qmp-pcie-phy";
- reg = <0x0008e000 0x1c4>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
+ reg = <0x0008e000 0x1000>;
clocks = <&gcc GCC_PCIE1_AUX_CLK>,
- <&gcc GCC_PCIE1_AHB_CLK>;
- clock-names = "aux", "cfg_ahb";
+ <&gcc GCC_PCIE1_AHB_CLK>,
+ <&gcc GCC_PCIE1_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "pipe";
+
+ clock-output-names = "pcie20_phy1_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
+
resets = <&gcc GCC_PCIE1_PHY_BCR>,
- <&gcc GCC_PCIE1PHY_PHY_BCR>;
+ <&gcc GCC_PCIE1PHY_PHY_BCR>;
reset-names = "phy",
"common";
status = "disabled";
-
- pcie_phy1: phy@8e200 {
- reg = <0x8e200 0x130>,
- <0x8e400 0x200>,
- <0x8e800 0x1f8>;
- #phy-cells = <0>;
- #clock-cells = <0>;
- clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "pcie20_phy1_pipe_clk";
- };
};
mdio: mdio@90000 {
@@ -807,7 +796,7 @@
#address-cells = <3>;
#size-cells = <2>;
- phys = <&pcie_phy1>;
+ phys = <&pcie_qmp1>;
phy-names = "pciephy";
ranges = <0x81000000 0x0 0x00000000 0x10200000 0x0 0x10000>, /* I/O */
@@ -869,7 +858,7 @@
#address-cells = <3>;
#size-cells = <2>;
- phys = <&pcie_phy0>;
+ phys = <&pcie_qmp0>;
phy-names = "pciephy";
ranges = <0x81000000 0x0 0x00000000 0x20200000 0x0 0x10000>, /* I/O */
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
index 51aba071c1eb..8a72ad4afd03 100644
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -195,7 +195,7 @@
smem@4aa00000 {
compatible = "qcom,smem";
reg = <0x0 0x4aa00000 0x0 0x100000>;
- hwlocks = <&tcsr_mutex 0>;
+ hwlocks = <&tcsr_mutex 3>;
no-map;
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
index 84723c9b73b4..57a74eea1005 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
@@ -155,6 +155,14 @@
extcon = <&usb_id>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -163,6 +171,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
accel_int_default: accel-int-default-state {
pins = "gpio115";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
index 47da738661bf..aa4c1ab1e673 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
@@ -192,6 +192,14 @@
extcon = <&usb_id>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -200,6 +208,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
accel_int_default: accel-int-default-state {
pins = "gpio31";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
index 92f695481769..a8be6ff66893 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
@@ -160,6 +160,14 @@
extcon = <&usb_id>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -168,6 +176,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
gpio_keys_default: gpio-keys-default-state {
pins = "gpio107", "gpio117";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
index 4aeeee24cedc..b748d140b52e 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
@@ -150,6 +150,14 @@
extcon = <&usb_id>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -158,6 +166,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
camera_flash_default: camera-flash-default-state {
pins = "gpio31", "gpio32";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
index 484e488a5eca..bf7fc89dd106 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
@@ -328,6 +328,14 @@
extcon = <&usb_id>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -336,6 +344,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
accel_irq_default: accel-irq-default-state {
pins = "gpio115";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
index 3892ad4f639a..47d1c5cb13f4 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
@@ -23,9 +23,14 @@
stdout-path = "serial0";
};
+ /*
+ * For some reason, the signed wcnss firmware is not relocatable.
+ * It must be loaded at 0x8b600000. All other firmware is relocatable,
+ * so place wcnss at the fixed address and then all other firmware
+ * regions will be automatically allocated at a fitting place.
+ */
reserved-memory {
- /* wcnss.mdt is not relocatable, so it must be loaded at 0x8b600000 */
- /delete-node/ wcnss@89300000;
+ /delete-node/ wcnss;
wcnss_mem: wcnss@8b600000 {
reg = <0x0 0x8b600000 0x0 0x600000>;
@@ -259,6 +264,14 @@
extcon = <&pm8916_usbin>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -267,6 +280,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
accel_int_default: accel-int-default-state {
pins = "gpio116";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
index d73294af1a06..41cadb906b98 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
@@ -146,6 +146,14 @@
extcon = <&usb_id>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -154,6 +162,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
button_backlight_default: button-backlight-default-state {
pins = "gpio17";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
index 019bf73178fa..0b29132b74e1 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
@@ -239,6 +239,10 @@
status = "okay";
};
+&gpu {
+ status = "okay";
+};
+
&mdss {
status = "okay";
};
@@ -284,6 +288,14 @@
extcon = <&muic>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&tlmm {
accel_int_default: accel-int-default-state {
pins = "gpio115";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
index e5a569698c4f..f5a808369518 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
@@ -120,6 +120,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
panel_vdd3_default: panel-vdd3-default-state {
pins = "gpio9";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
index 388482a1e3d9..391befa22bb4 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
@@ -71,6 +71,10 @@
compatible = "qcom,wcn3660b";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
tkey_en_default: tkey-en-default-state {
pins = "gpio97";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
index 6f65fd4b3ed3..0824ab041d80 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
@@ -83,6 +83,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
tkey_en_default: tkey-en-default-state {
pins = "gpio97";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
index 54d648972d35..c19cf20d7427 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
@@ -158,6 +158,14 @@
extcon = <&pm8916_usbin>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -166,6 +174,10 @@
compatible = "qcom,wcn3660b";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
accel_int_default: accel-int-default-state {
pins = "gpio115";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt510.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt510.dts
index 48111c6a2c78..75c4854ecd64 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt510.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt510.dts
@@ -19,6 +19,19 @@
pinctrl-names = "default";
};
+ reg_lcd_vmipi: regulator-lcd-vmipi {
+ compatible = "regulator-fixed";
+ regulator-name = "lcd_vmipi";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&lcd_en_default>;
+ pinctrl-names = "default";
+ };
+
reg_motor_vdd: regulator-motor-vdd {
compatible = "regulator-fixed";
regulator-name = "motor_vdd";
@@ -55,6 +68,19 @@
enable-active-high;
};
+ reg_vlcd_5p4v: regulator-vlcd-5p4v {
+ compatible = "regulator-fixed";
+ regulator-name = "vlcd_5p4v";
+ regulator-min-microvolt = <5400000>;
+ regulator-max-microvolt = <5400000>;
+
+ gpio = <&tlmm 51 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&buckbooster_en_default>;
+ pinctrl-names = "default";
+ };
+
vibrator {
compatible = "pwm-vibrator";
@@ -81,10 +107,49 @@
pinctrl-0 = <&tsp_int_rst_default>;
pinctrl-names = "default";
+
+ linux,keycodes = <KEY_APPSELECT KEY_BACK>;
+ };
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0 {
+ pinctrl-0 = <&mdss_default>;
+ pinctrl-1 = <&mdss_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ panel@0 {
+ compatible = "samsung,ltl101at01", "samsung,s6d7aa0";
+ reg = <0>;
+
+ power-supply = <&reg_vlcd_5p4v>;
+ vmipi-supply = <&reg_lcd_vmipi>;
+ reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
};
};
+&mdss_dsi0_out {
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&panel_in>;
+};
+
&tlmm {
+ buckbooster_en_default: buckbooster-en-default-state {
+ pins = "gpio51";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
motor_en_default: motor-en-default-state {
pins = "gpio76";
function = "gpio";
@@ -97,6 +162,27 @@
function = "gcc_gp2_clk_a";
};
+ lcd_en_default: lcd-en-default-state {
+ pins = "gpio8";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ mdss_default: mdss-default-state {
+ pins = "gpio97";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ mdss_sleep: mdss-sleep-state {
+ pins = "gpio97";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
tsp_en_default: tsp-en-default-state {
pins = "gpio73";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt58.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt58.dts
index 98ceaad7fcea..11359bcc27b3 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt58.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt58.dts
@@ -9,6 +9,19 @@
compatible = "samsung,gt58", "qcom,msm8916";
chassis-type = "tablet";
+ reg_5p4v: regulator-5p4v {
+ compatible = "regulator-fixed";
+ regulator-name = "vlcd_5p4v";
+ regulator-min-microvolt = <5400000>;
+ regulator-max-microvolt = <5400000>;
+
+ gpio = <&tlmm 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&buckbooster_en_default>;
+ pinctrl-names = "default";
+ };
+
reg_vdd_tsp: regulator-vdd-tsp {
compatible = "regulator-fixed";
regulator-name = "vdd_tsp";
@@ -51,7 +64,58 @@
};
};
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0 {
+ pinctrl-0 = <&mdss_default>;
+ pinctrl-1 = <&mdss_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ panel@0 {
+ compatible = "samsung,lsl080al03", "samsung,s6d7aa0";
+ reg = <0>;
+
+ power-supply = <&reg_5p4v>;
+ vmipi-supply = <&pm8916_l5>;
+ reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+};
+
+&mdss_dsi0_out {
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&panel_in>;
+};
+
&tlmm {
+ buckbooster_en_default: buckbooster-en-default-state {
+ pins = "gpio8";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ mdss_default: mdss-default-state {
+ pins = "gpio97";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ mdss_sleep: mdss-sleep-state {
+ pins = "gpio97";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
reg_tsp_en_default: reg-tsp-en-default-state {
pins = "gpio73";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
index cb0e4a7faf91..fe59be3505fe 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
@@ -84,6 +84,31 @@
pinctrl-0 = <&muic_int_default>;
};
};
+
+ i2c_sensors: i2c-sensors {
+ compatible = "i2c-gpio";
+
+ sda-gpios = <&tlmm 31 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&tlmm 32 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-0 = <&sensors_i2c_default>;
+ pinctrl-names = "default";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ accelerometer: accelerometer@1d {
+ compatible = "st,lis2hh12";
+ reg = <0x1d>;
+
+ interrupts-extended = <&tlmm 115 IRQ_TYPE_LEVEL_HIGH>;
+
+ pinctrl-0 = <&accel_int_default>;
+ pinctrl-names = "default";
+
+ st,drdy-int-pin = <1>;
+ };
+ };
};
&blsp_i2c5 {
@@ -138,6 +163,14 @@
extcon = <&muic>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -146,7 +179,18 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
gpio_hall_sensor_default: gpio-hall-sensor-default-state {
pins = "gpio52";
function = "gpio";
@@ -187,6 +231,13 @@
bias-disable;
};
+ sensors_i2c_default: sensors-i2c-default-state {
+ pins = "gpio31", "gpio32";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
tsp_int_default: tsp-int-default-state {
pins = "gpio13";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts
index 3e1ff5b4d2d7..58c2f5a70e78 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts
@@ -10,6 +10,11 @@
chassis-type = "handset";
};
+&accelerometer {
+ vdd-supply = <&pm8916_l5>;
+ vddio-supply = <&pm8916_l5>;
+};
+
&blsp_i2c5 {
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5x.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5x.dts
index b2fe109723d8..8b404a9cd62d 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5x.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5x.dts
@@ -23,6 +23,17 @@
};
};
+&accelerometer {
+ interrupts-extended = <&tlmm 49 IRQ_TYPE_LEVEL_HIGH>;
+
+ vdd-supply = <&pm8916_l6>;
+ vddio-supply = <&pm8916_l6>;
+
+ mount-matrix = "0", "-1", "0",
+ "1", "0", "0",
+ "0", "0", "-1";
+};
+
&muic {
interrupts = <121 IRQ_TYPE_EDGE_FALLING>;
};
@@ -40,6 +51,10 @@
};
};
+&accel_int_default {
+ pins = "gpio49";
+};
+
&muic_int_default {
pins = "gpio121";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
index eaf877378937..68da2a2d3077 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
@@ -359,6 +359,14 @@
extcon = <&muic>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -367,6 +375,10 @@
compatible = "qcom,wcn3660b";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
fg_alert_default: fg-alert-default-state {
pins = "gpio121";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
index 004a129a2ee2..c77ed04bb6c3 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
@@ -17,18 +17,6 @@
stdout-path = "serial0";
};
- reserved-memory {
- mpss_mem: mpss@86800000 {
- reg = <0x0 0x86800000 0x0 0x5500000>;
- no-map;
- };
-
- gps_mem: gps@8bd00000 {
- reg = <0x0 0x8bd00000 0x0 0x200000>;
- no-map;
- };
- };
-
gpio-keys {
compatible = "gpio-keys";
@@ -92,10 +80,19 @@
clocks = <&xo_board>, <&sleep_clk>, <0>, <0>, <0>, <0>, <0>;
};
+&mba_mem {
+ status = "okay";
+};
+
&mpss {
status = "okay";
};
+&mpss_mem {
+ reg = <0x0 0x86800000 0x0 0x5500000>;
+ status = "okay";
+};
+
&pm8916_usbin {
status = "okay";
};
@@ -115,6 +112,14 @@
extcon = <&pm8916_usbin>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -123,6 +128,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
/* pins are board-specific */
button_default: button-default-state {
diff --git a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
index 8e238976ab1c..419f35c1fc92 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
@@ -189,6 +189,14 @@
extcon = <&usb_id>;
};
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
&wcnss {
status = "okay";
};
@@ -197,6 +205,10 @@
compatible = "qcom,wcn3620";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
camera_flash_default: camera-flash-default-state {
pins = "gpio31", "gpio32";
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 33fb65d73104..4f799b536a92 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -74,23 +74,43 @@
};
mpss_mem: mpss@86800000 {
- reg = <0x0 0x86800000 0x0 0x2b00000>;
+ /*
+ * The memory region for the mpss firmware is generally
+ * relocatable and could be allocated dynamically.
+ * However, many firmware versions tend to fail when
+ * loaded to some special addresses, so it is hard to
+ * define reliable alloc-ranges.
+ *
+ * alignment = <0x0 0x400000>;
+ * alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
+ */
+ reg = <0x0 0x86800000 0x0 0>; /* size is device-specific */
no-map;
+ status = "disabled";
};
- wcnss_mem: wcnss@89300000 {
- reg = <0x0 0x89300000 0x0 0x600000>;
+ wcnss_mem: wcnss {
+ size = <0x0 0x600000>;
+ alignment = <0x0 0x100000>;
+ alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
no-map;
+ status = "disabled";
};
- venus_mem: venus@89900000 {
- reg = <0x0 0x89900000 0x0 0x600000>;
+ venus_mem: venus {
+ size = <0x0 0x500000>;
+ alignment = <0x0 0x100000>;
+ alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
no-map;
+ status = "disabled";
};
- mba_mem: mba@8ea00000 {
+ mba_mem: mba {
+ size = <0x0 0x100000>;
+ alignment = <0x0 0x100000>;
+ alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
no-map;
- reg = <0 0x8ea00000 0 0x100000>;
+ status = "disabled";
};
};
@@ -1750,7 +1770,7 @@
};
};
- gpu@1c00000 {
+ gpu: gpu@1c00000 {
compatible = "qcom,adreno-306.0", "qcom,adreno";
reg = <0x01c00000 0x20000>;
reg-names = "kgsl_3d0_reg_memory";
@@ -1773,6 +1793,7 @@
power-domains = <&gcc OXILI_GDSC>;
operating-points-v2 = <&gpu_opp_table>;
iommus = <&gpu_iommu 1>, <&gpu_iommu 2>;
+ status = "disabled";
gpu_opp_table: opp-table {
compatible = "operating-points-v2";
@@ -1797,7 +1818,7 @@
clock-names = "core", "iface", "bus";
iommus = <&apps_iommu 5>;
memory-region = <&venus_mem>;
- status = "okay";
+ status = "disabled";
video-decoder {
compatible = "venus-decoder";
@@ -1813,7 +1834,7 @@
#size-cells = <1>;
#iommu-cells = <1>;
compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1";
- ranges = <0 0x01e20000 0x40000>;
+ ranges = <0 0x01e20000 0x20000>;
reg = <0x01ef0000 0x3000>;
clocks = <&gcc GCC_SMMU_CFG_CLK>,
<&gcc GCC_APSS_TCU_CLK>;
diff --git a/arch/arm64/boot/dts/qcom/msm8939-longcheer-l9100.dts b/arch/arm64/boot/dts/qcom/msm8939-longcheer-l9100.dts
new file mode 100644
index 000000000000..6802714fda3f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8939-longcheer-l9100.dts
@@ -0,0 +1,334 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8939-pm8916.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
+
+/ {
+ model = "BQ Aquaris M5 (Longcheer L9100)";
+ compatible = "longcheer,l9100", "qcom,msm8939";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdhc_1; /* eMMC */
+ mmc1 = &sdhc_2; /* SD card */
+ serial0 = &blsp_uart2;
+ };
+
+ chosen {
+ stdout-path = "serial0";
+ };
+
+ gpio-hall-sensor {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_hall_sensor_default>;
+ pinctrl-names = "default";
+
+ label = "GPIO Hall Effect Sensor";
+
+ event-hall-sensor {
+ label = "Hall Effect Sensor";
+ gpios = <&tlmm 20 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ linux,can-disable;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_keys_default>;
+ pinctrl-names = "default";
+
+ label = "GPIO Buttons";
+
+ button-volume-up {
+ label = "Volume Up";
+ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ gpios = <&tlmm 17 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ default-state = "off";
+ function = LED_FUNCTION_KBD_BACKLIGHT;
+
+ pinctrl-0 = <&button_backlight_default>;
+ pinctrl-names = "default";
+ };
+ };
+
+ reg_ts_vdd: regulator-vdd-ts {
+ compatible = "regulator-fixed";
+ regulator-name = "regulator-vdd-ts";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+
+ gpio = <&tlmm 78 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&ts_vdd_default>;
+ pinctrl-names = "default";
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pm8916_pwm 0 100000>;
+ brightness-levels = <0 255>;
+ num-interpolated-steps = <255>;
+ default-brightness-level = <128>;
+ enable-gpios = <&tlmm 98 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&lcd_bl_en_default>;
+ pinctrl-names = "default";
+ };
+
+ flash-led-controller {
+ compatible = "ocs,ocp8110";
+ flash-gpios = <&tlmm 8 GPIO_ACTIVE_HIGH>;
+ enable-gpios = <&tlmm 49 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&camera_front_flash_default>;
+ pinctrl-names = "default";
+
+ led {
+ function = LED_FUNCTION_FLASH;
+ color = <LED_COLOR_ID_WHITE>;
+ flash-max-timeout-us = <250000>;
+ };
+ };
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&usb_id_default &usb_id_switch_default>;
+ pinctrl-names = "default";
+ };
+
+};
+
+&blsp_i2c3 {
+ status = "okay";
+
+ magnetometer@d {
+ compatible = "asahi-kasei,ak09911";
+ reg = <0x0d>;
+
+ vdd-supply = <&pm8916_l17>;
+ vid-supply = <&pm8916_l6>;
+
+ reset-gpios = <&tlmm 68 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&mag_reset_default>;
+ pinctrl-names = "default";
+ };
+
+ light-sensor@23 {
+ compatible = "liteon,ltr559";
+ reg = <0x23>;
+
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l5>;
+
+ interrupts-extended = <&tlmm 113 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&light_int_default>;
+ pinctrl-names = "default";
+ };
+
+ imu@68 {
+ compatible = "bosch,bmi160";
+ reg = <0x68>;
+
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l6>;
+ };
+};
+
+&blsp_i2c5 {
+ status = "okay";
+
+ touchscreen@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+
+ interrupts-extended = <&tlmm 13 IRQ_TYPE_LEVEL_LOW>;
+
+ reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
+
+ vdda-supply = <&pm8916_l6>;
+ vdd-supply = <&reg_ts_vdd>;
+
+ pinctrl-0 = <&ts_int_reset_default>;
+ pinctrl-names = "default";
+
+ /* Keys listed from right to left */
+ linux,keycodes = <KEY_APPSELECT KEY_HOMEPAGE KEY_BACK>;
+ };
+};
+
+&blsp_uart2 {
+ status = "okay";
+};
+
+&pm8916_mpps {
+ pwm_out: mpp4-state {
+ pins = "mpp4";
+ function = "digital";
+ power-source = <PM8916_MPP_VPH>;
+ output-low;
+ qcom,dtest = <1>;
+ };
+};
+
+&pm8916_pwm {
+ pinctrl-0 = <&pwm_out>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&pm8916_rpm_regulators {
+ pm8916_l17: l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+};
+
+&pm8916_vib {
+ status = "okay";
+};
+
+&sdhc_1 {
+ status = "okay";
+};
+
+&sdhc_2 {
+ pinctrl-0 = <&sdc2_default &sdc2_cd_default>;
+ pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>;
+ pinctrl-names = "default", "sleep";
+
+ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+
+ status = "okay";
+};
+
+&usb {
+ extcon = <&usb_id>, <&usb_id>;
+ status = "okay";
+};
+
+&usb_hs_phy {
+ extcon = <&usb_id>;
+};
+
+&wcnss {
+ status = "okay";
+};
+
+&wcnss_iris {
+ compatible = "qcom,wcn3620";
+};
+
+&tlmm {
+ button_backlight_default: button-backlight-default-state {
+ pins = "gpio17";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ camera_front_flash_default: camera-front-flash-default-state {
+ pins = "gpio8", "gpio49";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ gpio_hall_sensor_default: gpio-hall-sensor-default-state {
+ pins = "gpio20";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio107";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ lcd_bl_en_default: lcd-bl-en-default-state {
+ pins = "gpio98";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ light_int_default: light-int-default-state {
+ pins = "gpio113";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ mag_reset_default: mag-reset-default-state {
+ pins = "gpio68";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdc2_cd_default: sdc2-cd-default-state {
+ pins = "gpio38";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ ts_int_reset_default: ts-int-reset-default-state {
+ pins = "gpio12", "gpio13";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ ts_vdd_default: ts-vdd-default-state {
+ pins = "gpio78";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb_id_default: usb-id-default-state {
+ pins = "gpio110";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ usb_id_switch_default: usb-id-switch-default-state {
+ pins = "gpio121";
+ function = "gpio";
+ drive-strength = <2>;
+ output-high;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts b/arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts
index ba652909d162..fccd8fec8b8f 100644
--- a/arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts
+++ b/arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts
@@ -352,6 +352,10 @@
compatible = "qcom,wcn3660b";
};
+&wcnss_mem {
+ status = "okay";
+};
+
&tlmm {
accel_int_default: accel-int-default-state {
pins = "gpio115";
diff --git a/arch/arm64/boot/dts/qcom/msm8939-sony-xperia-kanuti-tulip.dts b/arch/arm64/boot/dts/qcom/msm8939-sony-xperia-kanuti-tulip.dts
index 89b6aebba404..eeb4d578c6fa 100644
--- a/arch/arm64/boot/dts/qcom/msm8939-sony-xperia-kanuti-tulip.dts
+++ b/arch/arm64/boot/dts/qcom/msm8939-sony-xperia-kanuti-tulip.dts
@@ -39,6 +39,10 @@
};
};
+&gpu {
+ status = "okay";
+};
+
&mdss {
status = "okay";
};
@@ -87,3 +91,7 @@
&wcnss_iris {
compatible = "qcom,wcn3660";
};
+
+&wcnss_mem {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8939.dtsi b/arch/arm64/boot/dts/qcom/msm8939.dtsi
index 6e24f0f2374f..324b5d26db40 100644
--- a/arch/arm64/boot/dts/qcom/msm8939.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8939.dtsi
@@ -346,23 +346,43 @@
};
mpss_mem: mpss@86800000 {
- reg = <0x0 0x86800000 0x0 0x5500000>;
+ /*
+ * The memory region for the mpss firmware is generally
+ * relocatable and could be allocated dynamically.
+ * However, many firmware versions tend to fail when
+ * loaded to some special addresses, so it is hard to
+ * define reliable alloc-ranges.
+ *
+ * alignment = <0x0 0x400000>;
+ * alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
+ */
+ reg = <0x0 0x86800000 0x0 0>; /* size is device-specific */
no-map;
+ status = "disabled";
};
- wcnss_mem: wcnss@8bd00000 {
- reg = <0x0 0x8bd00000 0x0 0x600000>;
+ wcnss_mem: wcnss {
+ size = <0x0 0x600000>;
+ alignment = <0x0 0x100000>;
+ alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
no-map;
+ status = "disabled";
};
- venus_mem: venus@8c300000 {
- reg = <0x0 0x8c300000 0x0 0x800000>;
+ venus_mem: venus {
+ size = <0x0 0x500000>;
+ alignment = <0x0 0x100000>;
+ alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
no-map;
+ status = "disabled";
};
- mba_mem: mba@8cb00000 {
- reg = <0x0 0x8cb00000 0x0 0x100000>;
+ mba_mem: mba {
+ size = <0x0 0x100000>;
+ alignment = <0x0 0x100000>;
+ alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
no-map;
+ status = "disabled";
};
};
@@ -1395,7 +1415,7 @@
};
};
- gpu@1c00000 {
+ gpu: gpu@1c00000 {
compatible = "qcom,adreno-405.0", "qcom,adreno";
reg = <0x01c00000 0x10000>;
reg-names = "kgsl_3d0_reg_memory";
@@ -1418,6 +1438,7 @@
power-domains = <&gcc OXILI_GDSC>;
operating-points-v2 = <&opp_table>;
iommus = <&gpu_iommu 1>, <&gpu_iommu 2>;
+ status = "disabled";
opp_table: opp-table {
compatible = "operating-points-v2";
@@ -1447,7 +1468,7 @@
apps_iommu: iommu@1ef0000 {
compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1";
reg = <0x01ef0000 0x3000>;
- ranges = <0 0x01e20000 0x40000>;
+ ranges = <0 0x01e20000 0x20000>;
clocks = <&gcc GCC_SMMU_CFG_CLK>,
<&gcc GCC_APSS_TCU_CLK>;
clock-names = "iface", "bus";
diff --git a/arch/arm64/boot/dts/qcom/msm8976.dtsi b/arch/arm64/boot/dts/qcom/msm8976.dtsi
index f9f5afbcc52b..d2bb1ada361a 100644
--- a/arch/arm64/boot/dts/qcom/msm8976.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8976.dtsi
@@ -338,7 +338,12 @@
};
lpass_mem: lpass@8c200000 {
- reg = <0x0 0x8c200000 0x0 0x1800000>;
+ reg = <0x0 0x8c200000 0x0 0x1000000>;
+ no-map;
+ };
+
+ wcnss_fw_mem: wcnss@8d200000 {
+ reg = <0x0 0x8d200000 0x0 0x800000>;
no-map;
};
@@ -379,7 +384,7 @@
smp2p-modem {
compatible = "qcom,smp2p";
interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 13>;
+ qcom,ipc = <&apcs 8 14>;
qcom,local-pid = <0>;
qcom,remote-pid = <1>;
@@ -402,7 +407,7 @@
smp2p-wcnss {
compatible = "qcom,smp2p";
interrupts = <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>;
- qcom,ipc = <&apcs 8 17>;
+ qcom,ipc = <&apcs 8 18>;
qcom,local-pid = <0>;
qcom,remote-pid = <4>;
@@ -428,9 +433,9 @@
#address-cells = <1>;
#size-cells = <0>;
- qcom,ipc-1 = <&apcs 8 12>;
+ qcom,ipc-1 = <&apcs 8 13>;
qcom,ipc-2 = <&apcs 8 9>;
- qcom,ipc-3 = <&apcs 8 18>;
+ qcom,ipc-3 = <&apcs 8 19>;
apps_smsm: apps@0 {
reg = <0>;
diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
index fcca1ba94da6..133f9c2540bc 100644
--- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
@@ -15,6 +15,7 @@
/delete-node/ &audio_mem;
/delete-node/ &mpss_mem;
/delete-node/ &peripheral_region;
+/delete-node/ &res_hyp_mem;
/delete-node/ &rmtfs_mem;
/ {
@@ -109,11 +110,6 @@
qcom,client-id = <1>;
};
- audio_mem: audio@cb400000 {
- reg = <0 0xcb000000 0 0x400000>;
- no-mem;
- };
-
qseecom_mem: qseecom@cb400000 {
reg = <0 0xcb400000 0 0x1c00000>;
no-mem;
diff --git a/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi b/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
index 2861bcdf87b7..cbc84459a5ae 100644
--- a/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
@@ -23,6 +23,7 @@
/delete-node/ &mba_mem;
/delete-node/ &mpss_mem;
/delete-node/ &peripheral_region;
+/delete-node/ &res_hyp_mem;
/delete-node/ &rmtfs_mem;
/delete-node/ &smem_mem;
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
index c3262571520d..8295bf1b219d 100644
--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
@@ -281,7 +281,7 @@
no-map;
};
- reserved@6c00000 {
+ res_hyp_mem: reserved@6c00000 {
reg = <0 0x06c00000 0 0x400000>;
no-map;
};
diff --git a/arch/arm64/boot/dts/qcom/msm8996-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/msm8996-oneplus-common.dtsi
index ec5457508fe6..38035e0db80b 100644
--- a/arch/arm64/boot/dts/qcom/msm8996-oneplus-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996-oneplus-common.dtsi
@@ -772,7 +772,6 @@
&ufsphy {
vdda-phy-supply = <&vreg_l28a_0p925>;
vdda-pll-supply = <&vreg_l12a_1p8>;
- vddp-ref-clk-supply = <&vreg_l25a_1p2>;
status = "okay";
};
@@ -781,6 +780,7 @@
vcc-supply = <&vreg_l20a_2p95>;
vccq-supply = <&vreg_l25a_1p2>;
vccq2-supply = <&vreg_s4a_1p8>;
+ vdd-hba-supply = <&vreg_l25a_1p2>;
vcc-max-microamp = <600000>;
vccq-max-microamp = <450000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi
index 06f8ff624181..5ab583be9e0a 100644
--- a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi
@@ -115,7 +115,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
/delete-node/ mba@91500000;
@@ -417,6 +417,7 @@
vcc-supply = <&vreg_l20a_2p95>;
vccq-supply = <&vreg_l25a_1p2>;
vccq2-supply = <&vreg_s4a_1p8>;
+ vdd-hba-supply = <&vreg_l25a_1p2>;
vcc-max-microamp = <600000>;
vccq-max-microamp = <450000>;
@@ -428,7 +429,6 @@
vdda-phy-supply = <&vreg_l28a_0p925>;
vdda-pll-supply = <&vreg_l12a_1p8>;
- vddp-ref-clk-supply = <&vreg_l25a_1p2>;
};
&venus {
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index c8e0986425ab..6ba9da9e6a8b 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -9,6 +9,7 @@
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/interconnect/qcom,msm8996.h>
#include <dt-bindings/interconnect/qcom,msm8996-cbf.h>
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/soc/qcom,apr.h>
@@ -538,7 +539,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
mpss_mem: mpss@88800000 {
diff --git a/arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts b/arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts
index b6a214bea70f..f1ceaedd9520 100644
--- a/arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts
+++ b/arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts
@@ -671,6 +671,7 @@
vcc-supply = <&vreg_l20a_2p95>;
vccq-supply = <&vreg_l26a_1p2>;
vccq2-supply = <&vreg_s4a_1p8>;
+ vdd-hba-supply = <&vreg_l26a_1p2>;
vcc-max-microamp = <750000>;
vccq-max-microamp = <560000>;
vccq2-max-microamp = <750000>;
@@ -680,7 +681,6 @@
status = "okay";
vdda-phy-supply = <&vreg_l1a_0p875>;
vdda-pll-supply = <&vreg_l2a_1p2>;
- vddp-ref-clk-supply = <&vreg_l26a_1p2>;
};
&usb3 {
diff --git a/arch/arm64/boot/dts/qcom/msm8998-mtp.dts b/arch/arm64/boot/dts/qcom/msm8998-mtp.dts
index 4319f4da8996..7c77612fb990 100644
--- a/arch/arm64/boot/dts/qcom/msm8998-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8998-mtp.dts
@@ -412,6 +412,7 @@
vcc-supply = <&vreg_l20a_2p95>;
vccq-supply = <&vreg_l26a_1p2>;
vccq2-supply = <&vreg_s4a_1p8>;
+ vdd-hba-supply = <&vreg_l26a_1p2>;
vcc-max-microamp = <750000>;
vccq-max-microamp = <560000>;
vccq2-max-microamp = <750000>;
@@ -421,7 +422,6 @@
status = "okay";
vdda-phy-supply = <&vreg_l1a_0p875>;
vdda-pll-supply = <&vreg_l2a_1p2>;
- vddp-ref-clk-supply = <&vreg_l26a_1p2>;
};
&usb3 {
diff --git a/arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi
index 68e634f8212c..e6a69d942a4a 100644
--- a/arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi
@@ -534,6 +534,7 @@
vcc-supply = <&vreg_l20a_2p95>;
vccq-supply = <&vreg_l26a_1p2>;
vccq2-supply = <&vreg_s4a_1p8>;
+ vdd-hba-supply = <&vreg_l26a_1p2>;
vcc-max-microamp = <750000>;
vccq-max-microamp = <560000>;
vccq2-max-microamp = <750000>;
@@ -544,7 +545,6 @@
vdda-phy-supply = <&vreg_l1a_0p875>;
vdda-pll-supply = <&vreg_l2a_1p2>;
- vddp-ref-clk-supply = <&vreg_l26a_1p2>;
};
&usb3 {
diff --git a/arch/arm64/boot/dts/qcom/msm8998-xiaomi-sagit.dts b/arch/arm64/boot/dts/qcom/msm8998-xiaomi-sagit.dts
index 437b30cc8bdc..0cac06f25a77 100644
--- a/arch/arm64/boot/dts/qcom/msm8998-xiaomi-sagit.dts
+++ b/arch/arm64/boot/dts/qcom/msm8998-xiaomi-sagit.dts
@@ -667,6 +667,7 @@
vcc-supply = <&vreg_l20a_2p95>;
vccq-supply = <&vreg_l26a_1p2>;
vccq2-supply = <&vreg_s4a_1p8>;
+ vdd-hba-supply = <&vreg_l26a_1p2>;
vcc-max-microamp = <750000>;
vccq-max-microamp = <560000>;
vccq2-max-microamp = <750000>;
@@ -676,7 +677,6 @@
&ufsphy {
vdda-phy-supply = <&vreg_l1a_0p875>;
vdda-pll-supply = <&vreg_l2a_1p2>;
- vddp-ref-clk-supply = <&vreg_l26a_1p2>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
index f180047cacb0..b485bf925ce6 100644
--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/clock/qcom,gpucc-msm8998.h>
#include <dt-bindings/clock/qcom,mmcc-msm8998.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/gpio/gpio.h>
@@ -56,7 +57,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
spss_mem: memory@8ab00000 {
@@ -945,7 +946,7 @@
#address-cells = <3>;
#size-cells = <2>;
num-lanes = <1>;
- phys = <&pciephy>;
+ phys = <&pcie_phy>;
phy-names = "pciephy";
status = "disabled";
@@ -975,32 +976,28 @@
pcie_phy: phy@1c06000 {
compatible = "qcom,msm8998-qmp-pcie-phy";
- reg = <0x01c06000 0x18c>;
- #address-cells = <1>;
- #size-cells = <1>;
+ reg = <0x01c06000 0x1000>;
status = "disabled";
- ranges;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
- <&gcc GCC_PCIE_CLKREF_CLK>;
- clock-names = "aux", "cfg_ahb", "ref";
+ <&gcc GCC_PCIE_CLKREF_CLK>,
+ <&gcc GCC_PCIE_0_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "pipe";
+
+ clock-output-names = "pcie_0_pipe_clk_src";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_0_PHY_BCR>, <&gcc GCC_PCIE_PHY_BCR>;
reset-names = "phy", "common";
vdda-phy-supply = <&vreg_l1a_0p875>;
vdda-pll-supply = <&vreg_l2a_1p2>;
-
- pciephy: phy@1c06800 {
- reg = <0x01c06200 0x128>, <0x01c06400 0x1fc>, <0x01c06800 0x20c>;
- #phy-cells = <0>;
-
- clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "pcie_0_pipe_clk_src";
- #clock-cells = <0>;
- };
};
ufshc: ufshc@1da4000 {
diff --git a/arch/arm64/boot/dts/qcom/pm6150.dtsi b/arch/arm64/boot/dts/qcom/pm6150.dtsi
index 7d4d1f2767ed..ddbaf7280b03 100644
--- a/arch/arm64/boot/dts/qcom/pm6150.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm6150.dtsi
@@ -53,6 +53,14 @@
bias-pull-up;
linux,code = <KEY_POWER>;
};
+
+ pm6150_resin: resin {
+ compatible = "qcom,pm8941-resin";
+ interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+ debounce = <15625>;
+ bias-pull-up;
+ status = "disabled";
+ };
};
pm6150_temp: temp-alarm@2400 {
@@ -88,6 +96,14 @@
status = "disabled";
};
+ pm6150_rtc: rtc@6000 {
+ compatible = "qcom,pm8941-rtc";
+ reg = <0x6000>, <0x6100>;
+ reg-names = "rtc", "alarm";
+ interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
pm6150_gpios: gpio@c000 {
compatible = "qcom,pm6150-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
diff --git a/arch/arm64/boot/dts/qcom/pm7250b.dtsi b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
index e8540c36bd99..df0afe82f250 100644
--- a/arch/arm64/boot/dts/qcom/pm7250b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
@@ -39,16 +39,16 @@
};
&spmi_bus {
- pmic@2 {
+ pmic@PM7250B_SID {
compatible = "qcom,pm7250b", "qcom,spmi-pmic";
- reg = <0x2 SPMI_USID>;
+ reg = <PM7250B_SID SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pm7250b_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
- interrupts = <0x2 0x24 0x0 IRQ_TYPE_EDGE_BOTH>;
+ interrupts = <PM7250B_SID 0x24 0x0 IRQ_TYPE_EDGE_BOTH>;
io-channels = <&pm7250b_adc ADC5_DIE_TEMP>;
io-channel-names = "thermal";
#thermal-sensor-cells = <0>;
@@ -60,7 +60,7 @@
#address-cells = <1>;
#size-cells = <0>;
#io-channel-cells = <1>;
- interrupts = <0x2 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <PM7250B_SID 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
channel@0 {
reg = <ADC5_REF_GND>;
@@ -141,7 +141,7 @@
pm7250b_adc_tm: adc-tm@3500 {
compatible = "qcom,spmi-adc-tm5";
reg = <0x3500>;
- interrupts = <0x2 0x35 0x0 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <PM7250B_SID 0x35 0x0 IRQ_TYPE_EDGE_RISING>;
#thermal-sensor-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
@@ -159,9 +159,9 @@
};
};
- pmic@3 {
+ pmic@PM7250B_SID1 {
compatible = "qcom,pm7250b", "qcom,spmi-pmic";
- reg = <0x3 SPMI_USID>;
+ reg = <PM7250B_SID1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
};
diff --git a/arch/arm64/boot/dts/qcom/pm8150b.dtsi b/arch/arm64/boot/dts/qcom/pm8150b.dtsi
index 2b9123df5847..1aee3270ce7b 100644
--- a/arch/arm64/boot/dts/qcom/pm8150b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8150b.dtsi
@@ -59,6 +59,46 @@
reg = <0x1100>;
};
+ pm8150b_typec: typec@1500 {
+ compatible = "qcom,pm8150b-typec";
+ status = "disabled";
+ reg = <0x1500>,
+ <0x1700>;
+ interrupts = <0x2 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
+ <0x2 0x15 0x02 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x15 0x03 IRQ_TYPE_EDGE_BOTH>,
+ <0x2 0x15 0x04 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x15 0x05 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x15 0x06 IRQ_TYPE_EDGE_BOTH>,
+ <0x2 0x15 0x07 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x17 0x00 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x17 0x01 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x17 0x02 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x17 0x03 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x17 0x04 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x17 0x05 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x17 0x06 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x17 0x07 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "or-rid-detect-change",
+ "vpd-detect",
+ "cc-state-change",
+ "vconn-oc",
+ "vbus-change",
+ "attach-detach",
+ "legacy-cable-detect",
+ "try-snk-src-detect",
+ "sig-tx",
+ "sig-rx",
+ "msg-tx",
+ "msg-rx",
+ "msg-tx-failed",
+ "msg-tx-discarded",
+ "msg-rx-discarded",
+ "fr-swap";
+ vdd-vbus-supply = <&pm8150b_vbus>;
+ };
+
pm8150b_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
diff --git a/arch/arm64/boot/dts/qcom/pm8150l.dtsi b/arch/arm64/boot/dts/qcom/pm8150l.dtsi
index b1686e5777b8..ac08a09c64c2 100644
--- a/arch/arm64/boot/dts/qcom/pm8150l.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8150l.dtsi
@@ -132,5 +132,15 @@
status = "disabled";
};
+ pm8150l_wled: leds@d800 {
+ compatible = "qcom,pm8150l-wled";
+ reg = <0xd800>, <0xd900>;
+ interrupts = <0x5 0xd8 0x1 IRQ_TYPE_EDGE_RISING>,
+ <0x5 0xd8 0x2 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "ovp", "short";
+ label = "backlight";
+
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/pm8350c.dtsi b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
index f28e71487d5c..aa74e21fe0dc 100644
--- a/arch/arm64/boot/dts/qcom/pm8350c.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
@@ -30,6 +30,12 @@
#interrupt-cells = <2>;
};
+ pm8350c_flash: led-controller@ee00 {
+ compatible = "qcom,pm8350c-flash-led", "qcom,spmi-flash-led";
+ reg = <0xee00>;
+ status = "disabled";
+ };
+
pm8350c_pwm: pwm {
compatible = "qcom,pm8350c-pwm";
#pwm-cells = <2>;
diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi
index 223442f909f1..f4de86787743 100644
--- a/arch/arm64/boot/dts/qcom/pm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi
@@ -142,9 +142,6 @@
pm8916_codec: audio-codec@f000 {
compatible = "qcom,pm8916-wcd-analog-codec";
reg = <0xf000>;
- reg-names = "pmic-codec-core";
- clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
- clock-names = "mclk";
interrupt-parent = <&spmi_bus>;
interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
<0x1 0xf0 0x1 IRQ_TYPE_NONE>,
diff --git a/arch/arm64/boot/dts/qcom/pmr735d.dtsi b/arch/arm64/boot/dts/qcom/pmr735d_a.dtsi
index 41fb664a10b3..37daaefe3431 100644
--- a/arch/arm64/boot/dts/qcom/pmr735d.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmr735d_a.dtsi
@@ -28,27 +28,6 @@
};
};
};
-
- pmr735d-l-thermal {
- polling-delay-passive = <100>;
- polling-delay = <0>;
-
- thermal-sensors = <&pmr735d_l_temp_alarm>;
-
- trips {
- trip0 {
- temperature = <95000>;
- hysteresis = <0>;
- type = "passive";
- };
-
- trip1 {
- temperature = <115000>;
- hysteresis = <0>;
- type = "hot";
- };
- };
- };
};
};
@@ -77,28 +56,4 @@
#interrupt-cells = <2>;
};
};
-
- pmr735d_l: pmic@b {
- compatible = "qcom,pmr735d", "qcom,spmi-pmic";
- reg = <0xb SPMI_USID>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- pmr735d_l_temp_alarm: temp-alarm@a00 {
- compatible = "qcom,spmi-temp-alarm";
- reg = <0xa00>;
- interrupts = <0xb 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
- #thermal-sensor-cells = <0>;
- };
-
- pmr735d_l_gpios: gpio@8800 {
- compatible = "qcom,pmr735d-gpio", "qcom,spmi-gpio";
- reg = <0x8800>;
- gpio-controller;
- gpio-ranges = <&pmr735d_l_gpios 0 0 2>;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
- };
};
diff --git a/arch/arm64/boot/dts/qcom/pmr735d_b.dtsi b/arch/arm64/boot/dts/qcom/pmr735d_b.dtsi
new file mode 100644
index 000000000000..3b470f6ac46f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pmr735d_b.dtsi
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+ thermal-zones {
+ pmr735d-l-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&pmr735d_l_temp_alarm>;
+
+ trips {
+ trip0 {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+
+ trip1 {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "hot";
+ };
+ };
+ };
+ };
+};
+
+
+&spmi_bus {
+ pmr735d_l: pmic@b {
+ compatible = "qcom,pmr735d", "qcom,spmi-pmic";
+ reg = <0xb SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmr735d_l_temp_alarm: temp-alarm@a00 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0xa00>;
+ interrupts = <0xb 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ pmr735d_l_gpios: gpio@8800 {
+ compatible = "qcom,pmr735d-gpio", "qcom,spmi-gpio";
+ reg = <0x8800>;
+ gpio-controller;
+ gpio-ranges = <&pmr735d_l_gpios 0 0 2>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
new file mode 100644
index 000000000000..2de0b8c26c35
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
@@ -0,0 +1,667 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023, Luca Weiss <luca.weiss@fairphone.com>
+ */
+
+/dts-v1/;
+
+/* PM7250B is configured to use SID8/9 */
+#define PM7250B_SID 8
+#define PM7250B_SID1 9
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sc7280.dtsi"
+#include "pm7250b.dtsi"
+#include "pm7325.dtsi"
+#include "pm8350c.dtsi" /* PM7350C */
+#include "pmk8350.dtsi" /* PMK7325 */
+
+/delete-node/ &rmtfs_mem;
+
+/ {
+ model = "Fairphone 5";
+ compatible = "fairphone,fp5", "qcom,qcm6490";
+ chassis-type = "handset";
+
+ aliases {
+ serial0 = &uart5;
+ serial1 = &uart7;
+ };
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ framebuffer0: framebuffer@a000000 {
+ compatible = "simple-framebuffer";
+ reg = <0x0 0xe1000000 0x0 (2700 * 1224 * 4)>;
+ width = <1224>;
+ height = <2700>;
+ stride = <(1224 * 4)>;
+ format = "a8r8g8b8";
+ clocks = <&gcc GCC_DISP_HF_AXI_CLK>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&volume_down_default>, <&hall_sensor_default>;
+ pinctrl-names = "default";
+
+ key-volume-up {
+ label = "Volume up";
+ gpios = <&pm7325_gpios 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ /* Powered by the always-on vreg_l8c */
+ event-hall-sensor {
+ label = "Hall Effect Sensor";
+ gpios = <&tlmm 155 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ linux,can-disable;
+ wakeup-source;
+ };
+ };
+
+ reserved-memory {
+ cont_splash_mem: cont-splash@e1000000 {
+ reg = <0x0 0xe1000000 0x0 0x2300000>;
+ no-map;
+ };
+
+ adsp_mem: adsp@86700000 {
+ reg = <0x0 0x86700000 0x0 0x2800000>;
+ no-map;
+ };
+
+ cdsp_mem: cdsp@88f00000 {
+ reg = <0x0 0x88f00000 0x0 0x1e00000>;
+ no-map;
+ };
+
+ mpss_mem: mpss@8b800000 {
+ reg = <0x0 0x8b800000 0x0 0xf600000>;
+ no-map;
+ };
+
+ wpss_mem: wpss@9ae00000 {
+ reg = <0x0 0x9ae00000 0x0 0x1900000>;
+ no-map;
+ };
+
+ rmtfs_mem: memory@f8500000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0 0xf8500000 0x0 0x600000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>, <QCOM_SCM_VMID_NAV>;
+ };
+ };
+
+ ois_avdd0_1p8: regulator-ois-avdd0-1p8 {
+ compatible = "regulator-fixed";
+ regulator-name = "OIS_AVDD0_1P8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&tlmm 157 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vreg_bob>;
+ };
+
+ ois_dvdd_1p1: regulator-ois-dvdd-1p1 {
+ compatible = "regulator-fixed";
+ regulator-name = "OIS_DVDD_1P1";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ gpio = <&tlmm 97 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vreg_s8b>;
+ };
+
+ afvdd_2p8: regulator-afvdd-2p8 {
+ compatible = "regulator-fixed";
+ regulator-name = "AFVDD_2P8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ gpio = <&tlmm 68 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vreg_bob>;
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm7325-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vreg_s1b: smps1 {
+ regulator-min-microvolt = <1840000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ vreg_s7b: smps7 {
+ regulator-min-microvolt = <535000>;
+ regulator-max-microvolt = <1120000>;
+ };
+
+ vreg_s8b: smps8 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>;
+ };
+
+ vreg_l1b: ldo1 {
+ regulator-min-microvolt = <825000>;
+ regulator-max-microvolt = <925000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b: ldo2 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3b: ldo3 {
+ regulator-min-microvolt = <312000>;
+ regulator-max-microvolt = <910000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6b: ldo6 {
+ regulator-min-microvolt = <1140000>;
+ regulator-max-microvolt = <1260000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7b: ldo7 {
+ regulator-min-microvolt = <2400000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8b: ldo8 {
+ regulator-min-microvolt = <870000>;
+ regulator-max-microvolt = <970000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9b: ldo9 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11b: ldo11 {
+ regulator-min-microvolt = <1504000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12b: ldo12 {
+ regulator-min-microvolt = <751000>;
+ regulator-max-microvolt = <824000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13b: ldo13 {
+ regulator-min-microvolt = <530000>;
+ regulator-max-microvolt = <824000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14b: ldo14 {
+ regulator-min-microvolt = <1080000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15b: ldo15 {
+ regulator-min-microvolt = <765000>;
+ regulator-max-microvolt = <1020000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l16b: ldo16 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17b: ldo17 {
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <1900000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l18b: ldo18 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l19b: ldo19 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8350c-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vreg_s1c: smps1 {
+ regulator-min-microvolt = <2190000>;
+ regulator-max-microvolt = <2210000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s9c: smps9 {
+ regulator-min-microvolt = <1010000>;
+ regulator-max-microvolt = <1170000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1c: ldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2c: ldo2 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c: ldo3 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4c: ldo4 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5c: ldo5 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6c: ldo6 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c: ldo7 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8c: ldo8 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ /* Hall sensor VDD */
+ regulator-always-on;
+ };
+
+ vreg_l9c: ldo9 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10c: ldo10 {
+ regulator-min-microvolt = <720000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11c: ldo11 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12c: ldo12 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13c: ldo13 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob: bob {
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ };
+ };
+};
+
+&dispcc {
+ /* Disable for now so simple-framebuffer continues working */
+ status = "disabled";
+};
+
+&gcc {
+ protected-clocks = <GCC_CFG_NOC_LPASS_CLK>,
+ <GCC_EDP_CLKREF_EN>,
+ <GCC_MSS_CFG_AHB_CLK>,
+ <GCC_MSS_GPLL0_MAIN_DIV_CLK_SRC>,
+ <GCC_MSS_OFFLINE_AXI_CLK>,
+ <GCC_MSS_Q6SS_BOOT_CLK_SRC>,
+ <GCC_MSS_Q6_MEMNOC_AXI_CLK>,
+ <GCC_MSS_SNOC_AXI_CLK>,
+ <GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
+ <GCC_QSPI_CORE_CLK>,
+ <GCC_QSPI_CORE_CLK_SRC>,
+ <GCC_SEC_CTRL_CLK_SRC>,
+ <GCC_WPSS_AHB_BDG_MST_CLK>,
+ <GCC_WPSS_AHB_CLK>,
+ <GCC_WPSS_RSCP_CLK>;
+};
+
+&gpi_dma0 {
+ status = "okay";
+};
+
+&gpi_dma1 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+
+ /* PM8008 PMIC @ 8 and 9 */
+ /* Pixelworks @ 26 */
+ /* FSA4480 USB audio switch @ 42 */
+ /* AW86927FCR haptics @ 5a */
+};
+
+&i2c2 {
+ status = "okay";
+
+ /* AW88261FCR amplifier @ 34 */
+ /* AW88261FCR amplifier @ 35 */
+};
+
+&i2c4 {
+ status = "okay";
+
+ /* PTN36502 USB redriver @ 1a */
+};
+
+&i2c9 {
+ status = "okay";
+
+ /* ST21NFC NFC @ 28 */
+ /* VL53L3 ToF @ 29 */
+};
+
+&ipa {
+ qcom,gsi-loader = "self";
+ memory-region = <&ipa_fw_mem>;
+ firmware-name = "qcom/qcm6490/fairphone5/ipa_fws.mdt";
+ status = "okay";
+};
+
+&pm7325_gpios {
+ volume_down_default: volume-down-default-state {
+ pins = "gpio6";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+};
+
+&pm8350c_flash {
+ status = "okay";
+
+ led-0 {
+ function = LED_FUNCTION_FLASH;
+ color = <LED_COLOR_ID_WHITE>;
+ led-sources = <1>, <4>;
+ led-max-microamp = <500000>;
+ flash-max-microamp = <1500000>;
+ flash-max-timeout-us = <1280000>;
+ };
+};
+
+&pmk8350_rtc {
+ status = "okay";
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&qup_spi13_cs {
+ drive-strength = <6>;
+ bias-disable;
+};
+
+&qup_spi13_data_clk {
+ drive-strength = <6>;
+ bias-disable;
+};
+
+&qup_uart5_rx {
+ drive-strength = <2>;
+ bias-disable;
+};
+
+&qup_uart5_tx {
+ drive-strength = <2>;
+ bias-disable;
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&sdc2_clk {
+ drive-strength = <16>;
+ bias-disable;
+};
+
+&sdc2_cmd {
+ drive-strength = <10>;
+ bias-pull-up;
+};
+
+&sdc2_data {
+ drive-strength = <10>;
+ bias-pull-up;
+};
+
+&sdhc_2 {
+ vmmc-supply = <&vreg_l9c>;
+ vqmmc-supply = <&vreg_l6c>;
+
+ pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>;
+ pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>;
+
+ status = "okay";
+};
+
+&spi13 {
+ status = "okay";
+
+ /* Goodix touchscreen @ 0 */
+};
+
+&tlmm {
+ /*
+ * 32-33: SMB1394 (SPMI)
+ * 56-59: fingerprint reader (SPI)
+ */
+ gpio-reserved-ranges = <32 2>, <56 4>;
+
+ bluetooth_enable_default: bluetooth-enable-default-state {
+ pins = "gpio85";
+ function = "gpio";
+ output-low;
+ bias-disable;
+ };
+
+ hall_sensor_default: hall-sensor-default-state {
+ pins = "gpio155";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_uart7_sleep_cts: qup-uart7-sleep-cts-state {
+ pins = "gpio28";
+ function = "gpio";
+ /*
+ * Configure a bias-bus-hold on CTS to lower power
+ * usage when Bluetooth is turned off. Bus hold will
+ * maintain a low power state regardless of whether
+ * the Bluetooth module drives the pin in either
+ * direction or leaves the pin fully unpowered.
+ */
+ bias-bus-hold;
+ };
+
+ qup_uart7_sleep_rts: qup-uart7-sleep-rts-state {
+ pins = "gpio29";
+ function = "gpio";
+ /*
+ * Configure pull-down on RTS. As RTS is active low
+ * signal, pull it low to indicate the BT SoC that it
+ * can wakeup the system anytime from suspend state by
+ * pulling RX low (by sending wakeup bytes).
+ */
+ bias-pull-down;
+ };
+
+ qup_uart7_sleep_tx: qup-uart7-sleep-tx-state {
+ pins = "gpio30";
+ function = "gpio";
+ /*
+ * Configure pull-up on TX when it isn't actively driven
+ * to prevent BT SoC from receiving garbage during sleep.
+ */
+ bias-pull-up;
+ };
+
+ qup_uart7_sleep_rx: qup-uart7-sleep-rx-state {
+ pins = "gpio31";
+ function = "gpio";
+ /*
+ * Configure a pull-up on RX. This is needed to avoid
+ * garbage data when the TX pin of the Bluetooth module
+ * is floating which may cause spurious wakeups.
+ */
+ bias-pull-up;
+ };
+
+ sw_ctrl_default: sw-ctrl-default-state {
+ pins = "gpio86";
+ function = "gpio";
+ bias-pull-down;
+ };
+};
+
+&uart5 {
+ compatible = "qcom,geni-debug-uart";
+ status = "okay";
+};
+
+&uart7 {
+ /delete-property/interrupts;
+ interrupts-extended = <&intc GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>,
+ <&tlmm 31 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-1 = <&qup_uart7_sleep_cts>, <&qup_uart7_sleep_rts>, <&qup_uart7_sleep_tx>, <&qup_uart7_sleep_rx>;
+ pinctrl-names = "default", "sleep";
+
+ status = "okay";
+
+ bluetooth: bluetooth {
+ compatible = "qcom,wcn6750-bt";
+
+ pinctrl-0 = <&bluetooth_enable_default>, <&sw_ctrl_default>;
+ pinctrl-names = "default";
+
+ enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>;
+ swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+
+ vddio-supply = <&vreg_l19b>;
+ vddaon-supply = <&vreg_s7b>;
+ vddbtcxmx-supply = <&vreg_s7b>;
+ vddrfacmn-supply = <&vreg_s7b>;
+ vddrfa0p8-supply = <&vreg_s7b>;
+ vddrfa1p7-supply = <&vreg_s1b>;
+ vddrfa1p2-supply = <&vreg_s8b>;
+ vddrfa2p2-supply = <&vreg_s1c>;
+ vddasd-supply = <&vreg_l11c>;
+
+ max-speed = <3200000>;
+ };
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&usb_1_hsphy {
+ vdda-pll-supply = <&vreg_l10c>;
+ vdda18-supply = <&vreg_l1c>;
+ vdda33-supply = <&vreg_l2b>;
+
+ qcom,hs-crossover-voltage-microvolt = <28000>;
+ qcom,hs-output-impedance-micro-ohms = <2600000>;
+ qcom,hs-rise-fall-time-bp = <5430>;
+ qcom,hs-disconnect-bp = <1743>;
+ qcom,hs-amplitude-bp = <2430>;
+
+ qcom,pre-emphasis-amplitude-bp = <20000>;
+ qcom,pre-emphasis-duration-bp = <20000>;
+
+ qcom,squelch-detector-bp = <(-2090)>;
+
+ status = "okay";
+};
+
+&usb_1_qmpphy {
+ vdda-phy-supply = <&vreg_l6b>;
+ vdda-pll-supply = <&vreg_l1b>;
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
index eadba066972e..94885b9c21c8 100644
--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
+++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
@@ -5,6 +5,7 @@
/dts-v1/;
+#include <dt-bindings/leds/common.h>
#include "qcm2290.dtsi"
#include "pm2250.dtsi"
@@ -13,7 +14,7 @@
compatible = "qcom,qrb2210-rb1", "qcom,qrb2210", "qcom,qcm2290";
aliases {
- serial0 = &uart0;
+ serial0 = &uart4;
sdhc1 = &sdhc_1;
sdhc2 = &sdhc_2;
};
@@ -39,6 +40,38 @@
};
};
+ leds {
+ compatible = "gpio-leds";
+
+ led-bt {
+ label = "blue:bt";
+ function = LED_FUNCTION_BLUETOOTH;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&tlmm 45 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "bluetooth-power";
+ default-state = "off";
+ };
+
+ led-user0 {
+ label = "green:user0";
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&tlmm 52 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "none";
+ default-state = "off";
+ panic-indicator;
+ };
+
+ led-wlan {
+ label = "yellow:wlan";
+ function = LED_FUNCTION_WLAN;
+ color = <LED_COLOR_ID_YELLOW>;
+ gpios = <&tlmm 47 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "phy0tx";
+ default-state = "off";
+ };
+ };
+
vreg_hdmi_out_1p2: regulator-hdmi-out-1p2 {
compatible = "regulator-fixed";
regulator-name = "VREG_HDMI_OUT_1P2";
@@ -134,6 +167,16 @@
status = "okay";
};
+&remoteproc_adsp {
+ firmware-name = "qcom/qcm2290/adsp.mbn";
+ status = "okay";
+};
+
+&remoteproc_mpss {
+ firmware-name = "qcom/qcm2290/modem.mbn";
+ status = "okay";
+};
+
&rpm_requests {
regulators {
compatible = "qcom,rpm-pm2250-regulators";
@@ -150,15 +193,15 @@
pm2250_s3: s3 {
/* 0.4V-1.6625V -> 1.3V (Power tree requirements) */
- regulator-min-microvolts = <1350000>;
- regulator-max-microvolts = <1350000>;
+ regulator-min-microvolt = <1352000>;
+ regulator-max-microvolt = <1352000>;
regulator-boot-on;
};
pm2250_s4: s4 {
/* 1.2V-2.35V -> 2.05V (Power tree requirements) */
- regulator-min-microvolts = <2072000>;
- regulator-max-microvolts = <2072000>;
+ regulator-min-microvolt = <2072000>;
+ regulator-max-microvolt = <2072000>;
regulator-boot-on;
};
@@ -166,47 +209,47 @@
pm2250_l2: l2 {
/* LPDDR4X VDD2 */
- regulator-min-microvolts = <1136000>;
- regulator-max-microvolts = <1136000>;
+ regulator-min-microvolt = <1136000>;
+ regulator-max-microvolt = <1136000>;
regulator-always-on;
regulator-boot-on;
};
pm2250_l3: l3 {
/* LPDDR4X VDDQ */
- regulator-min-microvolts = <616000>;
- regulator-max-microvolts = <616000>;
+ regulator-min-microvolt = <616000>;
+ regulator-max-microvolt = <616000>;
regulator-always-on;
regulator-boot-on;
};
pm2250_l4: l4 {
- /* max = 3.05V -> max = just below 3V (SDHCI2) */
- regulator-min-microvolts = <1648000>;
- regulator-max-microvolts = <2992000>;
+ /* max = 3.05V -> max = 2.7 to disable 3V signaling (SDHCI2) */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2700000>;
regulator-allow-set-load;
};
pm2250_l5: l5 {
/* CSI/DSI */
- regulator-min-microvolts = <1232000>;
- regulator-max-microvolts = <1232000>;
+ regulator-min-microvolt = <1232000>;
+ regulator-max-microvolt = <1232000>;
regulator-allow-set-load;
regulator-boot-on;
};
pm2250_l6: l6 {
/* DRAM PLL */
- regulator-min-microvolts = <928000>;
- regulator-max-microvolts = <928000>;
+ regulator-min-microvolt = <928000>;
+ regulator-max-microvolt = <928000>;
regulator-always-on;
regulator-boot-on;
};
pm2250_l7: l7 {
/* Wi-Fi CX/MX */
- regulator-min-microvolts = <664000>;
- regulator-max-microvolts = <664000>;
+ regulator-min-microvolt = <664000>;
+ regulator-max-microvolt = <664000>;
};
/*
@@ -216,37 +259,37 @@
pm2250_l10: l10 {
/* Wi-Fi RFA */
- regulator-min-microvolts = <1300000>;
- regulator-max-microvolts = <1300000>;
+ regulator-min-microvolt = <1304000>;
+ regulator-max-microvolt = <1304000>;
};
pm2250_l11: l11 {
/* GPS RF1 */
- regulator-min-microvolts = <1000000>;
- regulator-max-microvolts = <1000000>;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
regulator-boot-on;
};
pm2250_l12: l12 {
/* USB PHYs */
- regulator-min-microvolts = <928000>;
- regulator-max-microvolts = <928000>;
+ regulator-min-microvolt = <928000>;
+ regulator-max-microvolt = <928000>;
regulator-allow-set-load;
regulator-boot-on;
};
pm2250_l13: l13 {
/* USB/QFPROM/PLLs */
- regulator-min-microvolts = <1800000>;
- regulator-max-microvolts = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
regulator-allow-set-load;
regulator-boot-on;
};
pm2250_l14: l14 {
/* SDHCI1 VQMMC */
- regulator-min-microvolts = <1800000>;
- regulator-max-microvolts = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
regulator-allow-set-load;
/* Broken hardware, never turn it off! */
regulator-always-on;
@@ -254,8 +297,8 @@
pm2250_l15: l15 {
/* WCD/DSI/BT VDDIO */
- regulator-min-microvolts = <1800000>;
- regulator-max-microvolts = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
regulator-allow-set-load;
regulator-always-on;
regulator-boot-on;
@@ -263,47 +306,47 @@
pm2250_l16: l16 {
/* GPS RF2 */
- regulator-min-microvolts = <1800000>;
- regulator-max-microvolts = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
regulator-boot-on;
};
pm2250_l17: l17 {
- regulator-min-microvolts = <3000000>;
- regulator-max-microvolts = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
};
pm2250_l18: l18 {
/* VDD_PXn */
- regulator-min-microvolts = <1800000>;
- regulator-max-microvolts = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
};
pm2250_l19: l19 {
/* VDD_PXn */
- regulator-min-microvolts = <1800000>;
- regulator-max-microvolts = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
};
pm2250_l20: l20 {
/* SDHCI1 VMMC */
- regulator-min-microvolts = <2856000>;
- regulator-max-microvolts = <2856000>;
+ regulator-min-microvolt = <2400000>;
+ regulator-max-microvolt = <3600000>;
regulator-allow-set-load;
};
pm2250_l21: l21 {
/* SDHCI2 VMMC */
- regulator-min-microvolts = <2960000>;
- regulator-max-microvolts = <3300000>;
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <3300000>;
regulator-allow-set-load;
regulator-boot-on;
};
pm2250_l22: l22 {
/* Wi-Fi */
- regulator-min-microvolts = <3312000>;
- regulator-max-microvolts = <3312000>;
+ regulator-min-microvolt = <3312000>;
+ regulator-max-microvolt = <3312000>;
};
};
};
@@ -357,7 +400,7 @@
};
/* UART connected to the Micro-USB port via a FTDI chip */
-&uart0 {
+&uart4 {
compatible = "qcom,geni-debug-uart";
status = "okay";
};
@@ -366,6 +409,12 @@
status = "okay";
};
+&usb_qmpphy {
+ vdda-phy-supply = <&pm2250_l12>;
+ vdda-pll-supply = <&pm2250_l13>;
+ status = "okay";
+};
+
&usb_hsphy {
vdd-supply = <&pm2250_l12>;
vdda-pll-supply = <&pm2250_l13>;
@@ -373,6 +422,14 @@
status = "okay";
};
+&wifi {
+ vdd-0.8-cx-mx-supply = <&pm2250_l7>;
+ vdd-1.8-xo-supply = <&pm2250_l13>;
+ vdd-1.3-rfa-supply = <&pm2250_l10>;
+ vdd-3.3-ch0-supply = <&pm2250_l22>;
+ status = "okay";
+};
+
&xo_board {
clock-frequency = <38400000>;
};
diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index dfa8ee5c75af..c8cd40a462a3 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -9,6 +9,7 @@
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include <dt-bindings/sound/qcom,q6afe.h>
#include <dt-bindings/sound/qcom,q6asm.h>
+#include <dt-bindings/usb/pd.h>
#include "sm8250.dtsi"
#include "pm8150.dtsi"
#include "pm8150b.dtsi"
@@ -609,12 +610,61 @@
/* LS-I2C1 */
&i2c15 {
status = "okay";
+
+ typec-mux@1c {
+ compatible = "onnn,nb7vpq904m";
+ reg = <0x1c>;
+
+ vcc-supply = <&vreg_s4a_1p8>;
+
+ retimer-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ redriver_usb_con_ss: endpoint {
+ remote-endpoint = <&pm8150b_typec_mux_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ redriver_phy_con_ss: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_out>;
+ data-lanes = <0 1 2 3>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ redriver_usb_con_sbu: endpoint {
+ remote-endpoint = <&pm8150b_typec_sbu_out>;
+ };
+ };
+ };
+ };
};
&mdss {
status = "okay";
};
+&mdss_dp {
+ status = "okay";
+};
+
+&mdss_dp_out {
+ data-lanes = <0 1>;
+ remote-endpoint = <&usb_1_qmpphy_dp_in>;
+};
+
&mdss_dsi0 {
status = "okay";
vdda-supply = <&vreg_l9a_1p2>;
@@ -1273,7 +1323,12 @@
};
&usb_1_dwc3 {
- dr_mode = "peripheral";
+ dr_mode = "otg";
+ usb-role-switch;
+};
+
+&usb_1_role_switch_out {
+ remote-endpoint = <&pm8150b_role_switch_in>;
};
&usb_1_hsphy {
@@ -1289,6 +1344,11 @@
vdda-phy-supply = <&vreg_l9a_1p2>;
vdda-pll-supply = <&vreg_l18a_0p92>;
+ orientation-switch;
+};
+
+&usb_1_qmpphy_out {
+ remote-endpoint = <&redriver_phy_con_ss>;
};
&usb_2 {
@@ -1339,3 +1399,66 @@
drive-strength = <6>;
bias-disable;
};
+
+&pm8150b_vbus {
+ regulator-min-microamp = <500000>;
+ regulator-max-microamp = <3000000>;
+ status = "okay";
+};
+
+&pm8150b_typec {
+ status = "okay";
+
+ vdd-pdphy-supply = <&vreg_l2a_3p1>;
+
+ connector {
+ compatible = "usb-c-connector";
+
+ power-role = "source";
+ data-role = "dual";
+ self-powered;
+
+ source-pdos = <PDO_FIXED(5000, 3000,
+ PDO_FIXED_DUAL_ROLE |
+ PDO_FIXED_USB_COMM |
+ PDO_FIXED_DATA_SWAP)>;
+
+ altmodes {
+ displayport {
+ svid = <0xff01>;
+ vdo = <0x00001c46>;
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ pm8150b_role_switch_in: endpoint {
+ remote-endpoint = <&usb_1_role_switch_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ pm8150b_typec_mux_in: endpoint {
+ remote-endpoint = <&redriver_usb_con_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pm8150b_typec_sbu_out: endpoint {
+ remote-endpoint = <&redriver_usb_con_sbu>;
+ };
+ };
+ };
+ };
+};
+
+&usb_1_qmpphy_dp_in {
+ remote-endpoint = <&mdss_dp_out>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride.dts b/arch/arm64/boot/dts/qcom/sa8775p-ride.dts
index 81a7eeb9cfcd..9760bb4b468c 100644
--- a/arch/arm64/boot/dts/qcom/sa8775p-ride.dts
+++ b/arch/arm64/boot/dts/qcom/sa8775p-ride.dts
@@ -285,6 +285,7 @@
compatible = "ethernet-phy-id0141.0dd4";
reg = <0x8>;
device_type = "ethernet-phy";
+ interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
reset-assert-us = <11000>;
reset-deassert-us = <70000>;
@@ -294,6 +295,7 @@
compatible = "ethernet-phy-id0141.0dd4";
reg = <0xa>;
device_type = "ethernet-phy";
+ interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
reset-assert-us = <11000>;
reset-deassert-us = <70000>;
diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
index 9f4f58e831a4..b6a93b11cbbd 100644
--- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi
+++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
@@ -1525,6 +1525,7 @@
<0 0>,
<0 0>,
<0 0>;
+ qcom,ice = <&ice>;
status = "disabled";
};
@@ -1546,6 +1547,13 @@
status = "disabled";
};
+ ice: crypto@1d88000 {
+ compatible = "qcom,sa8775p-inline-crypto-engine",
+ "qcom,inline-crypto-engine";
+ reg = <0x0 0x01d88000 0x0 0x8000>;
+ clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
+ };
+
usb_0_hsphy: phy@88e4000 {
compatible = "qcom,sa8775p-usb-hs-phy",
"qcom,usb-snps-hs-5nm-phy";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
index a532cc4aac47..7765c8f64905 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
@@ -10,7 +10,6 @@
/* Deleted nodes from sc7180-trogdor.dtsi */
-/delete-node/ &alc5682;
/delete-node/ &pp3300_codec;
/ {
@@ -104,6 +103,7 @@ ap_ts_pen_1v8: &i2c4 {
interrupt-parent = <&tlmm>;
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ panel = <&panel>;
reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
vdd-supply = <&pp3300_ts>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
index b27dcd2ec856..2ba3bbf3b9ad 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
@@ -7,6 +7,8 @@
/* This file must be included after sc7180-trogdor.dtsi */
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
+
/ {
/* BOARD-SPECIFIC TOP LEVEL NODES */
@@ -116,6 +118,7 @@ ap_ts_pen_1v8: &i2c4 {
interrupt-parent = <&tlmm>;
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ panel = <&panel>;
reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
vdd-supply = <&pp3300_touch>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
index 36326ef972dc..d6db7d83adcf 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
@@ -11,19 +11,13 @@
#include "sc7180-trogdor-parade-ps8640.dtsi"
#include <arm/cros-ec-keyboard.dtsi>
#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682s-sku.dtsi"
/ {
model = "Google Kingoftown";
compatible = "google,kingoftown", "qcom,sc7180";
};
-&alc5682 {
- compatible = "realtek,rt5682s";
- /delete-property/ VBAT-supply;
- realtek,dmic1-clk-pin = <2>;
- realtek,dmic-clk-rate-hz = <2048000>;
-};
-
&ap_tp_i2c {
status = "okay";
};
@@ -84,11 +78,6 @@ ap_ts_pen_1v8: &i2c4 {
gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
};
-&sound {
- compatible = "google,sc7180-trogdor";
- model = "sc7180-rt5682s-max98357a-1mic";
-};
-
&wifi {
qcom,ath10k-calibration-variant = "GO_KINGOFTOWN";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r10.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r10.dts
new file mode 100644
index 000000000000..eba15535e1c7
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r10.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Lazor Limozeen board device tree source
+ *
+ * Copyright 2023 Google LLC.
+ */
+
+/dts-v1/;
+
+#include "sc7180-trogdor.dtsi"
+#include "sc7180-trogdor-parade-ps8640.dtsi"
+#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682s-sku.dtsi"
+
+/ {
+ model = "Google Lazor Limozeen without Touchscreen (rev10+)";
+ compatible = "google,lazor-sku6", "google,lazor-sku18", "qcom,sc7180";
+};
+
+/delete-node/ &ap_ts;
+
+&panel {
+ compatible = "edp-panel";
+};
+
+&sdhc_2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dts
index 7f01573b5543..e7da0d6e8ef5 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dts
@@ -11,6 +11,7 @@
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
model = "Google Lazor Limozeen without Touchscreen (rev5 - rev8)";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r9.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r9.dts
index 913b5fc3ba76..a609a2651549 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r9.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r9.dts
@@ -11,13 +11,14 @@
#include "sc7180-trogdor-parade-ps8640.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
- model = "Google Lazor Limozeen without Touchscreen (rev9+)";
- compatible = "google,lazor-sku6", "qcom,sc7180";
+ model = "Google Lazor Limozeen without Touchscreen (rev9)";
+ compatible = "google,lazor-rev9-sku6", "google,lazor-rev9-sku18", "qcom,sc7180";
};
-/delete-node/&ap_ts;
+/delete-node/ &ap_ts;
&panel {
compatible = "edp-panel";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r10.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r10.dts
new file mode 100644
index 000000000000..5cc7c0d8e70b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r10.dts
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Lazor Limozeen board device tree source
+ *
+ * Copyright 2023 Google LLC.
+ */
+
+/dts-v1/;
+
+#include "sc7180-trogdor.dtsi"
+#include "sc7180-trogdor-parade-ps8640.dtsi"
+#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682s-sku.dtsi"
+
+/ {
+ model = "Google Lazor Limozeen (rev10+)";
+ compatible = "google,lazor-sku4", "google,lazor-sku15", "qcom,sc7180";
+};
+
+/delete-node/ &ap_ts;
+
+&ap_ts_pen_1v8 {
+ ap_ts: touchscreen@10 {
+ compatible = "elan,ekth3500";
+ reg = <0x10>;
+ pinctrl-0 = <&ts_int_l>, <&ts_reset_l>;
+ pinctrl-names = "default";
+
+ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-parent = <&tlmm>;
+
+ vcc33-supply = <&pp3300_ts>;
+
+ reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&panel {
+ compatible = "auo,b116xa01";
+};
+
+&sdhc_2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r4.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r4.dts
index d42dcd421146..8a24812b9a00 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r4.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r4.dts
@@ -11,6 +11,8 @@
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
+
/ {
model = "Google Lazor Limozeen (rev4 - rev8)";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r9.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r9.dts
index 15d77dc5f956..dd377209dec3 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r9.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r9.dts
@@ -11,23 +11,24 @@
#include "sc7180-trogdor-parade-ps8640.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
- model = "Google Lazor Limozeen (rev9+)";
- compatible = "google,lazor-sku4", "qcom,sc7180";
+ model = "Google Lazor Limozeen (rev9)";
+ compatible = "google,lazor-rev9-sku4", "google,lazor-rev9-sku15", "qcom,sc7180";
};
-/delete-node/&ap_ts;
+/delete-node/ &ap_ts;
&ap_ts_pen_1v8 {
ap_ts: touchscreen@10 {
compatible = "elan,ekth3500";
reg = <0x10>;
- pinctrl-names = "default";
pinctrl-0 = <&ts_int_l>, <&ts_reset_l>;
+ pinctrl-names = "default";
- interrupt-parent = <&tlmm>;
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-parent = <&tlmm>;
vcc33-supply = <&pp3300_ts>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts
index 80c7108bc51b..b60060a38426 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts
@@ -10,6 +10,7 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
model = "Google Lazor (rev1 - 2)";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts
new file mode 100644
index 000000000000..45d34718a1bc
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Lazor board device tree source
+ *
+ * Copyright 2023 Google LLC.
+ */
+
+/dts-v1/;
+
+#include "sc7180-trogdor.dtsi"
+#include "sc7180-trogdor-parade-ps8640.dtsi"
+#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-lite.dtsi"
+#include "sc7180-trogdor-rt5682s-sku.dtsi"
+
+/ {
+ model = "Google Lazor (rev10+) with KB Backlight";
+ compatible = "google,lazor-sku2", "qcom,sc7180";
+};
+
+&keyboard_backlight {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts
new file mode 100644
index 000000000000..79028d0dd1b0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Lazor board device tree source
+ *
+ * Copyright 2023 Google LLC.
+ */
+
+/dts-v1/;
+
+#include "sc7180-trogdor.dtsi"
+#include "sc7180-trogdor-parade-ps8640.dtsi"
+#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682s-sku.dtsi"
+
+/ {
+ model = "Google Lazor (rev10+) with LTE";
+ compatible = "google,lazor-sku0", "google,lazor-sku10", "qcom,sc7180";
+};
+
+&ap_sar_sensor_i2c {
+ status = "okay";
+};
+
+&keyboard_backlight {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10.dts
new file mode 100644
index 000000000000..045827341ea0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Lazor board device tree source
+ *
+ * Copyright 2023 Google LLC.
+ */
+
+/dts-v1/;
+
+#include "sc7180-trogdor.dtsi"
+#include "sc7180-trogdor-parade-ps8640.dtsi"
+#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-lite.dtsi"
+#include "sc7180-trogdor-rt5682s-sku.dtsi"
+
+/ {
+ model = "Google Lazor (rev10+)";
+ compatible = "google,lazor", "qcom,sc7180";
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts
index 6ff81c1f7c44..3459b81c5628 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts
@@ -10,6 +10,7 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
#include "sc7180-lite.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts
index e58e36e35950..ff8f47da109d 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts
@@ -11,6 +11,7 @@
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
model = "Google Lazor (rev3 - 8) with LTE";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3.dts
index 76c83f88cb41..dd8f6d95655e 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3.dts
@@ -10,6 +10,7 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
#include "sc7180-lite.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts
index 960f7b7ce094..faf527972977 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts
@@ -10,11 +10,12 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-parade-ps8640.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
#include "sc7180-lite.dtsi"
/ {
- model = "Google Lazor (rev9+) with KB Backlight";
- compatible = "google,lazor-sku2", "qcom,sc7180";
+ model = "Google Lazor (rev9) with KB Backlight";
+ compatible = "google,lazor-rev9-sku2", "qcom,sc7180";
};
&keyboard_backlight {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts
index 38027f13b9d0..d737fd0637fb 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts
@@ -11,10 +11,11 @@
#include "sc7180-trogdor-parade-ps8640.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
- model = "Google Lazor (rev9+) with LTE";
- compatible = "google,lazor-sku0", "qcom,sc7180";
+ model = "Google Lazor (rev9) with LTE";
+ compatible = "google,lazor-rev9-sku0", "google,lazor-rev9-sku10", "qcom,sc7180";
};
&ap_sar_sensor_i2c {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9.dts
index 56dd222650d3..8daad32ff53b 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9.dts
@@ -10,9 +10,10 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-parade-ps8640.dtsi"
#include "sc7180-trogdor-lazor.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
#include "sc7180-lite.dtsi"
/ {
- model = "Google Lazor (rev9+)";
- compatible = "google,lazor", "qcom,sc7180";
+ model = "Google Lazor (rev9)";
+ compatible = "google,lazor-rev9", "qcom,sc7180";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
index 13339b723a93..e9f213d27711 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
@@ -43,6 +43,7 @@ ap_ts_pen_1v8: &i2c4 {
interrupt-parent = <&tlmm>;
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ panel = <&panel>;
post-power-on-delay-ms = <20>;
hid-descr-addr = <0x0001>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-parade.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-parade.dts
index 767cb7450c0d..1c3d9f1381ca 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-parade.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-parade.dts
@@ -11,6 +11,7 @@
#include "sc7180-trogdor-parade-ps8640.dtsi"
#include "sc7180-trogdor-pazquel.dtsi"
#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
model = "Google Pazquel (Parade,LTE)";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-ti.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-ti.dts
index 9145b74e9009..bf170471b00c 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-ti.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-ti.dts
@@ -11,6 +11,7 @@
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
#include "sc7180-trogdor-pazquel.dtsi"
#include "sc7180-trogdor-lte-sku.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
model = "Google Pazquel (TI,LTE)";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-parade.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-parade.dts
index 9a0e6632a786..60ae129b83c9 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-parade.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-parade.dts
@@ -10,6 +10,7 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-parade-ps8640.dtsi"
#include "sc7180-trogdor-pazquel.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
model = "Google Pazquel (Parade)";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-ti.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-ti.dts
index 47c5970d8c22..31678a98ce2c 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-ti.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-ti.dts
@@ -10,6 +10,7 @@
#include "sc7180-trogdor.dtsi"
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
#include "sc7180-trogdor-pazquel.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
model = "Google Pazquel (TI)";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel360.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel360.dtsi
index 273e2249f018..89034b6702f4 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel360.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel360.dtsi
@@ -7,13 +7,7 @@
/* This file must be included after sc7180-trogdor.dtsi */
#include "sc7180-trogdor-pazquel.dtsi"
-
-&alc5682 {
- compatible = "realtek,rt5682s";
- realtek,dmic1-clk-pin = <2>;
- realtek,dmic-clk-rate-hz = <2048000>;
- /delete-property/ VBAT-supply;
-};
+#include "sc7180-trogdor-rt5682s-sku.dtsi"
ap_ts_pen_1v8: &i2c4 {
clock-frequency = <400000>;
@@ -64,11 +58,6 @@ ap_ts_pen_1v8: &i2c4 {
>;
};
-&sound {
- compatible = "google,sc7180-trogdor";
- model = "sc7180-rt5682s-max98357a-1mic";
-};
-
&wifi {
qcom,ath10k-calibration-variant = "GO_PAZQUEL360";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
index fd944842dd6c..0be62331f982 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
@@ -8,6 +8,7 @@
#include "sc7180-trogdor.dtsi"
/* Must come after sc7180-trogdor.dtsi to modify cros_ec */
#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
/ {
@@ -102,6 +103,7 @@ ap_ts_pen_1v8: &i2c4 {
interrupt-parent = <&tlmm>;
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ panel = <&panel>;
post-power-on-delay-ms = <20>;
hid-descr-addr = <0x0001>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
index 62ab6427dd65..5f06842c683b 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
@@ -8,6 +8,7 @@
/dts-v1/;
#include "sc7180-trogdor.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/* This board only has 1 USB Type-C port. */
/delete-node/ &usb_c1;
@@ -69,6 +70,7 @@
interrupt-parent = <&tlmm>;
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ panel = <&panel>;
post-power-on-delay-ms = <20>;
hid-descr-addr = <0x0001>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
index 671b3691f1bb..c9667751a990 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
@@ -10,6 +10,7 @@
#include "sc7180-trogdor.dtsi"
/* Must come after sc7180-trogdor.dtsi to modify cros_ec */
#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
#include "sc7180-trogdor-ti-sn65dsi86.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-rt5682i-sku.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-rt5682i-sku.dtsi
new file mode 100644
index 000000000000..26f2f5de489c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-rt5682i-sku.dtsi
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Trogdor dts fragment for SKUs with rt5682i
+ *
+ * Copyright 2023 Google LLC.
+ */
+
+&hp_i2c {
+ alc5682: codec@1a {
+ compatible = "realtek,rt5682i";
+ reg = <0x1a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_irq>;
+
+ #sound-dai-cells = <1>;
+
+ interrupt-parent = <&tlmm>;
+ /*
+ * This will get ignored because the interrupt type
+ * is set in rt5682.c.
+ */
+ interrupts = <28 IRQ_TYPE_EDGE_BOTH>;
+
+ AVDD-supply = <&pp1800_alc5682>;
+ DBVDD-supply = <&pp1800_alc5682>;
+ LDO1-IN-supply = <&pp1800_alc5682>;
+ MICVDD-supply = <&pp3300_codec>;
+ VBAT-supply = <&pp3300_audio>;
+
+ realtek,dmic1-data-pin = <1>;
+ realtek,dmic1-clk-pin = <1>;
+ realtek,jd-src = <1>;
+ };
+};
+
+&sound {
+ model = "sc7180-rt5682-max98357a-1mic";
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-rt5682s-sku.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-rt5682s-sku.dtsi
new file mode 100644
index 000000000000..ea036a73f875
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-rt5682s-sku.dtsi
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Trogdor dts fragment for SKUs with rt5682s
+ *
+ * Copyright 2023 Google LLC.
+ */
+
+&hp_i2c {
+ alc5682: codec@1a {
+ compatible = "realtek,rt5682s";
+ reg = <0x1a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_irq>;
+
+ #sound-dai-cells = <1>;
+
+ interrupt-parent = <&tlmm>;
+ /*
+ * This will get ignored because the interrupt type
+ * is set in rt5682.c.
+ */
+ interrupts = <28 IRQ_TYPE_EDGE_BOTH>;
+
+ AVDD-supply = <&pp1800_alc5682>;
+ DBVDD-supply = <&pp1800_alc5682>;
+ LDO1-IN-supply = <&pp1800_alc5682>;
+ MICVDD-supply = <&pp3300_codec>;
+
+ realtek,dmic1-data-pin = <1>;
+ realtek,dmic1-clk-pin = <2>;
+ realtek,dmic-clk-rate-hz = <2048000>;
+ realtek,jd-src = <1>;
+ };
+};
+
+&sound {
+ model = "sc7180-rt5682s-max98357a-1mic";
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe-rt5682s.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe-rt5682s.dts
index 6225ab8329c3..116f79c25a5d 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe-rt5682s.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe-rt5682s.dts
@@ -10,21 +10,20 @@
/dts-v1/;
-#include "sc7180-trogdor-wormdingler-rev1-boe.dts"
+#include "sc7180-trogdor-wormdingler.dtsi"
+#include "sc7180-trogdor-rt5682s-sku.dtsi"
/ {
model = "Google Wormdingler rev1+ (BOE, rt5682s)";
compatible = "google,wormdingler-sku1025", "qcom,sc7180";
};
-&alc5682 {
- compatible = "realtek,rt5682s";
- /delete-property/ VBAT-supply;
- realtek,dmic1-clk-pin = <2>;
- realtek,dmic-clk-rate-hz = <2048000>;
+&mdss_dsi0_phy {
+ qcom,phy-rescode-offset-top = /bits/ 8 <31 31 31 31 (-32)>;
+ qcom,phy-rescode-offset-bot = /bits/ 8 <31 31 31 31 (-32)>;
+ qcom,phy-drive-ldo-level = <450>;
};
-&sound {
- compatible = "google,sc7180-trogdor";
- model = "sc7180-rt5682s-max98357a-1mic";
+&panel {
+ compatible = "boe,tv110c9m-ll3";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe.dts
index 6eeead70d3eb..72627760e2a4 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe.dts
@@ -11,6 +11,7 @@
/dts-v1/;
#include "sc7180-trogdor-wormdingler.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
model = "Google Wormdingler rev1+ BOE panel board";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx-rt5682s.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx-rt5682s.dts
index b40b068dad6a..0bf355e08f78 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx-rt5682s.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx-rt5682s.dts
@@ -10,21 +10,14 @@
/dts-v1/;
-#include "sc7180-trogdor-wormdingler-rev1-inx.dts"
+#include "sc7180-trogdor-wormdingler.dtsi"
+#include "sc7180-trogdor-rt5682s-sku.dtsi"
/ {
model = "Google Wormdingler rev1+ (INX, rt5682s)";
compatible = "google,wormdingler-sku1", "qcom,sc7180";
};
-&alc5682 {
- compatible = "realtek,rt5682s";
- /delete-property/ VBAT-supply;
- realtek,dmic1-clk-pin = <2>;
- realtek,dmic-clk-rate-hz = <2048000>;
-};
-
-&sound {
- compatible = "google,sc7180-trogdor";
- model = "sc7180-rt5682s-max98357a-1mic";
+&panel {
+ compatible = "innolux,hj110iz-01a";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx.dts
index dd34a2297ea0..4b165b826ab3 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx.dts
@@ -11,6 +11,7 @@
/dts-v1/;
#include "sc7180-trogdor-wormdingler.dtsi"
+#include "sc7180-trogdor-rt5682i-sku.dtsi"
/ {
model = "Google Wormdingler rev1+ INX panel board";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
index 2f6a340ddd2a..305ad127246e 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
@@ -123,6 +123,7 @@
interrupt-parent = <&tlmm>;
interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ panel = <&panel>;
post-power-on-delay-ms = <70>;
hid-descr-addr = <0x0001>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 5a33e16a8b67..46aaeba28604 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -372,7 +372,6 @@
sound: sound {
compatible = "google,sc7180-trogdor";
- model = "sc7180-rt5682-max98357a-1mic";
audio-routing =
"Headphone Jack", "HPOL",
@@ -747,32 +746,6 @@ ap_tp_i2c: &i2c7 {
hp_i2c: &i2c9 {
status = "okay";
clock-frequency = <400000>;
-
- alc5682: codec@1a {
- compatible = "realtek,rt5682i";
- reg = <0x1a>;
- pinctrl-names = "default";
- pinctrl-0 = <&hp_irq>;
-
- #sound-dai-cells = <1>;
-
- interrupt-parent = <&tlmm>;
- /*
- * This will get ignored because the interrupt type
- * is set in rt5682.c.
- */
- interrupts = <28 IRQ_TYPE_EDGE_BOTH>;
-
- AVDD-supply = <&pp1800_alc5682>;
- DBVDD-supply = <&pp1800_alc5682>;
- LDO1-IN-supply = <&pp1800_alc5682>;
- MICVDD-supply = <&pp3300_codec>;
- VBAT-supply = <&pp3300_audio>;
-
- realtek,dmic1-data-pin = <1>;
- realtek,dmic1-clk-pin = <1>;
- realtek,jd-src = <1>;
- };
};
&lpasscc {
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index a79c0f2e1879..11f353d416b4 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -11,15 +11,19 @@
#include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,videocc-sc7180.h>
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sc7180.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/phy/phy-qcom-qusb2.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/reset/qcom,sdm845-aoss.h>
#include <dt-bindings/reset/qcom,sdm845-pdc.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/soc/qcom,apr.h>
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -687,7 +691,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
};
@@ -2042,6 +2046,11 @@
pins = "gpio57";
function = "lpass_ext";
};
+
+ ter_mi2s_active: ter-mi2s-active-state {
+ pins = "gpio63", "gpio64", "gpio65", "gpio66";
+ function = "mi2s_2";
+ };
};
remoteproc_mpss: remoteproc@4080000 {
@@ -2795,49 +2804,28 @@
nvmem-cells = <&qusb2p_hstx_trim>;
};
- usb_1_qmpphy: phy-wrapper@88e9000 {
+ usb_1_qmpphy: phy@88e8000 {
compatible = "qcom,sc7180-qmp-usb3-dp-phy";
- reg = <0 0x088e9000 0 0x18c>,
- <0 0x088e8000 0 0x3c>,
- <0 0x088ea000 0 0x18c>;
+ reg = <0 0x088e8000 0 0x3000>;
status = "disabled";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
- <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
<&gcc GCC_USB3_PRIM_CLKREF_CLK>,
- <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "com_aux";
+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>,
+ <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>;
+ clock-names = "aux",
+ "ref",
+ "com_aux",
+ "usb3_pipe",
+ "cfg_ahb";
resets = <&gcc GCC_USB3_PHY_PRIM_BCR>,
<&gcc GCC_USB3_DP_PHY_PRIM_BCR>;
reset-names = "phy", "common";
- usb_1_ssphy: usb3-phy@88e9200 {
- reg = <0 0x088e9200 0 0x128>,
- <0 0x088e9400 0 0x200>,
- <0 0x088e9c00 0 0x218>,
- <0 0x088e9600 0 0x128>,
- <0 0x088e9800 0 0x200>,
- <0 0x088e9a00 0 0x18>;
- #clock-cells = <0>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "usb3_phy_pipe_clk_src";
- };
-
- dp_phy: dp-phy@88ea200 {
- reg = <0 0x088ea200 0 0x200>,
- <0 0x088ea400 0 0x200>,
- <0 0x088eaa00 0 0x200>,
- <0 0x088ea600 0 0x200>,
- <0 0x088ea800 0 0x200>;
- #clock-cells = <1>;
- #phy-cells = <0>;
- };
+ #clock-cells = <1>;
+ #phy-cells = <1>;
};
pmu@90b6300 {
@@ -3001,7 +2989,7 @@
iommus = <&apps_smmu 0x540 0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
- phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
+ phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
maximum-speed = "super-speed";
};
@@ -3307,8 +3295,9 @@
"ctrl_link_iface", "stream_pixel";
assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
<&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
- assigned-clock-parents = <&dp_phy 0>, <&dp_phy 1>;
- phys = <&dp_phy>;
+ assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
+ phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>;
phy-names = "dp";
operating-points-v2 = <&dp_opp_table>;
@@ -3365,8 +3354,8 @@
<&gcc GCC_DISP_GPLL0_CLK_SRC>,
<&mdss_dsi0_phy 0>,
<&mdss_dsi0_phy 1>,
- <&dp_phy 0>,
- <&dp_phy 1>;
+ <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
clock-names = "bi_tcxo",
"gcc_disp_gpll0_clk_src",
"dsi0_phy_pll_out_byteclk",
@@ -3776,6 +3765,126 @@
status = "disabled";
};
+ remoteproc_adsp: remoteproc@62400000 {
+ compatible = "qcom,sc7180-adsp-pas";
+ reg = <0 0x62400000 0 0x100>;
+
+ interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
+ <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+ <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+ <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+ <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "wdog",
+ "fatal",
+ "ready",
+ "handover",
+ "stop-ack";
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+ power-domains = <&rpmhpd SC7180_LCX>,
+ <&rpmhpd SC7180_LMX>;
+ power-domain-names = "lcx", "lmx";
+
+ qcom,qmp = <&aoss_qmp>;
+ qcom,smem-states = <&adsp_smp2p_out 0>;
+ qcom,smem-state-names = "stop";
+
+ status = "disabled";
+
+ glink-edge {
+ interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+ label = "lpass";
+ qcom,remote-pid = <2>;
+ mboxes = <&apss_shared 8>;
+
+ apr {
+ compatible = "qcom,apr-v2";
+ qcom,glink-channels = "apr_audio_svc";
+ qcom,domain = <APR_DOMAIN_ADSP>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ service@3 {
+ compatible = "qcom,q6core";
+ reg = <APR_SVC_ADSP_CORE>;
+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+ };
+
+ q6afe: service@4 {
+ compatible = "qcom,q6afe";
+ reg = <APR_SVC_AFE>;
+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+
+ q6afedai: dais {
+ compatible = "qcom,q6afe-dais";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #sound-dai-cells = <1>;
+ };
+
+ q6afecc: clock-controller {
+ compatible = "qcom,q6afe-clocks";
+ #clock-cells = <2>;
+ };
+ };
+
+ q6asm: service@7 {
+ compatible = "qcom,q6asm";
+ reg = <APR_SVC_ASM>;
+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+
+ q6asmdai: dais {
+ compatible = "qcom,q6asm-dais";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #sound-dai-cells = <1>;
+ iommus = <&apps_smmu 0x1001 0x0>;
+ };
+ };
+
+ q6adm: service@8 {
+ compatible = "qcom,q6adm";
+ reg = <APR_SVC_ADM>;
+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+
+ q6routing: routing {
+ compatible = "qcom,q6adm-routing";
+ #sound-dai-cells = <0>;
+ };
+ };
+ };
+
+ fastrpc {
+ compatible = "qcom,fastrpc";
+ qcom,glink-channels = "fastrpcglink-apps-dsp";
+ label = "adsp";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compute-cb@3 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <3>;
+ iommus = <&apps_smmu 0x1003 0x0>;
+ };
+
+ compute-cb@4 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <4>;
+ iommus = <&apps_smmu 0x1004 0x0>;
+ };
+
+ compute-cb@5 {
+ compatible = "qcom,fastrpc-compute-cb";
+ reg = <5>;
+ iommus = <&apps_smmu 0x1005 0x0>;
+ qcom,nsessions = <5>;
+ };
+ };
+ };
+ };
+
lpasscc: clock-controller@62d00000 {
compatible = "qcom,sc7180-lpasscorecc";
reg = <0 0x62d00000 0 0x50000>,
diff --git a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
index 2e1cd219fc18..5d462ae14ba1 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
@@ -46,6 +46,26 @@
};
};
+&lpass_aon {
+ status = "okay";
+};
+
+&lpass_core {
+ status = "okay";
+};
+
+&lpass_hm {
+ status = "okay";
+};
+
+&lpasscc {
+ status = "okay";
+};
+
+&pdc_reset {
+ status = "okay";
+};
+
/* The PMIC PON code isn't compatible w/ how Chrome EC/BIOS handle things. */
&pmk8350_pon {
status = "disabled";
@@ -84,6 +104,10 @@
dma-coherent;
};
+&watchdog {
+ status = "okay";
+};
+
&wifi {
status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/sc7280-crd-r3.dts b/arch/arm64/boot/dts/qcom/sc7280-crd-r3.dts
index afae7f46b050..c2cba9d7179b 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-crd-r3.dts
+++ b/arch/arm64/boot/dts/qcom/sc7280-crd-r3.dts
@@ -38,6 +38,10 @@
};
};
+&bluetooth {
+ vddio-supply = <&vreg_l18b_1p8>;
+};
+
ap_tp_i2c: &i2c0 {
status = "okay";
clock-frequency = <400000>;
diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 925428a5f6ae..66f1eb83cca7 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -13,11 +13,13 @@
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,videocc-sc7280.h>
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sc7280.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/reset/qcom,sdm845-aoss.h>
#include <dt-bindings/reset/qcom,sdm845-pdc.h>
@@ -156,7 +158,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
};
@@ -170,9 +172,8 @@
reg = <0x0 0x0>;
clocks = <&cpufreq_hw 0>;
enable-method = "psci";
- cpu-idle-states = <&LITTLE_CPU_SLEEP_0
- &LITTLE_CPU_SLEEP_1
- &CLUSTER_SLEEP_0>;
+ power-domains = <&CPU_PD0>;
+ power-domain-names = "psci";
next-level-cache = <&L2_0>;
operating-points-v2 = <&cpu0_opp_table>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
@@ -198,9 +199,8 @@
reg = <0x0 0x100>;
clocks = <&cpufreq_hw 0>;
enable-method = "psci";
- cpu-idle-states = <&LITTLE_CPU_SLEEP_0
- &LITTLE_CPU_SLEEP_1
- &CLUSTER_SLEEP_0>;
+ power-domains = <&CPU_PD1>;
+ power-domain-names = "psci";
next-level-cache = <&L2_100>;
operating-points-v2 = <&cpu0_opp_table>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
@@ -221,9 +221,8 @@
reg = <0x0 0x200>;
clocks = <&cpufreq_hw 0>;
enable-method = "psci";
- cpu-idle-states = <&LITTLE_CPU_SLEEP_0
- &LITTLE_CPU_SLEEP_1
- &CLUSTER_SLEEP_0>;
+ power-domains = <&CPU_PD2>;
+ power-domain-names = "psci";
next-level-cache = <&L2_200>;
operating-points-v2 = <&cpu0_opp_table>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
@@ -244,9 +243,8 @@
reg = <0x0 0x300>;
clocks = <&cpufreq_hw 0>;
enable-method = "psci";
- cpu-idle-states = <&LITTLE_CPU_SLEEP_0
- &LITTLE_CPU_SLEEP_1
- &CLUSTER_SLEEP_0>;
+ power-domains = <&CPU_PD3>;
+ power-domain-names = "psci";
next-level-cache = <&L2_300>;
operating-points-v2 = <&cpu0_opp_table>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
@@ -267,9 +265,8 @@
reg = <0x0 0x400>;
clocks = <&cpufreq_hw 1>;
enable-method = "psci";
- cpu-idle-states = <&BIG_CPU_SLEEP_0
- &BIG_CPU_SLEEP_1
- &CLUSTER_SLEEP_0>;
+ power-domains = <&CPU_PD4>;
+ power-domain-names = "psci";
next-level-cache = <&L2_400>;
operating-points-v2 = <&cpu4_opp_table>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
@@ -290,9 +287,8 @@
reg = <0x0 0x500>;
clocks = <&cpufreq_hw 1>;
enable-method = "psci";
- cpu-idle-states = <&BIG_CPU_SLEEP_0
- &BIG_CPU_SLEEP_1
- &CLUSTER_SLEEP_0>;
+ power-domains = <&CPU_PD5>;
+ power-domain-names = "psci";
next-level-cache = <&L2_500>;
operating-points-v2 = <&cpu4_opp_table>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
@@ -313,9 +309,8 @@
reg = <0x0 0x600>;
clocks = <&cpufreq_hw 1>;
enable-method = "psci";
- cpu-idle-states = <&BIG_CPU_SLEEP_0
- &BIG_CPU_SLEEP_1
- &CLUSTER_SLEEP_0>;
+ power-domains = <&CPU_PD6>;
+ power-domain-names = "psci";
next-level-cache = <&L2_600>;
operating-points-v2 = <&cpu4_opp_table>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
@@ -336,9 +331,8 @@
reg = <0x0 0x700>;
clocks = <&cpufreq_hw 2>;
enable-method = "psci";
- cpu-idle-states = <&BIG_CPU_SLEEP_0
- &BIG_CPU_SLEEP_1
- &CLUSTER_SLEEP_0>;
+ power-domains = <&CPU_PD7>;
+ power-domain-names = "psci";
next-level-cache = <&L2_700>;
operating-points-v2 = <&cpu7_opp_table>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
@@ -431,9 +425,11 @@
min-residency-us = <5555>;
local-timer-stop;
};
+ };
+ domain-idle-states {
CLUSTER_SLEEP_0: cluster-sleep-0 {
- compatible = "arm,idle-state";
+ compatible = "domain-idle-state";
idle-state-name = "cluster-power-down";
arm,psci-suspend-param = <0x40003444>;
entry-latency-us = <3263>;
@@ -649,18 +645,6 @@
};
};
- eud_typec: connector {
- compatible = "usb-c-connector";
-
- ports {
- port@0 {
- con_eud: endpoint {
- remote-endpoint = <&eud_con>;
- };
- };
- };
- };
-
memory@80000000 {
device_type = "memory";
/* We expect the bootloader to fill in the size */
@@ -811,6 +795,59 @@
psci {
compatible = "arm,psci-1.0";
method = "smc";
+
+ CPU_PD0: power-domain-cpu0 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+ };
+
+ CPU_PD1: power-domain-cpu1 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+ };
+
+ CPU_PD2: power-domain-cpu2 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+ };
+
+ CPU_PD3: power-domain-cpu3 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+ };
+
+ CPU_PD4: power-domain-cpu4 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+ };
+
+ CPU_PD5: power-domain-cpu5 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+ };
+
+ CPU_PD6: power-domain-cpu6 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+ };
+
+ CPU_PD7: power-domain-cpu7 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+ };
+
+ CLUSTER_PD: power-domain-cluster {
+ #power-domain-cells = <0>;
+ domain-idle-states = <&CLUSTER_SLEEP_0>;
+ };
};
qspi_opp_table: opp-table-qspi {
@@ -868,8 +905,9 @@
reg = <0 0x00100000 0 0x1f0000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>,
- <0>, <&pcie1_lane>,
- <0>, <0>, <0>, <0>;
+ <0>, <&pcie1_phy>,
+ <0>, <0>, <0>,
+ <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>;
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk",
"pcie_0_pipe_clk", "pcie_1_pipe_clk",
"ufs_phy_rx_symbol_0_clk", "ufs_phy_rx_symbol_1_clk",
@@ -2119,7 +2157,7 @@
clocks = <&gcc GCC_PCIE_1_PIPE_CLK>,
<&gcc GCC_PCIE_1_PIPE_CLK_SRC>,
- <&pcie1_lane>,
+ <&pcie1_phy>,
<&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_PCIE_1_AUX_CLK>,
<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
@@ -2153,7 +2191,7 @@
power-domains = <&gcc GCC_PCIE_1_GDSC>;
- phys = <&pcie1_lane>;
+ phys = <&pcie1_phy>;
phy-names = "pciephy";
pinctrl-names = "default";
@@ -2169,15 +2207,22 @@
pcie1_phy: phy@1c0e000 {
compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy";
- reg = <0 0x01c0e000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c0e000 0 0x1000>;
clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
<&gcc GCC_PCIE_CLKREF_EN>,
- <&gcc GCC_PCIE1_PHY_RCHNG_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE1_PHY_RCHNG_CLK>,
+ <&gcc GCC_PCIE_1_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+
+ clock-output-names = "pcie_1_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_1_PHY_BCR>;
reset-names = "phy";
@@ -2186,21 +2231,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie1_lane: phy@1c0e200 {
- reg = <0 0x01c0e200 0 0x170>,
- <0 0x01c0e400 0 0x200>,
- <0 0x01c0ea00 0 0x1f0>,
- <0 0x01c0e600 0 0x170>,
- <0 0x01c0e800 0 0x200>,
- <0 0x01c0ee00 0 0xf4>;
- clocks = <&gcc GCC_PCIE_1_PIPE_CLK>;
- clock-names = "pipe0";
-
- #phy-cells = <0>;
- #clock-cells = <0>;
- clock-output-names = "pcie_1_pipe_clk";
- };
};
ipa: ipa@1e40000 {
@@ -2266,6 +2296,7 @@
clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>;
clock-names = "iface";
#clock-cells = <1>;
+ status = "reserved"; /* Owned by ADSP firmware */
};
lpass_rx_macro: codec@3200000 {
@@ -2417,6 +2448,7 @@
clock-names = "bi_tcxo", "bi_tcxo_ao", "iface";
#clock-cells = <1>;
#power-domain-cells = <1>;
+ status = "reserved"; /* Owned by ADSP firmware */
};
lpass_core: clock-controller@3900000 {
@@ -2427,6 +2459,7 @@
power-domains = <&lpass_hm LPASS_CORE_CC_LPASS_CORE_HM_GDSC>;
#clock-cells = <1>;
#power-domain-cells = <1>;
+ status = "reserved"; /* Owned by ADSP firmware */
};
lpass_cpu: audio@3987000 {
@@ -2497,6 +2530,7 @@
clock-names = "bi_tcxo";
#clock-cells = <1>;
#power-domain-cells = <1>;
+ status = "reserved"; /* Owned by ADSP firmware */
};
lpass_ag_noc: interconnect@3c40000 {
@@ -2510,7 +2544,6 @@
compatible = "qcom,sc7280-lpass-lpi-pinctrl";
reg = <0 0x033c0000 0x0 0x20000>,
<0 0x03550000 0x0 0x10000>;
- qcom,adsp-bypass-mode;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&lpass_tlmm 0 0 15>;
@@ -3346,49 +3379,26 @@
resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
};
- usb_1_qmpphy: phy-wrapper@88e9000 {
- compatible = "qcom,sc7280-qmp-usb3-dp-phy",
- "qcom,sm8250-qmp-usb3-dp-phy";
- reg = <0 0x088e9000 0 0x200>,
- <0 0x088e8000 0 0x40>,
- <0 0x088ea000 0 0x200>;
+ usb_1_qmpphy: phy@88e8000 {
+ compatible = "qcom,sc7280-qmp-usb3-dp-phy";
+ reg = <0 0x088e8000 0 0x3000>;
status = "disabled";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
<&rpmhcc RPMH_CXO_CLK>,
- <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
- clock-names = "aux", "ref_clk_src", "com_aux";
+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+ clock-names = "aux",
+ "ref",
+ "com_aux",
+ "usb3_pipe";
resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>,
<&gcc GCC_USB3_PHY_PRIM_BCR>;
reset-names = "phy", "common";
- usb_1_ssphy: usb3-phy@88e9200 {
- reg = <0 0x088e9200 0 0x200>,
- <0 0x088e9400 0 0x200>,
- <0 0x088e9c00 0 0x400>,
- <0 0x088e9600 0 0x200>,
- <0 0x088e9800 0 0x200>,
- <0 0x088e9a00 0 0x100>;
- #clock-cells = <0>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "usb3_phy_pipe_clk_src";
- };
-
- dp_phy: dp-phy@88ea200 {
- reg = <0 0x088ea200 0 0x200>,
- <0 0x088ea400 0 0x200>,
- <0 0x088eaa00 0 0x200>,
- <0 0x088ea600 0 0x200>,
- <0 0x088ea800 0 0x200>;
- #phy-cells = <0>;
- #clock-cells = <1>;
- };
+ #clock-cells = <1>;
+ #phy-cells = <1>;
};
usb_2: usb@8cf8800 {
@@ -3624,6 +3634,8 @@
<0 0x88e2000 0 0x1000>;
interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -3634,13 +3646,6 @@
remote-endpoint = <&usb2_role_switch>;
};
};
-
- port@1 {
- reg = <1>;
- eud_con: endpoint {
- remote-endpoint = <&con_eud>;
- };
- };
};
};
@@ -3702,7 +3707,7 @@
iommus = <&apps_smmu 0xe0 0x0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
- phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
+ phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
maximum-speed = "super-speed";
};
@@ -3807,8 +3812,8 @@
<&gcc GCC_DISP_GPLL0_CLK_SRC>,
<&mdss_dsi_phy 0>,
<&mdss_dsi_phy 1>,
- <&dp_phy 0>,
- <&dp_phy 1>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>,
<&mdss_edp_phy 0>,
<&mdss_edp_phy 1>;
clock-names = "bi_tcxo",
@@ -4144,8 +4149,9 @@
"stream_pixel";
assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
<&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
- assigned-clock-parents = <&dp_phy 0>, <&dp_phy 1>;
- phys = <&dp_phy>;
+ assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
+ phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>;
phy-names = "dp";
operating-points-v2 = <&dp_opp_table>;
@@ -4215,6 +4221,7 @@
compatible = "qcom,sc7280-pdc-global";
reg = <0 0x0b5e0000 0 0x20000>;
#reset-cells = <1>;
+ status = "reserved"; /* Owned by firmware */
};
tsens0: thermal-sensor@c263000 {
@@ -5211,11 +5218,12 @@
};
};
- watchdog@17c10000 {
+ watchdog: watchdog@17c10000 {
compatible = "qcom,apss-wdt-sc7280", "qcom,kpss-wdt";
reg = <0 0x17c10000 0 0x1000>;
clocks = <&sleep_clk>;
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ status = "reserved"; /* Owned by Gunyah hyp */
};
timer@17c20000 {
@@ -5291,6 +5299,7 @@
<SLEEP_TCS 3>,
<WAKE_TCS 3>,
<CONTROL_TCS 1>;
+ power-domains = <&CLUSTER_PD>;
apps_bcm_voter: bcm-voter {
compatible = "qcom,bcm-voter";
@@ -5363,6 +5372,14 @@
reg = <0 0x18591000 0 0x1000>,
<0 0x18592000 0 0x1000>,
<0 0x18593000 0 0x1000>;
+
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dcvsh-irq-0",
+ "dcvsh-irq-1",
+ "dcvsh-irq-2";
+
clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
clock-names = "xo", "alternate";
#freq-domain-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts b/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts
index abc66613ccaa..3ea07d094b60 100644
--- a/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts
+++ b/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts
@@ -6,6 +6,7 @@
/dts-v1/;
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/gpio-keys.h>
#include <dt-bindings/input/input.h>
@@ -130,7 +131,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
wlan_mem: wlan-region@8bc00000 {
diff --git a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts
index 834e6f9fb7c8..fd2fab4895b3 100644
--- a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts
+++ b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts
@@ -6,6 +6,7 @@
/dts-v1/;
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/gpio-keys.h>
#include <dt-bindings/input/input.h>
@@ -135,7 +136,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
wlan_mem: wlan-region@8bc00000 {
diff --git a/arch/arm64/boot/dts/qcom/sc8180x.dtsi b/arch/arm64/boot/dts/qcom/sc8180x.dtsi
index 486f7ffef43b..a34f438ef2d9 100644
--- a/arch/arm64/boot/dts/qcom/sc8180x.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc8180x.dtsi
@@ -1749,23 +1749,28 @@
<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
interconnect-names = "pcie-mem", "cpu-pcie";
- phys = <&pcie0_lane>;
+ phys = <&pcie0_phy>;
phy-names = "pciephy";
status = "disabled";
};
- pcie0_phy: phy-wrapper@1c06000 {
+ pcie0_phy: phy@1c06000 {
compatible = "qcom,sc8180x-qmp-pcie-phy";
- reg = <0 0x1c06000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c06000 0 0x1000>;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
<&gcc GCC_PCIE_0_CLKREF_CLK>,
- <&gcc GCC_PCIE1_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE1_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_0_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+ #clock-cells = <0>;
+ clock-output-names = "pcie_0_pipe_clk";
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_0_PHY_BCR>;
reset-names = "phy";
@@ -1774,21 +1779,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie0_lane: phy@1c06200 {
- reg = <0 0x1c06200 0 0x170>, /* tx0 */
- <0 0x1c06400 0 0x200>, /* rx0 */
- <0 0x1c06a00 0 0x1f0>, /* pcs */
- <0 0x1c06600 0 0x170>, /* tx1 */
- <0 0x1c06800 0 0x200>, /* rx1 */
- <0 0x1c06e00 0 0xf4>; /* pcs_com */
- clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
- clock-names = "pipe0";
-
- #clock-cells = <0>;
- clock-output-names = "pcie_0_pipe_clk";
- #phy-cells = <0>;
- };
};
pcie3: pci@1c08000 {
@@ -1856,23 +1846,29 @@
<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
interconnect-names = "pcie-mem", "cpu-pcie";
- phys = <&pcie3_lane>;
+ phys = <&pcie3_phy>;
phy-names = "pciephy";
status = "disabled";
};
- pcie3_phy: phy-wrapper@1c0c000 {
+ pcie3_phy: phy@1c0c000 {
compatible = "qcom,sc8180x-qmp-pcie-phy";
- reg = <0 0x1c0c000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c0c000 0 0x1000>;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_3_CFG_AHB_CLK>,
<&gcc GCC_PCIE_3_CLKREF_CLK>,
- <&gcc GCC_PCIE2_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE2_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_3_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+ #clock-cells = <0>;
+ clock-output-names = "pcie_3_pipe_clk";
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_3_PHY_BCR>;
reset-names = "phy";
@@ -1881,21 +1877,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie3_lane: phy@1c0c200 {
- reg = <0 0x1c0c200 0 0x170>, /* tx0 */
- <0 0x1c0c400 0 0x200>, /* rx0 */
- <0 0x1c0ca00 0 0x1f0>, /* pcs */
- <0 0x1c0c600 0 0x170>, /* tx1 */
- <0 0x1c0c800 0 0x200>, /* rx1 */
- <0 0x1c0ce00 0 0xf4>; /* pcs_com */
- clocks = <&gcc GCC_PCIE_3_PIPE_CLK>;
- clock-names = "pipe0";
-
- #clock-cells = <0>;
- clock-output-names = "pcie_3_pipe_clk";
- #phy-cells = <0>;
- };
};
pcie1: pci@1c10000 {
@@ -1963,23 +1944,29 @@
<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
interconnect-names = "pcie-mem", "cpu-pcie";
- phys = <&pcie1_lane>;
+ phys = <&pcie1_phy>;
phy-names = "pciephy";
status = "disabled";
};
- pcie1_phy: phy-wrapper@1c16000 {
+ pcie1_phy: phy@1c16000 {
compatible = "qcom,sc8180x-qmp-pcie-phy";
- reg = <0 0x1c16000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c16000 0 0x1000>;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
<&gcc GCC_PCIE_1_CLKREF_CLK>,
- <&gcc GCC_PCIE1_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE1_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_1_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+ #clock-cells = <0>;
+ clock-output-names = "pcie_1_pipe_clk";
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_1_PHY_BCR>;
reset-names = "phy";
@@ -1988,21 +1975,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie1_lane: phy@1c0e200 {
- reg = <0 0x1c16200 0 0x170>, /* tx0 */
- <0 0x1c16400 0 0x200>, /* rx0 */
- <0 0x1c16a00 0 0x1f0>, /* pcs */
- <0 0x1c16600 0 0x170>, /* tx1 */
- <0 0x1c16800 0 0x200>, /* rx1 */
- <0 0x1c16e00 0 0xf4>; /* pcs_com */
- clocks = <&gcc GCC_PCIE_1_PIPE_CLK>;
- clock-names = "pipe0";
- #clock-cells = <0>;
- clock-output-names = "pcie_1_pipe_clk";
-
- #phy-cells = <0>;
- };
};
pcie2: pci@1c18000 {
@@ -2070,23 +2042,29 @@
<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
interconnect-names = "pcie-mem", "cpu-pcie";
- phys = <&pcie2_lane>;
+ phys = <&pcie2_phy>;
phy-names = "pciephy";
status = "disabled";
};
- pcie2_phy: phy-wrapper@1c1c000 {
+ pcie2_phy: phy@1c1c000 {
compatible = "qcom,sc8180x-qmp-pcie-phy";
- reg = <0 0x1c1c000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c1c000 0 0x1000>;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_2_CFG_AHB_CLK>,
<&gcc GCC_PCIE_2_CLKREF_CLK>,
- <&gcc GCC_PCIE2_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE2_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_2_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+ #clock-cells = <0>;
+ clock-output-names = "pcie_3_pipe_clk";
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_2_PHY_BCR>;
reset-names = "phy";
@@ -2095,22 +2073,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie2_lane: phy@1c0e200 {
- reg = <0 0x1c1c200 0 0x170>, /* tx0 */
- <0 0x1c1c400 0 0x200>, /* rx0 */
- <0 0x1c1ca00 0 0x1f0>, /* pcs */
- <0 0x1c1c600 0 0x170>, /* tx1 */
- <0 0x1c1c800 0 0x200>, /* rx1 */
- <0 0x1c1ce00 0 0xf4>; /* pcs_com */
- clocks = <&gcc GCC_PCIE_2_PIPE_CLK>;
- clock-names = "pipe0";
-
- #clock-cells = <0>;
- clock-output-names = "pcie_2_pipe_clk";
-
- #phy-cells = <0>;
- };
};
ufs_mem_hc: ufshc@1d84000 {
@@ -2118,7 +2080,7 @@
"jedec,ufs-2.0";
reg = <0 0x01d84000 0 0x2500>;
interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
- phys = <&ufs_mem_phy_lanes>;
+ phys = <&ufs_mem_phy>;
phy-names = "ufsphy";
lanes-per-direction = <2>;
#reset-cells = <1>;
@@ -2157,10 +2119,8 @@
ufs_mem_phy: phy-wrapper@1d87000 {
compatible = "qcom,sc8180x-qmp-ufs-phy";
- reg = <0 0x01d87000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01d87000 0 0x1000>;
+
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
clock-names = "ref",
@@ -2168,16 +2128,10 @@
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
- status = "disabled";
- ufs_mem_phy_lanes: phy@1d87400 {
- reg = <0 0x01d87400 0 0x108>,
- <0 0x01d87600 0 0x1e0>,
- <0 0x01d87c00 0 0x1dc>,
- <0 0x01d87800 0 0x108>,
- <0 0x01d87a00 0 0x1e0>;
- #phy-cells = <0>;
- };
+ #phy-cells = <0>;
+
+ status = "disabled";
};
ipa_virt: interconnect@1e00000 {
@@ -2606,14 +2560,14 @@
clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
<&gcc GCC_USB30_PRIM_MASTER_CLK>,
<&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
- <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
<&gcc GCC_USB30_PRIM_SLEEP_CLK>,
+ <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
<&gcc GCC_USB3_SEC_CLKREF_CLK>;
clock-names = "cfg_noc",
"core",
"iface",
- "mock_utmi",
"sleep",
+ "mock_utmi",
"xo";
resets = <&gcc GCC_USB30_PRIM_BCR>;
power-domains = <&gcc USB30_PRIM_GDSC>;
@@ -2657,14 +2611,14 @@
clocks = <&gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>,
<&gcc GCC_USB30_SEC_MASTER_CLK>,
<&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>,
- <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
<&gcc GCC_USB30_SEC_SLEEP_CLK>,
+ <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
<&gcc GCC_USB3_SEC_CLKREF_CLK>;
clock-names = "cfg_noc",
"core",
"iface",
- "mock_utmi",
"sleep",
+ "mock_utmi",
"xo";
resets = <&gcc GCC_USB30_SEC_BCR>;
power-domains = <&gcc USB30_SEC_GDSC>;
@@ -3307,7 +3261,6 @@
#size-cells = <0>;
interrupt-controller;
#interrupt-cells = <4>;
- cell-index = <0>;
};
apps_smmu: iommu@15000000 {
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index ec6003212c4d..775700f78e0f 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -8,6 +8,7 @@
#include <dt-bindings/clock/qcom,gpucc-sdm660.h>
#include <dt-bindings/clock/qcom,mmcc-sdm660.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/interconnect/qcom,sdm660.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/gpio/gpio.h>
@@ -453,7 +454,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
smem_region: smem-mem@86000000 {
@@ -1028,6 +1029,65 @@
};
};
+ remoteproc_mss: remoteproc@4080000 {
+ compatible = "qcom,sdm660-mss-pil";
+ reg = <0x04080000 0x100>, <0x04180000 0x40>;
+ reg-names = "qdsp6", "rmb";
+
+ interrupts-extended = <&intc GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+ <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+ <&modem_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+ <&modem_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+ <&modem_smp2p_in 3 IRQ_TYPE_EDGE_RISING>,
+ <&modem_smp2p_in 7 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "wdog",
+ "fatal",
+ "ready",
+ "handover",
+ "stop-ack",
+ "shutdown-ack";
+
+ clocks = <&gcc GCC_MSS_CFG_AHB_CLK>,
+ <&gcc GCC_BIMC_MSS_Q6_AXI_CLK>,
+ <&gcc GCC_BOOT_ROM_AHB_CLK>,
+ <&gcc GPLL0_OUT_MSSCC>,
+ <&gcc GCC_MSS_SNOC_AXI_CLK>,
+ <&gcc GCC_MSS_MNOC_BIMC_AXI_CLK>,
+ <&rpmcc RPM_SMD_QDSS_CLK>,
+ <&rpmcc RPM_SMD_XO_CLK_SRC>;
+ clock-names = "iface",
+ "bus",
+ "mem",
+ "gpll0_mss",
+ "snoc_axi",
+ "mnoc_axi",
+ "qdss",
+ "xo";
+
+ qcom,smem-states = <&modem_smp2p_out 0>;
+ qcom,smem-state-names = "stop";
+
+ resets = <&gcc GCC_MSS_RESTART>;
+ reset-names = "mss_restart";
+
+ qcom,halt-regs = <&tcsr_regs_1 0x3000 0x5000 0x4000>;
+
+ power-domains = <&rpmpd SDM660_VDDCX>,
+ <&rpmpd SDM660_VDDMX>;
+ power-domain-names = "cx", "mx";
+
+ memory-region = <&mba_region>, <&mpss_region>;
+
+ status = "disabled";
+
+ glink-edge {
+ interrupts = <GIC_SPI 452 IRQ_TYPE_EDGE_RISING>;
+ label = "modem";
+ qcom,remote-pid = <1>;
+ mboxes = <&apcs_glb 15>;
+ };
+ };
+
adreno_gpu: gpu@5000000 {
compatible = "qcom,adreno-508.0", "qcom,adreno";
@@ -1416,10 +1476,10 @@
clocks = <&gcc GCC_CFG_NOC_USB2_AXI_CLK>,
<&gcc GCC_USB20_MASTER_CLK>,
- <&gcc GCC_USB20_MOCK_UTMI_CLK>,
- <&gcc GCC_USB20_SLEEP_CLK>;
+ <&gcc GCC_USB20_SLEEP_CLK>,
+ <&gcc GCC_USB20_MOCK_UTMI_CLK>;
clock-names = "cfg_noc", "core",
- "mock_utmi", "sleep";
+ "sleep", "mock_utmi";
assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>,
<&gcc GCC_USB20_MASTER_CLK>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 84cd2e39266f..ba2043d67370 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -1328,7 +1328,8 @@
compatible = "qcom,sdm670-pdc", "qcom,pdc";
reg = <0 0x0b220000 0 0x30000>;
qcom,pdc-ranges = <0 480 40>, <41 521 7>, <49 529 4>,
- <54 534 24>, <79 559 30>, <115 630 7>;
+ <54 534 24>, <79 559 15>, <94 609 15>,
+ <115 630 7>;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupt-controller;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
index f86e7acdfd99..0ab5e8f53ac9 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
@@ -143,16 +143,20 @@
};
};
+&cpufreq_hw {
+ /delete-property/ interrupts-extended; /* reference to lmh_cluster[01] */
+};
+
&psci {
- /delete-node/ cpu0;
- /delete-node/ cpu1;
- /delete-node/ cpu2;
- /delete-node/ cpu3;
- /delete-node/ cpu4;
- /delete-node/ cpu5;
- /delete-node/ cpu6;
- /delete-node/ cpu7;
- /delete-node/ cpu-cluster0;
+ /delete-node/ power-domain-cpu0;
+ /delete-node/ power-domain-cpu1;
+ /delete-node/ power-domain-cpu2;
+ /delete-node/ power-domain-cpu3;
+ /delete-node/ power-domain-cpu4;
+ /delete-node/ power-domain-cpu5;
+ /delete-node/ power-domain-cpu6;
+ /delete-node/ power-domain-cpu7;
+ /delete-node/ power-domain-cluster;
};
&cpus {
@@ -275,6 +279,14 @@
&CLUSTER_SLEEP_0>;
};
+&lmh_cluster0 {
+ status = "disabled";
+};
+
+&lmh_cluster1 {
+ status = "disabled";
+};
+
/*
* Reserved memory changes
*
@@ -338,6 +350,8 @@
&apps_rsc {
+ /delete-property/ power-domains;
+
regulators-0 {
compatible = "qcom,pm8998-rpmh-regulators";
qcom,pmic-id = "a";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi
index f942c5afea9b..99dafc6716e7 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi
@@ -111,7 +111,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
/* rmtfs upper guard */
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
index b3c27a524742..76bfa786612c 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
@@ -114,7 +114,7 @@
&adsp_pas {
status = "okay";
- firmware-name = "qcom/sdm845/adsp.mdt";
+ firmware-name = "qcom/sdm845/adsp.mbn";
};
&apps_rsc {
@@ -415,7 +415,7 @@
&cdsp_pas {
status = "okay";
- firmware-name = "qcom/sdm845/cdsp.mdt";
+ firmware-name = "qcom/sdm845/cdsp.mbn";
};
&gcc {
@@ -533,6 +533,38 @@
firmware-name = "qcom/sdm845/mba.mbn", "qcom/sdm845/modem.mbn";
};
+&pcie0 {
+ perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&pcie0_default_state>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&pcie0_phy {
+ vdda-phy-supply = <&vreg_l1a_0p875>;
+ vdda-pll-supply = <&vreg_l26a_1p2>;
+
+ status = "okay";
+};
+
+&pcie1 {
+ perst-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_default_state>;
+
+ status = "okay";
+};
+
+&pcie1_phy {
+ status = "okay";
+
+ vdda-phy-supply = <&vreg_l1a_0p875>;
+ vdda-pll-supply = <&vreg_l26a_1p2>;
+};
+
&pm8998_adc {
channel@4c {
reg = <ADC5_XO_THERM_100K_PU>;
@@ -609,6 +641,11 @@
};
};
+&pm8998_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
&qupv3_id_1 {
status = "okay";
};
@@ -625,6 +662,52 @@
cd-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>;
};
+&tlmm {
+ pcie0_default_state: pcie0-default-state {
+ clkreq-pins {
+ pins = "gpio36";
+ function = "pci_e0";
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio35";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ wake-n-pins {
+ pins = "gpio37";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ pcie1_default_state: pcie1-default-state {
+ clkreq-pins {
+ pins = "gpio103";
+ function = "pci_e1";
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio102";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-pull-down;
+ };
+
+ wake-n-pins {
+ pins = "gpio104";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+};
+
&uart9 {
status = "okay";
};
@@ -716,6 +799,9 @@
vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+
+ qcom,snoc-host-cap-8bit-quirk;
+ qcom,ath10k-calibration-variant = "Qualcomm_sdm845mtp";
};
/* PINCTRL - additions to nodes defined in sdm845.dtsi */
diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
index 122c7128dea9..b523b5fff702 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
@@ -90,7 +90,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
rmtfs_upper_guard: rmtfs-upper-guard@f5d01000 {
no-map;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akari.dts b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akari.dts
index d97b7f1e7140..6e65909ab582 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akari.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akari.dts
@@ -15,3 +15,173 @@
&panel {
compatible = "sony,td4353-jdi-tama";
};
+
+&pmi8998_gpios {
+ gpio-line-names = "NC", /* GPIO_1 */
+ "NC",
+ "NC",
+ "",
+ "NC",
+ "NC",
+ "",
+ "WLC_EN_N",
+ "NC",
+ "NC", /* GPIO_10 */
+ "RSVD(WLC_EN_N)",
+ "CAM_IO_EN",
+ "",
+ "NC";
+};
+
+&tlmm {
+ gpio-line-names = "NC", /* GPIO_0 */
+ "NC",
+ "NC",
+ "NC",
+ "DEBUG_UART_TX",
+ "DEBUG_UART_RX",
+ "DISP_RESET_N",
+ "NC",
+ "CHAT_CAM_PWR_EN",
+ "CAM2_RSTN",
+ "MDP_VSYNC_P", /* GPIO_10 */
+ "RGBC_IR_INT",
+ "NFC_VEN",
+ "CAM_MCLK0",
+ "CAM_MCLK1",
+ "NC",
+ "NC",
+ "CCI_I2C_SDA0",
+ "CCI_I2C_SCL0",
+ "CCI_I2C_SDA1",
+ "CCI_I2C_SCL1", /* GPIO_20 */
+ "CAM_SOF",
+ "TOF_INT",
+ "TOF_RESET_N",
+ "NC",
+ "NC",
+ "NC",
+ "MAIN_CAM_PWR_EN",
+ "DVDT_ENABLE",
+ "DVDT_WRT_DET_AND",
+ "DVDT_WRT_DET_OR", /* GPIO_30 */
+ "WLC_INT_N",
+ "NC",
+ "CAMSENSOR_I2C_SDA",
+ "CAMSENSOR_I2C_SCL",
+ "NC",
+ "NC",
+ "NC",
+ "CC_DIR",
+ "NC",
+ "FP_RESET_N", /* GPIO_40 */
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "BT_HCI_UART_CTS_N",
+ "BT_HCI_UART_RFR_N",
+ "BT_HCI_UART_TXD",
+ "BT_HCI_UART_TRXD",
+ "USB_AUDIO_EN1",
+ "SW_SERVICE", /* GPIO_50 */
+ "US_EURO_SEL",
+ "NC",
+ "CODEC_INT2_N",
+ "CODEC_INT1_N",
+ "APPS_I2C_SDA",
+ "APPS_I2C_SCL",
+ "FORCED_USB_BOOT",
+ "NC",
+ "NC",
+ "NC", /* GPIO_60 */
+ "USB_PD_EN",
+ "NFC_DWLD_EN",
+ "NFC_IRQ",
+ "CODEC_RST_N",
+ "CODEC_SPI_MISO",
+ "CODEC_SPI_MOSI",
+ "CODEC_SPI_CLK",
+ "CODEC_SPI_CS_N",
+ "NC",
+ "CODEC_SLIMBUS_CLK", /* GPIO_70 */
+ "CODEC_SLIMBUS_DATA0",
+ "CODEC_SLIMBUS_DATA1",
+ "BT_FM_SLIMBUS_DATA",
+ "BT_FM_SLIMBUS_CLK",
+ "HW_ID_0",
+ "HW_ID_1",
+ "TX_GTR_THRES_IN",
+ "NC",
+ "NC",
+ "CAM1_RSTN", /* GPIO_80 */
+ "",
+ "",
+ "",
+ "",
+ "TS_I2C_SDA",
+ "TS_I2C_SCL",
+ "NC",
+ "NC",
+ "NC",
+ "NC", /* GPIO_90 */
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "RFFE6_CLK",
+ "RFFE6_DATA",
+ "TS_RESET_N",
+ "", /* GPIO_100 */
+ "GRFC4",
+ "DEBUG_GPIO0",
+ "DEBUG_GPIO1",
+ "RF_LCD_ID_EN",
+ "UIM2_DATA",
+ "UIM2_CLK",
+ "UIM2_RESET",
+ "UIM2_PRESENT",
+ "UIM1_DATA",
+ "UIM1_CLK", /* GPIO_110 */
+ "UIM1_RESET",
+ "UIM1_PRESENT",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "ACCEL_INT",
+ "GYRO_INT",
+ "COMPASS_INT",
+ "ALS_PROX_INT_N", /* GPIO_120 */
+ "FP_INT",
+ "RF_ID_EXTENTION",
+ "BAROMETER_INT",
+ "ACC_COVER_OPEN",
+ "TS_INT_N",
+ "TRAY_DET",
+ "GRFC3",
+ "NC",
+ "UIM2_DETECT_EN",
+ "QLINK_REQUEST", /* GPIO_130 */
+ "QLINK_ENABLE",
+ "GRFC2",
+ "NC",
+ "WMSS_RESET_N",
+ "PA_INDICATOR_OR",
+ "GRFC1",
+ "RFFE3_DATA",
+ "RFFE3_CLK",
+ "RFFE4_DATA",
+ "RFFE4_CLK", /* GPIO_140 */
+ "RFFE5_DATA",
+ "RFFE5_CLK",
+ "GNSS_EN",
+ "MSS_LTE_COXM_TXD",
+ "MSS_LTE_COXM_RXD",
+ "RFFE2_DATA",
+ "RFFE2_CLK",
+ "RFFE1_DATA",
+ "RFFE1_CLK";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts
index 5d2052a0ff69..82e59e453354 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts
@@ -44,11 +44,179 @@
/delete-property/ touch-reset-gpios;
};
+&pmi8998_gpios {
+ gpio-line-names = "NC", /* GPIO_1 */
+ "NC",
+ "NC",
+ "",
+ "NC",
+ "NC",
+ "",
+ "WLC_EN_N",
+ "NC",
+ "NC", /* GPIO_10 */
+ "NC",
+ "CAM_IO_EN",
+ "",
+ "NC";
+};
+
&pmi8998_wled {
status = "disabled";
};
&tlmm {
+ gpio-line-names = "NC", /* GPIO_0 */
+ "NC",
+ "NC",
+ "NC",
+ "DEBUG_UART_TX",
+ "DEBUG_UART_RX",
+ "DISP_RESET_N",
+ "SAMD_RSTEN_N",
+ "CHAT_CAM_PWR_EN",
+ "CAM2_RSTN",
+ "MDP_VSYNC_P", /* GPIO_10 */
+ "RGBC_IR_INT",
+ "NFC_VEN",
+ "CAM_MCLK0",
+ "CAM_MCLK1",
+ "NC",
+ "MASTER_RST_N",
+ "CCI_I2C_SDA0",
+ "CCI_I2C_SCL0",
+ "CCI_I2C_SDA1",
+ "CCI_I2C_SCL1", /* GPIO_20 */
+ "CAM_SOF",
+ "TOF_INT",
+ "TOF_RESET_N",
+ "NC",
+ "NC",
+ "NC",
+ "MAIN_CAM_PWR_EN",
+ "DVDT_ENABLE",
+ "DVDT_WRT_DET_AND",
+ "DVDT_WRT_DET_OR", /* GPIO_30 */
+ "WLC_INT_N",
+ "NC",
+ "CAMSENSOR_I2C_SDA",
+ "CAMSENSOR_I2C_SCL",
+ "NC",
+ "NC",
+ "NC",
+ "CC_DIR",
+ "NC",
+ "FP_RESET_N", /* GPIO_40 */
+ "NC",
+ "NC",
+ "NC",
+ "DISP_ERR_FG",
+ "BT_HCI_UART_CTS_N",
+ "BT_HCI_UART_RFR_N",
+ "BT_HCI_UART_TXD",
+ "BT_HCI_UART_TRXD",
+ "USB_AUDIO_EN1",
+ "SW_SERVICE", /* GPIO_50 */
+ "US_EURO_SEL",
+ "SAMD_BOOTL_PIN",
+ "CODEC_INT2_N",
+ "CODEC_INT1_N",
+ "APPS_I2C_SDA",
+ "APPS_I2C_SCL",
+ "FORCED_USB_BOOT",
+ "SDM_SWD_CLK",
+ "SDM_SWD_DAT",
+ "SAMD_RST", /* GPIO_60 */
+ "USB_PD_EN",
+ "NFC_DWLD_EN",
+ "NFC_IRQ",
+ "CODEC_RST_N",
+ "CODEC_SPI_MISO",
+ "CODEC_SPI_MOSI",
+ "CODEC_SPI_CLK",
+ "CODEC_SPI_CS_N",
+ "NC",
+ "CODEC_SLIMBUS_CLK", /* GPIO_70 */
+ "CODEC_SLIMBUS_DATA0",
+ "CODEC_SLIMBUS_DATA1",
+ "BT_FM_SLIMBUS_DATA",
+ "BT_FM_SLIMBUS_CLK",
+ "HW_ID_0",
+ "HW_ID_1",
+ "TX_GTR_THRES_IN",
+ "MODE_SEL2",
+ "NC",
+ "CAM1_RSTN", /* GPIO_80 */
+ "",
+ "",
+ "",
+ "",
+ "TS_I2C_SDA",
+ "TS_I2C_SCL",
+ "NC",
+ "NC",
+ "NC",
+ "NC", /* GPIO_90 */
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "RFFE6_CLK",
+ "RFFE6_DATA",
+ "TS_RESET_N",
+ "", /* GPIO_100 */
+ "GRFC4",
+ "DEBUG_GPIO0",
+ "DEBUG_GPIO1",
+ "RF_LCD_ID_EN",
+ "UIM2_DATA",
+ "UIM2_CLK",
+ "UIM2_RESET",
+ "UIM2_PRESENT",
+ "UIM1_DATA",
+ "UIM1_CLK", /* GPIO_110 */
+ "UIM1_RESET",
+ "UIM1_PRESENT",
+ "NC",
+ "NC",
+ "NC",
+ "NFC_ESE_PWR_REQ",
+ "ACCEL_INT",
+ "GYRO_INT",
+ "COMPASS_INT",
+ "ALS_PROX_INT_N", /* GPIO_120 */
+ "FP_INT",
+ "RF_ID_EXTENTION",
+ "BAROMETER_INT",
+ "ACC_COVER_OPEN",
+ "TS_INT_N",
+ "TRAY_DET",
+ "GRFC3",
+ "NC",
+ "UIM2_DETECT_EN",
+ "QLINK_REQUEST", /* GPIO_130 */
+ "QLINK_ENABLE",
+ "GRFC2",
+ "TS_VDDIO_EN",
+ "WMSS_RESET_N",
+ "PA_INDICATOR_OR",
+ "GRFC1",
+ "RFFE3_DATA",
+ "RFFE3_CLK",
+ "RFFE4_DATA",
+ "RFFE4_CLK", /* GPIO_140 */
+ "RFFE5_DATA",
+ "RFFE5_CLK",
+ "GNSS_EN",
+ "MSS_LTE_COXM_TXD",
+ "MSS_LTE_COXM_RXD",
+ "RFFE2_DATA",
+ "RFFE2_CLK",
+ "RFFE1_DATA",
+ "RFFE1_CLK";
+
ts_vddio_en: ts-vddio-en-state {
pins = "gpio133";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-apollo.dts b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-apollo.dts
index cd056f78070f..dc15ab1a2716 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-apollo.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-apollo.dts
@@ -17,3 +17,173 @@
height-mm = <112>;
width-mm = <56>;
};
+
+&pmi8998_gpios {
+ gpio-line-names = "NC", /* GPIO_1 */
+ "NC",
+ "NC",
+ "",
+ "VIB_LDO_EN",
+ "NC",
+ "",
+ "NC",
+ "NC",
+ "NC", /* GPIO_10 */
+ "NC",
+ "CAM_IO_EN",
+ "",
+ "NC";
+};
+
+&tlmm {
+ gpio-line-names = "NC", /* GPIO_0 */
+ "NC",
+ "NC",
+ "NC",
+ "DEBUG_UART_TX",
+ "DEBUG_UART_RX",
+ "DISP_RESET_N",
+ "NC",
+ "CHAT_CAM_PWR_EN",
+ "CAM2_RSTN",
+ "MDP_VSYNC_P", /* GPIO_10 */
+ "RGBC_IR_INT",
+ "NFC_VEN",
+ "CAM_MCLK0",
+ "CAM_MCLK1",
+ "NC",
+ "NC",
+ "CCI_I2C_SDA0",
+ "CCI_I2C_SCL0",
+ "CCI_I2C_SDA1",
+ "CCI_I2C_SCL1", /* GPIO_20 */
+ "CAM_SOF",
+ "TOF_INT",
+ "TOF_RESET_N",
+ "NC",
+ "NC",
+ "NC",
+ "MAIN_CAM_PWR_EN",
+ "DVDT_ENABLE",
+ "DVDT_WRT_DET_AND",
+ "DVDT_WRT_DET_OR", /* GPIO_30 */
+ "NC",
+ "NC",
+ "CAMSENSOR_I2C_SDA",
+ "CAMSENSOR_I2C_SCL",
+ "NC",
+ "NC",
+ "NC",
+ "CC_DIR",
+ "NC",
+ "FP_RESET_N", /* GPIO_40 */
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "BT_HCI_UART_CTS_N",
+ "BT_HCI_UART_RFR_N",
+ "BT_HCI_UART_TXD",
+ "BT_HCI_UART_TRXD",
+ "USB_AUDIO_EN1",
+ "SW_SERVICE", /* GPIO_50 */
+ "US_EURO_SEL",
+ "NC",
+ "CODEC_INT2_N",
+ "CODEC_INT1_N",
+ "APPS_I2C_SDA",
+ "APPS_I2C_SCL",
+ "FORCED_USB_BOOT",
+ "NC",
+ "NC",
+ "NC", /* GPIO_60 */
+ "USB_PD_EN",
+ "NFC_DWLD_EN",
+ "NFC_IRQ",
+ "CODEC_RST_N",
+ "CODEC_SPI_MISO",
+ "CODEC_SPI_MOSI",
+ "CODEC_SPI_CLK",
+ "CODEC_SPI_CS_N",
+ "NC",
+ "CODEC_SLIMBUS_CLK", /* GPIO_70 */
+ "CODEC_SLIMBUS_DATA0",
+ "CODEC_SLIMBUS_DATA1",
+ "BT_FM_SLIMBUS_DATA",
+ "BT_FM_SLIMBUS_CLK",
+ "HW_ID_0",
+ "HW_ID_1",
+ "TX_GTR_THRES_IN",
+ "NC",
+ "NC",
+ "CAM1_RSTN", /* GPIO_80 */
+ "",
+ "",
+ "",
+ "",
+ "TS_I2C_SDA",
+ "TS_I2C_SCL",
+ "NC",
+ "NC",
+ "NC",
+ "NC", /* GPIO_90 */
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "RFFE6_CLK",
+ "RFFE6_DATA",
+ "TS_RESET_N",
+ "", /* GPIO_100 */
+ "GRFC4",
+ "DEBUG_GPIO0",
+ "DEBUG_GPIO1",
+ "RF_LCD_ID_EN",
+ "UIM2_DATA",
+ "UIM2_CLK",
+ "UIM2_RESET",
+ "UIM2_PRESENT",
+ "UIM1_DATA",
+ "UIM1_CLK", /* GPIO_110 */
+ "UIM1_RESET",
+ "UIM1_PRESENT",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "ACCEL_INT",
+ "GYRO_INT",
+ "COMPASS_INT",
+ "ALS_PROX_INT_N", /* GPIO_120 */
+ "FP_INT",
+ "RF_ID_EXTENTION",
+ "BAROMETER_INT",
+ "ACC_COVER_OPEN",
+ "TS_INT_N",
+ "TRAY_DET",
+ "GRFC3",
+ "NC",
+ "UIM2_DETECT_EN",
+ "QLINK_REQUEST", /* GPIO_130 */
+ "QLINK_ENABLE",
+ "GRFC2",
+ "NC",
+ "WMSS_RESET_N",
+ "PA_INDICATOR_OR",
+ "GRFC1",
+ "RFFE3_DATA",
+ "RFFE3_CLK",
+ "RFFE4_DATA",
+ "RFFE4_CLK", /* GPIO_140 */
+ "RFFE5_DATA",
+ "RFFE5_CLK",
+ "GNSS_EN",
+ "MSS_LTE_COXM_TXD",
+ "MSS_LTE_COXM_RXD",
+ "RFFE2_DATA",
+ "RFFE2_CLK",
+ "RFFE1_DATA",
+ "RFFE1_CLK";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi
index 7ee61b20452e..b02a1dc5fecd 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi
@@ -67,6 +67,36 @@
};
};
+ cam_vana_front_vreg: cam-vana-front-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "cam_vana_front_vreg";
+ gpio = <&tlmm 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&chat_cam_pwr_en>;
+ pinctrl-names = "default";
+ };
+
+ cam_vana_rear_vreg: cam-vana-rear-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "cam_vana_rear_vreg";
+ gpio = <&tlmm 27 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&main_cam_pwr_en>;
+ pinctrl-names = "default";
+ };
+
+ cam_vio_vreg: cam-vio-reagulator {
+ compatible = "regulator-fixed";
+ regulator-name = "cam_vio_vreg";
+ gpio = <&pmi8998_gpios 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&cam_io_en>;
+ pinctrl-names = "default";
+ };
+
vph_pwr: vph-pwr-regulator {
compatible = "regulator-fixed";
regulator-name = "vph_pwr";
@@ -524,7 +554,41 @@
status = "okay";
};
+&pm8005_gpios {
+ gpio-line-names = "NC", /* GPIO_1 */
+ "NC",
+ "",
+ "";
+};
+
&pm8998_gpios {
+ gpio-line-names = "NC", /* GPIO_1 */
+ "FOCUS_N",
+ "",
+ "NC",
+ "VOL_DOWN_N",
+ "VOL_UP_N",
+ "SNAPSHOT_N",
+ "NC",
+ "FLASH_THERM",
+ "NC", /* GPIO_10 */
+ "LCD_ID",
+ "RF_ID",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "", /* GPIO_20 */
+ "NFC_CLK_REQ",
+ "",
+ "",
+ "",
+ "",
+ "";
+
focus_n: focus-n-state {
pins = "gpio2";
function = PMIC_GPIO_FUNC_NORMAL;
@@ -558,6 +622,17 @@
};
};
+&pmi8998_gpios {
+ cam_io_en: cam-io-en-state {
+ pins = "gpio12";
+ function = "normal";
+ qcom,drive-strength = <3>;
+ power-source = <0>;
+ drive-push-pull;
+ output-low;
+ };
+};
+
&pmi8998_wled {
default-brightness = <800>;
qcom,switching-freq = <800>;
@@ -626,6 +701,14 @@
bias-pull-down;
};
+ chat_cam_pwr_en: chat-cam-pwr-en-state {
+ pins = "gpio8";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+
sde_te_active_sleep: sde-te-active-sleep-state {
pins = "gpio10";
function = "mdp_vsync";
@@ -633,6 +716,14 @@
bias-pull-down;
};
+ main_cam_pwr_en: main-cam-pwr-en-state {
+ pins = "gpio27";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+
ts_default: ts-default-state {
reset-pins {
pins = "gpio99";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi
index 9d6faeb65624..93b1582e807d 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi
@@ -111,7 +111,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
index 6db12abaa88d..e386b504e978 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
@@ -108,7 +108,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 055ca80c0075..bf5e6eb9d313 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -18,6 +18,7 @@
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sdm845.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/phy/phy-qcom-qusb2.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/reset/qcom,sdm845-aoss.h>
@@ -813,7 +814,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
qseecom_mem: qseecom@8ab00000 {
@@ -1197,8 +1198,8 @@
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&rpmhcc RPMH_CXO_CLK_A>,
<&sleep_clk>,
- <&pcie0_lane>,
- <&pcie1_lane>;
+ <&pcie0_phy>,
+ <&pcie1_phy>;
clock-names = "bi_tcxo",
"bi_tcxo_ao",
"sleep_clk",
@@ -2370,7 +2371,7 @@
power-domains = <&gcc PCIE_0_GDSC>;
- phys = <&pcie0_lane>;
+ phys = <&pcie0_phy>;
phy-names = "pciephy";
status = "disabled";
@@ -2378,15 +2379,22 @@
pcie0_phy: phy@1c06000 {
compatible = "qcom,sdm845-qmp-pcie-phy";
- reg = <0 0x01c06000 0 0x18c>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c06000 0 0x1000>;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
<&gcc GCC_PCIE_0_CLKREF_CLK>,
- <&gcc GCC_PCIE_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_0_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+
+ clock-output-names = "pcie_0_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_0_PHY_BCR>;
reset-names = "phy";
@@ -2395,19 +2403,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie0_lane: phy@1c06200 {
- reg = <0 0x01c06200 0 0x128>,
- <0 0x01c06400 0 0x1fc>,
- <0 0x01c06800 0 0x218>,
- <0 0x01c06600 0 0x70>;
- clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
- clock-names = "pipe0";
-
- #clock-cells = <0>;
- #phy-cells = <0>;
- clock-output-names = "pcie_0_pipe_clk";
- };
};
pcie1: pci@1c08000 {
@@ -2480,7 +2475,7 @@
power-domains = <&gcc PCIE_1_GDSC>;
- phys = <&pcie1_lane>;
+ phys = <&pcie1_phy>;
phy-names = "pciephy";
status = "disabled";
@@ -2488,15 +2483,22 @@
pcie1_phy: phy@1c0a000 {
compatible = "qcom,sdm845-qhp-pcie-phy";
- reg = <0 0x01c0a000 0 0x800>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c0a000 0 0x2000>;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
<&gcc GCC_PCIE_1_CLKREF_CLK>,
- <&gcc GCC_PCIE_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_1_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+
+ clock-output-names = "pcie_1_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_1_PHY_BCR>;
reset-names = "phy";
@@ -2505,18 +2507,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie1_lane: phy@1c06200 {
- reg = <0 0x01c0a800 0 0x800>,
- <0 0x01c0a800 0 0x800>,
- <0 0x01c0b800 0 0x400>;
- clocks = <&gcc GCC_PCIE_1_PIPE_CLK>;
- clock-names = "pipe0";
-
- #clock-cells = <0>;
- #phy-cells = <0>;
- clock-output-names = "pcie_1_pipe_clk";
- };
};
mem_noc: interconnect@1380000 {
@@ -3984,49 +3974,28 @@
nvmem-cells = <&qusb2s_hstx_trim>;
};
- usb_1_qmpphy: phy@88e9000 {
+ usb_1_qmpphy: phy@88e8000 {
compatible = "qcom,sdm845-qmp-usb3-dp-phy";
- reg = <0 0x088e9000 0 0x18c>,
- <0 0x088e8000 0 0x38>,
- <0 0x088ea000 0 0x40>;
+ reg = <0 0x088e8000 0 0x3000>;
status = "disabled";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
- <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
<&gcc GCC_USB3_PRIM_CLKREF_CLK>,
- <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "com_aux";
+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>,
+ <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>;
+ clock-names = "aux",
+ "ref",
+ "com_aux",
+ "usb3_pipe",
+ "cfg_ahb";
resets = <&gcc GCC_USB3_PHY_PRIM_BCR>,
<&gcc GCC_USB3_DP_PHY_PRIM_BCR>;
reset-names = "phy", "common";
- usb_1_ssphy: usb3-phy@88e9200 {
- reg = <0 0x088e9200 0 0x128>,
- <0 0x088e9400 0 0x200>,
- <0 0x088e9c00 0 0x218>,
- <0 0x088e9600 0 0x128>,
- <0 0x088e9800 0 0x200>,
- <0 0x088e9a00 0 0x100>;
- #clock-cells = <0>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "usb3_phy_pipe_clk_src";
- };
-
- dp_phy: dp-phy@88ea200 {
- reg = <0 0x088ea200 0 0x200>,
- <0 0x088ea400 0 0x200>,
- <0 0x088eaa00 0 0x200>,
- <0 0x088ea600 0 0x200>,
- <0 0x088ea800 0 0x200>;
- #clock-cells = <1>;
- #phy-cells = <0>;
- };
+ #clock-cells = <1>;
+ #phy-cells = <1>;
};
usb_2_qmpphy: phy@88eb000 {
@@ -4106,7 +4075,7 @@
iommus = <&apps_smmu 0x740 0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
- phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
+ phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
};
};
@@ -4574,8 +4543,9 @@
"ctrl_link_iface", "stream_pixel";
assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
<&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
- assigned-clock-parents = <&dp_phy 0>, <&dp_phy 1>;
- phys = <&dp_phy>;
+ assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
+ phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>;
phy-names = "dp";
operating-points-v2 = <&dp_opp_table>;
@@ -4913,8 +4883,8 @@
<&mdss_dsi0_phy 1>,
<&mdss_dsi1_phy 0>,
<&mdss_dsi1_phy 1>,
- <&dp_phy 0>,
- <&dp_phy 1>;
+ <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
clock-names = "bi_tcxo",
"gcc_disp_gpll0_clk_src",
"gcc_disp_gpll0_div_clk_src",
diff --git a/arch/arm64/boot/dts/qcom/sdx75-idp.dts b/arch/arm64/boot/dts/qcom/sdx75-idp.dts
index 10d15871f2c4..a14e0650c4a8 100644
--- a/arch/arm64/boot/dts/qcom/sdx75-idp.dts
+++ b/arch/arm64/boot/dts/qcom/sdx75-idp.dts
@@ -44,7 +44,7 @@
};
&apps_rsc {
- pmx75-rpmh-regulators {
+ regulators-0 {
compatible = "qcom,pmx75-rpmh-regulators";
qcom,pmic-id = "b";
diff --git a/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts b/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts
index 75951fd439df..2c7a12983dae 100644
--- a/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts
+++ b/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts
@@ -225,13 +225,13 @@
vcc-max-microamp = <600000>;
vccq2-supply = <&vreg_l11a>;
vccq2-max-microamp = <600000>;
+ vdd-hba-supply = <&vreg_l18a>;
status = "okay";
};
&ufs_mem_phy {
vdda-phy-supply = <&vreg_l4a>;
vdda-pll-supply = <&vreg_l12a>;
- vddp-ref-clk-supply = <&vreg_l18a>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts b/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts
index 9b70a87906dc..98eb072fa912 100644
--- a/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts
+++ b/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts
@@ -219,13 +219,13 @@
vcc-max-microamp = <600000>;
vccq2-supply = <&pm6125_l11a>;
vccq2-max-microamp = <600000>;
+ vdd-hba-supply = <&pm6125_l18a>;
status = "okay";
};
&ufs_mem_phy {
vdda-phy-supply = <&pm6125_l4a>;
vdda-pll-supply = <&pm6125_l12a>;
- vddp-ref-clk-supply = <&pm6125_l18a>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts b/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
index c2d15fc6c96b..54da053a8042 100644
--- a/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
+++ b/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
@@ -344,13 +344,13 @@
vcc-max-microamp = <600000>;
vccq2-supply = <&pm6125_l11>;
vccq2-max-microamp = <600000>;
+ vdd-hba-supply = <&pm6125_l18>;
status = "okay";
};
&ufs_mem_phy {
vdda-phy-supply = <&pm6125_l4>;
vdda-pll-supply = <&pm6125_l12>;
- vddp-ref-clk-supply = <&pm6125_l18>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
index fb4cba004367..08046f866f60 100644
--- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
@@ -179,6 +179,43 @@
/* Cirrus Logic CS35L41 boosted audio amplifier @ 40 */
};
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0 {
+ vdda-supply = <&pm6125_l18>;
+ status = "okay";
+
+ panel@0 {
+ compatible = "samsung,sofef01-m-ams597ut01";
+ reg = <0>;
+
+ reset-gpios = <&tlmm 90 GPIO_ACTIVE_LOW>;
+
+ vddio-supply = <&pm6125_l12>;
+
+ pinctrl-0 = <&mdss_dsi_active &mdss_te_active_sleep>;
+ pinctrl-1 = <&mdss_dsi_sleep &mdss_te_active_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+};
+
+&mdss_dsi0_out {
+ remote-endpoint = <&panel_in>;
+ data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi0_phy {
+ status = "okay";
+};
+
&pm6125_adc {
pinctrl-names = "default";
pinctrl-0 = <&camera_flash_therm &emmc_ufs_therm &rf_pa1_therm>;
@@ -474,6 +511,28 @@
drive-strength = <2>;
bias-disable;
};
+
+ mdss_te_active_sleep: mdss-te-active-sleep-state {
+ pins = "gpio89";
+ function = "mdp_vsync";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ mdss_dsi_active: mdss-dsi-active-state {
+ pins = "gpio90";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ mdss_dsi_sleep: mdss-dsi-sleep-state {
+ pins = "gpio90";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
};
&usb3 {
diff --git a/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts b/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts
index 272bc85f1719..a49d3ebb1931 100644
--- a/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts
+++ b/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts
@@ -400,15 +400,13 @@
vccq2-supply = <&vreg_l11a>;
vcc-max-microamp = <600000>;
vccq2-max-microamp = <600000>;
+ vdd-hba-supply = <&vreg_l18a>;
status = "okay";
};
&ufs_mem_phy {
vdda-phy-supply = <&vreg_l4a>;
vdda-pll-supply = <&vreg_l10a>;
- vdda-phy-max-microamp = <51400>;
- vdda-pll-max-microamp = <14200>;
- vddp-ref-clk-supply = <&vreg_l18a>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
index d7c1a40617c6..eb07eca3a48d 100644
--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
@@ -3,6 +3,7 @@
* Copyright (c) 2021, Martin Botka <martin.botka@somainline.org>
*/
+#include <dt-bindings/clock/qcom,dispcc-sm6125.h>
#include <dt-bindings/clock/qcom,gcc-sm6125.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/dma/qcom-gpi.h>
@@ -22,7 +23,6 @@
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <19200000>;
- clock-output-names = "xo_board";
};
sleep_clk: sleep-clk {
@@ -198,6 +198,8 @@
rpmcc: clock-controller {
compatible = "qcom,rpmcc-sm6125", "qcom,rpmcc";
#clock-cells = <1>;
+ clocks = <&xo_board>;
+ clock-names = "xo";
};
rpmpd: power-controller {
@@ -683,6 +685,24 @@
status = "disabled";
};
+ spmi_bus: spmi@1c40000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0x01c40000 0x1100>,
+ <0x01e00000 0x2000000>,
+ <0x03e00000 0x100000>,
+ <0x03f00000 0xa0000>,
+ <0x01c0a000 0x26000>;
+ reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+ interrupt-names = "periph_irq";
+ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+ qcom,ee = <0>;
+ qcom,channel = <0>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ };
+
rpm_msg_ram: sram@45f0000 {
compatible = "qcom,rpm-msg-ram";
reg = <0x045f0000 0x7000>;
@@ -699,7 +719,7 @@
clocks = <&gcc GCC_SDCC1_AHB_CLK>,
<&gcc GCC_SDCC1_APPS_CLK>,
- <&xo_board>;
+ <&rpmcc RPM_SMD_XO_CLK_SRC>;
clock-names = "iface", "core", "xo";
iommus = <&apps_smmu 0x160 0x0>;
@@ -726,7 +746,7 @@
clocks = <&gcc GCC_SDCC2_AHB_CLK>,
<&gcc GCC_SDCC2_APPS_CLK>,
- <&xo_board>;
+ <&rpmcc RPM_SMD_XO_CLK_SRC>;
clock-names = "iface", "core", "xo";
iommus = <&apps_smmu 0x180 0x0>;
@@ -1188,27 +1208,226 @@
reg = <0x04690000 0x10000>;
};
- spmi_bus: spmi@1c40000 {
- compatible = "qcom,spmi-pmic-arb";
- reg = <0x01c40000 0x1100>,
- <0x01e00000 0x2000000>,
- <0x03e00000 0x100000>,
- <0x03f00000 0xa0000>,
- <0x01c0a000 0x26000>;
- reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
- interrupt-names = "periph_irq";
- interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
- qcom,ee = <0>;
- qcom,channel = <0>;
- #address-cells = <2>;
- #size-cells = <0>;
+ mdss: display-subsystem@5e00000 {
+ compatible = "qcom,sm6125-mdss";
+ reg = <0x05e00000 0x1000>;
+ reg-names = "mdss";
+
+ interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
- #interrupt-cells = <4>;
+ #interrupt-cells = <1>;
+
+ clocks = <&gcc GCC_DISP_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_CLK>;
+ clock-names = "iface",
+ "ahb",
+ "core";
+
+ power-domains = <&dispcc MDSS_GDSC>;
+
+ iommus = <&apps_smmu 0x400 0x0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ status = "disabled";
+
+ mdss_mdp: display-controller@5e01000 {
+ compatible = "qcom,sm6125-dpu";
+ reg = <0x05e01000 0x83208>,
+ <0x05eb0000 0x2008>;
+ reg-names = "mdp", "vbif";
+
+ interrupt-parent = <&mdss>;
+ interrupts = <0>;
+
+ clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_ROT_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_CLK>,
+ <&dispcc DISP_CC_MDSS_VSYNC_CLK>,
+ <&gcc GCC_DISP_THROTTLE_CORE_CLK>;
+ clock-names = "bus",
+ "iface",
+ "rot",
+ "lut",
+ "core",
+ "vsync",
+ "throttle";
+ assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
+ assigned-clock-rates = <19200000>;
+
+ operating-points-v2 = <&mdp_opp_table>;
+ power-domains = <&rpmpd SM6125_VDDCX>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dpu_intf1_out: endpoint {
+ remote-endpoint = <&mdss_dsi0_in>;
+ };
+ };
+ };
+
+ mdp_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-192000000 {
+ opp-hz = /bits/ 64 <192000000>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ };
+
+ opp-256000000 {
+ opp-hz = /bits/ 64 <256000000>;
+ required-opps = <&rpmpd_opp_svs>;
+ };
+
+ opp-307200000 {
+ opp-hz = /bits/ 64 <307200000>;
+ required-opps = <&rpmpd_opp_svs_plus>;
+ };
+
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ required-opps = <&rpmpd_opp_nom>;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ required-opps = <&rpmpd_opp_turbo>;
+ };
+ };
+ };
+
+ mdss_dsi0: dsi@5e94000 {
+ compatible = "qcom,sm6125-dsi-ctrl", "qcom,mdss-dsi-ctrl";
+ reg = <0x05e94000 0x400>;
+ reg-names = "dsi_ctrl";
+
+ interrupt-parent = <&mdss>;
+ interrupts = <4>;
+
+ clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
+ <&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_PCLK0_CLK>,
+ <&dispcc DISP_CC_MDSS_ESC0_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&gcc GCC_DISP_HF_AXI_CLK>;
+ clock-names = "byte",
+ "byte_intf",
+ "pixel",
+ "core",
+ "iface",
+ "bus";
+ assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
+ <&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
+ assigned-clock-parents = <&mdss_dsi0_phy 0>, <&mdss_dsi0_phy 1>;
+
+ operating-points-v2 = <&dsi_opp_table>;
+ power-domains = <&rpmpd SM6125_VDDCX>;
+
+ phys = <&mdss_dsi0_phy>;
+ phy-names = "dsi";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ mdss_dsi0_in: endpoint {
+ remote-endpoint = <&dpu_intf1_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ mdss_dsi0_out: endpoint {
+ };
+ };
+ };
+
+ dsi_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-164000000 {
+ opp-hz = /bits/ 64 <164000000>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ };
+
+ opp-187500000 {
+ opp-hz = /bits/ 64 <187500000>;
+ required-opps = <&rpmpd_opp_svs>;
+ };
+ };
+ };
+
+ mdss_dsi0_phy: phy@5e94400 {
+ compatible = "qcom,sm6125-dsi-phy-14nm";
+ reg = <0x05e94400 0x100>,
+ <0x05e94500 0x300>,
+ <0x05e94800 0x188>;
+ reg-names = "dsi_phy",
+ "dsi_phy_lane",
+ "dsi_pll";
+
+ #clock-cells = <1>;
+ #phy-cells = <0>;
+
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&rpmcc RPM_SMD_XO_CLK_SRC>;
+ clock-names = "iface",
+ "ref";
+
+ required-opps = <&rpmpd_opp_nom>;
+ power-domains = <&rpmpd SM6125_VDDMX>;
+
+ status = "disabled";
+ };
+ };
+
+ dispcc: clock-controller@5f00000 {
+ compatible = "qcom,sm6125-dispcc";
+ reg = <0x05f00000 0x20000>;
+
+ clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+ <&mdss_dsi0_phy 0>,
+ <&mdss_dsi0_phy 1>,
+ <0>,
+ <0>,
+ <0>,
+ <&gcc GCC_DISP_AHB_CLK>,
+ <&gcc GCC_DISP_GPLL0_DIV_CLK_SRC>;
+ clock-names = "bi_tcxo",
+ "dsi0_phy_pll_out_byteclk",
+ "dsi0_phy_pll_out_dsiclk",
+ "dsi1_phy_pll_out_dsiclk",
+ "dp_phy_pll_link_clk",
+ "dp_phy_pll_vco_div_clk",
+ "cfg_ahb_clk",
+ "gcc_disp_gpll0_div_clk_src";
+
+ required-opps = <&rpmpd_opp_ret>;
+ power-domains = <&rpmpd SM6125_VDDCX>;
+
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
};
apps_smmu: iommu@c600000 {
compatible = "qcom,sm6125-smmu-500", "qcom,smmu-500", "arm,mmu-500";
- reg = <0xc600000 0x80000>;
+ reg = <0x0c600000 0x80000>;
interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi b/arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi
new file mode 100644
index 000000000000..e55cd83c19b8
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/arm/qcom,ids.h>
+#include <dt-bindings/firmware/qcom,scm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sm7125.dtsi"
+#include "pm6150.dtsi"
+#include "pm6150l.dtsi"
+
+/delete-node/ &ipa_fw_mem;
+/delete-node/ &rmtfs_mem;
+
+/ {
+ chassis-type = "handset";
+
+ qcom,msm-id = <QCOM_ID_SM7125 0>;
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ framebuffer@9c000000 {
+ compatible = "simple-framebuffer";
+ reg = <0x0 0x9c000000 0x0 (1080 * 2400 * 4)>;
+ width = <1080>;
+ height = <2400>;
+ stride = <(1080 * 4)>;
+ format = "a8r8g8b8";
+ clocks = <&gcc GCC_DISP_HF_AXI_CLK>;
+ };
+ };
+
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+
+ key-vol-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&pm6150l_gpios 2 GPIO_ACTIVE_LOW>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+ };
+
+ reserved-memory {
+ mpss_mem: memory@86000000 {
+ reg = <0x0 0x86000000 0x0 0x8400000>;
+ no-map;
+ };
+
+ venus_mem: memory@8ee00000 {
+ reg = <0x0 0x8ee00000 0x0 0x500000>;
+ no-map;
+ };
+
+ cdsp_mem: memory@8f300000 {
+ reg = <0x0 0x8f300000 0x0 0x1e00000>;
+ no-map;
+ };
+
+ adsp_mem: memory@91100000 {
+ reg = <0x0 0x91100000 0x0 0x2800000>;
+ no-map;
+ };
+
+ wlan_mem: memory@93900000 {
+ reg = <0x0 0x93900000 0x0 0x200000>;
+ no-map;
+ };
+
+ ipa_fw_mem: memory@93b00000 {
+ reg = <0x0 0x93b00000 0x0 0x10000>;
+ no-map;
+ };
+
+ gpu_mem: memory@93b15000 {
+ reg = <0x0 0x93b15000 0x0 0x2000>;
+ no-map;
+ };
+
+ cont_splash_mem: memory@9c000000 {
+ reg = <0x0 0x9c000000 0x0 (1080 * 2400 * 4)>;
+ no-map;
+ };
+
+ pstore_mem: ramoops@9d800000 {
+ compatible = "ramoops";
+ reg = <0x0 0x9d800000 0x0 0x400000>;
+ record-size = <0x80000>;
+ pmsg-size = <0x200000>;
+ console-size = <0x100000>;
+ };
+
+ rmtfs_mem: memory@fa601000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0 0xfa601000 0x0 0x200000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
+ };
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm6150-rpmh-regulators";
+ qcom,pmic-id = "a";
+
+ vreg_s1a_1p1: smps1 {
+ regulator-min-microvolt = <1128000>;
+ regulator-max-microvolt = <1128000>;
+ };
+
+ vreg_s4a_1p0: smps4 {
+ regulator-min-microvolt = <824000>;
+ regulator-max-microvolt = <1120000>;
+ };
+
+ vreg_s5a_2p0: smps5 {
+ regulator-min-microvolt = <1744000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ vreg_l1a_1p2: ldo1 {
+ regulator-min-microvolt = <1178000>;
+ regulator-max-microvolt = <1256000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2a_1p0: ldo2 {
+ regulator-min-microvolt = <944000>;
+ regulator-max-microvolt = <1056000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3a_1p0: ldo3 {
+ regulator-min-microvolt = <968000>;
+ regulator-max-microvolt = <1064000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4a_0p88: ldo4 {
+ regulator-min-microvolt = <824000>;
+ regulator-max-microvolt = <928000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5a_2p7: ldo5 {
+ regulator-min-microvolt = <2496000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6a_0p6: ldo6 {
+ regulator-min-microvolt = <568000>;
+ regulator-max-microvolt = <648000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9a_0p664: ldo9 {
+ regulator-min-microvolt = <488000>;
+ regulator-max-microvolt = <800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10a_1p8: ldo10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1832000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11a_1p8: ldo11 {
+ regulator-min-microvolt = <1696000>;
+ regulator-max-microvolt = <1904000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12a_1p8: ldo12 {
+ regulator-min-microvolt = <1696000>;
+ regulator-max-microvolt = <1952000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13a_1p8: ldo13 {
+ regulator-min-microvolt = <1696000>;
+ regulator-max-microvolt = <1904000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14a_1p8: ldo14 {
+ regulator-min-microvolt = <1728000>;
+ regulator-max-microvolt = <1832000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15a_1p8: ldo15 {
+ regulator-min-microvolt = <1696000>;
+ regulator-max-microvolt = <1904000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l16a_2p7: ldo16 {
+ regulator-min-microvolt = <2496000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17a_3p1: ldo17 {
+ regulator-min-microvolt = <2920000>;
+ regulator-max-microvolt = <3232000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l18a_3p0: ldo18 {
+ regulator-min-microvolt = <1696000>;
+ regulator-max-microvolt = <1904000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l19a_3p0: ldo19 {
+ regulator-min-microvolt = <2696000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm6150l-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vreg_s8c_1p3: smps8 {
+ regulator-min-microvolt = <1120000>;
+ regulator-max-microvolt = <1408000>;
+ };
+
+ vreg_l1c_1p8: ldo1 {
+ regulator-min-microvolt = <1616000>;
+ regulator-max-microvolt = <1984000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2c_1p3: ldo2 {
+ regulator-min-microvolt = <1168000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c_1p23: ldo3 {
+ regulator-min-microvolt = <1144000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4c_1p8: ldo4 {
+ regulator-min-microvolt = <1648000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5c_1p8: ldo5 {
+ regulator-min-microvolt = <1648000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6c_3p0: ldo6 {
+ regulator-min-microvolt = <1648000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c_3p0: ldo7 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8c_1p8: ldo8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1904000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9c_2p9: ldo9 {
+ regulator-min-microvolt = <2952000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10c_3p3: ldo10 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11c_3p3: ldo11 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob: bob {
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ };
+ };
+};
+
+&dispcc {
+ /* HACK: disable until a panel driver is ready to retain simplefb */
+ status = "disabled";
+};
+
+&pm6150_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&pm6150_rtc {
+ status = "okay";
+};
+
+&sdhc_2 {
+ cd-gpios = <&tlmm 69 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&sdc2_on>;
+ pinctrl-1 = <&sdc2_off>;
+ vmmc-supply = <&vreg_l9c_2p9>;
+ vqmmc-supply = <&vreg_l6c_3p0>;
+ status = "okay";
+};
+
+&tlmm {
+ gpio-reserved-ranges = <0 4>, <34 4>, <59 4>;
+
+ sdc2_on: sdc2-on-state {
+ clk-pins {
+ pins = "sdc2_clk";
+ bias-disable;
+ drive-strength = <16>;
+ };
+
+ cmd-pins {
+ pins = "sdc2_cmd";
+ bias-pull-up;
+ drive-strength = <10>;
+ };
+
+ data-pins {
+ pins = "sdc2_data";
+ bias-pull-up;
+ drive-strength = <10>;
+ };
+
+ sd-cd-pins {
+ pins = "gpio69";
+ function = "gpio";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+ };
+
+ sdc2_off: sdc2-off-state {
+ clk-pins {
+ pins = "sdc2_clk";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ cmd-pins {
+ pins = "sdc2_cmd";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ data-pins {
+ pins = "sdc2_data";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ sd-cd-pins {
+ pins = "gpio69";
+ function = "gpio";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+ };
+};
+
+&usb_1 {
+ qcom,select-utmi-as-pipe-clk;
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "peripheral";
+ maximum-speed = "high-speed";
+ status = "okay";
+};
+
+&usb_1_hsphy {
+ vdd-supply = <&vreg_l4a_0p88>;
+ vdda-phy-dpdm-supply = <&vreg_l17a_3p1>;
+ vdda-pll-supply = <&vreg_l11a_1p8>;
+ status = "okay";
+};
+
+&usb_1_qmpphy {
+ vdda-phy-supply = <&vreg_l4a_0p88>;
+ vdda-pll-supply = <&vreg_l3c_1p23>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sm7125-xiaomi-joyeuse.dts b/arch/arm64/boot/dts/qcom/sm7125-xiaomi-joyeuse.dts
new file mode 100644
index 000000000000..e010d1957509
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm7125-xiaomi-joyeuse.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "sm7125-xiaomi-common.dtsi"
+
+/ {
+ model = "Xiaomi Redmi Note 9 Pro (Global)";
+ compatible = "xiaomi,joyeuse", "qcom,sm7125";
+
+ /* required for bootloader to select correct board */
+ qcom,board-id = <0x50022 1>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm7125.dtsi b/arch/arm64/boot/dts/qcom/sm7125.dtsi
new file mode 100644
index 000000000000..12dd72859a43
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm7125.dtsi
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#include "sc7180.dtsi"
+
+/* SM7125 uses Kryo 465 instead of Kryo 468 */
+&CPU0 { compatible = "qcom,kryo465"; };
+&CPU1 { compatible = "qcom,kryo465"; };
+&CPU2 { compatible = "qcom,kryo465"; };
+&CPU3 { compatible = "qcom,kryo465"; };
+&CPU4 { compatible = "qcom,kryo465"; };
+&CPU5 { compatible = "qcom,kryo465"; };
+&CPU6 { compatible = "qcom,kryo465"; };
+&CPU7 { compatible = "qcom,kryo465"; };
diff --git a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
index 18171c5d8a38..ade619805519 100644
--- a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
+++ b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
@@ -5,9 +5,14 @@
/dts-v1/;
+/* PM7250B is configured to use SID2/3 */
+#define PM7250B_SID 2
+#define PM7250B_SID1 3
+
/* PMK8350 (in reality a PMK8003) is configured to use SID6 instead of 0 */
#define PMK8350_SID 6
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
#include <dt-bindings/input/input.h>
@@ -75,7 +80,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
};
@@ -386,36 +391,10 @@
};
&i2c10 {
- clock-frequency = <400000>;
- status = "okay";
-
/* PM8008 PMIC @ 8 and 9 */
/* PX8618 @ 26 */
/* SMB1395 PMIC @ 34 */
-
- haptics@5a {
- compatible = "awinic,aw8695";
- reg = <0x5a>;
- interrupts-extended = <&tlmm 85 IRQ_TYPE_EDGE_FALLING>;
- reset-gpios = <&tlmm 90 GPIO_ACTIVE_HIGH>;
-
- awinic,f0-preset = <2350>;
- awinic,f0-coefficient = <260>;
- awinic,f0-calibration-percent = <7>;
- awinic,drive-level = <125>;
-
- awinic,f0-detection-play-time = <5>;
- awinic,f0-detection-wait-time = <3>;
- awinic,f0-detection-repeat = <2>;
- awinic,f0-detection-trace = <15>;
-
- awinic,boost-debug = /bits/ 8 <0x30 0xeb 0xd4>;
- awinic,tset = /bits/ 8 <0x12>;
- awinic,r-spare = /bits/ 8 <0x68>;
-
- awinic,bemf-upper-threshold = <4104>;
- awinic,bemf-lower-threshold = <1016>;
- };
+ /* awinic,aw8695 @ 5a */
};
&ipa {
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index 06c53000bb74..97623af13464 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -5,7 +5,9 @@
*/
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
#include <dt-bindings/clock/qcom,rpmh.h>
@@ -720,7 +722,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
camera_mem: memory@8b700000 {
@@ -1873,7 +1875,7 @@
power-domains = <&gcc PCIE_0_GDSC>;
- phys = <&pcie0_lane>;
+ phys = <&pcie0_phy>;
phy-names = "pciephy";
perst-gpio = <&tlmm 35 GPIO_ACTIVE_HIGH>;
@@ -1887,14 +1889,22 @@
pcie0_phy: phy@1c06000 {
compatible = "qcom,sm8150-qmp-gen3x1-pcie-phy";
- reg = <0 0x01c06000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c06000 0 0x1000>;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
- <&gcc GCC_PCIE0_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "refgen";
+ <&gcc GCC_PCIE_0_CLKREF_CLK>,
+ <&gcc GCC_PCIE0_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_0_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+
+ clock-output-names = "pcie_0_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_0_PHY_BCR>;
reset-names = "phy";
@@ -1903,18 +1913,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie0_lane: phy@1c06200 {
- reg = <0 0x01c06200 0 0x170>, /* tx */
- <0 0x01c06400 0 0x200>, /* rx */
- <0 0x01c06800 0 0x1f0>, /* pcs */
- <0 0x01c06c00 0 0xf4>; /* "pcs_lane" same as pcs_misc? */
- clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
- clock-names = "pipe0";
-
- #phy-cells = <0>;
- clock-output-names = "pcie_0_pipe_clk";
- };
};
pcie1: pci@1c08000 {
@@ -1971,7 +1969,7 @@
power-domains = <&gcc PCIE_1_GDSC>;
- phys = <&pcie1_lane>;
+ phys = <&pcie1_phy>;
phy-names = "pciephy";
perst-gpio = <&tlmm 102 GPIO_ACTIVE_HIGH>;
@@ -1985,14 +1983,22 @@
pcie1_phy: phy@1c0e000 {
compatible = "qcom,sm8150-qmp-gen3x2-pcie-phy";
- reg = <0 0x01c0e000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c0e000 0 0x1000>;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
- <&gcc GCC_PCIE1_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "refgen";
+ <&gcc GCC_PCIE_1_CLKREF_CLK>,
+ <&gcc GCC_PCIE1_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_1_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+
+ clock-output-names = "pcie_1_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_1_PHY_BCR>;
reset-names = "phy";
@@ -2001,20 +2007,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie1_lane: phy@1c0e200 {
- reg = <0 0x01c0e200 0 0x170>, /* tx0 */
- <0 0x01c0e400 0 0x200>, /* rx0 */
- <0 0x01c0ea00 0 0x1f0>, /* pcs */
- <0 0x01c0e600 0 0x170>, /* tx1 */
- <0 0x01c0e800 0 0x200>, /* rx1 */
- <0 0x01c0ee00 0 0xf4>; /* "pcs_com" same as pcs_misc? */
- clocks = <&gcc GCC_PCIE_1_PIPE_CLK>;
- clock-names = "pipe0";
-
- #phy-cells = <0>;
- clock-output-names = "pcie_1_pipe_clk";
- };
};
ufs_mem_hc: ufshc@1d84000 {
@@ -3434,38 +3426,27 @@
resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
};
- usb_1_qmpphy: phy@88e9000 {
- compatible = "qcom,sm8150-qmp-usb3-phy";
- reg = <0 0x088e9000 0 0x18c>,
- <0 0x088e8000 0 0x10>;
- status = "disabled";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ usb_1_qmpphy: phy@88e8000 {
+ compatible = "qcom,sm8150-qmp-usb3-dp-phy";
+ reg = <0 0x088e8000 0 0x3000>;
clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
- <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_USB3_PRIM_CLKREF_CLK>,
- <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
- clock-names = "aux", "ref_clk_src", "ref", "com_aux";
+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+ clock-names = "aux",
+ "ref",
+ "com_aux",
+ "usb3_pipe";
resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>,
<&gcc GCC_USB3_PHY_PRIM_BCR>;
reset-names = "phy", "common";
- usb_1_ssphy: phy@88e9200 {
- reg = <0 0x088e9200 0 0x200>,
- <0 0x088e9400 0 0x200>,
- <0 0x088e9c00 0 0x218>,
- <0 0x088e9600 0 0x200>,
- <0 0x088e9800 0 0x200>,
- <0 0x088e9a00 0 0x100>;
- #clock-cells = <0>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "usb3_phy_pipe_clk_src";
- };
+ #clock-cells = <1>;
+ #phy-cells = <1>;
+
+ status = "disabled";
};
usb_2_qmpphy: phy@88eb000 {
@@ -3606,7 +3587,7 @@
iommus = <&apps_smmu 0x140 0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
- phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
+ phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
};
};
@@ -3941,8 +3922,8 @@
<&mdss_dsi0_phy 1>,
<&mdss_dsi1_phy 0>,
<&mdss_dsi1_phy 1>,
- <0>,
- <0>;
+ <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
clock-names = "bi_tcxo",
"dsi0_phy_pll_out_byteclk",
"dsi0_phy_pll_out_dsiclk",
diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
index ecdc20bc10f5..e07d0311ecb5 100644
--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
@@ -18,7 +18,12 @@
qcom,msm-id = <356 0x20001>; /* SM8250 v2.1 */
qcom,board-id = <0x10008 0>;
+ aliases {
+ serial0 = &uart12;
+ };
+
chosen {
+ stdout-path = "serial0:115200n8";
#address-cells = <2>;
#size-cells = <2>;
ranges;
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index a4e58ad731c3..be970472f6c4 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -15,6 +15,7 @@
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sm8250.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
#include <dt-bindings/soc/qcom,apr.h>
@@ -371,6 +372,12 @@
};
};
+ qup_virt: interconnect-qup-virt {
+ compatible = "qcom,sm8250-qup-virt";
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
cpu0_opp_table: opp-table-cpu0 {
compatible = "operating-points-v2";
opp-shared;
@@ -1023,6 +1030,13 @@
dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>,
<&gpi_dma2 1 0 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1039,6 +1053,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1055,6 +1075,13 @@
dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>,
<&gpi_dma2 1 1 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1071,6 +1098,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1087,6 +1120,13 @@
dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>,
<&gpi_dma2 1 2 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1103,6 +1143,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1119,6 +1165,13 @@
dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>,
<&gpi_dma2 1 3 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1135,6 +1188,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1150,6 +1209,10 @@
interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>;
+ interconnect-names = "qup-core",
+ "qup-config";
status = "disabled";
};
@@ -1164,6 +1227,13 @@
dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>,
<&gpi_dma2 1 4 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1180,6 +1250,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1195,6 +1271,10 @@
interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>;
+ interconnect-names = "qup-core",
+ "qup-config";
status = "disabled";
};
@@ -1209,6 +1289,13 @@
dmas = <&gpi_dma2 0 5 QCOM_GPI_I2C>,
<&gpi_dma2 1 5 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1225,6 +1312,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_2 0 &qup_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_2 0>,
+ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1277,6 +1370,13 @@
dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>,
<&gpi_dma0 1 0 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1293,6 +1393,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1309,6 +1415,13 @@
dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>,
<&gpi_dma0 1 1 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1325,6 +1438,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1341,6 +1460,13 @@
dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>,
<&gpi_dma0 1 2 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1357,6 +1483,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1372,6 +1504,10 @@
interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>;
+ interconnect-names = "qup-core",
+ "qup-config";
status = "disabled";
};
@@ -1386,6 +1522,13 @@
dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>,
<&gpi_dma0 1 3 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1402,6 +1545,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1418,6 +1567,13 @@
dmas = <&gpi_dma0 0 4 QCOM_GPI_I2C>,
<&gpi_dma0 1 4 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1434,6 +1590,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1450,6 +1612,13 @@
dmas = <&gpi_dma0 0 5 QCOM_GPI_I2C>,
<&gpi_dma0 1 5 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1466,6 +1635,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1482,6 +1657,13 @@
dmas = <&gpi_dma0 0 6 QCOM_GPI_I2C>,
<&gpi_dma0 1 6 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1498,6 +1680,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1513,6 +1701,10 @@
interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>;
+ interconnect-names = "qup-core",
+ "qup-config";
status = "disabled";
};
@@ -1527,6 +1719,13 @@
dmas = <&gpi_dma0 0 7 QCOM_GPI_I2C>,
<&gpi_dma0 1 7 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1543,6 +1742,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>,
+ <&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1592,6 +1797,13 @@
dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>,
<&gpi_dma1 1 0 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1608,6 +1820,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1624,6 +1842,13 @@
dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>,
<&gpi_dma1 1 1 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1640,6 +1865,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1656,6 +1887,13 @@
dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>,
<&gpi_dma1 1 2 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1672,6 +1910,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1688,6 +1932,13 @@
dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>,
<&gpi_dma1 1 3 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1704,6 +1955,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1720,6 +1977,13 @@
dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>,
<&gpi_dma1 1 4 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1736,6 +2000,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1751,6 +2021,10 @@
interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>;
+ interconnect-names = "qup-core",
+ "qup-config";
status = "disabled";
};
@@ -1765,6 +2039,13 @@
dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>,
<&gpi_dma1 1 5 QCOM_GPI_I2C>;
dma-names = "tx", "rx";
+ power-domains = <&rpmhpd SM8250_CX>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1781,6 +2062,12 @@
dma-names = "tx", "rx";
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&qup_opp_table>;
+ interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>,
+ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_1 0>,
+ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI_CH0 0>;
+ interconnect-names = "qup-core",
+ "qup-config",
+ "qup-memory";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -1898,7 +2185,7 @@
power-domains = <&gcc PCIE_0_GDSC>;
- phys = <&pcie0_lane>;
+ phys = <&pcie0_phy>;
phy-names = "pciephy";
perst-gpios = <&tlmm 79 GPIO_ACTIVE_LOW>;
@@ -1913,15 +2200,23 @@
pcie0_phy: phy@1c06000 {
compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy";
- reg = <0 0x01c06000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c06000 0 0x1000>;
+
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
<&gcc GCC_PCIE_WIFI_CLKREF_EN>,
- <&gcc GCC_PCIE0_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE0_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_0_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+
+ clock-output-names = "pcie_0_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_0_PHY_BCR>;
reset-names = "phy";
@@ -1930,20 +2225,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie0_lane: phy@1c06200 {
- reg = <0 0x01c06200 0 0x170>, /* tx */
- <0 0x01c06400 0 0x200>, /* rx */
- <0 0x01c06800 0 0x1f0>, /* pcs */
- <0 0x01c06c00 0 0xf4>; /* "pcs_lane" same as pcs_misc? */
- clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
- clock-names = "pipe0";
-
- #phy-cells = <0>;
-
- #clock-cells = <0>;
- clock-output-names = "pcie_0_pipe_clk";
- };
};
pcie1: pci@1c08000 {
@@ -2005,7 +2286,7 @@
power-domains = <&gcc PCIE_1_GDSC>;
- phys = <&pcie1_lane>;
+ phys = <&pcie1_phy>;
phy-names = "pciephy";
perst-gpios = <&tlmm 82 GPIO_ACTIVE_LOW>;
@@ -2020,15 +2301,23 @@
pcie1_phy: phy@1c0e000 {
compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy";
- reg = <0 0x01c0e000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c0e000 0 0x1000>;
+
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
<&gcc GCC_PCIE_WIGIG_CLKREF_EN>,
- <&gcc GCC_PCIE1_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE1_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_1_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+
+ clock-output-names = "pcie_1_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_1_PHY_BCR>;
reset-names = "phy";
@@ -2037,22 +2326,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie1_lane: phy@1c0e200 {
- reg = <0 0x01c0e200 0 0x170>, /* tx0 */
- <0 0x01c0e400 0 0x200>, /* rx0 */
- <0 0x01c0ea00 0 0x1f0>, /* pcs */
- <0 0x01c0e600 0 0x170>, /* tx1 */
- <0 0x01c0e800 0 0x200>, /* rx1 */
- <0 0x01c0ee00 0 0xf4>; /* "pcs_com" same as pcs_misc? */
- clocks = <&gcc GCC_PCIE_1_PIPE_CLK>;
- clock-names = "pipe0";
-
- #phy-cells = <0>;
-
- #clock-cells = <0>;
- clock-output-names = "pcie_1_pipe_clk";
- };
};
pcie2: pci@1c10000 {
@@ -2114,7 +2387,7 @@
power-domains = <&gcc PCIE_2_GDSC>;
- phys = <&pcie2_lane>;
+ phys = <&pcie2_phy>;
phy-names = "pciephy";
perst-gpios = <&tlmm 85 GPIO_ACTIVE_LOW>;
@@ -2129,15 +2402,23 @@
pcie2_phy: phy@1c16000 {
compatible = "qcom,sm8250-qmp-modem-pcie-phy";
- reg = <0 0x01c16000 0 0x1c0>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c16000 0 0x1000>;
+
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_2_CFG_AHB_CLK>,
<&gcc GCC_PCIE_MDM_CLKREF_EN>,
- <&gcc GCC_PCIE2_PHY_REFGEN_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE2_PHY_REFGEN_CLK>,
+ <&gcc GCC_PCIE_2_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "refgen",
+ "pipe";
+
+ clock-output-names = "pcie_2_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_2_PHY_BCR>;
reset-names = "phy";
@@ -2146,22 +2427,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie2_lane: phy@1c16200 {
- reg = <0 0x01c16200 0 0x170>, /* tx0 */
- <0 0x01c16400 0 0x200>, /* rx0 */
- <0 0x01c16a00 0 0x1f0>, /* pcs */
- <0 0x01c16600 0 0x170>, /* tx1 */
- <0 0x01c16800 0 0x200>, /* rx1 */
- <0 0x01c16e00 0 0xf4>; /* "pcs_com" same as pcs_misc? */
- clocks = <&gcc GCC_PCIE_2_PIPE_CLK>;
- clock-names = "pipe0";
-
- #phy-cells = <0>;
-
- #clock-cells = <0>;
- clock-output-names = "pcie_2_pipe_clk";
- };
};
ufs_mem_hc: ufshc@1d84000 {
@@ -3580,47 +3845,45 @@
resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
};
- usb_1_qmpphy: phy@88e9000 {
+ usb_1_qmpphy: phy@88e8000 {
compatible = "qcom,sm8250-qmp-usb3-dp-phy";
- reg = <0 0x088e9000 0 0x200>,
- <0 0x088e8000 0 0x40>,
- <0 0x088ea000 0 0x200>;
+ reg = <0 0x088e8000 0 0x3000>;
status = "disabled";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
<&rpmhcc RPMH_CXO_CLK>,
- <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
- clock-names = "aux", "ref_clk_src", "com_aux";
+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+ clock-names = "aux",
+ "ref",
+ "com_aux",
+ "usb3_pipe";
resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>,
<&gcc GCC_USB3_PHY_PRIM_BCR>;
reset-names = "phy", "common";
- usb_1_ssphy: usb3-phy@88e9200 {
- reg = <0 0x088e9200 0 0x200>,
- <0 0x088e9400 0 0x200>,
- <0 0x088e9c00 0 0x400>,
- <0 0x088e9600 0 0x200>,
- <0 0x088e9800 0 0x200>,
- <0 0x088e9a00 0 0x100>;
- #clock-cells = <0>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
- clock-names = "pipe0";
- clock-output-names = "usb3_phy_pipe_clk_src";
- };
+ #clock-cells = <1>;
+ #phy-cells = <1>;
- dp_phy: dp-phy@88ea200 {
- reg = <0 0x088ea200 0 0x200>,
- <0 0x088ea400 0 0x200>,
- <0 0x088eaa00 0 0x200>,
- <0 0x088ea600 0 0x200>,
- <0 0x088ea800 0 0x200>;
- #phy-cells = <0>;
- #clock-cells = <1>;
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ usb_1_qmpphy_out: endpoint {};
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+
+ port@2 {
+ reg = <2>;
+
+ usb_1_qmpphy_dp_in: endpoint {};
+ };
};
};
@@ -3892,8 +4155,12 @@
iommus = <&apps_smmu 0x0 0x0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
- phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
+ phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
+
+ port {
+ usb_1_role_switch_out: endpoint {};
+ };
};
};
@@ -4383,6 +4650,14 @@
remote-endpoint = <&mdss_dsi1_in>;
};
};
+
+ port@2 {
+ reg = <2>;
+
+ dpu_intf0_out: endpoint {
+ remote-endpoint = <&mdss_dp_in>;
+ };
+ };
};
mdp_opp_table: opp-table {
@@ -4410,6 +4685,85 @@
};
};
+ mdss_dp: displayport-controller@ae90000 {
+ compatible = "qcom,sm8250-dp", "qcom,sm8350-dp";
+ reg = <0 0xae90000 0 0x200>,
+ <0 0xae90200 0 0x200>,
+ <0 0xae90400 0 0x600>,
+ <0 0xae91000 0 0x400>,
+ <0 0xae91400 0 0x400>;
+ interrupt-parent = <&mdss>;
+ interrupts = <12>;
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_LINK_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK>;
+ clock-names = "core_iface",
+ "core_aux",
+ "ctrl_link",
+ "ctrl_link_iface",
+ "stream_pixel";
+
+ assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
+ <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
+ assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
+
+ phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>;
+ phy-names = "dp";
+
+ #sound-dai-cells = <0>;
+
+ operating-points-v2 = <&dp_opp_table>;
+ power-domains = <&rpmhpd SM8250_MMCX>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ mdss_dp_in: endpoint {
+ remote-endpoint = <&dpu_intf0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ mdss_dp_out: endpoint {
+ };
+ };
+ };
+
+ dp_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-160000000 {
+ opp-hz = /bits/ 64 <160000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-270000000 {
+ opp-hz = /bits/ 64 <270000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-540000000 {
+ opp-hz = /bits/ 64 <540000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-810000000 {
+ opp-hz = /bits/ 64 <810000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
+ };
+
mdss_dsi0: dsi@ae94000 {
compatible = "qcom,sm8250-dsi-ctrl",
"qcom,mdss-dsi-ctrl";
@@ -4586,8 +4940,8 @@
<&mdss_dsi0_phy 1>,
<&mdss_dsi1_phy 0>,
<&mdss_dsi1_phy 1>,
- <&dp_phy 0>,
- <&dp_phy 1>;
+ <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
clock-names = "bi_tcxo",
"dsi0_phy_pll_out_byteclk",
"dsi0_phy_pll_out_dsiclk",
diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
index 4013d25a7df3..b43d264ed42b 100644
--- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
@@ -7,7 +7,12 @@
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "sm8350.dtsi"
+#include "pm8350.dtsi"
+#include "pm8350b.dtsi"
+#include "pm8350c.dtsi"
#include "pmk8350.dtsi"
+#include "pmr735a.dtsi"
+#include "pmr735b.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SM8350 HDK";
@@ -294,6 +299,81 @@
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
};
+
+ regulators-2 {
+ compatible = "qcom,pmr735a-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+
+ vdd-l1-l2-supply = <&vreg_s2e_0p85>;
+ vdd-l3-supply = <&vreg_s1e_1p25>;
+ vdd-l4-supply = <&vreg_s1c_1p86>;
+ vdd-l5-l6-supply = <&vreg_s1c_1p86>;
+ vdd-l7-bob-supply = <&vreg_bob>;
+
+ vreg_s1e_1p25: smps1 {
+ regulator-name = "vreg_s1e_1p25";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1280000>;
+ };
+
+ vreg_s2e_0p85: smps2 {
+ regulator-name = "vreg_s2e_0p85";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <976000>;
+ };
+
+ vreg_s3e_2p20: smps3 {
+ regulator-name = "vreg_s3e_2p20";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2352000>;
+ };
+
+ vreg_l1e_0p9: ldo1 {
+ regulator-name = "vreg_l1e_0p9";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ };
+
+ vreg_l2e_1p2: ldo2 {
+ regulator-name = "vreg_l2e_0p8";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vreg_l3e_1p2: ldo3 {
+ regulator-name = "vreg_l3e_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vreg_l4e_1p7: ldo4 {
+ regulator-name = "vreg_l4e_1p7";
+ regulator-min-microvolt = <1776000>;
+ regulator-max-microvolt = <1872000>;
+ };
+
+ vreg_l5e_0p8: ldo5 {
+ regulator-name = "vreg_l5e_0p8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ };
+
+ vreg_l6e_0p8: ldo6 {
+ regulator-name = "vreg_l6e_0p8";
+ regulator-min-microvolt = <480000>;
+ regulator-max-microvolt = <904000>;
+ };
+
+ vreg_l7e_2p8: ldo7 {
+ regulator-name = "vreg_l7e_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+ };
};
&cdsp {
@@ -760,6 +840,7 @@
vcc-max-microamp = <800000>;
vccq-supply = <&vreg_l9b_1p2>;
vccq-max-microamp = <900000>;
+ vdd-hba-supply = <&vreg_l9b_1p2>;
};
&ufs_mem_phy {
diff --git a/arch/arm64/boot/dts/qcom/sm8350-mtp.dts b/arch/arm64/boot/dts/qcom/sm8350-mtp.dts
index c5a6c8745606..8bee57f3b25a 100644
--- a/arch/arm64/boot/dts/qcom/sm8350-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8350-mtp.dts
@@ -325,6 +325,7 @@
vcc-max-microamp = <800000>;
vccq-supply = <&vreg_l9b_1p2>;
vccq-max-microamp = <900000>;
+ vdd-hba-supply = <&vreg_l9b_1p2>;
};
&ufs_mem_phy {
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
index 00604bf7724f..b46236235b7f 100644
--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
@@ -10,6 +10,7 @@
#include <dt-bindings/clock/qcom,gpucc-sm8350.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interconnect/qcom,sm8350.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
@@ -503,7 +504,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
hyp_reserved_mem: memory@d0000000 {
@@ -2964,7 +2965,7 @@
};
qup_uart18_default: qup-uart18-default-state {
- pins = "gpio58", "gpio59";
+ pins = "gpio68", "gpio69";
function = "qup18";
drive-strength = <2>;
bias-disable;
diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
index bd5e8181f2aa..20153d08edde 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
@@ -915,14 +915,23 @@
"SpkrRight IN", "WSA_SPK2 OUT",
"IN1_HPHL", "HPHL_OUT",
"IN2_HPHR", "HPHR_OUT",
+ "AMIC1", "MIC BIAS1",
"AMIC2", "MIC BIAS2",
- "VA DMIC0", "MIC BIAS1",
- "VA DMIC1", "MIC BIAS1",
- "VA DMIC2", "MIC BIAS3",
- "TX DMIC0", "MIC BIAS1",
- "TX DMIC1", "MIC BIAS2",
- "TX DMIC2", "MIC BIAS3",
- "TX SWR_ADC1", "ADC2_OUTPUT";
+ "AMIC3", "MIC BIAS3",
+ "AMIC4", "MIC BIAS3",
+ "AMIC5", "MIC BIAS4",
+ "VA DMIC0", "MIC BIAS3",
+ "VA DMIC1", "MIC BIAS3",
+ "VA DMIC2", "MIC BIAS1",
+ "VA DMIC3", "MIC BIAS1",
+ "TX DMIC0", "MIC BIAS3",
+ "TX DMIC1", "MIC BIAS3",
+ "TX DMIC2", "MIC BIAS1",
+ "TX DMIC3", "MIC BIAS1",
+ "TX SWR_INPUT0", "ADC1_OUTPUT",
+ "TX SWR_INPUT1", "ADC2_OUTPUT",
+ "TX SWR_INPUT2", "ADC3_OUTPUT",
+ "TX SWR_INPUT3", "ADC4_OUTPUT";
wcd-playback-dai-link {
link-name = "WCD Playback";
@@ -1073,6 +1082,7 @@
vcc-max-microamp = <1100000>;
vccq-supply = <&vreg_l9b_1p2>;
vccq-max-microamp = <1200000>;
+ vdd-hba-supply = <&vreg_l9b_1p2>;
};
&ufs_mem_phy {
diff --git a/arch/arm64/boot/dts/qcom/sm8450-qrd.dts b/arch/arm64/boot/dts/qcom/sm8450-qrd.dts
index 37479327707f..c7d05945aa51 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8450-qrd.dts
@@ -443,6 +443,7 @@
vcc-max-microamp = <1100000>;
vccq-supply = <&vreg_l9b_1p2>;
vccq-max-microamp = <1200000>;
+ vdd-hba-supply = <&vreg_l9b_1p2>;
};
&ufs_mem_phy {
diff --git a/arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi b/arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi
index 001fb2723fbb..8b29fcf483a3 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450-sony-xperia-nagara.dtsi
@@ -80,7 +80,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
ramoops@ffc00000 {
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index 2a60cf8bd891..1783fa78bdbc 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -10,6 +10,7 @@
#include <dt-bindings/clock/qcom,sm8450-dispcc.h>
#include <dt-bindings/clock/qcom,sm8450-videocc.h>
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
#include <dt-bindings/phy/phy-qcom-qmp.h>
@@ -540,7 +541,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
xbl_sc_mem2: memory@a6e00000 {
@@ -750,8 +751,8 @@
#power-domain-cells = <1>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&sleep_clk>,
- <&pcie0_lane>,
- <&pcie1_lane>,
+ <&pcie0_phy>,
+ <&pcie1_phy>,
<0>,
<&ufs_mem_phy_lanes 0>,
<&ufs_mem_phy_lanes 1>,
@@ -1738,11 +1739,6 @@
};
};
- rng: rng@10c3000 {
- compatible = "qcom,sm8450-prng-ee", "qcom,prng-ee";
- reg = <0 0x010c3000 0 0x1000>;
- };
-
pcie0: pci@1c00000 {
compatible = "qcom,pcie-sm8450-pcie0";
reg = <0 0x01c00000 0 0x3000>,
@@ -1780,7 +1776,7 @@
clocks = <&gcc GCC_PCIE_0_PIPE_CLK>,
<&gcc GCC_PCIE_0_PIPE_CLK_SRC>,
- <&pcie0_lane>,
+ <&pcie0_phy>,
<&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_PCIE_0_AUX_CLK>,
<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
@@ -1811,7 +1807,7 @@
power-domains = <&gcc PCIE_0_GDSC>;
- phys = <&pcie0_lane>;
+ phys = <&pcie0_phy>;
phy-names = "pciephy";
perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
@@ -1825,15 +1821,23 @@
pcie0_phy: phy@1c06000 {
compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy";
- reg = <0 0x01c06000 0 0x200>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c06000 0 0x2000>;
+
clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
<&gcc GCC_PCIE_0_CLKREF_EN>,
- <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>,
+ <&gcc GCC_PCIE_0_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "rchng",
+ "pipe";
+
+ clock-output-names = "pcie_0_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_0_PHY_BCR>;
reset-names = "phy";
@@ -1842,19 +1846,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie0_lane: phy@1c06200 {
- reg = <0 0x01c06e00 0 0x200>, /* tx */
- <0 0x01c07000 0 0x200>, /* rx */
- <0 0x01c06200 0 0x200>, /* pcs */
- <0 0x01c06600 0 0x200>; /* pcs_pcie */
- clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
- clock-names = "pipe0";
-
- #clock-cells = <0>;
- #phy-cells = <0>;
- clock-output-names = "pcie_0_pipe_clk";
- };
};
pcie1: pci@1c08000 {
@@ -1894,7 +1885,7 @@
clocks = <&gcc GCC_PCIE_1_PIPE_CLK>,
<&gcc GCC_PCIE_1_PIPE_CLK_SRC>,
- <&pcie1_lane>,
+ <&pcie1_phy>,
<&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_PCIE_1_AUX_CLK>,
<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
@@ -1923,7 +1914,7 @@
power-domains = <&gcc PCIE_1_GDSC>;
- phys = <&pcie1_lane>;
+ phys = <&pcie1_phy>;
phy-names = "pciephy";
perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
@@ -1935,17 +1926,25 @@
status = "disabled";
};
- pcie1_phy: phy@1c0f000 {
+ pcie1_phy: phy@1c0e000 {
compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy";
- reg = <0 0x01c0f000 0 0x200>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ reg = <0 0x01c0e000 0 0x2000>;
+
clocks = <&gcc GCC_PCIE_1_PHY_AUX_CLK>,
<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
<&gcc GCC_PCIE_1_CLKREF_EN>,
- <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>;
- clock-names = "aux", "cfg_ahb", "ref", "refgen";
+ <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>,
+ <&gcc GCC_PCIE_1_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "rchng",
+ "pipe";
+
+ clock-output-names = "pcie_1_pipe_clk";
+ #clock-cells = <0>;
+
+ #phy-cells = <0>;
resets = <&gcc GCC_PCIE_1_PHY_BCR>;
reset-names = "phy";
@@ -1954,21 +1953,6 @@
assigned-clock-rates = <100000000>;
status = "disabled";
-
- pcie1_lane: phy@1c0e000 {
- reg = <0 0x01c0e000 0 0x200>, /* tx */
- <0 0x01c0e200 0 0x300>, /* rx */
- <0 0x01c0f200 0 0x200>, /* pcs */
- <0 0x01c0e800 0 0x200>, /* tx */
- <0 0x01c0ea00 0 0x300>, /* rx */
- <0 0x01c0f400 0 0xc00>; /* pcs_pcie */
- clocks = <&gcc GCC_PCIE_1_PIPE_CLK>;
- clock-names = "pipe0";
-
- #clock-cells = <0>;
- #phy-cells = <0>;
- clock-output-names = "pcie_1_pipe_clk";
- };
};
config_noc: interconnect@1500000 {
diff --git a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
index f29cce5186ac..5b3488736fbe 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
@@ -13,7 +13,8 @@
#include "pm8550ve.dtsi"
#include "pm8550vs.dtsi"
#include "pmk8550.dtsi"
-#include "pmr735d.dtsi"
+#include "pmr735d_a.dtsi"
+#include "pmr735d_b.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SM8550 MTP";
@@ -797,8 +798,7 @@
vcc-max-microamp = <1300000>;
vccq-supply = <&vreg_l1g_1p2>;
vccq-max-microamp = <1200000>;
- vccq2-supply = <&vreg_l3g_1p2>;
- vccq2-max-microamp = <100>;
+ vdd-hba-supply = <&vreg_l3g_1p2>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
index 2c09ce8aeafd..320662024e89 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
@@ -14,7 +14,8 @@
#include "pm8550ve.dtsi"
#include "pm8550vs.dtsi"
#include "pmk8550.dtsi"
-#include "pmr735d.dtsi"
+#include "pmr735d_a.dtsi"
+#include "pmr735d_b.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SM8550 QRD";
@@ -23,6 +24,7 @@
aliases {
serial0 = &uart7;
+ serial1 = &uart14;
};
wcd938x: audio-codec {
@@ -765,6 +767,10 @@
status = "okay";
};
+&qupv3_id_1 {
+ status = "okay";
+};
+
&remoteproc_adsp {
firmware-name = "qcom/sm8550/adsp.mbn",
"qcom/sm8550/adsp_dtb.mbn";
@@ -842,6 +848,21 @@
&tlmm {
gpio-reserved-ranges = <32 8>;
+ bt_default: bt-default-state {
+ bt-en-pins {
+ pins = "gpio81";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ sw-ctrl-pins {
+ pins = "gpio82";
+ function = "gpio";
+ bias-pull-down;
+ };
+ };
+
sde_dsi_active: sde-dsi-active-state {
pins = "gpio133";
function = "gpio";
@@ -883,14 +904,36 @@
status = "okay";
};
+&uart14 {
+ status = "okay";
+
+ bluetooth {
+ compatible = "qcom,wcn7850-bt";
+
+ vddio-supply = <&vreg_l15b_1p8>;
+ vddaon-supply = <&vreg_s4e_0p95>;
+ vdddig-supply = <&vreg_s4e_0p95>;
+ vddrfa0p8-supply = <&vreg_s4e_0p95>;
+ vddrfa1p2-supply = <&vreg_s4g_1p25>;
+ vddrfa1p9-supply = <&vreg_s6g_1p86>;
+
+ max-speed = <3200000>;
+
+ enable-gpios = <&tlmm 81 GPIO_ACTIVE_HIGH>;
+ swctrl-gpios = <&tlmm 82 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&bt_default>;
+ pinctrl-names = "default";
+ };
+};
+
&ufs_mem_hc {
reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>;
vcc-supply = <&vreg_l17b_2p5>;
vcc-max-microamp = <1300000>;
vccq-supply = <&vreg_l1g_1p2>;
vccq-max-microamp = <1200000>;
- vccq2-supply = <&vreg_l3g_1p2>;
- vccq2-max-microamp = <100>;
+ vdd-hba-supply = <&vreg_l3g_1p2>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
index d115960bdeec..7b9ddde0b2c9 100644
--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
@@ -5,11 +5,13 @@
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,sm8450-videocc.h>
+#include <dt-bindings/clock/qcom,sm8550-camcc.h>
#include <dt-bindings/clock/qcom,sm8550-gcc.h>
#include <dt-bindings/clock/qcom,sm8550-gpucc.h>
#include <dt-bindings/clock/qcom,sm8550-tcsr.h>
#include <dt-bindings/clock/qcom,sm8550-dispcc.h>
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8550-rpmh.h>
@@ -570,7 +572,7 @@
no-map;
qcom,client-id = <1>;
- qcom,vmid = <15>;
+ qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
};
mpss_dsm_mem: mpss-dsm-region@d4d00000 {
@@ -1054,6 +1056,20 @@
status = "disabled";
};
+ uart14: serial@898000 {
+ compatible = "qcom,geni-uart";
+ reg = <0 0x898000 0 0x4000>;
+ clock-names = "se";
+ clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&qup_uart14_default>, <&qup_uart14_cts_rts>;
+ interrupts = <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>;
+ interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+ <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>;
+ interconnect-names = "qup-core", "qup-config";
+ status = "disabled";
+ };
+
i2c15: i2c@89c000 {
compatible = "qcom,geni-i2c";
reg = <0 0x0089c000 0 0x4000>;
@@ -2420,6 +2436,20 @@
#power-domain-cells = <1>;
};
+ camcc: clock-controller@ade0000 {
+ compatible = "qcom,sm8550-camcc";
+ reg = <0 0x0ade0000 0 0x20000>;
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&bi_tcxo_div2>,
+ <&bi_tcxo_ao_div2>,
+ <&sleep_clk>;
+ power-domains = <&rpmhpd SM8550_MMCX>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
mdss: display-subsystem@ae00000 {
compatible = "qcom,sm8550-mdss";
reg = <0 0x0ae00000 0 0x1000>;
@@ -3498,6 +3528,22 @@
bias-disable;
};
+ qup_uart14_default: qup-uart14-default-state {
+ /* TX, RX */
+ pins = "gpio78", "gpio79";
+ function = "qup2_se6";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ qup_uart14_cts_rts: qup-uart14-cts-rts-state {
+ /* CTS, RTS */
+ pins = "gpio76", "gpio77";
+ function = "qup2_se6";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
sdc2_sleep: sdc2-sleep-state {
clk-pins {
pins = "sdc2_clk";
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 7114cbbd8713..8ea68d582710 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -29,21 +29,35 @@ dtb-$(CONFIG_ARCH_R8A774E1) += r8a774e1-hihope-rzg2h-ex-idk-1110wr.dtb
dtb-$(CONFIG_ARCH_R8A774E1) += r8a774e1-hihope-rzg2h-ex-mipi-2.1.dtb
dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-salvator-x.dtb
+r8a77951-salvator-x-panel-aa104xd12-dtbs := r8a77951-salvator-x.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-salvator-x-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-salvator-xs.dtb
+r8a77951-salvator-xs-panel-aa104xd12-dtbs := r8a77951-salvator-xs.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-salvator-xs-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-ulcb.dtb
dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-ulcb-kf.dtb
dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-salvator-x.dtb
+r8a77960-salvator-x-panel-aa104xd12-dtbs := r8a77960-salvator-x.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-salvator-x-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-salvator-xs.dtb
+r8a77960-salvator-xs-panel-aa104xd12-dtbs := r8a77960-salvator-xs.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-salvator-xs-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-ulcb.dtb
dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-ulcb-kf.dtb
dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-salvator-xs.dtb
+r8a77961-salvator-xs-panel-aa104xd12-dtbs := r8a77961-salvator-xs.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-salvator-xs-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-ulcb.dtb
dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-ulcb-kf.dtb
dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x.dtb
+r8a77965-salvator-x-panel-aa104xd12-dtbs := r8a77965-salvator-x.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-xs.dtb
+r8a77965-salvator-xs-panel-aa104xd12-dtbs := r8a77965-salvator-xs.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-xs-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-ulcb.dtb
dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-ulcb-kf.dtb
@@ -55,36 +69,60 @@ dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk.dtb
dtb-$(CONFIG_ARCH_R8A77980) += r8a77980a-condor-i.dtb
dtb-$(CONFIG_ARCH_R8A77990) += r8a77990-ebisu.dtb
+r8a77990-ebisu-panel-aa104xd12-dtbs := r8a77990-ebisu.dtb draak-ebisu-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77990) += r8a77990-ebisu-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb
+r8a77995-draak-panel-aa104xd12-dtbs := r8a77995-draak.dtb draak-ebisu-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A779A0) += r8a779a0-falcon.dtb
dtb-$(CONFIG_ARCH_R8A779F0) += r8a779f0-spider.dtb
+dtb-$(CONFIG_ARCH_R8A779F0) += r8a779f4-s4sk.dtb
dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk.dtb
dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-ard-audio-da7212.dtbo
+r8a779g0-white-hawk-ard-audio-da7212-dtbs := r8a779g0-white-hawk.dtb r8a779g0-white-hawk-ard-audio-da7212.dtbo
+dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-ard-audio-da7212.dtb
dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-salvator-xs.dtb
+r8a779m1-salvator-xs-panel-aa104xd12-dtbs := r8a779m1-salvator-xs.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-salvator-xs-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb.dtb
dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb-kf.dtb
dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-salvator-xs.dtb
+r8a779m3-salvator-xs-panel-aa104xd12-dtbs := r8a779m3-salvator-xs.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-salvator-xs-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb.dtb
dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb-kf.dtb
dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs.dtb
+r8a779m5-salvator-xs-panel-aa104xd12-dtbs := r8a779m5-salvator-xs.dtb salvator-panel-aa104xd12.dtbo
+dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc.dtb
dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043-smarc-pmod.dtbo
+r9a07g043u11-smarc-pmod-dtbs := r9a07g043u11-smarc.dtb r9a07g043-smarc-pmod.dtbo
+dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc-pmod.dtb
dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-smarc.dtb
dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-smarc-cru-csi-ov5645.dtbo
+r9a07g044c2-smarc-cru-csi-ov5645-dtbs := r9a07g044c2-smarc.dtb r9a07g044c2-smarc-cru-csi-ov5645.dtbo
+dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-smarc-cru-csi-ov5645.dtb
+
dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc-cru-csi-ov5645.dtbo
+r9a07g044l2-smarc-cru-csi-ov5645-dtbs := r9a07g044l2-smarc.dtb r9a07g044l2-smarc-cru-csi-ov5645.dtbo
+dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc-cru-csi-ov5645.dtb
dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-smarc.dtb
dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-smarc-cru-csi-ov5645.dtbo
+r9a07g054l2-smarc-cru-csi-ov5645-dtbs := r9a07g054l2-smarc.dtb r9a07g054l2-smarc-cru-csi-ov5645.dtbo
+dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-smarc-cru-csi-ov5645.dtb
+
+dtb-$(CONFIG_ARCH_R9A08G045) += r9a08g045s33-smarc.dtb
dtb-$(CONFIG_ARCH_R9A09G011) += r9a09g011-v2mevk2.dtb
diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
index 2e9927b97732..5a14f116f7a1 100644
--- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
@@ -651,7 +651,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&versaclock6_bb 4>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE CPG_AUDIO_CLK_I>;
+ <&cpg CPG_MOD 922>;
status = "okay";
diff --git a/arch/arm64/boot/dts/renesas/ebisu.dtsi b/arch/arm64/boot/dts/renesas/ebisu.dtsi
index bbc29452d1be..f1a5778ef115 100644
--- a/arch/arm64/boot/dts/renesas/ebisu.dtsi
+++ b/arch/arm64/boot/dts/renesas/ebisu.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Device Tree Source for the Ebisu board
+ * Device Tree Source for the Ebisu/Ebisu-4D board
*
* Copyright (C) 2018 Renesas Electronics Corp.
*/
diff --git a/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi b/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi
index 7fc0339a3ac9..66f3affe0469 100644
--- a/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi
+++ b/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi
@@ -112,7 +112,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&cs2000>,
<&audio_clk_c>,
- <&cpg CPG_CORE CPG_AUDIO_CLK_I>;
+ <&cpg CPG_MOD 922>;
rsnd_port: port {
rsnd_endpoint: endpoint {
diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
index 9065dc243428..95b0a1f6debf 100644
--- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
@@ -10,8 +10,6 @@
#include <dt-bindings/clock/r8a774a1-cpg-mssr.h>
#include <dt-bindings/power/r8a774a1-sysc.h>
-#define CPG_AUDIO_CLK_I R8A774A1_CLK_S0D4
-
/ {
compatible = "renesas,r8a774a1";
#address-cells = <2>;
@@ -1713,7 +1711,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE R8A774A1_CLK_S0D4>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.9", "ssi.8", "ssi.7", "ssi.6",
"ssi.5", "ssi.4", "ssi.3", "ssi.2",
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
index 75776decd218..786660fcdea4 100644
--- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
@@ -10,8 +10,6 @@
#include <dt-bindings/clock/r8a774b1-cpg-mssr.h>
#include <dt-bindings/power/r8a774b1-sysc.h>
-#define CPG_AUDIO_CLK_I R8A774B1_CLK_S0D4
-
/ {
compatible = "renesas,r8a774b1";
#address-cells = <2>;
@@ -1597,7 +1595,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE R8A774B1_CLK_S0D4>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.9", "ssi.8", "ssi.7", "ssi.6",
"ssi.5", "ssi.4", "ssi.3", "ssi.2",
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
index ad2e87b039ac..eed94ffed7c1 100644
--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
@@ -1350,7 +1350,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE R8A774C0_CLK_ZA2>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.9", "ssi.8", "ssi.7", "ssi.6",
"ssi.5", "ssi.4", "ssi.3", "ssi.2",
diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
index 2acf4067ab2f..175e5d296da6 100644
--- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
@@ -10,8 +10,6 @@
#include <dt-bindings/clock/r8a774e1-cpg-mssr.h>
#include <dt-bindings/power/r8a774e1-sysc.h>
-#define CPG_AUDIO_CLK_I R8A774E1_CLK_S0D4
-
/ {
compatible = "renesas,r8a774e1";
#address-cells = <2>;
@@ -1809,7 +1807,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE R8A774E1_CLK_S0D4>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.9", "ssi.8", "ssi.7", "ssi.6",
"ssi.5", "ssi.4", "ssi.3", "ssi.2",
diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
index 6d15229d25ab..a4260d9291ba 100644
--- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
@@ -9,8 +9,6 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/r8a7795-sysc.h>
-#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4
-
#define SOC_HAS_HDMI1
#define SOC_HAS_SATA
#define SOC_HAS_USB2_CH2
@@ -2032,7 +2030,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE R8A7795_CLK_S0D4>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.9", "ssi.8", "ssi.7", "ssi.6",
"ssi.5", "ssi.4", "ssi.3", "ssi.2",
diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
index 17062ec506be..a631ead171b2 100644
--- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
@@ -9,8 +9,6 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/r8a7796-sysc.h>
-#define CPG_AUDIO_CLK_I R8A7796_CLK_S0D4
-
/ {
compatible = "renesas,r8a7796";
#address-cells = <2>;
@@ -1903,7 +1901,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE R8A7796_CLK_S0D4>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.9", "ssi.8", "ssi.7", "ssi.6",
"ssi.5", "ssi.4", "ssi.3", "ssi.2",
diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
index d3f47da1b626..7254912a241f 100644
--- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
@@ -9,8 +9,6 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/r8a77961-sysc.h>
-#define CPG_AUDIO_CLK_I R8A77961_CLK_S0D4
-
/ {
compatible = "renesas,r8a77961";
#address-cells = <2>;
@@ -1783,7 +1781,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE R8A77961_CLK_S0D4>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.9", "ssi.8", "ssi.7", "ssi.6",
"ssi.5", "ssi.4", "ssi.3", "ssi.2",
diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
index c75820038491..e57b9027066e 100644
--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
@@ -12,8 +12,6 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/r8a77965-sysc.h>
-#define CPG_AUDIO_CLK_I R8A77965_CLK_S0D4
-
#define SOC_HAS_SATA
/ {
@@ -1766,7 +1764,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE R8A77965_CLK_S0D4>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.9", "ssi.8", "ssi.7", "ssi.6",
"ssi.5", "ssi.4", "ssi.3", "ssi.2",
diff --git a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
index 9da0fd08f8c4..d5ac34a966f6 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Device Tree Source for the Ebisu board with R-Car E3
+ * Device Tree Source for the Ebisu/Ebisu-4D board with R-Car E3
*
* Copyright (C) 2018 Renesas Electronics Corp.
*/
diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index 4c545eff9b42..8c2b28342387 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -1501,7 +1501,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
<&audio_clk_c>,
- <&cpg CPG_CORE R8A77990_CLK_ZA2>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.9", "ssi.8", "ssi.7", "ssi.6",
"ssi.5", "ssi.4", "ssi.3", "ssi.2",
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index e25024a7b66c..8cf6473c63d3 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -1063,7 +1063,7 @@
<&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&audio_clk_b>,
- <&cpg CPG_CORE R8A77995_CLK_ZA2>;
+ <&cpg CPG_MOD 922>;
clock-names = "ssi-all",
"ssi.4", "ssi.3",
"src.6", "src.5",
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
index 5cbde8e8fcd5..477f3114d2fd 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
@@ -53,6 +53,12 @@
reg = <0x4 0x80000000 0x0 0x80000000>;
};
+ rc21012_pci: clk-rc21012-pci {
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ #clock-cells = <0>;
+ };
+
rc21012_ufs: clk-rc21012-ufs {
compatible = "fixed-clock";
clock-frequency = <38400000>;
@@ -106,6 +112,12 @@
reg = <0x20>;
gpio-controller;
#gpio-cells = <2>;
+
+ rc21012-gpio2-hog {
+ gpio-hog;
+ gpios = <5 GPIO_ACTIVE_LOW>;
+ output-high;
+ };
};
};
@@ -145,6 +157,18 @@
status = "okay";
};
+&pcie0_clkref {
+ compatible = "gpio-gate-clock";
+ clocks = <&rc21012_pci>;
+ enable-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+ /delete-property/ clock-frequency;
+};
+
+&pciec0 {
+ reset-gpio = <&gpio_exp_20 0 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
&pfc {
pinctrl-0 = <&scif_clk_pins>;
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
index ecdd5a523fa3..7fb4989cce8a 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -262,6 +262,20 @@
clock-frequency = <0>;
};
+ pcie0_clkref: pcie0-clkref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board */
+ clock-frequency = <0>;
+ };
+
+ pcie1_clkref: pcie1-clkref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board */
+ clock-frequency = <0>;
+ };
+
pmu_a55 {
compatible = "arm,cortex-a55-pmu";
interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
@@ -726,6 +740,126 @@
status = "disabled";
};
+ pciec0: pcie@e65d0000 {
+ compatible = "renesas,r8a779f0-pcie",
+ "renesas,rcar-gen4-pcie";
+ reg = <0 0xe65d0000 0 0x1000>, <0 0xe65d2000 0 0x0800>,
+ <0 0xe65d3000 0 0x2000>, <0 0xe65d5000 0 0x1200>,
+ <0 0xe65d6200 0 0x0e00>, <0 0xe65d7000 0 0x0400>,
+ <0 0xfe000000 0 0x400000>;
+ reg-names = "dbi", "dbi2", "atu", "dma", "app", "phy", "config";
+ interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi", "dma", "sft_ce", "app";
+ clocks = <&cpg CPG_MOD 624>, <&pcie0_clkref>;
+ clock-names = "core", "ref";
+ power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
+ resets = <&cpg 624>;
+ reset-names = "pwr";
+ max-link-speed = <4>;
+ num-lanes = <2>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x00 0xff>;
+ device_type = "pci";
+ ranges = <0x01000000 0 0x00000000 0 0xfe000000 0 0x00400000>,
+ <0x02000000 0 0x30000000 0 0x30000000 0 0x10000000>;
+ dma-ranges = <0x42000000 0 0x00000000 0 0x00000000 1 0x00000000>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &gic GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &gic GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &gic GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>;
+ snps,enable-cdm-check;
+ status = "disabled";
+ };
+
+ pciec1: pcie@e65d8000 {
+ compatible = "renesas,r8a779f0-pcie",
+ "renesas,rcar-gen4-pcie";
+ reg = <0 0xe65d8000 0 0x1000>, <0 0xe65da000 0 0x0800>,
+ <0 0xe65db000 0 0x2000>, <0 0xe65dd000 0 0x1200>,
+ <0 0xe65de200 0 0x0e00>, <0 0xe65df000 0 0x0400>,
+ <0 0xee900000 0 0x400000>;
+ reg-names = "dbi", "dbi2", "atu", "dma", "app", "phy", "config";
+ interrupts = <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi", "dma", "sft_ce", "app";
+ clocks = <&cpg CPG_MOD 625>, <&pcie1_clkref>;
+ clock-names = "core", "ref";
+ power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
+ resets = <&cpg 625>;
+ reset-names = "pwr";
+ max-link-speed = <4>;
+ num-lanes = <2>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x00 0xff>;
+ device_type = "pci";
+ ranges = <0x01000000 0 0x00000000 0 0xee900000 0 0x00400000>,
+ <0x02000000 0 0xc0000000 0 0xc0000000 0 0x10000000>;
+ dma-ranges = <0x42000000 0 0x00000000 0 0x00000000 1 0x00000000>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &gic GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &gic GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &gic GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>;
+ snps,enable-cdm-check;
+ status = "disabled";
+ };
+
+ pciec0_ep: pcie-ep@e65d0000 {
+ compatible = "renesas,r8a779f0-pcie-ep",
+ "renesas,rcar-gen4-pcie-ep";
+ reg = <0 0xe65d0000 0 0x2000>, <0 0xe65d2000 0 0x1000>,
+ <0 0xe65d3000 0 0x2000>, <0 0xe65d5000 0 0x1200>,
+ <0 0xe65d6200 0 0x0e00>, <0 0xe65d7000 0 0x0400>,
+ <0 0xfe000000 0 0x400000>;
+ reg-names = "dbi", "dbi2", "atu", "dma", "app", "phy", "addr_space";
+ interrupts = <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma", "sft_ce", "app";
+ clocks = <&cpg CPG_MOD 624>, <&pcie0_clkref>;
+ clock-names = "core", "ref";
+ power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
+ resets = <&cpg 624>;
+ reset-names = "pwr";
+ max-link-speed = <4>;
+ num-lanes = <2>;
+ max-functions = /bits/ 8 <2>;
+ status = "disabled";
+ };
+
+ pciec1_ep: pcie-ep@e65d8000 {
+ compatible = "renesas,r8a779f0-pcie-ep",
+ "renesas,rcar-gen4-pcie-ep";
+ reg = <0 0xe65d8000 0 0x2000>, <0 0xe65da000 0 0x1000>,
+ <0 0xe65db000 0 0x2000>, <0 0xe65dd000 0 0x1200>,
+ <0 0xe65de200 0 0x0e00>, <0 0xe65df000 0 0x0400>,
+ <0 0xee900000 0 0x400000>;
+ reg-names = "dbi", "dbi2", "atu", "dma", "app", "phy", "addr_space";
+ interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma", "sft_ce", "app";
+ clocks = <&cpg CPG_MOD 625>, <&pcie1_clkref>;
+ clock-names = "core", "ref";
+ power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
+ resets = <&cpg 625>;
+ reset-names = "pwr";
+ max-link-speed = <4>;
+ num-lanes = <2>;
+ max-functions = /bits/ 8 <2>;
+ status = "disabled";
+ };
+
ufs: ufs@e6860000 {
compatible = "renesas,r8a779f0-ufs";
reg = <0 0xe6860000 0 0x100>;
diff --git a/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts b/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts
new file mode 100644
index 000000000000..abfda5c6ca16
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Device Tree Source for the R-Car S4 Starter Kit board
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include "r8a779f4.dtsi"
+
+/ {
+ model = "R-Car S4 Starter Kit board";
+ compatible = "renesas,s4sk", "renesas,r8a779f4", "renesas,r8a779f0";
+
+ aliases {
+ serial0 = &hscif0;
+ serial1 = &hscif1;
+ eth0 = &rswitch;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
+ stdout-path = "serial0:921600n8";
+ };
+
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ /* The last 512MB is reserved for CR. */
+ reg = <0x0 0x48000000 0x0 0x58000000>;
+ };
+
+ memory@480000000 {
+ device_type = "memory";
+ reg = <0x4 0x80000000 0x0 0x80000000>;
+ };
+
+ vcc_sdhi: regulator-vcc-sdhi {
+ compatible = "regulator-fixed";
+ regulator-name = "SDHI Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
+
+&eth_serdes {
+ status = "okay";
+};
+
+&extal_clk {
+ clock-frequency = <20000000>;
+};
+
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
+&hscif0 {
+ pinctrl-0 = <&hscif0_pins>;
+ pinctrl-names = "default";
+
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&hscif1 {
+ pinctrl-0 = <&hscif1_pins>;
+ pinctrl-names = "default";
+
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+};
+
+&i2c4 {
+ pinctrl-0 = <&i2c4_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+};
+
+&i2c5 {
+ pinctrl-0 = <&i2c5_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ eeprom@50 {
+ compatible = "st,24c16", "atmel,24c16";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+&mmc0 {
+ pinctrl-0 = <&sd_pins>;
+ pinctrl-names = "default";
+
+ vmmc-supply = <&vcc_sdhi>;
+ cd-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&pfc {
+ pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ hscif0_pins: hscif0 {
+ groups = "hscif0_data", "hscif0_ctrl";
+ function = "hscif0";
+ };
+
+ hscif1_pins: hscif1 {
+ groups = "hscif1_data", "hscif1_ctrl";
+ function = "hscif1";
+ };
+
+ i2c2_pins: i2c2 {
+ groups = "i2c2";
+ function = "i2c2";
+ };
+
+ i2c4_pins: i2c4 {
+ groups = "i2c4";
+ function = "i2c4";
+ };
+
+ i2c5_pins: i2c5 {
+ groups = "i2c5";
+ function = "i2c5";
+ };
+
+ scif_clk_pins: scif_clk {
+ groups = "scif_clk";
+ function = "scif_clk";
+ };
+
+ sd_pins: sd {
+ groups = "mmc_data4", "mmc_ctrl";
+ function = "mmc";
+ power-source = <3300>;
+ };
+
+ tsn0_pins: tsn0 {
+ groups = "tsn0_mdio_b", "tsn0_link_b";
+ function = "tsn0";
+ drive-strength = <18>;
+ power-source = <3300>;
+ };
+
+ tsn1_pins: tsn1 {
+ groups = "tsn1_mdio_b", "tsn1_link_b";
+ function = "tsn1";
+ drive-strength = <18>;
+ power-source = <3300>;
+ };
+};
+
+&rswitch {
+ pinctrl-0 = <&tsn0_pins>, <&tsn1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ phy-handle = <&ic99>;
+ phy-mode = "sgmii";
+ phys = <&eth_serdes 0>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ic99: ethernet-phy@1 {
+ reg = <1>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ interrupt-parent = <&gpio3>;
+ interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ phy-handle = <&ic102>;
+ phy-mode = "sgmii";
+ phys = <&eth_serdes 1>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ic102: ethernet-phy@2 {
+ reg = <2>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ interrupt-parent = <&gpio3>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+ };
+
+ port@2 {
+ status = "disabled";
+ };
+ };
+};
+
+&rwdt {
+ timeout-sec = <60>;
+ status = "okay";
+};
+
+&scif_clk {
+ clock-frequency = <24000000>;
+};
+
+&ufs {
+ status = "okay";
+};
+
+&ufs30_clk {
+ clock-frequency = <38400000>;
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a779f4.dtsi b/arch/arm64/boot/dts/renesas/r8a779f4.dtsi
new file mode 100644
index 000000000000..ebed41892df3
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779f4.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Device Tree Source for the R-Car S4-8 (R8A779F4) SoC
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+#include "r8a779f0.dtsi"
+
+/ {
+ compatible = "renesas,r8a779f4", "renesas,r8a779f0";
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
new file mode 100644
index 000000000000..6c7b29b69d0e
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G3S SoC
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r9a08g045-cpg.h>
+
+/ {
+ compatible = "renesas,r9a08g045";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a55";
+ reg = <0>;
+ device_type = "cpu";
+ #cooling-cells = <2>;
+ next-level-cache = <&L3_CA55>;
+ enable-method = "psci";
+ clocks = <&cpg CPG_CORE R9A08G045_CLK_I>;
+ };
+
+ L3_CA55: cache-controller-0 {
+ compatible = "cache";
+ cache-level = <3>;
+ cache-unified;
+ cache-size = <0x40000>;
+ };
+ };
+
+ extal_clk: extal-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ scif0: serial@1004b800 {
+ compatible = "renesas,scif-r9a08g045", "renesas,scif-r9a07g044";
+ reg = <0 0x1004b800 0 0x400>;
+ interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi",
+ "bri", "dri", "tei";
+ clocks = <&cpg CPG_MOD R9A08G045_SCIF0_CLK_PCK>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A08G045_SCIF0_RST_SYSTEM_N>;
+ status = "disabled";
+ };
+
+ cpg: clock-controller@11010000 {
+ compatible = "renesas,r9a08g045-cpg";
+ reg = <0 0x11010000 0 0x10000>;
+ clocks = <&extal_clk>;
+ clock-names = "extal";
+ #clock-cells = <2>;
+ #reset-cells = <1>;
+ #power-domain-cells = <0>;
+ };
+
+ sysc: system-controller@11020000 {
+ compatible = "renesas,r9a08g045-sysc";
+ reg = <0 0x11020000 0 0x10000>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "lpm_int", "ca55stbydone_int",
+ "cm33stbyr_int", "ca55_deny";
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl@11030000 {
+ compatible = "renesas,r9a08g045-pinctrl";
+ reg = <0 0x11030000 0 0x10000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 152>;
+ clocks = <&cpg CPG_MOD R9A08G045_GPIO_HCLK>;
+ power-domains = <&cpg>;
+ resets = <&cpg R9A08G045_GPIO_RSTN>,
+ <&cpg R9A08G045_GPIO_PORT_RESETN>,
+ <&cpg R9A08G045_GPIO_SPARE_RESETN>;
+ };
+
+ sdhi0: mmc@11c00000 {
+ compatible = "renesas,sdhi-r9a08g045", "renesas,rcar-gen3-sdhi";
+ reg = <0x0 0x11c00000 0 0x10000>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A08G045_SDHI0_IMCLK>,
+ <&cpg CPG_MOD R9A08G045_SDHI0_CLK_HS>,
+ <&cpg CPG_MOD R9A08G045_SDHI0_IMCLK2>,
+ <&cpg CPG_MOD R9A08G045_SDHI0_ACLK>;
+ clock-names = "core", "clkh", "cd", "aclk";
+ resets = <&cpg R9A08G045_SDHI0_IXRST>;
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ sdhi1: mmc@11c10000 {
+ compatible = "renesas,sdhi-r9a08g045", "renesas,rcar-gen3-sdhi";
+ reg = <0x0 0x11c10000 0 0x10000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A08G045_SDHI1_IMCLK>,
+ <&cpg CPG_MOD R9A08G045_SDHI1_CLK_HS>,
+ <&cpg CPG_MOD R9A08G045_SDHI1_IMCLK2>,
+ <&cpg CPG_MOD R9A08G045_SDHI1_ACLK>;
+ clock-names = "core", "clkh", "cd", "aclk";
+ resets = <&cpg R9A08G045_SDHI1_IXRST>;
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ sdhi2: mmc@11c20000 {
+ compatible = "renesas,sdhi-r9a08g045", "renesas,rcar-gen3-sdhi";
+ reg = <0x0 0x11c20000 0 0x10000>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A08G045_SDHI2_IMCLK>,
+ <&cpg CPG_MOD R9A08G045_SDHI2_CLK_HS>,
+ <&cpg CPG_MOD R9A08G045_SDHI2_IMCLK2>,
+ <&cpg CPG_MOD R9A08G045_SDHI2_ACLK>;
+ clock-names = "core", "clkh", "cd", "aclk";
+ resets = <&cpg R9A08G045_SDHI2_IXRST>;
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@12400000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x0 0x12400000 0 0x40000>,
+ <0x0 0x12440000 0 0x60000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a08g045s33-smarc.dts b/arch/arm64/boot/dts/renesas/r9a08g045s33-smarc.dts
new file mode 100644
index 000000000000..6b57e0e02dbe
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a08g045s33-smarc.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G3S SMARC EVK board
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+
+#include "r9a08g045s33.dtsi"
+#include "rzg3s-smarc-som.dtsi"
+#include "rzg3s-smarc.dtsi"
+
+/ {
+ model = "Renesas SMARC EVK version 2 based on r9a08g045s33";
+ compatible = "renesas,smarc2-evk", "renesas,rzg3s-smarcm",
+ "renesas,r9a08g045s33", "renesas,r9a08g045";
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a08g045s33.dtsi b/arch/arm64/boot/dts/renesas/r9a08g045s33.dtsi
new file mode 100644
index 000000000000..3351f26c7a2a
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a08g045s33.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G3S R9A08G045S33 SoC specific part
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+
+#include "r9a08g045.dtsi"
+
+/ {
+ compatible = "renesas,r9a08g045s33", "renesas,r9a08g045";
+};
diff --git a/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
index a7594ba3a998..b7a3e6caa386 100644
--- a/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
@@ -32,12 +32,6 @@
stdout-path = "serial0:115200n8";
};
- audio_mclock: audio_mclock {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <11289600>;
- };
-
snd_rzg2l: sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
@@ -55,7 +49,7 @@
};
codec_dai: simple-audio-card,codec {
- clocks = <&audio_mclock>;
+ clocks = <&versa3 2>;
sound-dai = <&wm8978>;
};
};
@@ -76,6 +70,12 @@
gpios-states = <1>;
states = <3300000 1>, <1800000 0>;
};
+
+ x1: x1-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
};
&audio_clk1 {
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
index 68eab8e26bf2..37807f1bda4d 100644
--- a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
@@ -110,6 +110,26 @@
#sound-dai-cells = <0>;
reg = <0x1a>;
};
+
+ versa3: clock-generator@68 {
+ compatible = "renesas,5p35023";
+ reg = <0x68>;
+ #clock-cells = <1>;
+ clocks = <&x1>;
+
+ renesas,settings = [
+ 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf
+ 00 14 7a e1 00 00 00 00 01 55 59 bb 3f 30 90 b6
+ 80 b0 45 c4 95
+ ];
+
+ assigned-clocks = <&versa3 0>, <&versa3 1>,
+ <&versa3 2>, <&versa3 3>,
+ <&versa3 4>, <&versa3 5>;
+ assigned-clock-rates = <24000000>, <11289600>,
+ <11289600>, <12000000>,
+ <25000000>, <12288000>;
+ };
};
#if PMOD_MTU3
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
index 83fce96a2575..859bc8745e66 100644
--- a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
@@ -126,6 +126,26 @@
#sound-dai-cells = <0>;
reg = <0x1a>;
};
+
+ versa3: clock-generator@68 {
+ compatible = "renesas,5p35023";
+ reg = <0x68>;
+ #clock-cells = <1>;
+ clocks = <&x1>;
+
+ renesas,settings = [
+ 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf
+ 00 14 7a e1 00 00 00 00 01 55 59 bb 3f 30 90 b6
+ 80 b0 45 c4 95
+ ];
+
+ assigned-clocks = <&versa3 0>, <&versa3 1>,
+ <&versa3 2>, <&versa3 3>,
+ <&versa3 4>, <&versa3 5>;
+ assigned-clock-rates = <24000000>, <11289600>,
+ <11289600>, <12000000>,
+ <25000000>, <12288000>;
+ };
};
#if PMOD_MTU3
diff --git a/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
index 8eb411aac80d..de590996e10a 100644
--- a/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
@@ -20,6 +20,30 @@
sound-dai = <&ssi1>;
};
+&i2c0 {
+ clock-frequency = <400000>;
+
+ versa3: clock-generator@68 {
+ compatible = "renesas,5p35023";
+ reg = <0x68>;
+ #clock-cells = <1>;
+ clocks = <&x1>;
+
+ renesas,settings = [
+ 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf
+ 00 14 7a e1 00 00 00 00 01 55 59 bb 3f 30 90 b6
+ 80 b0 45 c4 95
+ ];
+
+ assigned-clocks = <&versa3 0>, <&versa3 1>,
+ <&versa3 2>, <&versa3 3>,
+ <&versa3 4>, <&versa3 5>;
+ assigned-clock-rates = <24000000>, <11289600>,
+ <11289600>, <12000000>,
+ <25000000>, <12288000>;
+ };
+};
+
&i2c1 {
wm8978: codec@1a {
compatible = "wlf,wm8978";
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
new file mode 100644
index 000000000000..a199de8f8b02
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the R9A08G045S33 SMARC Carrier-II's SoM board.
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
+
+/*
+ * Signals of SW_CONFIG switches:
+ * @SW_SD0_DEV_SEL:
+ * 0 - SD0 is connected to eMMC
+ * 1 - SD0 is connected to uSD0 card
+ */
+#define SW_SD0_DEV_SEL 1
+
+/ {
+ compatible = "renesas,rzg3s-smarcm", "renesas,r9a08g045s33", "renesas,r9a08g045";
+
+ aliases {
+ mmc0 = &sdhi0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@48000000 {
+ device_type = "memory";
+ /* First 128MB is reserved for secure area. */
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
+ vcc_sdhi0: regulator0 {
+ compatible = "regulator-fixed";
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&pinctrl RZG2L_GPIO(2, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+#if SW_SD0_DEV_SEL
+ vccq_sdhi0: regulator1 {
+ compatible = "regulator-gpio";
+ regulator-name = "SDHI0 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&pinctrl RZG2L_GPIO(2, 2) GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1>, <1800000 0>;
+ };
+#else
+ reg_1p8v: regulator1 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+#endif
+};
+
+&extal_clk {
+ clock-frequency = <24000000>;
+};
+
+#if SW_SD0_DEV_SEL
+/* SD0 slot */
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-1 = <&sdhi0_uhs_pins>;
+ pinctrl-names = "default", "state_uhs";
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ max-frequency = <125000000>;
+ status = "okay";
+};
+#else
+/* eMMC */
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_emmc_pins>;
+ pinctrl-1 = <&sdhi0_emmc_pins>;
+ pinctrl-names = "default", "state_uhs";
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&reg_1p8v>;
+ bus-width = <8>;
+ mmc-hs200-1_8v;
+ non-removable;
+ fixed-emmc-driver-type = <1>;
+ max-frequency = <125000000>;
+ status = "okay";
+};
+#endif
+
+&pinctrl {
+ sdhi0_pins: sd0 {
+ data {
+ pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3";
+ power-source = <3300>;
+ };
+
+ ctrl {
+ pins = "SD0_CLK", "SD0_CMD";
+ power-source = <3300>;
+ };
+
+ cd {
+ pinmux = <RZG2L_PORT_PINMUX(0, 0, 1)>; /* SD0_CD */
+ };
+ };
+
+ sdhi0_uhs_pins: sd0-uhs {
+ data {
+ pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3";
+ power-source = <1800>;
+ };
+
+ ctrl {
+ pins = "SD0_CLK", "SD0_CMD";
+ power-source = <1800>;
+ };
+
+ cd {
+ pinmux = <RZG2L_PORT_PINMUX(0, 0, 1)>; /* SD0_CD */
+ };
+ };
+
+ sdhi0_emmc_pins: sd0-emmc {
+ pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3",
+ "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7",
+ "SD0_CLK", "SD0_CMD", "SD0_RST#";
+ power-source = <1800>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
new file mode 100644
index 000000000000..e7073a09ed2e
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ SMARC Carrier-II Board.
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
+
+/ {
+ aliases {
+ serial0 = &scif0;
+ };
+};
+
+&pinctrl {
+ scif0_pins: scif0 {
+ pinmux = <RZG2L_PORT_PINMUX(6, 3, 1)>, /* RXD */
+ <RZG2L_PORT_PINMUX(6, 4, 1)>; /* TXD */
+ };
+};
+
+&scif0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&scif0_pins>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
index 4a3d5037821f..1eb4883b3219 100644
--- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
@@ -822,7 +822,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&cs2000>,
<&audio_clk_c>,
- <&cpg CPG_CORE CPG_AUDIO_CLK_I>;
+ <&cpg CPG_MOD 922>;
ports {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card-mix+split.dtsi b/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card-mix+split.dtsi
index 672b0a224ef9..be6d7a035739 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card-mix+split.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card-mix+split.dtsi
@@ -21,14 +21,14 @@
/ {
sound_card: sound {
compatible = "audio-graph-scu-card";
- label = "rcar-sound";
+ label = "snd-ulcb-mix";
routing = "ak4613 Playback", "DAI0 Playback",
"ak4613 Playback", "DAI1 Playback",
"DAI0 Capture", "ak4613 Capture";
- dais = <&rsnd_port0 /* (A) CPU0 */
- &rsnd_port1 /* (B) CPU1 */
+ dais = <&snd_ulcb1 /* (A) CPU0 */
+ &snd_ulcb2 /* (B) CPU1 */
>;
};
};
@@ -58,14 +58,18 @@
};
&rcar_sound {
- ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports@0 {
#address-cells = <1>;
#size-cells = <0>;
+ reg = <0>;
/*
* (A) CPU0
*/
- rsnd_port0: port@0 {
+ snd_ulcb1: port@0 {
reg = <0>;
rsnd_for_ak4613_1: endpoint {
remote-endpoint = <&ak4613_ep1>;
@@ -78,7 +82,7 @@
/*
* (B) CPU1
*/
- rsnd_port1: port@1 {
+ snd_ulcb2: port@1 {
reg = <1>;
rsnd_for_ak4613_2: endpoint {
remote-endpoint = <&ak4613_ep2>;
diff --git a/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card.dtsi b/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card.dtsi
index 3be54df645e6..3f1df6ee17ea 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card.dtsi
@@ -18,10 +18,10 @@
/ {
sound_card: sound {
compatible = "audio-graph-card";
- label = "rcar-sound";
+ label = "snd-ulcb";
- dais = <&rsnd_port0 /* (A) CPU0 <-> ak4613 */
- &rsnd_port1 /* (B) CPU1 -> HDMI */
+ dais = <&snd_ulcb1 /* (A) CPU0 <-> ak4613 */
+ &snd_ulcb2 /* (B) CPU1 -> HDMI */
>;
};
};
@@ -53,10 +53,15 @@
};
&rcar_sound {
- ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports@0 {
#address-cells = <1>;
#size-cells = <0>;
- rsnd_port0: port@0 {
+ reg = <0>;
+
+ snd_ulcb1: port@0 {
/*
* (A) CPU0 <-> ak4613
*/
@@ -69,7 +74,7 @@
capture = <&ssi1>, <&src1>, <&dvc1>;
};
};
- rsnd_port1: port@1 {
+ snd_ulcb2: port@1 {
/*
* (B) CPU1 -> HDMI
*/
diff --git a/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2-mix+split.dtsi b/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2-mix+split.dtsi
index 75b024e3fef1..8966e6a7d28b 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2-mix+split.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2-mix+split.dtsi
@@ -20,13 +20,12 @@
/ {
sound_card: sound {
compatible = "audio-graph-card2";
- label = "rcar-sound";
+ label = "snd-ulcb-mix";
routing = "ak4613 Playback", "DAI0 Playback",
"ak4613 Playback", "DAI1 Playback",
"DAI0 Capture", "ak4613 Capture";
- /delete-property/ dais;
links = <&fe_a /* (A) CPU0 */
&fe_b /* (B) CPU1 */
&be_x /* (X) ak4613 */
@@ -50,14 +49,12 @@
};
ports@1 {
- #address-cells = <1>;
- #size-cells = <0>;
reg = <1>;
/*
* BE
* (X) ak4613
*/
- be_x: port@0 { reg = <0>; be_x_ep: endpoint { remote-endpoint = <&ak4613_x_ep>; }; };
+ be_x: port { be_x_ep: endpoint { remote-endpoint = <&ak4613_x_ep>; }; };
};
};
};
@@ -78,9 +75,13 @@
};
&rcar_sound {
- ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports@0 {
#address-cells = <1>;
#size-cells = <0>;
+ reg = <0>;
/*
* (A) CPU0
diff --git a/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2.dtsi b/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2.dtsi
index 5ebec1235843..19fa6e102995 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-audio-graph-card2.dtsi
@@ -20,7 +20,7 @@
compatible = "audio-graph-card2";
/delete-property/ dais;
- links = <&rsnd_port0 /* (A) CPU0 <-> ak4613 */
- &rsnd_port1 /* (B) CPU1 -> HDMI */
+ links = <&snd_ulcb1 /* (A) CPU0 <-> ak4613 */
+ &snd_ulcb2 /* (B) CPU1 -> HDMI */
>;
};
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card-mix+split.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card-mix+split.dtsi
index 9b01354940fd..8ae6af1af094 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card-mix+split.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card-mix+split.dtsi
@@ -19,32 +19,31 @@
*
* (A) aplay -D plughw:0,0 xxx.wav (MIX-0)
* (B) aplay -D plughw:0,1 xxx.wav (MIX-1)
- * (C) aplay -D plughw:0,2 xxx.wav (TDM-0)
- * (D) aplay -D plughw:0,3 xxx.wav (TDM-1)
- * (E) aplay -D plughw:0,4 xxx.wav (TDM-2)
- * (F) aplay -D plughw:0,5 xxx.wav (TDM-3)
+ * (C) aplay -D plughw:1,0 xxx.wav (TDM-0)
+ * (D) aplay -D plughw:1,1 xxx.wav (TDM-1)
+ * (E) aplay -D plughw:1,2 xxx.wav (TDM-2)
+ * (F) aplay -D plughw:1,3 xxx.wav (TDM-3)
*
* (A) arecord -D plughw:0,0 xxx.wav
- * (G) arecord -D plughw:0,6 xxx.wav
+ * (G) arecord -D plughw:1,4 xxx.wav
*/
+/ {
+ sound_card_kf: expand-sound {
+ compatible = "audio-graph-scu-card";
+ label = "snd-kf-split";
-&sound_card {
- routing = "ak4613 Playback", "DAI0 Playback",
- "ak4613 Playback", "DAI1 Playback",
- "DAI0 Capture", "ak4613 Capture",
- "pcm3168a Playback", "DAI2 Playback",
- "pcm3168a Playback", "DAI3 Playback",
- "pcm3168a Playback", "DAI4 Playback",
- "pcm3168a Playback", "DAI5 Playback";
+ routing = "pcm3168a Playback", "DAI2 Playback",
+ "pcm3168a Playback", "DAI3 Playback",
+ "pcm3168a Playback", "DAI4 Playback",
+ "pcm3168a Playback", "DAI5 Playback";
- dais = <&rsnd_port0 /* (A) CPU0 */
- &rsnd_port1 /* (B) CPU1 */
- &rsnd_port2 /* (C) CPU2 */
- &rsnd_port3 /* (D) CPU3 */
- &rsnd_port4 /* (E) CPU4 */
- &rsnd_port5 /* (F) CPU5 */
- &rsnd_port6 /* (G) GPU6 */
- >;
+ dais = <&snd_kf1 /* (C) CPU2 */
+ &snd_kf2 /* (D) CPU3 */
+ &snd_kf3 /* (E) CPU4 */
+ &snd_kf4 /* (F) CPU5 */
+ &snd_kf5 /* (G) GPU6 */
+ >;
+ };
};
&pcm3168a {
@@ -103,13 +102,15 @@
};
&rcar_sound {
- ports {
- /* rsnd_port0-1 are defined in ulcb.dtsi */
+ ports@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
/*
* (C) CPU2
*/
- rsnd_port2: port@2 {
+ snd_kf1: port@2 {
reg = <2>;
rsnd_for_pcm3168a_play1: endpoint {
remote-endpoint = <&pcm3168a_endpoint_p1>;
@@ -121,7 +122,7 @@
/*
* (D) CPU3
*/
- rsnd_port3: port@3 {
+ snd_kf2: port@3 {
reg = <3>;
rsnd_for_pcm3168a_play2: endpoint {
remote-endpoint = <&pcm3168a_endpoint_p2>;
@@ -133,7 +134,7 @@
/*
* (E) CPU4
*/
- rsnd_port4: port@4 {
+ snd_kf3: port@4 {
reg = <4>;
rsnd_for_pcm3168a_play3: endpoint {
remote-endpoint = <&pcm3168a_endpoint_p3>;
@@ -145,7 +146,7 @@
/*
* (F) CPU5
*/
- rsnd_port5: port@5 {
+ snd_kf4: port@5 {
reg = <5>;
rsnd_for_pcm3168a_play4: endpoint {
remote-endpoint = <&pcm3168a_endpoint_p4>;
@@ -157,7 +158,7 @@
/*
* (G) CPU6
*/
- rsnd_port6: port@6 {
+ snd_kf5: port@6 {
reg = <6>;
rsnd_for_pcm3168a_capture: endpoint {
remote-endpoint = <&pcm3168a_endpoint_c>;
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card.dtsi
index 1db99b7608f0..5fbd4ca83e20 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card.dtsi
@@ -13,18 +13,20 @@
*
* (A) aplay -D plughw:0,0 xxx.wav
* (B) aplay -D plughw:0,1 xxx.wav
- * (C) aplay -D plughw:0,2 xxx.wav
+ * (C) aplay -D plughw:1,0 xxx.wav
*
* (A) arecord -D plughw:0,0 xxx.wav
- * (D) arecord -D plughw:0,3 xxx.wav
+ * (D) arecord -D plughw:1,1 xxx.wav
*/
+/ {
+ sound_card_kf: expand-sound {
+ compatible = "audio-graph-card";
+ label = "snd-kf";
-&sound_card {
- dais = <&rsnd_port0 /* (A) CPU0 <-> ak4613 */
- &rsnd_port1 /* (B) CPU1 -> HDMI */
- &rsnd_port2 /* (C) CPU2 -> PCM3168A-p */
- &rsnd_port3 /* (D) CPU3 <- PCM3168A-c */
+ dais = <&snd_kf1 /* (C) CPU2 -> PCM3168A-p */
+ &snd_kf2 /* (D) CPU3 <- PCM3168A-c */
>;
+ };
};
&pcm3168a {
@@ -56,12 +58,15 @@
};
&rcar_sound {
- ports {
- /* rsnd_port0/1 are defined in ulcb.dtsi */
+ ports@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
/*
* (C) CPU2 -> PCM3168A-p
*/
- rsnd_port2: port@2 {
+ snd_kf1: port@2 {
reg = <2>;
rsnd_for_pcm3168a_play: endpoint {
remote-endpoint = <&pcm3168a_endpoint_p>;
@@ -74,7 +79,7 @@
/*
* (D) CPU3 <- PCM3168A-c
*/
- rsnd_port3: port@3 {
+ snd_kf2: port@3 {
reg = <3>;
rsnd_for_pcm3168a_capture: endpoint {
remote-endpoint = <&pcm3168a_endpoint_c>;
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2-mix+split.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2-mix+split.dtsi
index da644128a9ae..4cf632bc4621 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2-mix+split.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2-mix+split.dtsi
@@ -19,61 +19,65 @@
*
* (A) aplay -D plughw:0,0 xxx.wav (MIX-0)
* (B) aplay -D plughw:0,1 xxx.wav (MIX-1)
- * (C) aplay -D plughw:0,2 xxx.wav (TDM-0)
- * (D) aplay -D plughw:0,3 xxx.wav (TDM-1)
- * (E) aplay -D plughw:0,4 xxx.wav (TDM-2)
- * (F) aplay -D plughw:0,5 xxx.wav (TDM-3)
+ * (C) aplay -D plughw:1,0 xxx.wav (TDM-0)
+ * (D) aplay -D plughw:1,1 xxx.wav (TDM-1)
+ * (E) aplay -D plughw:1,2 xxx.wav (TDM-2)
+ * (F) aplay -D plughw:1,3 xxx.wav (TDM-3)
*
* (A) arecord -D plughw:0,0 xxx.wav
- * (G) arecord -D plughw:0,6 xxx.wav
+ * (G) arecord -D plughw:1,4 xxx.wav
*/
-&sound_card {
- routing = "ak4613 Playback", "DAI0 Playback",
- "ak4613 Playback", "DAI1 Playback",
- "DAI0 Capture", "ak4613 Capture",
- "pcm3168a Playback", "DAI2 Playback",
- "pcm3168a Playback", "DAI3 Playback",
- "pcm3168a Playback", "DAI4 Playback",
- "pcm3168a Playback", "DAI5 Playback",
- "DAI6 Capture", "pcm3168a Capture";
+/ {
+ sound_card_kf: expand-sound {
+ compatible = "audio-graph-card2";
+ label = "snd-kf-split";
- /delete-property/ dais;
- links = <&fe_a /* (A) CPU0 */
- &fe_b /* (B) CPU1 */
- &fe_c /* (C) CPU2 */
- &fe_d /* (D) CPU3 */
- &fe_e /* (E) CPU4 */
- &fe_f /* (F) CPU5 */
- &rsnd_g /* (G) CPU6 */
- &be_x /* (X) ak4613 */
- &be_y /* (Y) PCM3168A-p */
- >;
+ routing = "pcm3168a Playback", "DAI2 Playback",
+ "pcm3168a Playback", "DAI3 Playback",
+ "pcm3168a Playback", "DAI4 Playback",
+ "pcm3168a Playback", "DAI5 Playback",
+ "DAI6 Capture", "pcm3168a Capture";
- dpcm {
- ports@0 {
- /*
- * FE
- *
- * (A)/(B) are defined on ulcb
- * (C) CPU2
- * (D) CPU3
- * (E) CPU4
- * (F) CPU5
- */
- fe_c: port@2 { reg = <2>; fe_c_ep: endpoint { remote-endpoint = <&rsnd_c_ep>; }; };
- fe_d: port@3 { reg = <3>; fe_d_ep: endpoint { remote-endpoint = <&rsnd_d_ep>; }; };
- fe_e: port@4 { reg = <4>; fe_e_ep: endpoint { remote-endpoint = <&rsnd_e_ep>; }; };
- fe_f: port@5 { reg = <5>; fe_f_ep: endpoint { remote-endpoint = <&rsnd_f_ep>; }; };
- };
+ links = <&fe_c /* (C) CPU2 */
+ &fe_d /* (D) CPU3 */
+ &fe_e /* (E) CPU4 */
+ &fe_f /* (F) CPU5 */
+ &rsnd_g /* (G) CPU6 */
+ &be_y /* (Y) PCM3168A-p */
+ >;
- ports@1 {
- /*
- * BE
- *
- * (X) is defined on ulcb
- * (Y) PCM3168A-p
- */
- be_y: port@1 { reg = <1>; be_y_ep: endpoint { remote-endpoint = <&pcm3168a_y_ep>; }; };
+ dpcm {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ /*
+ * FE
+ *
+ * (C) CPU2
+ * (D) CPU3
+ * (E) CPU4
+ * (F) CPU5
+ */
+ fe_c: port@2 { reg = <2>; fe_c_ep: endpoint { remote-endpoint = <&rsnd_c_ep>; }; };
+ fe_d: port@3 { reg = <3>; fe_d_ep: endpoint { remote-endpoint = <&rsnd_d_ep>; }; };
+ fe_e: port@4 { reg = <4>; fe_e_ep: endpoint { remote-endpoint = <&rsnd_e_ep>; }; };
+ fe_f: port@5 { reg = <5>; fe_f_ep: endpoint { remote-endpoint = <&rsnd_f_ep>; }; };
+ };
+
+ ports@1 {
+ reg = <1>;
+ /*
+ * BE
+ *
+ * (Y) PCM3168A-p
+ */
+ be_y: port { be_y_ep: endpoint { remote-endpoint = <&pcm3168a_y_ep>; }; };
+ };
};
};
};
@@ -111,8 +115,10 @@
};
&rcar_sound {
- ports {
- /* (A)/(B) are defined in ulcb.dtsi */
+ ports@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
/*
* (C) CPU2
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2.dtsi
index c30e056538e4..4fc229418dd7 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2.dtsi
@@ -13,18 +13,18 @@
*
* (A) aplay -D plughw:0,0 xxx.wav
* (B) aplay -D plughw:0,1 xxx.wav
- * (C) aplay -D plughw:0,2 xxx.wav
+ * (C) aplay -D plughw:1,0 xxx.wav
*
* (A) arecord -D plughw:0,0 xxx.wav
- * (D) arecord -D plughw:0,3 xxx.wav
+ * (D) arecord -D plughw:1,1 xxx.wav
*/
#include "ulcb-kf-audio-graph-card.dtsi"
-&sound_card {
+&sound_card_kf {
+ compatible = "audio-graph-card2";
+
/delete-property/ dais;
- links = <&rsnd_port0 /* (A) CPU0 <-> ak4613 */
- &rsnd_port1 /* (B) CPU1 -> HDMI */
- &rsnd_port2 /* (C) CPU2 -> PCM3168A-p */
- &rsnd_port3 /* (D) CPU3 <- PCM3168A-c */
+ links = <&snd_kf1 /* (C) CPU2 -> PCM3168A-p */
+ &snd_kf2 /* (D) CPU3 <- PCM3168A-c */
>;
};
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card-mix+split.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card-mix+split.dtsi
index bc221f994473..f01d91aaadf3 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card-mix+split.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card-mix+split.dtsi
@@ -19,89 +19,92 @@
*
* (A) aplay -D plughw:0,0 xxx.wav (MIX-0)
* (B) aplay -D plughw:0,1 xxx.wav (MIX-1)
- * (C) aplay -D plughw:0,2 xxx.wav (TDM-0)
- * (D) aplay -D plughw:0,3 xxx.wav (TDM-1)
- * (E) aplay -D plughw:0,4 xxx.wav (TDM-2)
- * (F) aplay -D plughw:0,5 xxx.wav (TDM-3)
+ * (C) aplay -D plughw:1,0 xxx.wav (TDM-0)
+ * (D) aplay -D plughw:1,1 xxx.wav (TDM-1)
+ * (E) aplay -D plughw:1,2 xxx.wav (TDM-2)
+ * (F) aplay -D plughw:1,3 xxx.wav (TDM-3)
*
* (A) arecord -D plughw:0,0 xxx.wav
- * (G) arecord -D plughw:0,6 xxx.wav
+ * (G) arecord -D plughw:1,4 xxx.wav
*/
-&sound_card {
-
- simple-audio-card,routing = "ak4613 Playback", "DAI0 Playback",
- "ak4613 Playback", "DAI1 Playback",
- "DAI0 Capture", "ak4613 Capture",
- "pcm3168a Playback", "DAI2 Playback",
- "pcm3168a Playback", "DAI3 Playback",
- "pcm3168a Playback", "DAI4 Playback",
- "pcm3168a Playback", "DAI5 Playback";
-
- /* dai-link@0 is defined in ulcb.dtsi */
-
- simple-audio-card,dai-link@1 {
+/ {
+ sound_card_kf: expand-sound {
#address-cells = <1>;
#size-cells = <0>;
- reg = <1>;
- convert-channels = <8>; /* to 8ch TDM */
- /*
- * (C) CPU2
- */
- cpu@0 {
+ compatible = "simple-scu-audio-card";
+ label = "snd-kf-split";
+
+ simple-audio-card,routing = "pcm3168a Playback", "DAI2 Playback",
+ "pcm3168a Playback", "DAI3 Playback",
+ "pcm3168a Playback", "DAI4 Playback",
+ "pcm3168a Playback", "DAI5 Playback";
+
+ simple-audio-card,dai-link@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
reg = <0>;
- bitclock-master;
- frame-master;
- sound-dai = <&rcar_sound 2>;
+ convert-channels = <8>; /* to 8ch TDM */
+
+ /*
+ * (C) CPU2
+ */
+ cpu@0 {
+ reg = <0>;
+ bitclock-master;
+ frame-master;
+ sound-dai = <&rcar_sound 2>;
+ };
+ /*
+ * (D) CPU3
+ */
+ cpu@1 {
+ reg = <1>;
+ sound-dai = <&rcar_sound 3>;
+ };
+ /*
+ * (E) CPU4
+ */
+ cpu@2 {
+ reg = <2>;
+ sound-dai = <&rcar_sound 4>;
+ };
+ /*
+ * (F) CPU5
+ */
+ cpu@3 {
+ reg = <3>;
+ sound-dai = <&rcar_sound 5>;
+ };
+ /*
+ * (Y) PCM3168A-p
+ */
+ codec {
+ prefix = "pcm3168a";
+ mclk-fs = <512>;
+ sound-dai = <&pcm3168a 0>;
+ };
};
- /*
- * (D) CPU3
- */
- cpu@1 {
+
+ simple-audio-card,dai-link@1 {
reg = <1>;
- sound-dai = <&rcar_sound 3>;
- };
- /*
- * (E) CPU4
- */
- cpu@2 {
- reg = <2>;
- sound-dai = <&rcar_sound 4>;
- };
- /*
- * (F) CPU5
- */
- cpu@3 {
- reg = <3>;
- sound-dai = <&rcar_sound 5>;
- };
- /*
- * (Y) PCM3168A-p
- */
- codec {
- prefix = "pcm3168a";
- mclk-fs = <512>;
- sound-dai = <&pcm3168a 0>;
- };
- };
- simple-audio-card,dai-link@2 {
- reg = <2>;
- /*
- * (G) CPU6
- */
- cpu {
- bitclock-master;
- frame-master;
- sound-dai = <&rcar_sound 6>;
- };
- /*
- * (Z) PCM3168A-c
- */
- codec {
- prefix = "pcm3168a";
- mclk-fs = <512>;
- sound-dai = <&pcm3168a 1>;
+ /*
+ * (G) CPU6
+ */
+ cpu {
+ bitclock-master;
+ frame-master;
+ sound-dai = <&rcar_sound 6>;
+ };
+ /*
+ * (Z) PCM3168A-c
+ */
+ codec {
+ prefix = "pcm3168a";
+ mclk-fs = <512>;
+ sound-dai = <&pcm3168a 1>;
+ };
};
};
};
@@ -115,7 +118,8 @@
};
&rcar_sound {
- rcar_sound,dai {
+ rcar_sound,dai@1 {
+ reg = <1>;
/* dai0-1 are defined in ulcb.dtsi */
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card.dtsi
index 2010e8ac7fdc..28d29ecfb395 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-kf-simple-audio-card.dtsi
@@ -13,45 +13,51 @@
*
* (A) aplay -D plughw:0,0 xxx.wav
* (B) aplay -D plughw:0,1 xxx.wav
- * (C) aplay -D plughw:0,2 xxx.wav
+ * (C) aplay -D plughw:1,0 xxx.wav
*
* (A) arecord -D plughw:0,0 xxx.wav
- * (D) arecord -D plughw:0,3 xxx.wav
+ * (D) arecord -D plughw:1,1 xxx.wav
*/
-&sound_card {
- /* dai-link@0/1 are defined in ulcb.dtsi */
+/ {
+ sound_card_kf: expand-sound {
+ compatible = "simple-audio-card";
+ label = "snd-kf";
- /*
- * (C) CPU2 -> PCM3168A-p
- */
- simple-audio-card,dai-link@2 {
- reg = <2>;
- cpu {
- bitclock-master;
- frame-master;
- dai-tdm-slot-num = <8>;
- sound-dai = <&rcar_sound 2>;
- };
- codec {
- mclk-fs = <512>;
- sound-dai = <&pcm3168a 0>;
- };
- };
- /*
- * (D) CPU3 <- PCM3168A-c
- */
- simple-audio-card,dai-link@3 {
- reg = <3>;
- cpu {
- bitclock-master;
- frame-master;
- dai-tdm-slot-num = <6>;
- sound-dai = <&rcar_sound 3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * (C) CPU2 -> PCM3168A-p
+ */
+ simple-audio-card,dai-link@0 {
+ reg = <0>;
+ cpu {
+ bitclock-master;
+ frame-master;
+ dai-tdm-slot-num = <8>;
+ sound-dai = <&rcar_sound 2>;
+ };
+ codec {
+ mclk-fs = <512>;
+ sound-dai = <&pcm3168a 0>;
+ };
};
- codec {
- mclk-fs = <512>;
- sound-dai = <&pcm3168a 1>;
+ /*
+ * (D) CPU3 <- PCM3168A-c
+ */
+ simple-audio-card,dai-link@1 {
+ reg = <1>;
+ cpu {
+ bitclock-master;
+ frame-master;
+ dai-tdm-slot-num = <6>;
+ sound-dai = <&rcar_sound 3>;
+ };
+ codec {
+ mclk-fs = <512>;
+ sound-dai = <&pcm3168a 1>;
+ };
};
};
};
@@ -65,9 +71,8 @@
};
&rcar_sound {
-
- rcar_sound,dai {
- /* dai0-1 are defined in ulcb.dtsi */
+ rcar_sound,dai@1 {
+ reg = <1>;
/*
* (C) CPU2 -> PCM3168A-p
diff --git a/arch/arm64/boot/dts/renesas/ulcb-simple-audio-card-mix+split.dtsi b/arch/arm64/boot/dts/renesas/ulcb-simple-audio-card-mix+split.dtsi
index 217d89019845..9b955510e38e 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-simple-audio-card-mix+split.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-simple-audio-card-mix+split.dtsi
@@ -24,7 +24,7 @@
#size-cells = <0>;
compatible = "simple-scu-audio-card";
- label = "rcar-sound";
+ label = "snd-ulcb-mix";
simple-audio-card,prefix = "ak4613";
simple-audio-card,routing = "ak4613 Playback", "DAI0 Playback",
@@ -72,9 +72,13 @@
};
&rcar_sound {
+ #address-cells = <1>;
+ #size-cells = <0>;
#sound-dai-cells = <1>;
- rcar_sound,dai {
+ rcar_sound,dai@0 {
+ reg = <0>;
+
/*
* (A) CPU0
*/
diff --git a/arch/arm64/boot/dts/renesas/ulcb-simple-audio-card.dtsi b/arch/arm64/boot/dts/renesas/ulcb-simple-audio-card.dtsi
index 751cfd8c5257..ba0e188e7b21 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-simple-audio-card.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-simple-audio-card.dtsi
@@ -18,7 +18,7 @@
/ {
sound_card: sound {
compatible = "simple-audio-card";
- label = "rcar-sound";
+ label = "snd-ulcb";
#address-cells = <1>;
#size-cells = <0>;
@@ -69,9 +69,13 @@
};
&rcar_sound {
+ #address-cells = <1>;
+ #size-cells = <0>;
#sound-dai-cells = <1>;
- rcar_sound,dai {
+ rcar_sound,dai@0 {
+ reg = <0>;
+
/*
* (A) CPU0 <-> ak4613
*/
diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi
index 0be2716659e9..a2f66f916048 100644
--- a/arch/arm64/boot/dts/renesas/ulcb.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi
@@ -383,7 +383,7 @@
<&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
<&audio_clk_a>, <&cs2000>,
<&audio_clk_c>,
- <&cpg CPG_CORE CPG_AUDIO_CLK_I>;
+ <&cpg CPG_MOD 922>;
};
&rpc {
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index e7728007fd1b..a18f33bf0c0e 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -77,6 +77,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353vs.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg503.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.1.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.2.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-powkiddy-rgb30.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-cm3-io.dtb
@@ -101,7 +102,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-orangepi-5-plus.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-turing-rk1.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5a.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 5bc2d4faeea6..faf02e59d6c7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1358,7 +1358,6 @@
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru PCLK_DDR_MON>;
clock-names = "pclk_ddr_mon";
- status = "disabled";
};
vpu: video-codec@ff650000 {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts
new file mode 100644
index 000000000000..1ead3c5c24b3
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3566-anbernic-rg353x.dtsi"
+
+/ {
+ model = "RGB30";
+ compatible = "powkiddy,rgb30", "rockchip,rk3566";
+
+ aliases {
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ mmc3 = &sdmmc2;
+ };
+
+ battery: battery {
+ compatible = "simple-battery";
+ charge-full-design-microamp-hours = <3151000>;
+ charge-term-current-microamp = <300000>;
+ constant-charge-current-max-microamp = <2000000>;
+ constant-charge-voltage-max-microvolt = <4250000>;
+ factory-internal-resistance-micro-ohms = <117000>;
+ voltage-max-design-microvolt = <4172000>;
+ voltage-min-design-microvolt = <3400000>;
+
+ ocv-capacity-celsius = <20>;
+ ocv-capacity-table-0 = <4172000 100>, <4092000 95>, <4035000 90>, <3990000 85>,
+ <3939000 80>, <3895000 75>, <3852000 70>, <3807000 65>,
+ <3762000 60>, <3713000 55>, <3672000 50>, <3647000 45>,
+ <3629000 40>, <3613000 35>, <3598000 30>, <3578000 25>,
+ <3550000 20>, <3519000 15>, <3479000 10>, <3438000 5>,
+ <3400000 0>;
+ };
+
+ /*
+ * Channels reversed for speakers. Headphones automatically switch via hardware when
+ * detected with no ability to control output in software. Headphones appear to be mono
+ * (each output channel receives all audio). No microphone support on 3.5mm jack.
+ */
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "rk817_ext";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,widgets =
+ "Headphone", "Headphones";
+ simple-audio-card,routing =
+ "Headphones", "HPOL",
+ "Headphones", "HPOR";
+
+ simple-audio-card,codec {
+ sound-dai = <&rk817>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+ };
+};
+
+/delete-node/ &adc_keys;
+
+&chosen {
+ /delete-property/ stdout-path;
+};
+
+&cru {
+ assigned-clocks = <&pmucru CLK_RTC_32K>, <&cru PLL_GPLL>,
+ <&pmucru PLL_PPLL>, <&cru PLL_VPLL>;
+ assigned-clock-rates = <32768>, <1200000000>,
+ <200000000>, <292500000>;
+};
+
+&gpio_keys_control {
+ button-r1 {
+ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>;
+ label = "TR";
+ linux,code = <BTN_TR>;
+ };
+
+ button-r2 {
+ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
+ label = "TR2";
+ linux,code = <BTN_TR2>;
+ };
+};
+
+/delete-node/ &{/i2c@fdd40000/regulator@40};
+
+&i2c0 {
+ vdd_cpu: regulator@1c {
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1390000>;
+ regulator-name = "vdd_cpu";
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc_sys>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+/*
+ * Device has 2 red LEDs instead of an amber and a red. Relabel LEDs as
+ * red_led0 and red_led1.
+ */
+/delete-node/ &{/pwm-leds/led-1};
+/delete-node/ &{/pwm-leds/led-2};
+
+&leds {
+ red_led0: led-1 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_CHARGING;
+ max-brightness = <255>;
+ pwms = <&pwm7 0 25000 0>;
+ };
+
+ red_led1: led-2 {
+ color = <LED_COLOR_ID_RED>;
+ default-state = "off";
+ function = LED_FUNCTION_STATUS;
+ max-brightness = <255>;
+ pwms = <&pwm0 0 25000 0>;
+ };
+};
+
+&panel {
+ compatible = "powkiddy,rgb30-panel";
+ vcc-supply = <&vcc3v3_lcd0_n>;
+ iovcc-supply = <&vcc3v3_lcd0_n>;
+ /delete-property/ vdd-supply;
+};
+
+&pwm5 {
+ status = "disabled";
+};
+
+&rk817 {
+ rk817_charger: charger {
+ monitored-battery = <&battery>;
+ rockchip,resistor-sense-micro-ohms = <10000>;
+ rockchip,sleep-enter-current-microamp = <300000>;
+ rockchip,sleep-filter-current-microamp = <100000>;
+ };
+};
+
+/* There is no UART header visible on the board for this device. */
+&uart2 {
+ status = "disabled";
+};
+
+/delete-node/ &vibrator;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
index e05ab11981f5..a5e974ea659e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
@@ -15,6 +15,7 @@
ethernet0 = &gmac1;
mmc0 = &sdhci;
mmc1 = &sdmmc0;
+ mmc2 = &sdmmc2;
};
chosen: chosen {
@@ -747,6 +748,9 @@
non-removable;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
sd-uhs-sdr104;
vmmc-supply = <&vcc3v3_sys>;
vqmmc-supply = <&vcc_1v8>;
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index abee88911982..0964761e3ce9 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -959,6 +959,13 @@
reg = <0x0 0xfe1a8100 0x0 0x20>;
};
+ dfi: dfi@fe230000 {
+ compatible = "rockchip,rk3568-dfi";
+ reg = <0x00 0xfe230000 0x00 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ rockchip,pmu = <&pmugrf>;
+ };
+
pcie2x1: pcie@fe260000 {
compatible = "rockchip,rk3568-pcie";
reg = <0x3 0xc0000000 0x0 0x00400000>,
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
index 229a9111f5eb..b9d789d57862 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include "rk3588.dtsi"
@@ -23,12 +24,84 @@
stdout-path = "serial2:1500000n8";
};
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-vol-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ press-threshold-microvolt = <17000>;
+ };
+
+ button-vol-down {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ press-threshold-microvolt = <417000>;
+ };
+
+ button-menu {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <890000>;
+ };
+
+ button-escape {
+ label = "Escape";
+ linux,code = <KEY_ESC>;
+ press-threshold-microvolt = <1235000>;
+ };
+ };
+
backlight: backlight {
compatible = "pwm-backlight";
power-supply = <&vcc12v_dcin>;
pwms = <&pwm2 0 25000 0>;
};
+ pcie20_avdd0v85: pcie20-avdd0v85-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie20_avdd0v85";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ vin-supply = <&avdd_0v85_s0>;
+ };
+
+ pcie20_avdd1v8: pcie20-avdd1v8-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie20_avdd1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&avcc_1v8_s0>;
+ };
+
+ pcie30_avdd0v75: pcie30-avdd0v75-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie30_avdd0v75";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ vin-supply = <&avdd_0v75_s0>;
+ };
+
+ pcie30_avdd1v8: pcie30-avdd1v8-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie30_avdd1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&avcc_1v8_s0>;
+ };
+
vcc12v_dcin: vcc12v-dcin-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc12v_dcin";
@@ -38,6 +111,19 @@
regulator-max-microvolt = <12000000>;
};
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc12v_dcin>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v3_pcie30_en>;
+ };
+
vcc5v0_host: vcc5v0-host-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_host";
@@ -87,6 +173,10 @@
status = "okay";
};
+&combphy2_psu {
+ status = "okay";
+};
+
&cpu_b0 {
cpu-supply = <&vdd_cpu_big0_s0>;
};
@@ -163,7 +253,32 @@
};
};
+&pcie2x1l1 {
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_1_rst>, <&rtl8111_isolate>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_reset>;
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
&pinctrl {
+ rtl8111 {
+ rtl8111_isolate: rtl8111-isolate {
+ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
rtl8211f {
rtl8211f_rst: rtl8211f-rst {
rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -177,6 +292,22 @@
};
};
+ pcie2 {
+ pcie2_1_rst: pcie2-1-rst {
+ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie3 {
+ pcie3_reset: pcie3-reset {
+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc3v3_pcie30_en: vcc3v3-pcie30-en {
+ rockchip,pins = <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
usb {
vcc5v0_host_en: vcc5v0-host-en {
rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -188,6 +319,11 @@
status = "okay";
};
+&saradc {
+ vref-supply = <&vcc_1v8_s0>;
+ status = "okay";
+};
+
&sdhci {
bus-width = <8>;
no-sdio;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
index 0bd80e515754..97af4f912828 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
@@ -137,6 +137,18 @@
vin-supply = <&vcc5v0_sys>;
};
+ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_m2_1_pwren>;
+ regulator-name = "vcc3v3_pcie2x1l0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
vcc3v3_pcie30: vcc3v3-pcie30-regulator {
compatible = "regulator-fixed";
enable-active-high;
@@ -421,6 +433,14 @@
status = "okay";
};
+&pcie2x1l1 {
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_1_rst>;
+ status = "okay";
+};
+
&pcie2x1l2 {
reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc_3v3_pcie20>;
@@ -467,6 +487,10 @@
rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
};
+ pcie2_1_rst: pcie2-1-rst {
+ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
pcie2_2_rst: pcie2-2-rst {
rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
};
@@ -474,6 +498,10 @@
pcie_m2_0_pwren: pcie-m20-pwren {
rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
+
+ pcie_m2_1_pwren: pcie-m21-pwren {
+ rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
};
usb {
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
new file mode 100644
index 000000000000..298c183d6f4f
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
@@ -0,0 +1,848 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Ondřej Jirman <megi@xff.cz>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
+#include "rk3588.dtsi"
+
+/ {
+ model = "Xunlong Orange Pi 5 Plus";
+ compatible = "xunlong,orangepi-5-plus", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ serial2 = &uart2;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-keys-0 {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-maskrom {
+ label = "Mask Rom";
+ linux,code = <KEY_SETUP>;
+ press-threshold-microvolt = <2000>;
+ };
+ };
+
+ adc-keys-1 {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <2000>;
+ };
+ };
+
+ speaker_amp: speaker-audio-amplifier {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>;
+ sound-name-prefix = "Speaker Amp";
+ };
+
+ headphone_amp: headphones-audio-amplifier {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>;
+ sound-name-prefix = "Headphones Amp";
+ };
+
+ ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_receiver_pin>;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&blue_led_pin>;
+
+ led {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_INDICATOR;
+ function-enumerator = <1>;
+ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 70 75 80 100>;
+ fan-supply = <&vcc5v0_sys>;
+ pwms = <&pwm3 0 50000 0>;
+ #cooling-cells = <2>;
+ };
+
+ pwm-leds {
+ compatible = "pwm-leds";
+
+ led {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
+ function-enumerator = <2>;
+ max-brightness = <255>;
+ pwms = <&pwm2 0 25000 0>;
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_detect>;
+ simple-audio-card,name = "Analog";
+ simple-audio-card,aux-devs = <&speaker_amp>, <&headphone_amp>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,hp-det-gpio = <&gpio1 RK_PD3 GPIO_ACTIVE_LOW>;
+ simple-audio-card,bitclock-master = <&daicpu>;
+ simple-audio-card,frame-master = <&daicpu>;
+ /*TODO: SARADC_IN3 is used as MIC detection / key input */
+
+ simple-audio-card,widgets =
+ "Microphone", "Onboard Microphone",
+ "Microphone", "Microphone Jack",
+ "Speaker", "Speaker",
+ "Headphone", "Headphones";
+
+ simple-audio-card,routing =
+ "Headphones", "LOUT1",
+ "Headphones", "ROUT1",
+ "Speaker", "LOUT2",
+ "Speaker", "ROUT2",
+
+ "Headphones", "Headphones Amp OUTL",
+ "Headphones", "Headphones Amp OUTR",
+ "Headphones Amp INL", "LOUT1",
+ "Headphones Amp INR", "ROUT1",
+
+ "Speaker", "Speaker Amp OUTL",
+ "Speaker", "Speaker Amp OUTR",
+ "Speaker Amp INL", "LOUT2",
+ "Speaker Amp INR", "ROUT2",
+
+ /* single ended signal to LINPUT1 */
+ "LINPUT1", "Microphone Jack",
+ "RINPUT1", "Microphone Jack",
+ /* differential signal */
+ "LINPUT2", "Onboard Microphone",
+ "RINPUT2", "Onboard Microphone";
+
+ daicpu: simple-audio-card,cpu {
+ sound-dai = <&i2s0_8ch>;
+ system-clock-frequency = <12288000>;
+ };
+
+ daicodec: simple-audio-card,codec {
+ sound-dai = <&es8388>;
+ system-clock-frequency = <12288000>;
+ };
+ };
+
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pcie_eth: vcc3v3-pcie-eth-regulator {
+ compatible = "regulator-fixed";
+ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
+ regulator-name = "vcc3v3_pcie_eth";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_wf: vcc3v3-wf-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_wf";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc5v0_usb20: vcc5v0-usb20-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_usb20_en>;
+ regulator-name = "vcc5v0_usb20";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ wakeup-source;
+ };
+};
+
+&i2c7 {
+ status = "okay";
+
+ /* PLDO2 vcca 1.8V, BUCK8 gated by PLDO2 being enabled */
+ es8388: audio-codec@11 {
+ compatible = "everest,es8388";
+ reg = <0x11>;
+ clocks = <&cru I2S0_8CH_MCLKOUT>;
+ clock-names = "mclk";
+ AVDD-supply = <&vcc_1v8_s0>;
+ DVDD-supply = <&vcc_1v8_s0>;
+ HPVDD-supply = <&vcc_3v3_s0>;
+ PVDD-supply = <&vcc_3v3_s0>;
+ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+ assigned-clock-rates = <12288000>;
+ #sound-dai-cells = <0>;
+ };
+};
+
+&i2s0_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_lrck
+ &i2s0_mclk
+ &i2s0_sclk
+ &i2s0_sdi0
+ &i2s0_sdo0>;
+ status = "okay";
+};
+
+&i2s2_2ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s2m0_lrck
+ &i2s2m0_sclk
+ &i2s2m0_sdi
+ &i2s2m0_sdo>;
+ status = "okay";
+};
+
+/* phy1 - M.KEY socket */
+&pcie2x1l0 {
+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_wf>;
+ status = "okay";
+};
+
+/* phy2 - right ethernet port */
+&pcie2x1l1 {
+ reset-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie_eth>;
+ status = "okay";
+};
+
+/* phy0 - left ethernet port */
+&pcie2x1l2 {
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie_eth>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
+&pinctrl {
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ blue_led_pin: blue-led {
+ rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ ir-receiver {
+ ir_receiver_pin: ir-receiver-pin {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sound {
+ hp_detect: hp-detect {
+ rockchip,pins = <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ vcc5v0_usb20_en: vcc5v0-usb20-en {
+ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm2 {
+ pinctrl-0 = <&pwm2m1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&pwm3 {
+ pinctrl-0 = <&pwm3m1_pins>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ max-frequency = <200000000>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-sdio;
+ no-mmc;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&sfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspim1_pins>;
+ status = "okay";
+
+ spi_flash: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-max-frequency = <100000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&spi2 {
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ status = "okay";
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+ spi-max-frequency = <1000000>;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vdd2_ddr_s3>;
+ vcc14-supply = <&vdd2_ddr_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: dcdc-reg1 {
+ regulator-name = "vdd_gpu_s0";
+ regulator-boot-on;
+ regulator-enable-ramp-delay = <400>;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: dcdc-reg2 {
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-name = "vdd_log_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <825000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: dcdc-reg4 {
+ regulator-name = "vdd_vdenc_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <825000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-name = "vdd_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-name = "vdd2_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-name = "vdd_2v0_pldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-name = "vcc_3v3_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-name = "vddq_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-name = "vcc_1v8_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-name = "avcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ /* shorted to avcc_1v8_s0 on the board */
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-name = "vcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-name = "avdd_1v2_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-name = "vcc_3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-name = "vccio_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-name = "pldo6_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-name = "vdd_0v75_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-name = "vdd_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-name = "avdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ /*
+ * The schematic mentions that actual setting
+ * should be 0.8375V. RK3588 datasheet specifies
+ * maximum as 0.825V. So we set datasheet max
+ * here.
+ */
+ regulator-min-microvolt = <825000>;
+ regulator-max-microvolt = <825000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-name = "vdd_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-name = "vdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ phy-supply = <&vcc5v0_usb20>;
+ status = "okay";
+};
+
+&u2phy3_host {
+ phy-supply = <&vcc5v0_usb20>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&uart9 {
+ pinctrl-0 = <&uart9m0_xfer>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
new file mode 100644
index 000000000000..5c59f9571dce
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
@@ -0,0 +1,1137 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Ondřej Jirman <megi@xff.cz>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
+#include "rk3588.dtsi"
+
+/ {
+ model = "PINE64 QuartzPro64";
+ compatible = "pine64,quartzpro64", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ serial2 = &uart2;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-keys-0 {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-maskrom {
+ label = "Mask Rom";
+ linux,code = <KEY_SETUP>;
+ press-threshold-microvolt = <393>;
+ };
+ };
+
+ adc-keys-1 {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-volume-up {
+ label = "V+/REC";
+ linux,code = <KEY_VOLUMEUP>;
+ press-threshold-microvolt = <17821>;
+ };
+
+ button-volume-down {
+ label = "V-";
+ linux,code = <KEY_VOLUMEDOWN>;
+ press-threshold-microvolt = <415384>;
+ };
+
+ button-menu {
+ label = "MENU";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <890909>;
+ };
+
+ button-esc {
+ label = "ESC";
+ linux,code = <KEY_ESC>;
+ press-threshold-microvolt = <1233962>;
+ };
+ };
+
+ headphone_amp: audio-amplifier-headphone {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ sound-name-prefix = "Headphones Amp";
+ };
+
+ speaker_amp: audio-amplifier-speaker {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>;
+ sound-name-prefix = "Speaker Amp";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ led-1 {
+ color = <LED_COLOR_ID_ORANGE>;
+ function = LED_FUNCTION_INDICATOR;
+ gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_detect>;
+ simple-audio-card,name = "Analog";
+ simple-audio-card,aux-devs = <&speaker_amp>, <&headphone_amp>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,hp-det-gpio = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>;
+ simple-audio-card,bitclock-master = <&daicpu>;
+ simple-audio-card,frame-master = <&daicpu>;
+ /* SARADC_IN3 is used as MIC detection / key input */
+
+ simple-audio-card,widgets =
+ "Microphone", "Onboard Microphone",
+ "Microphone", "Microphone Jack",
+ "Speaker", "Speaker",
+ "Headphone", "Headphones";
+
+ simple-audio-card,routing =
+ "Headphones", "LOUT1",
+ "Headphones", "ROUT1",
+ "Speaker", "LOUT2",
+ "Speaker", "ROUT2",
+
+ "Headphones", "Headphones Amp OUTL",
+ "Headphones", "Headphones Amp OUTR",
+ "Headphones Amp INL", "LOUT1",
+ "Headphones Amp INR", "ROUT1",
+
+ "Speaker", "Speaker Amp OUTL",
+ "Speaker", "Speaker Amp OUTR",
+ "Speaker Amp INL", "LOUT2",
+ "Speaker Amp INR", "ROUT2",
+
+ /* single ended signal to LINPUT1 */
+ "LINPUT1", "Microphone Jack",
+ "RINPUT1", "Microphone Jack",
+ /* differential signal */
+ "LINPUT2", "Onboard Microphone",
+ "RINPUT2", "Onboard Microphone";
+
+ daicpu: simple-audio-card,cpu {
+ sound-dai = <&i2s0_8ch>;
+ system-clock-frequency = <12288000>;
+ };
+
+ daicodec: simple-audio-card,codec {
+ sound-dai = <&es8388>;
+ system-clock-frequency = <12288000>;
+ };
+ };
+
+ vcc12v_dcin: vcc12v-dcin-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc12v_dcin";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ vcc3v3_bt: vcc3v3-bt-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_bt";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc_3v3_s0>;
+ };
+
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ vcc3v3_wf: vcc3v3-wf-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_wf";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc_3v3_s0>;
+ };
+
+ vcc4v0_sys: vcc4v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc4v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <4000000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host_en>;
+ regulator-name = "vcc5v0_host";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
+ vcc5v0_usb: vcc5v0-usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_usb";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gmac0 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy>;
+ phy-mode = "rgmii-rxid";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_tx_bus2
+ &gmac0_rx_bus2
+ &gmac0_rgmii_clk
+ &gmac0_rgmii_bus>;
+ rx_delay = <0x00>;
+ tx_delay = <0x43>;
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PD4 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ wakeup-source;
+ };
+};
+
+&i2c7 {
+ status = "okay";
+
+ es8388: audio-codec@11 {
+ compatible = "everest,es8388";
+ reg = <0x11>;
+ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+ assigned-clock-rates = <12288000>;
+ clocks = <&cru I2S0_8CH_MCLKOUT>;
+ clock-names = "mclk";
+ AVDD-supply = <&avcc_1v8_codec_s0>;
+ DVDD-supply = <&avcc_1v8_codec_s0>;
+ HPVDD-supply = <&vcc_3v3_s0>;
+ PVDD-supply = <&vcc_3v3_s0>;
+ #sound-dai-cells = <0>;
+ };
+};
+
+&i2s0_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_lrck
+ &i2s0_mclk
+ &i2s0_sclk
+ &i2s0_sdi0
+ &i2s0_sdo0>;
+ status = "okay";
+};
+
+&mdio0 {
+ rgmii_phy: ethernet-phy@1 {
+ /* RTL8211F */
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0x1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtl8211f_rst>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pinctrl {
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ leds {
+ led_pins: led-pins {
+ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ rtl8111 {
+ rtl8111_isolate: rtl8111-isolate {
+ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ rtl8211f {
+ rtl8211f_rst: rtl8211f-rst {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ };
+
+ sound {
+ hp_detect: hp-detect {
+ rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+/* WIFI */
+&pcie2x1l0 {
+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_wf>;
+ status = "okay";
+};
+
+/* GMAC1 */
+&pcie2x1l1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtl8111_isolate>;
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8_s0>;
+ status = "okay";
+};
+
+&sata0 {
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ max-frequency = <150000000>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-sdio;
+ no-mmc;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&spi2 {
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <2>;
+ status = "okay";
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+ pinctrl-names = "default";
+ spi-max-frequency = <1000000>;
+
+ vcc1-supply = <&vcc4v0_sys>;
+ vcc2-supply = <&vcc4v0_sys>;
+ vcc3-supply = <&vcc4v0_sys>;
+ vcc4-supply = <&vcc4v0_sys>;
+ vcc5-supply = <&vcc4v0_sys>;
+ vcc6-supply = <&vcc4v0_sys>;
+ vcc7-supply = <&vcc4v0_sys>;
+ vcc8-supply = <&vcc4v0_sys>;
+ vcc9-supply = <&vcc4v0_sys>;
+ vcc10-supply = <&vcc4v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc4v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc4v0_sys>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: dcdc-reg1 {
+ regulator-name = "vdd_gpu_s0";
+ regulator-boot-on;
+ regulator-enable-ramp-delay = <400>;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_npu_s0: dcdc-reg2 {
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-name = "vdd_log_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: dcdc-reg4 {
+ regulator-name = "vdd_vdenc_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+
+ };
+
+ vdd_gpu_mem_s0: dcdc-reg5 {
+ regulator-name = "vdd_gpu_mem_s0";
+ regulator-boot-on;
+ regulator-enable-ramp-delay = <400>;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+
+ };
+
+ vdd_npu_mem_s0: dcdc-reg6 {
+ regulator-name = "vdd_npu_mem_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-name = "vdd_2v0_pldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vdd_vdenc_mem_s0: dcdc-reg8 {
+ regulator-name = "vdd_vdenc_mem_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg9 {
+ regulator-name = "vdd2_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_1v1_nldo_s3: dcdc-reg10 {
+ regulator-name = "vcc_1v1_nldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1100000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-name = "avcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd1_1v8_ddr_s3: pldo-reg2 {
+ regulator-name = "vdd1_1v8_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_codec_s0: pldo-reg3 {
+ regulator-name = "avcc_1v8_codec_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s3: pldo-reg4 {
+ regulator-name = "vcc_3v3_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-name = "vccio_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: pldo-reg6 {
+ regulator-name = "vcc_1v8_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-name = "vdd_0v75_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ /* reserved for LPDDR5, unused? */
+ vdd2l_0v9_ddr_s3: nldo-reg2 {
+ regulator-name = "vdd2l_0v9_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vdd_0v75_hdmi_edp_s0: nldo-reg3 {
+ regulator-name = "vdd_0v75_hdmi_edp_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg4 {
+ regulator-name = "avdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg5 {
+ regulator-name = "vdd_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+
+ pmic@1 {
+ compatible = "rockchip,rk806";
+ reg = <0x01>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&rk806_slave_dvs1_null>, <&rk806_slave_dvs2_null>,
+ <&rk806_slave_dvs3_null>;
+ pinctrl-names = "default";
+ spi-max-frequency = <1000000>;
+
+ vcc1-supply = <&vcc4v0_sys>;
+ vcc2-supply = <&vcc4v0_sys>;
+ vcc3-supply = <&vcc4v0_sys>;
+ vcc4-supply = <&vcc4v0_sys>;
+ vcc5-supply = <&vcc4v0_sys>;
+ vcc6-supply = <&vcc4v0_sys>;
+ vcc7-supply = <&vcc4v0_sys>;
+ vcc8-supply = <&vcc4v0_sys>;
+ vcc9-supply = <&vcc4v0_sys>;
+ vcc10-supply = <&vcc4v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc4v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_2v0_pldo_s3>;
+ vcca-supply = <&vcc4v0_sys>;
+
+ rk806_slave_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
+ rk806_slave_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_slave_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_cpu_big1_s0: dcdc-reg1 {
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big0_s0: dcdc-reg2 {
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: dcdc-reg3 {
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: dcdc-reg4 {
+ regulator-name = "vcc_3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_mem_s0: dcdc-reg5 {
+ regulator-name = "vdd_cpu_big1_mem_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+
+ vdd_cpu_big0_mem_s0: dcdc-reg6 {
+ regulator-name = "vdd_cpu_big0_mem_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: dcdc-reg7 {
+ regulator-name = "vcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_mem_s0: dcdc-reg8 {
+ regulator-name = "vdd_cpu_lit_mem_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-name = "vddq_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg10 {
+ regulator-name = "vdd_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ /* reserved, unused? */
+ vcc_1v8_cam_s0: pldo-reg1 {
+ regulator-name = "vcc_1v8_cam_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ avdd1v8_ddr_pll_s0: pldo-reg2 {
+ regulator-name = "avdd1v8_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_1v8_pll_s0: pldo-reg3 {
+ regulator-name = "vdd_1v8_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ /* reserved, unused? */
+ vcc_3v3_sd_s0: pldo-reg4 {
+ regulator-name = "vcc_3v3_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ /* reserved, unused? */
+ vcc_2v8_cam_s0: pldo-reg5 {
+ regulator-name = "vcc_2v8_cam_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ /* unused */
+ pldo6_s3: pldo-reg6 {
+ regulator-name = "pldo6_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_pll_s0: nldo-reg1 {
+ regulator-name = "vdd_0v75_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-name = "vdd_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ avdd_0v85_s0: nldo-reg3 {
+ regulator-name = "avdd_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ /* reserved, unused */
+ avdd_1v2_cam_s0: nldo-reg4 {
+ regulator-name = "avdd_1v2_cam_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ avdd_1v2_s0: nldo-reg5 {
+ regulator-name = "avdd_1v2_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index 8ab60968f275..741f631db345 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -3,6 +3,7 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
#include "rk3588.dtsi"
/ {
@@ -12,6 +13,7 @@
aliases {
mmc0 = &sdhci;
mmc1 = &sdmmc;
+ mmc2 = &sdio;
serial2 = &uart2;
};
@@ -36,6 +38,19 @@
pinctrl-0 = <&hp_detect>;
};
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_rgb_b>;
+
+ led_rgb_b {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
fan: pwm-fan {
compatible = "pwm-fan";
cooling-levels = <0 95 145 195 255>;
@@ -44,6 +59,43 @@
#cooling-cells = <2>;
};
+ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_0_vcc3v3_en>;
+ regulator-name = "vcc3v3_pcie2x1l0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_vcc3v3_en>;
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
vcc5v0_host: vcc5v0-host-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_host";
@@ -78,6 +130,14 @@
};
};
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
&cpu_b0 {
cpu-supply = <&vdd_cpu_big0_s0>;
};
@@ -204,6 +264,34 @@
};
};
+&pcie2x1l0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_0_rst>;
+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
+ status = "okay";
+};
+
+&pcie2x1l2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_2_rst>;
+ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l2>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_rst>;
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
&pinctrl {
hym8563 {
hym8563_int: hym8563-int {
@@ -211,12 +299,42 @@
};
};
+ leds {
+ led_rgb_b: led-rgb-b {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
sound {
hp_detect: hp-detect {
rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+ pcie2 {
+ pcie2_0_rst: pcie2-0-rst {
+ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_0_vcc3v3_en: pcie2-0-vcc-en {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_2_rst: pcie2-2-rst {
+ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie3 {
+ pcie3_rst: pcie3-rst {
+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie3_vcc3v3_en: pcie3-vcc3v3-en {
+ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
usb {
vcc5v0_host_en: vcc5v0-host-en {
rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -258,6 +376,33 @@
status = "okay";
};
+&sdio {
+ max-frequency = <200000000>;
+ no-sd;
+ no-mmc;
+ non-removable;
+ bus-width = <4>;
+ cap-sdio-irq;
+ disable-wp;
+ keep-power-in-suspend;
+ wakeup-source;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_pcie2x1l0>;
+ vqmmc-supply = <&vcc_1v8_s3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdiom0_pins>;
+ status = "okay";
+};
+
+&uart6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>;
+ status = "okay";
+};
+
&spi2 {
status = "okay";
assigned-clocks = <&cru CLK_SPI2>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dts b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dts
new file mode 100644
index 000000000000..7bcad28d73b8
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * This device tree covers the common case where the RK1 is used as a
+ * "compute node" system, where the carrier board is functioning more like a
+ * generic backplane (with no non-autoenumerable peripherals of its own) than
+ * like a device that the SoM is meant to enable.
+ *
+ * Copyright (c) 2023 Sam Edwards <CFSworks@gmail.com>
+ */
+
+/dts-v1/;
+#include "rk3588-turing-rk1.dtsi"
+
+/ {
+ model = "Turing Machines RK1";
+ compatible = "turing,rk1", "rockchip,rk3588";
+
+ chosen {
+ stdout-path = "serial9:115200n8";
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
new file mode 100644
index 000000000000..9570b34aca2e
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
@@ -0,0 +1,614 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device tree definitions for the Turing RK1 SoM.
+ *
+ * Copyright (c) 2023 Sam Edwards <CFSworks@gmail.com>
+ *
+ * Based on RK3588-EVB1 devicetree
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588.dtsi"
+
+/ {
+ compatible = "turing,rk1", "rockchip,rk3588";
+
+ aliases {
+ ethernet0 = &gmac1;
+ mmc0 = &sdhci;
+ serial2 = &uart2;
+ serial9 = &uart9;
+ };
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 25 95 145 195 255>;
+ fan-supply = <&vcc5v0_sys>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0m2_pins &fan_int>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>;
+ pwms = <&pwm0 0 50000 0>;
+ #cooling-cells = <2>;
+ };
+
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v3_pcie30_en>;
+ startup-delay-us = <5000>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v1_nldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gmac1 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy>;
+ phy-mode = "rgmii-rxid";
+ pinctrl-0 = <&gmac1_miim
+ &gmac1_tx_bus2
+ &gmac1_rx_bus2
+ &gmac1_rgmii_clk
+ &gmac1_rgmii_bus>;
+ pinctrl-names = "default";
+ rx_delay = <0x00>;
+ tx_delay = <0x43>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1m2_xfer>;
+ status = "okay";
+
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+ };
+};
+
+&mdio1 {
+ rgmii_phy: ethernet-phy@1 {
+ /* RTL8211F */
+ compatible = "ethernet-phy-id001c.c916",
+ "ethernet-phy-ieee802.3-c22";
+ reg = <0x1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtl8211f_rst>;
+ reset-assert-us = <15000>;
+ reset-deassert-us = <50000>;
+ reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pcie2x1l1 {
+ linux,pci-domain = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_reset>;
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ linux,pci-domain = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_reset>;
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
+&pinctrl {
+ fan {
+ fan_int: fan-int {
+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie2 {
+ pcie2_reset: pcie2-reset {
+ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie3 {
+ pcie3_reset: pcie3-reset {
+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc3v3_pcie30_en: pcie3-reg {
+ rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ rtl8211f {
+ rtl8211f_rst: rtl8211f-rst {
+ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm0 {
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ status = "okay";
+};
+
+&spi2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ num-cs = <1>;
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ spi-max-frequency = <1000000>;
+ reg = <0x0>;
+
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_cpu_lit_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_log_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_vdenc_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_2v0_pldo_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "avcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "avdd_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vcc_3v3_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "avdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&uart9 {
+ pinctrl-0 = <&uart9m0_xfer>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index d1503a4b233a..60f00ceb630e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -3,6 +3,7 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/usb/pd.h>
#include "rk3588s.dtsi"
@@ -11,6 +12,34 @@
model = "Indiedroid Nova";
compatible = "indiedroid,nova", "rockchip,rk3588s";
+ adc-keys-0 {
+ compatible = "adc-keys";
+ io-channel-names = "buttons";
+ io-channels = <&saradc 0>;
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-boot {
+ label = "boot";
+ linux,code = <KEY_PROG1>;
+ press-threshold-microvolt = <18000>;
+ };
+ };
+
+ adc-keys-1 {
+ compatible = "adc-keys";
+ io-channel-names = "buttons";
+ io-channels = <&saradc 1>;
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-recovery {
+ label = "recovery";
+ linux,code = <KEY_PROG2>;
+ press-threshold-microvolt = <18000>;
+ };
+ };
+
aliases {
mmc0 = &sdhci;
mmc1 = &sdmmc;
@@ -109,6 +138,10 @@
};
};
+&combphy0_ps {
+ status = "okay";
+};
+
&cpu_l0 {
cpu-supply = <&vdd_cpu_lit_s0>;
};
@@ -348,6 +381,12 @@
};
};
+&pcie2x1l2 {
+ pinctrl-0 = <&rtl8111_perstb>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
&pinctrl {
bluetooth-pins {
bt_reset: bt-reset {
@@ -366,6 +405,12 @@
};
};
+ ethernet-pins {
+ rtl8111_perstb: rtl8111-perstb {
+ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
hym8563 {
hym8563_int: hym8563-int {
@@ -394,6 +439,11 @@
};
};
+&saradc {
+ vref-supply = <&vcca_1v8_s0>;
+ status = "okay";
+};
+
/* HS400 modes seemed to cause io errors. */
&sdhci {
bus-width = <8>;
@@ -735,6 +785,24 @@
status = "okay";
};
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ phy-supply = <&vcc5v0_usb>;
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ phy-supply = <&vcc5v0_usb>;
+ status = "okay";
+};
+
&uart2 {
pinctrl-0 = <&uart2m0_xfer>;
status = "okay";
@@ -759,3 +827,19 @@
pinctrl-names = "default";
};
};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
new file mode 100644
index 000000000000..8f399c4317bd
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
@@ -0,0 +1,662 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588s.dtsi"
+
+/ {
+ model = "Xunlong Orange Pi 5";
+ compatible = "xunlong,orangepi-5", "rockchip,rk3588s";
+
+ aliases {
+ mmc0 = &sdmmc;
+ serial2 = &uart2;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <1800>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 =<&leds_gpio>;
+
+ led-1 {
+ gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>;
+ label = "status_led";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ vbus_typec: vbus-typec-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&typec5v_pwren>;
+ regulator-name = "vbus_typec";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-low;
+ gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_LOW>;
+ regulator-name = "vcc_3v3_sd_s0";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc3v3_pcie20: vcc3v3-pcie20-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_pcie20";
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gmac1 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-rxid";
+ pinctrl-0 = <&gmac1_miim
+ &gmac1_tx_bus2
+ &gmac1_rx_bus2
+ &gmac1_rgmii_clk
+ &gmac1_rgmii_bus>;
+ pinctrl-names = "default";
+ tx_delay = <0x42>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6m3_xfer>;
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+ };
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pcie2x1l2 {
+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie20>;
+ status = "okay";
+};
+
+&pinctrl {
+ gpio-func {
+ leds_gpio: leds-gpio {
+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb-typec {
+ usbc0_int: usbc0-int {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ typec5v_pwren: typec5v-pwren {
+ rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&avcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-mmc;
+ no-sdio;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_sd_s0>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&sfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspim0_pins>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-max-frequency = <100000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+ spi-max-frequency = <1000000>;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: dcdc-reg1 {
+ regulator-name = "vdd_gpu_s0";
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: dcdc-reg2 {
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-name = "vdd_log_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: dcdc-reg4 {
+ regulator-name = "vdd_vdenc_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-name = "vdd_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vcc_1v1_nldo_s3: vdd2_ddr_s3: dcdc-reg6 {
+ regulator-name = "vdd2_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1100000>;
+ regulator-min-microvolt = <1100000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-name = "vdd_2v0_pldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-name = "vcc_3v3_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-name = "vddq_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-name = "vcc_1v8_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-name = "avcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-name = "vcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-name = "avdd_1v2_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-name = "vcc_3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-name = "vccio_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-name = "pldo6_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-name = "vdd_0v75_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-name = "vdd_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-name = "avdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-name = "vdd_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-name = "vdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
index 48181671eacb..63151d9d2377 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
@@ -1350,6 +1350,41 @@
i2s2 {
/omit-if-no-ref/
+ i2s2m0_lrck: i2s2m0-lrck {
+ rockchip,pins =
+ /* i2s2m0_lrck */
+ <2 RK_PC0 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ i2s2m0_mclk: i2s2m0-mclk {
+ rockchip,pins =
+ /* i2s2m0_mclk */
+ <2 RK_PB6 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ i2s2m0_sclk: i2s2m0-sclk {
+ rockchip,pins =
+ /* i2s2m0_sclk */
+ <2 RK_PB7 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ i2s2m0_sdi: i2s2m0-sdi {
+ rockchip,pins =
+ /* i2s2m0_sdi */
+ <2 RK_PC3 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ i2s2m0_sdo: i2s2m0-sdo {
+ rockchip,pins =
+ /* i2s2m0_sdo */
+ <4 RK_PC3 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
i2s2m1_lrck: i2s2m1-lrck {
rockchip,pins =
/* i2s2m1_lrck */
@@ -3308,6 +3343,15 @@
uart9 {
/omit-if-no-ref/
+ uart9m0_xfer: uart9m0-xfer {
+ rockchip,pins =
+ /* uart9_rx_m0 */
+ <2 RK_PC4 10 &pcfg_pull_up>,
+ /* uart9_tx_m0 */
+ <2 RK_PC2 10 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
uart9m1_xfer: uart9m1-xfer {
rockchip,pins =
/* uart9_rx_m1 */
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 5544f66c6ff4..2993e1255042 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -443,6 +443,11 @@
status = "disabled";
};
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
+ };
+
sys_grf: syscon@fd58c000 {
compatible = "rockchip,rk3588-sys-grf", "syscon";
reg = <0x0 0xfd58c000 0x0 0x1000>;
@@ -1329,6 +1334,17 @@
};
};
+ dfi: dfi@fe060000 {
+ reg = <0x00 0xfe060000 0x00 0x10000>;
+ compatible = "rockchip,rk3588-dfi";
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "ch0", "ch1", "ch2", "ch3";
+ rockchip,pmu = <&pmu1grf>;
+ };
+
gmac1: ethernet@fe1c0000 {
compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
reg = <0x0 0xfe1c0000 0x0 0x10000>;
@@ -1424,6 +1440,17 @@
};
};
+ sfc: spi@fe2b0000 {
+ compatible = "rockchip,sfc";
+ reg = <0x0 0xfe2b0000 0x0 0x4000>;
+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+ clock-names = "clk_sfc", "hclk_sfc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
sdmmc: mmc@fe2c0000 {
compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe2c0000 0x0 0x4000>;
@@ -2304,6 +2331,19 @@
#interrupt-cells = <2>;
};
};
+
+ av1d: video-codec@fdc70000 {
+ compatible = "rockchip,rk3588-av1-vpu";
+ reg = <0x0 0xfdc70000 0x0 0x800>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "vdpu";
+ assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+ assigned-clock-rates = <400000000>, <400000000>;
+ clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+ clock-names = "aclk", "hclk";
+ power-domains = <&power RK3588_PD_AV1>;
+ resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
+ };
};
#include "rk3588s-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
index 7bb36b071475..4680571c264d 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
@@ -52,6 +52,8 @@
l2: l2-cache {
compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
};
};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
index 4e2171630272..335093da6573 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
@@ -86,10 +86,14 @@
a72_l2: l2-cache0 {
compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
};
a53_l2: l2-cache1 {
compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
};
};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi
index 38ccfb46ea42..d6e3cc6fdb25 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi
@@ -83,6 +83,8 @@
l2: l2-cache {
compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
};
};
diff --git a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
index d34a1d5e79c0..66791a974f8f 100644
--- a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
@@ -6,6 +6,60 @@
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
&pinctrl {
+ sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
+ <STM32_PINMUX('E', 5, AF10)>, /* SDMMC1_D1 */
+ <STM32_PINMUX('E', 0, AF10)>, /* SDMMC1_D2 */
+ <STM32_PINMUX('E', 1, AF10)>, /* SDMMC1_D3 */
+ <STM32_PINMUX('E', 2, AF10)>; /* SDMMC1_CMD */
+ slew-rate = <2>;
+ drive-push-pull;
+ bias-disable;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC1_CK */
+ slew-rate = <3>;
+ drive-push-pull;
+ bias-disable;
+ };
+ };
+
+ sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
+ <STM32_PINMUX('E', 5, AF10)>, /* SDMMC1_D1 */
+ <STM32_PINMUX('E', 0, AF10)>, /* SDMMC1_D2 */
+ <STM32_PINMUX('E', 1, AF10)>; /* SDMMC1_D3 */
+ slew-rate = <2>;
+ drive-push-pull;
+ bias-disable;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC1_CK */
+ slew-rate = <3>;
+ drive-push-pull;
+ bias-disable;
+ };
+ pins3 {
+ pinmux = <STM32_PINMUX('E', 2, AF10)>; /* SDMMC1_CMD */
+ slew-rate = <2>;
+ drive-open-drain;
+ bias-disable;
+ };
+ };
+
+ sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('E', 4, ANALOG)>, /* SDMMC1_D0 */
+ <STM32_PINMUX('E', 5, ANALOG)>, /* SDMMC1_D1 */
+ <STM32_PINMUX('E', 0, ANALOG)>, /* SDMMC1_D2 */
+ <STM32_PINMUX('E', 1, ANALOG)>, /* SDMMC1_D3 */
+ <STM32_PINMUX('E', 3, ANALOG)>, /* SDMMC1_CK */
+ <STM32_PINMUX('E', 2, ANALOG)>; /* SDMMC1_CMD */
+ };
+ };
+
usart2_pins_a: usart2-0 {
pins1 {
pinmux = <STM32_PINMUX('A', 4, AF6)>; /* USART2_TX */
diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 5268a4321841..124403f5f1f4 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -28,6 +28,12 @@
interrupt-parent = <&intc>;
};
+ arm_wdt: watchdog {
+ compatible = "arm,smc-wdt";
+ arm,smc-id = <0xb200005a>;
+ status = "disabled";
+ };
+
clocks {
ck_flexgen_08: ck-flexgen-08 {
#clock-cells = <0>;
@@ -119,6 +125,19 @@
clocks = <&ck_flexgen_08>;
status = "disabled";
};
+
+ sdmmc1: mmc@48220000 {
+ compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00353180>;
+ reg = <0x48220000 0x400>, <0x44230400 0x8>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ck_flexgen_51>;
+ clock-names = "apb_pclk";
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <120000000>;
+ status = "disabled";
+ };
};
syscfg: syscon@44230000 {
diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index 39b4726cc098..b2d3afb15758 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -6,6 +6,7 @@
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
#include "stm32mp257.dtsi"
#include "stm32mp25xf.dtsi"
#include "stm32mp25-pinctrl.dtsi"
@@ -39,6 +40,32 @@
no-map;
};
};
+
+ vdd_sdcard: vdd-sdcard {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_sdcard";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+};
+
+&arm_wdt {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&sdmmc1 {
+ pinctrl-names = "default", "opendrain", "sleep";
+ pinctrl-0 = <&sdmmc1_b4_pins_a>;
+ pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
+ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
+ cd-gpios = <&gpiod 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ disable-wp;
+ st,neg-edge;
+ bus-width = <4>;
+ vmmc-supply = <&vdd_sdcard>;
+ status = "okay";
};
&usart2 {
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index e7b8e2e7f083..77a347f9f47d 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -9,6 +9,8 @@
# alphabetically.
# Boards with AM62x SoC
+k3-am625-sk-hdmi-audio-dtbs := k3-am625-sk.dtb k3-am62x-sk-hdmi-audio.dtbo
+k3-am62-lp-sk-hdmi-audio-dtbs := k3-am62-lp-sk.dtb k3-am62x-sk-hdmi-audio.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am625-beagleplay.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am625-phyboard-lyra-rdk.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am625-sk.dtb
@@ -19,7 +21,8 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dahlia.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
-dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-hdmi-audio.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am625-sk-hdmi-audio.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk-hdmi-audio.dtb
# Boards with AM62Ax SoC
dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
@@ -43,6 +46,8 @@ dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl-wlan.dtb
# Boards with AM65x SoC
k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
+k3-am654-evm-dtbs := k3-am654-base-board.dtb k3-am654-icssg2.dtbo
+k3-am654-idk-dtbs := k3-am654-evm.dtb k3-am654-idk.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic-pg2.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced.dtb
@@ -50,6 +55,8 @@ dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-m2.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-pg2.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am654-gp-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am654-idk.dtb
# Boards with J7200 SoC
k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
@@ -66,6 +73,8 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-common-proc-board.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-gesi-exp-board.dtbo
+k3-j721s2-evm-dtbs := k3-j721s2-common-proc-board.dtb k3-j721s2-evm-gesi-exp-board.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm.dtb
# Boards with J784s4 SoC
dtb-$(CONFIG_ARCH_K3) += k3-am69-sk.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 284b90c94da8..e5c64c86d1d5 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -81,7 +81,8 @@
};
dmss: bus@48000000 {
- compatible = "simple-mfd";
+ bootph-all;
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
dma-ranges;
@@ -90,6 +91,7 @@
ti,sci-dev-id = <25>;
secure_proxy_main: mailbox@4d000000 {
+ bootph-all;
compatible = "ti,am654-secure-proxy";
#mbox-cells = <1>;
reg-names = "target_data", "rt", "scfg";
@@ -165,6 +167,7 @@
};
dmsc: system-controller@44043000 {
+ bootph-all;
compatible = "ti,k2g-sci";
ti,host-id = <12>;
mbox-names = "rx", "tx";
@@ -174,16 +177,19 @@
reg = <0x00 0x44043000 0x00 0xfe0>;
k3_pds: power-controller {
+ bootph-all;
compatible = "ti,sci-pm-domain";
#power-domain-cells = <2>;
};
k3_clks: clock-controller {
+ bootph-all;
compatible = "ti,k2g-sci-clk";
#clock-cells = <2>;
};
k3_reset: reset-controller {
+ bootph-all;
compatible = "ti,sci-reset";
#reset-cells = <2>;
};
@@ -202,6 +208,7 @@
};
secure_proxy_sa3: mailbox@43600000 {
+ bootph-pre-ram;
compatible = "ti,am654-secure-proxy";
#mbox-cells = <1>;
reg-names = "target_data", "rt", "scfg";
@@ -217,6 +224,7 @@
};
main_pmx0: pinctrl@f4000 {
+ bootph-all;
compatible = "pinctrl-single";
reg = <0x00 0xf4000 0x00 0x2ac>;
#pinctrl-cells = <1>;
@@ -225,12 +233,14 @@
};
main_esm: esm@420000 {
+ bootph-pre-ram;
compatible = "ti,j721e-esm";
reg = <0x00 0x420000 0x00 0x1000>;
ti,esm-pins = <160>, <161>, <162>, <163>, <177>, <178>;
};
main_timer0: timer@2400000 {
+ bootph-all;
compatible = "ti,am654-timer";
reg = <0x00 0x2400000 0x00 0x400>;
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
index 80a3e1db26a9..0e0b234581c6 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
@@ -7,6 +7,7 @@
&cbass_mcu {
mcu_pmx0: pinctrl@4084000 {
+ bootph-all;
compatible = "pinctrl-single";
reg = <0x00 0x04084000 0x00 0x88>;
#pinctrl-cells = <1>;
@@ -15,6 +16,7 @@
};
mcu_esm: esm@4100000 {
+ bootph-pre-ram;
compatible = "ti,j721e-esm";
reg = <0x00 0x4100000 0x00 0x1000>;
ti,esm-pins = <0>, <1>, <2>, <85>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
index 90ddc71bcd30..a6808b10c7b2 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
@@ -35,5 +35,11 @@
&main_uart5 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart5>;
+ uart-has-rtscts;
status = "okay";
+
+ bluetooth {
+ compatible = "nxp,88w8987-bt";
+ fw-init-baudrate = <3000000>;
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
index 40992e7e4c30..5db52f237253 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -1061,6 +1061,7 @@
vddc-supply = <&reg_1v2_dsi>;
vddmipi-supply = <&reg_1v2_dsi>;
vddio-supply = <&reg_1v8_dsi>;
+ status = "disabled";
dsi_bridge_ports: ports {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
index eae052887186..fef76f52a52e 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -7,6 +7,7 @@
&cbass_wakeup {
wkup_conf: syscon@43000000 {
+ bootph-all;
compatible = "syscon", "simple-mfd";
reg = <0x00 0x43000000 0x00 0x20000>;
#address-cells = <1>;
@@ -14,6 +15,7 @@
ranges = <0x0 0x00 0x43000000 0x20000>;
chipid: chipid@14 {
+ bootph-all;
compatible = "ti,am654-chipid";
reg = <0x14 0x4>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62.dtsi b/arch/arm64/boot/dts/ti/k3-am62.dtsi
index 11f14eef2d44..f1e15206e1ce 100644
--- a/arch/arm64/boot/dts/ti/k3-am62.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62.dtsi
@@ -47,6 +47,7 @@
};
cbass_main: bus@f0000 {
+ bootph-all;
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
@@ -86,6 +87,7 @@
<0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>;
cbass_mcu: bus@4000000 {
+ bootph-all;
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
@@ -93,6 +95,7 @@
};
cbass_wakeup: bus@b00000 {
+ bootph-all;
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
index 7cfdf562b53b..00891a0f8fc3 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -46,6 +46,7 @@
};
memory@80000000 {
+ bootph-pre-ram;
device_type = "memory";
/* 2G RAM */
reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
@@ -58,7 +59,7 @@
ramoops: ramoops@9ca00000 {
compatible = "ramoops";
- reg = <0x00 0x9c700000 0x00 0x00100000>;
+ reg = <0x00 0x9ca00000 0x00 0x00100000>;
record-size = <0x8000>;
console-size = <0x8000>;
ftrace-size = <0x00>;
@@ -83,6 +84,7 @@
};
vsys_5v0: regulator-1 {
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vsys_5v0";
regulator-min-microvolt = <5000000>;
@@ -93,6 +95,7 @@
vdd_3v3: regulator-2 {
/* output of TLV62595DMQR-U12 */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vdd_3v3";
regulator-min-microvolt = <3300000>;
@@ -118,6 +121,7 @@
vdd_3v3_sd: regulator-4 {
/* output of TPS22918DBVR-U21 */
+ bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&vdd_3v3_sd_pins_default>;
@@ -132,6 +136,7 @@
};
vdd_sd_dv: regulator-5 {
+ bootph-all;
compatible = "regulator-gpio";
regulator-name = "sd_hs200_switch";
pinctrl-names = "default";
@@ -146,9 +151,11 @@
};
leds {
+ bootph-all;
compatible = "gpio-leds";
led-0 {
+ bootph-all;
gpios = <&main_gpio0 3 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
function = LED_FUNCTION_HEARTBEAT;
@@ -156,6 +163,7 @@
};
led-1 {
+ bootph-all;
gpios = <&main_gpio0 4 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "disk-activity";
function = LED_FUNCTION_DISK_ACTIVITY;
@@ -163,16 +171,19 @@
};
led-2 {
+ bootph-all;
gpios = <&main_gpio0 5 GPIO_ACTIVE_HIGH>;
function = LED_FUNCTION_CPU;
};
led-3 {
+ bootph-all;
gpios = <&main_gpio0 6 GPIO_ACTIVE_HIGH>;
function = LED_FUNCTION_LAN;
};
led-4 {
+ bootph-all;
gpios = <&main_gpio0 9 GPIO_ACTIVE_HIGH>;
function = LED_FUNCTION_WLAN;
};
@@ -245,6 +256,7 @@
&main_pmx0 {
gpio0_pins_default: gpio0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x0004, PIN_INPUT, 7) /* (G25) OSPI0_LBCLKO.GPIO0_1 */
AM62X_IOPAD(0x0008, PIN_INPUT, 7) /* (J24) OSPI0_DQS.GPIO0_2 */
@@ -264,6 +276,7 @@
};
vdd_sd_dv_pins_default: vdd-sd-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x0244, PIN_OUTPUT, 7) /* (C17) MMC1_SDWP.GPIO1_49 */
>;
@@ -283,6 +296,7 @@
};
local_i2c_pins_default: local-i2c-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (B16) I2C0_SCL */
AM62X_IOPAD(0x01e4, PIN_INPUT_PULLUP, 0) /* (A16) I2C0_SDA */
@@ -321,6 +335,7 @@
};
emmc_pins_default: emmc-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x0220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
AM62X_IOPAD(0x0218, PIN_INPUT, 0) /* (AB1) MMC0_CLK */
@@ -336,12 +351,14 @@
};
vdd_3v3_sd_pins_default: vdd-3v3-sd-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x01c4, PIN_INPUT, 7) /* (B14) SPI0_D1_GPIO1_19 */
>;
};
sd_pins_default: sd-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x023c, PIN_INPUT, 0) /* (A21) MMC1_CMD */
AM62X_IOPAD(0x0234, PIN_INPUT, 0) /* (B22) MMC1_CLK */
@@ -418,6 +435,7 @@
};
mikrobus_gpio_pins_default: mikrobus-gpio-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x019c, PIN_INPUT, 7) /* (B18) MCASP0_AXR1.GPIO1_9 */
AM62X_IOPAD(0x01a0, PIN_INPUT, 7) /* (E18) MCASP0_AXR0.GPIO1_10 */
@@ -426,6 +444,7 @@
};
console_pins_default: console-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x01c8, PIN_INPUT, 0) /* (D14) UART0_RXD */
AM62X_IOPAD(0x01cc, PIN_OUTPUT, 0) /* (E14) UART0_TXD */
@@ -597,6 +616,7 @@
};
&main_gpio0 {
+ bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&gpio0_pins_default>;
gpio-line-names = "BL_EN_3V3", "SPE_PO_EN", "RTC_INT", /* 0-2 */
@@ -616,6 +636,7 @@
};
&main_gpio1 {
+ bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&mikrobus_gpio_pins_default>;
gpio-line-names = "", "", "", "", "", /* 0-4 */
@@ -633,6 +654,7 @@
};
&main_i2c0 {
+ bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&local_i2c_pins_default>;
clock-frequency = <400000>;
@@ -651,6 +673,7 @@
};
tps65219: pmic@30 {
+ bootph-all;
compatible = "ti,tps65219";
reg = <0x30>;
buck1-supply = <&vsys_5v0>;
@@ -801,6 +824,7 @@
};
&sdhci0 {
+ bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&emmc_pins_default>;
ti,driver-strength-ohm = <50>;
@@ -810,6 +834,7 @@
&sdhci1 {
/* SD/MMC */
+ bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&sd_pins_default>;
@@ -850,6 +875,7 @@
};
&main_uart0 {
+ bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&console_pins_default>;
status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am625-sk.dts b/arch/arm64/boot/dts/ti/k3-am625-sk.dts
index 7c98c1b855d1..b18092497c9a 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk.dts
@@ -31,6 +31,7 @@
vmain_pd: regulator-0 {
/* TPS65988 PD CONTROLLER OUTPUT */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vmain_pd";
regulator-min-microvolt = <5000000>;
@@ -41,6 +42,7 @@
vcc_5v0: regulator-1 {
/* Output of LM34936 */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vcc_5v0";
regulator-min-microvolt = <5000000>;
@@ -52,6 +54,7 @@
vcc_3v3_sys: regulator-2 {
/* output of LM61460-Q1 */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vcc_3v3_sys";
regulator-min-microvolt = <3300000>;
@@ -63,6 +66,7 @@
vdd_mmc1: regulator-3 {
/* TPS22918DBVR */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vdd_mmc1";
regulator-min-microvolt = <3300000>;
@@ -75,6 +79,7 @@
vdd_sd_dv: regulator-4 {
/* Output of TLV71033 */
+ bootph-all;
compatible = "regulator-gpio";
regulator-name = "tlv71033";
pinctrl-names = "default";
@@ -102,6 +107,7 @@
&main_pmx0 {
main_rgmii2_pins_default: main-rgmii2-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x184, PIN_INPUT, 0) /* (AE23) RGMII2_RD0 */
AM62X_IOPAD(0x188, PIN_INPUT, 0) /* (AB20) RGMII2_RD1 */
@@ -119,6 +125,7 @@
};
ospi0_pins_default: ospi0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x000, PIN_OUTPUT, 0) /* (H24) OSPI0_CLK */
AM62X_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F23) OSPI0_CSn0 */
@@ -135,20 +142,32 @@
};
vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x07c, PIN_OUTPUT, 7) /* (P25) GPMC0_CLK.GPIO0_31 */
>;
};
main_gpio1_ioexp_intr_pins_default: main-gpio1-ioexp-intr-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x01d4, PIN_INPUT, 7) /* (B15) UART0_RTSn.GPIO1_23 */
>;
};
};
+&main_gpio0 {
+ bootph-all;
+};
+
+&main_gpio1 {
+ bootph-all;
+};
+
&main_i2c1 {
+ bootph-all;
exp1: gpio@22 {
+ bootph-all;
compatible = "ti,tca6424";
reg = <0x22>;
gpio-controller;
@@ -207,12 +226,18 @@
};
};
+&fss {
+ bootph-all;
+};
+
&ospi0 {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&ospi0_pins_default>;
flash@0 {
+ bootph-all;
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <8>;
@@ -225,6 +250,7 @@
cdns,read-delay = <4>;
partitions {
+ bootph-all;
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
@@ -260,6 +286,7 @@
};
partition@3fc0000 {
+ bootph-pre-ram;
label = "ospi.phypattern";
reg = <0x3fc0000 0x40000>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 3198af08fb9f..4ae7fdc5221b 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -816,4 +816,64 @@
clock-names = "fck";
status = "disabled";
};
+
+ mcasp0: audio-controller@2b00000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b00000 0x00 0x2000>,
+ <0x00 0x02b08000 0x00 0x400>;
+ reg-names = "mpu", "dat";
+ interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+
+ dmas = <&main_bcdma 0 0xc500 0>, <&main_bcdma 0 0x4500 0>;
+ dma-names = "tx", "rx";
+
+ clocks = <&k3_clks 190 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 190 0>;
+ assigned-clock-parents = <&k3_clks 190 2>;
+ power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp1: audio-controller@2b10000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b10000 0x00 0x2000>,
+ <0x00 0x02b18000 0x00 0x400>;
+ reg-names = "mpu", "dat";
+ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+
+ dmas = <&main_bcdma 0 0xc501 0>, <&main_bcdma 0 0x4501 0>;
+ dma-names = "tx", "rx";
+
+ clocks = <&k3_clks 191 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 191 0>;
+ assigned-clock-parents = <&k3_clks 191 2>;
+ power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp2: audio-controller@2b20000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b20000 0x00 0x2000>,
+ <0x00 0x02b28000 0x00 0x400>;
+ reg-names = "mpu", "dat";
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+
+ dmas = <&main_bcdma 0 0xc502 0>, <&main_bcdma 0 0x4502 0>;
+ dma-names = "tx", "rx";
+
+ clocks = <&k3_clks 192 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 192 0>;
+ assigned-clock-parents = <&k3_clks 192 2>;
+ power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index cff283c75f8e..8f64ac2c7568 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -79,10 +79,10 @@
regulator-boot-on;
};
- vcc_3v3_sys: regulator-2 {
+ vcc_3v3_main: regulator-2 {
/* output of LM5141-Q1 */
compatible = "regulator-fixed";
- regulator-name = "vcc_3v3_sys";
+ regulator-name = "vcc_3v3_main";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vmain_pd>;
@@ -101,6 +101,17 @@
gpio = <&exp1 3 GPIO_ACTIVE_HIGH>;
};
+ vcc_3v3_sys: regulator-4 {
+ /* output of TPS222965DSGT */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_sys";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_main>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -114,6 +125,41 @@
default-state = "off";
};
};
+
+ tlv320_mclk: clk-0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12288000>;
+ };
+
+ codec_audio: sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "AM62Ax-SKEVM";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Line", "Line In",
+ "Microphone", "Microphone Jack";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "LINE1L", "Line In",
+ "LINE1R", "Line In",
+ "MIC3R", "Microphone Jack",
+ "Microphone Jack", "Mic Bias";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&sound_master>;
+ simple-audio-card,frame-master = <&sound_master>;
+ simple-audio-card,bitclock-inversion;
+
+ simple-audio-card,cpu {
+ sound-dai = <&mcasp1>;
+ };
+
+ sound_master: simple-audio-card,codec {
+ sound-dai = <&tlv320aic3106>;
+ clocks = <&tlv320_mclk>;
+ };
+ };
};
&mcu_pmx0 {
@@ -219,6 +265,29 @@
AM62AX_IOPAD(0x12c, PIN_INPUT, 0) /* (W16) RGMII1_TX_CTL */
>;
};
+
+ main_mcasp1_pins_default: main-mcasp1-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x090, PIN_INPUT, 2) /* (L19) GPMC0_BE0n_CLE.MCASP1_ACLKX */
+ AM62AX_IOPAD(0x098, PIN_INPUT, 2) /* (R18) GPMC0_WAIT0.MCASP1_AFSX */
+ AM62AX_IOPAD(0x08c, PIN_OUTPUT, 2) /* (K19) GPMC0_WEn.MCASP1_AXR0 */
+ AM62AX_IOPAD(0x084, PIN_INPUT, 2) /* (L18) GPMC0_ADVn_ALE.MCASP1_AXR2 */
+ >;
+ };
+};
+
+&mcu_pmx0 {
+ status = "okay";
+
+ pmic_irq_pins_default: pmic-irq-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (E11) MCU_GPIO0_0 */
+ >;
+ };
+};
+
+&mcu_gpio0 {
+ status = "okay";
};
&main_i2c0 {
@@ -244,13 +313,94 @@
};
};
};
+
+ tps659312: pmic@48 {
+ compatible = "ti,tps6593-q1";
+ reg = <0x48>;
+ ti,primary-pmic;
+ system-power-controller;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_irq_pins_default>;
+ interrupt-parent = <&mcu_gpio0>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+
+ buck123-supply = <&vcc_3v3_sys>;
+ buck4-supply = <&vcc_3v3_sys>;
+ buck5-supply = <&vcc_3v3_sys>;
+ ldo1-supply = <&vcc_3v3_sys>;
+ ldo2-supply = <&vcc_3v3_sys>;
+ ldo3-supply = <&buck5>;
+ ldo4-supply = <&vcc_3v3_sys>;
+
+ regulators {
+ buck123: buck123 {
+ regulator-name = "vcc_core";
+ regulator-min-microvolt = <715000>;
+ regulator-max-microvolt = <895000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck4: buck4 {
+ regulator-name = "vcc_1v1";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck5: buck5 {
+ regulator-name = "vcc_1v8_sys";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1: ldo1 {
+ regulator-name = "vddshv5_sdio";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2: ldo2 {
+ regulator-name = "vpp_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3: ldo3 {
+ regulator-name = "vcc_0v85";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4: ldo4 {
+ regulator-name = "vdda_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
};
&main_i2c1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_i2c1_pins_default>;
- clock-frequency = <400000>;
+ clock-frequency = <100000>;
exp1: gpio@22 {
compatible = "ti,tca6424";
@@ -271,6 +421,19 @@
"MCASP1_FET_SEL", "UART1_FET_SEL",
"PD_I2C_IRQ", "IO_EXP_TEST_LED";
};
+
+ tlv320aic3106: audio-codec@1b {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3106";
+ reg = <0x1b>;
+ ai3x-micbias-vg = <1>; /* 2.0V */
+
+ /* Regulators */
+ AVDD-supply = <&vcc_3v3_sys>;
+ IOVDD-supply = <&vcc_3v3_sys>;
+ DRVDD-supply = <&vcc_3v3_sys>;
+ DVDD-supply = <&buck5>;
+ };
};
&sdhci1 {
@@ -361,3 +524,23 @@
ti,min-output-impedance;
};
};
+
+&mcasp1 {
+ status = "okay";
+ #sound-dai-cells = <0>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcasp1_pins_default>;
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 1 0 2 0
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index c24ff905437f..963758c7d377 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -40,18 +40,37 @@
};
};
+ main_conf: bus@100000 {
+ compatible = "simple-bus";
+ reg = <0x00 0x00100000 0x00 0x20000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00 0x00 0x00100000 0x20000>;
+
+ phy_gmii_sel: phy@4044 {
+ compatible = "ti,am654-phy-gmii-sel";
+ reg = <0x4044 0x8>;
+ #phy-cells = <1>;
+ };
+
+ epwm_tbclk: clock-controller@4130 {
+ compatible = "ti,am62-epwm-tbclk";
+ reg = <0x4130 0x4>;
+ #clock-cells = <1>;
+ };
+ };
+
dmss: bus@48000000 {
- bootph-all;
- compatible = "simple-mfd";
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
dma-ranges;
ranges = <0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>;
+ bootph-all;
ti,sci-dev-id = <25>;
secure_proxy_main: mailbox@4d000000 {
- bootph-all;
compatible = "ti,am654-secure-proxy";
#mbox-cells = <1>;
reg-names = "target_data", "rt", "scfg";
@@ -60,11 +79,76 @@
<0x00 0x4a400000 0x00 0x80000>;
interrupt-names = "rx_012";
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ bootph-all;
+ };
+
+ inta_main_dmss: interrupt-controller@48000000 {
+ compatible = "ti,sci-inta";
+ reg = <0x00 0x48000000 0x00 0x100000>;
+ #interrupt-cells = <0>;
+ interrupt-controller;
+ interrupt-parent = <&gic500>;
+ msi-controller;
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <28>;
+ ti,interrupt-ranges = <5 69 35>;
+ ti,unmapped-event-sources = <&main_bcdma>, <&main_pktdma>;
+ };
+
+ main_bcdma: dma-controller@485c0100 {
+ compatible = "ti,am64-dmss-bcdma";
+ reg = <0x00 0x485c0100 0x00 0x100>,
+ <0x00 0x4c000000 0x00 0x20000>,
+ <0x00 0x4a820000 0x00 0x20000>,
+ <0x00 0x4aa40000 0x00 0x20000>,
+ <0x00 0x4bc00000 0x00 0x100000>;
+ reg-names = "gcfg", "bchanrt", "rchanrt", "tchanrt", "ringrt";
+ msi-parent = <&inta_main_dmss>;
+ #dma-cells = <3>;
+
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <26>;
+ ti,sci-rm-range-bchan = <0x20>; /* BLOCK_COPY_CHAN */
+ ti,sci-rm-range-rchan = <0x21>; /* SPLIT_TR_RX_CHAN */
+ ti,sci-rm-range-tchan = <0x22>; /* SPLIT_TR_TX_CHAN */
+ bootph-all;
+ };
+
+ main_pktdma: dma-controller@485c0000 {
+ compatible = "ti,am64-dmss-pktdma";
+ reg = <0x00 0x485c0000 0x00 0x100>,
+ <0x00 0x4a800000 0x00 0x20000>,
+ <0x00 0x4aa00000 0x00 0x40000>,
+ <0x00 0x4b800000 0x00 0x400000>;
+ reg-names = "gcfg", "rchanrt", "tchanrt", "ringrt";
+ msi-parent = <&inta_main_dmss>;
+ #dma-cells = <2>;
+ bootph-all;
+
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <30>;
+ ti,sci-rm-range-tchan = <0x23>, /* UNMAPPED_TX_CHAN */
+ <0x24>, /* CPSW_TX_CHAN */
+ <0x25>, /* SAUL_TX_0_CHAN */
+ <0x26>; /* SAUL_TX_1_CHAN */
+ ti,sci-rm-range-tflow = <0x10>, /* RING_UNMAPPED_TX_CHAN */
+ <0x11>, /* RING_CPSW_TX_CHAN */
+ <0x12>, /* RING_SAUL_TX_0_CHAN */
+ <0x13>; /* RING_SAUL_TX_1_CHAN */
+ ti,sci-rm-range-rchan = <0x29>, /* UNMAPPED_RX_CHAN */
+ <0x2b>, /* CPSW_RX_CHAN */
+ <0x2d>, /* SAUL_RX_0_CHAN */
+ <0x2f>, /* SAUL_RX_1_CHAN */
+ <0x31>, /* SAUL_RX_2_CHAN */
+ <0x33>; /* SAUL_RX_3_CHAN */
+ ti,sci-rm-range-rflow = <0x2a>, /* FLOW_UNMAPPED_RX_CHAN */
+ <0x2c>, /* FLOW_CPSW_RX_CHAN */
+ <0x2e>, /* FLOW_SAUL_RX_0/1_CHAN */
+ <0x32>; /* FLOW_SAUL_RX_2/3_CHAN */
};
};
dmsc: system-controller@44043000 {
- bootph-all;
compatible = "ti,k2g-sci";
ti,host-id = <12>;
mbox-names = "rx", "tx";
@@ -72,37 +156,72 @@
<&secure_proxy_main 13>;
reg-names = "debug_messages";
reg = <0x00 0x44043000 0x00 0xfe0>;
+ bootph-all;
k3_pds: power-controller {
- bootph-all;
compatible = "ti,sci-pm-domain";
#power-domain-cells = <2>;
+ bootph-all;
};
k3_clks: clock-controller {
- bootph-all;
compatible = "ti,k2g-sci-clk";
#clock-cells = <2>;
+ bootph-all;
};
k3_reset: reset-controller {
- bootph-all;
compatible = "ti,sci-reset";
#reset-cells = <2>;
+ bootph-all;
};
};
- main_pmx0: pinctrl@f4000 {
+ crypto: crypto@40900000 {
+ compatible = "ti,am62-sa3ul";
+ reg = <0x00 0x40900000 0x00 0x1200>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x00 0x40900000 0x00 0x40900000 0x00 0x30000>;
+
+ dmas = <&main_pktdma 0xf501 0>, <&main_pktdma 0x7506 0>,
+ <&main_pktdma 0x7507 0>;
+ dma-names = "tx", "rx1", "rx2";
+ };
+
+ secure_proxy_sa3: mailbox@43600000 {
+ compatible = "ti,am654-secure-proxy";
+ #mbox-cells = <1>;
+ reg-names = "target_data", "rt", "scfg";
+ reg = <0x00 0x43600000 0x00 0x10000>,
+ <0x00 0x44880000 0x00 0x20000>,
+ <0x00 0x44860000 0x00 0x20000>;
+ /*
+ * Marked Disabled:
+ * Node is incomplete as it is meant for bootloaders and
+ * firmware on non-MPU processors
+ */
+ status = "disabled";
bootph-all;
+ };
+
+ main_pmx0: pinctrl@f4000 {
compatible = "pinctrl-single";
reg = <0x00 0xf4000 0x00 0x2ac>;
#pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0xffffffff>;
+ bootph-all;
+ };
+
+ main_esm: esm@420000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x420000 0x00 0x1000>;
+ ti,esm-pins = <160>, <161>, <162>, <163>, <177>, <178>;
+ bootph-pre-ram;
};
main_timer0: timer@2400000 {
- bootph-all;
compatible = "ti,am654-timer";
reg = <0x00 0x2400000 0x00 0x400>;
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
@@ -112,6 +231,91 @@
assigned-clock-parents = <&k3_clks 36 3>;
power-domains = <&k3_pds 36 TI_SCI_PD_EXCLUSIVE>;
ti,timer-pwm;
+ bootph-all;
+ };
+
+ main_timer1: timer@2410000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2410000 0x00 0x400>;
+ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 37 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 37 2>;
+ assigned-clock-parents = <&k3_clks 37 3>;
+ power-domains = <&k3_pds 37 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer2: timer@2420000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2420000 0x00 0x400>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 38 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 38 2>;
+ assigned-clock-parents = <&k3_clks 38 3>;
+ power-domains = <&k3_pds 38 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer3: timer@2430000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2430000 0x00 0x400>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 39 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 39 2>;
+ assigned-clock-parents = <&k3_clks 39 3>;
+ power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer4: timer@2440000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2440000 0x00 0x400>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 40 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 40 2>;
+ assigned-clock-parents = <&k3_clks 40 3>;
+ power-domains = <&k3_pds 40 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer5: timer@2450000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2450000 0x00 0x400>;
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 41 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 41 2>;
+ assigned-clock-parents = <&k3_clks 41 3>;
+ power-domains = <&k3_pds 41 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer6: timer@2460000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2460000 0x00 0x400>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 42 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 42 2>;
+ assigned-clock-parents = <&k3_clks 42 3>;
+ power-domains = <&k3_pds 42 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ };
+
+ main_timer7: timer@2470000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x2470000 0x00 0x400>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 43 2>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 43 2>;
+ assigned-clock-parents = <&k3_clks 43 3>;
+ power-domains = <&k3_pds 43 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
};
main_uart0: serial@2800000 {
@@ -133,4 +337,548 @@
clock-names = "fclk";
status = "disabled";
};
+
+ main_uart2: serial@2820000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02820000 0x00 0x100>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 153 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart3: serial@2830000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02830000 0x00 0x100>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 154 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart4: serial@2840000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02840000 0x00 0x100>;
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 155 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 155 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart5: serial@2850000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02850000 0x00 0x100>;
+ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 156 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 156 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_uart6: serial@2860000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02860000 0x00 0x100>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 158 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 158 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ main_i2c0: i2c@20000000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20000000 0x00 0x100>;
+ interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 102 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 102 2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_i2c1: i2c@20010000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20010000 0x00 0x100>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 103 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 103 2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_i2c2: i2c@20020000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20020000 0x00 0x100>;
+ interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 104 2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_i2c3: i2c@20030000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20030000 0x00 0x100>;
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 105 2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_spi0: spi@20100000 {
+ compatible = "ti,am654-mcspi", "ti,omap4-mcspi";
+ reg = <0x00 0x20100000 0x00 0x400>;
+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 141 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 141 0>;
+ status = "disabled";
+ };
+
+ main_spi1: spi@20110000 {
+ compatible = "ti,am654-mcspi","ti,omap4-mcspi";
+ reg = <0x00 0x20110000 0x00 0x400>;
+ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 142 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 142 0>;
+ status = "disabled";
+ };
+
+ main_spi2: spi@20120000 {
+ compatible = "ti,am654-mcspi","ti,omap4-mcspi";
+ reg = <0x00 0x20120000 0x00 0x400>;
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 143 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 143 0>;
+ status = "disabled";
+ };
+
+ main_gpio_intr: interrupt-controller@a00000 {
+ compatible = "ti,sci-intr";
+ reg = <0x00 0x00a00000 0x00 0x800>;
+ ti,intr-trigger-type = <1>;
+ interrupt-controller;
+ interrupt-parent = <&gic500>;
+ #interrupt-cells = <1>;
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <3>;
+ ti,interrupt-ranges = <0 32 16>;
+ };
+
+ main_gpio0: gpio@600000 {
+ compatible = "ti,am64-gpio", "ti,keystone-gpio";
+ reg = <0x00 0x00600000 0x00 0x100>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&main_gpio_intr>;
+ interrupts = <190>, <191>, <192>,
+ <193>, <194>, <195>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,ngpio = <92>;
+ ti,davinci-gpio-unbanked = <0>;
+ power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 77 0>;
+ clock-names = "gpio";
+ };
+
+ main_gpio1: gpio@601000 {
+ compatible = "ti,am64-gpio", "ti,keystone-gpio";
+ reg = <0x00 0x00601000 0x00 0x100>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&main_gpio_intr>;
+ interrupts = <180>, <181>, <182>,
+ <183>, <184>, <185>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,ngpio = <52>;
+ ti,davinci-gpio-unbanked = <0>;
+ power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 78 0>;
+ clock-names = "gpio";
+ };
+
+ sdhci0: mmc@fa10000 {
+ compatible = "ti,am64-sdhci-8bit";
+ reg = <0x00 0x0fa10000 0x00 0x1000>, <0x00 0x0fa18000 0x00 0x400>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 57 1>, <&k3_clks 57 2>;
+ clock-names = "clk_ahb", "clk_xin";
+ assigned-clocks = <&k3_clks 57 2>;
+ assigned-clock-parents = <&k3_clks 57 4>;
+ ti,otap-del-sel-legacy = <0x0>;
+ status = "disabled";
+ };
+
+ sdhci1: mmc@fa00000 {
+ compatible = "ti,am62-sdhci";
+ reg = <0x00 0x0fa00000 0x00 0x1000>, <0x00 0x0fa08000 0x00 0x400>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
+ clock-names = "clk_ahb", "clk_xin";
+ ti,otap-del-sel-legacy = <0x8>;
+ status = "disabled";
+ };
+
+ sdhci2: mmc@fa20000 {
+ compatible = "ti,am62-sdhci";
+ reg = <0x00 0x0fa20000 0x00 0x1000>, <0x00 0x0fa28000 0x00 0x400>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
+ clock-names = "clk_ahb", "clk_xin";
+ ti,otap-del-sel-legacy = <0x8>;
+ status = "disabled";
+ };
+
+ fss: bus@fc00000 {
+ compatible = "simple-bus";
+ reg = <0x00 0x0fc00000 0x00 0x70000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ospi0: spi@fc40000 {
+ compatible = "ti,am654-ospi", "cdns,qspi-nor";
+ reg = <0x00 0x0fc40000 0x00 0x100>,
+ <0x05 0x00000000 0x01 0x00000000>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ cdns,fifo-depth = <256>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x0>;
+ clocks = <&k3_clks 75 7>;
+ assigned-clocks = <&k3_clks 75 7>;
+ assigned-clock-parents = <&k3_clks 75 8>;
+ assigned-clock-rates = <166666666>;
+ power-domains = <&k3_pds 75 TI_SCI_PD_EXCLUSIVE>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ cpsw3g: ethernet@8000000 {
+ compatible = "ti,am642-cpsw-nuss";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ reg = <0x00 0x08000000 0x00 0x200000>;
+ reg-names = "cpsw_nuss";
+ ranges = <0x00 0x00 0x00 0x08000000 0x00 0x200000>;
+ clocks = <&k3_clks 13 0>;
+ assigned-clocks = <&k3_clks 13 3>;
+ assigned-clock-parents = <&k3_clks 13 11>;
+ clock-names = "fck";
+ power-domains = <&k3_pds 13 TI_SCI_PD_EXCLUSIVE>;
+
+ dmas = <&main_pktdma 0xc600 15>,
+ <&main_pktdma 0xc601 15>,
+ <&main_pktdma 0xc602 15>,
+ <&main_pktdma 0xc603 15>,
+ <&main_pktdma 0xc604 15>,
+ <&main_pktdma 0xc605 15>,
+ <&main_pktdma 0xc606 15>,
+ <&main_pktdma 0xc607 15>,
+ <&main_pktdma 0x4600 15>;
+ dma-names = "tx0", "tx1", "tx2", "tx3", "tx4", "tx5", "tx6",
+ "tx7", "rx";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpsw_port1: port@1 {
+ reg = <1>;
+ ti,mac-only;
+ label = "port1";
+ phys = <&phy_gmii_sel 1>;
+ mac-address = [00 00 00 00 00 00];
+ };
+
+ cpsw_port2: port@2 {
+ reg = <2>;
+ ti,mac-only;
+ label = "port2";
+ phys = <&phy_gmii_sel 2>;
+ mac-address = [00 00 00 00 00 00];
+ };
+ };
+
+ cpsw3g_mdio: mdio@f00 {
+ compatible = "ti,cpsw-mdio","ti,davinci_mdio";
+ reg = <0x00 0xf00 0x00 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&k3_clks 13 0>;
+ clock-names = "fck";
+ bus_freq = <1000000>;
+ status = "disabled";
+ };
+
+ cpts@3d000 {
+ compatible = "ti,j721e-cpts";
+ reg = <0x00 0x3d000 0x00 0x400>;
+ clocks = <&k3_clks 13 3>;
+ clock-names = "cpts";
+ interrupts-extended = <&gic500 GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cpts";
+ ti,cpts-ext-ts-inputs = <4>;
+ ti,cpts-periodic-outputs = <2>;
+ };
+ };
+
+ hwspinlock: spinlock@2a000000 {
+ compatible = "ti,am64-hwspinlock";
+ reg = <0x00 0x2a000000 0x00 0x1000>;
+ #hwlock-cells = <1>;
+ };
+
+ mailbox0_cluster0: mailbox@29000000 {
+ compatible = "ti,am64-mailbox";
+ reg = <0x00 0x29000000 0x00 0x200>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <16>;
+ };
+
+ mailbox0_cluster1: mailbox@29010000 {
+ compatible = "ti,am64-mailbox";
+ reg = <0x00 0x29010000 0x00 0x200>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <16>;
+ };
+
+ mailbox0_cluster2: mailbox@29020000 {
+ compatible = "ti,am64-mailbox";
+ reg = <0x00 0x29020000 0x00 0x200>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <16>;
+ };
+
+ mailbox0_cluster3: mailbox@29030000 {
+ compatible = "ti,am64-mailbox";
+ reg = <0x00 0x29030000 0x00 0x200>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <16>;
+ };
+
+ ecap0: pwm@23100000 {
+ compatible = "ti,am3352-ecap";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23100000 0x00 0x100>;
+ power-domains = <&k3_pds 51 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 51 0>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ ecap1: pwm@23110000 {
+ compatible = "ti,am3352-ecap";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23110000 0x00 0x100>;
+ power-domains = <&k3_pds 52 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 52 0>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ ecap2: pwm@23120000 {
+ compatible = "ti,am3352-ecap";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23120000 0x00 0x100>;
+ power-domains = <&k3_pds 53 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 53 0>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ main_mcan0: can@20701000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x20701000 0x00 0x200>,
+ <0x00 0x20708000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 98 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 98 6>, <&k3_clks 98 1>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan1: can@20711000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x20711000 0x00 0x200>,
+ <0x00 0x20718000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 99 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 99 6>, <&k3_clks 99 1>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_rti0: watchdog@e000000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e000000 0x00 0x100>;
+ clocks = <&k3_clks 125 0>;
+ power-domains = <&k3_pds 125 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 125 0>;
+ assigned-clock-parents = <&k3_clks 125 2>;
+ };
+
+ main_rti1: watchdog@e010000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e010000 0x00 0x100>;
+ clocks = <&k3_clks 126 0>;
+ power-domains = <&k3_pds 126 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 126 0>;
+ assigned-clock-parents = <&k3_clks 126 2>;
+ };
+
+ main_rti2: watchdog@e020000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e020000 0x00 0x100>;
+ clocks = <&k3_clks 127 0>;
+ power-domains = <&k3_pds 127 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 127 0>;
+ assigned-clock-parents = <&k3_clks 127 2>;
+ };
+
+ main_rti3: watchdog@e030000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e030000 0x00 0x100>;
+ clocks = <&k3_clks 128 0>;
+ power-domains = <&k3_pds 128 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 128 0>;
+ assigned-clock-parents = <&k3_clks 128 2>;
+ };
+
+ main_rti15: watchdog@e0f0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x0e0f0000 0x00 0x100>;
+ clocks = <&k3_clks 130 0>;
+ power-domains = <&k3_pds 130 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 130 0>;
+ assigned-clock-parents = <&k3_clks 130 2>;
+ };
+
+ epwm0: pwm@23000000 {
+ compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23000000 0x00 0x100>;
+ power-domains = <&k3_pds 86 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&epwm_tbclk 0>, <&k3_clks 86 0>;
+ clock-names = "tbclk", "fck";
+ status = "disabled";
+ };
+
+ epwm1: pwm@23010000 {
+ compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23010000 0x00 0x100>;
+ power-domains = <&k3_pds 87 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&epwm_tbclk 1>, <&k3_clks 87 0>;
+ clock-names = "tbclk", "fck";
+ status = "disabled";
+ };
+
+ epwm2: pwm@23020000 {
+ compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x00 0x23020000 0x00 0x100>;
+ power-domains = <&k3_pds 88 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&epwm_tbclk 2>, <&k3_clks 88 0>;
+ clock-names = "tbclk", "fck";
+ status = "disabled";
+ };
+
+ mcasp0: audio-controller@2b00000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b00000 0x00 0x2000>,
+ <0x00 0x02b08000 0x00 0x400>;
+ reg-names = "mpu", "dat";
+ interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+
+ dmas = <&main_bcdma 0 0xc500 0>, <&main_bcdma 0 0x4500 0>;
+ dma-names = "tx", "rx";
+
+ clocks = <&k3_clks 190 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 190 0>;
+ assigned-clock-parents = <&k3_clks 190 2>;
+ power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp1: audio-controller@2b10000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b10000 0x00 0x2000>,
+ <0x00 0x02b18000 0x00 0x400>;
+ reg-names = "mpu", "dat";
+ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+
+ dmas = <&main_bcdma 0 0xc501 0>, <&main_bcdma 0 0x4501 0>;
+ dma-names = "tx", "rx";
+
+ clocks = <&k3_clks 191 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 191 0>;
+ assigned-clock-parents = <&k3_clks 191 2>;
+ power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ mcasp2: audio-controller@2b20000 {
+ compatible = "ti,am33xx-mcasp-audio";
+ reg = <0x00 0x02b20000 0x00 0x2000>,
+ <0x00 0x02b28000 0x00 0x400>;
+ reg-names = "mpu", "dat";
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+
+ dmas = <&main_bcdma 0 0xc502 0>, <&main_bcdma 0 0x4502 0>;
+ dma-names = "tx", "rx";
+
+ clocks = <&k3_clks 192 0>;
+ clock-names = "fck";
+ assigned-clocks = <&k3_clks 192 0>;
+ assigned-clock-parents = <&k3_clks 192 2>;
+ power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi
index 27ca1c9c6d13..c4b0b91d70cf 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi
@@ -11,5 +11,195 @@
#pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0xffffffff>;
+ bootph-all;
+ };
+
+ mcu_esm: esm@4100000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x4100000 0x00 0x1000>;
+ ti,esm-pins = <0>, <1>, <2>, <85>;
+ status = "reserved";
+ bootph-pre-ram;
+ };
+
+ /*
+ * The MCU domain timer interrupts are routed only to the ESM module,
+ * and not currently available for Linux. The MCU domain timers are
+ * of limited use without interrupts, and likely reserved by the ESM.
+ */
+ mcu_timer0: timer@4800000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x4800000 0x00 0x400>;
+ clocks = <&k3_clks 35 2>;
+ clock-names = "fck";
+ power-domains = <&k3_pds 35 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ status = "reserved";
+ };
+
+ mcu_timer1: timer@4810000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x4810000 0x00 0x400>;
+ clocks = <&k3_clks 48 2>;
+ clock-names = "fck";
+ power-domains = <&k3_pds 48 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ status = "reserved";
+ };
+
+ mcu_timer2: timer@4820000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x4820000 0x00 0x400>;
+ clocks = <&k3_clks 49 2>;
+ clock-names = "fck";
+ power-domains = <&k3_pds 49 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ status = "reserved";
+ };
+
+ mcu_timer3: timer@4830000 {
+ compatible = "ti,am654-timer";
+ reg = <0x00 0x4830000 0x00 0x400>;
+ clocks = <&k3_clks 50 2>;
+ clock-names = "fck";
+ power-domains = <&k3_pds 50 TI_SCI_PD_EXCLUSIVE>;
+ ti,timer-pwm;
+ status = "reserved";
+ };
+
+ mcu_uart0: serial@4a00000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x04a00000 0x00 0x100>;
+ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 149 0>;
+ clock-names = "fclk";
+ status = "disabled";
+ };
+
+ mcu_i2c0: i2c@4900000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x04900000 0x00 0x100>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 106 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 106 2>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ mcu_spi0: spi@4b00000 {
+ compatible = "ti,am654-mcspi", "ti,omap4-mcspi";
+ reg = <0x00 0x04b00000 0x00 0x400>;
+ interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 147 0>;
+ status = "disabled";
+ };
+
+ mcu_spi1: spi@4b10000 {
+ compatible = "ti,am654-mcspi","ti,omap4-mcspi";
+ reg = <0x00 0x04b10000 0x00 0x400>;
+ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 148 0>;
+ status = "disabled";
+ };
+
+ mcu_gpio_intr: interrupt-controller@4210000 {
+ compatible = "ti,sci-intr";
+ reg = <0x00 0x04210000 0x00 0x200>;
+ ti,intr-trigger-type = <1>;
+ interrupt-controller;
+ interrupt-parent = <&gic500>;
+ #interrupt-cells = <1>;
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <5>;
+ ti,interrupt-ranges = <0 104 4>;
+ };
+
+ mcu_gpio0: gpio@4201000 {
+ compatible = "ti,am64-gpio", "ti,keystone-gpio";
+ reg = <0x00 0x4201000 0x00 0x100>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&mcu_gpio_intr>;
+ interrupts = <30>, <31>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,ngpio = <24>;
+ ti,davinci-gpio-unbanked = <0>;
+ power-domains = <&k3_pds 79 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 79 0>;
+ clock-names = "gpio";
+ };
+
+ mcu_rti0: watchdog@4880000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x04880000 0x00 0x100>;
+ clocks = <&k3_clks 131 0>;
+ power-domains = <&k3_pds 131 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 131 0>;
+ assigned-clock-parents = <&k3_clks 131 2>;
+ /* Tightly coupled to M4F */
+ status = "reserved";
+ };
+
+ mcu_mcan0: can@4e08000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x4e08000 0x00 0x200>,
+ <0x00 0x4e00000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 188 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 188 6>, <&k3_clks 188 1>;
+ clock-names = "hclk", "cclk";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ status = "disabled";
+ };
+
+ mcu_mcan1: can@4e18000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x4e18000 0x00 0x200>,
+ <0x00 0x4e10000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 189 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 189 6>, <&k3_clks 189 1>;
+ clock-names = "hclk", "cclk";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ status = "disabled";
+ };
+
+ mcu_r5fss0: r5fss@79000000 {
+ compatible = "ti,am62-r5fss";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x79000000 0x00 0x79000000 0x8000>,
+ <0x79020000 0x00 0x79020000 0x8000>;
+ power-domains = <&k3_pds 7 TI_SCI_PD_EXCLUSIVE>;
+ mcu_r5fss0_core0: r5f@79000000 {
+ compatible = "ti,am62-r5f";
+ reg = <0x79000000 0x00008000>,
+ <0x79020000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <9>;
+ ti,sci-proc-ids = <0x03 0xff>;
+ resets = <&k3_reset 9 1>;
+ firmware-name = "am62p-mcu-r5f0_0-fw";
+ ti,atcm-enable = <0>;
+ ti,btcm-enable = <1>;
+ ti,loczrama = <0>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi
new file mode 100644
index 000000000000..85ce545633ea
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dt-bindings/thermal/thermal.h>
+
+thermal_zones: thermal-zones {
+ main0_thermal: main0-thermal {
+ polling-delay-passive = <250>; /* milliSeconds */
+ polling-delay = <500>; /* milliSeconds */
+ thermal-sensors = <&wkup_vtm0 0>;
+
+ trips {
+ main0_crit: main0-crit {
+ temperature = <125000>; /* milliCelsius */
+ hysteresis = <2000>; /* milliCelsius */
+ type = "critical";
+ };
+ };
+ };
+
+ main1_thermal: main1-thermal {
+ polling-delay-passive = <250>; /* milliSeconds */
+ polling-delay = <500>; /* milliSeconds */
+ thermal-sensors = <&wkup_vtm0 1>;
+
+ trips {
+ main1_crit: main1-crit {
+ temperature = <125000>; /* milliCelsius */
+ hysteresis = <2000>; /* milliCelsius */
+ type = "critical";
+ };
+ };
+ };
+
+ main2_thermal: main2-thermal {
+ polling-delay-passive = <250>; /* milliSeconds */
+ polling-delay = <500>; /* milliSeconds */
+ thermal-sensors = <&wkup_vtm0 2>;
+
+ trips {
+ main2_crit: main2-crit {
+ temperature = <125000>; /* milliCelsius */
+ hysteresis = <2000>; /* milliCelsius */
+ type = "critical";
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
index aaf4b793b58e..19f42b39394e 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
@@ -6,17 +6,17 @@
&cbass_wakeup {
wkup_conf: bus@43000000 {
- bootph-all;
compatible = "simple-bus";
reg = <0x00 0x43000000 0x00 0x20000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x00 0x00 0x43000000 0x20000>;
+ bootph-all;
chipid: chipid@14 {
- bootph-all;
compatible = "ti,am654-chipid";
reg = <0x14 0x4>;
+ bootph-all;
};
};
@@ -29,4 +29,69 @@
clock-names = "fclk";
status = "disabled";
};
+
+ wkup_i2c0: i2c@2b200000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x2b200000 0x00 0x100>;
+ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 107 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 107 4>;
+ clock-names = "fck";
+ status = "disabled";
+ };
+
+ wkup_rtc0: rtc@2b1f0000 {
+ compatible = "ti,am62-rtc";
+ reg = <0x00 0x2b1f0000 0x00 0x100>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 117 6> , <&k3_clks 117 0>;
+ clock-names = "vbus", "osc32k";
+ power-domains = <&k3_pds 117 TI_SCI_PD_EXCLUSIVE>;
+ wakeup-source;
+ };
+
+ wkup_rti0: watchdog@2b000000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2b000000 0x00 0x100>;
+ clocks = <&k3_clks 132 0>;
+ power-domains = <&k3_pds 132 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 132 0>;
+ assigned-clock-parents = <&k3_clks 132 2>;
+ /* Used by DM firmware */
+ status = "reserved";
+ };
+
+ wkup_vtm0: temperature-sensor@b00000 {
+ compatible = "ti,j7200-vtm";
+ reg = <0x00 0xb00000 0x00 0x400>,
+ <0x00 0xb01000 0x00 0x400>;
+ power-domains = <&k3_pds 95 TI_SCI_PD_EXCLUSIVE>;
+ #thermal-sensor-cells = <1>;
+ };
+
+ wkup_r5fss0: r5fss@78000000 {
+ compatible = "ti,am62-r5fss";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x78000000 0x00 0x78000000 0x8000>,
+ <0x78100000 0x00 0x78100000 0x8000>;
+ power-domains = <&k3_pds 119 TI_SCI_PD_EXCLUSIVE>;
+
+ wkup_r5fss0_core0: r5f@78000000 {
+ compatible = "ti,am62-r5f";
+ reg = <0x78000000 0x00008000>,
+ <0x78100000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <121>;
+ ti,sci-proc-ids = <0x01 0xff>;
+ resets = <&k3_reset 121 1>;
+ firmware-name = "am62-wkup-r5f0_0-fw";
+ ti,atcm-enable = <1>;
+ ti,btcm-enable = <1>;
+ ti,loczrama = <1>;
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
index 294ab73ec98b..84ffe7b9dcaf 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
@@ -45,10 +45,10 @@
};
cbass_main: bus@f0000 {
- bootph-all;
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
+ bootph-all;
ranges = <0x00 0x000f0000 0x00 0x000f0000 0x00 0x00030000>, /* Main MMRs */
<0x00 0x00420000 0x00 0x00420000 0x00 0x00001000>, /* ESM0 */
@@ -100,10 +100,10 @@
<0x00 0x79020000 0x00 0x79020000 0x00 0x00008000>, /* MCU R5 BTCM */
<0x00 0x79100000 0x00 0x79100000 0x00 0x00040000>, /* MCU IRAM0 */
<0x00 0x79140000 0x00 0x79140000 0x00 0x00040000>; /* MCU IRAM1 */
+ bootph-all;
};
cbass_wakeup: bus@b00000 {
- bootph-all;
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
@@ -112,8 +112,11 @@
<0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>, /* WKUP CTRL MMR */
<0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>, /* DM R5 ATCM*/
<0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>; /* DM R5 BTCM*/
+ bootph-all;
};
};
+
+ #include "k3-am62p-thermal.dtsi"
};
/* Now include peripherals for each bus segment */
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 6fb17b17c95e..f377eadef0c1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -8,6 +8,9 @@
/dts-v1/;
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/net/ti-dp83867.h>
#include "k3-am62p5.dtsi"
/ {
@@ -18,6 +21,12 @@
serial0 = &wkup_uart0;
serial2 = &main_uart0;
serial3 = &main_uart1;
+ mmc0 = &sdhci0;
+ mmc1 = &sdhci1;
+ mmc2 = &sdhci2;
+ spi0 = &ospi0;
+ ethernet0 = &cpsw_port1;
+ ethernet1 = &cpsw_port2;
};
chosen {
@@ -29,6 +38,7 @@
reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
<0x00000008 0x80000000 0x00000001 0x80000000>;
device_type = "memory";
+ bootph-pre-ram;
};
reserved-memory {
@@ -52,35 +62,511 @@
no-map;
};
};
+
+ vmain_pd: regulator-0 {
+ /* TPS65988 PD CONTROLLER OUTPUT */
+ compatible = "regulator-fixed";
+ regulator-name = "vmain_pd";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ bootph-all;
+ };
+
+ vcc_5v0: regulator-1 {
+ /* Output of TPS630702RNMR */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vmain_pd>;
+ regulator-always-on;
+ regulator-boot-on;
+ bootph-all;
+ };
+
+ vdd_mmc1: regulator-2 {
+ /* TPS22918DBVR */
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_mmc1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&exp1 3 GPIO_ACTIVE_HIGH>;
+ bootph-all;
+ };
+
+ vddshv_sdio: regulator-3 {
+ compatible = "regulator-gpio";
+ regulator-name = "vddshv_sdio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vddshv_sdio_pins_default>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ gpios = <&main_gpio0 31 GPIO_ACTIVE_HIGH>;
+ states = <1800000 0x0>,
+ <3300000 0x1>;
+ bootph-all;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usr_led_pins_default>;
+
+ led-0 {
+ label = "am62-sk:green:heartbeat";
+ gpios = <&main_gpio1 49 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ function = LED_FUNCTION_HEARTBEAT;
+ default-state = "off";
+ };
+ };
+
+ tlv320_mclk: clk-0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <12288000>;
+ };
+
+ codec_audio: sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "AM62x-SKEVM";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Line", "Line In",
+ "Microphone", "Microphone Jack";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "LINE1L", "Line In",
+ "LINE1R", "Line In",
+ "MIC3R", "Microphone Jack",
+ "Microphone Jack", "Mic Bias";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&sound_master>;
+ simple-audio-card,frame-master = <&sound_master>;
+ simple-audio-card,bitclock-inversion;
+
+ simple-audio-card,cpu {
+ sound-dai = <&mcasp1>;
+ };
+
+ sound_master: simple-audio-card,codec {
+ sound-dai = <&tlv320aic3106>;
+ clocks = <&tlv320_mclk>;
+ };
+ };
+};
+
+&main_gpio0 {
+ bootph-all;
+};
+
+&main_gpio1 {
+ bootph-all;
};
&main_pmx0 {
- main_uart0_pins_default: main-uart0-default-pins {
+ bootph-all;
+
+ main_i2c0_pins_default: main-i2c0-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (B25) I2C0_SCL */
+ AM62PX_IOPAD(0x01e4, PIN_INPUT_PULLUP, 0) /* (A24) I2C0_SDA */
+ >;
+ };
+
+ main_i2c1_pins_default: main-i2c1-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x01e8, PIN_INPUT_PULLUP, 0) /* (C24) I2C1_SCL */
+ AM62PX_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (B24) I2C1_SDA */
+ >;
bootph-all;
+ };
+
+ main_i2c2_pins_default: main-i2c2-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x00b0, PIN_INPUT_PULLUP, 1) /* (T22) GPMC0_CSn2.I2C2_SCL */
+ AM62PX_IOPAD(0x00b4, PIN_INPUT_PULLUP, 1) /* (U25) GPMC0_CSn3.I2C2_SDA */
+ >;
+ };
+
+ main_gpio1_ioexp_intr_pins_default: main-gpio1-ioexp-intr-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x01d4, PIN_INPUT, 7) /* (C22) UART0_RTSn.GPIO1_23 */
+ >;
+ };
+
+ main_mcasp1_pins_default: main-mcasp1-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x0090, PIN_INPUT, 2) /* (U24) GPMC0_BE0n_CLE.MCASP1_ACLKX */
+ AM62PX_IOPAD(0x0098, PIN_INPUT, 2) /* (AA24) GPMC0_WAIT0.MCASP1_AFSX */
+ AM62PX_IOPAD(0x008c, PIN_INPUT, 2) /* (T25) GPMC0_WEn.MCASP1_AXR0 */
+ AM62PX_IOPAD(0x0084, PIN_INPUT, 2) /* (R25) GPMC0_ADVn_ALE.MCASP1_AXR2 */
+ >;
+ };
+
+ main_mdio1_pins_default: main-mdio1-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x0160, PIN_OUTPUT, 0) /* (F17) MDIO0_MDC */
+ AM62PX_IOPAD(0x015c, PIN_INPUT, 0) /* (F16) MDIO0_MDIO */
+ >;
+ };
+
+ main_mmc1_pins_default: main-mmc1-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x023c, PIN_INPUT, 0) /* (H20) MMC1_CMD */
+ AM62PX_IOPAD(0x0234, PIN_OUTPUT, 0) /* (J24) MMC1_CLK */
+ AM62PX_IOPAD(0x0230, PIN_INPUT, 0) /* (H21) MMC1_DAT0 */
+ AM62PX_IOPAD(0x022c, PIN_INPUT_PULLUP, 0) /* (H23) MMC1_DAT1 */
+ AM62PX_IOPAD(0x0228, PIN_INPUT_PULLUP, 0) /* (H22) MMC1_DAT2 */
+ AM62PX_IOPAD(0x0224, PIN_INPUT_PULLUP, 0) /* (H25) MMC1_DAT3 */
+ AM62PX_IOPAD(0x0240, PIN_INPUT, 0) /* (D23) MMC1_SDCD */
+ >;
+ bootph-all;
+ };
+
+ main_mmc2_pins_default: main-mmc2-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x0120, PIN_INPUT, 0) /* (K24) MMC2_CMD */
+ AM62PX_IOPAD(0x0118, PIN_OUTPUT, 0) /* (K21) MMC2_CLK */
+ AM62PX_IOPAD(0x011C, PIN_INPUT, 0) /* () MMC2_CLKLB */
+ AM62PX_IOPAD(0x0114, PIN_INPUT, 0) /* (K23) MMC2_DAT0 */
+ AM62PX_IOPAD(0x0110, PIN_INPUT_PULLUP, 0) /* (K22) MMC2_DAT1 */
+ AM62PX_IOPAD(0x010c, PIN_INPUT_PULLUP, 0) /* (L20) MMC2_DAT2 */
+ AM62PX_IOPAD(0x0108, PIN_INPUT_PULLUP, 0) /* (L21) MMC2_DAT3 */
+ >;
+ bootph-all;
+ };
+
+ main_rgmii1_pins_default: main-rgmii1-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x014c, PIN_INPUT, 0) /* (B15) RGMII1_RD0 */
+ AM62PX_IOPAD(0x0150, PIN_INPUT, 0) /* (B16) RGMII1_RD1 */
+ AM62PX_IOPAD(0x0154, PIN_INPUT, 0) /* (A14) RGMII1_RD2 */
+ AM62PX_IOPAD(0x0158, PIN_INPUT, 0) /* (B14) RGMII1_RD3 */
+ AM62PX_IOPAD(0x0148, PIN_INPUT, 0) /* (A16) RGMII1_RXC */
+ AM62PX_IOPAD(0x0144, PIN_INPUT, 0) /* (A15) RGMII1_RX_CTL */
+ AM62PX_IOPAD(0x0134, PIN_INPUT, 0) /* (A18) RGMII1_TD0 */
+ AM62PX_IOPAD(0x0138, PIN_INPUT, 0) /* (C17) RGMII1_TD1 */
+ AM62PX_IOPAD(0x013c, PIN_INPUT, 0) /* (A17) RGMII1_TD2 */
+ AM62PX_IOPAD(0x0140, PIN_INPUT, 0) /* (C16) RGMII1_TD3 */
+ AM62PX_IOPAD(0x0130, PIN_INPUT, 0) /* (B17) RGMII1_TXC */
+ AM62PX_IOPAD(0x012c, PIN_INPUT, 0) /* (B18) RGMII1_TX_CTL */
+ >;
+ bootph-all;
+ };
+
+ main_rgmii2_pins_default: main-rgmii2-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x0184, PIN_INPUT, 0) /* (E19) RGMII2_RD0 */
+ AM62PX_IOPAD(0x0188, PIN_INPUT, 0) /* (E16) RGMII2_RD1 */
+ AM62PX_IOPAD(0x018c, PIN_INPUT, 0) /* (E17) RGMII2_RD2 */
+ AM62PX_IOPAD(0x0190, PIN_INPUT, 0) /* (C19) RGMII2_RD3 */
+ AM62PX_IOPAD(0x0180, PIN_INPUT, 0) /* (D19) RGMII2_RXC */
+ AM62PX_IOPAD(0x017c, PIN_INPUT, 0) /* (F19) RGMII2_RX_CTL */
+ AM62PX_IOPAD(0x016c, PIN_INPUT, 0) /* (B19) RGMII2_TD0 */
+ AM62PX_IOPAD(0x0170, PIN_INPUT, 0) /* (A21) RGMII2_TD1 */
+ AM62PX_IOPAD(0x0174, PIN_INPUT, 0) /* (D17) RGMII2_TD2 */
+ AM62PX_IOPAD(0x0178, PIN_INPUT, 0) /* (A19) RGMII2_TD3 */
+ AM62PX_IOPAD(0x0168, PIN_INPUT, 0) /* (D16) RGMII2_TXC */
+ AM62PX_IOPAD(0x0164, PIN_INPUT, 0) /* (A20) RGMII2_TX_CTL */
+ >;
+ bootph-all;
+ };
+
+ main_uart0_pins_default: main-uart0-default-pins {
pinctrl-single,pins = <
AM62PX_IOPAD(0x1c8, PIN_INPUT, 0) /* (A22) UART0_RXD */
AM62PX_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (B22) UART0_TXD */
- AM62PX_IOPAD(0x1d0, PIN_INPUT, 0) /* (A23) UART0_CTSn */
- AM62PX_IOPAD(0x1d4, PIN_OUTPUT, 0) /* (C22) UART0_RTSn */
>;
+ bootph-all;
};
main_uart1_pins_default: main-uart1-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x0194, PIN_INPUT, 2) /* (D25) MCASP0_AXR3.UART1_CTSn */
+ AM62PX_IOPAD(0x0198, PIN_OUTPUT, 2) /* (E25) MCASP0_AXR2.UART1_RTSn */
+ AM62PX_IOPAD(0x01ac, PIN_INPUT, 2) /* (G23) MCASP0_AFSR.UART1_RXD */
+ AM62PX_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR.UART1_TXD */
+ >;
bootph-all;
+ };
+
+ main_wlirq_pins_default: main-wlirq-default-pins {
pinctrl-single,pins = <
- AM62PX_IOPAD(0x194, PIN_INPUT, 2) /* (D25) MCASP0_AXR3 */
- AM62PX_IOPAD(0x198, PIN_OUTPUT, 2) /* (E25) MCASP0_AXR2 */
- AM62PX_IOPAD(0x1ac, PIN_INPUT, 2) /* (G23) MCASP0_AFSR */
- AM62PX_IOPAD(0x1b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR */
+ AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
+ >;
+ };
+
+ ospi0_pins_default: ospi0-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x0000, PIN_OUTPUT, 0) /* (P23) OSPI0_CLK */
+ AM62PX_IOPAD(0x002c, PIN_OUTPUT, 0) /* (M25) OSPI0_CSn0 */
+ AM62PX_IOPAD(0x000c, PIN_INPUT, 0) /* (L25) OSPI0_D0 */
+ AM62PX_IOPAD(0x0010, PIN_INPUT, 0) /* (N24) OSPI0_D1 */
+ AM62PX_IOPAD(0x0014, PIN_INPUT, 0) /* (N25) OSPI0_D2 */
+ AM62PX_IOPAD(0x0018, PIN_INPUT, 0) /* (M24) OSPI0_D3 */
+ AM62PX_IOPAD(0x001c, PIN_INPUT, 0) /* (N21) OSPI0_D4 */
+ AM62PX_IOPAD(0x0020, PIN_INPUT, 0) /* (N22) OSPI0_D5 */
+ AM62PX_IOPAD(0x0024, PIN_INPUT, 0) /* (P21) OSPI0_D6 */
+ AM62PX_IOPAD(0x0028, PIN_INPUT, 0) /* (N20) OSPI0_D7 */
+ AM62PX_IOPAD(0x0008, PIN_INPUT, 0) /* (P22) OSPI0_DQS */
+ >;
+ bootph-all;
+ };
+
+ usr_led_pins_default: usr-led-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x0244, PIN_INPUT, 7) /* (D24) MMC1_SDWP.GPIO1_49 */
+ >;
+ };
+
+ vddshv_sdio_pins_default: vddshvr-sdio-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x007c, PIN_INPUT, 7) /* (Y25) GPMC0_CLK.GPIO0_31 */
+ >;
+ bootph-all;
+ };
+
+ wlan_en_pins_default: wlan-en-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
>;
};
};
-&main_uart0 {
+&main_i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_pins_default>;
+ clock-frequency = <100000>;
+ bootph-all;
+
+ tlv320aic3106: audio-codec@1b {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3106";
+ reg = <0x1b>;
+ ai3x-micbias-vg = <1>; /* 2.0V */
+ };
+
+ exp1: gpio@22 {
+ compatible = "ti,tca6424";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "OLDI_INT#", "x8_NAND_DETECT",
+ "UART1_FET_SEL", "MMC1_SD_EN",
+ "VPP_EN", "EXP_PS_3V3_EN",
+ "UART1_FET_BUF_EN", "EXP_HAT_DETECT",
+ "DSI_GPIO0", "DSI_GPIO1",
+ "OLDI_EDID", "BT_UART_WAKE_SOC_3V3",
+ "USB_TYPEA_OC_INDICATION", "CSI_GPIO0",
+ "CSI_GPIO1", "WLAN_ALERTn",
+ "HDMI_INTn", "TEST_GPIO2",
+ "MCASP1_FET_EN", "MCASP1_BUF_BT_EN",
+ "MCASP1_FET_SEL", "DSI_EDID",
+ "PD_I2C_IRQ", "IO_EXP_TEST_LED";
+
+ interrupt-parent = <&main_gpio1>;
+ interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_gpio1_ioexp_intr_pins_default>;
+ bootph-all;
+ };
+
+ exp2: gpio@23 {
+ compatible = "ti,tca6424";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "BT_EN_SOC", "EXP_PS_5V0_EN",
+ "", "",
+ "", "",
+ "", "",
+ "WL_LT_EN", "",
+ "TP3", "TP6",
+ "TP4", "TP7",
+ "TP5", "TP8",
+ "SoC_I2C2_MCAN_SEL", "GPIO_HDMI_RSTn",
+ "GPIO_CPSW2_RST", "GPIO_CPSW1_RST",
+ "GPIO_OLDI_RSTn", "GPIO_AUD_RSTn",
+ "GPIO_eMMC_RSTn", "SoC_WLAN_SDIO_RST";
+ };
+};
+
+&main_i2c2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c2_pins_default>;
+ clock-frequency = <400000>;
+};
+
+&sdhci0 {
+ status = "okay";
+ ti,driver-strength-ohm = <50>;
+ disable-wp;
+};
+
+&sdhci1 {
+ /* SD/MMC */
+ status = "okay";
+ vmmc-supply = <&vdd_mmc1>;
+ vqmmc-supply = <&vddshv_sdio>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mmc1_pins_default>;
+ ti,driver-strength-ohm = <50>;
+ disable-wp;
+ no-1-8-v;
+ bootph-all;
+};
+
+&cpsw3g {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_rgmii1_pins_default>,
+ <&main_rgmii2_pins_default>;
+};
+
+&cpsw_port1 {
+ phy-mode = "rgmii-rxid";
+ phy-handle = <&cpsw3g_phy0>;
+};
+
+&cpsw_port2 {
+ phy-mode = "rgmii-rxid";
+ phy-handle = <&cpsw3g_phy1>;
+};
+
+&cpsw3g_mdio {
+ cpsw3g_phy0: ethernet-phy@0 {
+ reg = <0>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,min-output-impedance;
+ };
+
+ cpsw3g_phy1: ethernet-phy@1 {
+ reg = <1>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,min-output-impedance;
+ };
+};
+
+&mcasp1 {
+ status = "okay";
+ #sound-dai-cells = <0>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcasp1_pins_default>;
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 1 0 2 0
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+};
+
+&fss {
bootph-all;
+};
+
+&ospi0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ospi0_pins_default>;
+ bootph-all;
+
+ flash@0{
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <8>;
+ spi-rx-bus-width = <8>;
+ spi-max-frequency = <25000000>;
+ cdns,tshsl-ns = <60>;
+ cdns,tsd2d-ns = <60>;
+ cdns,tchsh-ns = <60>;
+ cdns,tslch-ns = <60>;
+ cdns,read-delay = <4>;
+ bootph-all;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bootph-all;
+
+ partition@0 {
+ label = "ospi.tiboot3";
+ reg = <0x00 0x80000>;
+ };
+
+ partition@80000 {
+ label = "ospi.tispl";
+ reg = <0x80000 0x200000>;
+ };
+
+ partition@280000 {
+ label = "ospi.u-boot";
+ reg = <0x280000 0x400000>;
+ };
+
+ partition@680000 {
+ label = "ospi.env";
+ reg = <0x680000 0x40000>;
+ };
+
+ partition@6c0000 {
+ label = "ospi.env.backup";
+ reg = <0x6c0000 0x40000>;
+ };
+
+ partition@800000 {
+ label = "ospi.rootfs";
+ reg = <0x800000 0x37c0000>;
+ };
+
+ partition@3fc0000 {
+ label = "ospi.phypattern";
+ reg = <0x3fc0000 0x40000>;
+ bootph-all;
+ };
+ };
+ };
+};
+
+&mailbox0_cluster0 {
+ mbox_r5_0: mbox-r5-0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+};
+
+&mailbox0_cluster1 {
+ mbox_mcu_r5_0: mbox-mcu-r5-0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+};
+
+&main_uart0 {
pinctrl-names = "default";
pinctrl-0 = <&main_uart0_pins_default>;
status = "okay";
+ bootph-all;
};
&main_uart1 {
@@ -88,29 +574,27 @@
pinctrl-0 = <&main_uart1_pins_default>;
/* Main UART1 is used by TIFS firmware */
status = "reserved";
-};
-
-&cbass_mcu {
bootph-all;
};
&mcu_pmx0 {
bootph-all;
+
wkup_uart0_pins_default: wkup-uart0-default-pins {
- bootph-all;
pinctrl-single,pins = <
AM62PX_MCU_IOPAD(0x02c, PIN_INPUT, 0) /* (C7) WKUP_UART0_CTSn */
AM62PX_MCU_IOPAD(0x030, PIN_OUTPUT, 0) /* (C6) WKUP_UART0_RTSn */
AM62PX_MCU_IOPAD(0x024, PIN_INPUT, 0) /* (D8) WKUP_UART0_RXD */
AM62PX_MCU_IOPAD(0x028, PIN_OUTPUT, 0) /* (D7) WKUP_UART0_TXD */
>;
+ bootph-all;
};
};
&wkup_uart0 {
/* WKUP UART0 is used by DM firmware */
- bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&wkup_uart0_pins_default>;
status = "reserved";
+ bootph-all;
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
index 677ff8de4b6e..19f57ead4ebd 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -28,6 +28,7 @@
};
memory@80000000 {
+ bootph-pre-ram;
device_type = "memory";
/* 2G RAM */
reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
@@ -130,6 +131,7 @@
&main_pmx0 {
/* First pad number is ALW package and second is AMC package */
main_uart0_pins_default: main-uart0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x1c8, PIN_INPUT, 0) /* (D14/A13) UART0_RXD */
AM62X_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (E14/E11) UART0_TXD */
@@ -137,6 +139,7 @@
};
main_uart1_pins_default: main-uart1-default-pins {
+ bootph-pre-ram;
pinctrl-single,pins = <
AM62X_IOPAD(0x194, PIN_INPUT, 2) /* (B19/B18) MCASP0_AXR3.UART1_CTSn */
AM62X_IOPAD(0x198, PIN_OUTPUT, 2) /* (A19/B17) MCASP0_AXR2.UART1_RTSn */
@@ -167,6 +170,7 @@
};
main_mmc0_pins_default: main-mmc0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3/V3) MMC0_CMD */
AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1/Y1) MMC0_CLK */
@@ -182,6 +186,7 @@
};
main_mmc1_pins_default: main-mmc1-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (A21/C18) MMC1_CMD */
AM62X_IOPAD(0x234, PIN_INPUT, 0) /* (B22/A20) MMC1_CLK */
@@ -207,6 +212,7 @@
};
main_rgmii1_pins_default: main-rgmii1-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM62X_IOPAD(0x14c, PIN_INPUT, 0) /* (AB17/W15) RGMII1_RD0 */
AM62X_IOPAD(0x150, PIN_INPUT, 0) /* (AC17/Y16) RGMII1_RD1 */
@@ -274,6 +280,7 @@
&mcu_pmx0 {
wkup_uart0_pins_default: wkup-uart0-default-pins {
+ bootph-pre-ram;
pinctrl-single,pins = <
AM62X_MCU_IOPAD(0x02c, PIN_INPUT, 0) /* (C6/A7) WKUP_UART0_CTSn */
AM62X_MCU_IOPAD(0x030, PIN_OUTPUT, 0) /* (A4/B4) WKUP_UART0_RTSn */
@@ -285,12 +292,14 @@
&wkup_uart0 {
/* WKUP UART0 is used by DM firmware */
+ bootph-pre-ram;
status = "reserved";
pinctrl-names = "default";
pinctrl-0 = <&wkup_uart0_pins_default>;
};
&main_uart0 {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_uart0_pins_default>;
@@ -298,6 +307,7 @@
&main_uart1 {
/* Main UART1 is used by TIFS firmware */
+ bootph-pre-ram;
status = "reserved";
pinctrl-names = "default";
pinctrl-0 = <&main_uart1_pins_default>;
@@ -390,6 +400,7 @@
};
&sdhci0 {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_mmc0_pins_default>;
@@ -399,6 +410,7 @@
&sdhci1 {
/* SD/MMC */
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_mmc1_pins_default>;
@@ -407,21 +419,25 @@
};
&cpsw3g {
+ bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&main_rgmii1_pins_default>;
};
&cpsw_port1 {
+ bootph-all;
phy-mode = "rgmii-rxid";
phy-handle = <&cpsw3g_phy0>;
};
&cpsw3g_mdio {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_mdio1_pins_default>;
cpsw3g_phy0: ethernet-phy@0 {
+ bootph-all;
reg = <0>;
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 0df54a741824..0be642bc1b86 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -38,6 +38,7 @@
};
main_conf: syscon@43000000 {
+ bootph-all;
compatible = "ti,j721e-system-controller", "syscon", "simple-mfd";
reg = <0x0 0x43000000 0x0 0x20000>;
#address-cells = <1>;
@@ -45,6 +46,7 @@
ranges = <0x0 0x0 0x43000000 0x20000>;
chipid@14 {
+ bootph-all;
compatible = "ti,am654-chipid";
reg = <0x00000014 0x4>;
};
@@ -96,7 +98,8 @@
};
dmss: bus@48000000 {
- compatible = "simple-mfd";
+ bootph-all;
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
dma-ranges;
@@ -105,6 +108,7 @@
ti,sci-dev-id = <25>;
secure_proxy_main: mailbox@4d000000 {
+ bootph-all;
compatible = "ti,am654-secure-proxy";
#mbox-cells = <1>;
reg-names = "target_data", "rt", "scfg";
@@ -188,6 +192,7 @@
};
dmsc: system-controller@44043000 {
+ bootph-all;
compatible = "ti,k2g-sci";
ti,host-id = <12>;
mbox-names = "rx", "tx";
@@ -197,22 +202,26 @@
reg = <0x00 0x44043000 0x00 0xfe0>;
k3_pds: power-controller {
+ bootph-all;
compatible = "ti,sci-pm-domain";
#power-domain-cells = <2>;
};
k3_clks: clock-controller {
+ bootph-all;
compatible = "ti,k2g-sci-clk";
#clock-cells = <2>;
};
k3_reset: reset-controller {
+ bootph-all;
compatible = "ti,sci-reset";
#reset-cells = <2>;
};
};
main_pmx0: pinctrl@f4000 {
+ bootph-all;
compatible = "pinctrl-single";
reg = <0x00 0xf4000 0x00 0x2d0>;
#pinctrl-cells = <1>;
@@ -221,6 +230,7 @@
};
main_timer0: timer@2400000 {
+ bootph-all;
compatible = "ti,am654-timer";
reg = <0x00 0x2400000 0x00 0x400>;
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
@@ -365,6 +375,7 @@
};
main_esm: esm@420000 {
+ bootph-pre-ram;
compatible = "ti,j721e-esm";
reg = <0x00 0x420000 0x00 0x1000>;
ti,esm-pins = <160>, <161>;
@@ -1158,21 +1169,21 @@
};
main_rti0: watchdog@e000000 {
- compatible = "ti,j7-rti-wdt";
- reg = <0x00 0xe000000 0x00 0x100>;
- clocks = <&k3_clks 125 0>;
- power-domains = <&k3_pds 125 TI_SCI_PD_EXCLUSIVE>;
- assigned-clocks = <&k3_clks 125 0>;
- assigned-clock-parents = <&k3_clks 125 2>;
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0xe000000 0x00 0x100>;
+ clocks = <&k3_clks 125 0>;
+ power-domains = <&k3_pds 125 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 125 0>;
+ assigned-clock-parents = <&k3_clks 125 2>;
};
main_rti1: watchdog@e010000 {
- compatible = "ti,j7-rti-wdt";
- reg = <0x00 0xe010000 0x00 0x100>;
- clocks = <&k3_clks 126 0>;
- power-domains = <&k3_pds 126 TI_SCI_PD_EXCLUSIVE>;
- assigned-clocks = <&k3_clks 126 0>;
- assigned-clock-parents = <&k3_clks 126 2>;
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0xe010000 0x00 0x100>;
+ clocks = <&k3_clks 126 0>;
+ power-domains = <&k3_pds 126 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 126 0>;
+ assigned-clock-parents = <&k3_clks 126 2>;
};
icssg0: icssg@30000000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
index 686d49790721..b9508072bebb 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
@@ -146,6 +146,7 @@
};
mcu_pmx0: pinctrl@4084000 {
+ bootph-all;
compatible = "pinctrl-single";
reg = <0x00 0x4084000 0x00 0x84>;
#pinctrl-cells = <1>;
@@ -154,6 +155,7 @@
};
mcu_esm: esm@4100000 {
+ bootph-pre-ram;
compatible = "ti,j721e-esm";
reg = <0x00 0x4100000 0x00 0x1000>;
ti,esm-pins = <0>, <1>;
diff --git a/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
index 1c2c8f0daca9..f87f09d83c95 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
@@ -126,6 +126,12 @@
AM64X_IOPAD(0x002c, PIN_OUTPUT, 0) /* (L19) OSPI0_CSn0 */
>;
};
+
+ rtc_pins_default: rtc-defaults-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0278, PIN_INPUT, 7) /* (C19) EXTINTn.GPIO1_70 */
+ >;
+ };
};
&cpsw3g {
@@ -177,6 +183,11 @@
i2c_som_rtc: rtc@52 {
compatible = "microcrystal,rv3028";
reg = <0x52>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_pins_default>;
+ interrupt-parent = <&main_gpio1>;
+ interrupts = <70 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-am64.dtsi b/arch/arm64/boot/dts/ti/k3-am64.dtsi
index 8e9c2bc70f4d..0187c42aed4f 100644
--- a/arch/arm64/boot/dts/ti/k3-am64.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64.dtsi
@@ -47,6 +47,7 @@
};
cbass_main: bus@f4000 {
+ bootph-all;
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
@@ -85,6 +86,7 @@
<0x00 0x04000000 0x00 0x04000000 0x00 0x01ff1400>;
cbass_mcu: bus@4000000 {
+ bootph-all;
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index b4a1f73d4fb1..4dba18941015 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -35,6 +35,7 @@
};
memory@80000000 {
+ bootph-all;
device_type = "memory";
/* 2G RAM */
reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
@@ -108,6 +109,7 @@
evm_12v0: regulator-0 {
/* main DC jack */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "evm_12v0";
regulator-min-microvolt = <12000000>;
@@ -129,6 +131,7 @@
vsys_3v3: regulator-2 {
/* output of LM5140 */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vsys_3v3";
regulator-min-microvolt = <3300000>;
@@ -140,6 +143,7 @@
vdd_mmc1: regulator-3 {
/* TPS2051BD */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vdd_mmc1";
regulator-min-microvolt = <3300000>;
@@ -161,6 +165,7 @@
};
vtt_supply: regulator-5 {
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vtt";
pinctrl-names = "default";
@@ -251,6 +256,7 @@
};
main_uart0_pins_default: main-uart0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x0238, PIN_INPUT, 0) /* (B16) UART0_CTSn */
AM64X_IOPAD(0x023c, PIN_OUTPUT, 0) /* (A16) UART0_RTSn */
@@ -269,6 +275,7 @@
};
main_i2c0_pins_default: main-i2c0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x0260, PIN_INPUT_PULLUP, 0) /* (A18) I2C0_SCL */
AM64X_IOPAD(0x0264, PIN_INPUT_PULLUP, 0) /* (B18) I2C0_SDA */
@@ -276,6 +283,7 @@
};
main_i2c1_pins_default: main-i2c1-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x0268, PIN_INPUT_PULLUP, 0) /* (C18) I2C1_SCL */
AM64X_IOPAD(0x026c, PIN_INPUT_PULLUP, 0) /* (B19) I2C1_SDA */
@@ -283,6 +291,7 @@
};
mdio1_pins_default: mdio1-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x01fc, PIN_OUTPUT, 4) /* (R2) PRG0_PRU1_GPO19.MDIO0_MDC */
AM64X_IOPAD(0x01f8, PIN_INPUT, 4) /* (P5) PRG0_PRU1_GPO18.MDIO0_MDIO */
@@ -290,6 +299,7 @@
};
rgmii1_pins_default: rgmii1-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x01cc, PIN_INPUT, 4) /* (W5) PRG0_PRU1_GPO7.RGMII1_RD0 */
AM64X_IOPAD(0x01d4, PIN_INPUT, 4) /* (Y5) PRG0_PRU1_GPO9.RGMII1_RD1 */
@@ -307,6 +317,7 @@
};
rgmii2_pins_default: rgmii2-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x0108, PIN_INPUT, 4) /* (W11) PRG1_PRU1_GPO0.RGMII2_RD0 */
AM64X_IOPAD(0x010c, PIN_INPUT, 4) /* (V11) PRG1_PRU1_GPO1.RGMII2_RD1 */
@@ -324,6 +335,7 @@
};
main_usb0_pins_default: main-usb0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0) /* (E19) USB0_DRVVBUS */
>;
@@ -366,6 +378,7 @@
};
ddr_vtt_pins_default: ddr-vtt-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x0030, PIN_OUTPUT_PULLUP, 7) /* (L18) OSPI0_CSN1.GPIO0_12 */
>;
@@ -373,6 +386,7 @@
};
&main_uart0 {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_uart0_pins_default>;
@@ -387,11 +401,21 @@
};
&main_i2c0 {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_i2c0_pins_default>;
clock-frequency = <400000>;
+ gpio@38 {
+ /* TCA9554 */
+ compatible = "nxp,pca9554";
+ reg = <0x38>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "HSE_DETECT";
+ };
+
eeprom@50 {
/* AT24CM01 */
compatible = "atmel,24c1024";
@@ -400,12 +424,14 @@
};
&main_i2c1 {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_i2c1_pins_default>;
clock-frequency = <400000>;
exp1: gpio@22 {
+ bootph-all;
compatible = "ti,tca6424";
reg = <0x22>;
gpio-controller;
@@ -438,6 +464,10 @@
};
};
+&main_gpio0 {
+ bootph-all;
+};
+
/* mcu_gpio0 is reserved for mcu firmware usage */
&mcu_gpio0 {
status = "reserved";
@@ -467,6 +497,7 @@
&sdhci1 {
/* SD/MMC */
+ bootph-all;
vmmc-supply = <&vdd_mmc1>;
pinctrl-names = "default";
bus-width = <4>;
@@ -476,11 +507,13 @@
};
&usbss0 {
+ bootph-all;
ti,vbus-divider;
ti,usb2-only;
};
&usb0 {
+ bootph-all;
dr_mode = "otg";
maximum-speed = "high-speed";
pinctrl-names = "default";
@@ -488,11 +521,13 @@
};
&cpsw3g {
+ bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&rgmii1_pins_default>, <&rgmii2_pins_default>;
};
&cpsw_port1 {
+ bootph-all;
phy-mode = "rgmii-rxid";
phy-handle = <&cpsw3g_phy0>;
};
@@ -503,11 +538,13 @@
};
&cpsw3g_mdio {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&mdio1_pins_default>;
cpsw3g_phy0: ethernet-phy@0 {
+ bootph-all;
reg = <0>;
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 722fd285a34e..f29c8a9b59ba 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -34,6 +34,7 @@
};
memory@80000000 {
+ bootph-pre-ram;
device_type = "memory";
/* 2G RAM */
reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
@@ -107,6 +108,7 @@
vusb_main: regulator-0 {
/* USB MAIN INPUT 5V DC */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vusb_main5v0";
regulator-min-microvolt = <5000000>;
@@ -117,6 +119,7 @@
vcc_3v3_sys: regulator-1 {
/* output of LP8733xx */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vcc_3v3_sys";
regulator-min-microvolt = <3300000>;
@@ -128,6 +131,7 @@
vdd_mmc1: regulator-2 {
/* TPS2051BD */
+ bootph-all;
compatible = "regulator-fixed";
regulator-name = "vdd_mmc1";
regulator-min-microvolt = <3300000>;
@@ -234,6 +238,7 @@
&main_pmx0 {
main_mmc1_pins_default: main-mmc1-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x029c, PIN_INPUT_PULLUP, 0) /* (C20) MMC1_SDWP */
AM64X_IOPAD(0x0298, PIN_INPUT_PULLUP, 0) /* (D19) MMC1_SDCD */
@@ -248,6 +253,7 @@
};
main_uart0_pins_default: main-uart0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x0238, PIN_INPUT, 0) /* (B16) UART0_CTSn */
AM64X_IOPAD(0x023c, PIN_OUTPUT, 0) /* (A16) UART0_RTSn */
@@ -257,6 +263,7 @@
};
main_uart1_pins_default: main-uart1-default-pins {
+ bootph-pre-ram;
pinctrl-single,pins = <
AM64X_IOPAD(0x0248, PIN_INPUT, 0) /* (D16) UART1_CTSn */
AM64X_IOPAD(0x024c, PIN_OUTPUT, 0) /* (E16) UART1_RTSn */
@@ -266,12 +273,14 @@
};
main_usb0_pins_default: main-usb0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0) /* (E19) USB0_DRVVBUS */
>;
};
main_i2c0_pins_default: main-i2c0-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x0260, PIN_INPUT_PULLUP, 0) /* (A18) I2C0_SCL */
AM64X_IOPAD(0x0264, PIN_INPUT_PULLUP, 0) /* (B18) I2C0_SDA */
@@ -279,6 +288,7 @@
};
main_i2c1_pins_default: main-i2c1-default-pins {
+ bootph-all;
pinctrl-single,pins = <
AM64X_IOPAD(0x0268, PIN_INPUT_PULLUP, 0) /* (C18) I2C1_SCL */
AM64X_IOPAD(0x026c, PIN_INPUT_PULLUP, 0) /* (B19) I2C1_SDA */
@@ -367,6 +377,7 @@
};
&main_uart0 {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_uart0_pins_default>;
@@ -375,12 +386,14 @@
&main_uart1 {
/* main_uart1 is reserved for firmware usage */
+ bootph-pre-ram;
status = "reserved";
pinctrl-names = "default";
pinctrl-0 = <&main_uart1_pins_default>;
};
&main_i2c0 {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_i2c0_pins_default>;
@@ -393,12 +406,14 @@
};
&main_i2c1 {
+ bootph-all;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_i2c1_pins_default>;
clock-frequency = <400000>;
exp1: gpio@70 {
+ bootph-all;
compatible = "nxp,pca9538";
reg = <0x70>;
gpio-controller;
@@ -445,6 +460,7 @@
&sdhci1 {
/* SD/MMC */
+ bootph-all;
vmmc-supply = <&vdd_mmc1>;
pinctrl-names = "default";
bus-width = <4>;
@@ -454,11 +470,22 @@
};
&serdes_ln_ctrl {
+ bootph-all;
idle-states = <AM64_SERDES0_LANE0_USB>;
};
+&serdes_refclk {
+ bootph-all;
+};
+
+&serdes_wiz0 {
+ bootph-all;
+};
+
&serdes0 {
+ bootph-all;
serdes0_usb_link: phy@0 {
+ bootph-all;
reg = <0>;
cdns,num-lanes = <1>;
#phy-cells = <0>;
@@ -468,10 +495,12 @@
};
&usbss0 {
+ bootph-all;
ti,vbus-divider;
};
&usb0 {
+ bootph-all;
dr_mode = "host";
maximum-speed = "super-speed";
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
index 04c15b64f0b7..d95d80076a42 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
@@ -8,6 +8,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/net/ti-dp83867.h>
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/pwm/pwm.h>
@@ -19,6 +20,7 @@
compatible = "tq,am642-tqma6442l-mbax4xxl", "tq,am642-tqma6442l",
"ti,am642";
model = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
+ chassis-type = "embedded";
aliases {
ethernet0 = &cpsw_port1;
@@ -58,12 +60,14 @@
pinctrl-0 = <&mcu_gpio_leds_pins>;
led-0 {
- label = "led0";
gpios = <&mcu_gpio0 8 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
};
led-1 {
- label = "led1";
gpios = <&mcu_gpio0 9 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_INDICATOR;
};
};
@@ -170,7 +174,8 @@
&main_gpio1 {
pinctrl-names = "default";
- pinctrl-0 = <&main_gpio1_hog_pins>;
+ pinctrl-0 = <&main_gpio1_hog_pins>,
+ <&main_gpio1_pru_pins>;
gpio-line-names =
"", "", "", "", /* 0-3 */
"", "", "", "", /* 4-7 */
@@ -545,6 +550,79 @@
>;
};
+ main_gpio1_pru_pins: main-gpio1-pru-pins {
+ pinctrl-single,pins = <
+ /* (Y1) PRG0_PRU0_GPO0.GPIO1_0 */
+ AM64X_IOPAD(0x0160, PIN_INPUT, 7)
+ /* (R4) PRG0_PRU0_GPO1.GPIO1_1 */
+ AM64X_IOPAD(0x0164, PIN_INPUT, 7)
+ /* (U2) PRG0_PRU0_GPO2.GPIO1_2 */
+ AM64X_IOPAD(0x0168, PIN_INPUT, 7)
+ /* (V2) PRG0_PRU0_GPO3.GPIO1_3 */
+ AM64X_IOPAD(0x016c, PIN_INPUT, 7)
+ /* (AA2) PRG0_PRU0_GPO4.GPIO1_4 */
+ AM64X_IOPAD(0x0170, PIN_INPUT, 7)
+ /* (R3) PRG0_PRU0_GPO5.GPIO1_5 */
+ AM64X_IOPAD(0x0174, PIN_INPUT, 7)
+ /* (T3) PRG0_PRU0_GPO6.GPIO1_6 */
+ AM64X_IOPAD(0x0178, PIN_INPUT, 7)
+ /* (T1) PRG0_PRU0_GPO7.GPIO1_7 */
+ AM64X_IOPAD(0x017c, PIN_INPUT, 7)
+ /* (T2) PRG0_PRU0_GPO8.GPIO1_8 */
+ AM64X_IOPAD(0x0180, PIN_INPUT, 7)
+ /* (Y3) PRG0_PRU0_GPO11.GPIO1_11 */
+ AM64X_IOPAD(0x018c, PIN_INPUT, 7)
+ /* (AA3) PRG0_PRU0_GPO12.GPIO1_12 */
+ AM64X_IOPAD(0x0190, PIN_INPUT, 7)
+ /* (R6) PRG0_PRU0_GPO13.GPIO1_13 */
+ AM64X_IOPAD(0x0194, PIN_INPUT, 7)
+ /* (V4) PRG0_PRU0_GPO14.GPIO1_14 */
+ AM64X_IOPAD(0x0198, PIN_INPUT, 7)
+ /* (T5) PRG0_PRU0_GPO15.GPIO1_15 */
+ AM64X_IOPAD(0x019c, PIN_INPUT, 7)
+ /* (U4) PRG0_PRU0_GPO16.GPIO1_16 */
+ AM64X_IOPAD(0x01a0, PIN_INPUT, 7)
+ /* (U1) PRG0_PRU0_GPO17.GPIO1_17 */
+ AM64X_IOPAD(0x01a4, PIN_INPUT, 7)
+ /* (V1) PRG0_PRU0_GPO18.GPIO1_18 */
+ AM64X_IOPAD(0x01a8, PIN_INPUT, 7)
+ /* (W1) PRG0_PRU0_GPO19.GPIO1_19 */
+ AM64X_IOPAD(0x01ac, PIN_INPUT, 7)
+ /* (Y2) PRG0_PRU1_GPO0.GPIO1_20 */
+ AM64X_IOPAD(0x01b0, PIN_INPUT, 7)
+ /* (W2) PRG0_PRU1_GPO1.GPIO1_21 */
+ AM64X_IOPAD(0x01b4, PIN_INPUT, 7)
+ /* (V3) PRG0_PRU1_GPO2.GPIO1_22 */
+ AM64X_IOPAD(0x01b8, PIN_INPUT, 7)
+ /* (T4) PRG0_PRU1_GPO3.GPIO1_23 */
+ AM64X_IOPAD(0x01bc, PIN_INPUT, 7)
+ /* (W3) PRG0_PRU1_GPO4.GPIO1_24 */
+ AM64X_IOPAD(0x01c0, PIN_INPUT, 7)
+ /* (P4) PRG0_PRU1_GPO5.GPIO1_25 */
+ AM64X_IOPAD(0x01c4, PIN_INPUT, 7)
+ /* (R5) PRG0_PRU1_GPO6.GPIO1_26 */
+ AM64X_IOPAD(0x01c8, PIN_INPUT, 7)
+ /* (R1) PRG0_PRU1_GPO8.GPIO1_28 */
+ AM64X_IOPAD(0x01d0, PIN_INPUT, 7)
+ /* (W4) PRG0_PRU1_GPO11.GPIO1_31 */
+ AM64X_IOPAD(0x01dc, PIN_INPUT, 7)
+ /* (Y4) PRG0_PRU1_GPO12.GPIO1_32 */
+ AM64X_IOPAD(0x01e0, PIN_INPUT, 7)
+ /* (T6) PRG0_PRU1_GPO13.GPIO1_33 */
+ AM64X_IOPAD(0x01e4, PIN_INPUT, 7)
+ /* (U6) PRG0_PRU1_GPO14.GPIO1_34 */
+ AM64X_IOPAD(0x01e8, PIN_INPUT, 7)
+ /* (U5) PRG0_PRU1_GPO15.GPIO1_35 */
+ AM64X_IOPAD(0x01ec, PIN_INPUT, 7)
+ /* (AA4) PRG0_PRU1_GPO16.GPIO1_36 */
+ AM64X_IOPAD(0x01f0, PIN_INPUT, 7)
+ /* (P2) PRG0_MDIO0_MDIO.GPIO1_40 */
+ AM64X_IOPAD(0x0200, PIN_INPUT, 7)
+ /* (P3) PRG0_MDIO0_MDC.GPIO1_41 */
+ AM64X_IOPAD(0x0204, PIN_INPUT, 7)
+ >;
+ };
+
main_mcan0_pins: main-mcan0-pins {
pinctrl-single,pins = <
/* (B17) MCAN0_RX */
diff --git a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi
index 6229849b5d96..d82d4a98306a 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi
@@ -85,6 +85,15 @@
no-map;
};
};
+
+ reg_1v8: regulator-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
};
&main_i2c0 {
@@ -96,11 +105,13 @@
tmp1075: temperature-sensor@4a {
compatible = "ti,tmp1075";
reg = <0x4a>;
+ vs-supply = <&reg_1v8>;
};
eeprom0: eeprom@50 {
compatible = "st,24c02", "atmel,24c02";
reg = <0x50>;
+ vcc-supply = <&reg_1v8>;
pagesize = <16>;
read-only;
};
@@ -114,6 +125,7 @@
eeprom1: eeprom@54 {
compatible = "st,24c64", "atmel,24c64";
reg = <0x54>;
+ vcc-supply = <&reg_1v8>;
pagesize = <32>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index bc460033a37a..5ebb87f467de 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -600,7 +600,7 @@
};
main_navss: bus@30800000 {
- compatible = "simple-mfd";
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x0 0x30800000 0x0 0x30800000 0x0 0xbc00000>;
@@ -1151,6 +1151,18 @@
};
};
+ icssg0_iep0: iep@2e000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2e000 0x1000>;
+ clocks = <&icssg0_iepclk_mux>;
+ };
+
+ icssg0_iep1: iep@2f000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2f000 0x1000>;
+ clocks = <&icssg0_iepclk_mux>;
+ };
+
icssg0_mii_rt: mii-rt@32000 {
compatible = "ti,pruss-mii", "syscon";
reg = <0x32000 0x100>;
@@ -1293,6 +1305,18 @@
};
};
+ icssg1_iep0: iep@2e000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2e000 0x1000>;
+ clocks = <&icssg1_iepclk_mux>;
+ };
+
+ icssg1_iep1: iep@2f000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2f000 0x1000>;
+ clocks = <&icssg1_iepclk_mux>;
+ };
+
icssg1_mii_rt: mii-rt@32000 {
compatible = "ti,pruss-mii", "syscon";
reg = <0x32000 0x100>;
@@ -1435,6 +1459,18 @@
};
};
+ icssg2_iep0: iep@2e000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2e000 0x1000>;
+ clocks = <&icssg2_iepclk_mux>;
+ };
+
+ icssg2_iep1: iep@2f000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2f000 0x1000>;
+ clocks = <&icssg2_iepclk_mux>;
+ };
+
icssg2_mii_rt: mii-rt@32000 {
compatible = "ti,pruss-mii", "syscon";
reg = <0x32000 0x100>;
diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
index 1e536dc41f61..edd5cfbec40e 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
@@ -185,7 +185,7 @@
};
mcu_navss: bus@28380000 {
- compatible = "simple-mfd";
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>;
diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
index f5c26e9fba98..1637ec5ab5ed 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
@@ -369,6 +369,13 @@
ti,enable-vout-discharge;
};
+ gpio@38 {
+ compatible = "nxp,pca9554";
+ reg = <0x38>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
pca9554: gpio@39 {
compatible = "nxp,pca9554";
reg = <0x39>;
diff --git a/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
new file mode 100644
index 000000000000..ec8cf20ca3ac
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT overlay for IDK application board on AM654 EVM
+ *
+ * Copyright (C) 2018-2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/net/ti-dp83867.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+ aliases {
+ ethernet1 = "/icssg2-eth/ethernet-ports/port@0";
+ ethernet2 = "/icssg2-eth/ethernet-ports/port@1";
+ };
+
+ /* Ethernet node on PRU-ICSSG2 */
+ icssg2_eth: icssg2-eth {
+ compatible = "ti,am654-icssg-prueth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg2_rgmii_pins_default>;
+ sram = <&msmc_ram>;
+ ti,prus = <&pru2_0>, <&rtu2_0>, <&tx_pru2_0>,
+ <&pru2_1>, <&rtu2_1>, <&tx_pru2_1>;
+ firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
+
+ ti,pruss-gp-mux-sel = <2>, /* MII mode */
+ <2>,
+ <2>,
+ <2>, /* MII mode */
+ <2>,
+ <2>;
+
+ ti,mii-g-rt = <&icssg2_mii_g_rt>;
+ ti,mii-rt = <&icssg2_mii_rt>;
+ ti,iep = <&icssg2_iep0>, <&icssg2_iep1>;
+
+ interrupt-parent = <&icssg2_intc>;
+ interrupts = <24 0 2>, <25 1 3>;
+ interrupt-names = "tx_ts0", "tx_ts1";
+
+ dmas = <&main_udmap 0xc300>, /* egress slice 0 */
+ <&main_udmap 0xc301>, /* egress slice 0 */
+ <&main_udmap 0xc302>, /* egress slice 0 */
+ <&main_udmap 0xc303>, /* egress slice 0 */
+ <&main_udmap 0xc304>, /* egress slice 1 */
+ <&main_udmap 0xc305>, /* egress slice 1 */
+ <&main_udmap 0xc306>, /* egress slice 1 */
+ <&main_udmap 0xc307>, /* egress slice 1 */
+ <&main_udmap 0x4300>, /* ingress slice 0 */
+ <&main_udmap 0x4301>; /* ingress slice 1 */
+
+ dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+ "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+ "rx0", "rx1";
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ icssg2_emac0: port@0 {
+ reg = <0>;
+ phy-handle = <&icssg2_phy0>;
+ phy-mode = "rgmii-id";
+ ti,syscon-rgmii-delay = <&scm_conf 0x4120>;
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ icssg2_emac1: port@1 {
+ reg = <1>;
+ phy-handle = <&icssg2_phy1>;
+ phy-mode = "rgmii-id";
+ ti,syscon-rgmii-delay = <&scm_conf 0x4124>;
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ };
+ };
+};
+
+&main_pmx0 {
+
+ icssg2_mdio_pins_default: icssg2-mdio-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x0094, PIN_INPUT, 2) /* (AC19) PRG2_PRU0_GPO7.PRG2_MDIO0_MDIO */
+ AM65X_IOPAD(0x00c8, PIN_OUTPUT, 2) /* (AE15) PRG2_PRU1_GPO7.PRG2_MDIO0_MDC */
+ >;
+ };
+
+ icssg2_rgmii_pins_default: icssg2-rgmii-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x00ac, PIN_INPUT, 2) /* (AH15) PRG2_PRU1_GPO0.PRG2_RGMII2_RD0 */
+ AM65X_IOPAD(0x00b0, PIN_INPUT, 2) /* (AC16) PRG2_PRU1_GPO1.PRG2_RGMII2_RD1 */
+ AM65X_IOPAD(0x00b4, PIN_INPUT, 2) /* (AD17) PRG2_PRU1_GPO2.PRG2_RGMII2_RD2 */
+ AM65X_IOPAD(0x00b8, PIN_INPUT, 2) /* (AH14) PRG2_PRU1_GPO3.PRG2_RGMII2_RD3 */
+ AM65X_IOPAD(0x00cc, PIN_OUTPUT, 2) /* (AD15) PRG2_PRU1_GPO8.PRG2_RGMII2_TD0 */
+ AM65X_IOPAD(0x00d0, PIN_OUTPUT, 2) /* (AF14) PRG2_PRU1_GPO9.PRG2_RGMII2_TD1 */
+ AM65X_IOPAD(0x00d4, PIN_OUTPUT, 2) /* (AC15) PRG2_PRU1_GPO10.PRG2_RGMII2_TD2 */
+ AM65X_IOPAD(0x00d8, PIN_OUTPUT, 2) /* (AD14) PRG2_PRU1_GPO11.PRG2_RGMII2_TD3 */
+ AM65X_IOPAD(0x00dc, PIN_INPUT, 2) /* (AE14) PRG2_PRU1_GPO16.PRG2_RGMII2_TXC */
+ AM65X_IOPAD(0x00c4, PIN_OUTPUT, 2) /* (AC17) PRG2_PRU1_GPO6.PRG2_RGMII2_TX_CTL */
+ AM65X_IOPAD(0x00c0, PIN_INPUT, 2) /* (AG15) PRG2_PRU1_GPO5.PRG2_RGMII2_RXC */
+ AM65X_IOPAD(0x00bc, PIN_INPUT, 2) /* (AG14) PRG2_PRU1_GPO4.PRG2_RGMII2_RX_CTL */
+
+ AM65X_IOPAD(0x0078, PIN_INPUT, 2) /* (AF18) PRG2_PRU0_GPO0.PRG2_RGMII1_RD0 */
+ AM65X_IOPAD(0x007c, PIN_INPUT, 2) /* (AE18) PRG2_PRU0_GPO1.PRG2_RGMII1_RD1 */
+ AM65X_IOPAD(0x0080, PIN_INPUT, 2) /* (AH17) PRG2_PRU0_GPO2.PRG2_RGMII1_RD2 */
+ AM65X_IOPAD(0x0084, PIN_INPUT, 2) /* (AG18) PRG2_PRU0_GPO3.PRG2_RGMII1_RD3 */
+ AM65X_IOPAD(0x0098, PIN_OUTPUT, 2) /* (AH16) PRG2_PRU0_GPO8.PRG2_RGMII1_TD0 */
+ AM65X_IOPAD(0x009c, PIN_OUTPUT, 2) /* (AG16) PRG2_PRU0_GPO9.PRG2_RGMII1_TD1 */
+ AM65X_IOPAD(0x00a0, PIN_OUTPUT, 2) /* (AF16) PRG2_PRU0_GPO10.PRG2_RGMII1_TD2 */
+ AM65X_IOPAD(0x00a4, PIN_OUTPUT, 2) /* (AE16) PRG2_PRU0_GPO11.PRG2_RGMII1_TD3 */
+ AM65X_IOPAD(0x00a8, PIN_INPUT, 2) /* (AD16) PRG2_PRU0_GPO16.PRG2_RGMII1_TXC */
+ AM65X_IOPAD(0x0090, PIN_OUTPUT, 2) /* (AE17) PRG2_PRU0_GPO6.PRG2_RGMII1_TX_CTL */
+ AM65X_IOPAD(0x008c, PIN_INPUT, 2) /* (AF17) PRG2_PRU0_GPO5.PRG2_RGMII1_RXC */
+ AM65X_IOPAD(0x0088, PIN_INPUT, 2) /* (AG17) PRG2_PRU0_GPO4.PRG2_RGMII1_RX_CTL */
+ >;
+ };
+};
+
+&icssg2_mdio {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg2_mdio_pins_default>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ icssg2_phy0: ethernet-phy@0 {
+ reg = <0>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ };
+
+ icssg2_phy1: ethernet-phy@3 {
+ reg = <3>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am654-idk.dtso b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
new file mode 100644
index 000000000000..150428dfce6f
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT overlay for IDK application board on AM654 EVM
+ *
+ * Copyright (C) 2018-2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/net/ti-dp83867.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+ aliases {
+ ethernet3 = "/icssg0-eth/ethernet-ports/port@0";
+ ethernet4 = "/icssg0-eth/ethernet-ports/port@1";
+ ethernet5 = "/icssg1-eth/ethernet-ports/port@0";
+ ethernet6 = "/icssg1-eth/ethernet-ports/port@1";
+ };
+
+ /* Ethernet node on PRU-ICSSG0 */
+ icssg0_eth: icssg0-eth {
+ compatible = "ti,am654-icssg-prueth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg0_rgmii_pins_default>;
+ sram = <&msmc_ram>;
+ ti,prus = <&pru0_0>, <&rtu0_0>, <&tx_pru0_0>, <&pru0_1>, <&rtu0_1>, <&tx_pru0_1>;
+ firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
+
+ ti,pruss-gp-mux-sel = <2>, /* MII mode */
+ <2>,
+ <2>,
+ <2>, /* MII mode */
+ <2>,
+ <2>;
+
+ ti,mii-g-rt = <&icssg0_mii_g_rt>;
+ ti,mii-rt = <&icssg0_mii_rt>;
+ ti,iep = <&icssg0_iep0>, <&icssg0_iep1>;
+
+ interrupt-parent = <&icssg0_intc>;
+ interrupts = <24 0 2>, <25 1 3>;
+ interrupt-names = "tx_ts0", "tx_ts1";
+
+ dmas = <&main_udmap 0xc100>, /* egress slice 0 */
+ <&main_udmap 0xc101>, /* egress slice 0 */
+ <&main_udmap 0xc102>, /* egress slice 0 */
+ <&main_udmap 0xc103>, /* egress slice 0 */
+ <&main_udmap 0xc104>, /* egress slice 1 */
+ <&main_udmap 0xc105>, /* egress slice 1 */
+ <&main_udmap 0xc106>, /* egress slice 1 */
+ <&main_udmap 0xc107>, /* egress slice 1 */
+
+ <&main_udmap 0x4100>, /* ingress slice 0 */
+ <&main_udmap 0x4101>, /* ingress slice 1 */
+ <&main_udmap 0x4102>, /* mgmnt rsp slice 0 */
+ <&main_udmap 0x4103>; /* mgmnt rsp slice 1 */
+ dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+ "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+ "rx0", "rx1";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ icssg0_emac0: port@0 {
+ reg = <0>;
+ phy-handle = <&icssg0_phy0>;
+ phy-mode = "rgmii-id";
+ ti,syscon-rgmii-delay = <&scm_conf 0x4100>;
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ icssg0_emac1: port@1 {
+ reg = <1>;
+ phy-handle = <&icssg0_phy1>;
+ phy-mode = "rgmii-id";
+ ti,syscon-rgmii-delay = <&scm_conf 0x4104>;
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ };
+ };
+
+ /* Ethernet node on PRU-ICSSG1 */
+ icssg1_eth: icssg1-eth {
+ compatible = "ti,am654-icssg-prueth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg1_rgmii_pins_default>;
+ sram = <&msmc_ram>;
+ ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+ firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
+
+ ti,pruss-gp-mux-sel = <2>, /* MII mode */
+ <2>,
+ <2>,
+ <2>, /* MII mode */
+ <2>,
+ <2>;
+
+ ti,mii-g-rt = <&icssg1_mii_g_rt>;
+ ti,mii-rt = <&icssg1_mii_rt>;
+ ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
+
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <24 0 2>, <25 1 3>;
+ interrupt-names = "tx_ts0", "tx_ts1";
+
+ dmas = <&main_udmap 0xc200>, /* egress slice 0 */
+ <&main_udmap 0xc201>, /* egress slice 0 */
+ <&main_udmap 0xc202>, /* egress slice 0 */
+ <&main_udmap 0xc203>, /* egress slice 0 */
+ <&main_udmap 0xc204>, /* egress slice 1 */
+ <&main_udmap 0xc205>, /* egress slice 1 */
+ <&main_udmap 0xc206>, /* egress slice 1 */
+ <&main_udmap 0xc207>, /* egress slice 1 */
+
+ <&main_udmap 0x4200>, /* ingress slice 0 */
+ <&main_udmap 0x4201>, /* ingress slice 1 */
+ <&main_udmap 0x4202>, /* mgmnt rsp slice 0 */
+ <&main_udmap 0x4203>; /* mgmnt rsp slice 1 */
+ dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+ "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+ "rx0", "rx1";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ icssg1_emac0: port@0 {
+ reg = <0>;
+ phy-handle = <&icssg1_phy0>;
+ phy-mode = "rgmii-id";
+ ti,syscon-rgmii-delay = <&scm_conf 0x4110>;
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ icssg1_emac1: port@1 {
+ reg = <1>;
+ phy-handle = <&icssg1_phy1>;
+ phy-mode = "rgmii-id";
+ ti,syscon-rgmii-delay = <&scm_conf 0x4114>;
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ };
+ };
+};
+
+&main_pmx0 {
+
+ icssg0_mdio_pins_default: icssg0-mdio-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x0294, PIN_INPUT, 0) /* (AE26) PRG0_MDIO0_MDIO */
+ AM65X_IOPAD(0x0298, PIN_OUTPUT, 0) /* (AE28) PRG0_MDIO0_MDC */
+ >;
+ };
+
+ icssg0_rgmii_pins_default: icssg0-rgmii-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x0244, PIN_INPUT, 2) /* (AB28) PRG0_PRU1_GPO0.PRG0_RGMII2_RD0 */
+ AM65X_IOPAD(0x0248, PIN_INPUT, 2) /* (AC28) PRG0_PRU1_GPO1.PRG0_RGMII2_RD1 */
+ AM65X_IOPAD(0x024c, PIN_INPUT, 2) /* (AC27) PRG0_PRU1_GPO2.PRG0_RGMII2_RD2 */
+ AM65X_IOPAD(0x0250, PIN_INPUT, 2) /* (AB26) PRG0_PRU1_GPO3.PRG0_RGMII2_RD3 */
+ AM65X_IOPAD(0x0274, PIN_OUTPUT, 2) /* (AC25) PRG0_PRU1_GPO12.PRG0_RGMII2_TD0 */
+ AM65X_IOPAD(0x0278, PIN_OUTPUT, 2) /* (AD25) PRG0_PRU1_GPO13.PRG0_RGMII2_TD1 */
+ AM65X_IOPAD(0x027c, PIN_OUTPUT, 2) /* (AD24) PRG0_PRU1_GPO14.PRG0_RGMII2_TD2 */
+ AM65X_IOPAD(0x0280, PIN_OUTPUT, 2) /* (AE27) PRG0_PRU1_GPO15.PRG0_RGMII2_TD3 */
+ AM65X_IOPAD(0x0284, PIN_INPUT, 2) /* (AC24) PRG0_PRU1_GPO16.PRG0_RGMII2_TXC */
+ AM65X_IOPAD(0x0270, PIN_OUTPUT, 2) /* (AB24) PRG0_PRU1_GPO11.PRG0_RGMII2_TX_CTL */
+ AM65X_IOPAD(0x025c, PIN_INPUT, 2) /* (AB27) PRG0_PRU1_GPO6.PRG0_RGMII2_RXC */
+ AM65X_IOPAD(0x0254, PIN_INPUT, 2) /* (AA25) PRG0_PRU1_GPO4.PRG0_RGMII2_RX_CTL */
+
+ AM65X_IOPAD(0x01f4, PIN_INPUT, 2) /* (V24) PRG0_PRU0_GPO0.PRG0_RGMII1_RD0 */
+ AM65X_IOPAD(0x01f8, PIN_INPUT, 2) /* (W25) PRG0_PRU0_GPO1.PRG0_RGMII1_RD1 */
+ AM65X_IOPAD(0x01fc, PIN_INPUT, 2) /* (W24) PRG0_PRU0_GPO2.PRG0_RGMII1_RD2 */
+ AM65X_IOPAD(0x0200, PIN_INPUT, 2) /* (AA27) PRG0_PRU0_GPO3.PRG0_RGMII1_RD3 */
+ AM65X_IOPAD(0x0224, PIN_OUTPUT, 2) /* (AD27) PRG0_PRU0_GPO12.PRG0_RGMII1_TD0 */
+ AM65X_IOPAD(0x0228, PIN_OUTPUT, 2) /* (AC26) PRG0_PRU0_GPO13.PRG0_RGMII1_TD1 */
+ AM65X_IOPAD(0x022c, PIN_OUTPUT, 2) /* (AD26) PRG0_PRU0_GPO14.PRG0_RGMII1_TD2 */
+ AM65X_IOPAD(0x0230, PIN_OUTPUT, 2) /* (AA24) PRG0_PRU0_GPO15.PRG0_RGMII1_TD3 */
+ AM65X_IOPAD(0x0234, PIN_INPUT, 2) /* (AD28) PRG0_PRU0_GPO16.PRG0_RGMII1_TXC */
+ AM65X_IOPAD(0x0220, PIN_OUTPUT, 2) /* (AB25) PRG0_PRU0_GPO11.PRG0_RGMII1_TX_CTL */
+ AM65X_IOPAD(0x020c, PIN_INPUT, 2) /* (Y25) PRG0_PRU0_GPO6.PRG0_RGMII1_RXC */
+ AM65X_IOPAD(0x0204, PIN_INPUT, 2) /* (Y24) PRG0_PRU0_GPO4.PRG0_RGMII1_RX_CTL */
+ >;
+ };
+
+ icssg0_iep0_pins_default: icssg0-iep0-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x0240, PIN_INPUT, 2) /* (U24) PRG0_PRU0_GPO19.PRG0_IEP0_EDC_SYNC_OUT0 */
+ >;
+ };
+
+ icssg1_mdio_pins_default: icssg1-mdio-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x0180, PIN_INPUT, 0) /* (AD18) PRG1_MDIO0_MDIO */
+ AM65X_IOPAD(0x0184, PIN_OUTPUT, 0) /* (AH18) PRG1_MDIO0_MDC */
+ >;
+ };
+
+ icssg1_rgmii_pins_default: icssg1-rgmii-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x0130, PIN_INPUT, 2) /* (AH24) PRG1_PRU1_GPO0.PRG1_RGMII2_RD0 */
+ AM65X_IOPAD(0x0134, PIN_INPUT, 2) /* (AH23) PRG1_PRU1_GPO1.PRG1_RGMII2_RD1 */
+ AM65X_IOPAD(0x0138, PIN_INPUT, 2) /* (AG21) PRG1_PRU1_GPO2.PRG1_RGMII2_RD2 */
+ AM65X_IOPAD(0x013c, PIN_INPUT, 2) /* (AH22) PRG1_PRU1_GPO3.PRG1_RGMII2_RD3 */
+ AM65X_IOPAD(0x0160, PIN_OUTPUT, 2) /* (AE20) PRG1_PRU1_GPO12.PRG1_RGMII2_TD0 */
+ AM65X_IOPAD(0x0164, PIN_OUTPUT, 2) /* (AF19) PRG1_PRU1_GPO13.PRG1_RGMII2_TD1 */
+ AM65X_IOPAD(0x0168, PIN_OUTPUT, 2) /* (AH19) PRG1_PRU1_GPO14.PRG1_RGMII2_TD2 */
+ AM65X_IOPAD(0x016c, PIN_OUTPUT, 2) /* (AG19) PRG1_PRU1_GPO15.PRG1_RGMII2_TD3 */
+ AM65X_IOPAD(0x0170, PIN_INPUT, 2) /* (AE19) PRG1_PRU1_GPO16.PRG1_RGMII2_TXC */
+ AM65X_IOPAD(0x015c, PIN_OUTPUT, 2) /* (AC20) PRG1_PRU1_GPO11.PRG1_RGMII2_TX_CTL */
+ AM65X_IOPAD(0x0148, PIN_INPUT, 2) /* (AG22) PRG1_PRU1_GPO6.PRG1_RGMII2_RXC */
+ AM65X_IOPAD(0x0140, PIN_INPUT, 2) /* (AE21) PRG1_PRU1_GPO4.PRG1_RGMII2_RX_CTL */
+
+ AM65X_IOPAD(0x00e0, PIN_INPUT, 2) /* (AE22) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+ AM65X_IOPAD(0x00e4, PIN_INPUT, 2) /* (AG24) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+ AM65X_IOPAD(0x00e8, PIN_INPUT, 2) /* (AF23) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+ AM65X_IOPAD(0x00ec, PIN_INPUT, 2) /* (AD21) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+ AM65X_IOPAD(0x0110, PIN_OUTPUT, 2) /* (AH20) PRG1_PRU0_GPO12.PRG1_RGMII1_TD0 */
+ AM65X_IOPAD(0x0114, PIN_OUTPUT, 2) /* (AH21) PRG1_PRU0_GPO13.PRG1_RGMII1_TD1 */
+ AM65X_IOPAD(0x0118, PIN_OUTPUT, 2) /* (AG20) PRG1_PRU0_GPO14.PRG1_RGMII1_TD2 */
+ AM65X_IOPAD(0x011c, PIN_OUTPUT, 2) /* (AD19) PRG1_PRU0_GPO15.PRG1_RGMII1_TD3 */
+ AM65X_IOPAD(0x0120, PIN_INPUT, 2) /* (AD20) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+ AM65X_IOPAD(0x010c, PIN_OUTPUT, 2) /* (AF21) PRG1_PRU0_GPO11.PRG1_RGMII1_TX_CTL */
+ AM65X_IOPAD(0x00f8, PIN_INPUT, 2) /* (AF22) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+ AM65X_IOPAD(0x00f0, PIN_INPUT, 2) /* (AG23) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+ >;
+ };
+
+ icssg1_iep0_pins_default: icssg1-iep0-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x012c, PIN_INPUT, 2) /* (AG26) PRG1_PRU0_GPO19.PRG1_IEP0_EDC_SYNC_OUT0 */
+ >;
+ };
+};
+
+&icssg0_mdio {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg0_mdio_pins_default>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ icssg0_phy0: ethernet-phy@0 {
+ reg = <0>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ };
+
+ icssg0_phy1: ethernet-phy@3 {
+ reg = <3>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ };
+};
+
+&icssg0_iep0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg0_iep0_pins_default>;
+};
+
+&icssg1_mdio {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg1_mdio_pins_default>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ icssg1_phy0: ethernet-phy@0 {
+ reg = <0>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ };
+
+ icssg1_phy1: ethernet-phy@3 {
+ reg = <3>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ };
+};
+
+&icssg1_iep0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg1_iep0_pins_default>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
index 5df5946687b3..1e1a82f9d2b8 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
@@ -553,3 +553,59 @@
};
};
};
+
+&serdes_ln_ctrl {
+ idle-states = <J721S2_SERDES0_LANE0_PCIE1_LANE0>, <J721S2_SERDES0_LANE1_PCIE1_LANE1>,
+ <J721S2_SERDES0_LANE2_USB_SWAP>, <J721S2_SERDES0_LANE3_USB>;
+};
+
+&serdes_refclk {
+ clock-frequency = <100000000>;
+};
+
+&serdes0 {
+ status = "okay";
+
+ serdes0_pcie_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <2>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_PCIE>;
+ resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>;
+ };
+
+ serdes0_usb_link: phy@2 {
+ status = "okay";
+ reg = <2>;
+ cdns,num-lanes = <1>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_USB3>;
+ resets = <&serdes_wiz0 3>;
+ };
+};
+
+&pcie1_rc {
+ status = "okay";
+ reset-gpios = <&exp1 10 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes0_pcie_link>;
+ phy-names = "pcie-phy";
+ num-lanes = <2>;
+};
+
+&usb_serdes_mux {
+ idle-states = <0>; /* USB0 to SERDES lane 2 */
+};
+
+&usbss0 {
+ status = "okay";
+ pinctrl-0 = <&main_usbss0_pins_default>;
+ pinctrl-names = "default";
+ ti,vbus-divider;
+};
+
+&usb0 {
+ dr_mode = "host";
+ maximum-speed = "super-speed";
+ phys = <&serdes0_usb_link>;
+ phy-names = "cdns3,usb3-phy";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
index 6c9139f73201..20861a0a46b0 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
@@ -25,6 +25,108 @@
reg = <0x00 0x9e800000 0x00 0x01800000>;
no-map;
};
+
+ mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0000000 0x00 0x100000>;
+ no-map;
+ };
+
+ mcu_r5fss0_core0_memory_region: r5f-memory@a0100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ mcu_r5fss0_core1_dma_memory_region: r5f-dma-memory@a1000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa1000000 0x00 0x100000>;
+ no-map;
+ };
+
+ mcu_r5fss0_core1_memory_region: r5f-memory@a1100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa1100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss0_core0_dma_memory_region: r5f-dma-memory@a2000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa2000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss0_core0_memory_region: r5f-memory@a2100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa2100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss0_core1_dma_memory_region: r5f-dma-memory@a3000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa3000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss0_core1_memory_region: r5f-memory@a3100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa3100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss1_core0_dma_memory_region: r5f-dma-memory@a4000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa4000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss1_core0_memory_region: r5f-memory@a4100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa4100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss1_core1_dma_memory_region: r5f-dma-memory@a5000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa5000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss1_core1_memory_region: r5f-memory@a5100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa5100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ c71_0_dma_memory_region: c71-dma-memory@a6000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa6000000 0x00 0x100000>;
+ no-map;
+ };
+
+ c71_0_memory_region: c71-memory@a6100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa6100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ c71_1_dma_memory_region: c71-dma-memory@a7000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa7000000 0x00 0x100000>;
+ no-map;
+ };
+
+ c71_1_memory_region: c71-memory@a7100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa7100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ rtos_ipc_memory_region: ipc-memories@a8000000 {
+ reg = <0x00 0xa8000000 0x00 0x01c00000>;
+ alignment = <0x1000>;
+ no-map;
+ };
};
};
@@ -49,3 +151,109 @@
reg = <0x51>;
};
};
+
+&mailbox0_cluster0 {
+ status = "okay";
+ interrupts = <436>;
+ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster1 {
+ status = "okay";
+ interrupts = <432>;
+ mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster2 {
+ status = "okay";
+ interrupts = <428>;
+ mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster4 {
+ status = "okay";
+ interrupts = <420>;
+ mbox_c71_0: mbox-c71-0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_c71_1: mbox-c71-1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mcu_r5fss0_core0 {
+ mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
+ <&mcu_r5fss0_core0_memory_region>;
+};
+
+&mcu_r5fss0_core1 {
+ mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
+ <&mcu_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss0_core0 {
+ mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ memory-region = <&main_r5fss0_core0_dma_memory_region>,
+ <&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+ mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ memory-region = <&main_r5fss0_core1_dma_memory_region>,
+ <&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+ mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core0>;
+ memory-region = <&main_r5fss1_core0_dma_memory_region>,
+ <&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+ mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core1>;
+ memory-region = <&main_r5fss1_core1_dma_memory_region>,
+ <&main_r5fss1_core1_memory_region>;
+};
+
+&c71_0 {
+ status = "okay";
+ mboxes = <&mailbox0_cluster4>, <&mbox_c71_0>;
+ memory-region = <&c71_0_dma_memory_region>,
+ <&c71_0_memory_region>;
+};
+
+&c71_1 {
+ status = "okay";
+ mboxes = <&mailbox0_cluster4>, <&mbox_c71_1>;
+ memory-region = <&c71_1_dma_memory_region>,
+ <&c71_1_memory_region>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 06993709111e..9868c7049bfb 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -47,6 +47,150 @@
reg = <0x00 0x9e800000 0x00 0x01800000>;
no-map;
};
+
+ mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0000000 0x00 0x100000>;
+ no-map;
+ };
+
+ mcu_r5fss0_core0_memory_region: r5f-memory@a0100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ mcu_r5fss0_core1_dma_memory_region: r5f-dma-memory@a1000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa1000000 0x00 0x100000>;
+ no-map;
+ };
+
+ mcu_r5fss0_core1_memory_region: r5f-memory@a1100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa1100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss0_core0_dma_memory_region: r5f-dma-memory@a2000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa2000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss0_core0_memory_region: r5f-memory@a2100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa2100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss0_core1_dma_memory_region: r5f-dma-memory@a3000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa3000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss0_core1_memory_region: r5f-memory@a3100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa3100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss1_core0_dma_memory_region: r5f-dma-memory@a4000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa4000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss1_core0_memory_region: r5f-memory@a4100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa4100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss1_core1_dma_memory_region: r5f-dma-memory@a5000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa5000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss1_core1_memory_region: r5f-memory@a5100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa5100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss2_core0_dma_memory_region: r5f-dma-memory@a6000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa6000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss2_core0_memory_region: r5f-memory@a6100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa6100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss2_core1_dma_memory_region: r5f-dma-memory@a7000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa7000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss2_core1_memory_region: r5f-memory@a7100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa7100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ c71_0_dma_memory_region: c71-dma-memory@a8000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa8000000 0x00 0x100000>;
+ no-map;
+ };
+
+ c71_0_memory_region: c71-memory@a8100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa8100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ c71_1_dma_memory_region: c71-dma-memory@a9000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa9000000 0x00 0x100000>;
+ no-map;
+ };
+
+ c71_1_memory_region: c71-memory@a9100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa9100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ c71_2_dma_memory_region: c71-dma-memory@aa000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xaa000000 0x00 0x100000>;
+ no-map;
+ };
+
+ c71_2_memory_region: c71-memory@aa100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xaa100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ c71_3_dma_memory_region: c71-dma-memory@ab000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xab000000 0x00 0x100000>;
+ no-map;
+ };
+
+ c71_3_memory_region: c71-memory@ab100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xab100000 0x00 0xf00000>;
+ no-map;
+ };
};
vusb_main: regulator-vusb-main5v0 {
@@ -107,6 +251,76 @@
states = <1800000 0x0>,
<3300000 0x1>;
};
+
+ dp0_pwr_3v3: regulator-dp0-pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "dp0-pwr";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp_pwr_en_pins_default>;
+ gpio = <&main_gpio0 4 0>; /* DP0_3V3 _EN */
+ enable-active-high;
+ };
+
+ dp0: connector-dp0 {
+ compatible = "dp-connector";
+ label = "DP0";
+ type = "full-size";
+ dp-pwr-supply = <&dp0_pwr_3v3>;
+
+ port {
+ dp0_connector_in: endpoint {
+ remote-endpoint = <&dp0_out>;
+ };
+ };
+ };
+
+ connector-hdmi {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+ type = "a";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd_pins_default>;
+ ddc-i2c-bus = <&mcu_i2c1>;
+ hpd-gpios = <&main_gpio0 0 GPIO_ACTIVE_HIGH>; /* HDMI_HPD */
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+
+ bridge-dvi {
+ compatible = "ti,tfp410";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_pdn_pins_default>;
+ powerdown-gpios = <&wkup_gpio0 14 GPIO_ACTIVE_LOW>; /* HDMI_PDn */
+ ti,deskew = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint {
+ remote-endpoint = <&dpi1_out0>;
+ pclk-sample = <1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+ };
};
&main_pmx0 {
@@ -164,6 +378,57 @@
J784S4_IOPAD(0x004, PIN_INPUT, 7) /* (AG36) MCAN12_TX.GPIO0_1 */
>;
};
+
+ dp0_pins_default: dp0-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x014, PIN_INPUT, 13) /* (AG33) MCAN14_TX.DP0_HPD */
+ >;
+ };
+
+ dp_pwr_en_pins_default: dp-pwr-en-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x010, PIN_INPUT, 7) /* (AH33) MCAN13_RX.GPIO0_4 */
+ >;
+ };
+
+ dss_vout0_pins_default: dss-vout0-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x074, PIN_OUTPUT, 2) /* (AC33) MCAN2_TX.VOUT0_DATA0 */
+ J784S4_IOPAD(0x070, PIN_OUTPUT, 2) /* (AH38) MCAN1_RX.VOUT0_DATA1 */
+ J784S4_IOPAD(0x07c, PIN_OUTPUT, 2) /* (AJ38) MCASP0_AXR3.VOUT0_DATA2 */
+ J784S4_IOPAD(0x068, PIN_OUTPUT, 2) /* (AE38) MCAN0_RX.VOUT0_DATA3 */
+ J784S4_IOPAD(0x064, PIN_OUTPUT, 2) /* (AF38) MCAN0_TX.VOUT0_DATA4 */
+ J784S4_IOPAD(0x060, PIN_OUTPUT, 2) /* (AE36) MCASP2_AXR1.VOUT0_DATA5 */
+ J784S4_IOPAD(0x05c, PIN_OUTPUT, 2) /* (AC36) MCASP2_AXR0.VOUT0_DATA6 */
+ J784S4_IOPAD(0x058, PIN_OUTPUT, 2) /* (AE37) MCASP2_AFSX.VOUT0_DATA7 */
+ J784S4_IOPAD(0x054, PIN_OUTPUT, 2) /* (AD37) MCASP2_ACLKX.VOUT0_DATA8 */
+ J784S4_IOPAD(0x050, PIN_OUTPUT, 2) /* (AC37) MCASP1_AXR2.VOUT0_DATA9 */
+ J784S4_IOPAD(0x04c, PIN_OUTPUT, 2) /* (AC32) MCASP1_AXR1.VOUT0_DATA10 */
+ J784S4_IOPAD(0x048, PIN_OUTPUT, 2) /* (AK33) MCASP0_AXR2.VOUT0_DATA11 */
+ J784S4_IOPAD(0x044, PIN_OUTPUT, 2) /* (AG37) MCASP0_AXR1.VOUT0_DATA12 */
+ J784S4_IOPAD(0x040, PIN_OUTPUT, 2) /* (AF37) MCASP0_AXR0.VOUT0_DATA13 */
+ J784S4_IOPAD(0x03c, PIN_OUTPUT, 2) /* (AK38) MCASP0_AFSX.VOUT0_DATA14 */
+ J784S4_IOPAD(0x038, PIN_OUTPUT, 2) /* (AK35) MCASP0_ACLKX.VOUT0_DATA15 */
+ J784S4_IOPAD(0x0c8, PIN_OUTPUT, 2) /* (AJ32) EXT_REFCLK1.VOUT0_DATA16 */
+ J784S4_IOPAD(0x030, PIN_OUTPUT, 2) /* (AK37) GPIO0_12.VOUT0_DATA17 */
+ J784S4_IOPAD(0x02c, PIN_OUTPUT, 2) /* (AL32) GPIO0_11.VOUT0_DATA18 */
+ J784S4_IOPAD(0x028, PIN_OUTPUT, 2) /* (AE33) MCAN16_RX.VOUT0_DATA19 */
+ J784S4_IOPAD(0x024, PIN_OUTPUT, 2) /* (AH34) MCAN16_TX.VOUT0_DATA20 */
+ J784S4_IOPAD(0x020, PIN_OUTPUT, 2) /* (AJ35) MCAN15_RX.VOUT0_DATA21 */
+ J784S4_IOPAD(0x01c, PIN_OUTPUT, 2) /* (AG34) MCAN15_TX.VOUT0_DATA22 */
+ J784S4_IOPAD(0x018, PIN_OUTPUT, 2) /* (AK36) MCAN14_RX.VOUT0_DATA23 */
+ J784S4_IOPAD(0x084, PIN_OUTPUT, 2) /* (AG38) MCASP0_AXR5.VOUT0_DE */
+ J784S4_IOPAD(0x080, PIN_OUTPUT, 2) /* (AK34) MCASP0_AXR4.VOUT0_HSYNC */
+ J784S4_IOPAD(0x078, PIN_OUTPUT, 2) /* (AH37) MCAN2_RX.VOUT0_PCLK */
+ J784S4_IOPAD(0x088, PIN_OUTPUT, 2) /* (AF36) MCASP0_AXR6.VOUT0_VSYNC */
+ >;
+ };
+
+ hdmi_hpd_pins_default: hdmi-hpd-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x000, PIN_INPUT, 7) /* (AN35) EXTINTN.GPIO0_0 */
+ >;
+ };
};
&wkup_pmx2 {
@@ -238,6 +503,21 @@
J784S4_WKUP_IOPAD(0x11c, PIN_INPUT, 7) /* (M34) WKUP_GPIO0_67 */
>;
};
+
+ mcu_i2c1_pins_default: mcu-i2c1-default-pins {
+ pinctrl-single,pins = <
+ /* (L35) WKUP_GPIO0_8.MCU_I2C1_SCL */
+ J784S4_WKUP_IOPAD(0x078, PIN_INPUT_PULLUP, 0)
+ /* (L34) WKUP_GPIO0_9.MCU_I2C1_SDA */
+ J784S4_WKUP_IOPAD(0x07c, PIN_INPUT_PULLUP, 0)
+ >;
+ };
+
+ hdmi_pdn_pins_default: hdmi-pdn-default-pins {
+ pinctrl-single,pins = <
+ J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 7) /* (H37) WKUP_GPIO0_14 */
+ >;
+ };
};
&wkup_pmx3 {
@@ -248,6 +528,90 @@
};
};
+&mailbox0_cluster0 {
+ status = "okay";
+ interrupts = <436>;
+ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster1 {
+ status = "okay";
+ interrupts = <432>;
+ mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster2 {
+ status = "okay";
+ interrupts = <428>;
+ mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster3 {
+ status = "okay";
+ interrupts = <424>;
+ mbox_main_r5fss2_core0: mbox-main-r5fss2-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_main_r5fss2_core1: mbox-main-r5fss2-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster4 {
+ status = "okay";
+ interrupts = <420>;
+ mbox_c71_0: mbox-c71-0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_c71_1: mbox-c71-1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster5 {
+ status = "okay";
+ interrupts = <416>;
+ mbox_c71_2: mbox-c71-2 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_c71_3: mbox-c71-3 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
&wkup_uart0 {
/* Firmware usage */
status = "reserved";
@@ -362,3 +726,175 @@
phy-mode = "rgmii-rxid";
phy-handle = <&mcu_phy0>;
};
+
+&mcu_r5fss0_core0 {
+ mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
+ <&mcu_r5fss0_core0_memory_region>;
+};
+
+&mcu_r5fss0_core1 {
+ mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
+ <&mcu_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss0_core0 {
+ mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ memory-region = <&main_r5fss0_core0_dma_memory_region>,
+ <&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+ mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ memory-region = <&main_r5fss0_core1_dma_memory_region>,
+ <&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+ mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core0>;
+ memory-region = <&main_r5fss1_core0_dma_memory_region>,
+ <&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+ mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core1>;
+ memory-region = <&main_r5fss1_core1_dma_memory_region>,
+ <&main_r5fss1_core1_memory_region>;
+};
+
+&main_r5fss2_core0 {
+ mboxes = <&mailbox0_cluster3>, <&mbox_main_r5fss2_core0>;
+ memory-region = <&main_r5fss2_core0_dma_memory_region>,
+ <&main_r5fss2_core0_memory_region>;
+};
+
+&main_r5fss2_core1 {
+ mboxes = <&mailbox0_cluster3>, <&mbox_main_r5fss2_core1>;
+ memory-region = <&main_r5fss2_core1_dma_memory_region>,
+ <&main_r5fss2_core1_memory_region>;
+};
+
+&c71_0 {
+ status = "okay";
+ mboxes = <&mailbox0_cluster4>, <&mbox_c71_0>;
+ memory-region = <&c71_0_dma_memory_region>,
+ <&c71_0_memory_region>;
+};
+
+&c71_1 {
+ status = "okay";
+ mboxes = <&mailbox0_cluster4>, <&mbox_c71_1>;
+ memory-region = <&c71_1_dma_memory_region>,
+ <&c71_1_memory_region>;
+};
+
+&c71_2 {
+ status = "okay";
+ mboxes = <&mailbox0_cluster5>, <&mbox_c71_2>;
+ memory-region = <&c71_2_dma_memory_region>,
+ <&c71_2_memory_region>;
+};
+
+&c71_3 {
+ status = "okay";
+ mboxes = <&mailbox0_cluster5>, <&mbox_c71_3>;
+ memory-region = <&c71_3_dma_memory_region>,
+ <&c71_3_memory_region>;
+};
+
+&wkup_gpio_intr {
+ status = "okay";
+};
+
+&mcu_i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_i2c1_pins_default>;
+ clock-frequency = <100000>;
+};
+
+&serdes_refclk {
+ status = "okay";
+ clock-frequency = <100000000>;
+};
+
+&dss {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_vout0_pins_default>;
+ assigned-clocks = <&k3_clks 218 2>,
+ <&k3_clks 218 5>,
+ <&k3_clks 218 14>,
+ <&k3_clks 218 18>;
+ assigned-clock-parents = <&k3_clks 218 3>,
+ <&k3_clks 218 7>,
+ <&k3_clks 218 16>,
+ <&k3_clks 218 22>;
+};
+
+&serdes_wiz4 {
+ status = "okay";
+};
+
+&serdes4 {
+ status = "okay";
+ serdes4_dp_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <4>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_DP>;
+ resets = <&serdes_wiz4 1>, <&serdes_wiz4 2>,
+ <&serdes_wiz4 3>, <&serdes_wiz4 4>;
+ };
+};
+
+&mhdp {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp0_pins_default>;
+ phys = <&serdes4_dp_link>;
+ phy-names = "dpphy";
+};
+
+&dss_ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* DP */
+ port@0 {
+ reg = <0>;
+
+ dpi0_out: endpoint {
+ remote-endpoint = <&dp0_in>;
+ };
+ };
+
+ /* HDMI */
+ port@1 {
+ reg = <1>;
+
+ dpi1_out0: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ };
+ };
+};
+
+&dp0_ports {
+
+ port@0 {
+ reg = <0>;
+
+ dp0_in: endpoint {
+ remote-endpoint = <&dpi0_out>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+
+ dp0_out: endpoint {
+ remote-endpoint = <&dp0_connector_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
index cdb1d6b2a982..264913f83287 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -91,7 +91,7 @@
};
main_navss: bus@30000000 {
- compatible = "simple-mfd";
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>;
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
index 6ffaf85fa63f..3fc588b848c6 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
@@ -318,7 +318,7 @@
};
mcu_navss: bus@28380000 {
- compatible = "simple-mfd";
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>;
@@ -637,4 +637,11 @@
power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
#thermal-sensor-cells = <1>;
};
+
+ mcu_esm: esm@40800000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x40800000 0x00 0x1000>;
+ ti,esm-pins = <95>;
+ bootph-pre-ram;
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index f6c7e1614521..746b9f8b1c64 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -181,7 +181,7 @@
};
main_navss: bus@30000000 {
- compatible = "simple-mfd";
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>;
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
index 05d6ef127ba7..f7ab7719fc07 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
@@ -440,7 +440,7 @@
};
mcu_navss: bus@28380000 {
- compatible = "simple-mfd";
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>;
@@ -671,4 +671,11 @@
power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
#thermal-sensor-cells = <1>;
};
+
+ mcu_esm: esm@40800000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x40800000 0x00 0x1000>;
+ ti,esm-pins = <95>;
+ bootph-pre-ram;
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index 084f8f5b6699..b03731b53a26 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -775,7 +775,7 @@
};
main_navss: bus@30000000 {
- compatible = "simple-mfd";
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>;
@@ -807,6 +807,7 @@
ti,sci = <&sms>;
ti,sci-dev-id = <265>;
ti,interrupt-ranges = <0 0 256>;
+ ti,unmapped-event-sources = <&main_bcdma_csi>;
};
secure_proxy_main: mailbox@32c00000 {
@@ -1103,6 +1104,22 @@
ti,sci-rm-range-rflow = <0x00>; /* GP RFLOW */
};
+ main_bcdma_csi: dma-controller@311a0000 {
+ compatible = "ti,j721s2-dmss-bcdma-csi";
+ reg = <0x00 0x311a0000 0x00 0x100>,
+ <0x00 0x35d00000 0x00 0x20000>,
+ <0x00 0x35c00000 0x00 0x10000>,
+ <0x00 0x35e00000 0x00 0x80000>;
+ reg-names = "gcfg", "rchanrt", "tchanrt", "ringrt";
+ msi-parent = <&main_udmass_inta>;
+ #dma-cells = <3>;
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <225>;
+ ti,sci-rm-range-rchan = <0x21>;
+ ti,sci-rm-range-tchan = <0x22>;
+ status = "disabled";
+ };
+
cpts@310d0000 {
compatible = "ti,j721e-cpts";
reg = <0x0 0x310d0000 0x0 0x400>;
@@ -1695,4 +1712,217 @@
dss_ports: ports {
};
};
+
+ main_r5fss0: r5fss@5c00000 {
+ compatible = "ti,j721s2-r5fss";
+ ti,cluster-mode = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x5c00000 0x00 0x5c00000 0x20000>,
+ <0x5d00000 0x00 0x5d00000 0x20000>;
+ power-domains = <&k3_pds 277 TI_SCI_PD_EXCLUSIVE>;
+
+ main_r5fss0_core0: r5f@5c00000 {
+ compatible = "ti,j721s2-r5f";
+ reg = <0x5c00000 0x00010000>,
+ <0x5c10000 0x00010000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <279>;
+ ti,sci-proc-ids = <0x06 0xff>;
+ resets = <&k3_reset 279 1>;
+ firmware-name = "j721s2-main-r5f0_0-fw";
+ ti,atcm-enable = <1>;
+ ti,btcm-enable = <1>;
+ ti,loczrama = <1>;
+ };
+
+ main_r5fss0_core1: r5f@5d00000 {
+ compatible = "ti,j721s2-r5f";
+ reg = <0x5d00000 0x00010000>,
+ <0x5d10000 0x00010000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <280>;
+ ti,sci-proc-ids = <0x07 0xff>;
+ resets = <&k3_reset 280 1>;
+ firmware-name = "j721s2-main-r5f0_1-fw";
+ ti,atcm-enable = <1>;
+ ti,btcm-enable = <1>;
+ ti,loczrama = <1>;
+ };
+ };
+
+ main_r5fss1: r5fss@5e00000 {
+ compatible = "ti,j721s2-r5fss";
+ ti,cluster-mode = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x5e00000 0x00 0x5e00000 0x20000>,
+ <0x5f00000 0x00 0x5f00000 0x20000>;
+ power-domains = <&k3_pds 278 TI_SCI_PD_EXCLUSIVE>;
+
+ main_r5fss1_core0: r5f@5e00000 {
+ compatible = "ti,j721s2-r5f";
+ reg = <0x5e00000 0x00010000>,
+ <0x5e10000 0x00010000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <281>;
+ ti,sci-proc-ids = <0x08 0xff>;
+ resets = <&k3_reset 281 1>;
+ firmware-name = "j721s2-main-r5f1_0-fw";
+ ti,atcm-enable = <1>;
+ ti,btcm-enable = <1>;
+ ti,loczrama = <1>;
+ };
+
+ main_r5fss1_core1: r5f@5f00000 {
+ compatible = "ti,j721s2-r5f";
+ reg = <0x5f00000 0x00010000>,
+ <0x5f10000 0x00010000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <282>;
+ ti,sci-proc-ids = <0x09 0xff>;
+ resets = <&k3_reset 282 1>;
+ firmware-name = "j721s2-main-r5f1_1-fw";
+ ti,atcm-enable = <1>;
+ ti,btcm-enable = <1>;
+ ti,loczrama = <1>;
+ };
+ };
+
+ c71_0: dsp@64800000 {
+ compatible = "ti,j721s2-c71-dsp";
+ reg = <0x00 0x64800000 0x00 0x00080000>,
+ <0x00 0x64e00000 0x00 0x0000c000>;
+ reg-names = "l2sram", "l1dram";
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <8>;
+ ti,sci-proc-ids = <0x30 0xff>;
+ resets = <&k3_reset 8 1>;
+ firmware-name = "j721s2-c71_0-fw";
+ status = "disabled";
+ };
+
+ c71_1: dsp@65800000 {
+ compatible = "ti,j721s2-c71-dsp";
+ reg = <0x00 0x65800000 0x00 0x00080000>,
+ <0x00 0x65e00000 0x00 0x0000c000>;
+ reg-names = "l2sram", "l1dram";
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <11>;
+ ti,sci-proc-ids = <0x31 0xff>;
+ resets = <&k3_reset 11 1>;
+ firmware-name = "j721s2-c71_1-fw";
+ status = "disabled";
+ };
+
+ main_esm: esm@700000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x700000 0x00 0x1000>;
+ ti,esm-pins = <688>, <689>;
+ bootph-pre-ram;
+ };
+
+ watchdog0: watchdog@2200000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2200000 0x00 0x100>;
+ clocks = <&k3_clks 286 1>;
+ power-domains = <&k3_pds 286 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 286 1>;
+ assigned-clock-parents = <&k3_clks 286 5>;
+ };
+
+ watchdog1: watchdog@2210000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2210000 0x00 0x100>;
+ clocks = <&k3_clks 287 1>;
+ power-domains = <&k3_pds 287 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 287 1>;
+ assigned-clock-parents = <&k3_clks 287 5>;
+ };
+
+ /*
+ * The following RTI instances are coupled with MCU R5Fs, c7x and
+ * GPU so keeping them reserved as these will be used by their
+ * respective firmware
+ */
+ watchdog2: watchdog@22f0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x22f0000 0x00 0x100>;
+ clocks = <&k3_clks 290 1>;
+ power-domains = <&k3_pds 290 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 290 1>;
+ assigned-clock-parents = <&k3_clks 290 5>;
+ /* reserved for GPU */
+ status = "reserved";
+ };
+
+ watchdog3: watchdog@2300000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2300000 0x00 0x100>;
+ clocks = <&k3_clks 288 1>;
+ power-domains = <&k3_pds 288 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 288 1>;
+ assigned-clock-parents = <&k3_clks 288 5>;
+ /* reserved for C7X_0 */
+ status = "reserved";
+ };
+
+ watchdog4: watchdog@2310000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2310000 0x00 0x100>;
+ clocks = <&k3_clks 289 1>;
+ power-domains = <&k3_pds 289 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 289 1>;
+ assigned-clock-parents = <&k3_clks 289 5>;
+ /* reserved for C7X_1 */
+ status = "reserved";
+ };
+
+ watchdog5: watchdog@23c0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x23c0000 0x00 0x100>;
+ clocks = <&k3_clks 291 1>;
+ power-domains = <&k3_pds 291 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 291 1>;
+ assigned-clock-parents = <&k3_clks 291 5>;
+ /* reserved for MAIN_R5F0_0 */
+ status = "reserved";
+ };
+
+ watchdog6: watchdog@23d0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x23d0000 0x00 0x100>;
+ clocks = <&k3_clks 292 1>;
+ power-domains = <&k3_pds 292 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 292 1>;
+ assigned-clock-parents = <&k3_clks 292 5>;
+ /* reserved for MAIN_R5F0_1 */
+ status = "reserved";
+ };
+
+ watchdog7: watchdog@23e0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x23e0000 0x00 0x100>;
+ clocks = <&k3_clks 293 1>;
+ power-domains = <&k3_pds 293 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 293 1>;
+ assigned-clock-parents = <&k3_clks 293 5>;
+ /* reserved for MAIN_R5F1_0 */
+ status = "reserved";
+ };
+
+ watchdog8: watchdog@23f0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x23f0000 0x00 0x100>;
+ clocks = <&k3_clks 294 1>;
+ power-domains = <&k3_pds 294 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 294 1>;
+ assigned-clock-parents = <&k3_clks 294 5>;
+ /* reserved for MAIN_R5F1_1 */
+ status = "reserved";
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
index 2ddad9318554..7254f3bd3634 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
@@ -443,7 +443,7 @@
};
mcu_navss: bus@28380000 {
- compatible = "simple-mfd";
+ compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>;
@@ -655,4 +655,84 @@
power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>;
#thermal-sensor-cells = <1>;
};
+
+ mcu_r5fss0: r5fss@41000000 {
+ compatible = "ti,j721s2-r5fss";
+ ti,cluster-mode = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x41000000 0x00 0x41000000 0x20000>,
+ <0x41400000 0x00 0x41400000 0x20000>;
+ power-domains = <&k3_pds 283 TI_SCI_PD_EXCLUSIVE>;
+
+ mcu_r5fss0_core0: r5f@41000000 {
+ compatible = "ti,j721s2-r5f";
+ reg = <0x41000000 0x00010000>,
+ <0x41010000 0x00010000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <284>;
+ ti,sci-proc-ids = <0x01 0xff>;
+ resets = <&k3_reset 284 1>;
+ firmware-name = "j721s2-mcu-r5f0_0-fw";
+ ti,atcm-enable = <1>;
+ ti,btcm-enable = <1>;
+ ti,loczrama = <1>;
+ };
+
+ mcu_r5fss0_core1: r5f@41400000 {
+ compatible = "ti,j721s2-r5f";
+ reg = <0x41400000 0x00010000>,
+ <0x41410000 0x00010000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <285>;
+ ti,sci-proc-ids = <0x02 0xff>;
+ resets = <&k3_reset 285 1>;
+ firmware-name = "j721s2-mcu-r5f0_1-fw";
+ ti,atcm-enable = <1>;
+ ti,btcm-enable = <1>;
+ ti,loczrama = <1>;
+ };
+ };
+
+ mcu_esm: esm@40800000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x40800000 0x00 0x1000>;
+ ti,esm-pins = <95>;
+ bootph-pre-ram;
+ };
+
+ wkup_esm: esm@42080000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x42080000 0x00 0x1000>;
+ ti,esm-pins = <63>;
+ bootph-pre-ram;
+ };
+
+ /*
+ * The 2 RTI instances are couple with MCU R5Fs so keeping them
+ * reserved as these will be used by their respective firmware
+ */
+ mcu_watchdog0: watchdog@40600000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x40600000 0x00 0x100>;
+ clocks = <&k3_clks 295 1>;
+ power-domains = <&k3_pds 295 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 295 1>;
+ assigned-clock-parents = <&k3_clks 295 5>;
+ /* reserved for MCU_R5F0_0 */
+ status = "reserved";
+ };
+
+ mcu_watchdog1: watchdog@40610000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x40610000 0x00 0x100>;
+ clocks = <&k3_clks 296 1>;
+ power-domains = <&k3_pds 296 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 296 1>;
+ assigned-clock-parents = <&k3_clks 296 5>;
+ /* reserved for MCU_R5F0_1 */
+ status = "reserved";
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi
index a4006f328027..dcad372620b1 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi
@@ -29,6 +29,108 @@
alignment = <0x1000>;
no-map;
};
+
+ mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0000000 0x00 0x100000>;
+ no-map;
+ };
+
+ mcu_r5fss0_core0_memory_region: r5f-memory@a0100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ mcu_r5fss0_core1_dma_memory_region: r5f-dma-memory@a1000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa1000000 0x00 0x100000>;
+ no-map;
+ };
+
+ mcu_r5fss0_core1_memory_region: r5f-memory@a1100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa1100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss0_core0_dma_memory_region: r5f-dma-memory@a2000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa2000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss0_core0_memory_region: r5f-memory@a2100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa2100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss0_core1_dma_memory_region: r5f-dma-memory@a3000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa3000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss0_core1_memory_region: r5f-memory@a3100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa3100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss1_core0_dma_memory_region: r5f-dma-memory@a4000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa4000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss1_core0_memory_region: r5f-memory@a4100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa4100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss1_core1_dma_memory_region: r5f-dma-memory@a5000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa5000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss1_core1_memory_region: r5f-memory@a5100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa5100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ c71_0_dma_memory_region: c71-dma-memory@a6000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa6000000 0x00 0x100000>;
+ no-map;
+ };
+
+ c71_0_memory_region: c71-memory@a6100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa6100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ c71_1_dma_memory_region: c71-dma-memory@a7000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa7000000 0x00 0x100000>;
+ no-map;
+ };
+
+ c71_1_memory_region: c71-memory@a7100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa7100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ rtos_ipc_memory_region: ipc-memories@a8000000 {
+ reg = <0x00 0xa8000000 0x00 0x01c00000>;
+ alignment = <0x1000>;
+ no-map;
+ };
};
mux0: mux-controller {
@@ -151,3 +253,109 @@
cdns,read-delay = <4>;
};
};
+
+&mailbox0_cluster0 {
+ status = "okay";
+ interrupts = <436>;
+ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster1 {
+ status = "okay";
+ interrupts = <432>;
+ mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster2 {
+ status = "okay";
+ interrupts = <428>;
+ mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mailbox0_cluster4 {
+ status = "okay";
+ interrupts = <420>;
+ mbox_c71_0: mbox-c71-0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+
+ mbox_c71_1: mbox-c71-1 {
+ ti,mbox-rx = <2 0 0>;
+ ti,mbox-tx = <3 0 0>;
+ };
+};
+
+&mcu_r5fss0_core0 {
+ mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
+ <&mcu_r5fss0_core0_memory_region>;
+};
+
+&mcu_r5fss0_core1 {
+ mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
+ <&mcu_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss0_core0 {
+ mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ memory-region = <&main_r5fss0_core0_dma_memory_region>,
+ <&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+ mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ memory-region = <&main_r5fss0_core1_dma_memory_region>,
+ <&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+ mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core0>;
+ memory-region = <&main_r5fss1_core0_dma_memory_region>,
+ <&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+ mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core1>;
+ memory-region = <&main_r5fss1_core1_dma_memory_region>,
+ <&main_r5fss1_core1_memory_region>;
+};
+
+&c71_0 {
+ status = "okay";
+ mboxes = <&mailbox0_cluster4>, <&mbox_c71_0>;
+ memory-region = <&c71_0_dma_memory_region>,
+ <&c71_0_memory_region>;
+};
+
+&c71_1 {
+ status = "okay";
+ mboxes = <&mailbox0_cluster4>, <&mbox_c71_1>;
+ memory-region = <&c71_1_dma_memory_region>,
+ <&c71_1_memory_region>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index 5991c2e1d994..f1f4c8634ab6 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -249,6 +249,28 @@
states = <1800000 0x0>,
<3300000 0x1>;
};
+
+ dp0_pwr_3v3: regulator-dp0-prw {
+ compatible = "regulator-fixed";
+ regulator-name = "dp0-pwr";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&exp4 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ dp0: connector-dp0 {
+ compatible = "dp-connector";
+ label = "DP0";
+ type = "full-size";
+ dp-pwr-supply = <&dp0_pwr_3v3>;
+
+ port {
+ dp0_connector_in: endpoint {
+ remote-endpoint = <&dp0_out>;
+ };
+ };
+ };
};
&main_pmx0 {
@@ -289,6 +311,19 @@
J784S4_IOPAD(0x020, PIN_INPUT, 7) /* (AJ35) MCAN15_RX.GPIO0_8 */
>;
};
+
+ dp0_pins_default: dp0-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x0cc, PIN_INPUT, 12) /* (AM37) SPI0_CS0.DP0_HPD */
+ >;
+ };
+
+ main_i2c4_pins_default: main-i2c4-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x014, PIN_INPUT_PULLUP, 8) /* (AG33) MCAN14_TX.I2C4_SCL */
+ J784S4_IOPAD(0x010, PIN_INPUT_PULLUP, 8) /* (AH33) MCAN13_RX.I2C4_SDA */
+ >;
+ };
};
&wkup_pmx2 {
@@ -862,3 +897,85 @@
ti,adc-channels = <0 1 2 3 4 5 6 7>;
};
};
+
+&serdes_refclk {
+ status = "okay";
+ clock-frequency = <100000000>;
+};
+
+&dss {
+ status = "okay";
+ assigned-clocks = <&k3_clks 218 2>,
+ <&k3_clks 218 5>,
+ <&k3_clks 218 14>,
+ <&k3_clks 218 18>;
+ assigned-clock-parents = <&k3_clks 218 3>,
+ <&k3_clks 218 7>,
+ <&k3_clks 218 16>,
+ <&k3_clks 218 22>;
+};
+
+&serdes_wiz4 {
+ status = "okay";
+};
+
+&serdes4 {
+ status = "okay";
+ serdes4_dp_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <4>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_DP>;
+ resets = <&serdes_wiz4 1>, <&serdes_wiz4 2>,
+ <&serdes_wiz4 3>, <&serdes_wiz4 4>;
+ };
+};
+
+&mhdp {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp0_pins_default>;
+ phys = <&serdes4_dp_link>;
+ phy-names = "dpphy";
+};
+
+&dss_ports {
+ /* DP */
+ port {
+ dpi0_out: endpoint {
+ remote-endpoint = <&dp0_in>;
+ };
+ };
+};
+
+&main_i2c4 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c4_pins_default>;
+ clock-frequency = <400000>;
+
+ exp4: gpio@20 {
+ compatible = "ti,tca6408";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&dp0_ports {
+ port@0 {
+ reg = <0>;
+
+ dp0_in: endpoint {
+ remote-endpoint = <&dpi0_out>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+
+ dp0_out: endpoint {
+ remote-endpoint = <&dp0_connector_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index efed2d683f63..d89bcddcfe3d 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -5,6 +5,21 @@
* Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
*/
+#include <dt-bindings/mux/mux.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-ti.h>
+
+#include "k3-serdes.h"
+
+/ {
+ serdes_refclk: clock-serdes {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ /* To be enabled when serdes_wiz* is functional */
+ status = "disabled";
+ };
+};
+
&cbass_main {
msmc_ram: sram@70000000 {
compatible = "mmio-sram";
@@ -26,6 +41,42 @@
};
};
+ scm_conf: bus@100000 {
+ compatible = "simple-bus";
+ reg = <0x00 0x00100000 0x00 0x1c000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00 0x00 0x00100000 0x1c000>;
+
+ serdes_ln_ctrl: mux-controller@4080 {
+ compatible = "reg-mux";
+ reg = <0x00004080 0x30>;
+ #mux-control-cells = <1>;
+ mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
+ <0x4088 0x3>, <0x408c 0x3>, /* SERDES0 lane2/3 select */
+ <0x4090 0x3>, <0x4094 0x3>, /* SERDES1 lane0/1 select */
+ <0x4098 0x3>, <0x409c 0x3>, /* SERDES1 lane2/3 select */
+ <0x40a0 0x3>, <0x40a4 0x3>, /* SERDES2 lane0/1 select */
+ <0x40a8 0x3>, <0x40ac 0x3>; /* SERDES2 lane2/3 select */
+ idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>,
+ <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
+ <J784S4_SERDES0_LANE2_IP3_UNUSED>,
+ <J784S4_SERDES0_LANE3_USB>,
+ <J784S4_SERDES1_LANE0_PCIE0_LANE0>,
+ <J784S4_SERDES1_LANE1_PCIE0_LANE1>,
+ <J784S4_SERDES1_LANE2_PCIE0_LANE2>,
+ <J784S4_SERDES1_LANE3_PCIE0_LANE3>,
+ <J784S4_SERDES2_LANE0_IP2_UNUSED>,
+ <J784S4_SERDES2_LANE1_IP2_UNUSED>,
+ <J784S4_SERDES2_LANE2_QSGMII_LANE1>,
+ <J784S4_SERDES2_LANE3_QSGMII_LANE2>,
+ <J784S4_SERDES4_LANE0_EDP_LANE0>,
+ <J784S4_SERDES4_LANE1_EDP_LANE1>,
+ <J784S4_SERDES4_LANE2_EDP_LANE2>,
+ <J784S4_SERDES4_LANE3_EDP_LANE3>;
+ };
+ };
+
gic500: interrupt-controller@1800000 {
compatible = "arm,gic-v3";
#address-cells = <2>;
@@ -669,6 +720,160 @@
status = "disabled";
};
+ serdes_wiz0: wiz@5060000 {
+ compatible = "ti,j784s4-wiz-10g";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ power-domains = <&k3_pds 404 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 404 2>, <&k3_clks 404 6>, <&serdes_refclk>, <&k3_clks 404 5>;
+ clock-names = "fck", "core_ref_clk", "ext_ref_clk", "core_ref1_clk";
+ assigned-clocks = <&k3_clks 404 6>;
+ assigned-clock-parents = <&k3_clks 404 10>;
+ num-lanes = <4>;
+ #reset-cells = <1>;
+ #clock-cells = <1>;
+ ranges = <0x5060000 0x00 0x5060000 0x10000>;
+ status = "disabled";
+
+ serdes0: serdes@5060000 {
+ compatible = "ti,j721e-serdes-10g";
+ reg = <0x05060000 0x010000>;
+ reg-names = "torrent_phy";
+ resets = <&serdes_wiz0 0>;
+ reset-names = "torrent_reset";
+ clocks = <&serdes_wiz0 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz0 TI_WIZ_PHY_EN_REFCLK>;
+ clock-names = "refclk", "phy_en_refclk";
+ assigned-clocks = <&serdes_wiz0 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz0 TI_WIZ_PLL1_REFCLK>,
+ <&serdes_wiz0 TI_WIZ_REFCLK_DIG>;
+ assigned-clock-parents = <&k3_clks 404 6>,
+ <&k3_clks 404 6>,
+ <&k3_clks 404 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <1>;
+ status = "disabled";
+ };
+ };
+
+ serdes_wiz1: wiz@5070000 {
+ compatible = "ti,j784s4-wiz-10g";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ power-domains = <&k3_pds 405 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 405 2>, <&k3_clks 405 6>, <&serdes_refclk>, <&k3_clks 405 5>;
+ clock-names = "fck", "core_ref_clk", "ext_ref_clk", "core_ref1_clk";
+ assigned-clocks = <&k3_clks 405 6>;
+ assigned-clock-parents = <&k3_clks 405 10>;
+ num-lanes = <4>;
+ #reset-cells = <1>;
+ #clock-cells = <1>;
+ ranges = <0x05070000 0x00 0x05070000 0x10000>;
+ status = "disabled";
+
+ serdes1: serdes@5070000 {
+ compatible = "ti,j721e-serdes-10g";
+ reg = <0x05070000 0x010000>;
+ reg-names = "torrent_phy";
+ resets = <&serdes_wiz1 0>;
+ reset-names = "torrent_reset";
+ clocks = <&serdes_wiz1 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz1 TI_WIZ_PHY_EN_REFCLK>;
+ clock-names = "refclk", "phy_en_refclk";
+ assigned-clocks = <&serdes_wiz1 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz1 TI_WIZ_PLL1_REFCLK>,
+ <&serdes_wiz1 TI_WIZ_REFCLK_DIG>;
+ assigned-clock-parents = <&k3_clks 405 6>,
+ <&k3_clks 405 6>,
+ <&k3_clks 405 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <1>;
+ status = "disabled";
+ };
+ };
+
+ serdes_wiz2: wiz@5020000 {
+ compatible = "ti,j784s4-wiz-10g";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ power-domains = <&k3_pds 406 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 406 2>, <&k3_clks 406 6>, <&serdes_refclk>, <&k3_clks 406 5>;
+ clock-names = "fck", "core_ref_clk", "ext_ref_clk", "core_ref1_clk";
+ assigned-clocks = <&k3_clks 406 6>;
+ assigned-clock-parents = <&k3_clks 406 10>;
+ num-lanes = <4>;
+ #reset-cells = <1>;
+ #clock-cells = <1>;
+ ranges = <0x05020000 0x00 0x05020000 0x10000>;
+ status = "disabled";
+
+ serdes2: serdes@5020000 {
+ compatible = "ti,j721e-serdes-10g";
+ reg = <0x05020000 0x010000>;
+ reg-names = "torrent_phy";
+ resets = <&serdes_wiz2 0>;
+ reset-names = "torrent_reset";
+ clocks = <&serdes_wiz2 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz2 TI_WIZ_PHY_EN_REFCLK>;
+ clock-names = "refclk", "phy_en_refclk";
+ assigned-clocks = <&serdes_wiz2 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz2 TI_WIZ_PLL1_REFCLK>,
+ <&serdes_wiz2 TI_WIZ_REFCLK_DIG>;
+ assigned-clock-parents = <&k3_clks 406 6>,
+ <&k3_clks 406 6>,
+ <&k3_clks 406 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <1>;
+ status = "disabled";
+ };
+ };
+
+ serdes_wiz4: wiz@5050000 {
+ compatible = "ti,j784s4-wiz-10g";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ power-domains = <&k3_pds 407 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 407 2>, <&k3_clks 407 6>, <&serdes_refclk>, <&k3_clks 407 5>;
+ clock-names = "fck", "core_ref_clk", "ext_ref_clk", "core_ref1_clk";
+ assigned-clocks = <&k3_clks 407 6>;
+ assigned-clock-parents = <&k3_clks 407 10>;
+ num-lanes = <4>;
+ #reset-cells = <1>;
+ #clock-cells = <1>;
+ ranges = <0x05050000 0x00 0x05050000 0x10000>,
+ <0xa030a00 0x00 0xa030a00 0x40>; /* DPTX PHY */
+ status = "disabled";
+
+ serdes4: serdes@5050000 {
+ /*
+ * Note: we also map DPTX PHY registers as the Torrent
+ * needs to manage those.
+ */
+ compatible = "ti,j721e-serdes-10g";
+ reg = <0x05050000 0x010000>,
+ <0x0a030a00 0x40>; /* DPTX PHY */
+ reg-names = "torrent_phy";
+ resets = <&serdes_wiz4 0>;
+ reset-names = "torrent_reset";
+ clocks = <&serdes_wiz4 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz4 TI_WIZ_PHY_EN_REFCLK>;
+ clock-names = "refclk", "phy_en_refclk";
+ assigned-clocks = <&serdes_wiz4 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz4 TI_WIZ_PLL1_REFCLK>,
+ <&serdes_wiz4 TI_WIZ_REFCLK_DIG>;
+ assigned-clock-parents = <&k3_clks 407 6>,
+ <&k3_clks 407 6>,
+ <&k3_clks 407 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <1>;
+ status = "disabled";
+ };
+ };
+
main_navss: bus@30000000 {
bootph-all;
compatible = "simple-bus";
@@ -703,6 +908,7 @@
ti,sci = <&sms>;
ti,sci-dev-id = <321>;
ti,interrupt-ranges = <0 0 256>;
+ ti,unmapped-event-sources = <&main_bcdma_csi>;
};
secure_proxy_main: mailbox@32c00000 {
@@ -1000,6 +1206,22 @@
ti,sci-rm-range-rflow = <0x00>; /* GP RFLOW */
};
+ main_bcdma_csi: dma-controller@311a0000 {
+ compatible = "ti,j721s2-dmss-bcdma-csi";
+ reg = <0x00 0x311a0000 0x00 0x100>,
+ <0x00 0x35d00000 0x00 0x20000>,
+ <0x00 0x35c00000 0x00 0x10000>,
+ <0x00 0x35e00000 0x00 0x80000>;
+ reg-names = "gcfg", "rchanrt", "tchanrt", "ringrt";
+ msi-parent = <&main_udmass_inta>;
+ #dma-cells = <3>;
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <281>;
+ ti,sci-rm-range-rchan = <0x21>;
+ ti,sci-rm-range-tchan = <0x22>;
+ status = "disabled";
+ };
+
cpts@310d0000 {
compatible = "ti,j721e-cpts";
reg = <0x00 0x310d0000 0x00 0x400>;
@@ -1568,4 +1790,279 @@
firmware-name = "j784s4-c71_3-fw";
status = "disabled";
};
+
+ main_esm: esm@700000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x700000 0x00 0x1000>;
+ ti,esm-pins = <688>, <689>, <690>, <691>, <692>, <693>, <694>,
+ <695>;
+ bootph-pre-ram;
+ };
+
+ watchdog0: watchdog@2200000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2200000 0x00 0x100>;
+ clocks = <&k3_clks 348 1>;
+ power-domains = <&k3_pds 348 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 348 0>;
+ assigned-clock-parents = <&k3_clks 348 4>;
+ };
+
+ watchdog1: watchdog@2210000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2210000 0x00 0x100>;
+ clocks = <&k3_clks 349 1>;
+ power-domains = <&k3_pds 349 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 349 0>;
+ assigned-clock-parents = <&k3_clks 349 4>;
+ };
+
+ watchdog2: watchdog@2220000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2220000 0x00 0x100>;
+ clocks = <&k3_clks 350 1>;
+ power-domains = <&k3_pds 350 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 350 0>;
+ assigned-clock-parents = <&k3_clks 350 4>;
+ };
+
+ watchdog3: watchdog@2230000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2230000 0x00 0x100>;
+ clocks = <&k3_clks 351 1>;
+ power-domains = <&k3_pds 351 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 351 0>;
+ assigned-clock-parents = <&k3_clks 351 4>;
+ };
+
+ watchdog4: watchdog@2240000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2240000 0x00 0x100>;
+ clocks = <&k3_clks 352 1>;
+ power-domains = <&k3_pds 352 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 352 0>;
+ assigned-clock-parents = <&k3_clks 352 4>;
+ };
+
+ watchdog5: watchdog@2250000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2250000 0x00 0x100>;
+ clocks = <&k3_clks 353 1>;
+ power-domains = <&k3_pds 353 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 353 0>;
+ assigned-clock-parents = <&k3_clks 353 4>;
+ };
+
+ watchdog6: watchdog@2260000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2260000 0x00 0x100>;
+ clocks = <&k3_clks 354 1>;
+ power-domains = <&k3_pds 354 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 354 0>;
+ assigned-clock-parents = <&k3_clks 354 4>;
+ };
+
+ watchdog7: watchdog@2270000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2270000 0x00 0x100>;
+ clocks = <&k3_clks 355 1>;
+ power-domains = <&k3_pds 355 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 355 0>;
+ assigned-clock-parents = <&k3_clks 355 4>;
+ };
+
+ /*
+ * The following RTI instances are coupled with MCU R5Fs, c7x and
+ * GPU so keeping them reserved as these will be used by their
+ * respective firmware
+ */
+ watchdog8: watchdog@22f0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x22f0000 0x00 0x100>;
+ clocks = <&k3_clks 360 1>;
+ power-domains = <&k3_pds 360 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 360 0>;
+ assigned-clock-parents = <&k3_clks 360 4>;
+ /* reserved for GPU */
+ status = "reserved";
+ };
+
+ watchdog9: watchdog@2300000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2300000 0x00 0x100>;
+ clocks = <&k3_clks 356 1>;
+ power-domains = <&k3_pds 356 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 356 0>;
+ assigned-clock-parents = <&k3_clks 356 4>;
+ /* reserved for C7X_0 DSP */
+ status = "reserved";
+ };
+
+ watchdog10: watchdog@2310000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2310000 0x00 0x100>;
+ clocks = <&k3_clks 357 1>;
+ power-domains = <&k3_pds 357 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 357 0>;
+ assigned-clock-parents = <&k3_clks 357 4>;
+ /* reserved for C7X_1 DSP */
+ status = "reserved";
+ };
+
+ watchdog11: watchdog@2320000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2320000 0x00 0x100>;
+ clocks = <&k3_clks 358 1>;
+ power-domains = <&k3_pds 358 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 358 0>;
+ assigned-clock-parents = <&k3_clks 358 4>;
+ /* reserved for C7X_2 DSP */
+ status = "reserved";
+ };
+
+ watchdog12: watchdog@2330000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2330000 0x00 0x100>;
+ clocks = <&k3_clks 359 1>;
+ power-domains = <&k3_pds 359 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 359 0>;
+ assigned-clock-parents = <&k3_clks 359 4>;
+ /* reserved for C7X_3 DSP */
+ status = "reserved";
+ };
+
+ watchdog13: watchdog@23c0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x23c0000 0x00 0x100>;
+ clocks = <&k3_clks 361 1>;
+ power-domains = <&k3_pds 361 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 361 0>;
+ assigned-clock-parents = <&k3_clks 361 4>;
+ /* reserved for MAIN_R5F0_0 */
+ status = "reserved";
+ };
+
+ watchdog14: watchdog@23d0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x23d0000 0x00 0x100>;
+ clocks = <&k3_clks 362 1>;
+ power-domains = <&k3_pds 362 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 362 0>;
+ assigned-clock-parents = <&k3_clks 362 4>;
+ /* reserved for MAIN_R5F0_1 */
+ status = "reserved";
+ };
+
+ watchdog15: watchdog@23e0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x23e0000 0x00 0x100>;
+ clocks = <&k3_clks 363 1>;
+ power-domains = <&k3_pds 363 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 363 0>;
+ assigned-clock-parents = <&k3_clks 363 4>;
+ /* reserved for MAIN_R5F1_0 */
+ status = "reserved";
+ };
+
+ watchdog16: watchdog@23f0000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x23f0000 0x00 0x100>;
+ clocks = <&k3_clks 364 1>;
+ power-domains = <&k3_pds 364 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 364 0>;
+ assigned-clock-parents = <&k3_clks 364 4>;
+ /* reserved for MAIN_R5F1_1 */
+ status = "reserved";
+ };
+
+ watchdog17: watchdog@2540000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2540000 0x00 0x100>;
+ clocks = <&k3_clks 365 1>;
+ power-domains = <&k3_pds 365 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 365 0>;
+ assigned-clock-parents = <&k3_clks 366 4>;
+ /* reserved for MAIN_R5F2_0 */
+ status = "reserved";
+ };
+
+ watchdog18: watchdog@2550000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x2550000 0x00 0x100>;
+ clocks = <&k3_clks 366 1>;
+ power-domains = <&k3_pds 366 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 366 0>;
+ assigned-clock-parents = <&k3_clks 366 4>;
+ /* reserved for MAIN_R5F2_1 */
+ status = "reserved";
+ };
+
+ mhdp: bridge@a000000 {
+ compatible = "ti,j721e-mhdp8546";
+ reg = <0x0 0xa000000 0x0 0x30a00>,
+ <0x0 0x4f40000 0x0 0x20>;
+ reg-names = "mhdptx", "j721e-intg";
+ clocks = <&k3_clks 217 11>;
+ interrupt-parent = <&gic500>;
+ interrupts = <GIC_SPI 614 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 217 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ dp0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* Remote-endpoints are on the boards so
+ * ports are defined in the platform dt file.
+ */
+ };
+ };
+
+ dss: dss@4a00000 {
+ compatible = "ti,j721e-dss";
+ reg = <0x00 0x04a00000 0x00 0x10000>, /* common_m */
+ <0x00 0x04a10000 0x00 0x10000>, /* common_s0*/
+ <0x00 0x04b00000 0x00 0x10000>, /* common_s1*/
+ <0x00 0x04b10000 0x00 0x10000>, /* common_s2*/
+ <0x00 0x04a20000 0x00 0x10000>, /* vidl1 */
+ <0x00 0x04a30000 0x00 0x10000>, /* vidl2 */
+ <0x00 0x04a50000 0x00 0x10000>, /* vid1 */
+ <0x00 0x04a60000 0x00 0x10000>, /* vid2 */
+ <0x00 0x04a70000 0x00 0x10000>, /* ovr1 */
+ <0x00 0x04a90000 0x00 0x10000>, /* ovr2 */
+ <0x00 0x04ab0000 0x00 0x10000>, /* ovr3 */
+ <0x00 0x04ad0000 0x00 0x10000>, /* ovr4 */
+ <0x00 0x04a80000 0x00 0x10000>, /* vp1 */
+ <0x00 0x04aa0000 0x00 0x10000>, /* vp1 */
+ <0x00 0x04ac0000 0x00 0x10000>, /* vp1 */
+ <0x00 0x04ae0000 0x00 0x10000>, /* vp4 */
+ <0x00 0x04af0000 0x00 0x10000>; /* wb */
+ reg-names = "common_m", "common_s0",
+ "common_s1", "common_s2",
+ "vidl1", "vidl2","vid1","vid2",
+ "ovr1", "ovr2", "ovr3", "ovr4",
+ "vp1", "vp2", "vp3", "vp4",
+ "wb";
+ clocks = <&k3_clks 218 0>,
+ <&k3_clks 218 2>,
+ <&k3_clks 218 5>,
+ <&k3_clks 218 14>,
+ <&k3_clks 218 18>;
+ clock-names = "fck", "vp1", "vp2", "vp3", "vp4";
+ power-domains = <&k3_pds 218 TI_SCI_PD_EXCLUSIVE>;
+ interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "common_m",
+ "common_s0",
+ "common_s1",
+ "common_s2";
+ status = "disabled";
+
+ dss_ports: ports {
+ /* Ports that DSS drives are platform specific
+ * so they are defined in platform dt file.
+ */
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
index 4ab4018d3695..adb5ea6b9732 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
@@ -700,4 +700,44 @@
status = "disabled";
};
};
+
+ mcu_esm: esm@40800000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x40800000 0x00 0x1000>;
+ ti,esm-pins = <95>;
+ bootph-pre-ram;
+ };
+
+ wkup_esm: esm@42080000 {
+ compatible = "ti,j721e-esm";
+ reg = <0x00 0x42080000 0x00 0x1000>;
+ ti,esm-pins = <63>;
+ bootph-pre-ram;
+ };
+
+ /*
+ * The 2 RTI instances are couple with MCU R5Fs so keeping them
+ * reserved as these will be used by their respective firmware
+ */
+ mcu_watchdog0: watchdog@40600000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x40600000 0x00 0x100>;
+ clocks = <&k3_clks 367 1>;
+ power-domains = <&k3_pds 367 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 367 0>;
+ assigned-clock-parents = <&k3_clks 367 4>;
+ /* reserved for MCU_R5F0_0 */
+ status = "reserved";
+ };
+
+ mcu_watchdog1: watchdog@40610000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0x40610000 0x00 0x100>;
+ clocks = <&k3_clks 368 1>;
+ power-domains = <&k3_pds 368 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 368 0>;
+ assigned-clock-parents = <&k3_clks 368 4>;
+ /* reserved for MCU_R5F0_1 */
+ status = "reserved";
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-serdes.h b/arch/arm64/boot/dts/ti/k3-serdes.h
index 29167f85c1f6..21b4886c47ba 100644
--- a/arch/arm64/boot/dts/ti/k3-serdes.h
+++ b/arch/arm64/boot/dts/ti/k3-serdes.h
@@ -111,7 +111,7 @@
#define J721S2_SERDES0_LANE2_EDP_LANE2 0x0
#define J721S2_SERDES0_LANE2_PCIE1_LANE2 0x1
-#define J721S2_SERDES0_LANE2_IP3_UNUSED 0x2
+#define J721S2_SERDES0_LANE2_USB_SWAP 0x2
#define J721S2_SERDES0_LANE2_IP4_UNUSED 0x3
#define J721S2_SERDES0_LANE3_EDP_LANE3 0x0
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 424429c3053a..b60aa1f89343 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -423,6 +423,7 @@ CONFIG_MHI_WWAN_MBIM=m
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_ADC=m
CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_GPIO_POLLED=m
CONFIG_KEYBOARD_SNVS_PWRKEY=m
CONFIG_KEYBOARD_IMX_SC_KEY=m
CONFIG_KEYBOARD_CROS_EC=y
@@ -599,6 +600,7 @@ CONFIG_PINCTRL_SDM660=y
CONFIG_PINCTRL_SDM670=y
CONFIG_PINCTRL_SDM845=y
CONFIG_PINCTRL_SM6115=y
+CONFIG_PINCTRL_SM6115_LPASS_LPI=m
CONFIG_PINCTRL_SM6125=y
CONFIG_PINCTRL_SM6350=y
CONFIG_PINCTRL_SM6375=y
@@ -606,12 +608,14 @@ CONFIG_PINCTRL_SM8150=y
CONFIG_PINCTRL_SM8250=y
CONFIG_PINCTRL_SM8250_LPASS_LPI=m
CONFIG_PINCTRL_SM8350=y
+CONFIG_PINCTRL_SM8350_LPASS_LPI=m
CONFIG_PINCTRL_SM8450=y
CONFIG_PINCTRL_SM8450_LPASS_LPI=m
CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m
CONFIG_PINCTRL_SM8550=y
CONFIG_PINCTRL_SM8550_LPASS_LPI=m
CONFIG_PINCTRL_LPASS_LPI=m
+CONFIG_GPIO_AGGREGATOR=m
CONFIG_GPIO_ALTERA=m
CONFIG_GPIO_DAVINCI=y
CONFIG_GPIO_DWAPB=y
@@ -683,6 +687,7 @@ CONFIG_QCOM_SPMI_ADC_TM5=m
CONFIG_QCOM_SPMI_TEMP_ALARM=m
CONFIG_QCOM_LMH=m
CONFIG_UNIPHIER_THERMAL=y
+CONFIG_KHADAS_MCU_FAN_THERMAL=m
CONFIG_WATCHDOG=y
CONFIG_SL28CPLD_WATCHDOG=m
CONFIG_ARM_SP805_WATCHDOG=y
@@ -722,9 +727,11 @@ CONFIG_MFD_SEC_CORE=y
CONFIG_MFD_SL28CPLD=y
CONFIG_RZ_MTU3=y
CONFIG_MFD_TPS65219=y
+CONFIG_MFD_TPS6594_I2C=m
CONFIG_MFD_TI_AM335X_TSCADC=m
CONFIG_MFD_ROHM_BD718XX=y
CONFIG_MFD_WCD934X=m
+CONFIG_MFD_KHADAS_MCU=m
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_AXP20X=y
CONFIG_REGULATOR_BD718XX=y
@@ -762,6 +769,8 @@ CONFIG_RC_DEVICES=y
CONFIG_IR_GPIO_CIR=m
CONFIG_IR_MESON=m
CONFIG_IR_SUNXI=m
+CONFIG_MEDIA_CEC_SUPPORT=y
+CONFIG_CEC_MESON_G12A_AO=m
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
@@ -847,6 +856,7 @@ CONFIG_DRM_LONTIUM_LT9611UXC=m
CONFIG_DRM_ITE_IT66121=m
CONFIG_DRM_NWL_MIPI_DSI=m
CONFIG_DRM_PARADE_PS8640=m
+CONFIG_DRM_SAMSUNG_DSIM=m
CONFIG_DRM_SII902X=m
CONFIG_DRM_SIMPLE_BRIDGE=m
CONFIG_DRM_THINE_THC63LVD1024=m
@@ -1032,16 +1042,20 @@ CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_MASS_STORAGE=m
CONFIG_TYPEC=m
CONFIG_TYPEC_TCPM=m
CONFIG_TYPEC_TCPCI=m
CONFIG_TYPEC_FUSB302=m
CONFIG_TYPEC_TPS6598X=m
CONFIG_TYPEC_HD3SS3220=m
+CONFIG_TYPEC_QCOM_PMIC=m
CONFIG_TYPEC_UCSI=m
CONFIG_TYPEC_MUX_FSA4480=m
+CONFIG_TYPEC_MUX_NB7VPQ904M=m
CONFIG_UCSI_CCG=m
CONFIG_TYPEC_MUX_GPIO_SBU=m
+CONFIG_TYPEC_DP_ALTMODE=m
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_ARMMMCI=y
@@ -1107,6 +1121,7 @@ CONFIG_RTC_DRV_RK808=m
CONFIG_RTC_DRV_ISL1208=m
CONFIG_RTC_DRV_PCF85063=m
CONFIG_RTC_DRV_PCF85363=m
+CONFIG_RTC_DRV_PCF8563=m
CONFIG_RTC_DRV_M41T80=m
CONFIG_RTC_DRV_BQ32K=m
CONFIG_RTC_DRV_RX8581=m
@@ -1162,6 +1177,7 @@ CONFIG_XEN_GRANT_DEV_ALLOC=y
CONFIG_STAGING=y
CONFIG_STAGING_MEDIA=y
CONFIG_VIDEO_MAX96712=m
+CONFIG_VIDEO_MESON_VDEC=m
CONFIG_CHROME_PLATFORMS=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
@@ -1336,6 +1352,7 @@ CONFIG_ARCH_R8A774B1=y
CONFIG_ARCH_R9A07G043=y
CONFIG_ARCH_R9A07G044=y
CONFIG_ARCH_R9A07G054=y
+CONFIG_ARCH_R9A08G045=y
CONFIG_ARCH_R9A09G011=y
CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_ROCKCHIP_PM_DOMAINS=y
@@ -1423,6 +1440,7 @@ CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=m
CONFIG_PHY_QCOM_USB_HS_28NM=m
CONFIG_PHY_QCOM_USB_SS=m
CONFIG_PHY_QCOM_SGMII_ETH=m
+CONFIG_PHY_QCOM_M31_USB=m
CONFIG_PHY_R8A779F0_ETHERNET_SERDES=y
CONFIG_PHY_RCAR_GEN3_PCIE=y
CONFIG_PHY_RCAR_GEN3_USB2=y
@@ -1453,6 +1471,7 @@ CONFIG_QCOM_L3_PMU=y
CONFIG_ARM_SPE_PMU=m
CONFIG_ARM_DMC620_PMU=m
CONFIG_HISI_PMU=y
+CONFIG_MESON_DDR_PMU=m
CONFIG_NVMEM_LAYOUT_SL28_VPD=m
CONFIG_NVMEM_IMX_OCOTP=y
CONFIG_NVMEM_IMX_OCOTP_ELE=m
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 5c8ee5a541d2..4b6d2d52053e 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -6,5 +6,5 @@ generic-y += qspinlock.h
generic-y += parport.h
generic-y += user.h
-generated-y += cpucaps.h
+generated-y += cpucap-defs.h
generated-y += sysreg-defs.h
diff --git a/arch/arm64/include/asm/alternative-macros.h b/arch/arm64/include/asm/alternative-macros.h
index 94b486192e1f..210bb43cff2c 100644
--- a/arch/arm64/include/asm/alternative-macros.h
+++ b/arch/arm64/include/asm/alternative-macros.h
@@ -226,8 +226,8 @@ alternative_endif
static __always_inline bool
alternative_has_cap_likely(const unsigned long cpucap)
{
- compiletime_assert(cpucap < ARM64_NCAPS,
- "cpucap must be < ARM64_NCAPS");
+ if (!cpucap_is_possible(cpucap))
+ return false;
asm_volatile_goto(
ALTERNATIVE_CB("b %l[l_no]", %[cpucap], alt_cb_patch_nops)
@@ -244,8 +244,8 @@ l_no:
static __always_inline bool
alternative_has_cap_unlikely(const unsigned long cpucap)
{
- compiletime_assert(cpucap < ARM64_NCAPS,
- "cpucap must be < ARM64_NCAPS");
+ if (!cpucap_is_possible(cpucap))
+ return false;
asm_volatile_goto(
ALTERNATIVE("nop", "b %l[l_yes]", %[cpucap])
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 01281a5336cf..5f172611654b 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -79,6 +79,14 @@ static inline u64 gic_read_iar_cavium_thunderx(void)
return 0x3ff;
}
+static u64 __maybe_unused gic_read_iar(void)
+{
+ if (alternative_has_cap_unlikely(ARM64_WORKAROUND_CAVIUM_23154))
+ return gic_read_iar_cavium_thunderx();
+ else
+ return gic_read_iar_common();
+}
+
static inline void gic_write_ctlr(u32 val)
{
write_sysreg_s(val, SYS_ICC_CTLR_EL1);
diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index b0abc64f86b0..ecdb3cfcd0f8 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -63,7 +63,7 @@ static __always_inline bool __cpu_has_rng(void)
{
if (unlikely(!system_capabilities_finalized() && !preemptible()))
return this_cpu_has_cap(ARM64_HAS_RNG);
- return cpus_have_const_cap(ARM64_HAS_RNG);
+ return alternative_has_cap_unlikely(ARM64_HAS_RNG);
}
static inline size_t __must_check arch_get_random_longs(unsigned long *v, size_t max_longs)
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
index d115451ed263..fefac75fa009 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -132,7 +132,7 @@ void flush_dcache_folio(struct folio *);
static __always_inline void icache_inval_all_pou(void)
{
- if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC))
+ if (alternative_has_cap_unlikely(ARM64_HAS_CACHE_DIC))
return;
asm("ic ialluis");
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index e749838b9c5d..f3034099fd95 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -63,12 +63,6 @@ struct cpuinfo_arm64 {
u64 reg_id_aa64smfr0;
struct cpuinfo_32bit aarch32;
-
- /* pseudo-ZCR for recording maximum ZCR_EL1 LEN value: */
- u64 reg_zcr;
-
- /* pseudo-SMCR for recording maximum SMCR_EL1 LEN value: */
- u64 reg_smcr;
};
DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
new file mode 100644
index 000000000000..270680e2b5c4
--- /dev/null
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ASM_CPUCAPS_H
+#define __ASM_CPUCAPS_H
+
+#include <asm/cpucap-defs.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+/*
+ * Check whether a cpucap is possible at compiletime.
+ */
+static __always_inline bool
+cpucap_is_possible(const unsigned int cap)
+{
+ compiletime_assert(__builtin_constant_p(cap),
+ "cap must be a constant");
+ compiletime_assert(cap < ARM64_NCAPS,
+ "cap must be < ARM64_NCAPS");
+
+ switch (cap) {
+ case ARM64_HAS_PAN:
+ return IS_ENABLED(CONFIG_ARM64_PAN);
+ case ARM64_HAS_EPAN:
+ return IS_ENABLED(CONFIG_ARM64_EPAN);
+ case ARM64_SVE:
+ return IS_ENABLED(CONFIG_ARM64_SVE);
+ case ARM64_SME:
+ case ARM64_SME2:
+ case ARM64_SME_FA64:
+ return IS_ENABLED(CONFIG_ARM64_SME);
+ case ARM64_HAS_CNP:
+ return IS_ENABLED(CONFIG_ARM64_CNP);
+ case ARM64_HAS_ADDRESS_AUTH:
+ case ARM64_HAS_GENERIC_AUTH:
+ return IS_ENABLED(CONFIG_ARM64_PTR_AUTH);
+ case ARM64_HAS_GIC_PRIO_MASKING:
+ return IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI);
+ case ARM64_MTE:
+ return IS_ENABLED(CONFIG_ARM64_MTE);
+ case ARM64_BTI:
+ return IS_ENABLED(CONFIG_ARM64_BTI);
+ case ARM64_HAS_TLB_RANGE:
+ return IS_ENABLED(CONFIG_ARM64_TLB_RANGE);
+ case ARM64_UNMAP_KERNEL_AT_EL0:
+ return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0);
+ case ARM64_WORKAROUND_843419:
+ return IS_ENABLED(CONFIG_ARM64_ERRATUM_843419);
+ case ARM64_WORKAROUND_1742098:
+ return IS_ENABLED(CONFIG_ARM64_ERRATUM_1742098);
+ case ARM64_WORKAROUND_2645198:
+ return IS_ENABLED(CONFIG_ARM64_ERRATUM_2645198);
+ case ARM64_WORKAROUND_2658417:
+ return IS_ENABLED(CONFIG_ARM64_ERRATUM_2658417);
+ case ARM64_WORKAROUND_CAVIUM_23154:
+ return IS_ENABLED(CONFIG_CAVIUM_ERRATUM_23154);
+ case ARM64_WORKAROUND_NVIDIA_CARMEL_CNP:
+ return IS_ENABLED(CONFIG_NVIDIA_CARMEL_CNP_ERRATUM);
+ case ARM64_WORKAROUND_REPEAT_TLBI:
+ return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
+ }
+
+ return true;
+}
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 5bba39376055..f6d416fe49b0 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -23,6 +23,7 @@
#include <linux/bug.h>
#include <linux/jump_label.h>
#include <linux/kernel.h>
+#include <linux/cpumask.h>
/*
* CPU feature register tracking
@@ -380,6 +381,7 @@ struct arm64_cpu_capabilities {
* method is robust against being called multiple times.
*/
const struct arm64_cpu_capabilities *match_list;
+ const struct cpumask *cpus;
};
static inline int cpucap_default_scope(const struct arm64_cpu_capabilities *cap)
@@ -438,6 +440,11 @@ unsigned long cpu_get_elf_hwcap2(void);
#define cpu_set_named_feature(name) cpu_set_feature(cpu_feature(name))
#define cpu_have_named_feature(name) cpu_have_feature(cpu_feature(name))
+static __always_inline bool boot_capabilities_finalized(void)
+{
+ return alternative_has_cap_likely(ARM64_ALWAYS_BOOT);
+}
+
static __always_inline bool system_capabilities_finalized(void)
{
return alternative_has_cap_likely(ARM64_ALWAYS_SYSTEM);
@@ -450,6 +457,8 @@ static __always_inline bool system_capabilities_finalized(void)
*/
static __always_inline bool cpus_have_cap(unsigned int num)
{
+ if (__builtin_constant_p(num) && !cpucap_is_possible(num))
+ return false;
if (num >= ARM64_NCAPS)
return false;
return arch_test_bit(num, system_cpucaps);
@@ -458,55 +467,37 @@ static __always_inline bool cpus_have_cap(unsigned int num)
/*
* Test for a capability without a runtime check.
*
- * Before capabilities are finalized, this returns false.
- * After capabilities are finalized, this is patched to avoid a runtime check.
+ * Before boot capabilities are finalized, this will BUG().
+ * After boot capabilities are finalized, this is patched to avoid a runtime
+ * check.
*
* @num must be a compile-time constant.
*/
-static __always_inline bool __cpus_have_const_cap(int num)
+static __always_inline bool cpus_have_final_boot_cap(int num)
{
- if (num >= ARM64_NCAPS)
- return false;
- return alternative_has_cap_unlikely(num);
+ if (boot_capabilities_finalized())
+ return alternative_has_cap_unlikely(num);
+ else
+ BUG();
}
/*
* Test for a capability without a runtime check.
*
- * Before capabilities are finalized, this will BUG().
- * After capabilities are finalized, this is patched to avoid a runtime check.
+ * Before system capabilities are finalized, this will BUG().
+ * After system capabilities are finalized, this is patched to avoid a runtime
+ * check.
*
* @num must be a compile-time constant.
*/
static __always_inline bool cpus_have_final_cap(int num)
{
if (system_capabilities_finalized())
- return __cpus_have_const_cap(num);
+ return alternative_has_cap_unlikely(num);
else
BUG();
}
-/*
- * Test for a capability, possibly with a runtime check for non-hyp code.
- *
- * For hyp code, this behaves the same as cpus_have_final_cap().
- *
- * For non-hyp code:
- * Before capabilities are finalized, this behaves as cpus_have_cap().
- * After capabilities are finalized, this is patched to avoid a runtime check.
- *
- * @num must be a compile-time constant.
- */
-static __always_inline bool cpus_have_const_cap(int num)
-{
- if (is_hyp_code())
- return cpus_have_final_cap(num);
- else if (system_capabilities_finalized())
- return __cpus_have_const_cap(num);
- else
- return cpus_have_cap(num);
-}
-
static inline int __attribute_const__
cpuid_feature_extract_signed_field_width(u64 features, int field, int width)
{
@@ -626,7 +617,9 @@ static inline bool id_aa64pfr1_mte(u64 pfr1)
return val >= ID_AA64PFR1_EL1_MTE_MTE2;
}
-void __init setup_cpu_features(void);
+void __init setup_system_features(void);
+void __init setup_user_features(void);
+
void check_local_cpu_capabilities(void);
u64 read_sanitised_ftr_reg(u32 id);
@@ -735,13 +728,12 @@ static inline bool system_supports_mixed_endian(void)
static __always_inline bool system_supports_fpsimd(void)
{
- return !cpus_have_const_cap(ARM64_HAS_NO_FPSIMD);
+ return alternative_has_cap_likely(ARM64_HAS_FPSIMD);
}
static inline bool system_uses_hw_pan(void)
{
- return IS_ENABLED(CONFIG_ARM64_PAN) &&
- cpus_have_const_cap(ARM64_HAS_PAN);
+ return alternative_has_cap_unlikely(ARM64_HAS_PAN);
}
static inline bool system_uses_ttbr0_pan(void)
@@ -752,26 +744,22 @@ static inline bool system_uses_ttbr0_pan(void)
static __always_inline bool system_supports_sve(void)
{
- return IS_ENABLED(CONFIG_ARM64_SVE) &&
- cpus_have_const_cap(ARM64_SVE);
+ return alternative_has_cap_unlikely(ARM64_SVE);
}
static __always_inline bool system_supports_sme(void)
{
- return IS_ENABLED(CONFIG_ARM64_SME) &&
- cpus_have_const_cap(ARM64_SME);
+ return alternative_has_cap_unlikely(ARM64_SME);
}
static __always_inline bool system_supports_sme2(void)
{
- return IS_ENABLED(CONFIG_ARM64_SME) &&
- cpus_have_const_cap(ARM64_SME2);
+ return alternative_has_cap_unlikely(ARM64_SME2);
}
static __always_inline bool system_supports_fa64(void)
{
- return IS_ENABLED(CONFIG_ARM64_SME) &&
- cpus_have_const_cap(ARM64_SME_FA64);
+ return alternative_has_cap_unlikely(ARM64_SME_FA64);
}
static __always_inline bool system_supports_tpidr2(void)
@@ -781,20 +769,17 @@ static __always_inline bool system_supports_tpidr2(void)
static __always_inline bool system_supports_cnp(void)
{
- return IS_ENABLED(CONFIG_ARM64_CNP) &&
- cpus_have_const_cap(ARM64_HAS_CNP);
+ return alternative_has_cap_unlikely(ARM64_HAS_CNP);
}
static inline bool system_supports_address_auth(void)
{
- return IS_ENABLED(CONFIG_ARM64_PTR_AUTH) &&
- cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH);
+ return cpus_have_final_boot_cap(ARM64_HAS_ADDRESS_AUTH);
}
static inline bool system_supports_generic_auth(void)
{
- return IS_ENABLED(CONFIG_ARM64_PTR_AUTH) &&
- cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH);
+ return alternative_has_cap_unlikely(ARM64_HAS_GENERIC_AUTH);
}
static inline bool system_has_full_ptr_auth(void)
@@ -804,14 +789,12 @@ static inline bool system_has_full_ptr_auth(void)
static __always_inline bool system_uses_irq_prio_masking(void)
{
- return IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) &&
- cpus_have_const_cap(ARM64_HAS_GIC_PRIO_MASKING);
+ return alternative_has_cap_unlikely(ARM64_HAS_GIC_PRIO_MASKING);
}
static inline bool system_supports_mte(void)
{
- return IS_ENABLED(CONFIG_ARM64_MTE) &&
- cpus_have_const_cap(ARM64_MTE);
+ return alternative_has_cap_unlikely(ARM64_MTE);
}
static inline bool system_has_prio_mask_debugging(void)
@@ -822,13 +805,18 @@ static inline bool system_has_prio_mask_debugging(void)
static inline bool system_supports_bti(void)
{
- return IS_ENABLED(CONFIG_ARM64_BTI) && cpus_have_const_cap(ARM64_BTI);
+ return cpus_have_final_cap(ARM64_BTI);
+}
+
+static inline bool system_supports_bti_kernel(void)
+{
+ return IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) &&
+ cpus_have_final_boot_cap(ARM64_BTI);
}
static inline bool system_supports_tlb_range(void)
{
- return IS_ENABLED(CONFIG_ARM64_TLB_RANGE) &&
- cpus_have_const_cap(ARM64_HAS_TLB_RANGE);
+ return alternative_has_cap_unlikely(ARM64_HAS_TLB_RANGE);
}
int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 74d00feb62f0..7c7493cb571f 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -86,7 +86,8 @@
#define ARM_CPU_PART_NEOVERSE_N2 0xD49
#define ARM_CPU_PART_CORTEX_A78C 0xD4B
-#define APM_CPU_PART_POTENZA 0x000
+#define APM_CPU_PART_XGENE 0x000
+#define APM_CPU_VAR_POTENZA 0x00
#define CAVIUM_CPU_PART_THUNDERX 0x0A1
#define CAVIUM_CPU_PART_THUNDERX_81XX 0x0A2
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 8df46f186c64..50e5f25d3024 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -32,6 +32,32 @@
#define VFP_STATE_SIZE ((32 * 8) + 4)
#endif
+static inline unsigned long cpacr_save_enable_kernel_sve(void)
+{
+ unsigned long old = read_sysreg(cpacr_el1);
+ unsigned long set = CPACR_EL1_FPEN_EL1EN | CPACR_EL1_ZEN_EL1EN;
+
+ write_sysreg(old | set, cpacr_el1);
+ isb();
+ return old;
+}
+
+static inline unsigned long cpacr_save_enable_kernel_sme(void)
+{
+ unsigned long old = read_sysreg(cpacr_el1);
+ unsigned long set = CPACR_EL1_FPEN_EL1EN | CPACR_EL1_SMEN_EL1EN;
+
+ write_sysreg(old | set, cpacr_el1);
+ isb();
+ return old;
+}
+
+static inline void cpacr_restore(unsigned long cpacr)
+{
+ write_sysreg(cpacr, cpacr_el1);
+ isb();
+}
+
/*
* When we defined the maximum SVE vector length we defined the ABI so
* that the maximum vector length included all the reserved for future
@@ -123,12 +149,12 @@ extern void sme_save_state(void *state, int zt);
extern void sme_load_state(void const *state, int zt);
struct arm64_cpu_capabilities;
-extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
-extern void sme_kernel_enable(const struct arm64_cpu_capabilities *__unused);
-extern void sme2_kernel_enable(const struct arm64_cpu_capabilities *__unused);
-extern void fa64_kernel_enable(const struct arm64_cpu_capabilities *__unused);
+extern void cpu_enable_fpsimd(const struct arm64_cpu_capabilities *__unused);
+extern void cpu_enable_sve(const struct arm64_cpu_capabilities *__unused);
+extern void cpu_enable_sme(const struct arm64_cpu_capabilities *__unused);
+extern void cpu_enable_sme2(const struct arm64_cpu_capabilities *__unused);
+extern void cpu_enable_fa64(const struct arm64_cpu_capabilities *__unused);
-extern u64 read_zcr_features(void);
extern u64 read_smcr_features(void);
/*
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 521267478d18..cd71e09ea14d 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -139,6 +139,9 @@
#define KERNEL_HWCAP_SME_F16F16 __khwcap2_feature(SME_F16F16)
#define KERNEL_HWCAP_MOPS __khwcap2_feature(MOPS)
#define KERNEL_HWCAP_HBC __khwcap2_feature(HBC)
+#define KERNEL_HWCAP_SVE_B16B16 __khwcap2_feature(SVE_B16B16)
+#define KERNEL_HWCAP_LRCPC3 __khwcap2_feature(LRCPC3)
+#define KERNEL_HWCAP_LSE128 __khwcap2_feature(LSE128)
/*
* This yields a mask that user programs can use to figure out what
diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index fac08e18bcd5..50ce8b697ff3 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -6,6 +6,9 @@
#include <asm-generic/irq.h>
+void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu);
+#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
+
struct pt_regs;
int set_handle_irq(void (*handle_irq)(struct pt_regs *));
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index 1f31ec146d16..0a7186a93882 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -21,12 +21,6 @@
* exceptions should be unmasked.
*/
-static __always_inline bool __irqflags_uses_pmr(void)
-{
- return IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) &&
- alternative_has_cap_unlikely(ARM64_HAS_GIC_PRIO_MASKING);
-}
-
static __always_inline void __daif_local_irq_enable(void)
{
barrier();
@@ -49,7 +43,7 @@ static __always_inline void __pmr_local_irq_enable(void)
static inline void arch_local_irq_enable(void)
{
- if (__irqflags_uses_pmr()) {
+ if (system_uses_irq_prio_masking()) {
__pmr_local_irq_enable();
} else {
__daif_local_irq_enable();
@@ -77,7 +71,7 @@ static __always_inline void __pmr_local_irq_disable(void)
static inline void arch_local_irq_disable(void)
{
- if (__irqflags_uses_pmr()) {
+ if (system_uses_irq_prio_masking()) {
__pmr_local_irq_disable();
} else {
__daif_local_irq_disable();
@@ -99,7 +93,7 @@ static __always_inline unsigned long __pmr_local_save_flags(void)
*/
static inline unsigned long arch_local_save_flags(void)
{
- if (__irqflags_uses_pmr()) {
+ if (system_uses_irq_prio_masking()) {
return __pmr_local_save_flags();
} else {
return __daif_local_save_flags();
@@ -118,7 +112,7 @@ static __always_inline bool __pmr_irqs_disabled_flags(unsigned long flags)
static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
- if (__irqflags_uses_pmr()) {
+ if (system_uses_irq_prio_masking()) {
return __pmr_irqs_disabled_flags(flags);
} else {
return __daif_irqs_disabled_flags(flags);
@@ -137,7 +131,7 @@ static __always_inline bool __pmr_irqs_disabled(void)
static inline bool arch_irqs_disabled(void)
{
- if (__irqflags_uses_pmr()) {
+ if (system_uses_irq_prio_masking()) {
return __pmr_irqs_disabled();
} else {
return __daif_irqs_disabled();
@@ -169,7 +163,7 @@ static __always_inline unsigned long __pmr_local_irq_save(void)
static inline unsigned long arch_local_irq_save(void)
{
- if (__irqflags_uses_pmr()) {
+ if (system_uses_irq_prio_masking()) {
return __pmr_local_irq_save();
} else {
return __daif_local_irq_save();
@@ -196,7 +190,7 @@ static __always_inline void __pmr_local_irq_restore(unsigned long flags)
*/
static inline void arch_local_irq_restore(unsigned long flags)
{
- if (__irqflags_uses_pmr()) {
+ if (system_uses_irq_prio_masking()) {
__pmr_local_irq_restore(flags);
} else {
__daif_local_irq_restore(flags);
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 3d6725ff0bf6..cbd2f163a67d 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -71,14 +71,14 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
if (has_vhe() || has_hvhe())
vcpu->arch.hcr_el2 |= HCR_E2H;
- if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
+ if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
/* route synchronous external abort exceptions to EL2 */
vcpu->arch.hcr_el2 |= HCR_TEA;
/* trap error record accesses */
vcpu->arch.hcr_el2 |= HCR_TERR;
}
- if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB)) {
+ if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB)) {
vcpu->arch.hcr_el2 |= HCR_FWB;
} else {
/*
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index af06ccb7ee34..e64d64e6ad44 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1052,7 +1052,7 @@ static inline void kvm_init_host_cpu_context(struct kvm_cpu_context *cpu_ctxt)
static inline bool kvm_system_needs_idmapped_vectors(void)
{
- return cpus_have_const_cap(ARM64_SPECTRE_V3A);
+ return cpus_have_final_cap(ARM64_SPECTRE_V3A);
}
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 96a80e8f6226..27810667dec7 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -218,7 +218,7 @@ static inline void __clean_dcache_guest_page(void *va, size_t size)
* faulting in pages. Furthermore, FWB implies IDC, so cleaning to
* PoU is not required either in this case.
*/
- if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
+ if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
return;
kvm_flush_dcache_to_poc(va, size);
diff --git a/arch/arm64/include/asm/lse.h b/arch/arm64/include/asm/lse.h
index cbbcdc35c4cd..3129a5819d0e 100644
--- a/arch/arm64/include/asm/lse.h
+++ b/arch/arm64/include/asm/lse.h
@@ -16,14 +16,9 @@
#include <asm/atomic_lse.h>
#include <asm/cpucaps.h>
-static __always_inline bool system_uses_lse_atomics(void)
-{
- return alternative_has_cap_likely(ARM64_HAS_LSE_ATOMICS);
-}
-
#define __lse_ll_sc_body(op, ...) \
({ \
- system_uses_lse_atomics() ? \
+ alternative_has_cap_likely(ARM64_HAS_LSE_ATOMICS) ? \
__lse_##op(__VA_ARGS__) : \
__ll_sc_##op(__VA_ARGS__); \
})
@@ -34,8 +29,6 @@ static __always_inline bool system_uses_lse_atomics(void)
#else /* CONFIG_ARM64_LSE_ATOMICS */
-static inline bool system_uses_lse_atomics(void) { return false; }
-
#define __lse_ll_sc_body(op, ...) __ll_sc_##op(__VA_ARGS__)
#define ARM64_LSE_ATOMIC_INSN(llsc, lse) llsc
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 94b68850cb9f..2fcf51231d6e 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -57,7 +57,7 @@ typedef struct {
static inline bool arm64_kernel_unmapped_at_el0(void)
{
- return cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0);
+ return alternative_has_cap_unlikely(ARM64_UNMAP_KERNEL_AT_EL0);
}
extern void arm64_memblock_init(void);
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index a6fb325424e7..9ce4200508b1 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -152,7 +152,7 @@ static inline void cpu_install_ttbr0(phys_addr_t ttbr0, unsigned long t0sz)
* Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD,
* avoiding the possibility of conflicting TLB entries being allocated.
*/
-static inline void cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap)
+static inline void __cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap, bool cnp)
{
typedef void (ttbr_replace_func)(phys_addr_t);
extern ttbr_replace_func idmap_cpu_replace_ttbr1;
@@ -162,17 +162,8 @@ static inline void cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap)
/* phys_to_ttbr() zeros lower 2 bits of ttbr with 52-bit PA */
phys_addr_t ttbr1 = phys_to_ttbr(virt_to_phys(pgdp));
- if (system_supports_cnp() && !WARN_ON(pgdp != lm_alias(swapper_pg_dir))) {
- /*
- * cpu_replace_ttbr1() is used when there's a boot CPU
- * up (i.e. cpufeature framework is not up yet) and
- * latter only when we enable CNP via cpufeature's
- * enable() callback.
- * Also we rely on the system_cpucaps bit being set before
- * calling the enable() function.
- */
+ if (cnp)
ttbr1 |= TTBR_CNP_BIT;
- }
replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1);
@@ -189,6 +180,21 @@ static inline void cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap)
cpu_uninstall_idmap();
}
+static inline void cpu_enable_swapper_cnp(void)
+{
+ __cpu_replace_ttbr1(lm_alias(swapper_pg_dir), idmap_pg_dir, true);
+}
+
+static inline void cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap)
+{
+ /*
+ * Only for early TTBR1 replacement before cpucaps are finalized and
+ * before we've decided whether to use CNP.
+ */
+ WARN_ON(system_capabilities_finalized());
+ __cpu_replace_ttbr1(pgdp, idmap, false);
+}
+
/*
* It would be nice to return ASIDs back to the allocator, but unfortunately
* that introduces a race with a generation rollover where we could erroneously
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
index bfa6638b4c93..79550b22ba19 100644
--- a/arch/arm64/include/asm/module.h
+++ b/arch/arm64/include/asm/module.h
@@ -44,8 +44,7 @@ struct plt_entry {
static inline bool is_forbidden_offset_for_adrp(void *place)
{
- return IS_ENABLED(CONFIG_ARM64_ERRATUM_843419) &&
- cpus_have_const_cap(ARM64_WORKAROUND_843419) &&
+ return cpus_have_final_cap(ARM64_WORKAROUND_843419) &&
((u64)place & 0xfff) >= 0xff8;
}
diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
index 4cedbaa16f41..91fbd5c8a391 100644
--- a/arch/arm64/include/asm/mte.h
+++ b/arch/arm64/include/asm/mte.h
@@ -90,7 +90,7 @@ static inline bool try_page_mte_tagging(struct page *page)
}
void mte_zero_clear_page_tags(void *addr);
-void mte_sync_tags(pte_t pte);
+void mte_sync_tags(pte_t pte, unsigned int nr_pages);
void mte_copy_page_tags(void *kto, const void *kfrom);
void mte_thread_init_user(void);
void mte_thread_switch(struct task_struct *next);
@@ -122,7 +122,7 @@ static inline bool try_page_mte_tagging(struct page *page)
static inline void mte_zero_clear_page_tags(void *addr)
{
}
-static inline void mte_sync_tags(pte_t pte)
+static inline void mte_sync_tags(pte_t pte, unsigned int nr_pages)
{
}
static inline void mte_copy_page_tags(void *kto, const void *kfrom)
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index eed814b00a38..e9624f6326dd 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -75,11 +75,7 @@ extern bool arm64_use_ng_mappings;
* If we have userspace only BTI we don't want to mark kernel pages
* guarded even if the system does support BTI.
*/
-#ifdef CONFIG_ARM64_BTI_KERNEL
-#define PTE_MAYBE_GP (system_supports_bti() ? PTE_GP : 0)
-#else
-#define PTE_MAYBE_GP 0
-#endif
+#define PTE_MAYBE_GP (system_supports_bti_kernel() ? PTE_GP : 0)
#define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL_RO)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7f7d9b1df4e5..b19a8aee684c 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -325,8 +325,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
__func__, pte_val(old_pte), pte_val(pte));
}
-static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
+static inline void __sync_cache_and_tags(pte_t pte, unsigned int nr_pages)
{
if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
__sync_icache_dcache(pte);
@@ -339,24 +338,22 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
*/
if (system_supports_mte() && pte_access_permitted(pte, false) &&
!pte_special(pte) && pte_tagged(pte))
- mte_sync_tags(pte);
-
- __check_safe_pte_update(mm, ptep, pte);
-
- set_pte(ptep, pte);
+ mte_sync_tags(pte, nr_pages);
}
-static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte, unsigned int nr)
+static inline void set_ptes(struct mm_struct *mm,
+ unsigned long __always_unused addr,
+ pte_t *ptep, pte_t pte, unsigned int nr)
{
page_table_check_ptes_set(mm, ptep, pte, nr);
+ __sync_cache_and_tags(pte, nr);
for (;;) {
- __set_pte_at(mm, addr, ptep, pte);
+ __check_safe_pte_update(mm, ptep, pte);
+ set_pte(ptep, pte);
if (--nr == 0)
break;
ptep++;
- addr += PAGE_SIZE;
pte_val(pte) += PAGE_SIZE;
}
}
@@ -531,18 +528,29 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
#define pud_pfn(pud) ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT)
#define pfn_pud(pfn,prot) __pud(__phys_to_pud_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
+static inline void __set_pte_at(struct mm_struct *mm,
+ unsigned long __always_unused addr,
+ pte_t *ptep, pte_t pte, unsigned int nr)
+{
+ __sync_cache_and_tags(pte, nr);
+ __check_safe_pte_update(mm, ptep, pte);
+ set_pte(ptep, pte);
+}
+
static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
pmd_t *pmdp, pmd_t pmd)
{
page_table_check_pmd_set(mm, pmdp, pmd);
- return __set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd));
+ return __set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd),
+ PMD_SIZE >> PAGE_SHIFT);
}
static inline void set_pud_at(struct mm_struct *mm, unsigned long addr,
pud_t *pudp, pud_t pud)
{
page_table_check_pud_set(mm, pudp, pud);
- return __set_pte_at(mm, addr, (pte_t *)pudp, pud_pte(pud));
+ return __set_pte_at(mm, addr, (pte_t *)pudp, pud_pte(pud),
+ PUD_SIZE >> PAGE_SHIFT);
}
#define __p4d_to_phys(p4d) __pte_to_phys(p4d_pte(p4d))
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 9b31e6d0da17..efb13112b408 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -89,9 +89,9 @@ extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
-extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
+extern void arch_send_wakeup_ipi(unsigned int cpu);
#else
-static inline void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+static inline void arch_send_wakeup_ipi(unsigned int cpu)
{
BUILD_BUG();
}
diff --git a/arch/arm64/include/asm/spectre.h b/arch/arm64/include/asm/spectre.h
index 9cc501450486..06c357d83b13 100644
--- a/arch/arm64/include/asm/spectre.h
+++ b/arch/arm64/include/asm/spectre.h
@@ -73,7 +73,7 @@ static __always_inline void arm64_apply_bp_hardening(void)
{
struct bp_hardening_data *d;
- if (!cpus_have_const_cap(ARM64_SPECTRE_V2))
+ if (!alternative_has_cap_unlikely(ARM64_SPECTRE_V2))
return;
d = this_cpu_ptr(&bp_hardening_data);
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index b149cf9f91bc..7aa476a52180 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -105,7 +105,7 @@ static inline unsigned long get_trans_granule(void)
#define __tlbi_level(op, addr, level) do { \
u64 arg = addr; \
\
- if (cpus_have_const_cap(ARM64_HAS_ARMv8_4_TTL) && \
+ if (alternative_has_cap_unlikely(ARM64_HAS_ARMv8_4_TTL) && \
level) { \
u64 ttl = level & 3; \
ttl |= get_trans_granule() << 2; \
@@ -284,16 +284,15 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
{
-#ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
/*
* TLB flush deferral is not required on systems which are affected by
* ARM64_WORKAROUND_REPEAT_TLBI, as __tlbi()/__tlbi_user() implementation
* will have two consecutive TLBI instructions with a dsb(ish) in between
* defeating the purpose (i.e save overall 'dsb ish' cost).
*/
- if (unlikely(cpus_have_const_cap(ARM64_WORKAROUND_REPEAT_TLBI)))
+ if (alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI))
return false;
-#endif
+
return true;
}
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index c453291154fd..9f7c1bf99526 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -508,8 +508,8 @@ __SYSCALL(__NR_io_submit, compat_sys_io_submit)
__SYSCALL(__NR_io_cancel, sys_io_cancel)
#define __NR_exit_group 248
__SYSCALL(__NR_exit_group, sys_exit_group)
-#define __NR_lookup_dcookie 249
-__SYSCALL(__NR_lookup_dcookie, compat_sys_lookup_dcookie)
+ /* 249 was lookup_dcookie */
+__SYSCALL(249, sys_ni_syscall)
#define __NR_epoll_create 250
__SYSCALL(__NR_epoll_create, sys_epoll_create)
#define __NR_epoll_ctl 251
@@ -911,6 +911,8 @@ __SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node)
__SYSCALL(__NR_cachestat, sys_cachestat)
#define __NR_fchmodat2 452
__SYSCALL(__NR_fchmodat2, sys_fchmodat2)
+#define __NR_map_shadow_stack 453
+__SYSCALL(__NR_map_shadow_stack, sys_map_shadow_stack)
#define __NR_futex_wake 454
__SYSCALL(__NR_futex_wake, sys_futex_wake)
#define __NR_futex_wait 455
diff --git a/arch/arm64/include/asm/vectors.h b/arch/arm64/include/asm/vectors.h
index bc9a2145f419..b815d8f2c0dc 100644
--- a/arch/arm64/include/asm/vectors.h
+++ b/arch/arm64/include/asm/vectors.h
@@ -62,7 +62,7 @@ DECLARE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector);
static inline const char *
arm64_get_bp_hardening_vector(enum arm64_bp_harden_el1_vectors slot)
{
- if (arm64_kernel_unmapped_at_el0())
+ if (cpus_have_cap(ARM64_UNMAP_KERNEL_AT_EL0))
return (char *)(TRAMP_VALIAS + SZ_2K * slot);
WARN_ON_ONCE(slot == EL1_VECTOR_KPTI);
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index 53026f45a509..5023599fa278 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -104,5 +104,8 @@
#define HWCAP2_SME_F16F16 (1UL << 42)
#define HWCAP2_MOPS (1UL << 43)
#define HWCAP2_HBC (1UL << 44)
+#define HWCAP2_SVE_B16B16 (1UL << 45)
+#define HWCAP2_LRCPC3 (1UL << 46)
+#define HWCAP2_LSE128 (1UL << 47)
#endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/kernel/acpi_parking_protocol.c b/arch/arm64/kernel/acpi_parking_protocol.c
index b1990e38aed0..e1be29e608b7 100644
--- a/arch/arm64/kernel/acpi_parking_protocol.c
+++ b/arch/arm64/kernel/acpi_parking_protocol.c
@@ -103,7 +103,7 @@ static int acpi_parking_protocol_cpu_boot(unsigned int cpu)
&mailbox->entry_point);
writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id);
- arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+ arch_send_wakeup_ipi(cpu);
return 0;
}
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index e459cfd33711..dd6ce86d4332 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -52,10 +52,8 @@ struct insn_emulation {
int min;
int max;
- /*
- * sysctl for this emulation + a sentinal entry.
- */
- struct ctl_table sysctl[2];
+ /* sysctl for this emulation */
+ struct ctl_table sysctl;
};
#define ARM_OPCODE_CONDTEST_FAIL 0
@@ -558,7 +556,7 @@ static void __init register_insn_emulation(struct insn_emulation *insn)
update_insn_emulation_mode(insn, INSN_UNDEF);
if (insn->status != INSN_UNAVAILABLE) {
- sysctl = &insn->sysctl[0];
+ sysctl = &insn->sysctl;
sysctl->mode = 0644;
sysctl->maxlen = sizeof(int);
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 5706e74c5578..e29e0fea63fb 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -121,22 +121,6 @@ cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused)
sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCI, 0);
}
-static DEFINE_RAW_SPINLOCK(reg_user_mask_modification);
-static void __maybe_unused
-cpu_clear_bf16_from_user_emulation(const struct arm64_cpu_capabilities *__unused)
-{
- struct arm64_ftr_reg *regp;
-
- regp = get_arm64_ftr_reg(SYS_ID_AA64ISAR1_EL1);
- if (!regp)
- return;
-
- raw_spin_lock(&reg_user_mask_modification);
- if (regp->user_mask & ID_AA64ISAR1_EL1_BF16_MASK)
- regp->user_mask &= ~ID_AA64ISAR1_EL1_BF16_MASK;
- raw_spin_unlock(&reg_user_mask_modification);
-}
-
#define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max) \
.matches = is_affected_midr_range, \
.midr_range = MIDR_RANGE(model, v_min, r_min, v_max, r_max)
@@ -727,7 +711,6 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
/* Cortex-A510 r0p0 - r1p1 */
ERRATA_MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1),
MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)),
- .cpu_enable = cpu_clear_bf16_from_user_emulation,
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2966298
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 444a73c2e638..f6b2e2906fc9 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -279,6 +279,8 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_SHA3_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
+ FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_B16B16_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_BF16_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_BitPerm_SHIFT, 4, 0),
@@ -611,18 +613,6 @@ static const struct arm64_ftr_bits ftr_id_dfr1[] = {
ARM64_FTR_END,
};
-static const struct arm64_ftr_bits ftr_zcr[] = {
- ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE,
- ZCR_ELx_LEN_SHIFT, ZCR_ELx_LEN_WIDTH, 0), /* LEN */
- ARM64_FTR_END,
-};
-
-static const struct arm64_ftr_bits ftr_smcr[] = {
- ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE,
- SMCR_ELx_LEN_SHIFT, SMCR_ELx_LEN_WIDTH, 0), /* LEN */
- ARM64_FTR_END,
-};
-
/*
* Common ftr bits for a 32bit register with all hidden, strict
* attributes, with 4bit feature fields and a default safe value of
@@ -735,10 +725,6 @@ static const struct __ftr_reg_entry {
ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
ARM64_FTR_REG(SYS_ID_AA64MMFR3_EL1, ftr_id_aa64mmfr3),
- /* Op1 = 0, CRn = 1, CRm = 2 */
- ARM64_FTR_REG(SYS_ZCR_EL1, ftr_zcr),
- ARM64_FTR_REG(SYS_SMCR_EL1, ftr_smcr),
-
/* Op1 = 1, CRn = 0, CRm = 0 */
ARM64_FTR_REG(SYS_GMID_EL1, ftr_gmid),
@@ -1040,22 +1026,26 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
if (IS_ENABLED(CONFIG_ARM64_SVE) &&
id_aa64pfr0_sve(read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1))) {
- info->reg_zcr = read_zcr_features();
- init_cpu_ftr_reg(SYS_ZCR_EL1, info->reg_zcr);
+ unsigned long cpacr = cpacr_save_enable_kernel_sve();
+
vec_init_vq_map(ARM64_VEC_SVE);
+
+ cpacr_restore(cpacr);
}
if (IS_ENABLED(CONFIG_ARM64_SME) &&
id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
- info->reg_smcr = read_smcr_features();
+ unsigned long cpacr = cpacr_save_enable_kernel_sme();
+
/*
* We mask out SMPS since even if the hardware
* supports priorities the kernel does not at present
* and we block access to them.
*/
info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
- init_cpu_ftr_reg(SYS_SMCR_EL1, info->reg_smcr);
vec_init_vq_map(ARM64_VEC_SME);
+
+ cpacr_restore(cpacr);
}
if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
@@ -1289,32 +1279,34 @@ void update_cpu_features(int cpu,
taint |= check_update_ftr_reg(SYS_ID_AA64SMFR0_EL1, cpu,
info->reg_id_aa64smfr0, boot->reg_id_aa64smfr0);
+ /* Probe vector lengths */
if (IS_ENABLED(CONFIG_ARM64_SVE) &&
id_aa64pfr0_sve(read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1))) {
- info->reg_zcr = read_zcr_features();
- taint |= check_update_ftr_reg(SYS_ZCR_EL1, cpu,
- info->reg_zcr, boot->reg_zcr);
+ if (!system_capabilities_finalized()) {
+ unsigned long cpacr = cpacr_save_enable_kernel_sve();
- /* Probe vector lengths */
- if (!system_capabilities_finalized())
vec_update_vq_map(ARM64_VEC_SVE);
+
+ cpacr_restore(cpacr);
+ }
}
if (IS_ENABLED(CONFIG_ARM64_SME) &&
id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
- info->reg_smcr = read_smcr_features();
+ unsigned long cpacr = cpacr_save_enable_kernel_sme();
+
/*
* We mask out SMPS since even if the hardware
* supports priorities the kernel does not at present
* and we block access to them.
*/
info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
- taint |= check_update_ftr_reg(SYS_SMCR_EL1, cpu,
- info->reg_smcr, boot->reg_smcr);
/* Probe vector lengths */
if (!system_capabilities_finalized())
vec_update_vq_map(ARM64_VEC_SME);
+
+ cpacr_restore(cpacr);
}
/*
@@ -1564,14 +1556,6 @@ static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry, int _
MIDR_CPU_VAR_REV(1, MIDR_REVISION_MASK));
}
-static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unused)
-{
- u64 pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
-
- return cpuid_feature_extract_signed_field(pfr0,
- ID_AA64PFR0_EL1_FP_SHIFT) < 0;
-}
-
static bool has_cache_idc(const struct arm64_cpu_capabilities *entry,
int scope)
{
@@ -1621,7 +1605,7 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope)
if (is_kdump_kernel())
return false;
- if (cpus_have_const_cap(ARM64_WORKAROUND_NVIDIA_CARMEL_CNP))
+ if (cpus_have_cap(ARM64_WORKAROUND_NVIDIA_CARMEL_CNP))
return false;
return has_cpuid_feature(entry, scope);
@@ -1754,16 +1738,15 @@ void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt,
phys_addr_t size, pgprot_t prot,
phys_addr_t (*pgtable_alloc)(int), int flags);
-static phys_addr_t kpti_ng_temp_alloc;
+static phys_addr_t __initdata kpti_ng_temp_alloc;
-static phys_addr_t kpti_ng_pgd_alloc(int shift)
+static phys_addr_t __init kpti_ng_pgd_alloc(int shift)
{
kpti_ng_temp_alloc -= PAGE_SIZE;
return kpti_ng_temp_alloc;
}
-static void
-kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
+static int __init __kpti_install_ng_mappings(void *__unused)
{
typedef void (kpti_remap_fn)(int, int, phys_addr_t, unsigned long);
extern kpti_remap_fn idmap_kpti_install_ng_mappings;
@@ -1776,20 +1759,6 @@ kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
pgd_t *kpti_ng_temp_pgd;
u64 alloc = 0;
- if (__this_cpu_read(this_cpu_vector) == vectors) {
- const char *v = arm64_get_bp_hardening_vector(EL1_VECTOR_KPTI);
-
- __this_cpu_write(this_cpu_vector, v);
- }
-
- /*
- * We don't need to rewrite the page-tables if either we've done
- * it already or we have KASLR enabled and therefore have not
- * created any global mappings at all.
- */
- if (arm64_use_ng_mappings)
- return;
-
remap_fn = (void *)__pa_symbol(idmap_kpti_install_ng_mappings);
if (!cpu) {
@@ -1826,14 +1795,39 @@ kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
free_pages(alloc, order);
arm64_use_ng_mappings = true;
}
+
+ return 0;
+}
+
+static void __init kpti_install_ng_mappings(void)
+{
+ /*
+ * We don't need to rewrite the page-tables if either we've done
+ * it already or we have KASLR enabled and therefore have not
+ * created any global mappings at all.
+ */
+ if (arm64_use_ng_mappings)
+ return;
+
+ stop_machine(__kpti_install_ng_mappings, NULL, cpu_online_mask);
}
+
#else
-static void
-kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
+static inline void kpti_install_ng_mappings(void)
{
}
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
+static void cpu_enable_kpti(struct arm64_cpu_capabilities const *cap)
+{
+ if (__this_cpu_read(this_cpu_vector) == vectors) {
+ const char *v = arm64_get_bp_hardening_vector(EL1_VECTOR_KPTI);
+
+ __this_cpu_write(this_cpu_vector, v);
+ }
+
+}
+
static int __init parse_kpti(char *str)
{
bool enabled;
@@ -1848,6 +1842,8 @@ static int __init parse_kpti(char *str)
early_param("kpti", parse_kpti);
#ifdef CONFIG_ARM64_HW_AFDBM
+static struct cpumask dbm_cpus __read_mostly;
+
static inline void __cpu_enable_hw_dbm(void)
{
u64 tcr = read_sysreg(tcr_el1) | TCR_HD;
@@ -1883,35 +1879,22 @@ static bool cpu_can_use_dbm(const struct arm64_cpu_capabilities *cap)
static void cpu_enable_hw_dbm(struct arm64_cpu_capabilities const *cap)
{
- if (cpu_can_use_dbm(cap))
+ if (cpu_can_use_dbm(cap)) {
__cpu_enable_hw_dbm();
+ cpumask_set_cpu(smp_processor_id(), &dbm_cpus);
+ }
}
static bool has_hw_dbm(const struct arm64_cpu_capabilities *cap,
int __unused)
{
- static bool detected = false;
/*
* DBM is a non-conflicting feature. i.e, the kernel can safely
* run a mix of CPUs with and without the feature. So, we
* unconditionally enable the capability to allow any late CPU
* to use the feature. We only enable the control bits on the
- * CPU, if it actually supports.
- *
- * We have to make sure we print the "feature" detection only
- * when at least one CPU actually uses it. So check if this CPU
- * can actually use it and print the message exactly once.
- *
- * This is safe as all CPUs (including secondary CPUs - due to the
- * LOCAL_CPU scope - and the hotplugged CPUs - via verification)
- * goes through the "matches" check exactly once. Also if a CPU
- * matches the criteria, it is guaranteed that the CPU will turn
- * the DBM on, as the capability is unconditionally enabled.
+ * CPU, if it is supported.
*/
- if (!detected && cpu_can_use_dbm(cap)) {
- detected = true;
- pr_info("detected: Hardware dirty bit management\n");
- }
return true;
}
@@ -1944,8 +1927,6 @@ int get_cpu_with_amu_feat(void)
static void cpu_amu_enable(struct arm64_cpu_capabilities const *cap)
{
if (has_cpuid_feature(cap, SCOPE_LOCAL_CPU)) {
- pr_info("detected CPU%d: Activity Monitors Unit (AMU)\n",
- smp_processor_id());
cpumask_set_cpu(smp_processor_id(), &amu_cpus);
/* 0 reference values signal broken/disabled counters */
@@ -2190,12 +2171,23 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
}
#endif /* CONFIG_ARM64_MTE */
+static void user_feature_fixup(void)
+{
+ if (cpus_have_cap(ARM64_WORKAROUND_2658417)) {
+ struct arm64_ftr_reg *regp;
+
+ regp = get_arm64_ftr_reg(SYS_ID_AA64ISAR1_EL1);
+ if (regp)
+ regp->user_mask &= ~ID_AA64ISAR1_EL1_BF16_MASK;
+ }
+}
+
static void elf_hwcap_fixup(void)
{
-#ifdef CONFIG_ARM64_ERRATUM_1742098
- if (cpus_have_const_cap(ARM64_WORKAROUND_1742098))
+#ifdef CONFIG_COMPAT
+ if (cpus_have_cap(ARM64_WORKAROUND_1742098))
compat_elf_hwcap2 &= ~COMPAT_HWCAP2_AES;
-#endif /* ARM64_ERRATUM_1742098 */
+#endif /* CONFIG_COMPAT */
}
#ifdef CONFIG_KVM
@@ -2351,7 +2343,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.desc = "Kernel page table isolation (KPTI)",
.capability = ARM64_UNMAP_KERNEL_AT_EL0,
.type = ARM64_CPUCAP_BOOT_RESTRICTED_CPU_LOCAL_FEATURE,
- .cpu_enable = kpti_install_ng_mappings,
+ .cpu_enable = cpu_enable_kpti,
.matches = unmap_kernel_at_el0,
/*
* The ID feature fields below are used to indicate that
@@ -2361,11 +2353,11 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, CSV3, IMP)
},
{
- /* FP/SIMD is not implemented */
- .capability = ARM64_HAS_NO_FPSIMD,
- .type = ARM64_CPUCAP_BOOT_RESTRICTED_CPU_LOCAL_FEATURE,
- .min_field_value = 0,
- .matches = has_no_fpsimd,
+ .capability = ARM64_HAS_FPSIMD,
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .matches = has_cpuid_feature,
+ .cpu_enable = cpu_enable_fpsimd,
+ ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, FP, IMP)
},
#ifdef CONFIG_ARM64_PMEM
{
@@ -2388,7 +2380,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.desc = "Scalable Vector Extension",
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.capability = ARM64_SVE,
- .cpu_enable = sve_kernel_enable,
+ .cpu_enable = cpu_enable_sve,
.matches = has_cpuid_feature,
ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, SVE, IMP)
},
@@ -2405,16 +2397,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
#endif /* CONFIG_ARM64_RAS_EXTN */
#ifdef CONFIG_ARM64_AMU_EXTN
{
- /*
- * The feature is enabled by default if CONFIG_ARM64_AMU_EXTN=y.
- * Therefore, don't provide .desc as we don't want the detection
- * message to be shown until at least one CPU is detected to
- * support the feature.
- */
+ .desc = "Activity Monitors Unit (AMU)",
.capability = ARM64_HAS_AMU_EXTN,
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
.matches = has_amu,
.cpu_enable = cpu_amu_enable,
+ .cpus = &amu_cpus,
ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, AMU, IMP)
},
#endif /* CONFIG_ARM64_AMU_EXTN */
@@ -2454,18 +2442,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
},
#ifdef CONFIG_ARM64_HW_AFDBM
{
- /*
- * Since we turn this on always, we don't want the user to
- * think that the feature is available when it may not be.
- * So hide the description.
- *
- * .desc = "Hardware pagetable Dirty Bit Management",
- *
- */
+ .desc = "Hardware dirty bit management",
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
.capability = ARM64_HW_DBM,
.matches = has_hw_dbm,
.cpu_enable = cpu_enable_hw_dbm,
+ .cpus = &dbm_cpus,
ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, DBM)
},
#endif
@@ -2641,7 +2623,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.capability = ARM64_SME,
.matches = has_cpuid_feature,
- .cpu_enable = sme_kernel_enable,
+ .cpu_enable = cpu_enable_sme,
ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, SME, IMP)
},
/* FA64 should be sorted after the base SME capability */
@@ -2650,7 +2632,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.capability = ARM64_SME_FA64,
.matches = has_cpuid_feature,
- .cpu_enable = fa64_kernel_enable,
+ .cpu_enable = cpu_enable_fa64,
ARM64_CPUID_FIELDS(ID_AA64SMFR0_EL1, FA64, IMP)
},
{
@@ -2658,7 +2640,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.capability = ARM64_SME2,
.matches = has_cpuid_feature,
- .cpu_enable = sme2_kernel_enable,
+ .cpu_enable = cpu_enable_sme2,
ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, SME, SME2)
},
#endif /* CONFIG_ARM64_SME */
@@ -2787,6 +2769,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
HWCAP_CAP(ID_AA64ISAR0_EL1, SHA2, SHA512, CAP_HWCAP, KERNEL_HWCAP_SHA512),
HWCAP_CAP(ID_AA64ISAR0_EL1, CRC32, IMP, CAP_HWCAP, KERNEL_HWCAP_CRC32),
HWCAP_CAP(ID_AA64ISAR0_EL1, ATOMIC, IMP, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
+ HWCAP_CAP(ID_AA64ISAR0_EL1, ATOMIC, FEAT_LSE128, CAP_HWCAP, KERNEL_HWCAP_LSE128),
HWCAP_CAP(ID_AA64ISAR0_EL1, RDM, IMP, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
HWCAP_CAP(ID_AA64ISAR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SHA3),
HWCAP_CAP(ID_AA64ISAR0_EL1, SM3, IMP, CAP_HWCAP, KERNEL_HWCAP_SM3),
@@ -2807,6 +2790,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
HWCAP_CAP(ID_AA64ISAR1_EL1, FCMA, IMP, CAP_HWCAP, KERNEL_HWCAP_FCMA),
HWCAP_CAP(ID_AA64ISAR1_EL1, LRCPC, IMP, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
HWCAP_CAP(ID_AA64ISAR1_EL1, LRCPC, LRCPC2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
+ HWCAP_CAP(ID_AA64ISAR1_EL1, LRCPC, LRCPC3, CAP_HWCAP, KERNEL_HWCAP_LRCPC3),
HWCAP_CAP(ID_AA64ISAR1_EL1, FRINTTS, IMP, CAP_HWCAP, KERNEL_HWCAP_FRINT),
HWCAP_CAP(ID_AA64ISAR1_EL1, SB, IMP, CAP_HWCAP, KERNEL_HWCAP_SB),
HWCAP_CAP(ID_AA64ISAR1_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_BF16),
@@ -2821,6 +2805,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
HWCAP_CAP(ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
HWCAP_CAP(ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
HWCAP_CAP(ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
+ HWCAP_CAP(ID_AA64ZFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_B16B16),
HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16),
HWCAP_CAP(ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
@@ -2981,7 +2966,7 @@ static void update_cpu_capabilities(u16 scope_mask)
!caps->matches(caps, cpucap_default_scope(caps)))
continue;
- if (caps->desc)
+ if (caps->desc && !caps->cpus)
pr_info("detected: %s\n", caps->desc);
__set_bit(caps->capability, system_cpucaps);
@@ -3153,36 +3138,28 @@ static void verify_local_elf_hwcaps(void)
static void verify_sve_features(void)
{
- u64 safe_zcr = read_sanitised_ftr_reg(SYS_ZCR_EL1);
- u64 zcr = read_zcr_features();
+ unsigned long cpacr = cpacr_save_enable_kernel_sve();
- unsigned int safe_len = safe_zcr & ZCR_ELx_LEN_MASK;
- unsigned int len = zcr & ZCR_ELx_LEN_MASK;
-
- if (len < safe_len || vec_verify_vq_map(ARM64_VEC_SVE)) {
+ if (vec_verify_vq_map(ARM64_VEC_SVE)) {
pr_crit("CPU%d: SVE: vector length support mismatch\n",
smp_processor_id());
cpu_die_early();
}
- /* Add checks on other ZCR bits here if necessary */
+ cpacr_restore(cpacr);
}
static void verify_sme_features(void)
{
- u64 safe_smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
- u64 smcr = read_smcr_features();
-
- unsigned int safe_len = safe_smcr & SMCR_ELx_LEN_MASK;
- unsigned int len = smcr & SMCR_ELx_LEN_MASK;
+ unsigned long cpacr = cpacr_save_enable_kernel_sme();
- if (len < safe_len || vec_verify_vq_map(ARM64_VEC_SME)) {
+ if (vec_verify_vq_map(ARM64_VEC_SME)) {
pr_crit("CPU%d: SME: vector length support mismatch\n",
smp_processor_id());
cpu_die_early();
}
- /* Add checks on other SMCR bits here if necessary */
+ cpacr_restore(cpacr);
}
static void verify_hyp_capabilities(void)
@@ -3289,7 +3266,6 @@ EXPORT_SYMBOL_GPL(this_cpu_has_cap);
* This helper function is used in a narrow window when,
* - The system wide safe registers are set with all the SMP CPUs and,
* - The SYSTEM_FEATURE system_cpucaps may not have been set.
- * In all other cases cpus_have_{const_}cap() should be used.
*/
static bool __maybe_unused __system_matches_cap(unsigned int n)
{
@@ -3328,23 +3304,50 @@ unsigned long cpu_get_elf_hwcap2(void)
return elf_hwcap[1];
}
-static void __init setup_system_capabilities(void)
+void __init setup_system_features(void)
{
+ int i;
/*
- * We have finalised the system-wide safe feature
- * registers, finalise the capabilities that depend
- * on it. Also enable all the available capabilities,
- * that are not enabled already.
+ * The system-wide safe feature feature register values have been
+ * finalized. Finalize and log the available system capabilities.
*/
update_cpu_capabilities(SCOPE_SYSTEM);
+ if (IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN) &&
+ !cpus_have_cap(ARM64_HAS_PAN))
+ pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
+
+ /*
+ * Enable all the available capabilities which have not been enabled
+ * already.
+ */
enable_cpu_capabilities(SCOPE_ALL & ~SCOPE_BOOT_CPU);
+
+ kpti_install_ng_mappings();
+
+ sve_setup();
+ sme_setup();
+
+ /*
+ * Check for sane CTR_EL0.CWG value.
+ */
+ if (!cache_type_cwg())
+ pr_warn("No Cache Writeback Granule information, assuming %d\n",
+ ARCH_DMA_MINALIGN);
+
+ for (i = 0; i < ARM64_NCAPS; i++) {
+ const struct arm64_cpu_capabilities *caps = cpucap_ptrs[i];
+
+ if (caps && caps->cpus && caps->desc &&
+ cpumask_any(caps->cpus) < nr_cpu_ids)
+ pr_info("detected: %s on CPU%*pbl\n",
+ caps->desc, cpumask_pr_args(caps->cpus));
+ }
}
-void __init setup_cpu_features(void)
+void __init setup_user_features(void)
{
- u32 cwg;
+ user_feature_fixup();
- setup_system_capabilities();
setup_elf_hwcaps(arm64_elf_hwcaps);
if (system_supports_32bit_el0()) {
@@ -3352,20 +3355,7 @@ void __init setup_cpu_features(void)
elf_hwcap_fixup();
}
- if (system_uses_ttbr0_pan())
- pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
-
- sve_setup();
- sme_setup();
minsigstksz_setup();
-
- /*
- * Check for sane CTR_EL0.CWG value.
- */
- cwg = cache_type_cwg();
- if (!cwg)
- pr_warn("No Cache Writeback Granule information, assuming %d\n",
- ARCH_DMA_MINALIGN);
}
static int enable_mismatched_32bit_el0(unsigned int cpu)
@@ -3422,7 +3412,7 @@ subsys_initcall_sync(init_32bit_el0_mask);
static void __maybe_unused cpu_enable_cnp(struct arm64_cpu_capabilities const *cap)
{
- cpu_replace_ttbr1(lm_alias(swapper_pg_dir), idmap_pg_dir);
+ cpu_enable_swapper_cnp();
}
/*
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 98fda8500535..a257da7b56fe 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -127,6 +127,9 @@ static const char *const hwcap_str[] = {
[KERNEL_HWCAP_SME_F16F16] = "smef16f16",
[KERNEL_HWCAP_MOPS] = "mops",
[KERNEL_HWCAP_HBC] = "hbc",
+ [KERNEL_HWCAP_SVE_B16B16] = "sveb16b16",
+ [KERNEL_HWCAP_LRCPC3] = "lrcpc3",
+ [KERNEL_HWCAP_LSE128] = "lse128",
};
#ifdef CONFIG_COMPAT
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 2b478ca356b0..3f8c9c143552 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -113,8 +113,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
if (md->attribute & EFI_MEMORY_XP)
pte = set_pte_bit(pte, __pgprot(PTE_PXN));
- else if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) &&
- system_supports_bti() && spd->has_bti)
+ else if (system_supports_bti_kernel() && spd->has_bti)
pte = set_pte_bit(pte, __pgprot(PTE_GP));
set_pte(ptep, pte);
return 0;
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 91e44ac7150f..1559c706d32d 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -589,7 +589,6 @@ static struct ctl_table sve_default_vl_table[] = {
.proc_handler = vec_proc_do_default_vl,
.extra1 = &vl_info[ARM64_VEC_SVE],
},
- { }
};
static int __init sve_sysctl_init(void)
@@ -613,7 +612,6 @@ static struct ctl_table sme_default_vl_table[] = {
.proc_handler = vec_proc_do_default_vl,
.extra1 = &vl_info[ARM64_VEC_SME],
},
- { }
};
static int __init sme_sysctl_init(void)
@@ -1160,44 +1158,20 @@ fail:
panic("Cannot allocate percpu memory for EFI SVE save/restore");
}
-/*
- * Enable SVE for EL1.
- * Intended for use by the cpufeatures code during CPU boot.
- */
-void sve_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+void cpu_enable_sve(const struct arm64_cpu_capabilities *__always_unused p)
{
write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_ZEN_EL1EN, CPACR_EL1);
isb();
}
-/*
- * Read the pseudo-ZCR used by cpufeatures to identify the supported SVE
- * vector length.
- *
- * Use only if SVE is present.
- * This function clobbers the SVE vector length.
- */
-u64 read_zcr_features(void)
-{
- /*
- * Set the maximum possible VL, and write zeroes to all other
- * bits to see if they stick.
- */
- sve_kernel_enable(NULL);
- write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL1);
-
- /* Return LEN value that would be written to get the maximum VL */
- return sve_vq_from_vl(sve_get_vl()) - 1;
-}
-
void __init sve_setup(void)
{
struct vl_info *info = &vl_info[ARM64_VEC_SVE];
- u64 zcr;
DECLARE_BITMAP(tmp_map, SVE_VQ_MAX);
unsigned long b;
+ int max_bit;
- if (!system_supports_sve())
+ if (!cpus_have_cap(ARM64_SVE))
return;
/*
@@ -1208,17 +1182,8 @@ void __init sve_setup(void)
if (WARN_ON(!test_bit(__vq_to_bit(SVE_VQ_MIN), info->vq_map)))
set_bit(__vq_to_bit(SVE_VQ_MIN), info->vq_map);
- zcr = read_sanitised_ftr_reg(SYS_ZCR_EL1);
- info->max_vl = sve_vl_from_vq((zcr & ZCR_ELx_LEN_MASK) + 1);
-
- /*
- * Sanity-check that the max VL we determined through CPU features
- * corresponds properly to sve_vq_map. If not, do our best:
- */
- if (WARN_ON(info->max_vl != find_supported_vector_length(ARM64_VEC_SVE,
- info->max_vl)))
- info->max_vl = find_supported_vector_length(ARM64_VEC_SVE,
- info->max_vl);
+ max_bit = find_first_bit(info->vq_map, SVE_VQ_MAX);
+ info->max_vl = sve_vl_from_vq(__bit_to_vq(max_bit));
/*
* For the default VL, pick the maximum supported value <= 64.
@@ -1296,7 +1261,7 @@ static void sme_free(struct task_struct *task)
task->thread.sme_state = NULL;
}
-void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+void cpu_enable_sme(const struct arm64_cpu_capabilities *__always_unused p)
{
/* Set priority for all PEs to architecturally defined minimum */
write_sysreg_s(read_sysreg_s(SYS_SMPRI_EL1) & ~SMPRI_EL1_PRIORITY_MASK,
@@ -1311,80 +1276,48 @@ void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
isb();
}
-/*
- * This must be called after sme_kernel_enable(), we rely on the
- * feature table being sorted to ensure this.
- */
-void sme2_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+void cpu_enable_sme2(const struct arm64_cpu_capabilities *__always_unused p)
{
+ /* This must be enabled after SME */
+ BUILD_BUG_ON(ARM64_SME2 <= ARM64_SME);
+
/* Allow use of ZT0 */
write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_EZT0_MASK,
SYS_SMCR_EL1);
}
-/*
- * This must be called after sme_kernel_enable(), we rely on the
- * feature table being sorted to ensure this.
- */
-void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+void cpu_enable_fa64(const struct arm64_cpu_capabilities *__always_unused p)
{
+ /* This must be enabled after SME */
+ BUILD_BUG_ON(ARM64_SME_FA64 <= ARM64_SME);
+
/* Allow use of FA64 */
write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_FA64_MASK,
SYS_SMCR_EL1);
}
-/*
- * Read the pseudo-SMCR used by cpufeatures to identify the supported
- * vector length.
- *
- * Use only if SME is present.
- * This function clobbers the SME vector length.
- */
-u64 read_smcr_features(void)
-{
- sme_kernel_enable(NULL);
-
- /*
- * Set the maximum possible VL.
- */
- write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_LEN_MASK,
- SYS_SMCR_EL1);
-
- /* Return LEN value that would be written to get the maximum VL */
- return sve_vq_from_vl(sme_get_vl()) - 1;
-}
-
void __init sme_setup(void)
{
struct vl_info *info = &vl_info[ARM64_VEC_SME];
- u64 smcr;
- int min_bit;
+ int min_bit, max_bit;
- if (!system_supports_sme())
+ if (!cpus_have_cap(ARM64_SME))
return;
/*
* SME doesn't require any particular vector length be
* supported but it does require at least one. We should have
* disabled the feature entirely while bringing up CPUs but
- * let's double check here.
+ * let's double check here. The bitmap is SVE_VQ_MAP sized for
+ * sharing with SVE.
*/
WARN_ON(bitmap_empty(info->vq_map, SVE_VQ_MAX));
min_bit = find_last_bit(info->vq_map, SVE_VQ_MAX);
info->min_vl = sve_vl_from_vq(__bit_to_vq(min_bit));
- smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
- info->max_vl = sve_vl_from_vq((smcr & SMCR_ELx_LEN_MASK) + 1);
-
- /*
- * Sanity-check that the max VL we determined through CPU features
- * corresponds properly to sme_vq_map. If not, do our best:
- */
- if (WARN_ON(info->max_vl != find_supported_vector_length(ARM64_VEC_SME,
- info->max_vl)))
- info->max_vl = find_supported_vector_length(ARM64_VEC_SME,
- info->max_vl);
+ max_bit = find_first_bit(info->vq_map, SVE_VQ_MAX);
+ info->max_vl = sve_vl_from_vq(__bit_to_vq(max_bit));
WARN_ON(info->min_vl > info->max_vl);
@@ -1529,8 +1462,17 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
*/
void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs)
{
- /* TODO: implement lazy context saving/restoring */
- WARN_ON(1);
+ /* Even if we chose not to use FPSIMD, the hardware could still trap: */
+ if (!system_supports_fpsimd()) {
+ force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
+ return;
+ }
+
+ /*
+ * When FPSIMD is enabled, we should never take a trap unless something
+ * has gone very wrong.
+ */
+ BUG();
}
/*
@@ -1771,13 +1713,23 @@ void fpsimd_bind_state_to_cpu(struct cpu_fp_state *state)
void fpsimd_restore_current_state(void)
{
/*
- * For the tasks that were created before we detected the absence of
- * FP/SIMD, the TIF_FOREIGN_FPSTATE could be set via fpsimd_thread_switch(),
- * e.g, init. This could be then inherited by the children processes.
- * If we later detect that the system doesn't support FP/SIMD,
- * we must clear the flag for all the tasks to indicate that the
- * FPSTATE is clean (as we can't have one) to avoid looping for ever in
- * do_notify_resume().
+ * TIF_FOREIGN_FPSTATE is set on the init task and copied by
+ * arch_dup_task_struct() regardless of whether FP/SIMD is detected.
+ * Thus user threads can have this set even when FP/SIMD hasn't been
+ * detected.
+ *
+ * When FP/SIMD is detected, begin_new_exec() will set
+ * TIF_FOREIGN_FPSTATE via flush_thread() -> fpsimd_flush_thread(),
+ * and fpsimd_thread_switch() will set TIF_FOREIGN_FPSTATE when
+ * switching tasks. We detect FP/SIMD before we exec the first user
+ * process, ensuring this has TIF_FOREIGN_FPSTATE set and
+ * do_notify_resume() will call fpsimd_restore_current_state() to
+ * install the user FP/SIMD context.
+ *
+ * When FP/SIMD is not detected, nothing else will clear or set
+ * TIF_FOREIGN_FPSTATE prior to the first return to userspace, and
+ * we must clear TIF_FOREIGN_FPSTATE to avoid do_notify_resume()
+ * looping forever calling fpsimd_restore_current_state().
*/
if (!system_supports_fpsimd()) {
clear_thread_flag(TIF_FOREIGN_FPSTATE);
@@ -2110,6 +2062,13 @@ static inline void fpsimd_hotplug_init(void)
static inline void fpsimd_hotplug_init(void) { }
#endif
+void cpu_enable_fpsimd(const struct arm64_cpu_capabilities *__always_unused p)
+{
+ unsigned long enable = CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN;
+ write_sysreg(read_sysreg(CPACR_EL1) | enable, CPACR_EL1);
+ isb();
+}
+
/*
* FP/SIMD support code initialisation.
*/
diff --git a/arch/arm64/kernel/idle.c b/arch/arm64/kernel/idle.c
index c1125753fe9b..05cfb347ec26 100644
--- a/arch/arm64/kernel/idle.c
+++ b/arch/arm64/kernel/idle.c
@@ -20,7 +20,7 @@
* ensure that interrupts are not masked at the PMR (because the core will
* not wake up if we block the wake up signal in the interrupt controller).
*/
-void noinstr cpu_do_idle(void)
+void __cpuidle cpu_do_idle(void)
{
struct arm_cpuidle_irq_context context;
@@ -35,7 +35,7 @@ void noinstr cpu_do_idle(void)
/*
* This is our default idle handler.
*/
-void noinstr arch_cpu_idle(void)
+void __cpuidle arch_cpu_idle(void)
{
/*
* This should do all the clock switching and wait for interrupt
diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c
index bd69a4e7cd60..bde32979c06a 100644
--- a/arch/arm64/kernel/module-plts.c
+++ b/arch/arm64/kernel/module-plts.c
@@ -167,9 +167,6 @@ static unsigned int count_plts(Elf64_Sym *syms, Elf64_Rela *rela, int num,
switch (ELF64_R_TYPE(rela[i].r_info)) {
case R_AARCH64_JUMP26:
case R_AARCH64_CALL26:
- if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE))
- break;
-
/*
* We only have to consider branch targets that resolve
* to symbols that are defined in a different section.
@@ -203,8 +200,7 @@ static unsigned int count_plts(Elf64_Sym *syms, Elf64_Rela *rela, int num,
break;
case R_AARCH64_ADR_PREL_PG_HI21_NC:
case R_AARCH64_ADR_PREL_PG_HI21:
- if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_843419) ||
- !cpus_have_const_cap(ARM64_WORKAROUND_843419))
+ if (!cpus_have_final_cap(ARM64_WORKAROUND_843419))
break;
/*
@@ -239,13 +235,13 @@ static unsigned int count_plts(Elf64_Sym *syms, Elf64_Rela *rela, int num,
}
}
- if (IS_ENABLED(CONFIG_ARM64_ERRATUM_843419) &&
- cpus_have_const_cap(ARM64_WORKAROUND_843419))
+ if (cpus_have_final_cap(ARM64_WORKAROUND_843419)) {
/*
* Add some slack so we can skip PLT slots that may trigger
* the erratum due to the placement of the ADRP instruction.
*/
ret += DIV_ROUND_UP(ret, (SZ_4K / sizeof(struct plt_entry)));
+ }
return ret;
}
@@ -269,9 +265,6 @@ static int partition_branch_plt_relas(Elf64_Sym *syms, Elf64_Rela *rela,
{
int i = 0, j = numrels - 1;
- if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE))
- return 0;
-
while (i < j) {
if (branch_rela_needs_plt(syms, &rela[i], dstidx))
i++;
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index 4edecaac8f91..2fb5e7a7a4d5 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -35,10 +35,10 @@ DEFINE_STATIC_KEY_FALSE(mte_async_or_asymm_mode);
EXPORT_SYMBOL_GPL(mte_async_or_asymm_mode);
#endif
-void mte_sync_tags(pte_t pte)
+void mte_sync_tags(pte_t pte, unsigned int nr_pages)
{
struct page *page = pte_page(pte);
- long i, nr_pages = compound_nr(page);
+ unsigned int i;
/* if PG_mte_tagged is set, tags have already been initialised */
for (i = 0; i < nr_pages; i++, page++) {
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 0fcc4eb1a7ab..7387b68c745b 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -454,7 +454,7 @@ static void ssbs_thread_switch(struct task_struct *next)
* If all CPUs implement the SSBS extension, then we just need to
* context-switch the PSTATE field.
*/
- if (cpus_have_const_cap(ARM64_SSBS))
+ if (alternative_has_cap_unlikely(ARM64_SSBS))
return;
spectre_v4_enable_task_mitigation(next);
@@ -724,7 +724,6 @@ static struct ctl_table tagged_addr_sysctl_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
- { }
};
static int __init tagged_addr_init(void)
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 05f40c4e18fd..6268a13a1d58 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -972,7 +972,7 @@ static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
* When KPTI is in use, the vectors are switched when exiting to
* user-space.
*/
- if (arm64_kernel_unmapped_at_el0())
+ if (cpus_have_cap(ARM64_UNMAP_KERNEL_AT_EL0))
return;
write_sysreg(v, vbar_el1);
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 196533c362e1..be95b523c101 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -32,7 +32,9 @@
#include <linux/irq_work.h>
#include <linux/kernel_stat.h>
#include <linux/kexec.h>
+#include <linux/kgdb.h>
#include <linux/kvm_host.h>
+#include <linux/nmi.h>
#include <asm/alternative.h>
#include <asm/atomic.h>
@@ -72,13 +74,19 @@ enum ipi_msg_type {
IPI_CPU_CRASH_STOP,
IPI_TIMER,
IPI_IRQ_WORK,
- IPI_WAKEUP,
- NR_IPI
+ NR_IPI,
+ /*
+ * Any enum >= NR_IPI and < MAX_IPI is special and not tracable
+ * with trace_ipi_*
+ */
+ IPI_CPU_BACKTRACE = NR_IPI,
+ IPI_KGDB_ROUNDUP,
+ MAX_IPI
};
-static int ipi_irq_base __read_mostly;
-static int nr_ipi __read_mostly = NR_IPI;
-static struct irq_desc *ipi_desc[NR_IPI] __read_mostly;
+static int ipi_irq_base __ro_after_init;
+static int nr_ipi __ro_after_init = NR_IPI;
+static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init;
static void ipi_setup(int cpu);
@@ -431,9 +439,10 @@ static void __init hyp_mode_check(void)
void __init smp_cpus_done(unsigned int max_cpus)
{
pr_info("SMP: Total of %d processors activated.\n", num_online_cpus());
- setup_cpu_features();
+ setup_system_features();
hyp_mode_check();
apply_alternatives_all();
+ setup_user_features();
mark_linear_text_alias_ro();
}
@@ -520,7 +529,7 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
{
u64 hwid = processor->arm_mpidr;
- if (!(processor->flags & ACPI_MADT_ENABLED)) {
+ if (!acpi_gicc_is_usable(processor)) {
pr_debug("skipping disabled CPU entry with 0x%llx MPIDR\n", hwid);
return;
}
@@ -764,7 +773,6 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
[IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts",
[IPI_TIMER] = "Timer broadcast interrupts",
[IPI_IRQ_WORK] = "IRQ work interrupts",
- [IPI_WAKEUP] = "CPU wake-up interrupts",
};
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr);
@@ -797,13 +805,6 @@ void arch_send_call_function_single_ipi(int cpu)
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC);
}
-#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
-void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
-{
- smp_cross_call(mask, IPI_WAKEUP);
-}
-#endif
-
#ifdef CONFIG_IRQ_WORK
void arch_irq_work_raise(void)
{
@@ -854,6 +855,38 @@ static void __noreturn ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs
#endif
}
+static void arm64_backtrace_ipi(cpumask_t *mask)
+{
+ __ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask);
+}
+
+void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
+{
+ /*
+ * NOTE: though nmi_trigger_cpumask_backtrace() has "nmi_" in the name,
+ * nothing about it truly needs to be implemented using an NMI, it's
+ * just that it's _allowed_ to work with NMIs. If ipi_should_be_nmi()
+ * returned false our backtrace attempt will just use a regular IPI.
+ */
+ nmi_trigger_cpumask_backtrace(mask, exclude_cpu, arm64_backtrace_ipi);
+}
+
+#ifdef CONFIG_KGDB
+void kgdb_roundup_cpus(void)
+{
+ int this_cpu = raw_smp_processor_id();
+ int cpu;
+
+ for_each_online_cpu(cpu) {
+ /* No need to roundup ourselves */
+ if (cpu == this_cpu)
+ continue;
+
+ __ipi_send_single(ipi_desc[IPI_KGDB_ROUNDUP], cpu);
+ }
+}
+#endif
+
/*
* Main handler for inter-processor interrupts
*/
@@ -897,13 +930,17 @@ static void do_handle_IPI(int ipinr)
break;
#endif
-#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
- case IPI_WAKEUP:
- WARN_ONCE(!acpi_parking_protocol_valid(cpu),
- "CPU%u: Wake-up IPI outside the ACPI parking protocol\n",
- cpu);
+ case IPI_CPU_BACKTRACE:
+ /*
+ * NOTE: in some cases this _won't_ be NMI context. See the
+ * comment in arch_trigger_cpumask_backtrace().
+ */
+ nmi_cpu_backtrace(get_irq_regs());
+ break;
+
+ case IPI_KGDB_ROUNDUP:
+ kgdb_nmicallback(cpu, get_irq_regs());
break;
-#endif
default:
pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
@@ -926,6 +963,25 @@ static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
__ipi_send_mask(ipi_desc[ipinr], target);
}
+static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
+{
+ DECLARE_STATIC_KEY_FALSE(supports_pseudo_nmis);
+
+ if (!system_uses_irq_prio_masking() ||
+ !static_branch_likely(&supports_pseudo_nmis))
+ return false;
+
+ switch (ipi) {
+ case IPI_CPU_STOP:
+ case IPI_CPU_CRASH_STOP:
+ case IPI_CPU_BACKTRACE:
+ case IPI_KGDB_ROUNDUP:
+ return true;
+ default:
+ return false;
+ }
+}
+
static void ipi_setup(int cpu)
{
int i;
@@ -933,8 +989,14 @@ static void ipi_setup(int cpu)
if (WARN_ON_ONCE(!ipi_irq_base))
return;
- for (i = 0; i < nr_ipi; i++)
- enable_percpu_irq(ipi_irq_base + i, 0);
+ for (i = 0; i < nr_ipi; i++) {
+ if (ipi_should_be_nmi(i)) {
+ prepare_percpu_nmi(ipi_irq_base + i);
+ enable_percpu_nmi(ipi_irq_base + i, 0);
+ } else {
+ enable_percpu_irq(ipi_irq_base + i, 0);
+ }
+ }
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -945,8 +1007,14 @@ static void ipi_teardown(int cpu)
if (WARN_ON_ONCE(!ipi_irq_base))
return;
- for (i = 0; i < nr_ipi; i++)
- disable_percpu_irq(ipi_irq_base + i);
+ for (i = 0; i < nr_ipi; i++) {
+ if (ipi_should_be_nmi(i)) {
+ disable_percpu_nmi(ipi_irq_base + i);
+ teardown_percpu_nmi(ipi_irq_base + i);
+ } else {
+ disable_percpu_irq(ipi_irq_base + i);
+ }
+ }
}
#endif
@@ -954,15 +1022,23 @@ void __init set_smp_ipi_range(int ipi_base, int n)
{
int i;
- WARN_ON(n < NR_IPI);
- nr_ipi = min(n, NR_IPI);
+ WARN_ON(n < MAX_IPI);
+ nr_ipi = min(n, MAX_IPI);
for (i = 0; i < nr_ipi; i++) {
int err;
- err = request_percpu_irq(ipi_base + i, ipi_handler,
- "IPI", &cpu_number);
- WARN_ON(err);
+ if (ipi_should_be_nmi(i)) {
+ err = request_percpu_nmi(ipi_base + i, ipi_handler,
+ "IPI", &cpu_number);
+ WARN(err, "Could not request IPI %d as NMI, err=%d\n",
+ i, err);
+ } else {
+ err = request_percpu_irq(ipi_base + i, ipi_handler,
+ "IPI", &cpu_number);
+ WARN(err, "Could not request IPI %d as IRQ, err=%d\n",
+ i, err);
+ }
ipi_desc[i] = irq_to_desc(ipi_base + i);
irq_set_status_flags(ipi_base + i, IRQ_HIDDEN);
@@ -979,6 +1055,17 @@ void arch_smp_send_reschedule(int cpu)
smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
}
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+void arch_send_wakeup_ipi(unsigned int cpu)
+{
+ /*
+ * We use a scheduler IPI to wake the CPU as this avoids the need for a
+ * dedicated IPI and we can safely handle spurious scheduler IPIs.
+ */
+ smp_send_reschedule(cpu);
+}
+#endif
+
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
void tick_broadcast(const struct cpumask *mask)
{
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 0fbdf5fe64d8..eca4d0435211 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -55,13 +55,13 @@ void notrace __cpu_suspend_exit(void)
/* Restore CnP bit in TTBR1_EL1 */
if (system_supports_cnp())
- cpu_replace_ttbr1(lm_alias(swapper_pg_dir), idmap_pg_dir);
+ cpu_enable_swapper_cnp();
/*
* PSTATE was not saved over suspend/resume, re-enable any detected
* features that might not have been set correctly.
*/
- if (cpus_have_const_cap(ARM64_HAS_DIT))
+ if (alternative_has_cap_unlikely(ARM64_HAS_DIT))
set_pstate_dit(1);
__uaccess_enable_hw_pan();
@@ -98,6 +98,15 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
struct sleep_stack_data state;
struct arm_cpuidle_irq_context context;
+ /*
+ * Some portions of CPU state (e.g. PSTATE.{PAN,DIT}) are initialized
+ * before alternatives are patched, but are only restored by
+ * __cpu_suspend_exit() after alternatives are patched. To avoid
+ * accidentally losing these bits we must not attempt to suspend until
+ * after alternatives have been patched.
+ */
+ WARN_ON(!system_capabilities_finalized());
+
/* Report any MTE async fault before going to suspend */
mte_suspend_enter();
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index df14336c3a29..4a609e9b65de 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -31,7 +31,7 @@ __do_compat_cache_op(unsigned long start, unsigned long end)
if (fatal_signal_pending(current))
return 0;
- if (cpus_have_const_cap(ARM64_WORKAROUND_1542419)) {
+ if (cpus_have_final_cap(ARM64_WORKAROUND_1542419)) {
/*
* The workaround requires an inner-shareable tlbi.
* We pick the reserved-ASID to minimise the impact.
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 8b70759cdbb9..9eba6cdd7038 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -631,7 +631,7 @@ static void ctr_read_handler(unsigned long esr, struct pt_regs *regs)
int rt = ESR_ELx_SYS64_ISS_RT(esr);
unsigned long val = arm64_ftr_reg_user_value(&arm64_ftr_reg_ctrel0);
- if (cpus_have_const_cap(ARM64_WORKAROUND_1542419)) {
+ if (cpus_have_final_cap(ARM64_WORKAROUND_1542419)) {
/* Hide DIC so that we can trap the unnecessary maintenance...*/
val &= ~BIT(CTR_EL0_DIC_SHIFT);
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index d9e1355730ef..5562daf38a22 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -212,7 +212,7 @@ static int __setup_additional_pages(enum vdso_abi abi,
if (IS_ERR(ret))
goto up_fail;
- if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) && system_supports_bti())
+ if (system_supports_bti_kernel())
gp_flags = VM_ARM64_BTI;
vdso_base += VVAR_NR_PAGES * PAGE_SIZE;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 4866b3f7b4ea..4ea6c22250a5 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -284,7 +284,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = kvm_arm_pvtime_supported();
break;
case KVM_CAP_ARM_EL1_32BIT:
- r = cpus_have_const_cap(ARM64_HAS_32BIT_EL1);
+ r = cpus_have_final_cap(ARM64_HAS_32BIT_EL1);
break;
case KVM_CAP_GUEST_DEBUG_HW_BPS:
r = get_num_brps();
@@ -296,7 +296,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = kvm_arm_support_pmu_v3();
break;
case KVM_CAP_ARM_INJECT_SERROR_ESR:
- r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
+ r = cpus_have_final_cap(ARM64_HAS_RAS_EXTN);
break;
case KVM_CAP_ARM_VM_IPA_SIZE:
r = get_kvm_ipa_limit();
@@ -1207,7 +1207,7 @@ static int kvm_vcpu_init_check_features(struct kvm_vcpu *vcpu,
if (!test_bit(KVM_ARM_VCPU_EL1_32BIT, &features))
return 0;
- if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1))
+ if (!cpus_have_final_cap(ARM64_HAS_32BIT_EL1))
return -EINVAL;
/* MTE is incompatible with AArch32 */
@@ -1777,7 +1777,7 @@ static void hyp_install_host_vector(void)
* Call initialization code, and switch to the full blown HYP code.
* If the cpucaps haven't been finalized yet, something has gone very
* wrong, and hyp will crash and burn when it uses any
- * cpus_have_const_cap() wrapper.
+ * cpus_have_*_cap() wrapper.
*/
BUG_ON(!system_capabilities_finalized());
params = this_cpu_ptr_nvhe_sym(kvm_init_params);
@@ -2310,7 +2310,7 @@ static int __init init_hyp_mode(void)
if (is_protected_kvm_enabled()) {
if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL) &&
- cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH))
+ cpus_have_final_cap(ARM64_HAS_ADDRESS_AUTH))
pkvm_hyp_init_ptrauth();
init_cpu_logical_map();
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 95f6945c4432..aaf1d4939739 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -815,7 +815,7 @@ int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
struct kvm_vcpu_events *events)
{
events->exception.serror_pending = !!(vcpu->arch.hcr_el2 & HCR_VSE);
- events->exception.serror_has_esr = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
+ events->exception.serror_has_esr = cpus_have_final_cap(ARM64_HAS_RAS_EXTN);
if (events->exception.serror_pending && events->exception.serror_has_esr)
events->exception.serror_esr = vcpu_get_vsesr(vcpu);
@@ -837,7 +837,7 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
bool ext_dabt_pending = events->exception.ext_dabt_pending;
if (serror_pending && has_esr) {
- if (!cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+ if (!cpus_have_final_cap(ARM64_HAS_RAS_EXTN))
return -EINVAL;
if (!((events->exception.serror_esr) & ~ESR_ELx_ISS_MASK))
@@ -874,7 +874,7 @@ u32 __attribute_const__ kvm_target_cpu(void)
break;
case ARM_CPU_IMP_APM:
switch (part_number) {
- case APM_CPU_PART_POTENZA:
+ case APM_CPU_PART_XGENE:
return KVM_ARM_TARGET_XGENE_POTENZA;
}
break;
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 6e4dba9eadef..320f2eaa14a9 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -423,6 +423,7 @@ static __always_inline void do_ffa_mem_xfer(const u64 func_id,
DECLARE_REG(u32, fraglen, ctxt, 2);
DECLARE_REG(u64, addr_mbz, ctxt, 3);
DECLARE_REG(u32, npages_mbz, ctxt, 4);
+ struct ffa_mem_region_attributes *ep_mem_access;
struct ffa_composite_mem_region *reg;
struct ffa_mem_region *buf;
u32 offset, nr_ranges;
@@ -452,7 +453,9 @@ static __always_inline void do_ffa_mem_xfer(const u64 func_id,
buf = hyp_buffers.tx;
memcpy(buf, host_buffers.tx, fraglen);
- offset = buf->ep_mem_access[0].composite_off;
+ ep_mem_access = (void *)buf +
+ ffa_mem_desc_offset(buf, 0, FFA_VERSION_1_0);
+ offset = ep_mem_access->composite_off;
if (!offset || buf->ep_count != 1 || buf->sender_id != HOST_FFA_ID) {
ret = FFA_RET_INVALID_PARAMETERS;
goto out_unlock;
@@ -504,6 +507,7 @@ static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
DECLARE_REG(u32, handle_lo, ctxt, 1);
DECLARE_REG(u32, handle_hi, ctxt, 2);
DECLARE_REG(u32, flags, ctxt, 3);
+ struct ffa_mem_region_attributes *ep_mem_access;
struct ffa_composite_mem_region *reg;
u32 offset, len, fraglen, fragoff;
struct ffa_mem_region *buf;
@@ -528,7 +532,9 @@ static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
len = res->a1;
fraglen = res->a2;
- offset = buf->ep_mem_access[0].composite_off;
+ ep_mem_access = (void *)buf +
+ ffa_mem_desc_offset(buf, 0, FFA_VERSION_1_0);
+ offset = ep_mem_access->composite_off;
/*
* We can trust the SPMD to get this right, but let's at least
* check that we end up with something that doesn't look _completely_
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index f155b8c9e98c..77fb330c7bf4 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -401,7 +401,7 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
if (device)
return -EINVAL;
- if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) && system_supports_bti())
+ if (system_supports_bti_kernel())
attr |= KVM_PTE_LEAF_ATTR_HI_S1_GP;
} else {
attr |= KVM_PTE_LEAF_ATTR_HI_S1_XN;
@@ -664,7 +664,7 @@ u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
static bool stage2_has_fwb(struct kvm_pgtable *pgt)
{
- if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
+ if (!cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
return false;
return !(pgt->flags & KVM_PGTABLE_S2_NOFWB);
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 482280fe22d7..e6061fd174b0 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1578,7 +1578,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (device)
prot |= KVM_PGTABLE_PROT_DEVICE;
- else if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC))
+ else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
prot |= KVM_PGTABLE_PROT_X;
/*
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 0afd6136e275..b78017ed22e6 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -207,7 +207,7 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
* CPU left in the system, and certainly not from non-secure
* software).
*/
- if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
+ if (!cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
kvm_set_way_flush(vcpu);
return true;
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 3dfc8b84e03e..9465d3706ab9 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -684,7 +684,7 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
if (kvm_vgic_global_state.vcpu_base == 0)
kvm_info("disabling GICv2 emulation\n");
- if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_30115)) {
+ if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_30115)) {
group0_trap = true;
group1_trap = true;
}
diff --git a/arch/arm64/lib/delay.c b/arch/arm64/lib/delay.c
index 5b7890139bc2..cb2062e7e234 100644
--- a/arch/arm64/lib/delay.c
+++ b/arch/arm64/lib/delay.c
@@ -27,7 +27,7 @@ void __delay(unsigned long cycles)
{
cycles_t start = get_cycles();
- if (cpus_have_const_cap(ARM64_HAS_WFXT)) {
+ if (alternative_has_cap_unlikely(ARM64_HAS_WFXT)) {
u64 end = start + cycles;
/*
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 2e5d1e238af9..460d799e1296 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -571,7 +571,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
/* Write implies read */
vm_flags |= VM_WRITE;
/* If EPAN is absent then exec implies read */
- if (!cpus_have_const_cap(ARM64_HAS_EPAN))
+ if (!alternative_has_cap_unlikely(ARM64_HAS_EPAN))
vm_flags |= VM_EXEC;
}
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 13fd592228b1..f5aae342632c 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -544,8 +544,7 @@ bool __init arch_hugetlb_valid_size(unsigned long size)
pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
{
- if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2645198) &&
- cpus_have_const_cap(ARM64_WORKAROUND_2645198)) {
+ if (alternative_has_cap_unlikely(ARM64_WORKAROUND_2645198)) {
/*
* Break-before-make (BBM) is required for all user space mappings
* when the permission changes from executable to non-executable
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8a0f8604348b..8deec68028ac 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -16,6 +16,7 @@
#include <linux/nodemask.h>
#include <linux/initrd.h>
#include <linux/gfp.h>
+#include <linux/math.h>
#include <linux/memblock.h>
#include <linux/sort.h>
#include <linux/of.h>
@@ -493,8 +494,16 @@ void __init mem_init(void)
{
bool swiotlb = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
- if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC))
+ if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb) {
+ /*
+ * If no bouncing needed for ZONE_DMA, reduce the swiotlb
+ * buffer for kmalloc() bouncing to 1MB per 1GB of RAM.
+ */
+ unsigned long size =
+ DIV_ROUND_UP(memblock_phys_mem_size(), 1024);
+ swiotlb_adjust_size(min(swiotlb_size_or_default(), size));
swiotlb = true;
+ }
swiotlb_init(swiotlb, SWIOTLB_VERBOSE);
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 8f5b7ce857ed..645fe60d000f 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -68,7 +68,7 @@ static int __init adjust_protection_map(void)
* With Enhanced PAN we can honour the execute-only permissions as
* there is no PAN override with such mappings.
*/
- if (cpus_have_const_cap(ARM64_HAS_EPAN)) {
+ if (cpus_have_cap(ARM64_HAS_EPAN)) {
protection_map[VM_EXEC] = PAGE_EXECONLY;
protection_map[VM_EXEC | VM_SHARED] = PAGE_EXECONLY;
}
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 47781bec6171..15f6347d23b6 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1469,8 +1469,7 @@ early_initcall(prevent_bootmem_remove_init);
pte_t ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
{
- if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2645198) &&
- cpus_have_const_cap(ARM64_WORKAROUND_2645198)) {
+ if (alternative_has_cap_unlikely(ARM64_WORKAROUND_2645198)) {
/*
* Break-before-make (BBM) is required for all user space mappings
* when the permission changes from executable to non-executable
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 14fdf645edc8..f66c37a1610e 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -405,8 +405,7 @@ SYM_FUNC_START(__cpu_setup)
tlbi vmalle1 // Invalidate local TLB
dsb nsh
- mov x1, #3 << 20
- msr cpacr_el1, x1 // Enable FP/ASIMD
+ msr cpacr_el1, xzr // Reset cpacr_el1
mov x1, #1 << 12 // Reset mdscr_el1 and disable
msr mdscr_el1, x1 // access to the DCC from EL0
isb // Unmask debug exceptions now,
diff --git a/arch/arm64/tools/Makefile b/arch/arm64/tools/Makefile
index 07a93ab21a62..fa2251d9762d 100644
--- a/arch/arm64/tools/Makefile
+++ b/arch/arm64/tools/Makefile
@@ -3,7 +3,7 @@
gen := arch/$(ARCH)/include/generated
kapi := $(gen)/asm
-kapi-hdrs-y := $(kapi)/cpucaps.h $(kapi)/sysreg-defs.h
+kapi-hdrs-y := $(kapi)/cpucap-defs.h $(kapi)/sysreg-defs.h
targets += $(addprefix ../../../, $(kapi-hdrs-y))
@@ -17,7 +17,7 @@ quiet_cmd_gen_cpucaps = GEN $@
quiet_cmd_gen_sysreg = GEN $@
cmd_gen_sysreg = mkdir -p $(dir $@); $(AWK) -f $(real-prereqs) > $@
-$(kapi)/cpucaps.h: $(src)/gen-cpucaps.awk $(src)/cpucaps FORCE
+$(kapi)/cpucap-defs.h: $(src)/gen-cpucaps.awk $(src)/cpucaps FORCE
$(call if_changed,gen_cpucaps)
$(kapi)/sysreg-defs.h: $(src)/gen-sysreg.awk $(src)/sysreg FORCE
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index dea3dc89234b..b98c38288a9d 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -27,6 +27,7 @@ HAS_ECV_CNTPOFF
HAS_EPAN
HAS_EVT
HAS_FGT
+HAS_FPSIMD
HAS_GENERIC_AUTH
HAS_GENERIC_AUTH_ARCH_QARMA3
HAS_GENERIC_AUTH_ARCH_QARMA5
@@ -39,7 +40,6 @@ HAS_LDAPR
HAS_LSE_ATOMICS
HAS_MOPS
HAS_NESTED_VIRT
-HAS_NO_FPSIMD
HAS_NO_HW_PREFETCH
HAS_PAN
HAS_S1PIE
diff --git a/arch/arm64/tools/gen-cpucaps.awk b/arch/arm64/tools/gen-cpucaps.awk
index 8525980379d7..2f4f61a0af17 100755
--- a/arch/arm64/tools/gen-cpucaps.awk
+++ b/arch/arm64/tools/gen-cpucaps.awk
@@ -15,8 +15,8 @@ function fatal(msg) {
/^#/ { next }
BEGIN {
- print "#ifndef __ASM_CPUCAPS_H"
- print "#define __ASM_CPUCAPS_H"
+ print "#ifndef __ASM_CPUCAP_DEFS_H"
+ print "#define __ASM_CPUCAP_DEFS_H"
print ""
print "/* Generated file - do not edit */"
cap_num = 0
@@ -31,7 +31,7 @@ BEGIN {
END {
printf("#define ARM64_NCAPS\t\t\t\t\t%d\n", cap_num)
print ""
- print "#endif /* __ASM_CPUCAPS_H */"
+ print "#endif /* __ASM_CPUCAP_DEFS_H */"
}
# Any lines not handled by previous rules are unexpected
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 76ce150e7347..96cbeeab4eec 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1026,7 +1026,11 @@ UnsignedEnum 35:32 SHA3
0b0000 NI
0b0001 IMP
EndEnum
-Res0 31:24
+Res0 31:28
+UnsignedEnum 27:24 B16B16
+ 0b0000 NI
+ 0b0001 IMP
+EndEnum
UnsignedEnum 23:20 BF16
0b0000 NI
0b0001 IMP
@@ -1235,6 +1239,7 @@ EndEnum
UnsignedEnum 23:20 ATOMIC
0b0000 NI
0b0010 IMP
+ 0b0011 FEAT_LSE128
EndEnum
UnsignedEnum 19:16 CRC32
0b0000 NI
@@ -1305,6 +1310,7 @@ UnsignedEnum 23:20 LRCPC
0b0000 NI
0b0001 IMP
0b0010 LRCPC2
+ 0b0011 LRCPC3
EndEnum
UnsignedEnum 19:16 FCMA
0b0000 NI
diff --git a/arch/csky/abiv1/alignment.c b/arch/csky/abiv1/alignment.c
index b60259daed1b..e5b8b4b2109a 100644
--- a/arch/csky/abiv1/alignment.c
+++ b/arch/csky/abiv1/alignment.c
@@ -329,7 +329,6 @@ static struct ctl_table alignment_tbl[5] = {
.mode = 0666,
.proc_handler = &proc_dointvec
},
- {}
};
static int __init csky_alignment_init(void)
diff --git a/arch/hexagon/include/asm/ptrace.h b/arch/hexagon/include/asm/ptrace.h
new file mode 100644
index 000000000000..ed35da1ee685
--- /dev/null
+++ b/arch/hexagon/include/asm/ptrace.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ptrace definitions for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _ASM_HEXAGON_PTRACE_H
+#define _ASM_HEXAGON_PTRACE_H
+
+#include <uapi/asm/ptrace.h>
+
+/* kprobe-based event tracer support */
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+
+#define current_pt_regs() \
+ ((struct pt_regs *) \
+ ((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
+
+#if CONFIG_HEXAGON_ARCH_VERSION >= 4
+#define arch_has_single_step() (1)
+#endif
+
+#endif
diff --git a/arch/hexagon/include/uapi/asm/ptrace.h b/arch/hexagon/include/uapi/asm/ptrace.h
index f79de05b8689..2a3ea14ad9b9 100644
--- a/arch/hexagon/include/uapi/asm/ptrace.h
+++ b/arch/hexagon/include/uapi/asm/ptrace.h
@@ -29,17 +29,4 @@
#define profile_pc(regs) instruction_pointer(regs)
-/* kprobe-based event tracer support */
-extern int regs_query_register_offset(const char *name);
-extern const char *regs_query_register_name(unsigned int offset);
-
-#define current_pt_regs() \
- ((struct pt_regs *) \
- ((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
-
-#if CONFIG_HEXAGON_ARCH_VERSION >= 4
-#define arch_has_single_step() (1)
-#endif
-
-
#endif
diff --git a/arch/ia64/Kbuild b/arch/ia64/Kbuild
deleted file mode 100644
index e77cc76d228c..000000000000
--- a/arch/ia64/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-y += kernel/ mm/
-obj-$(CONFIG_IA64_SGI_UV) += uv/
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
deleted file mode 100644
index 53faa122b0f4..000000000000
--- a/arch/ia64/Kconfig
+++ /dev/null
@@ -1,394 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config PGTABLE_LEVELS
- int "Page Table Levels" if !IA64_PAGE_SIZE_64KB
- range 3 4 if !IA64_PAGE_SIZE_64KB
- default 3
-
-menu "Processor type and features"
-
-config IA64
- bool
- select ARCH_BINFMT_ELF_EXTRA_PHDRS
- select ARCH_HAS_CPU_FINALIZE_INIT
- select ARCH_HAS_DMA_MARK_CLEAN
- select ARCH_HAS_STRNCPY_FROM_USER
- select ARCH_HAS_STRNLEN_USER
- select ARCH_MIGHT_HAVE_PC_PARPORT
- select ARCH_MIGHT_HAVE_PC_SERIO
- select ACPI
- select ACPI_NUMA if NUMA
- select ARCH_ENABLE_MEMORY_HOTPLUG
- select ARCH_ENABLE_MEMORY_HOTREMOVE
- select ARCH_SUPPORTS_ACPI
- select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI
- select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
- select FORCE_PCI
- select PCI_DOMAINS if PCI
- select PCI_MSI
- select PCI_SYSCALL if PCI
- select HAS_IOPORT
- select HAVE_ASM_MODVERSIONS
- select HAVE_UNSTABLE_SCHED_CLOCK
- select HAVE_EXIT_THREAD
- select HAVE_KPROBES
- select HAVE_KRETPROBES
- select HAVE_FTRACE_MCOUNT_RECORD
- select HAVE_DYNAMIC_FTRACE if (!ITANIUM)
- select HAVE_FUNCTION_TRACER
- select HAVE_SETUP_PER_CPU_AREA
- select TTY
- select HAVE_ARCH_TRACEHOOK
- select HAVE_FUNCTION_DESCRIPTORS
- select HAVE_VIRT_CPU_ACCOUNTING
- select HUGETLB_PAGE_SIZE_VARIABLE if HUGETLB_PAGE
- select GENERIC_IRQ_PROBE
- select GENERIC_PENDING_IRQ if SMP
- select GENERIC_IRQ_SHOW
- select GENERIC_IRQ_LEGACY
- select ARCH_HAVE_NMI_SAFE_CMPXCHG
- select GENERIC_IOMAP
- select GENERIC_IOREMAP
- select GENERIC_SMP_IDLE_THREAD
- select ARCH_TASK_STRUCT_ON_STACK
- select ARCH_TASK_STRUCT_ALLOCATOR
- select ARCH_THREAD_STACK_ALLOCATOR
- select ARCH_CLOCKSOURCE_DATA
- select GENERIC_TIME_VSYSCALL
- select LEGACY_TIMER_TICK
- select SWIOTLB
- select SYSCTL_ARCH_UNALIGN_NO_WARN
- select HAVE_MOD_ARCH_SPECIFIC
- select MODULES_USE_ELF_RELA
- select ARCH_USE_CMPXCHG_LOCKREF
- select HAVE_ARCH_AUDITSYSCALL
- select NEED_DMA_MAP_STATE
- select NEED_SG_DMA_LENGTH
- select NUMA if !FLATMEM
- select PCI_MSI_ARCH_FALLBACKS if PCI_MSI
- select ZONE_DMA32
- select FUNCTION_ALIGNMENT_32B
- default y
- help
- The Itanium Processor Family is Intel's 64-bit successor to
- the 32-bit X86 line. The IA-64 Linux project has a home
- page at <http://www.linuxia64.org/> and a mailing list at
- <linux-ia64@vger.kernel.org>.
-
-config 64BIT
- bool
- select ATA_NONSTANDARD if ATA
- default y
-
-config MMU
- bool
- default y
-
-config STACKTRACE_SUPPORT
- def_bool y
-
-config GENERIC_LOCKBREAK
- def_bool n
-
-config GENERIC_CALIBRATE_DELAY
- bool
- default y
-
-config DMI
- bool
- default y
- select DMI_SCAN_MACHINE_NON_EFI_FALLBACK
-
-config EFI
- bool
- select UCS2_STRING
- default y
-
-config SCHED_OMIT_FRAME_POINTER
- bool
- default y
-
-config IA64_UNCACHED_ALLOCATOR
- bool
- select GENERIC_ALLOCATOR
-
-config ARCH_USES_PG_UNCACHED
- def_bool y
- depends on IA64_UNCACHED_ALLOCATOR
-
-config AUDIT_ARCH
- bool
- default y
-
-choice
- prompt "Processor type"
- default ITANIUM
-
-config ITANIUM
- bool "Itanium"
- help
- Select your IA-64 processor type. The default is Itanium.
- This choice is safe for all IA-64 systems, but may not perform
- optimally on systems with, say, Itanium 2 or newer processors.
-
-config MCKINLEY
- bool "Itanium 2"
- help
- Select this to configure for an Itanium 2 (McKinley) processor.
-
-endchoice
-
-choice
- prompt "Kernel page size"
- default IA64_PAGE_SIZE_16KB
-
-config IA64_PAGE_SIZE_4KB
- bool "4KB"
- help
- This lets you select the page size of the kernel. For best IA-64
- performance, a page size of 8KB or 16KB is recommended. For best
- IA-32 compatibility, a page size of 4KB should be selected (the vast
- majority of IA-32 binaries work perfectly fine with a larger page
- size). For Itanium 2 or newer systems, a page size of 64KB can also
- be selected.
-
- 4KB For best IA-32 compatibility
- 8KB For best IA-64 performance
- 16KB For best IA-64 performance
- 64KB Requires Itanium 2 or newer processor.
-
- If you don't know what to do, choose 16KB.
-
-config IA64_PAGE_SIZE_8KB
- bool "8KB"
-
-config IA64_PAGE_SIZE_16KB
- bool "16KB"
-
-config IA64_PAGE_SIZE_64KB
- depends on !ITANIUM
- bool "64KB"
-
-endchoice
-
-source "kernel/Kconfig.hz"
-
-config IA64_BRL_EMU
- bool
- depends on ITANIUM
- default y
-
-# align cache-sensitive data to 128 bytes
-config IA64_L1_CACHE_SHIFT
- int
- default "7" if MCKINLEY
- default "6" if ITANIUM
-
-config IA64_SGI_UV
- bool "SGI-UV support"
- help
- Selecting this option will add specific support for running on SGI
- UV based systems. If you have an SGI UV system or are building a
- distro kernel, select this option.
-
-config IA64_HP_SBA_IOMMU
- bool "HP SBA IOMMU support"
- select DMA_OPS
- default y
- help
- Say Y here to add support for the SBA IOMMU found on HP zx1 and
- sx1000 systems. If you're unsure, answer Y.
-
-config IA64_CYCLONE
- bool "Cyclone (EXA) Time Source support"
- help
- Say Y here to enable support for IBM EXA Cyclone time source.
- If you're unsure, answer N.
-
-config ARCH_FORCE_MAX_ORDER
- int
- default "16" if HUGETLB_PAGE
- default "10"
-
-config SMP
- bool "Symmetric multi-processing support"
- help
- This enables support for systems with more than one CPU. If you have
- a system with only one CPU, say N. If you have a system with more
- than one CPU, say Y.
-
- If you say N here, the kernel will run on single and multiprocessor
- systems, but will use only one CPU of a multiprocessor system. If
- you say Y here, the kernel will run on many, but not all,
- single processor systems. On a single processor system, the kernel
- will run faster if you say N here.
-
- See also the SMP-HOWTO available at
- <http://www.tldp.org/docs.html#howto>.
-
- If you don't know what to do here, say N.
-
-config NR_CPUS
- int "Maximum number of CPUs (2-4096)"
- range 2 4096
- depends on SMP
- default "4096"
- help
- You should set this to the number of CPUs in your system, but
- keep in mind that a kernel compiled for, e.g., 2 CPUs will boot but
- only use 2 CPUs on a >2 CPU system. Setting this to a value larger
- than 64 will cause the use of a CPU mask array, causing a small
- performance hit.
-
-config HOTPLUG_CPU
- bool "Support for hot-pluggable CPUs"
- depends on SMP
- default n
- help
- Say Y here to experiment with turning CPUs off and on. CPUs
- can be controlled through /sys/devices/system/cpu/cpu#.
- Say N if you want to disable CPU hotplug.
-
-config SCHED_SMT
- bool "SMT scheduler support"
- depends on SMP
- help
- Improves the CPU scheduler's decision making when dealing with
- Intel IA64 chips with MultiThreading at a cost of slightly increased
- overhead in some places. If unsure say N here.
-
-config PERMIT_BSP_REMOVE
- bool "Support removal of Bootstrap Processor"
- depends on HOTPLUG_CPU
- default n
- help
- Say Y here if your platform SAL will support removal of BSP with HOTPLUG_CPU
- support.
-
-config FORCE_CPEI_RETARGET
- bool "Force assumption that CPEI can be re-targeted"
- depends on PERMIT_BSP_REMOVE
- default n
- help
- Say Y if you need to force the assumption that CPEI can be re-targeted to
- any cpu in the system. This hint is available via ACPI 3.0 specifications.
- Tiger4 systems are capable of re-directing CPEI to any CPU other than BSP.
- This option it useful to enable this feature on older BIOS's as well.
- You can also enable this by using boot command line option force_cpei=1.
-
-config ARCH_SELECT_MEMORY_MODEL
- def_bool y
-
-config ARCH_FLATMEM_ENABLE
- def_bool y
-
-config ARCH_SPARSEMEM_ENABLE
- def_bool y
- select SPARSEMEM_VMEMMAP_ENABLE
-
-config ARCH_SPARSEMEM_DEFAULT
- def_bool y
- depends on ARCH_SPARSEMEM_ENABLE
-
-config NUMA
- bool "NUMA support"
- depends on !FLATMEM
- select SMP
- select USE_PERCPU_NUMA_NODE_ID
- help
- Say Y to compile the kernel to support NUMA (Non-Uniform Memory
- Access). This option is for configuring high-end multiprocessor
- server systems. If in doubt, say N.
-
-config NODES_SHIFT
- int "Max num nodes shift(3-10)"
- range 3 10
- default "10"
- depends on NUMA
- help
- This option specifies the maximum number of nodes in your SSI system.
- MAX_NUMNODES will be 2^(This value).
- If in doubt, use the default.
-
-config HAVE_ARCH_NODEDATA_EXTENSION
- def_bool y
- depends on NUMA
-
-config HAVE_MEMORYLESS_NODES
- def_bool NUMA
-
-config ARCH_PROC_KCORE_TEXT
- def_bool y
- depends on PROC_KCORE
-
-config IA64_MCA_RECOVERY
- bool "MCA recovery from errors other than TLB."
-
-config IA64_PALINFO
- tristate "/proc/pal support"
- help
- If you say Y here, you are able to get PAL (Processor Abstraction
- Layer) information in /proc/pal. This contains useful information
- about the processors in your systems, such as cache and TLB sizes
- and the PAL firmware version in use.
-
- To use this option, you have to ensure that the "/proc file system
- support" (CONFIG_PROC_FS) is enabled, too.
-
-config IA64_MC_ERR_INJECT
- tristate "MC error injection support"
- help
- Adds support for MC error injection. If enabled, the kernel
- will provide a sysfs interface for user applications to
- call MC error injection PAL procedures to inject various errors.
- This is a useful tool for MCA testing.
-
- If you're unsure, do not select this option.
-
-config IA64_ESI
- bool "ESI (Extensible SAL Interface) support"
- help
- If you say Y here, support is built into the kernel to
- make ESI calls. ESI calls are used to support vendor-specific
- firmware extensions, such as the ability to inject memory-errors
- for test-purposes. If you're unsure, say N.
-
-config IA64_HP_AML_NFW
- bool "Support ACPI AML calls to native firmware"
- help
- This driver installs a global ACPI Operation Region handler for
- region 0xA1. AML methods can use this OpRegion to call arbitrary
- native firmware functions. The driver installs the OpRegion
- handler if there is an HPQ5001 device or if the user supplies
- the "force" module parameter, e.g., with the "aml_nfw.force"
- kernel command line option.
-
-endmenu
-
-config ARCH_SUPPORTS_KEXEC
- def_bool !SMP || HOTPLUG_CPU
-
-config ARCH_SUPPORTS_CRASH_DUMP
- def_bool IA64_MCA_RECOVERY && (!SMP || HOTPLUG_CPU)
-
-menu "Power management and ACPI options"
-
-source "kernel/power/Kconfig"
-
-source "drivers/acpi/Kconfig"
-
-if PM
-menu "CPU Frequency scaling"
-source "drivers/cpufreq/Kconfig"
-endmenu
-endif
-
-endmenu
-
-config MSPEC
- tristate "Memory special operations driver"
- depends on IA64
- select IA64_UNCACHED_ALLOCATOR
- help
- If you have an ia64 and you want to enable memory special
- operations support (formerly known as fetchop), say Y here,
- otherwise say N.
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
deleted file mode 100644
index 2ce008e2d164..000000000000
--- a/arch/ia64/Kconfig.debug
+++ /dev/null
@@ -1,55 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-choice
- prompt "Physical memory granularity"
- default IA64_GRANULE_64MB
-
-config IA64_GRANULE_16MB
- bool "16MB"
- help
- IA-64 identity-mapped regions use a large page size called "granules".
-
- Select "16MB" for a small granule size.
- Select "64MB" for a large granule size. This is the current default.
-
-config IA64_GRANULE_64MB
- bool "64MB"
- depends on BROKEN
-
-endchoice
-
-config IA64_PRINT_HAZARDS
- bool "Print possible IA-64 dependency violations to console"
- depends on DEBUG_KERNEL
- help
- Selecting this option prints more information for Illegal Dependency
- Faults, that is, for Read-after-Write (RAW), Write-after-Write (WAW),
- or Write-after-Read (WAR) violations. This option is ignored if you
- are compiling for an Itanium A step processor
- (CONFIG_ITANIUM_ASTEP_SPECIFIC). If you're unsure, select Y.
-
-config DISABLE_VHPT
- bool "Disable VHPT"
- depends on DEBUG_KERNEL
- help
- The Virtual Hash Page Table (VHPT) enhances virtual address
- translation performance. Normally you want the VHPT active but you
- can select this option to disable the VHPT for debugging. If you're
- unsure, answer N.
-
-config IA64_DEBUG_CMPXCHG
- bool "Turn on compare-and-exchange bug checking (slow!)"
- depends on DEBUG_KERNEL && PRINTK
- help
- Selecting this option turns on bug checking for the IA-64
- compare-and-exchange instructions. This is slow! Itaniums
- from step B3 or later don't have this problem. If you're unsure,
- select N.
-
-config IA64_DEBUG_IRQ
- bool "Turn on irq debug checks (slow!)"
- depends on DEBUG_KERNEL
- help
- Selecting this option turns on bug checking for the IA-64 irq_save
- and restore instructions. It's useful for tracking down spinlock
- problems, but slow! If you're unsure, select N.
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
deleted file mode 100644
index d553ab7022fe..000000000000
--- a/arch/ia64/Makefile
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# ia64/Makefile
-#
-# This file is included by the global makefile so that you can add your own
-# architecture-specific flags and dependencies.
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License. See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1998-2004 by David Mosberger-Tang <davidm@hpl.hp.com>
-#
-
-KBUILD_DEFCONFIG := generic_defconfig
-
-NM := $(CROSS_COMPILE)nm -B
-
-CHECKFLAGS += -D__ia64=1 -D__ia64__=1 -D_LP64 -D__LP64__
-
-OBJCOPYFLAGS := --strip-all
-LDFLAGS_vmlinux := -static
-KBUILD_AFLAGS_KERNEL := -mconstant-gp
-EXTRA :=
-
-cflags-y := -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \
- -frename-registers -fno-optimize-sibling-calls
-KBUILD_CFLAGS_KERNEL := -mconstant-gp
-
-GAS_STATUS = $(shell $(srctree)/arch/ia64/scripts/check-gas "$(CC)" "$(OBJDUMP)")
-KBUILD_CPPFLAGS += $(shell $(srctree)/arch/ia64/scripts/toolchain-flags "$(CC)" "$(OBJDUMP)" "$(READELF)")
-
-ifeq ($(GAS_STATUS),buggy)
-$(error Sorry, you need a newer version of the assember, one that is built from \
- a source-tree that post-dates 18-Dec-2002. You can find a pre-compiled \
- static binary of such an assembler at: \
- \
- ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
-endif
-
-quiet_cmd_gzip = GZIP $@
-cmd_gzip = cat $(real-prereqs) | $(KGZIP) -n -f -9 > $@
-
-quiet_cmd_objcopy = OBJCOPY $@
-cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
-
-KBUILD_CFLAGS += $(cflags-y)
-
-libs-y += arch/ia64/lib/
-
-drivers-y += arch/ia64/pci/ arch/ia64/hp/common/
-
-PHONY += compressed check
-
-all: compressed unwcheck
-
-compressed: vmlinux.gz
-
-vmlinuz: vmlinux.gz
-
-vmlinux.gz: vmlinux.bin FORCE
- $(call if_changed,gzip)
-
-vmlinux.bin: vmlinux FORCE
- $(call if_changed,objcopy)
-
-unwcheck: vmlinux
- -$(Q)READELF=$(READELF) $(PYTHON3) $(srctree)/arch/ia64/scripts/unwcheck.py $<
-
-archheaders:
- $(Q)$(MAKE) $(build)=arch/ia64/kernel/syscalls all
-
-CLEAN_FILES += vmlinux.gz
-
-install: KBUILD_IMAGE := vmlinux.gz
-install:
- $(call cmd,install)
-
-define archhelp
- echo '* compressed - Build compressed kernel image'
- echo ' install - Install compressed kernel image'
- echo '* unwcheck - Check vmlinux for invalid unwind info'
-endef
diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig
deleted file mode 100644
index 7cb96db9a25d..000000000000
--- a/arch/ia64/configs/bigsur_defconfig
+++ /dev/null
@@ -1,102 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_PROFILING=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_SGI_PARTITION=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_PREEMPT=y
-CONFIG_IA64_PALINFO=y
-CONFIG_BINFMT_MISC=m
-CONFIG_ACPI_BUTTON=m
-CONFIG_ACPI_FAN=m
-CONFIG_ACPI_PROCESSOR=m
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IPV6 is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=m
-CONFIG_ATA=m
-CONFIG_ATA_GENERIC=m
-CONFIG_ATA_PIIX=m
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_QLOGIC_1280=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_EFI=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_AGP=m
-CONFIG_AGP_I460=m
-CONFIG_DRM=m
-CONFIG_DRM_R128=m
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_CS4281=m
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=m
-CONFIG_USB_MON=m
-CONFIG_USB_UHCI_HCD=m
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_XFS_FS=y
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_AUTOFS_FS=m
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_VFAT_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_HUGETLBFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V4=m
-CONFIG_NFSD=m
-CONFIG_NFSD_V4=y
-CONFIG_CIFS=m
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig
deleted file mode 100644
index 4581240013dd..000000000000
--- a/arch/ia64/configs/generic_defconfig
+++ /dev/null
@@ -1,206 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=20
-CONFIG_CGROUPS=y
-CONFIG_CPUSETS=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_SGI_PARTITION=y
-CONFIG_MCKINLEY=y
-CONFIG_IA64_PAGE_SIZE_64KB=y
-CONFIG_IA64_CYCLONE=y
-CONFIG_SMP=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_IA64_MCA_RECOVERY=y
-CONFIG_IA64_PALINFO=y
-CONFIG_KEXEC=y
-CONFIG_CRASH_DUMP=y
-CONFIG_BINFMT_MISC=m
-CONFIG_ACPI_BUTTON=m
-CONFIG_ACPI_FAN=m
-CONFIG_ACPI_DOCK=y
-CONFIG_ACPI_PROCESSOR=m
-CONFIG_HOTPLUG_PCI=y
-CONFIG_HOTPLUG_PCI_ACPI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_CONNECTOR=y
-# CONFIG_PNP_DEBUG_MESSAGES is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_SGI_XP=m
-CONFIG_ATA=y
-CONFIG_ATA_GENERIC=y
-CONFIG_PATA_CMD64X=y
-CONFIG_ATA_PIIX=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_QLOGIC_1280=y
-CONFIG_SATA_VITESSE=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_FC=m
-CONFIG_FUSION_SAS=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_NETCONSOLE=y
-CONFIG_TIGON3=y
-CONFIG_NET_TULIP=y
-CONFIG_TULIP=m
-CONFIG_E100=m
-CONFIG_E1000=y
-CONFIG_IGB=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_GAMEPORT=m
-CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=6
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_EFI=y
-CONFIG_HPET=y
-CONFIG_AGP=m
-CONFIG_AGP_I460=m
-CONFIG_AGP_HP_ZX1=m
-CONFIG_DRM=m
-CONFIG_DRM_TDFX=m
-CONFIG_DRM_R128=m
-CONFIG_DRM_RADEON=m
-CONFIG_DRM_MGA=m
-CONFIG_DRM_SIS=m
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_SEQUENCER_OSS=y
-CONFIG_SND_VERBOSE_PRINTK=y
-CONFIG_SND_DUMMY=m
-CONFIG_SND_VIRMIDI=m
-CONFIG_SND_MTPAV=m
-CONFIG_SND_SERIAL_U16550=m
-CONFIG_SND_MPU401=m
-CONFIG_SND_CS4281=m
-CONFIG_SND_CS46XX=m
-CONFIG_SND_EMU10K1=m
-CONFIG_SND_FM801=m
-CONFIG_HID_GYRATION=m
-CONFIG_HID_PANTHERLORD=m
-CONFIG_HID_PETALYNX=m
-CONFIG_HID_SAMSUNG=m
-CONFIG_HID_SONY=m
-CONFIG_HID_SUNPLUS=m
-CONFIG_USB=m
-CONFIG_USB_MON=m
-CONFIG_USB_EHCI_HCD=m
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_UHCI_HCD=m
-CONFIG_USB_STORAGE=m
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_MTHCA=m
-CONFIG_INFINIBAND_IPOIB=m
-CONFIG_INTEL_IOMMU=y
-CONFIG_MSPEC=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_REISERFS_FS=y
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
-CONFIG_XFS_FS=y
-CONFIG_AUTOFS_FS=m
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_VFAT_FS=y
-CONFIG_NTFS_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_HUGETLBFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V4=m
-CONFIG_NFSD=m
-CONFIG_NFSD_V4=y
-CONFIG_CIFS=m
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRC_T10DIF=y
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig
deleted file mode 100644
index c9e806616544..000000000000
--- a/arch/ia64/configs/gensparse_defconfig
+++ /dev/null
@@ -1,184 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=20
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_SGI_PARTITION=y
-CONFIG_MCKINLEY=y
-CONFIG_IA64_CYCLONE=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=512
-CONFIG_HOTPLUG_CPU=y
-CONFIG_SPARSEMEM_MANUAL=y
-CONFIG_IA64_MCA_RECOVERY=y
-CONFIG_IA64_PALINFO=y
-CONFIG_BINFMT_MISC=m
-CONFIG_ACPI_BUTTON=m
-CONFIG_ACPI_FAN=m
-CONFIG_ACPI_PROCESSOR=m
-CONFIG_HOTPLUG_PCI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_IPV6 is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_ATA=y
-CONFIG_ATA_GENERIC=y
-CONFIG_PATA_CMD64X=y
-CONFIG_ATA_PIIX=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_QLOGIC_1280=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_FC=m
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_NETCONSOLE=y
-CONFIG_TIGON3=y
-CONFIG_NET_TULIP=y
-CONFIG_TULIP=m
-CONFIG_E100=m
-CONFIG_E1000=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_GAMEPORT=m
-CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=6
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_EFI=y
-CONFIG_HPET=y
-CONFIG_AGP=m
-CONFIG_AGP_I460=m
-CONFIG_AGP_HP_ZX1=m
-CONFIG_DRM=m
-CONFIG_DRM_TDFX=m
-CONFIG_DRM_R128=m
-CONFIG_DRM_RADEON=m
-CONFIG_DRM_MGA=m
-CONFIG_DRM_SIS=m
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_SEQUENCER_OSS=y
-CONFIG_SND_VERBOSE_PRINTK=y
-CONFIG_SND_DUMMY=m
-CONFIG_SND_VIRMIDI=m
-CONFIG_SND_MTPAV=m
-CONFIG_SND_SERIAL_U16550=m
-CONFIG_SND_MPU401=m
-CONFIG_SND_CS4281=m
-CONFIG_SND_CS46XX=m
-CONFIG_SND_EMU10K1=m
-CONFIG_SND_FM801=m
-CONFIG_USB=m
-CONFIG_USB_MON=m
-CONFIG_USB_EHCI_HCD=m
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_UHCI_HCD=m
-CONFIG_USB_STORAGE=m
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_MTHCA=m
-CONFIG_INFINIBAND_IPOIB=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_REISERFS_FS=y
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
-CONFIG_XFS_FS=y
-CONFIG_AUTOFS_FS=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_VFAT_FS=y
-CONFIG_NTFS_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_HUGETLBFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V4=m
-CONFIG_NFSD=m
-CONFIG_NFSD_V4=y
-CONFIG_CIFS=m
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_CRYPTO_MD5=y
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
deleted file mode 100644
index d7d8fb5c7b71..000000000000
--- a/arch/ia64/configs/tiger_defconfig
+++ /dev/null
@@ -1,169 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=20
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_SGI_PARTITION=y
-CONFIG_MCKINLEY=y
-CONFIG_IA64_PAGE_SIZE_64KB=y
-CONFIG_IA64_CYCLONE=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=16
-CONFIG_HOTPLUG_CPU=y
-CONFIG_PERMIT_BSP_REMOVE=y
-CONFIG_FORCE_CPEI_RETARGET=y
-CONFIG_IA64_MCA_RECOVERY=y
-CONFIG_IA64_PALINFO=y
-CONFIG_KEXEC=y
-CONFIG_BINFMT_MISC=m
-CONFIG_ACPI_BUTTON=m
-CONFIG_ACPI_FAN=m
-CONFIG_ACPI_PROCESSOR=m
-CONFIG_HOTPLUG_PCI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_IPV6 is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_ATA=y
-CONFIG_ATA_GENERIC=y
-CONFIG_PATA_CMD64X=y
-CONFIG_ATA_PIIX=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_QLOGIC_1280=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_FC=y
-CONFIG_FUSION_CTL=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_NETCONSOLE=y
-CONFIG_TIGON3=y
-CONFIG_NET_TULIP=y
-CONFIG_TULIP=m
-CONFIG_E100=m
-CONFIG_E1000=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_GAMEPORT=m
-CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=6
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_EFI=y
-CONFIG_HPET=y
-CONFIG_AGP=m
-CONFIG_AGP_I460=m
-CONFIG_DRM=m
-CONFIG_DRM_TDFX=m
-CONFIG_DRM_R128=m
-CONFIG_DRM_RADEON=m
-CONFIG_DRM_MGA=m
-CONFIG_DRM_SIS=m
-CONFIG_USB=y
-CONFIG_USB_EHCI_HCD=m
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_UHCI_HCD=y
-CONFIG_USB_STORAGE=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_REISERFS_FS=y
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
-CONFIG_XFS_FS=y
-CONFIG_AUTOFS_FS=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_VFAT_FS=y
-CONFIG_NTFS_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_HUGETLBFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V4=m
-CONFIG_NFSD=m
-CONFIG_NFSD_V4=y
-CONFIG_CIFS=m
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_IA64_GRANULE_16MB=y
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_MD5=y
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
deleted file mode 100644
index ed104550d0d5..000000000000
--- a/arch/ia64/configs/zx1_defconfig
+++ /dev/null
@@ -1,148 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KPROBES=y
-CONFIG_MODULES=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MCKINLEY=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=16
-CONFIG_HOTPLUG_CPU=y
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_IA64_MCA_RECOVERY=y
-CONFIG_IA64_PALINFO=y
-CONFIG_CRASH_DUMP=y
-CONFIG_BINFMT_MISC=y
-CONFIG_HOTPLUG_PCI=y
-CONFIG_HOTPLUG_PCI_ACPI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_ATA=y
-CONFIG_ATA_GENERIC=y
-CONFIG_PATA_CMD64X=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_QLOGIC_1280=y
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_FC=y
-CONFIG_FUSION_CTL=m
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-CONFIG_TIGON3=y
-CONFIG_NET_TULIP=y
-CONFIG_TULIP=y
-CONFIG_TULIP_MWI=y
-CONFIG_TULIP_MMIO=y
-CONFIG_TULIP_NAPI=y
-CONFIG_TULIP_NAPI_HW_MITIGATION=y
-CONFIG_E100=y
-CONFIG_E1000=y
-CONFIG_INPUT_JOYDEV=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=8
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_EFI=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_AGP=y
-CONFIG_AGP_HP_ZX1=y
-CONFIG_DRM=y
-CONFIG_DRM_RADEON=y
-CONFIG_FB_RADEON=y
-CONFIG_FB_RADEON_DEBUG=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SEQUENCER=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
-CONFIG_SND_FM801=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-CONFIG_USB_MON=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_UHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_HUGETLBFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_NFSD=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=y
-CONFIG_NLS_CODEPAGE_775=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_CODEPAGE_855=y
-CONFIG_NLS_CODEPAGE_857=y
-CONFIG_NLS_CODEPAGE_860=y
-CONFIG_NLS_CODEPAGE_861=y
-CONFIG_NLS_CODEPAGE_862=y
-CONFIG_NLS_CODEPAGE_863=y
-CONFIG_NLS_CODEPAGE_864=y
-CONFIG_NLS_CODEPAGE_865=y
-CONFIG_NLS_CODEPAGE_866=y
-CONFIG_NLS_CODEPAGE_869=y
-CONFIG_NLS_CODEPAGE_936=y
-CONFIG_NLS_CODEPAGE_950=y
-CONFIG_NLS_CODEPAGE_932=y
-CONFIG_NLS_CODEPAGE_949=y
-CONFIG_NLS_CODEPAGE_874=y
-CONFIG_NLS_ISO8859_8=y
-CONFIG_NLS_CODEPAGE_1251=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=y
-CONFIG_NLS_ISO8859_3=y
-CONFIG_NLS_ISO8859_4=y
-CONFIG_NLS_ISO8859_5=y
-CONFIG_NLS_ISO8859_6=y
-CONFIG_NLS_ISO8859_7=y
-CONFIG_NLS_ISO8859_9=y
-CONFIG_NLS_ISO8859_13=y
-CONFIG_NLS_ISO8859_14=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_KOI8_R=y
-CONFIG_NLS_KOI8_U=y
-CONFIG_NLS_UTF8=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_IA64_PRINT_HAZARDS=y
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_PCBC=m
diff --git a/arch/ia64/hp/common/Makefile b/arch/ia64/hp/common/Makefile
deleted file mode 100644
index 11a56ed38229..000000000000
--- a/arch/ia64/hp/common/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# ia64/platform/hp/common/Makefile
-#
-# Copyright (C) 2002 Hewlett Packard
-# Copyright (C) Alex Williamson (alex_williamson@hp.com)
-#
-
-obj-$(CONFIG_IA64_HP_SBA_IOMMU) += sba_iommu.o
-obj-$(CONFIG_IA64_HP_AML_NFW) += aml_nfw.o
diff --git a/arch/ia64/hp/common/aml_nfw.c b/arch/ia64/hp/common/aml_nfw.c
deleted file mode 100644
index 901df49461a0..000000000000
--- a/arch/ia64/hp/common/aml_nfw.c
+++ /dev/null
@@ -1,232 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * OpRegion handler to allow AML to call native firmware
- *
- * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- *
- * This driver implements HP Open Source Review Board proposal 1842,
- * which was approved on 9/20/2006.
- *
- * For technical documentation, see the HP SPPA Firmware EAS, Appendix F.
- *
- * ACPI does not define a mechanism for AML methods to call native firmware
- * interfaces such as PAL or SAL. This OpRegion handler adds such a mechanism.
- * After the handler is installed, an AML method can call native firmware by
- * storing the arguments and firmware entry point to specific offsets in the
- * OpRegion. When AML reads the "return value" offset from the OpRegion, this
- * handler loads up the arguments, makes the firmware call, and returns the
- * result.
- */
-
-#include <linux/module.h>
-#include <linux/acpi.h>
-#include <asm/sal.h>
-
-MODULE_AUTHOR("Bjorn Helgaas <bjorn.helgaas@hp.com>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ACPI opregion handler for native firmware calls");
-
-static bool force_register;
-module_param_named(force, force_register, bool, 0);
-MODULE_PARM_DESC(force, "Install opregion handler even without HPQ5001 device");
-
-#define AML_NFW_SPACE 0xA1
-
-struct ia64_pdesc {
- void *ip;
- void *gp;
-};
-
-/*
- * N.B. The layout of this structure is defined in the HP SPPA FW EAS, and
- * the member offsets are embedded in AML methods.
- */
-struct ia64_nfw_context {
- u64 arg[8];
- struct ia64_sal_retval ret;
- u64 ip;
- u64 gp;
- u64 pad[2];
-};
-
-static void *virt_map(u64 address)
-{
- if (address & (1UL << 63))
- return (void *) (__IA64_UNCACHED_OFFSET | address);
-
- return __va(address);
-}
-
-static void aml_nfw_execute(struct ia64_nfw_context *c)
-{
- struct ia64_pdesc virt_entry;
- ia64_sal_handler entry;
-
- virt_entry.ip = virt_map(c->ip);
- virt_entry.gp = virt_map(c->gp);
-
- entry = (ia64_sal_handler) &virt_entry;
-
- IA64_FW_CALL(entry, c->ret,
- c->arg[0], c->arg[1], c->arg[2], c->arg[3],
- c->arg[4], c->arg[5], c->arg[6], c->arg[7]);
-}
-
-static void aml_nfw_read_arg(u8 *offset, u32 bit_width, u64 *value)
-{
- switch (bit_width) {
- case 8:
- *value = *(u8 *)offset;
- break;
- case 16:
- *value = *(u16 *)offset;
- break;
- case 32:
- *value = *(u32 *)offset;
- break;
- case 64:
- *value = *(u64 *)offset;
- break;
- }
-}
-
-static void aml_nfw_write_arg(u8 *offset, u32 bit_width, u64 *value)
-{
- switch (bit_width) {
- case 8:
- *(u8 *) offset = *value;
- break;
- case 16:
- *(u16 *) offset = *value;
- break;
- case 32:
- *(u32 *) offset = *value;
- break;
- case 64:
- *(u64 *) offset = *value;
- break;
- }
-}
-
-static acpi_status aml_nfw_handler(u32 function, acpi_physical_address address,
- u32 bit_width, u64 *value, void *handler_context,
- void *region_context)
-{
- struct ia64_nfw_context *context = handler_context;
- u8 *offset = (u8 *) context + address;
-
- if (bit_width != 8 && bit_width != 16 &&
- bit_width != 32 && bit_width != 64)
- return AE_BAD_PARAMETER;
-
- if (address + (bit_width >> 3) > sizeof(struct ia64_nfw_context))
- return AE_BAD_PARAMETER;
-
- switch (function) {
- case ACPI_READ:
- if (address == offsetof(struct ia64_nfw_context, ret))
- aml_nfw_execute(context);
- aml_nfw_read_arg(offset, bit_width, value);
- break;
- case ACPI_WRITE:
- aml_nfw_write_arg(offset, bit_width, value);
- break;
- }
-
- return AE_OK;
-}
-
-static struct ia64_nfw_context global_context;
-static int global_handler_registered;
-
-static int aml_nfw_add_global_handler(void)
-{
- acpi_status status;
-
- if (global_handler_registered)
- return 0;
-
- status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
- AML_NFW_SPACE, aml_nfw_handler, NULL, &global_context);
- if (ACPI_FAILURE(status))
- return -ENODEV;
-
- global_handler_registered = 1;
- printk(KERN_INFO "Global 0x%02X opregion handler registered\n",
- AML_NFW_SPACE);
- return 0;
-}
-
-static int aml_nfw_remove_global_handler(void)
-{
- acpi_status status;
-
- if (!global_handler_registered)
- return 0;
-
- status = acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
- AML_NFW_SPACE, aml_nfw_handler);
- if (ACPI_FAILURE(status))
- return -ENODEV;
-
- global_handler_registered = 0;
- printk(KERN_INFO "Global 0x%02X opregion handler removed\n",
- AML_NFW_SPACE);
- return 0;
-}
-
-static int aml_nfw_add(struct acpi_device *device)
-{
- /*
- * We would normally allocate a new context structure and install
- * the address space handler for the specific device we found.
- * But the HP-UX implementation shares a single global context
- * and always puts the handler at the root, so we'll do the same.
- */
- return aml_nfw_add_global_handler();
-}
-
-static void aml_nfw_remove(struct acpi_device *device)
-{
- aml_nfw_remove_global_handler();
-}
-
-static const struct acpi_device_id aml_nfw_ids[] = {
- {"HPQ5001", 0},
- {"", 0}
-};
-
-static struct acpi_driver acpi_aml_nfw_driver = {
- .name = "native firmware",
- .ids = aml_nfw_ids,
- .ops = {
- .add = aml_nfw_add,
- .remove = aml_nfw_remove,
- },
-};
-
-static int __init aml_nfw_init(void)
-{
- int result;
-
- if (force_register)
- aml_nfw_add_global_handler();
-
- result = acpi_bus_register_driver(&acpi_aml_nfw_driver);
- if (result < 0) {
- aml_nfw_remove_global_handler();
- return result;
- }
-
- return 0;
-}
-
-static void __exit aml_nfw_exit(void)
-{
- acpi_bus_unregister_driver(&acpi_aml_nfw_driver);
- aml_nfw_remove_global_handler();
-}
-
-module_init(aml_nfw_init);
-module_exit(aml_nfw_exit);
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
deleted file mode 100644
index c4d477e8bcd4..000000000000
--- a/arch/ia64/hp/common/sba_iommu.c
+++ /dev/null
@@ -1,2155 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
-** IA64 System Bus Adapter (SBA) I/O MMU manager
-**
-** (c) Copyright 2002-2005 Alex Williamson
-** (c) Copyright 2002-2003 Grant Grundler
-** (c) Copyright 2002-2005 Hewlett-Packard Company
-**
-** Portions (c) 2000 Grant Grundler (from parisc I/O MMU code)
-** Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU code)
-**
-**
-**
-** This module initializes the IOC (I/O Controller) found on HP
-** McKinley machines and their successors.
-**
-*/
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/acpi.h>
-#include <linux/efi.h>
-#include <linux/nodemask.h>
-#include <linux/bitops.h> /* hweight64() */
-#include <linux/crash_dump.h>
-#include <linux/iommu-helper.h>
-#include <linux/dma-map-ops.h>
-#include <linux/prefetch.h>
-#include <linux/swiotlb.h>
-
-#include <asm/delay.h> /* ia64_get_itc() */
-#include <asm/io.h>
-#include <asm/page.h> /* PAGE_OFFSET */
-#include <asm/dma.h>
-
-#include <asm/acpi-ext.h>
-
-#define PFX "IOC: "
-
-/*
-** Enabling timing search of the pdir resource map. Output in /proc.
-** Disabled by default to optimize performance.
-*/
-#undef PDIR_SEARCH_TIMING
-
-/*
-** This option allows cards capable of 64bit DMA to bypass the IOMMU. If
-** not defined, all DMA will be 32bit and go through the TLB.
-** There's potentially a conflict in the bio merge code with us
-** advertising an iommu, but then bypassing it. Since I/O MMU bypassing
-** appears to give more performance than bio-level virtual merging, we'll
-** do the former for now. NOTE: BYPASS_SG also needs to be undef'd to
-** completely restrict DMA to the IOMMU.
-*/
-#define ALLOW_IOV_BYPASS
-
-/*
-** This option specifically allows/disallows bypassing scatterlists with
-** multiple entries. Coalescing these entries can allow better DMA streaming
-** and in some cases shows better performance than entirely bypassing the
-** IOMMU. Performance increase on the order of 1-2% sequential output/input
-** using bonnie++ on a RAID0 MD device (sym2 & mpt).
-*/
-#undef ALLOW_IOV_BYPASS_SG
-
-/*
-** If a device prefetches beyond the end of a valid pdir entry, it will cause
-** a hard failure, ie. MCA. Version 3.0 and later of the zx1 LBA should
-** disconnect on 4k boundaries and prevent such issues. If the device is
-** particularly aggressive, this option will keep the entire pdir valid such
-** that prefetching will hit a valid address. This could severely impact
-** error containment, and is therefore off by default. The page that is
-** used for spill-over is poisoned, so that should help debugging somewhat.
-*/
-#undef FULL_VALID_PDIR
-
-#define ENABLE_MARK_CLEAN
-
-/*
-** The number of debug flags is a clue - this code is fragile. NOTE: since
-** tightening the use of res_lock the resource bitmap and actual pdir are no
-** longer guaranteed to stay in sync. The sanity checking code isn't going to
-** like that.
-*/
-#undef DEBUG_SBA_INIT
-#undef DEBUG_SBA_RUN
-#undef DEBUG_SBA_RUN_SG
-#undef DEBUG_SBA_RESOURCE
-#undef ASSERT_PDIR_SANITY
-#undef DEBUG_LARGE_SG_ENTRIES
-#undef DEBUG_BYPASS
-
-#if defined(FULL_VALID_PDIR) && defined(ASSERT_PDIR_SANITY)
-#error FULL_VALID_PDIR and ASSERT_PDIR_SANITY are mutually exclusive
-#endif
-
-#define SBA_INLINE __inline__
-/* #define SBA_INLINE */
-
-#ifdef DEBUG_SBA_INIT
-#define DBG_INIT(x...) printk(x)
-#else
-#define DBG_INIT(x...)
-#endif
-
-#ifdef DEBUG_SBA_RUN
-#define DBG_RUN(x...) printk(x)
-#else
-#define DBG_RUN(x...)
-#endif
-
-#ifdef DEBUG_SBA_RUN_SG
-#define DBG_RUN_SG(x...) printk(x)
-#else
-#define DBG_RUN_SG(x...)
-#endif
-
-
-#ifdef DEBUG_SBA_RESOURCE
-#define DBG_RES(x...) printk(x)
-#else
-#define DBG_RES(x...)
-#endif
-
-#ifdef DEBUG_BYPASS
-#define DBG_BYPASS(x...) printk(x)
-#else
-#define DBG_BYPASS(x...)
-#endif
-
-#ifdef ASSERT_PDIR_SANITY
-#define ASSERT(expr) \
- if(!(expr)) { \
- printk( "\n" __FILE__ ":%d: Assertion " #expr " failed!\n",__LINE__); \
- panic(#expr); \
- }
-#else
-#define ASSERT(expr)
-#endif
-
-/*
-** The number of pdir entries to "free" before issuing
-** a read to PCOM register to flush out PCOM writes.
-** Interacts with allocation granularity (ie 4 or 8 entries
-** allocated and free'd/purged at a time might make this
-** less interesting).
-*/
-#define DELAYED_RESOURCE_CNT 64
-
-#define PCI_DEVICE_ID_HP_SX2000_IOC 0x12ec
-
-#define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP)
-#define ZX2_IOC_ID ((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP)
-#define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP)
-#define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP)
-#define SX2000_IOC_ID ((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP)
-
-#define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */
-
-#define IOC_FUNC_ID 0x000
-#define IOC_FCLASS 0x008 /* function class, bist, header, rev... */
-#define IOC_IBASE 0x300 /* IO TLB */
-#define IOC_IMASK 0x308
-#define IOC_PCOM 0x310
-#define IOC_TCNFG 0x318
-#define IOC_PDIR_BASE 0x320
-
-#define IOC_ROPE0_CFG 0x500
-#define IOC_ROPE_AO 0x10 /* Allow "Relaxed Ordering" */
-
-
-/* AGP GART driver looks for this */
-#define ZX1_SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL
-
-/*
-** The zx1 IOC supports 4/8/16/64KB page sizes (see TCNFG register)
-**
-** Some IOCs (sx1000) can run at the above pages sizes, but are
-** really only supported using the IOC at a 4k page size.
-**
-** iovp_size could only be greater than PAGE_SIZE if we are
-** confident the drivers really only touch the next physical
-** page iff that driver instance owns it.
-*/
-static unsigned long iovp_size;
-static unsigned long iovp_shift;
-static unsigned long iovp_mask;
-
-struct ioc {
- void __iomem *ioc_hpa; /* I/O MMU base address */
- char *res_map; /* resource map, bit == pdir entry */
- u64 *pdir_base; /* physical base address */
- unsigned long ibase; /* pdir IOV Space base */
- unsigned long imask; /* pdir IOV Space mask */
-
- unsigned long *res_hint; /* next avail IOVP - circular search */
- unsigned long dma_mask;
- spinlock_t res_lock; /* protects the resource bitmap, but must be held when */
- /* clearing pdir to prevent races with allocations. */
- unsigned int res_bitshift; /* from the RIGHT! */
- unsigned int res_size; /* size of resource map in bytes */
-#ifdef CONFIG_NUMA
- unsigned int node; /* node where this IOC lives */
-#endif
-#if DELAYED_RESOURCE_CNT > 0
- spinlock_t saved_lock; /* may want to try to get this on a separate cacheline */
- /* than res_lock for bigger systems. */
- int saved_cnt;
- struct sba_dma_pair {
- dma_addr_t iova;
- size_t size;
- } saved[DELAYED_RESOURCE_CNT];
-#endif
-
-#ifdef PDIR_SEARCH_TIMING
-#define SBA_SEARCH_SAMPLE 0x100
- unsigned long avg_search[SBA_SEARCH_SAMPLE];
- unsigned long avg_idx; /* current index into avg_search */
-#endif
-
- /* Stuff we don't need in performance path */
- struct ioc *next; /* list of IOC's in system */
- acpi_handle handle; /* for multiple IOC's */
- const char *name;
- unsigned int func_id;
- unsigned int rev; /* HW revision of chip */
- u32 iov_size;
- unsigned int pdir_size; /* in bytes, determined by IOV Space size */
- struct pci_dev *sac_only_dev;
-};
-
-static struct ioc *ioc_list, *ioc_found;
-static int reserve_sba_gart = 1;
-
-static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
-static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t);
-
-#define sba_sg_address(sg) sg_virt((sg))
-
-#ifdef FULL_VALID_PDIR
-static u64 prefetch_spill_page;
-#endif
-
-#define GET_IOC(dev) ((dev_is_pci(dev)) \
- ? ((struct ioc *) PCI_CONTROLLER(to_pci_dev(dev))->iommu) : NULL)
-
-/*
-** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up
-** (or rather not merge) DMAs into manageable chunks.
-** On parisc, this is more of the software/tuning constraint
-** rather than the HW. I/O MMU allocation algorithms can be
-** faster with smaller sizes (to some degree).
-*/
-#define DMA_CHUNK_SIZE (BITS_PER_LONG*iovp_size)
-
-#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
-
-/************************************
-** SBA register read and write support
-**
-** BE WARNED: register writes are posted.
-** (ie follow writes which must reach HW with a read)
-**
-*/
-#define READ_REG(addr) __raw_readq(addr)
-#define WRITE_REG(val, addr) __raw_writeq(val, addr)
-
-#ifdef DEBUG_SBA_INIT
-
-/**
- * sba_dump_tlb - debugging only - print IOMMU operating parameters
- * @hpa: base address of the IOMMU
- *
- * Print the size/location of the IO MMU PDIR.
- */
-static void
-sba_dump_tlb(char *hpa)
-{
- DBG_INIT("IO TLB at 0x%p\n", (void *)hpa);
- DBG_INIT("IOC_IBASE : %016lx\n", READ_REG(hpa+IOC_IBASE));
- DBG_INIT("IOC_IMASK : %016lx\n", READ_REG(hpa+IOC_IMASK));
- DBG_INIT("IOC_TCNFG : %016lx\n", READ_REG(hpa+IOC_TCNFG));
- DBG_INIT("IOC_PDIR_BASE: %016lx\n", READ_REG(hpa+IOC_PDIR_BASE));
- DBG_INIT("\n");
-}
-#endif
-
-
-#ifdef ASSERT_PDIR_SANITY
-
-/**
- * sba_dump_pdir_entry - debugging only - print one IOMMU PDIR entry
- * @ioc: IO MMU structure which owns the pdir we are interested in.
- * @msg: text to print ont the output line.
- * @pide: pdir index.
- *
- * Print one entry of the IO MMU PDIR in human readable form.
- */
-static void
-sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide)
-{
- /* start printing from lowest pde in rval */
- u64 *ptr = &ioc->pdir_base[pide & ~(BITS_PER_LONG - 1)];
- unsigned long *rptr = (unsigned long *) &ioc->res_map[(pide >>3) & -sizeof(unsigned long)];
- uint rcnt;
-
- printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n",
- msg, rptr, pide & (BITS_PER_LONG - 1), *rptr);
-
- rcnt = 0;
- while (rcnt < BITS_PER_LONG) {
- printk(KERN_DEBUG "%s %2d %p %016Lx\n",
- (rcnt == (pide & (BITS_PER_LONG - 1)))
- ? " -->" : " ",
- rcnt, ptr, (unsigned long long) *ptr );
- rcnt++;
- ptr++;
- }
- printk(KERN_DEBUG "%s", msg);
-}
-
-
-/**
- * sba_check_pdir - debugging only - consistency checker
- * @ioc: IO MMU structure which owns the pdir we are interested in.
- * @msg: text to print ont the output line.
- *
- * Verify the resource map and pdir state is consistent
- */
-static int
-sba_check_pdir(struct ioc *ioc, char *msg)
-{
- u64 *rptr_end = (u64 *) &(ioc->res_map[ioc->res_size]);
- u64 *rptr = (u64 *) ioc->res_map; /* resource map ptr */
- u64 *pptr = ioc->pdir_base; /* pdir ptr */
- uint pide = 0;
-
- while (rptr < rptr_end) {
- u64 rval;
- int rcnt; /* number of bits we might check */
-
- rval = *rptr;
- rcnt = 64;
-
- while (rcnt) {
- /* Get last byte and highest bit from that */
- u32 pde = ((u32)((*pptr >> (63)) & 0x1));
- if ((rval & 0x1) ^ pde)
- {
- /*
- ** BUMMER! -- res_map != pdir --
- ** Dump rval and matching pdir entries
- */
- sba_dump_pdir_entry(ioc, msg, pide);
- return(1);
- }
- rcnt--;
- rval >>= 1; /* try the next bit */
- pptr++;
- pide++;
- }
- rptr++; /* look at next word of res_map */
- }
- /* It'd be nice if we always got here :^) */
- return 0;
-}
-
-
-/**
- * sba_dump_sg - debugging only - print Scatter-Gather list
- * @ioc: IO MMU structure which owns the pdir we are interested in.
- * @startsg: head of the SG list
- * @nents: number of entries in SG list
- *
- * print the SG list so we can verify it's correct by hand.
- */
-static void
-sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
-{
- while (nents-- > 0) {
- printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents,
- startsg->dma_address, startsg->dma_length,
- sba_sg_address(startsg));
- startsg = sg_next(startsg);
- }
-}
-
-static void
-sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
-{
- struct scatterlist *the_sg = startsg;
- int the_nents = nents;
-
- while (the_nents-- > 0) {
- if (sba_sg_address(the_sg) == 0x0UL)
- sba_dump_sg(NULL, startsg, nents);
- the_sg = sg_next(the_sg);
- }
-}
-
-#endif /* ASSERT_PDIR_SANITY */
-
-
-
-
-/**************************************************************
-*
-* I/O Pdir Resource Management
-*
-* Bits set in the resource map are in use.
-* Each bit can represent a number of pages.
-* LSbs represent lower addresses (IOVA's).
-*
-***************************************************************/
-#define PAGES_PER_RANGE 1 /* could increase this to 4 or 8 if needed */
-
-/* Convert from IOVP to IOVA and vice versa. */
-#define SBA_IOVA(ioc,iovp,offset) ((ioc->ibase) | (iovp) | (offset))
-#define SBA_IOVP(ioc,iova) ((iova) & ~(ioc->ibase))
-
-#define PDIR_ENTRY_SIZE sizeof(u64)
-
-#define PDIR_INDEX(iovp) ((iovp)>>iovp_shift)
-
-#define RESMAP_MASK(n) ~(~0UL << (n))
-#define RESMAP_IDX_MASK (sizeof(unsigned long) - 1)
-
-
-/**
- * For most cases the normal get_order is sufficient, however it limits us
- * to PAGE_SIZE being the minimum mapping alignment and TC flush granularity.
- * It only incurs about 1 clock cycle to use this one with the static variable
- * and makes the code more intuitive.
- */
-static SBA_INLINE int
-get_iovp_order (unsigned long size)
-{
- long double d = size - 1;
- long order;
-
- order = ia64_getf_exp(d);
- order = order - iovp_shift - 0xffff + 1;
- if (order < 0)
- order = 0;
- return order;
-}
-
-static unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr,
- unsigned int bitshiftcnt)
-{
- return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3)
- + bitshiftcnt;
-}
-
-/**
- * sba_search_bitmap - find free space in IO PDIR resource bitmap
- * @ioc: IO MMU structure which owns the pdir we are interested in.
- * @bits_wanted: number of entries we need.
- * @use_hint: use res_hint to indicate where to start looking
- *
- * Find consecutive free bits in resource bitmap.
- * Each bit represents one entry in the IO Pdir.
- * Cool perf optimization: search for log2(size) bits at a time.
- */
-static SBA_INLINE unsigned long
-sba_search_bitmap(struct ioc *ioc, struct device *dev,
- unsigned long bits_wanted, int use_hint)
-{
- unsigned long *res_ptr;
- unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
- unsigned long flags, pide = ~0UL, tpide;
- unsigned long boundary_size;
- unsigned long shift;
- int ret;
-
- ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
- ASSERT(res_ptr < res_end);
-
- boundary_size = dma_get_seg_boundary_nr_pages(dev, iovp_shift);
-
- BUG_ON(ioc->ibase & ~iovp_mask);
- shift = ioc->ibase >> iovp_shift;
-
- spin_lock_irqsave(&ioc->res_lock, flags);
-
- /* Allow caller to force a search through the entire resource space */
- if (likely(use_hint)) {
- res_ptr = ioc->res_hint;
- } else {
- res_ptr = (ulong *)ioc->res_map;
- ioc->res_bitshift = 0;
- }
-
- /*
- * N.B. REO/Grande defect AR2305 can cause TLB fetch timeouts
- * if a TLB entry is purged while in use. sba_mark_invalid()
- * purges IOTLB entries in power-of-two sizes, so we also
- * allocate IOVA space in power-of-two sizes.
- */
- bits_wanted = 1UL << get_iovp_order(bits_wanted << iovp_shift);
-
- if (likely(bits_wanted == 1)) {
- unsigned int bitshiftcnt;
- for(; res_ptr < res_end ; res_ptr++) {
- if (likely(*res_ptr != ~0UL)) {
- bitshiftcnt = ffz(*res_ptr);
- *res_ptr |= (1UL << bitshiftcnt);
- pide = ptr_to_pide(ioc, res_ptr, bitshiftcnt);
- ioc->res_bitshift = bitshiftcnt + bits_wanted;
- goto found_it;
- }
- }
- goto not_found;
-
- }
-
- if (likely(bits_wanted <= BITS_PER_LONG/2)) {
- /*
- ** Search the resource bit map on well-aligned values.
- ** "o" is the alignment.
- ** We need the alignment to invalidate I/O TLB using
- ** SBA HW features in the unmap path.
- */
- unsigned long o = 1 << get_iovp_order(bits_wanted << iovp_shift);
- uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o);
- unsigned long mask, base_mask;
-
- base_mask = RESMAP_MASK(bits_wanted);
- mask = base_mask << bitshiftcnt;
-
- DBG_RES("%s() o %ld %p", __func__, o, res_ptr);
- for(; res_ptr < res_end ; res_ptr++)
- {
- DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr);
- ASSERT(0 != mask);
- for (; mask ; mask <<= o, bitshiftcnt += o) {
- tpide = ptr_to_pide(ioc, res_ptr, bitshiftcnt);
- ret = iommu_is_span_boundary(tpide, bits_wanted,
- shift,
- boundary_size);
- if ((0 == ((*res_ptr) & mask)) && !ret) {
- *res_ptr |= mask; /* mark resources busy! */
- pide = tpide;
- ioc->res_bitshift = bitshiftcnt + bits_wanted;
- goto found_it;
- }
- }
-
- bitshiftcnt = 0;
- mask = base_mask;
-
- }
-
- } else {
- int qwords, bits, i;
- unsigned long *end;
-
- qwords = bits_wanted >> 6; /* /64 */
- bits = bits_wanted - (qwords * BITS_PER_LONG);
-
- end = res_end - qwords;
-
- for (; res_ptr < end; res_ptr++) {
- tpide = ptr_to_pide(ioc, res_ptr, 0);
- ret = iommu_is_span_boundary(tpide, bits_wanted,
- shift, boundary_size);
- if (ret)
- goto next_ptr;
- for (i = 0 ; i < qwords ; i++) {
- if (res_ptr[i] != 0)
- goto next_ptr;
- }
- if (bits && res_ptr[i] && (__ffs(res_ptr[i]) < bits))
- continue;
-
- /* Found it, mark it */
- for (i = 0 ; i < qwords ; i++)
- res_ptr[i] = ~0UL;
- res_ptr[i] |= RESMAP_MASK(bits);
-
- pide = tpide;
- res_ptr += qwords;
- ioc->res_bitshift = bits;
- goto found_it;
-next_ptr:
- ;
- }
- }
-
-not_found:
- prefetch(ioc->res_map);
- ioc->res_hint = (unsigned long *) ioc->res_map;
- ioc->res_bitshift = 0;
- spin_unlock_irqrestore(&ioc->res_lock, flags);
- return (pide);
-
-found_it:
- ioc->res_hint = res_ptr;
- spin_unlock_irqrestore(&ioc->res_lock, flags);
- return (pide);
-}
-
-
-/**
- * sba_alloc_range - find free bits and mark them in IO PDIR resource bitmap
- * @ioc: IO MMU structure which owns the pdir we are interested in.
- * @size: number of bytes to create a mapping for
- *
- * Given a size, find consecutive unmarked and then mark those bits in the
- * resource bit map.
- */
-static int
-sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
-{
- unsigned int pages_needed = size >> iovp_shift;
-#ifdef PDIR_SEARCH_TIMING
- unsigned long itc_start;
-#endif
- unsigned long pide;
-
- ASSERT(pages_needed);
- ASSERT(0 == (size & ~iovp_mask));
-
-#ifdef PDIR_SEARCH_TIMING
- itc_start = ia64_get_itc();
-#endif
- /*
- ** "seek and ye shall find"...praying never hurts either...
- */
- pide = sba_search_bitmap(ioc, dev, pages_needed, 1);
- if (unlikely(pide >= (ioc->res_size << 3))) {
- pide = sba_search_bitmap(ioc, dev, pages_needed, 0);
- if (unlikely(pide >= (ioc->res_size << 3))) {
-#if DELAYED_RESOURCE_CNT > 0
- unsigned long flags;
-
- /*
- ** With delayed resource freeing, we can give this one more shot. We're
- ** getting close to being in trouble here, so do what we can to make this
- ** one count.
- */
- spin_lock_irqsave(&ioc->saved_lock, flags);
- if (ioc->saved_cnt > 0) {
- struct sba_dma_pair *d;
- int cnt = ioc->saved_cnt;
-
- d = &(ioc->saved[ioc->saved_cnt - 1]);
-
- spin_lock(&ioc->res_lock);
- while (cnt--) {
- sba_mark_invalid(ioc, d->iova, d->size);
- sba_free_range(ioc, d->iova, d->size);
- d--;
- }
- ioc->saved_cnt = 0;
- READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */
- spin_unlock(&ioc->res_lock);
- }
- spin_unlock_irqrestore(&ioc->saved_lock, flags);
-
- pide = sba_search_bitmap(ioc, dev, pages_needed, 0);
- if (unlikely(pide >= (ioc->res_size << 3))) {
- printk(KERN_WARNING "%s: I/O MMU @ %p is"
- "out of mapping resources, %u %u %lx\n",
- __func__, ioc->ioc_hpa, ioc->res_size,
- pages_needed, dma_get_seg_boundary(dev));
- return -1;
- }
-#else
- printk(KERN_WARNING "%s: I/O MMU @ %p is"
- "out of mapping resources, %u %u %lx\n",
- __func__, ioc->ioc_hpa, ioc->res_size,
- pages_needed, dma_get_seg_boundary(dev));
- return -1;
-#endif
- }
- }
-
-#ifdef PDIR_SEARCH_TIMING
- ioc->avg_search[ioc->avg_idx++] = (ia64_get_itc() - itc_start) / pages_needed;
- ioc->avg_idx &= SBA_SEARCH_SAMPLE - 1;
-#endif
-
- prefetchw(&(ioc->pdir_base[pide]));
-
-#ifdef ASSERT_PDIR_SANITY
- /* verify the first enable bit is clear */
- if(0x00 != ((u8 *) ioc->pdir_base)[pide*PDIR_ENTRY_SIZE + 7]) {
- sba_dump_pdir_entry(ioc, "sba_search_bitmap() botched it?", pide);
- }
-#endif
-
- DBG_RES("%s(%x) %d -> %lx hint %x/%x\n",
- __func__, size, pages_needed, pide,
- (uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
- ioc->res_bitshift );
-
- return (pide);
-}
-
-
-/**
- * sba_free_range - unmark bits in IO PDIR resource bitmap
- * @ioc: IO MMU structure which owns the pdir we are interested in.
- * @iova: IO virtual address which was previously allocated.
- * @size: number of bytes to create a mapping for
- *
- * clear bits in the ioc's resource map
- */
-static SBA_INLINE void
-sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
-{
- unsigned long iovp = SBA_IOVP(ioc, iova);
- unsigned int pide = PDIR_INDEX(iovp);
- unsigned int ridx = pide >> 3; /* convert bit to byte address */
- unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]);
- int bits_not_wanted = size >> iovp_shift;
- unsigned long m;
-
- /* Round up to power-of-two size: see AR2305 note above */
- bits_not_wanted = 1UL << get_iovp_order(bits_not_wanted << iovp_shift);
- for (; bits_not_wanted > 0 ; res_ptr++) {
-
- if (unlikely(bits_not_wanted > BITS_PER_LONG)) {
-
- /* these mappings start 64bit aligned */
- *res_ptr = 0UL;
- bits_not_wanted -= BITS_PER_LONG;
- pide += BITS_PER_LONG;
-
- } else {
-
- /* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */
- m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1));
- bits_not_wanted = 0;
-
- DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n", __func__, (uint) iova, size,
- bits_not_wanted, m, pide, res_ptr, *res_ptr);
-
- ASSERT(m != 0);
- ASSERT(bits_not_wanted);
- ASSERT((*res_ptr & m) == m); /* verify same bits are set */
- *res_ptr &= ~m;
- }
- }
-}
-
-
-/**************************************************************
-*
-* "Dynamic DMA Mapping" support (aka "Coherent I/O")
-*
-***************************************************************/
-
-/**
- * sba_io_pdir_entry - fill in one IO PDIR entry
- * @pdir_ptr: pointer to IO PDIR entry
- * @vba: Virtual CPU address of buffer to map
- *
- * SBA Mapping Routine
- *
- * Given a virtual address (vba, arg1) sba_io_pdir_entry()
- * loads the I/O PDIR entry pointed to by pdir_ptr (arg0).
- * Each IO Pdir entry consists of 8 bytes as shown below
- * (LSB == bit 0):
- *
- * 63 40 11 7 0
- * +-+---------------------+----------------------------------+----+--------+
- * |V| U | PPN[39:12] | U | FF |
- * +-+---------------------+----------------------------------+----+--------+
- *
- * V == Valid Bit
- * U == Unused
- * PPN == Physical Page Number
- *
- * The physical address fields are filled with the results of virt_to_phys()
- * on the vba.
- */
-
-#if 1
-#define sba_io_pdir_entry(pdir_ptr, vba) *pdir_ptr = ((vba & ~0xE000000000000FFFULL) \
- | 0x8000000000000000ULL)
-#else
-void SBA_INLINE
-sba_io_pdir_entry(u64 *pdir_ptr, unsigned long vba)
-{
- *pdir_ptr = ((vba & ~0xE000000000000FFFULL) | 0x80000000000000FFULL);
-}
-#endif
-
-#ifdef ENABLE_MARK_CLEAN
-/*
- * Since DMA is i-cache coherent, any (complete) pages that were written via
- * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to
- * flush them when they get mapped into an executable vm-area.
- */
-static void mark_clean(void *addr, size_t size)
-{
- struct folio *folio = virt_to_folio(addr);
- ssize_t left = size;
- size_t offset = offset_in_folio(folio, addr);
-
- if (offset) {
- left -= folio_size(folio) - offset;
- if (left <= 0)
- return;
- folio = folio_next(folio);
- }
-
- while (left >= folio_size(folio)) {
- left -= folio_size(folio);
- set_bit(PG_arch_1, &folio->flags);
- if (!left)
- break;
- folio = folio_next(folio);
- }
-}
-#endif
-
-/**
- * sba_mark_invalid - invalidate one or more IO PDIR entries
- * @ioc: IO MMU structure which owns the pdir we are interested in.
- * @iova: IO Virtual Address mapped earlier
- * @byte_cnt: number of bytes this mapping covers.
- *
- * Marking the IO PDIR entry(ies) as Invalid and invalidate
- * corresponding IO TLB entry. The PCOM (Purge Command Register)
- * is to purge stale entries in the IO TLB when unmapping entries.
- *
- * The PCOM register supports purging of multiple pages, with a minium
- * of 1 page and a maximum of 2GB. Hardware requires the address be
- * aligned to the size of the range being purged. The size of the range
- * must be a power of 2. The "Cool perf optimization" in the
- * allocation routine helps keep that true.
- */
-static SBA_INLINE void
-sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
-{
- u32 iovp = (u32) SBA_IOVP(ioc,iova);
-
- int off = PDIR_INDEX(iovp);
-
- /* Must be non-zero and rounded up */
- ASSERT(byte_cnt > 0);
- ASSERT(0 == (byte_cnt & ~iovp_mask));
-
-#ifdef ASSERT_PDIR_SANITY
- /* Assert first pdir entry is set */
- if (!(ioc->pdir_base[off] >> 60)) {
- sba_dump_pdir_entry(ioc,"sba_mark_invalid()", PDIR_INDEX(iovp));
- }
-#endif
-
- if (byte_cnt <= iovp_size)
- {
- ASSERT(off < ioc->pdir_size);
-
- iovp |= iovp_shift; /* set "size" field for PCOM */
-
-#ifndef FULL_VALID_PDIR
- /*
- ** clear I/O PDIR entry "valid" bit
- ** Do NOT clear the rest - save it for debugging.
- ** We should only clear bits that have previously
- ** been enabled.
- */
- ioc->pdir_base[off] &= ~(0x80000000000000FFULL);
-#else
- /*
- ** If we want to maintain the PDIR as valid, put in
- ** the spill page so devices prefetching won't
- ** cause a hard fail.
- */
- ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page);
-#endif
- } else {
- u32 t = get_iovp_order(byte_cnt) + iovp_shift;
-
- iovp |= t;
- ASSERT(t <= 31); /* 2GB! Max value of "size" field */
-
- do {
- /* verify this pdir entry is enabled */
- ASSERT(ioc->pdir_base[off] >> 63);
-#ifndef FULL_VALID_PDIR
- /* clear I/O Pdir entry "valid" bit first */
- ioc->pdir_base[off] &= ~(0x80000000000000FFULL);
-#else
- ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page);
-#endif
- off++;
- byte_cnt -= iovp_size;
- } while (byte_cnt > 0);
- }
-
- WRITE_REG(iovp | ioc->ibase, ioc->ioc_hpa+IOC_PCOM);
-}
-
-/**
- * sba_map_page - map one buffer and return IOVA for DMA
- * @dev: instance of PCI owned by the driver that's asking.
- * @page: page to map
- * @poff: offset into page
- * @size: number of bytes to map
- * @dir: dma direction
- * @attrs: optional dma attributes
- *
- * See Documentation/core-api/dma-api-howto.rst
- */
-static dma_addr_t sba_map_page(struct device *dev, struct page *page,
- unsigned long poff, size_t size,
- enum dma_data_direction dir,
- unsigned long attrs)
-{
- struct ioc *ioc;
- void *addr = page_address(page) + poff;
- dma_addr_t iovp;
- dma_addr_t offset;
- u64 *pdir_start;
- int pide;
-#ifdef ASSERT_PDIR_SANITY
- unsigned long flags;
-#endif
-#ifdef ALLOW_IOV_BYPASS
- unsigned long pci_addr = virt_to_phys(addr);
-#endif
-
-#ifdef ALLOW_IOV_BYPASS
- ASSERT(to_pci_dev(dev)->dma_mask);
- /*
- ** Check if the PCI device can DMA to ptr... if so, just return ptr
- */
- if (likely((pci_addr & ~to_pci_dev(dev)->dma_mask) == 0)) {
- /*
- ** Device is bit capable of DMA'ing to the buffer...
- ** just return the PCI address of ptr
- */
- DBG_BYPASS("sba_map_page() bypass mask/addr: "
- "0x%lx/0x%lx\n",
- to_pci_dev(dev)->dma_mask, pci_addr);
- return pci_addr;
- }
-#endif
- ioc = GET_IOC(dev);
- ASSERT(ioc);
-
- prefetch(ioc->res_hint);
-
- ASSERT(size > 0);
- ASSERT(size <= DMA_CHUNK_SIZE);
-
- /* save offset bits */
- offset = ((dma_addr_t) (long) addr) & ~iovp_mask;
-
- /* round up to nearest iovp_size */
- size = (size + offset + ~iovp_mask) & iovp_mask;
-
-#ifdef ASSERT_PDIR_SANITY
- spin_lock_irqsave(&ioc->res_lock, flags);
- if (sba_check_pdir(ioc,"Check before sba_map_page()"))
- panic("Sanity check failed");
- spin_unlock_irqrestore(&ioc->res_lock, flags);
-#endif
-
- pide = sba_alloc_range(ioc, dev, size);
- if (pide < 0)
- return DMA_MAPPING_ERROR;
-
- iovp = (dma_addr_t) pide << iovp_shift;
-
- DBG_RUN("%s() 0x%p -> 0x%lx\n", __func__, addr, (long) iovp | offset);
-
- pdir_start = &(ioc->pdir_base[pide]);
-
- while (size > 0) {
- ASSERT(((u8 *)pdir_start)[7] == 0); /* verify availability */
- sba_io_pdir_entry(pdir_start, (unsigned long) addr);
-
- DBG_RUN(" pdir 0x%p %lx\n", pdir_start, *pdir_start);
-
- addr += iovp_size;
- size -= iovp_size;
- pdir_start++;
- }
- /* force pdir update */
- wmb();
-
- /* form complete address */
-#ifdef ASSERT_PDIR_SANITY
- spin_lock_irqsave(&ioc->res_lock, flags);
- sba_check_pdir(ioc,"Check after sba_map_page()");
- spin_unlock_irqrestore(&ioc->res_lock, flags);
-#endif
- return SBA_IOVA(ioc, iovp, offset);
-}
-
-#ifdef ENABLE_MARK_CLEAN
-static SBA_INLINE void
-sba_mark_clean(struct ioc *ioc, dma_addr_t iova, size_t size)
-{
- u32 iovp = (u32) SBA_IOVP(ioc,iova);
- int off = PDIR_INDEX(iovp);
- void *addr;
-
- if (size <= iovp_size) {
- addr = phys_to_virt(ioc->pdir_base[off] &
- ~0xE000000000000FFFULL);
- mark_clean(addr, size);
- } else {
- do {
- addr = phys_to_virt(ioc->pdir_base[off] &
- ~0xE000000000000FFFULL);
- mark_clean(addr, min(size, iovp_size));
- off++;
- size -= iovp_size;
- } while (size > 0);
- }
-}
-#endif
-
-/**
- * sba_unmap_page - unmap one IOVA and free resources
- * @dev: instance of PCI owned by the driver that's asking.
- * @iova: IOVA of driver buffer previously mapped.
- * @size: number of bytes mapped in driver buffer.
- * @dir: R/W or both.
- * @attrs: optional dma attributes
- *
- * See Documentation/core-api/dma-api-howto.rst
- */
-static void sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size,
- enum dma_data_direction dir, unsigned long attrs)
-{
- struct ioc *ioc;
-#if DELAYED_RESOURCE_CNT > 0
- struct sba_dma_pair *d;
-#endif
- unsigned long flags;
- dma_addr_t offset;
-
- ioc = GET_IOC(dev);
- ASSERT(ioc);
-
-#ifdef ALLOW_IOV_BYPASS
- if (likely((iova & ioc->imask) != ioc->ibase)) {
- /*
- ** Address does not fall w/in IOVA, must be bypassing
- */
- DBG_BYPASS("sba_unmap_page() bypass addr: 0x%lx\n",
- iova);
-
-#ifdef ENABLE_MARK_CLEAN
- if (dir == DMA_FROM_DEVICE) {
- mark_clean(phys_to_virt(iova), size);
- }
-#endif
- return;
- }
-#endif
- offset = iova & ~iovp_mask;
-
- DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size);
-
- iova ^= offset; /* clear offset bits */
- size += offset;
- size = ROUNDUP(size, iovp_size);
-
-#ifdef ENABLE_MARK_CLEAN
- if (dir == DMA_FROM_DEVICE)
- sba_mark_clean(ioc, iova, size);
-#endif
-
-#if DELAYED_RESOURCE_CNT > 0
- spin_lock_irqsave(&ioc->saved_lock, flags);
- d = &(ioc->saved[ioc->saved_cnt]);
- d->iova = iova;
- d->size = size;
- if (unlikely(++(ioc->saved_cnt) >= DELAYED_RESOURCE_CNT)) {
- int cnt = ioc->saved_cnt;
- spin_lock(&ioc->res_lock);
- while (cnt--) {
- sba_mark_invalid(ioc, d->iova, d->size);
- sba_free_range(ioc, d->iova, d->size);
- d--;
- }
- ioc->saved_cnt = 0;
- READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */
- spin_unlock(&ioc->res_lock);
- }
- spin_unlock_irqrestore(&ioc->saved_lock, flags);
-#else /* DELAYED_RESOURCE_CNT == 0 */
- spin_lock_irqsave(&ioc->res_lock, flags);
- sba_mark_invalid(ioc, iova, size);
- sba_free_range(ioc, iova, size);
- READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */
- spin_unlock_irqrestore(&ioc->res_lock, flags);
-#endif /* DELAYED_RESOURCE_CNT == 0 */
-}
-
-/**
- * sba_alloc_coherent - allocate/map shared mem for DMA
- * @dev: instance of PCI owned by the driver that's asking.
- * @size: number of bytes mapped in driver buffer.
- * @dma_handle: IOVA of new buffer.
- *
- * See Documentation/core-api/dma-api-howto.rst
- */
-static void *
-sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flags, unsigned long attrs)
-{
- struct page *page;
- struct ioc *ioc;
- int node = -1;
- void *addr;
-
- ioc = GET_IOC(dev);
- ASSERT(ioc);
-#ifdef CONFIG_NUMA
- node = ioc->node;
-#endif
-
- page = alloc_pages_node(node, flags, get_order(size));
- if (unlikely(!page))
- return NULL;
-
- addr = page_address(page);
- memset(addr, 0, size);
- *dma_handle = page_to_phys(page);
-
-#ifdef ALLOW_IOV_BYPASS
- ASSERT(dev->coherent_dma_mask);
- /*
- ** Check if the PCI device can DMA to ptr... if so, just return ptr
- */
- if (likely((*dma_handle & ~dev->coherent_dma_mask) == 0)) {
- DBG_BYPASS("sba_alloc_coherent() bypass mask/addr: 0x%lx/0x%lx\n",
- dev->coherent_dma_mask, *dma_handle);
-
- return addr;
- }
-#endif
-
- /*
- * If device can't bypass or bypass is disabled, pass the 32bit fake
- * device to map single to get an iova mapping.
- */
- *dma_handle = sba_map_page(&ioc->sac_only_dev->dev, page, 0, size,
- DMA_BIDIRECTIONAL, 0);
- if (dma_mapping_error(dev, *dma_handle))
- return NULL;
- return addr;
-}
-
-
-/**
- * sba_free_coherent - free/unmap shared mem for DMA
- * @dev: instance of PCI owned by the driver that's asking.
- * @size: number of bytes mapped in driver buffer.
- * @vaddr: virtual address IOVA of "consistent" buffer.
- * @dma_handler: IO virtual address of "consistent" buffer.
- *
- * See Documentation/core-api/dma-api-howto.rst
- */
-static void sba_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle, unsigned long attrs)
-{
- sba_unmap_page(dev, dma_handle, size, 0, 0);
- free_pages((unsigned long) vaddr, get_order(size));
-}
-
-
-/*
-** Since 0 is a valid pdir_base index value, can't use that
-** to determine if a value is valid or not. Use a flag to indicate
-** the SG list entry contains a valid pdir index.
-*/
-#define PIDE_FLAG 0x1UL
-
-#ifdef DEBUG_LARGE_SG_ENTRIES
-int dump_run_sg = 0;
-#endif
-
-
-/**
- * sba_fill_pdir - write allocated SG entries into IO PDIR
- * @ioc: IO MMU structure which owns the pdir we are interested in.
- * @startsg: list of IOVA/size pairs
- * @nents: number of entries in startsg list
- *
- * Take preprocessed SG list and write corresponding entries
- * in the IO PDIR.
- */
-
-static SBA_INLINE int
-sba_fill_pdir(
- struct ioc *ioc,
- struct scatterlist *startsg,
- int nents)
-{
- struct scatterlist *dma_sg = startsg; /* pointer to current DMA */
- int n_mappings = 0;
- u64 *pdirp = NULL;
- unsigned long dma_offset = 0;
-
- while (nents-- > 0) {
- int cnt = startsg->dma_length;
- startsg->dma_length = 0;
-
-#ifdef DEBUG_LARGE_SG_ENTRIES
- if (dump_run_sg)
- printk(" %2d : %08lx/%05x %p\n",
- nents, startsg->dma_address, cnt,
- sba_sg_address(startsg));
-#else
- DBG_RUN_SG(" %d : %08lx/%05x %p\n",
- nents, startsg->dma_address, cnt,
- sba_sg_address(startsg));
-#endif
- /*
- ** Look for the start of a new DMA stream
- */
- if (startsg->dma_address & PIDE_FLAG) {
- u32 pide = startsg->dma_address & ~PIDE_FLAG;
- dma_offset = (unsigned long) pide & ~iovp_mask;
- startsg->dma_address = 0;
- if (n_mappings)
- dma_sg = sg_next(dma_sg);
- dma_sg->dma_address = pide | ioc->ibase;
- pdirp = &(ioc->pdir_base[pide >> iovp_shift]);
- n_mappings++;
- }
-
- /*
- ** Look for a VCONTIG chunk
- */
- if (cnt) {
- unsigned long vaddr = (unsigned long) sba_sg_address(startsg);
- ASSERT(pdirp);
-
- /* Since multiple Vcontig blocks could make up
- ** one DMA stream, *add* cnt to dma_len.
- */
- dma_sg->dma_length += cnt;
- cnt += dma_offset;
- dma_offset=0; /* only want offset on first chunk */
- cnt = ROUNDUP(cnt, iovp_size);
- do {
- sba_io_pdir_entry(pdirp, vaddr);
- vaddr += iovp_size;
- cnt -= iovp_size;
- pdirp++;
- } while (cnt > 0);
- }
- startsg = sg_next(startsg);
- }
- /* force pdir update */
- wmb();
-
-#ifdef DEBUG_LARGE_SG_ENTRIES
- dump_run_sg = 0;
-#endif
- return(n_mappings);
-}
-
-
-/*
-** Two address ranges are DMA contiguous *iff* "end of prev" and
-** "start of next" are both on an IOV page boundary.
-**
-** (shift left is a quick trick to mask off upper bits)
-*/
-#define DMA_CONTIG(__X, __Y) \
- (((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - iovp_shift)) == 0UL)
-
-
-/**
- * sba_coalesce_chunks - preprocess the SG list
- * @ioc: IO MMU structure which owns the pdir we are interested in.
- * @startsg: list of IOVA/size pairs
- * @nents: number of entries in startsg list
- *
- * First pass is to walk the SG list and determine where the breaks are
- * in the DMA stream. Allocates PDIR entries but does not fill them.
- * Returns the number of DMA chunks.
- *
- * Doing the fill separate from the coalescing/allocation keeps the
- * code simpler. Future enhancement could make one pass through
- * the sglist do both.
- */
-static SBA_INLINE int
-sba_coalesce_chunks(struct ioc *ioc, struct device *dev,
- struct scatterlist *startsg,
- int nents)
-{
- struct scatterlist *vcontig_sg; /* VCONTIG chunk head */
- unsigned long vcontig_len; /* len of VCONTIG chunk */
- unsigned long vcontig_end;
- struct scatterlist *dma_sg; /* next DMA stream head */
- unsigned long dma_offset, dma_len; /* start/len of DMA stream */
- int n_mappings = 0;
- unsigned int max_seg_size = dma_get_max_seg_size(dev);
- int idx;
-
- while (nents > 0) {
- unsigned long vaddr = (unsigned long) sba_sg_address(startsg);
-
- /*
- ** Prepare for first/next DMA stream
- */
- dma_sg = vcontig_sg = startsg;
- dma_len = vcontig_len = vcontig_end = startsg->length;
- vcontig_end += vaddr;
- dma_offset = vaddr & ~iovp_mask;
-
- /* PARANOID: clear entries */
- startsg->dma_address = startsg->dma_length = 0;
-
- /*
- ** This loop terminates one iteration "early" since
- ** it's always looking one "ahead".
- */
- while (--nents > 0) {
- unsigned long vaddr; /* tmp */
-
- startsg = sg_next(startsg);
-
- /* PARANOID */
- startsg->dma_address = startsg->dma_length = 0;
-
- /* catch brokenness in SCSI layer */
- ASSERT(startsg->length <= DMA_CHUNK_SIZE);
-
- /*
- ** First make sure current dma stream won't
- ** exceed DMA_CHUNK_SIZE if we coalesce the
- ** next entry.
- */
- if (((dma_len + dma_offset + startsg->length + ~iovp_mask) & iovp_mask)
- > DMA_CHUNK_SIZE)
- break;
-
- if (dma_len + startsg->length > max_seg_size)
- break;
-
- /*
- ** Then look for virtually contiguous blocks.
- **
- ** append the next transaction?
- */
- vaddr = (unsigned long) sba_sg_address(startsg);
- if (vcontig_end == vaddr)
- {
- vcontig_len += startsg->length;
- vcontig_end += startsg->length;
- dma_len += startsg->length;
- continue;
- }
-
-#ifdef DEBUG_LARGE_SG_ENTRIES
- dump_run_sg = (vcontig_len > iovp_size);
-#endif
-
- /*
- ** Not virtually contiguous.
- ** Terminate prev chunk.
- ** Start a new chunk.
- **
- ** Once we start a new VCONTIG chunk, dma_offset
- ** can't change. And we need the offset from the first
- ** chunk - not the last one. Ergo Successive chunks
- ** must start on page boundaries and dove tail
- ** with it's predecessor.
- */
- vcontig_sg->dma_length = vcontig_len;
-
- vcontig_sg = startsg;
- vcontig_len = startsg->length;
-
- /*
- ** 3) do the entries end/start on page boundaries?
- ** Don't update vcontig_end until we've checked.
- */
- if (DMA_CONTIG(vcontig_end, vaddr))
- {
- vcontig_end = vcontig_len + vaddr;
- dma_len += vcontig_len;
- continue;
- } else {
- break;
- }
- }
-
- /*
- ** End of DMA Stream
- ** Terminate last VCONTIG block.
- ** Allocate space for DMA stream.
- */
- vcontig_sg->dma_length = vcontig_len;
- dma_len = (dma_len + dma_offset + ~iovp_mask) & iovp_mask;
- ASSERT(dma_len <= DMA_CHUNK_SIZE);
- idx = sba_alloc_range(ioc, dev, dma_len);
- if (idx < 0) {
- dma_sg->dma_length = 0;
- return -1;
- }
- dma_sg->dma_address = (dma_addr_t)(PIDE_FLAG | (idx << iovp_shift)
- | dma_offset);
- n_mappings++;
- }
-
- return n_mappings;
-}
-
-static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir,
- unsigned long attrs);
-/**
- * sba_map_sg - map Scatter/Gather list
- * @dev: instance of PCI owned by the driver that's asking.
- * @sglist: array of buffer/length pairs
- * @nents: number of entries in list
- * @dir: R/W or both.
- * @attrs: optional dma attributes
- *
- * See Documentation/core-api/dma-api-howto.rst
- */
-static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir,
- unsigned long attrs)
-{
- struct ioc *ioc;
- int coalesced, filled = 0;
-#ifdef ASSERT_PDIR_SANITY
- unsigned long flags;
-#endif
-#ifdef ALLOW_IOV_BYPASS_SG
- struct scatterlist *sg;
-#endif
-
- DBG_RUN_SG("%s() START %d entries\n", __func__, nents);
- ioc = GET_IOC(dev);
- ASSERT(ioc);
-
-#ifdef ALLOW_IOV_BYPASS_SG
- ASSERT(to_pci_dev(dev)->dma_mask);
- if (likely((ioc->dma_mask & ~to_pci_dev(dev)->dma_mask) == 0)) {
- for_each_sg(sglist, sg, nents, filled) {
- sg->dma_length = sg->length;
- sg->dma_address = virt_to_phys(sba_sg_address(sg));
- }
- return filled;
- }
-#endif
- /* Fast path single entry scatterlists. */
- if (nents == 1) {
- sglist->dma_length = sglist->length;
- sglist->dma_address = sba_map_page(dev, sg_page(sglist),
- sglist->offset, sglist->length, dir, attrs);
- if (dma_mapping_error(dev, sglist->dma_address))
- return -EIO;
- return 1;
- }
-
-#ifdef ASSERT_PDIR_SANITY
- spin_lock_irqsave(&ioc->res_lock, flags);
- if (sba_check_pdir(ioc,"Check before sba_map_sg_attrs()"))
- {
- sba_dump_sg(ioc, sglist, nents);
- panic("Check before sba_map_sg_attrs()");
- }
- spin_unlock_irqrestore(&ioc->res_lock, flags);
-#endif
-
- prefetch(ioc->res_hint);
-
- /*
- ** First coalesce the chunks and allocate I/O pdir space
- **
- ** If this is one DMA stream, we can properly map using the
- ** correct virtual address associated with each DMA page.
- ** w/o this association, we wouldn't have coherent DMA!
- ** Access to the virtual address is what forces a two pass algorithm.
- */
- coalesced = sba_coalesce_chunks(ioc, dev, sglist, nents);
- if (coalesced < 0) {
- sba_unmap_sg_attrs(dev, sglist, nents, dir, attrs);
- return -ENOMEM;
- }
-
- /*
- ** Program the I/O Pdir
- **
- ** map the virtual addresses to the I/O Pdir
- ** o dma_address will contain the pdir index
- ** o dma_len will contain the number of bytes to map
- ** o address contains the virtual address.
- */
- filled = sba_fill_pdir(ioc, sglist, nents);
-
-#ifdef ASSERT_PDIR_SANITY
- spin_lock_irqsave(&ioc->res_lock, flags);
- if (sba_check_pdir(ioc,"Check after sba_map_sg_attrs()"))
- {
- sba_dump_sg(ioc, sglist, nents);
- panic("Check after sba_map_sg_attrs()\n");
- }
- spin_unlock_irqrestore(&ioc->res_lock, flags);
-#endif
-
- ASSERT(coalesced == filled);
- DBG_RUN_SG("%s() DONE %d mappings\n", __func__, filled);
-
- return filled;
-}
-
-/**
- * sba_unmap_sg_attrs - unmap Scatter/Gather list
- * @dev: instance of PCI owned by the driver that's asking.
- * @sglist: array of buffer/length pairs
- * @nents: number of entries in list
- * @dir: R/W or both.
- * @attrs: optional dma attributes
- *
- * See Documentation/core-api/dma-api-howto.rst
- */
-static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir,
- unsigned long attrs)
-{
-#ifdef ASSERT_PDIR_SANITY
- struct ioc *ioc;
- unsigned long flags;
-#endif
-
- DBG_RUN_SG("%s() START %d entries, %p,%x\n",
- __func__, nents, sba_sg_address(sglist), sglist->length);
-
-#ifdef ASSERT_PDIR_SANITY
- ioc = GET_IOC(dev);
- ASSERT(ioc);
-
- spin_lock_irqsave(&ioc->res_lock, flags);
- sba_check_pdir(ioc,"Check before sba_unmap_sg_attrs()");
- spin_unlock_irqrestore(&ioc->res_lock, flags);
-#endif
-
- while (nents && sglist->dma_length) {
-
- sba_unmap_page(dev, sglist->dma_address, sglist->dma_length,
- dir, attrs);
- sglist = sg_next(sglist);
- nents--;
- }
-
- DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents);
-
-#ifdef ASSERT_PDIR_SANITY
- spin_lock_irqsave(&ioc->res_lock, flags);
- sba_check_pdir(ioc,"Check after sba_unmap_sg_attrs()");
- spin_unlock_irqrestore(&ioc->res_lock, flags);
-#endif
-
-}
-
-/**************************************************************
-*
-* Initialization and claim
-*
-***************************************************************/
-
-static void
-ioc_iova_init(struct ioc *ioc)
-{
- int tcnfg;
- int agp_found = 0;
- struct pci_dev *device = NULL;
-#ifdef FULL_VALID_PDIR
- unsigned long index;
-#endif
-
- /*
- ** Firmware programs the base and size of a "safe IOVA space"
- ** (one that doesn't overlap memory or LMMIO space) in the
- ** IBASE and IMASK registers.
- */
- ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE) & ~0x1UL;
- ioc->imask = READ_REG(ioc->ioc_hpa + IOC_IMASK) | 0xFFFFFFFF00000000UL;
-
- ioc->iov_size = ~ioc->imask + 1;
-
- DBG_INIT("%s() hpa %p IOV base 0x%lx mask 0x%lx (%dMB)\n",
- __func__, ioc->ioc_hpa, ioc->ibase, ioc->imask,
- ioc->iov_size >> 20);
-
- switch (iovp_size) {
- case 4*1024: tcnfg = 0; break;
- case 8*1024: tcnfg = 1; break;
- case 16*1024: tcnfg = 2; break;
- case 64*1024: tcnfg = 3; break;
- default:
- panic(PFX "Unsupported IOTLB page size %ldK",
- iovp_size >> 10);
- break;
- }
- WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG);
-
- ioc->pdir_size = (ioc->iov_size / iovp_size) * PDIR_ENTRY_SIZE;
- ioc->pdir_base = (void *) __get_free_pages(GFP_KERNEL,
- get_order(ioc->pdir_size));
- if (!ioc->pdir_base)
- panic(PFX "Couldn't allocate I/O Page Table\n");
-
- memset(ioc->pdir_base, 0, ioc->pdir_size);
-
- DBG_INIT("%s() IOV page size %ldK pdir %p size %x\n", __func__,
- iovp_size >> 10, ioc->pdir_base, ioc->pdir_size);
-
- ASSERT(ALIGN((unsigned long) ioc->pdir_base, 4*1024) == (unsigned long) ioc->pdir_base);
- WRITE_REG(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
-
- /*
- ** If an AGP device is present, only use half of the IOV space
- ** for PCI DMA. Unfortunately we can't know ahead of time
- ** whether GART support will actually be used, for now we
- ** can just key on an AGP device found in the system.
- ** We program the next pdir index after we stop w/ a key for
- ** the GART code to handshake on.
- */
- for_each_pci_dev(device)
- agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP);
-
- if (agp_found && reserve_sba_gart) {
- printk(KERN_INFO PFX "reserving %dMb of IOVA space at 0x%lx for agpgart\n",
- ioc->iov_size/2 >> 20, ioc->ibase + ioc->iov_size/2);
- ioc->pdir_size /= 2;
- ((u64 *)ioc->pdir_base)[PDIR_INDEX(ioc->iov_size/2)] = ZX1_SBA_IOMMU_COOKIE;
- }
-#ifdef FULL_VALID_PDIR
- /*
- ** Check to see if the spill page has been allocated, we don't need more than
- ** one across multiple SBAs.
- */
- if (!prefetch_spill_page) {
- char *spill_poison = "SBAIOMMU POISON";
- int poison_size = 16;
- void *poison_addr, *addr;
-
- addr = (void *)__get_free_pages(GFP_KERNEL, get_order(iovp_size));
- if (!addr)
- panic(PFX "Couldn't allocate PDIR spill page\n");
-
- poison_addr = addr;
- for ( ; (u64) poison_addr < addr + iovp_size; poison_addr += poison_size)
- memcpy(poison_addr, spill_poison, poison_size);
-
- prefetch_spill_page = virt_to_phys(addr);
-
- DBG_INIT("%s() prefetch spill addr: 0x%lx\n", __func__, prefetch_spill_page);
- }
- /*
- ** Set all the PDIR entries valid w/ the spill page as the target
- */
- for (index = 0 ; index < (ioc->pdir_size / PDIR_ENTRY_SIZE) ; index++)
- ((u64 *)ioc->pdir_base)[index] = (0x80000000000000FF | prefetch_spill_page);
-#endif
-
- /* Clear I/O TLB of any possible entries */
- WRITE_REG(ioc->ibase | (get_iovp_order(ioc->iov_size) + iovp_shift), ioc->ioc_hpa + IOC_PCOM);
- READ_REG(ioc->ioc_hpa + IOC_PCOM);
-
- /* Enable IOVA translation */
- WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE);
- READ_REG(ioc->ioc_hpa + IOC_IBASE);
-}
-
-static void __init
-ioc_resource_init(struct ioc *ioc)
-{
- spin_lock_init(&ioc->res_lock);
-#if DELAYED_RESOURCE_CNT > 0
- spin_lock_init(&ioc->saved_lock);
-#endif
-
- /* resource map size dictated by pdir_size */
- ioc->res_size = ioc->pdir_size / PDIR_ENTRY_SIZE; /* entries */
- ioc->res_size >>= 3; /* convert bit count to byte count */
- DBG_INIT("%s() res_size 0x%x\n", __func__, ioc->res_size);
-
- ioc->res_map = (char *) __get_free_pages(GFP_KERNEL,
- get_order(ioc->res_size));
- if (!ioc->res_map)
- panic(PFX "Couldn't allocate resource map\n");
-
- memset(ioc->res_map, 0, ioc->res_size);
- /* next available IOVP - circular search */
- ioc->res_hint = (unsigned long *) ioc->res_map;
-
-#ifdef ASSERT_PDIR_SANITY
- /* Mark first bit busy - ie no IOVA 0 */
- ioc->res_map[0] = 0x1;
- ioc->pdir_base[0] = 0x8000000000000000ULL | ZX1_SBA_IOMMU_COOKIE;
-#endif
-#ifdef FULL_VALID_PDIR
- /* Mark the last resource used so we don't prefetch beyond IOVA space */
- ioc->res_map[ioc->res_size - 1] |= 0x80UL; /* res_map is chars */
- ioc->pdir_base[(ioc->pdir_size / PDIR_ENTRY_SIZE) - 1] = (0x80000000000000FF
- | prefetch_spill_page);
-#endif
-
- DBG_INIT("%s() res_map %x %p\n", __func__,
- ioc->res_size, (void *) ioc->res_map);
-}
-
-static void __init
-ioc_sac_init(struct ioc *ioc)
-{
- struct pci_dev *sac = NULL;
- struct pci_controller *controller = NULL;
-
- /*
- * pci_alloc_coherent() must return a DMA address which is
- * SAC (single address cycle) addressable, so allocate a
- * pseudo-device to enforce that.
- */
- sac = kzalloc(sizeof(*sac), GFP_KERNEL);
- if (!sac)
- panic(PFX "Couldn't allocate struct pci_dev");
-
- controller = kzalloc(sizeof(*controller), GFP_KERNEL);
- if (!controller)
- panic(PFX "Couldn't allocate struct pci_controller");
-
- controller->iommu = ioc;
- sac->sysdata = controller;
- sac->dma_mask = 0xFFFFFFFFUL;
- sac->dev.bus = &pci_bus_type;
- ioc->sac_only_dev = sac;
-}
-
-static void __init
-ioc_zx1_init(struct ioc *ioc)
-{
- unsigned long rope_config;
- unsigned int i;
-
- if (ioc->rev < 0x20)
- panic(PFX "IOC 2.0 or later required for IOMMU support\n");
-
- /* 38 bit memory controller + extra bit for range displaced by MMIO */
- ioc->dma_mask = (0x1UL << 39) - 1;
-
- /*
- ** Clear ROPE(N)_CONFIG AO bit.
- ** Disables "NT Ordering" (~= !"Relaxed Ordering")
- ** Overrides bit 1 in DMA Hint Sets.
- ** Improves netperf UDP_STREAM by ~10% for tg3 on bcm5701.
- */
- for (i=0; i<(8*8); i+=8) {
- rope_config = READ_REG(ioc->ioc_hpa + IOC_ROPE0_CFG + i);
- rope_config &= ~IOC_ROPE_AO;
- WRITE_REG(rope_config, ioc->ioc_hpa + IOC_ROPE0_CFG + i);
- }
-}
-
-typedef void (initfunc)(struct ioc *);
-
-struct ioc_iommu {
- u32 func_id;
- char *name;
- initfunc *init;
-};
-
-static struct ioc_iommu ioc_iommu_info[] __initdata = {
- { ZX1_IOC_ID, "zx1", ioc_zx1_init },
- { ZX2_IOC_ID, "zx2", NULL },
- { SX1000_IOC_ID, "sx1000", NULL },
- { SX2000_IOC_ID, "sx2000", NULL },
-};
-
-static void __init ioc_init(unsigned long hpa, struct ioc *ioc)
-{
- struct ioc_iommu *info;
-
- ioc->next = ioc_list;
- ioc_list = ioc;
-
- ioc->ioc_hpa = ioremap(hpa, 0x1000);
-
- ioc->func_id = READ_REG(ioc->ioc_hpa + IOC_FUNC_ID);
- ioc->rev = READ_REG(ioc->ioc_hpa + IOC_FCLASS) & 0xFFUL;
- ioc->dma_mask = 0xFFFFFFFFFFFFFFFFUL; /* conservative */
-
- for (info = ioc_iommu_info; info < ioc_iommu_info + ARRAY_SIZE(ioc_iommu_info); info++) {
- if (ioc->func_id == info->func_id) {
- ioc->name = info->name;
- if (info->init)
- (info->init)(ioc);
- }
- }
-
- iovp_size = (1 << iovp_shift);
- iovp_mask = ~(iovp_size - 1);
-
- DBG_INIT("%s: PAGE_SIZE %ldK, iovp_size %ldK\n", __func__,
- PAGE_SIZE >> 10, iovp_size >> 10);
-
- if (!ioc->name) {
- ioc->name = kmalloc(24, GFP_KERNEL);
- if (ioc->name)
- sprintf((char *) ioc->name, "Unknown (%04x:%04x)",
- ioc->func_id & 0xFFFF, (ioc->func_id >> 16) & 0xFFFF);
- else
- ioc->name = "Unknown";
- }
-
- ioc_iova_init(ioc);
- ioc_resource_init(ioc);
- ioc_sac_init(ioc);
-
- printk(KERN_INFO PFX
- "%s %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
- ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
- hpa, ioc->iov_size >> 20, ioc->ibase);
-}
-
-
-
-/**************************************************************************
-**
-** SBA initialization code (HW and SW)
-**
-** o identify SBA chip itself
-** o FIXME: initialize DMA hints for reasonable defaults
-**
-**************************************************************************/
-
-#ifdef CONFIG_PROC_FS
-static void *
-ioc_start(struct seq_file *s, loff_t *pos)
-{
- struct ioc *ioc;
- loff_t n = *pos;
-
- for (ioc = ioc_list; ioc; ioc = ioc->next)
- if (!n--)
- return ioc;
-
- return NULL;
-}
-
-static void *
-ioc_next(struct seq_file *s, void *v, loff_t *pos)
-{
- struct ioc *ioc = v;
-
- ++*pos;
- return ioc->next;
-}
-
-static void
-ioc_stop(struct seq_file *s, void *v)
-{
-}
-
-static int
-ioc_show(struct seq_file *s, void *v)
-{
- struct ioc *ioc = v;
- unsigned long *res_ptr = (unsigned long *)ioc->res_map;
- int i, used = 0;
-
- seq_printf(s, "Hewlett Packard %s IOC rev %d.%d\n",
- ioc->name, ((ioc->rev >> 4) & 0xF), (ioc->rev & 0xF));
-#ifdef CONFIG_NUMA
- if (ioc->node != NUMA_NO_NODE)
- seq_printf(s, "NUMA node : %d\n", ioc->node);
-#endif
- seq_printf(s, "IOVA size : %ld MB\n", ((ioc->pdir_size >> 3) * iovp_size)/(1024*1024));
- seq_printf(s, "IOVA page size : %ld kb\n", iovp_size/1024);
-
- for (i = 0; i < (ioc->res_size / sizeof(unsigned long)); ++i, ++res_ptr)
- used += hweight64(*res_ptr);
-
- seq_printf(s, "PDIR size : %d entries\n", ioc->pdir_size >> 3);
- seq_printf(s, "PDIR used : %d entries\n", used);
-
-#ifdef PDIR_SEARCH_TIMING
- {
- unsigned long i = 0, avg = 0, min, max;
- min = max = ioc->avg_search[0];
- for (i = 0; i < SBA_SEARCH_SAMPLE; i++) {
- avg += ioc->avg_search[i];
- if (ioc->avg_search[i] > max) max = ioc->avg_search[i];
- if (ioc->avg_search[i] < min) min = ioc->avg_search[i];
- }
- avg /= SBA_SEARCH_SAMPLE;
- seq_printf(s, "Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles/IOVA page)\n",
- min, avg, max);
- }
-#endif
-#ifndef ALLOW_IOV_BYPASS
- seq_printf(s, "IOVA bypass disabled\n");
-#endif
- return 0;
-}
-
-static const struct seq_operations ioc_seq_ops = {
- .start = ioc_start,
- .next = ioc_next,
- .stop = ioc_stop,
- .show = ioc_show
-};
-
-static void __init
-ioc_proc_init(void)
-{
- struct proc_dir_entry *dir;
-
- dir = proc_mkdir("bus/mckinley", NULL);
- if (!dir)
- return;
-
- proc_create_seq(ioc_list->name, 0, dir, &ioc_seq_ops);
-}
-#endif
-
-static void
-sba_connect_bus(struct pci_bus *bus)
-{
- acpi_handle handle, parent;
- acpi_status status;
- struct ioc *ioc;
-
- if (!PCI_CONTROLLER(bus))
- panic(PFX "no sysdata on bus %d!\n", bus->number);
-
- if (PCI_CONTROLLER(bus)->iommu)
- return;
-
- handle = acpi_device_handle(PCI_CONTROLLER(bus)->companion);
- if (!handle)
- return;
-
- /*
- * The IOC scope encloses PCI root bridges in the ACPI
- * namespace, so work our way out until we find an IOC we
- * claimed previously.
- */
- do {
- for (ioc = ioc_list; ioc; ioc = ioc->next)
- if (ioc->handle == handle) {
- PCI_CONTROLLER(bus)->iommu = ioc;
- return;
- }
-
- status = acpi_get_parent(handle, &parent);
- handle = parent;
- } while (ACPI_SUCCESS(status));
-
- printk(KERN_WARNING "No IOC for PCI Bus %04x:%02x in ACPI\n", pci_domain_nr(bus), bus->number);
-}
-
-static void __init
-sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle)
-{
-#ifdef CONFIG_NUMA
- unsigned int node;
-
- node = acpi_get_node(handle);
- if (node != NUMA_NO_NODE && !node_online(node))
- node = NUMA_NO_NODE;
-
- ioc->node = node;
-#endif
-}
-
-static void __init acpi_sba_ioc_add(struct ioc *ioc)
-{
- acpi_handle handle = ioc->handle;
- acpi_status status;
- u64 hpa, length;
- struct acpi_device_info *adi;
-
- ioc_found = ioc->next;
- status = hp_acpi_csr_space(handle, &hpa, &length);
- if (ACPI_FAILURE(status))
- goto err;
-
- status = acpi_get_object_info(handle, &adi);
- if (ACPI_FAILURE(status))
- goto err;
-
- /*
- * For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI
- * root bridges, and its CSR space includes the IOC function.
- */
- if (strncmp("HWP0001", adi->hardware_id.string, 7) == 0) {
- hpa += ZX1_IOC_OFFSET;
- /* zx1 based systems default to kernel page size iommu pages */
- if (!iovp_shift)
- iovp_shift = min(PAGE_SHIFT, 16);
- }
- kfree(adi);
-
- /*
- * default anything not caught above or specified on cmdline to 4k
- * iommu page size
- */
- if (!iovp_shift)
- iovp_shift = 12;
-
- ioc_init(hpa, ioc);
- /* setup NUMA node association */
- sba_map_ioc_to_node(ioc, handle);
- return;
-
- err:
- kfree(ioc);
-}
-
-static const struct acpi_device_id hp_ioc_iommu_device_ids[] = {
- {"HWP0001", 0},
- {"HWP0004", 0},
- {"", 0},
-};
-
-static int acpi_sba_ioc_attach(struct acpi_device *device,
- const struct acpi_device_id *not_used)
-{
- struct ioc *ioc;
-
- ioc = kzalloc(sizeof(*ioc), GFP_KERNEL);
- if (!ioc)
- return -ENOMEM;
-
- ioc->next = ioc_found;
- ioc_found = ioc;
- ioc->handle = device->handle;
- return 1;
-}
-
-
-static struct acpi_scan_handler acpi_sba_ioc_handler = {
- .ids = hp_ioc_iommu_device_ids,
- .attach = acpi_sba_ioc_attach,
-};
-
-static int __init acpi_sba_ioc_init_acpi(void)
-{
- return acpi_scan_add_handler(&acpi_sba_ioc_handler);
-}
-/* This has to run before acpi_scan_init(). */
-arch_initcall(acpi_sba_ioc_init_acpi);
-
-static int sba_dma_supported (struct device *dev, u64 mask)
-{
- /* make sure it's at least 32bit capable */
- return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
-}
-
-static const struct dma_map_ops sba_dma_ops = {
- .alloc = sba_alloc_coherent,
- .free = sba_free_coherent,
- .map_page = sba_map_page,
- .unmap_page = sba_unmap_page,
- .map_sg = sba_map_sg_attrs,
- .unmap_sg = sba_unmap_sg_attrs,
- .dma_supported = sba_dma_supported,
- .mmap = dma_common_mmap,
- .get_sgtable = dma_common_get_sgtable,
- .alloc_pages = dma_common_alloc_pages,
- .free_pages = dma_common_free_pages,
-};
-
-static int __init
-sba_init(void)
-{
- /*
- * If we are booting a kdump kernel, the sba_iommu will cause devices
- * that were not shutdown properly to MCA as soon as they are turned
- * back on. Our only option for a successful kdump kernel boot is to
- * use swiotlb.
- */
- if (is_kdump_kernel())
- return 0;
-
- /*
- * ioc_found should be populated by the acpi_sba_ioc_handler's .attach()
- * routine, but that only happens if acpi_scan_init() has already run.
- */
- while (ioc_found)
- acpi_sba_ioc_add(ioc_found);
-
- if (!ioc_list)
- return 0;
-
- {
- struct pci_bus *b = NULL;
- while ((b = pci_find_next_bus(b)) != NULL)
- sba_connect_bus(b);
- }
-
- /* no need for swiotlb with the iommu */
- swiotlb_exit();
- dma_ops = &sba_dma_ops;
-
-#ifdef CONFIG_PROC_FS
- ioc_proc_init();
-#endif
- return 0;
-}
-
-subsys_initcall(sba_init); /* must be initialized after ACPI etc., but before any drivers... */
-
-static int __init
-nosbagart(char *str)
-{
- reserve_sba_gart = 0;
- return 1;
-}
-
-__setup("nosbagart", nosbagart);
-
-static int __init
-sba_page_override(char *str)
-{
- unsigned long page_size;
-
- page_size = memparse(str, &str);
- switch (page_size) {
- case 4096:
- case 8192:
- case 16384:
- case 65536:
- iovp_shift = ffs(page_size) - 1;
- break;
- default:
- printk("%s: unknown/unsupported iommu page size %ld\n",
- __func__, page_size);
- }
-
- return 1;
-}
-
-__setup("sbapagesize=",sba_page_override);
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
deleted file mode 100644
index aefae2efde9f..000000000000
--- a/arch/ia64/include/asm/Kbuild
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-generated-y += syscall_table.h
-generic-y += agp.h
-generic-y += kvm_para.h
-generic-y += mcs_spinlock.h
-generic-y += vtime.h
diff --git a/arch/ia64/include/asm/acenv.h b/arch/ia64/include/asm/acenv.h
deleted file mode 100644
index 9d673cd4c2ad..000000000000
--- a/arch/ia64/include/asm/acenv.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * IA64 specific ACPICA environments and implementation
- *
- * Copyright (C) 2014, Intel Corporation
- * Author: Lv Zheng <lv.zheng@intel.com>
- */
-
-#ifndef _ASM_IA64_ACENV_H
-#define _ASM_IA64_ACENV_H
-
-#include <asm/intrinsics.h>
-
-#define COMPILER_DEPENDENT_INT64 long
-#define COMPILER_DEPENDENT_UINT64 unsigned long
-
-/* Asm macros */
-
-static inline int
-ia64_acpi_acquire_global_lock(unsigned int *lock)
-{
- unsigned int old, new, val;
- do {
- old = *lock;
- new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
- val = ia64_cmpxchg4_acq(lock, new, old);
- } while (unlikely (val != old));
- return (new < 3) ? -1 : 0;
-}
-
-static inline int
-ia64_acpi_release_global_lock(unsigned int *lock)
-{
- unsigned int old, new, val;
- do {
- old = *lock;
- new = old & ~0x3;
- val = ia64_cmpxchg4_acq(lock, new, old);
- } while (unlikely (val != old));
- return old & 0x1;
-}
-
-#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \
- ((Acq) = ia64_acpi_acquire_global_lock(&facs->global_lock))
-
-#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \
- ((Acq) = ia64_acpi_release_global_lock(&facs->global_lock))
-
-#endif /* _ASM_IA64_ACENV_H */
diff --git a/arch/ia64/include/asm/acpi-ext.h b/arch/ia64/include/asm/acpi-ext.h
deleted file mode 100644
index eaa57583d151..000000000000
--- a/arch/ia64/include/asm/acpi-ext.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * (c) Copyright 2003, 2006 Hewlett-Packard Development Company, L.P.
- * Alex Williamson <alex.williamson@hp.com>
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- *
- * Vendor specific extensions to ACPI.
- */
-
-#ifndef _ASM_IA64_ACPI_EXT_H
-#define _ASM_IA64_ACPI_EXT_H
-
-#include <linux/types.h>
-
-extern acpi_status hp_acpi_csr_space (acpi_handle, u64 *base, u64 *length);
-
-#endif /* _ASM_IA64_ACPI_EXT_H */
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h
deleted file mode 100644
index 58500a964238..000000000000
--- a/arch/ia64/include/asm/acpi.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
- * Copyright (C) 2001,2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- */
-
-#ifndef _ASM_ACPI_H
-#define _ASM_ACPI_H
-
-#ifdef __KERNEL__
-
-#include <acpi/proc_cap_intel.h>
-
-#include <linux/init.h>
-#include <linux/numa.h>
-#include <asm/numa.h>
-
-
-extern int acpi_lapic;
-#define acpi_disabled 0 /* ACPI always enabled on IA64 */
-#define acpi_noirq 0 /* ACPI always enabled on IA64 */
-#define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */
-#define acpi_strict 1 /* no ACPI spec workarounds on IA64 */
-
-static inline bool acpi_has_cpu_in_madt(void)
-{
- return !!acpi_lapic;
-}
-
-#define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
-static inline void disable_acpi(void) { }
-
-int acpi_request_vector (u32 int_type);
-int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
-
-/* Low-level suspend routine. */
-extern int acpi_suspend_lowlevel(void);
-
-static inline unsigned long acpi_get_wakeup_address(void)
-{
- return 0;
-}
-
-/*
- * Record the cpei override flag and current logical cpu. This is
- * useful for CPU removal.
- */
-extern unsigned int can_cpei_retarget(void);
-extern unsigned int is_cpu_cpei_target(unsigned int cpu);
-extern void set_cpei_target_cpu(unsigned int cpu);
-extern unsigned int get_cpei_target_cpu(void);
-extern void prefill_possible_map(void);
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-extern int additional_cpus;
-#else
-#define additional_cpus 0
-#endif
-
-#ifdef CONFIG_ACPI_NUMA
-#if MAX_NUMNODES > 256
-#define MAX_PXM_DOMAINS MAX_NUMNODES
-#else
-#define MAX_PXM_DOMAINS (256)
-#endif
-extern int pxm_to_nid_map[MAX_PXM_DOMAINS];
-extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
-#endif
-
-static inline bool arch_has_acpi_pdc(void) { return true; }
-static inline void arch_acpi_set_proc_cap_bits(u32 *cap)
-{
- *cap |= ACPI_PROC_CAP_EST_CAPABILITY_SMP;
-}
-
-#ifdef CONFIG_ACPI_NUMA
-extern cpumask_t early_cpu_possible_map;
-#define for_each_possible_early_cpu(cpu) \
- for_each_cpu((cpu), &early_cpu_possible_map)
-
-static inline void per_cpu_scan_finalize(int min_cpus, int reserve_cpus)
-{
- int low_cpu, high_cpu;
- int cpu;
- int next_nid = 0;
-
- low_cpu = cpumask_weight(&early_cpu_possible_map);
-
- high_cpu = max(low_cpu, min_cpus);
- high_cpu = min(high_cpu + reserve_cpus, NR_CPUS);
-
- for (cpu = low_cpu; cpu < high_cpu; cpu++) {
- cpumask_set_cpu(cpu, &early_cpu_possible_map);
- if (node_cpuid[cpu].nid == NUMA_NO_NODE) {
- node_cpuid[cpu].nid = next_nid;
- next_nid++;
- if (next_nid >= num_online_nodes())
- next_nid = 0;
- }
- }
-}
-
-extern void acpi_numa_fixup(void);
-
-#endif /* CONFIG_ACPI_NUMA */
-
-#endif /*__KERNEL__*/
-
-#endif /*_ASM_ACPI_H*/
diff --git a/arch/ia64/include/asm/asm-offsets.h b/arch/ia64/include/asm/asm-offsets.h
deleted file mode 100644
index d370ee36a182..000000000000
--- a/arch/ia64/include/asm/asm-offsets.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <generated/asm-offsets.h>
diff --git a/arch/ia64/include/asm/asm-prototypes.h b/arch/ia64/include/asm/asm-prototypes.h
deleted file mode 100644
index a96689447a74..000000000000
--- a/arch/ia64/include/asm/asm-prototypes.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_ASM_PROTOTYPES_H
-#define _ASM_IA64_ASM_PROTOTYPES_H
-
-#include <asm/cacheflush.h>
-#include <asm/checksum.h>
-#include <asm/esi.h>
-#include <asm/ftrace.h>
-#include <asm/page.h>
-#include <asm/pal.h>
-#include <asm/string.h>
-#include <linux/uaccess.h>
-#include <asm/unwind.h>
-#include <asm/xor.h>
-
-extern const char ia64_ivt[];
-
-signed int __divsi3(signed int, unsigned int);
-signed int __modsi3(signed int, unsigned int);
-
-signed long long __divdi3(signed long long, unsigned long long);
-signed long long __moddi3(signed long long, unsigned long long);
-
-unsigned int __udivsi3(unsigned int, unsigned int);
-unsigned int __umodsi3(unsigned int, unsigned int);
-
-unsigned long long __udivdi3(unsigned long long, unsigned long long);
-unsigned long long __umoddi3(unsigned long long, unsigned long long);
-
-#endif /* _ASM_IA64_ASM_PROTOTYPES_H */
diff --git a/arch/ia64/include/asm/asmmacro.h b/arch/ia64/include/asm/asmmacro.h
deleted file mode 100644
index 52619c517f09..000000000000
--- a/arch/ia64/include/asm/asmmacro.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_ASMMACRO_H
-#define _ASM_IA64_ASMMACRO_H
-
-/*
- * Copyright (C) 2000-2001, 2003-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-
-#define ENTRY(name) \
- .align 32; \
- .proc name; \
-name:
-
-#define ENTRY_MIN_ALIGN(name) \
- .align 16; \
- .proc name; \
-name:
-
-#define GLOBAL_ENTRY(name) \
- .global name; \
- ENTRY(name)
-
-#define END(name) \
- .endp name
-
-/*
- * Helper macros to make unwind directives more readable:
- */
-
-/* prologue_gr: */
-#define ASM_UNW_PRLG_RP 0x8
-#define ASM_UNW_PRLG_PFS 0x4
-#define ASM_UNW_PRLG_PSP 0x2
-#define ASM_UNW_PRLG_PR 0x1
-#define ASM_UNW_PRLG_GRSAVE(ninputs) (32+(ninputs))
-
-/*
- * Helper macros for accessing user memory.
- *
- * When adding any new .section/.previous entries here, make sure to
- * also add it to the DISCARD section in arch/ia64/kernel/gate.lds.S or
- * unpleasant things will happen.
- */
-
- .section "__ex_table", "a" // declare section & section attributes
- .previous
-
-# define EX(y,x...) \
- .xdata4 "__ex_table", 99f-., y-.; \
- [99:] x
-# define EXCLR(y,x...) \
- .xdata4 "__ex_table", 99f-., y-.+4; \
- [99:] x
-
-/*
- * Tag MCA recoverable instruction ranges.
- */
-
- .section "__mca_table", "a" // declare section & section attributes
- .previous
-
-# define MCA_RECOVER_RANGE(y) \
- .xdata4 "__mca_table", y-., 99f-.; \
- [99:]
-
-/*
- * Mark instructions that need a load of a virtual address patched to be
- * a load of a physical address. We use this either in critical performance
- * path (ivt.S - TLB miss processing) or in places where it might not be
- * safe to use a "tpa" instruction (mca_asm.S - error recovery).
- */
- .section ".data..patch.vtop", "a" // declare section & section attributes
- .previous
-
-#define LOAD_PHYSICAL(pr, reg, obj) \
-[1:](pr)movl reg = obj; \
- .xdata4 ".data..patch.vtop", 1b-.
-
-/*
- * For now, we always put in the McKinley E9 workaround. On CPUs that don't need it,
- * we'll patch out the work-around bundles with NOPs, so their impact is minimal.
- */
-#define DO_MCKINLEY_E9_WORKAROUND
-
-#ifdef DO_MCKINLEY_E9_WORKAROUND
- .section ".data..patch.mckinley_e9", "a"
- .previous
-/* workaround for Itanium 2 Errata 9: */
-# define FSYS_RETURN \
- .xdata4 ".data..patch.mckinley_e9", 1f-.; \
-1:{ .mib; \
- nop.m 0; \
- mov r16=ar.pfs; \
- br.call.sptk.many b7=2f;; \
- }; \
-2:{ .mib; \
- nop.m 0; \
- mov ar.pfs=r16; \
- br.ret.sptk.many b6;; \
- }
-#else
-# define FSYS_RETURN br.ret.sptk.many b6
-#endif
-
-/*
- * If physical stack register size is different from DEF_NUM_STACK_REG,
- * dynamically patch the kernel for correct size.
- */
- .section ".data..patch.phys_stack_reg", "a"
- .previous
-#define LOAD_PHYS_STACK_REG_SIZE(reg) \
-[1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \
- .xdata4 ".data..patch.phys_stack_reg", 1b-.
-
-/*
- * Up until early 2004, use of .align within a function caused bad unwind info.
- * TEXT_ALIGN(n) expands into ".align n" if a fixed GAS is available or into nothing
- * otherwise.
- */
-#ifdef HAVE_WORKING_TEXT_ALIGN
-# define TEXT_ALIGN(n) .align n
-#else
-# define TEXT_ALIGN(n)
-#endif
-
-#ifdef HAVE_SERIALIZE_DIRECTIVE
-# define dv_serialize_data .serialize.data
-# define dv_serialize_instruction .serialize.instruction
-#else
-# define dv_serialize_data
-# define dv_serialize_instruction
-#endif
-
-#endif /* _ASM_IA64_ASMMACRO_H */
diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
deleted file mode 100644
index 6540a628d257..000000000000
--- a/arch/ia64/include/asm/atomic.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_ATOMIC_H
-#define _ASM_IA64_ATOMIC_H
-
-/*
- * Atomic operations that C can't guarantee us. Useful for
- * resource counting etc..
- *
- * NOTE: don't mess with the types below! The "unsigned long" and
- * "int" types were carefully placed so as to ensure proper operation
- * of the macros.
- *
- * Copyright (C) 1998, 1999, 2002-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#include <linux/types.h>
-
-#include <asm/intrinsics.h>
-#include <asm/barrier.h>
-
-
-#define ATOMIC64_INIT(i) { (i) }
-
-#define arch_atomic_read(v) READ_ONCE((v)->counter)
-#define arch_atomic64_read(v) READ_ONCE((v)->counter)
-
-#define arch_atomic_set(v,i) WRITE_ONCE(((v)->counter), (i))
-#define arch_atomic64_set(v,i) WRITE_ONCE(((v)->counter), (i))
-
-#define ATOMIC_OP(op, c_op) \
-static __inline__ int \
-ia64_atomic_##op (int i, atomic_t *v) \
-{ \
- __s32 old, new; \
- CMPXCHG_BUGCHECK_DECL \
- \
- do { \
- CMPXCHG_BUGCHECK(v); \
- old = arch_atomic_read(v); \
- new = old c_op i; \
- } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); \
- return new; \
-}
-
-#define ATOMIC_FETCH_OP(op, c_op) \
-static __inline__ int \
-ia64_atomic_fetch_##op (int i, atomic_t *v) \
-{ \
- __s32 old, new; \
- CMPXCHG_BUGCHECK_DECL \
- \
- do { \
- CMPXCHG_BUGCHECK(v); \
- old = arch_atomic_read(v); \
- new = old c_op i; \
- } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); \
- return old; \
-}
-
-#define ATOMIC_OPS(op, c_op) \
- ATOMIC_OP(op, c_op) \
- ATOMIC_FETCH_OP(op, c_op)
-
-ATOMIC_OPS(add, +)
-ATOMIC_OPS(sub, -)
-
-#ifdef __OPTIMIZE__
-#define __ia64_atomic_const(i) \
- static const int __ia64_atomic_p = __builtin_constant_p(i) ? \
- ((i) == 1 || (i) == 4 || (i) == 8 || (i) == 16 || \
- (i) == -1 || (i) == -4 || (i) == -8 || (i) == -16) : 0;\
- __ia64_atomic_p
-#else
-#define __ia64_atomic_const(i) 0
-#endif
-
-#define arch_atomic_add_return(i,v) \
-({ \
- int __ia64_aar_i = (i); \
- __ia64_atomic_const(i) \
- ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \
- : ia64_atomic_add(__ia64_aar_i, v); \
-})
-
-#define arch_atomic_sub_return(i,v) \
-({ \
- int __ia64_asr_i = (i); \
- __ia64_atomic_const(i) \
- ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \
- : ia64_atomic_sub(__ia64_asr_i, v); \
-})
-
-#define arch_atomic_fetch_add(i,v) \
-({ \
- int __ia64_aar_i = (i); \
- __ia64_atomic_const(i) \
- ? ia64_fetchadd(__ia64_aar_i, &(v)->counter, acq) \
- : ia64_atomic_fetch_add(__ia64_aar_i, v); \
-})
-
-#define arch_atomic_fetch_sub(i,v) \
-({ \
- int __ia64_asr_i = (i); \
- __ia64_atomic_const(i) \
- ? ia64_fetchadd(-__ia64_asr_i, &(v)->counter, acq) \
- : ia64_atomic_fetch_sub(__ia64_asr_i, v); \
-})
-
-ATOMIC_FETCH_OP(and, &)
-ATOMIC_FETCH_OP(or, |)
-ATOMIC_FETCH_OP(xor, ^)
-
-#define arch_atomic_and(i,v) (void)ia64_atomic_fetch_and(i,v)
-#define arch_atomic_or(i,v) (void)ia64_atomic_fetch_or(i,v)
-#define arch_atomic_xor(i,v) (void)ia64_atomic_fetch_xor(i,v)
-
-#define arch_atomic_fetch_and(i,v) ia64_atomic_fetch_and(i,v)
-#define arch_atomic_fetch_or(i,v) ia64_atomic_fetch_or(i,v)
-#define arch_atomic_fetch_xor(i,v) ia64_atomic_fetch_xor(i,v)
-
-#undef ATOMIC_OPS
-#undef ATOMIC_FETCH_OP
-#undef ATOMIC_OP
-
-#define ATOMIC64_OP(op, c_op) \
-static __inline__ s64 \
-ia64_atomic64_##op (s64 i, atomic64_t *v) \
-{ \
- s64 old, new; \
- CMPXCHG_BUGCHECK_DECL \
- \
- do { \
- CMPXCHG_BUGCHECK(v); \
- old = arch_atomic64_read(v); \
- new = old c_op i; \
- } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old); \
- return new; \
-}
-
-#define ATOMIC64_FETCH_OP(op, c_op) \
-static __inline__ s64 \
-ia64_atomic64_fetch_##op (s64 i, atomic64_t *v) \
-{ \
- s64 old, new; \
- CMPXCHG_BUGCHECK_DECL \
- \
- do { \
- CMPXCHG_BUGCHECK(v); \
- old = arch_atomic64_read(v); \
- new = old c_op i; \
- } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old); \
- return old; \
-}
-
-#define ATOMIC64_OPS(op, c_op) \
- ATOMIC64_OP(op, c_op) \
- ATOMIC64_FETCH_OP(op, c_op)
-
-ATOMIC64_OPS(add, +)
-ATOMIC64_OPS(sub, -)
-
-#define arch_atomic64_add_return(i,v) \
-({ \
- s64 __ia64_aar_i = (i); \
- __ia64_atomic_const(i) \
- ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \
- : ia64_atomic64_add(__ia64_aar_i, v); \
-})
-
-#define arch_atomic64_sub_return(i,v) \
-({ \
- s64 __ia64_asr_i = (i); \
- __ia64_atomic_const(i) \
- ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \
- : ia64_atomic64_sub(__ia64_asr_i, v); \
-})
-
-#define arch_atomic64_fetch_add(i,v) \
-({ \
- s64 __ia64_aar_i = (i); \
- __ia64_atomic_const(i) \
- ? ia64_fetchadd(__ia64_aar_i, &(v)->counter, acq) \
- : ia64_atomic64_fetch_add(__ia64_aar_i, v); \
-})
-
-#define arch_atomic64_fetch_sub(i,v) \
-({ \
- s64 __ia64_asr_i = (i); \
- __ia64_atomic_const(i) \
- ? ia64_fetchadd(-__ia64_asr_i, &(v)->counter, acq) \
- : ia64_atomic64_fetch_sub(__ia64_asr_i, v); \
-})
-
-ATOMIC64_FETCH_OP(and, &)
-ATOMIC64_FETCH_OP(or, |)
-ATOMIC64_FETCH_OP(xor, ^)
-
-#define arch_atomic64_and(i,v) (void)ia64_atomic64_fetch_and(i,v)
-#define arch_atomic64_or(i,v) (void)ia64_atomic64_fetch_or(i,v)
-#define arch_atomic64_xor(i,v) (void)ia64_atomic64_fetch_xor(i,v)
-
-#define arch_atomic64_fetch_and(i,v) ia64_atomic64_fetch_and(i,v)
-#define arch_atomic64_fetch_or(i,v) ia64_atomic64_fetch_or(i,v)
-#define arch_atomic64_fetch_xor(i,v) ia64_atomic64_fetch_xor(i,v)
-
-#undef ATOMIC64_OPS
-#undef ATOMIC64_FETCH_OP
-#undef ATOMIC64_OP
-
-#define arch_atomic_add(i,v) (void)arch_atomic_add_return((i), (v))
-#define arch_atomic_sub(i,v) (void)arch_atomic_sub_return((i), (v))
-
-#define arch_atomic64_add(i,v) (void)arch_atomic64_add_return((i), (v))
-#define arch_atomic64_sub(i,v) (void)arch_atomic64_sub_return((i), (v))
-
-#endif /* _ASM_IA64_ATOMIC_H */
diff --git a/arch/ia64/include/asm/barrier.h b/arch/ia64/include/asm/barrier.h
deleted file mode 100644
index 751cdd353446..000000000000
--- a/arch/ia64/include/asm/barrier.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Memory barrier definitions. This is based on information published
- * in the Processor Abstraction Layer and the System Abstraction Layer
- * manual.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- */
-#ifndef _ASM_IA64_BARRIER_H
-#define _ASM_IA64_BARRIER_H
-
-#include <linux/compiler.h>
-
-/*
- * Macros to force memory ordering. In these descriptions, "previous"
- * and "subsequent" refer to program order; "visible" means that all
- * architecturally visible effects of a memory access have occurred
- * (at a minimum, this means the memory has been read or written).
- *
- * wmb(): Guarantees that all preceding stores to memory-
- * like regions are visible before any subsequent
- * stores and that all following stores will be
- * visible only after all previous stores.
- * rmb(): Like wmb(), but for reads.
- * mb(): wmb()/rmb() combo, i.e., all previous memory
- * accesses are visible before all subsequent
- * accesses and vice versa. This is also known as
- * a "fence."
- *
- * Note: "mb()" and its variants cannot be used as a fence to order
- * accesses to memory mapped I/O registers. For that, mf.a needs to
- * be used. However, we don't want to always use mf.a because (a)
- * it's (presumably) much slower than mf and (b) mf.a is supported for
- * sequential memory pages only.
- */
-#define mb() ia64_mf()
-#define rmb() mb()
-#define wmb() mb()
-
-#define dma_rmb() mb()
-#define dma_wmb() mb()
-
-# define __smp_mb() mb()
-
-#define __smp_mb__before_atomic() barrier()
-#define __smp_mb__after_atomic() barrier()
-
-/*
- * IA64 GCC turns volatile stores into st.rel and volatile loads into ld.acq no
- * need for asm trickery!
- */
-
-#define __smp_store_release(p, v) \
-do { \
- compiletime_assert_atomic_type(*p); \
- barrier(); \
- WRITE_ONCE(*p, v); \
-} while (0)
-
-#define __smp_load_acquire(p) \
-({ \
- typeof(*p) ___p1 = READ_ONCE(*p); \
- compiletime_assert_atomic_type(*p); \
- barrier(); \
- ___p1; \
-})
-
-/*
- * The group barrier in front of the rsm & ssm are necessary to ensure
- * that none of the previous instructions in the same group are
- * affected by the rsm/ssm.
- */
-
-#include <asm-generic/barrier.h>
-
-#endif /* _ASM_IA64_BARRIER_H */
diff --git a/arch/ia64/include/asm/bitops.h b/arch/ia64/include/asm/bitops.h
deleted file mode 100644
index 1accb7842f58..000000000000
--- a/arch/ia64/include/asm/bitops.h
+++ /dev/null
@@ -1,453 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_BITOPS_H
-#define _ASM_IA64_BITOPS_H
-
-/*
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 02/06/02 find_next_bit() and find_first_bit() added from Erich Focht's ia64
- * O(1) scheduler patch
- */
-
-#ifndef _LINUX_BITOPS_H
-#error only <linux/bitops.h> can be included directly
-#endif
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <asm/intrinsics.h>
-#include <asm/barrier.h>
-
-/**
- * set_bit - Atomically set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * This function is atomic and may not be reordered. See __set_bit()
- * if you do not require the atomic guarantees.
- * Note that @nr may be almost arbitrarily large; this function is not
- * restricted to acting on a single-word quantity.
- *
- * The address must be (at least) "long" aligned.
- * Note that there are driver (e.g., eepro100) which use these operations to
- * operate on hw-defined data-structures, so we can't easily change these
- * operations to force a bigger alignment.
- *
- * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
- */
-static __inline__ void
-set_bit (int nr, volatile void *addr)
-{
- __u32 bit, old, new;
- volatile __u32 *m;
- CMPXCHG_BUGCHECK_DECL
-
- m = (volatile __u32 *) addr + (nr >> 5);
- bit = 1 << (nr & 31);
- do {
- CMPXCHG_BUGCHECK(m);
- old = *m;
- new = old | bit;
- } while (cmpxchg_acq(m, old, new) != old);
-}
-
-/**
- * arch___set_bit - Set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * Unlike set_bit(), this function is non-atomic and may be reordered.
- * If it's called on the same region of memory simultaneously, the effect
- * may be that only one operation succeeds.
- */
-static __always_inline void
-arch___set_bit(unsigned long nr, volatile unsigned long *addr)
-{
- *((__u32 *) addr + (nr >> 5)) |= (1 << (nr & 31));
-}
-
-/**
- * clear_bit - Clears a bit in memory
- * @nr: Bit to clear
- * @addr: Address to start counting from
- *
- * clear_bit() is atomic and may not be reordered. However, it does
- * not contain a memory barrier, so if it is used for locking purposes,
- * you should call smp_mb__before_atomic() and/or smp_mb__after_atomic()
- * in order to ensure changes are visible on other processors.
- */
-static __inline__ void
-clear_bit (int nr, volatile void *addr)
-{
- __u32 mask, old, new;
- volatile __u32 *m;
- CMPXCHG_BUGCHECK_DECL
-
- m = (volatile __u32 *) addr + (nr >> 5);
- mask = ~(1 << (nr & 31));
- do {
- CMPXCHG_BUGCHECK(m);
- old = *m;
- new = old & mask;
- } while (cmpxchg_acq(m, old, new) != old);
-}
-
-/**
- * clear_bit_unlock - Clears a bit in memory with release
- * @nr: Bit to clear
- * @addr: Address to start counting from
- *
- * clear_bit_unlock() is atomic and may not be reordered. It does
- * contain a memory barrier suitable for unlock type operations.
- */
-static __inline__ void
-clear_bit_unlock (int nr, volatile void *addr)
-{
- __u32 mask, old, new;
- volatile __u32 *m;
- CMPXCHG_BUGCHECK_DECL
-
- m = (volatile __u32 *) addr + (nr >> 5);
- mask = ~(1 << (nr & 31));
- do {
- CMPXCHG_BUGCHECK(m);
- old = *m;
- new = old & mask;
- } while (cmpxchg_rel(m, old, new) != old);
-}
-
-/**
- * __clear_bit_unlock - Non-atomically clears a bit in memory with release
- * @nr: Bit to clear
- * @addr: Address to start counting from
- *
- * Similarly to clear_bit_unlock, the implementation uses a store
- * with release semantics. See also arch_spin_unlock().
- */
-static __inline__ void
-__clear_bit_unlock(int nr, void *addr)
-{
- __u32 * const m = (__u32 *) addr + (nr >> 5);
- __u32 const new = *m & ~(1 << (nr & 31));
-
- ia64_st4_rel_nta(m, new);
-}
-
-/**
- * arch___clear_bit - Clears a bit in memory (non-atomic version)
- * @nr: the bit to clear
- * @addr: the address to start counting from
- *
- * Unlike clear_bit(), this function is non-atomic and may be reordered.
- * If it's called on the same region of memory simultaneously, the effect
- * may be that only one operation succeeds.
- */
-static __always_inline void
-arch___clear_bit(unsigned long nr, volatile unsigned long *addr)
-{
- *((__u32 *) addr + (nr >> 5)) &= ~(1 << (nr & 31));
-}
-
-/**
- * change_bit - Toggle a bit in memory
- * @nr: Bit to toggle
- * @addr: Address to start counting from
- *
- * change_bit() is atomic and may not be reordered.
- * Note that @nr may be almost arbitrarily large; this function is not
- * restricted to acting on a single-word quantity.
- */
-static __inline__ void
-change_bit (int nr, volatile void *addr)
-{
- __u32 bit, old, new;
- volatile __u32 *m;
- CMPXCHG_BUGCHECK_DECL
-
- m = (volatile __u32 *) addr + (nr >> 5);
- bit = (1 << (nr & 31));
- do {
- CMPXCHG_BUGCHECK(m);
- old = *m;
- new = old ^ bit;
- } while (cmpxchg_acq(m, old, new) != old);
-}
-
-/**
- * arch___change_bit - Toggle a bit in memory
- * @nr: the bit to toggle
- * @addr: the address to start counting from
- *
- * Unlike change_bit(), this function is non-atomic and may be reordered.
- * If it's called on the same region of memory simultaneously, the effect
- * may be that only one operation succeeds.
- */
-static __always_inline void
-arch___change_bit(unsigned long nr, volatile unsigned long *addr)
-{
- *((__u32 *) addr + (nr >> 5)) ^= (1 << (nr & 31));
-}
-
-/**
- * test_and_set_bit - Set a bit and return its old value
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This operation is atomic and cannot be reordered.
- * It also implies the acquisition side of the memory barrier.
- */
-static __inline__ int
-test_and_set_bit (int nr, volatile void *addr)
-{
- __u32 bit, old, new;
- volatile __u32 *m;
- CMPXCHG_BUGCHECK_DECL
-
- m = (volatile __u32 *) addr + (nr >> 5);
- bit = 1 << (nr & 31);
- do {
- CMPXCHG_BUGCHECK(m);
- old = *m;
- new = old | bit;
- } while (cmpxchg_acq(m, old, new) != old);
- return (old & bit) != 0;
-}
-
-/**
- * test_and_set_bit_lock - Set a bit and return its old value for lock
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This is the same as test_and_set_bit on ia64
- */
-#define test_and_set_bit_lock test_and_set_bit
-
-/**
- * arch___test_and_set_bit - Set a bit and return its old value
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This operation is non-atomic and can be reordered.
- * If two examples of this operation race, one can appear to succeed
- * but actually fail. You must protect multiple accesses with a lock.
- */
-static __always_inline bool
-arch___test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
-{
- __u32 *p = (__u32 *) addr + (nr >> 5);
- __u32 m = 1 << (nr & 31);
- int oldbitset = (*p & m) != 0;
-
- *p |= m;
- return oldbitset;
-}
-
-/**
- * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- *
- * This operation is atomic and cannot be reordered.
- * It also implies the acquisition side of the memory barrier.
- */
-static __inline__ int
-test_and_clear_bit (int nr, volatile void *addr)
-{
- __u32 mask, old, new;
- volatile __u32 *m;
- CMPXCHG_BUGCHECK_DECL
-
- m = (volatile __u32 *) addr + (nr >> 5);
- mask = ~(1 << (nr & 31));
- do {
- CMPXCHG_BUGCHECK(m);
- old = *m;
- new = old & mask;
- } while (cmpxchg_acq(m, old, new) != old);
- return (old & ~mask) != 0;
-}
-
-/**
- * arch___test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- *
- * This operation is non-atomic and can be reordered.
- * If two examples of this operation race, one can appear to succeed
- * but actually fail. You must protect multiple accesses with a lock.
- */
-static __always_inline bool
-arch___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
-{
- __u32 *p = (__u32 *) addr + (nr >> 5);
- __u32 m = 1 << (nr & 31);
- int oldbitset = (*p & m) != 0;
-
- *p &= ~m;
- return oldbitset;
-}
-
-/**
- * test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to change
- * @addr: Address to count from
- *
- * This operation is atomic and cannot be reordered.
- * It also implies the acquisition side of the memory barrier.
- */
-static __inline__ int
-test_and_change_bit (int nr, volatile void *addr)
-{
- __u32 bit, old, new;
- volatile __u32 *m;
- CMPXCHG_BUGCHECK_DECL
-
- m = (volatile __u32 *) addr + (nr >> 5);
- bit = (1 << (nr & 31));
- do {
- CMPXCHG_BUGCHECK(m);
- old = *m;
- new = old ^ bit;
- } while (cmpxchg_acq(m, old, new) != old);
- return (old & bit) != 0;
-}
-
-/**
- * arch___test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to change
- * @addr: Address to count from
- *
- * This operation is non-atomic and can be reordered.
- */
-static __always_inline bool
-arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
-{
- __u32 old, bit = (1 << (nr & 31));
- __u32 *m = (__u32 *) addr + (nr >> 5);
-
- old = *m;
- *m = old ^ bit;
- return (old & bit) != 0;
-}
-
-#define arch_test_bit generic_test_bit
-#define arch_test_bit_acquire generic_test_bit_acquire
-
-/**
- * ffz - find the first zero bit in a long word
- * @x: The long word to find the bit in
- *
- * Returns the bit-number (0..63) of the first (least significant) zero bit.
- * Undefined if no zero exists, so code should check against ~0UL first...
- */
-static inline unsigned long
-ffz (unsigned long x)
-{
- unsigned long result;
-
- result = ia64_popcnt(x & (~x - 1));
- return result;
-}
-
-/**
- * __ffs - find first bit in word.
- * @x: The word to search
- *
- * Undefined if no bit exists, so code should check against 0 first.
- */
-static __inline__ unsigned long
-__ffs (unsigned long x)
-{
- unsigned long result;
-
- result = ia64_popcnt((x-1) & ~x);
- return result;
-}
-
-#ifdef __KERNEL__
-
-/*
- * Return bit number of last (most-significant) bit set. Undefined
- * for x==0. Bits are numbered from 0..63 (e.g., ia64_fls(9) == 3).
- */
-static inline unsigned long
-ia64_fls (unsigned long x)
-{
- long double d = x;
- long exp;
-
- exp = ia64_getf_exp(d);
- return exp - 0xffff;
-}
-
-/*
- * Find the last (most significant) bit set. Returns 0 for x==0 and
- * bits are numbered from 1..32 (e.g., fls(9) == 4).
- */
-static inline int fls(unsigned int t)
-{
- unsigned long x = t & 0xffffffffu;
-
- if (!x)
- return 0;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return ia64_popcnt(x);
-}
-
-/*
- * Find the last (most significant) bit set. Undefined for x==0.
- * Bits are numbered from 0..63 (e.g., __fls(9) == 3).
- */
-static inline unsigned long
-__fls (unsigned long x)
-{
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- x |= x >> 32;
- return ia64_popcnt(x) - 1;
-}
-
-#include <asm-generic/bitops/fls64.h>
-
-#include <asm-generic/bitops/builtin-ffs.h>
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-static __inline__ unsigned long __arch_hweight64(unsigned long x)
-{
- unsigned long result;
- result = ia64_popcnt(x);
- return result;
-}
-
-#define __arch_hweight32(x) ((unsigned int) __arch_hweight64((x) & 0xfffffffful))
-#define __arch_hweight16(x) ((unsigned int) __arch_hweight64((x) & 0xfffful))
-#define __arch_hweight8(x) ((unsigned int) __arch_hweight64((x) & 0xfful))
-
-#include <asm-generic/bitops/const_hweight.h>
-
-#endif /* __KERNEL__ */
-
-#ifdef __KERNEL__
-
-#include <asm-generic/bitops/non-instrumented-non-atomic.h>
-
-#include <asm-generic/bitops/le.h>
-
-#include <asm-generic/bitops/ext2-atomic-setbit.h>
-
-#include <asm-generic/bitops/sched.h>
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_IA64_BITOPS_H */
diff --git a/arch/ia64/include/asm/bug.h b/arch/ia64/include/asm/bug.h
deleted file mode 100644
index 66b37a532765..000000000000
--- a/arch/ia64/include/asm/bug.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_BUG_H
-#define _ASM_IA64_BUG_H
-
-#ifdef CONFIG_BUG
-#define ia64_abort() __builtin_trap()
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- barrier_before_unreachable(); \
- ia64_abort(); \
-} while (0)
-
-/* should this BUG be made generic? */
-#define HAVE_ARCH_BUG
-#endif
-
-#include <asm-generic/bug.h>
-
-#endif
diff --git a/arch/ia64/include/asm/cache.h b/arch/ia64/include/asm/cache.h
deleted file mode 100644
index 2f1c70647068..000000000000
--- a/arch/ia64/include/asm/cache.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_CACHE_H
-#define _ASM_IA64_CACHE_H
-
-
-/*
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-/* Bytes per L1 (data) cache line. */
-#define L1_CACHE_SHIFT CONFIG_IA64_L1_CACHE_SHIFT
-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
-
-#ifdef CONFIG_SMP
-# define SMP_CACHE_SHIFT L1_CACHE_SHIFT
-# define SMP_CACHE_BYTES L1_CACHE_BYTES
-#else
- /*
- * The "aligned" directive can only _increase_ alignment, so this is
- * safe and provides an easy way to avoid wasting space on a
- * uni-processor:
- */
-# define SMP_CACHE_SHIFT 3
-# define SMP_CACHE_BYTES (1 << 3)
-#endif
-
-#define __read_mostly __section(".data..read_mostly")
-
-#endif /* _ASM_IA64_CACHE_H */
diff --git a/arch/ia64/include/asm/cacheflush.h b/arch/ia64/include/asm/cacheflush.h
deleted file mode 100644
index eac493fa9e0d..000000000000
--- a/arch/ia64/include/asm/cacheflush.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_CACHEFLUSH_H
-#define _ASM_IA64_CACHEFLUSH_H
-
-/*
- * Copyright (C) 2002 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/page-flags.h>
-#include <linux/bitops.h>
-
-#include <asm/page.h>
-
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
-static inline void flush_dcache_folio(struct folio *folio)
-{
- clear_bit(PG_arch_1, &folio->flags);
-}
-#define flush_dcache_folio flush_dcache_folio
-
-static inline void flush_dcache_page(struct page *page)
-{
- flush_dcache_folio(page_folio(page));
-}
-
-extern void flush_icache_range(unsigned long start, unsigned long end);
-#define flush_icache_range flush_icache_range
-extern void clflush_cache_range(void *addr, int size);
-
-#define flush_icache_user_page(vma, page, user_addr, len) \
-do { \
- unsigned long _addr = (unsigned long) page_address(page) + ((user_addr) & ~PAGE_MASK); \
- flush_icache_range(_addr, _addr + (len)); \
-} while (0)
-
-#include <asm-generic/cacheflush.h>
-
-#endif /* _ASM_IA64_CACHEFLUSH_H */
diff --git a/arch/ia64/include/asm/checksum.h b/arch/ia64/include/asm/checksum.h
deleted file mode 100644
index f3026213aa32..000000000000
--- a/arch/ia64/include/asm/checksum.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_CHECKSUM_H
-#define _ASM_IA64_CHECKSUM_H
-
-/*
- * Modified 1998, 1999
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-/*
- * This is a version of ip_compute_csum() optimized for IP headers,
- * which always checksum on 4 octet boundaries.
- */
-extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
-
-/*
- * Computes the checksum of the TCP/UDP pseudo-header returns a 16-bit
- * checksum, already complemented
- */
-extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- __u32 len, __u8 proto, __wsum sum);
-
-extern __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- __u32 len, __u8 proto, __wsum sum);
-
-/*
- * Computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-extern __wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * This routine is used for miscellaneous IP-like checksums, mainly in
- * icmp.c
- */
-extern __sum16 ip_compute_csum(const void *buff, int len);
-
-/*
- * Fold a partial checksum without adding pseudo headers.
- */
-static inline __sum16 csum_fold(__wsum csum)
-{
- u32 sum = (__force u32)csum;
- sum = (sum & 0xffff) + (sum >> 16);
- sum = (sum & 0xffff) + (sum >> 16);
- return (__force __sum16)~sum;
-}
-
-#define _HAVE_ARCH_IPV6_CSUM 1
-struct in6_addr;
-extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
- const struct in6_addr *daddr,
- __u32 len, __u8 proto, __wsum csum);
-
-#endif /* _ASM_IA64_CHECKSUM_H */
diff --git a/arch/ia64/include/asm/clocksource.h b/arch/ia64/include/asm/clocksource.h
deleted file mode 100644
index 71a517751afa..000000000000
--- a/arch/ia64/include/asm/clocksource.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* IA64-specific clocksource additions */
-
-#ifndef _ASM_IA64_CLOCKSOURCE_H
-#define _ASM_IA64_CLOCKSOURCE_H
-
-struct arch_clocksource_data {
- void *fsys_mmio; /* used by fsyscall asm code */
-};
-
-#endif /* _ASM_IA64_CLOCKSOURCE_H */
diff --git a/arch/ia64/include/asm/cmpxchg.h b/arch/ia64/include/asm/cmpxchg.h
deleted file mode 100644
index d85ee1a0a227..000000000000
--- a/arch/ia64/include/asm/cmpxchg.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_CMPXCHG_H
-#define _ASM_IA64_CMPXCHG_H
-
-#include <uapi/asm/cmpxchg.h>
-
-#define arch_xchg(ptr, x) \
-({(__typeof__(*(ptr))) __arch_xchg((unsigned long) (x), (ptr), sizeof(*(ptr)));})
-
-#define arch_cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n))
-#define arch_cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n))
-
-#define arch_cmpxchg_local arch_cmpxchg
-#define arch_cmpxchg64_local arch_cmpxchg64
-
-#ifdef CONFIG_IA64_DEBUG_CMPXCHG
-# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128;
-# define CMPXCHG_BUGCHECK(v) \
-do { \
- if (_cmpxchg_bugcheck_count-- <= 0) { \
- void *ip; \
- extern int _printk(const char *fmt, ...); \
- ip = (void *) ia64_getreg(_IA64_REG_IP); \
- _printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));\
- break; \
- } \
-} while (0)
-#else /* !CONFIG_IA64_DEBUG_CMPXCHG */
-# define CMPXCHG_BUGCHECK_DECL
-# define CMPXCHG_BUGCHECK(v)
-#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
-
-#endif /* _ASM_IA64_CMPXCHG_H */
diff --git a/arch/ia64/include/asm/cpu.h b/arch/ia64/include/asm/cpu.h
deleted file mode 100644
index 642d71675ddb..000000000000
--- a/arch/ia64/include/asm/cpu.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_CPU_H_
-#define _ASM_IA64_CPU_H_
-
-#include <linux/device.h>
-#include <linux/cpu.h>
-#include <linux/topology.h>
-#include <linux/percpu.h>
-
-struct ia64_cpu {
- struct cpu cpu;
-};
-
-DECLARE_PER_CPU(struct ia64_cpu, cpu_devices);
-
-DECLARE_PER_CPU(int, cpu_state);
-
-#endif /* _ASM_IA64_CPU_H_ */
diff --git a/arch/ia64/include/asm/cputime.h b/arch/ia64/include/asm/cputime.h
deleted file mode 100644
index 7f28c3564d5d..000000000000
--- a/arch/ia64/include/asm/cputime.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Definitions for measuring cputime on ia64 machines.
- *
- * Based on <asm-powerpc/cputime.h>.
- *
- * Copyright (C) 2007 FUJITSU LIMITED
- * Copyright (C) 2007 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
- *
- * If we have CONFIG_VIRT_CPU_ACCOUNTING_NATIVE, we measure cpu time in nsec.
- * Otherwise we measure cpu time in jiffies using the generic definitions.
- */
-
-#ifndef __IA64_CPUTIME_H
-#define __IA64_CPUTIME_H
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-extern void arch_vtime_task_switch(struct task_struct *tsk);
-#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
-
-#endif /* __IA64_CPUTIME_H */
diff --git a/arch/ia64/include/asm/current.h b/arch/ia64/include/asm/current.h
deleted file mode 100644
index 86fbcc88dff2..000000000000
--- a/arch/ia64/include/asm/current.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_CURRENT_H
-#define _ASM_IA64_CURRENT_H
-
-/*
- * Modified 1998-2000
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-#include <asm/intrinsics.h>
-
-/*
- * In kernel mode, thread pointer (r13) is used to point to the current task
- * structure.
- */
-#define current ((struct task_struct *) ia64_getreg(_IA64_REG_TP))
-
-#endif /* _ASM_IA64_CURRENT_H */
diff --git a/arch/ia64/include/asm/cyclone.h b/arch/ia64/include/asm/cyclone.h
deleted file mode 100644
index a481393647e9..000000000000
--- a/arch/ia64/include/asm/cyclone.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef ASM_IA64_CYCLONE_H
-#define ASM_IA64_CYCLONE_H
-
-#ifdef CONFIG_IA64_CYCLONE
-extern int use_cyclone;
-extern void __init cyclone_setup(void);
-#else /* CONFIG_IA64_CYCLONE */
-#define use_cyclone 0
-static inline void cyclone_setup(void)
-{
- printk(KERN_ERR "Cyclone Counter: System not configured"
- " w/ CONFIG_IA64_CYCLONE.\n");
-}
-#endif /* CONFIG_IA64_CYCLONE */
-#endif /* !ASM_IA64_CYCLONE_H */
diff --git a/arch/ia64/include/asm/delay.h b/arch/ia64/include/asm/delay.h
deleted file mode 100644
index 0227ac586107..000000000000
--- a/arch/ia64/include/asm/delay.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_DELAY_H
-#define _ASM_IA64_DELAY_H
-
-/*
- * Delay routines using a pre-computed "cycles/usec" value.
- *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/compiler.h>
-
-#include <asm/intrinsics.h>
-#include <asm/processor.h>
-
-static __inline__ void
-ia64_set_itm (unsigned long val)
-{
- ia64_setreg(_IA64_REG_CR_ITM, val);
- ia64_srlz_d();
-}
-
-static __inline__ unsigned long
-ia64_get_itm (void)
-{
- unsigned long result;
-
- result = ia64_getreg(_IA64_REG_CR_ITM);
- ia64_srlz_d();
- return result;
-}
-
-static __inline__ void
-ia64_set_itv (unsigned long val)
-{
- ia64_setreg(_IA64_REG_CR_ITV, val);
- ia64_srlz_d();
-}
-
-static __inline__ unsigned long
-ia64_get_itv (void)
-{
- return ia64_getreg(_IA64_REG_CR_ITV);
-}
-
-static __inline__ void
-ia64_set_itc (unsigned long val)
-{
- ia64_setreg(_IA64_REG_AR_ITC, val);
- ia64_srlz_d();
-}
-
-static __inline__ unsigned long
-ia64_get_itc (void)
-{
- unsigned long result;
-
- result = ia64_getreg(_IA64_REG_AR_ITC);
- ia64_barrier();
-#ifdef CONFIG_ITANIUM
- while (unlikely((__s32) result == -1)) {
- result = ia64_getreg(_IA64_REG_AR_ITC);
- ia64_barrier();
- }
-#endif
- return result;
-}
-
-extern void ia64_delay_loop (unsigned long loops);
-
-static __inline__ void
-__delay (unsigned long loops)
-{
- if (unlikely(loops < 1))
- return;
-
- ia64_delay_loop (loops - 1);
-}
-
-extern void udelay (unsigned long usecs);
-
-#endif /* _ASM_IA64_DELAY_H */
diff --git a/arch/ia64/include/asm/device.h b/arch/ia64/include/asm/device.h
deleted file mode 100644
index 918b198cd5bb..000000000000
--- a/arch/ia64/include/asm/device.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Arch specific extensions to struct device
- */
-#ifndef _ASM_IA64_DEVICE_H
-#define _ASM_IA64_DEVICE_H
-
-struct dev_archdata {
-};
-
-struct pdev_archdata {
-};
-
-#endif /* _ASM_IA64_DEVICE_H */
diff --git a/arch/ia64/include/asm/div64.h b/arch/ia64/include/asm/div64.h
deleted file mode 100644
index 6cd978cefb28..000000000000
--- a/arch/ia64/include/asm/div64.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/div64.h>
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
deleted file mode 100644
index af6fa8e1597c..000000000000
--- a/arch/ia64/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_DMA_MAPPING_H
-#define _ASM_IA64_DMA_MAPPING_H
-
-/*
- * Copyright (C) 2003-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-extern const struct dma_map_ops *dma_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(void)
-{
- return dma_ops;
-}
-
-#endif /* _ASM_IA64_DMA_MAPPING_H */
diff --git a/arch/ia64/include/asm/dma.h b/arch/ia64/include/asm/dma.h
deleted file mode 100644
index eaed2626ffda..000000000000
--- a/arch/ia64/include/asm/dma.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_DMA_H
-#define _ASM_IA64_DMA_H
-
-/*
- * Copyright (C) 1998-2002 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-
-#include <asm/io.h> /* need byte IO */
-
-extern unsigned long MAX_DMA_ADDRESS;
-
-#define free_dma(x)
-
-#endif /* _ASM_IA64_DMA_H */
diff --git a/arch/ia64/include/asm/dmi.h b/arch/ia64/include/asm/dmi.h
deleted file mode 100644
index ecd9e0a0f5f9..000000000000
--- a/arch/ia64/include/asm/dmi.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_DMI_H
-#define _ASM_DMI_H 1
-
-#include <linux/slab.h>
-#include <asm/io.h>
-
-/* Use normal IO mappings for DMI */
-#define dmi_early_remap ioremap
-#define dmi_early_unmap(x, l) iounmap(x)
-#define dmi_remap ioremap
-#define dmi_unmap iounmap
-#define dmi_alloc(l) kzalloc(l, GFP_ATOMIC)
-
-#endif
diff --git a/arch/ia64/include/asm/early_ioremap.h b/arch/ia64/include/asm/early_ioremap.h
deleted file mode 100644
index 934191b1e2e3..000000000000
--- a/arch/ia64/include/asm/early_ioremap.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_EARLY_IOREMAP_H
-#define _ASM_IA64_EARLY_IOREMAP_H
-
-extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
-#define early_memremap(phys_addr, size) early_ioremap(phys_addr, size)
-
-extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
-#define early_memunmap(addr, size) early_iounmap(addr, size)
-
-#endif
diff --git a/arch/ia64/include/asm/efi.h b/arch/ia64/include/asm/efi.h
deleted file mode 100644
index 6a4a50d8f19a..000000000000
--- a/arch/ia64/include/asm/efi.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_EFI_H
-#define _ASM_EFI_H
-
-typedef int (*efi_freemem_callback_t) (u64 start, u64 end, void *arg);
-
-void *efi_get_pal_addr(void);
-void efi_map_pal_code(void);
-void efi_memmap_walk(efi_freemem_callback_t, void *);
-void efi_memmap_walk_uc(efi_freemem_callback_t, void *);
-void efi_gettimeofday(struct timespec64 *ts);
-
-#endif
diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
deleted file mode 100644
index 2ef5f9966ad1..000000000000
--- a/arch/ia64/include/asm/elf.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_ELF_H
-#define _ASM_IA64_ELF_H
-
-/*
- * ELF-specific definitions.
- *
- * Copyright (C) 1998-1999, 2002-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-
-#include <asm/fpu.h>
-#include <asm/page.h>
-#include <asm/auxvec.h>
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_IA_64)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS ELFCLASS64
-#define ELF_DATA ELFDATA2LSB
-#define ELF_ARCH EM_IA_64
-
-#define CORE_DUMP_USE_REGSET
-
-/* Least-significant four bits of ELF header's e_flags are OS-specific. The bits are
- interpreted as follows by Linux: */
-#define EF_IA_64_LINUX_EXECUTABLE_STACK 0x1 /* is stack (& heap) executable by default? */
-
-#define ELF_EXEC_PAGESIZE PAGE_SIZE
-
-/*
- * This is the location that an ET_DYN program is loaded if exec'ed.
- * Typical use of this is to invoke "./ld.so someprog" to test out a
- * new version of the loader. We need to make sure that it is out of
- * the way of the program that it will "exec", and that there is
- * sufficient room for the brk.
- */
-#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
-
-#define PT_IA_64_UNWIND 0x70000001
-
-/* IA-64 relocations: */
-#define R_IA64_NONE 0x00 /* none */
-#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
-#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
-#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
-#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
-#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
-#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
-#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
-#define R_IA64_GPREL22 0x2a /* @gprel(sym+add), add imm22 */
-#define R_IA64_GPREL64I 0x2b /* @gprel(sym+add), mov imm64 */
-#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym+add), data4 MSB */
-#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym+add), data4 LSB */
-#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym+add), data8 MSB */
-#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym+add), data8 LSB */
-#define R_IA64_LTOFF22 0x32 /* @ltoff(sym+add), add imm22 */
-#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym+add), mov imm64 */
-#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym+add), add imm22 */
-#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym+add), mov imm64 */
-#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym+add), data8 MSB */
-#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym+add), data8 LSB */
-#define R_IA64_FPTR64I 0x43 /* @fptr(sym+add), mov imm64 */
-#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym+add), data4 MSB */
-#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym+add), data4 LSB */
-#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym+add), data8 MSB */
-#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym+add), data8 LSB */
-#define R_IA64_PCREL60B 0x48 /* @pcrel(sym+add), brl */
-#define R_IA64_PCREL21B 0x49 /* @pcrel(sym+add), ptb, call */
-#define R_IA64_PCREL21M 0x4a /* @pcrel(sym+add), chk.s */
-#define R_IA64_PCREL21F 0x4b /* @pcrel(sym+add), fchkf */
-#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym+add), data4 MSB */
-#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym+add), data4 LSB */
-#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym+add), data8 MSB */
-#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym+add), data8 LSB */
-#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
-#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
-#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), 4 MSB */
-#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), 4 LSB */
-#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), 8 MSB */
-#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), 8 LSB */
-#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym+add), data4 MSB */
-#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym+add), data4 LSB */
-#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym+add), data8 MSB */
-#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym+add), data8 LSB */
-#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym+add), data4 MSB */
-#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym+add), data4 LSB */
-#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym+add), data8 MSB */
-#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym+add), data8 LSB */
-#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
-#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
-#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
-#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
-#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */
-#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */
-#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */
-#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */
-#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym+add), ptb, call */
-#define R_IA64_PCREL22 0x7a /* @pcrel(sym+add), imm22 */
-#define R_IA64_PCREL64I 0x7b /* @pcrel(sym+add), imm64 */
-#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
-#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
-#define R_IA64_COPY 0x84 /* dynamic reloc, data copy */
-#define R_IA64_SUB 0x85 /* -symbol + addend, add imm22 */
-#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
-#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
-#define R_IA64_TPREL14 0x91 /* @tprel(sym+add), add imm14 */
-#define R_IA64_TPREL22 0x92 /* @tprel(sym+add), add imm22 */
-#define R_IA64_TPREL64I 0x93 /* @tprel(sym+add), add imm64 */
-#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym+add), data8 MSB */
-#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym+add), data8 LSB */
-#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), add imm22 */
-#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym+add), data8 MSB */
-#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym+add), data8 LSB */
-#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(s+a)), imm22 */
-#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym+add), imm14 */
-#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym+add), imm22 */
-#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym+add), imm64 */
-#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym+add), data4 MSB */
-#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym+add), data4 LSB */
-#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym+add), data8 MSB */
-#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym+add), data8 LSB */
-#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */
-
-/* IA-64 specific section flags: */
-#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
-
-/*
- * We use (abuse?) this macro to insert the (empty) vm_area that is
- * used to map the register backing store. I don't see any better
- * place to do this, but we should discuss this with Linus once we can
- * talk to him...
- */
-extern void ia64_init_addr_space (void);
-#define ELF_PLAT_INIT(_r, load_addr) ia64_init_addr_space()
-
-/* ELF register definitions. This is needed for core dump support. */
-
-/*
- * elf_gregset_t contains the application-level state in the following order:
- * r0-r31
- * NaT bits (for r0-r31; bit N == 1 iff rN is a NaT)
- * predicate registers (p0-p63)
- * b0-b7
- * ip cfm psr
- * ar.rsc ar.bsp ar.bspstore ar.rnat
- * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
- */
-#define ELF_NGREG 128 /* we really need just 72 but let's leave some headroom... */
-#define ELF_NFPREG 128 /* f0 and f1 could be omitted, but so what... */
-
-/* elf_gregset_t register offsets */
-#define ELF_GR_0_OFFSET 0
-#define ELF_NAT_OFFSET (32 * sizeof(elf_greg_t))
-#define ELF_PR_OFFSET (33 * sizeof(elf_greg_t))
-#define ELF_BR_0_OFFSET (34 * sizeof(elf_greg_t))
-#define ELF_CR_IIP_OFFSET (42 * sizeof(elf_greg_t))
-#define ELF_CFM_OFFSET (43 * sizeof(elf_greg_t))
-#define ELF_CR_IPSR_OFFSET (44 * sizeof(elf_greg_t))
-#define ELF_GR_OFFSET(i) (ELF_GR_0_OFFSET + i * sizeof(elf_greg_t))
-#define ELF_BR_OFFSET(i) (ELF_BR_0_OFFSET + i * sizeof(elf_greg_t))
-#define ELF_AR_RSC_OFFSET (45 * sizeof(elf_greg_t))
-#define ELF_AR_BSP_OFFSET (46 * sizeof(elf_greg_t))
-#define ELF_AR_BSPSTORE_OFFSET (47 * sizeof(elf_greg_t))
-#define ELF_AR_RNAT_OFFSET (48 * sizeof(elf_greg_t))
-#define ELF_AR_CCV_OFFSET (49 * sizeof(elf_greg_t))
-#define ELF_AR_UNAT_OFFSET (50 * sizeof(elf_greg_t))
-#define ELF_AR_FPSR_OFFSET (51 * sizeof(elf_greg_t))
-#define ELF_AR_PFS_OFFSET (52 * sizeof(elf_greg_t))
-#define ELF_AR_LC_OFFSET (53 * sizeof(elf_greg_t))
-#define ELF_AR_EC_OFFSET (54 * sizeof(elf_greg_t))
-#define ELF_AR_CSD_OFFSET (55 * sizeof(elf_greg_t))
-#define ELF_AR_SSD_OFFSET (56 * sizeof(elf_greg_t))
-#define ELF_AR_END_OFFSET (57 * sizeof(elf_greg_t))
-
-typedef unsigned long elf_greg_t;
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct ia64_fpreg elf_fpreg_t;
-typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-
-
-
-struct pt_regs; /* forward declaration... */
-extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
-#define ELF_CORE_COPY_REGS(_dest,_regs) ia64_elf_core_copy_regs(_regs, _dest);
-
-/* This macro yields a bitmask that programs can use to figure out
- what instruction set this CPU supports. */
-#define ELF_HWCAP 0
-
-/* This macro yields a string that ld.so will use to load
- implementation specific libraries for optimization. Not terribly
- relevant until we have real hardware to play with... */
-#define ELF_PLATFORM NULL
-
-#define elf_read_implies_exec(ex, executable_stack) \
- ((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
-
-struct task_struct;
-
-#define GATE_EHDR ((const struct elfhdr *) GATE_ADDR)
-
-/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
-#define ARCH_DLINFO \
-do { \
- extern char __kernel_syscall_via_epc[]; \
- NEW_AUX_ENT(AT_SYSINFO, (unsigned long) __kernel_syscall_via_epc); \
- NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \
-} while (0)
-
-/*
- * format for entries in the Global Offset Table
- */
-struct got_entry {
- uint64_t val;
-};
-
-/*
- * Layout of the Function Descriptor
- */
-struct fdesc {
- uint64_t addr;
- uint64_t gp;
-};
-
-#endif /* _ASM_IA64_ELF_H */
diff --git a/arch/ia64/include/asm/emergency-restart.h b/arch/ia64/include/asm/emergency-restart.h
deleted file mode 100644
index 108d8c48e42e..000000000000
--- a/arch/ia64/include/asm/emergency-restart.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_EMERGENCY_RESTART_H
-#define _ASM_EMERGENCY_RESTART_H
-
-#include <asm-generic/emergency-restart.h>
-
-#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/arch/ia64/include/asm/esi.h b/arch/ia64/include/asm/esi.h
deleted file mode 100644
index 56d1310af06e..000000000000
--- a/arch/ia64/include/asm/esi.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * ESI service calls.
- *
- * Copyright (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P.
- * Alex Williamson <alex.williamson@hp.com>
- */
-#ifndef esi_h
-#define esi_h
-
-#include <linux/efi.h>
-
-#define ESI_QUERY 0x00000001
-#define ESI_OPEN_HANDLE 0x02000000
-#define ESI_CLOSE_HANDLE 0x02000001
-
-enum esi_proc_type {
- ESI_PROC_SERIALIZED, /* calls need to be serialized */
- ESI_PROC_MP_SAFE, /* MP-safe, but not reentrant */
- ESI_PROC_REENTRANT /* MP-safe and reentrant */
-};
-
-extern struct ia64_sal_retval esi_call_phys (void *, u64 *);
-extern int ia64_esi_call(efi_guid_t, struct ia64_sal_retval *,
- enum esi_proc_type,
- u64, u64, u64, u64, u64, u64, u64, u64);
-extern int ia64_esi_call_phys(efi_guid_t, struct ia64_sal_retval *, u64, u64,
- u64, u64, u64, u64, u64, u64);
-
-#endif /* esi_h */
diff --git a/arch/ia64/include/asm/exception.h b/arch/ia64/include/asm/exception.h
deleted file mode 100644
index 1d5df8116a31..000000000000
--- a/arch/ia64/include/asm/exception.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-#ifndef __ASM_EXCEPTION_H
-#define __ASM_EXCEPTION_H
-
-struct pt_regs;
-struct exception_table_entry;
-
-extern void ia64_handle_exception(struct pt_regs *regs,
- const struct exception_table_entry *e);
-
-#define ia64_done_with_exception(regs) \
-({ \
- int __ex_ret = 0; \
- const struct exception_table_entry *e; \
- e = search_exception_tables((regs)->cr_iip + ia64_psr(regs)->ri); \
- if (e) { \
- ia64_handle_exception(regs, e); \
- __ex_ret = 1; \
- } \
- __ex_ret; \
-})
-
-#endif /* __ASM_EXCEPTION_H */
diff --git a/arch/ia64/include/asm/extable.h b/arch/ia64/include/asm/extable.h
deleted file mode 100644
index 83eac6aa0639..000000000000
--- a/arch/ia64/include/asm/extable.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_EXTABLE_H
-#define _ASM_IA64_EXTABLE_H
-
-#define ARCH_HAS_RELATIVE_EXTABLE
-
-struct exception_table_entry {
- int insn; /* location-relative address of insn this fixup is for */
- int fixup; /* location-relative continuation addr.; if bit 2 is set, r9 is set to 0 */
-};
-
-#endif
diff --git a/arch/ia64/include/asm/fb.h b/arch/ia64/include/asm/fb.h
deleted file mode 100644
index 7fce0d542359..000000000000
--- a/arch/ia64/include/asm/fb.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <linux/compiler.h>
-#include <linux/efi.h>
-#include <linux/string.h>
-
-#include <asm/page.h>
-
-static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
- unsigned long vm_start, unsigned long vm_end,
- unsigned long offset)
-{
- if (efi_range_is_wc(vm_start, vm_end - vm_start))
- return pgprot_writecombine(prot);
- else
- return pgprot_noncached(prot);
-}
-#define pgprot_framebuffer pgprot_framebuffer
-
-static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
-{
- memcpy(to, (void __force *)from, n);
-}
-#define fb_memcpy_fromio fb_memcpy_fromio
-
-static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
-{
- memcpy((void __force *)to, from, n);
-}
-#define fb_memcpy_toio fb_memcpy_toio
-
-static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
-{
- memset((void __force *)addr, c, n);
-}
-#define fb_memset fb_memset_io
-
-#include <asm-generic/fb.h>
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/ia64/include/asm/fpswa.h b/arch/ia64/include/asm/fpswa.h
deleted file mode 100644
index 2a0c23728b26..000000000000
--- a/arch/ia64/include/asm/fpswa.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_FPSWA_H
-#define _ASM_IA64_FPSWA_H
-
-/*
- * Floating-point Software Assist
- *
- * Copyright (C) 1999 Intel Corporation.
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Goutham Rao <goutham.rao@intel.com>
- */
-
-typedef struct {
- /* 4 * 128 bits */
- unsigned long fp_lp[4*2];
-} fp_state_low_preserved_t;
-
-typedef struct {
- /* 10 * 128 bits */
- unsigned long fp_lv[10 * 2];
-} fp_state_low_volatile_t;
-
-typedef struct {
- /* 16 * 128 bits */
- unsigned long fp_hp[16 * 2];
-} fp_state_high_preserved_t;
-
-typedef struct {
- /* 96 * 128 bits */
- unsigned long fp_hv[96 * 2];
-} fp_state_high_volatile_t;
-
-/**
- * floating point state to be passed to the FP emulation library by
- * the trap/fault handler
- */
-typedef struct {
- unsigned long bitmask_low64;
- unsigned long bitmask_high64;
- fp_state_low_preserved_t *fp_state_low_preserved;
- fp_state_low_volatile_t *fp_state_low_volatile;
- fp_state_high_preserved_t *fp_state_high_preserved;
- fp_state_high_volatile_t *fp_state_high_volatile;
-} fp_state_t;
-
-typedef struct {
- unsigned long status;
- unsigned long err0;
- unsigned long err1;
- unsigned long err2;
-} fpswa_ret_t;
-
-/**
- * function header for the Floating Point software assist
- * library. This function is invoked by the Floating point software
- * assist trap/fault handler.
- */
-typedef fpswa_ret_t (*efi_fpswa_t) (unsigned long trap_type, void *bundle, unsigned long *ipsr,
- unsigned long *fsr, unsigned long *isr, unsigned long *preds,
- unsigned long *ifs, fp_state_t *fp_state);
-
-/**
- * This is the FPSWA library interface as defined by EFI. We need to pass a
- * pointer to the interface itself on a call to the assist library
- */
-typedef struct {
- unsigned int revision;
- unsigned int reserved;
- efi_fpswa_t fpswa;
-} fpswa_interface_t;
-
-extern fpswa_interface_t *fpswa_interface;
-
-#endif /* _ASM_IA64_FPSWA_H */
diff --git a/arch/ia64/include/asm/ftrace.h b/arch/ia64/include/asm/ftrace.h
deleted file mode 100644
index a07a8e575453..000000000000
--- a/arch/ia64/include/asm/ftrace.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_FTRACE_H
-#define _ASM_IA64_FTRACE_H
-
-#ifdef CONFIG_FUNCTION_TRACER
-#define MCOUNT_INSN_SIZE 32 /* sizeof mcount call */
-
-#ifndef __ASSEMBLY__
-extern void _mcount(unsigned long pfs, unsigned long r1, unsigned long b0, unsigned long r0);
-#define mcount _mcount
-
-/* In IA64, MCOUNT_ADDR is set in link time, so it's not a constant at compile time */
-#define MCOUNT_ADDR (((struct fnptr *)mcount)->ip)
-#define FTRACE_ADDR (((struct fnptr *)ftrace_caller)->ip)
-
-static inline unsigned long ftrace_call_adjust(unsigned long addr)
-{
- /* second bundle, insn 2 */
- return addr - 0x12;
-}
-
-struct dyn_arch_ftrace {
-};
-#endif
-
-#endif /* CONFIG_FUNCTION_TRACER */
-
-#endif /* _ASM_IA64_FTRACE_H */
diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h
deleted file mode 100644
index 1db26b432d8c..000000000000
--- a/arch/ia64/include/asm/futex.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
-
-#include <linux/futex.h>
-#include <linux/uaccess.h>
-#include <asm/errno.h>
-
-#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
-do { \
- register unsigned long r8 __asm ("r8") = 0; \
- __asm__ __volatile__( \
- " mf;; \n" \
- "[1:] " insn ";; \n" \
- " .xdata4 \"__ex_table\", 1b-., 2f-. \n" \
- "[2:]" \
- : "+r" (r8), "=r" (oldval) \
- : "r" (uaddr), "r" (oparg) \
- : "memory"); \
- ret = r8; \
-} while (0)
-
-#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
-do { \
- register unsigned long r8 __asm ("r8") = 0; \
- int val, newval; \
- do { \
- __asm__ __volatile__( \
- " mf;; \n" \
- "[1:] ld4 %3=[%4];; \n" \
- " mov %2=%3 \n" \
- insn ";; \n" \
- " mov ar.ccv=%2;; \n" \
- "[2:] cmpxchg4.acq %1=[%4],%3,ar.ccv;; \n" \
- " .xdata4 \"__ex_table\", 1b-., 3f-.\n" \
- " .xdata4 \"__ex_table\", 2b-., 3f-.\n" \
- "[3:]" \
- : "+r" (r8), "=r" (val), "=&r" (oldval), \
- "=&r" (newval) \
- : "r" (uaddr), "r" (oparg) \
- : "memory"); \
- if (unlikely (r8)) \
- break; \
- } while (unlikely (val != oldval)); \
- ret = r8; \
-} while (0)
-
-static inline int
-arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
-{
- int oldval = 0, ret;
-
- if (!access_ok(uaddr, sizeof(u32)))
- return -EFAULT;
-
- switch (op) {
- case FUTEX_OP_SET:
- __futex_atomic_op1("xchg4 %1=[%2],%3", ret, oldval, uaddr,
- oparg);
- break;
- case FUTEX_OP_ADD:
- __futex_atomic_op2("add %3=%3,%5", ret, oldval, uaddr, oparg);
- break;
- case FUTEX_OP_OR:
- __futex_atomic_op2("or %3=%3,%5", ret, oldval, uaddr, oparg);
- break;
- case FUTEX_OP_ANDN:
- __futex_atomic_op2("and %3=%3,%5", ret, oldval, uaddr,
- ~oparg);
- break;
- case FUTEX_OP_XOR:
- __futex_atomic_op2("xor %3=%3,%5", ret, oldval, uaddr, oparg);
- break;
- default:
- ret = -ENOSYS;
- }
-
- if (!ret)
- *oval = oldval;
-
- return ret;
-}
-
-static inline int
-futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
- u32 oldval, u32 newval)
-{
- if (!access_ok(uaddr, sizeof(u32)))
- return -EFAULT;
-
- {
- register unsigned long r8 __asm ("r8") = 0;
- unsigned long prev;
- __asm__ __volatile__(
- " mf;; \n"
- " mov ar.ccv=%4;; \n"
- "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n"
- " .xdata4 \"__ex_table\", 1b-., 2f-. \n"
- "[2:]"
- : "+r" (r8), "=&r" (prev)
- : "r" (uaddr), "r" (newval),
- "rO" ((long) (unsigned) oldval)
- : "memory");
- *uval = prev;
- return r8;
- }
-}
-
-#endif /* _ASM_FUTEX_H */
diff --git a/arch/ia64/include/asm/gcc_intrin.h b/arch/ia64/include/asm/gcc_intrin.h
deleted file mode 100644
index 83f230b23867..000000000000
--- a/arch/ia64/include/asm/gcc_intrin.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *
- * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
- * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
- */
-#ifndef _ASM_IA64_GCC_INTRIN_H
-#define _ASM_IA64_GCC_INTRIN_H
-
-#include <uapi/asm/gcc_intrin.h>
-
-register unsigned long ia64_r13 asm ("r13") __used;
-#endif /* _ASM_IA64_GCC_INTRIN_H */
diff --git a/arch/ia64/include/asm/hardirq.h b/arch/ia64/include/asm/hardirq.h
deleted file mode 100644
index ccde7c2ba00f..000000000000
--- a/arch/ia64/include/asm/hardirq.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_HARDIRQ_H
-#define _ASM_IA64_HARDIRQ_H
-
-/*
- * Modified 1998-2002, 2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-/*
- * No irq_cpustat_t for IA-64. The data is held in the per-CPU data structure.
- */
-
-#define __ARCH_IRQ_STAT 1
-
-#define local_softirq_pending_ref ia64_cpu_info.softirq_pending
-
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-#include <asm/processor.h>
-
-extern void __iomem *ipi_base_addr;
-
-void ack_bad_irq(unsigned int irq);
-
-#endif /* _ASM_IA64_HARDIRQ_H */
diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h
deleted file mode 100644
index 026ead47cd53..000000000000
--- a/arch/ia64/include/asm/hugetlb.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_HUGETLB_H
-#define _ASM_IA64_HUGETLB_H
-
-#include <asm/page.h>
-
-#define __HAVE_ARCH_HUGETLB_FREE_PGD_RANGE
-void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
- unsigned long end, unsigned long floor,
- unsigned long ceiling);
-
-#define __HAVE_ARCH_PREPARE_HUGEPAGE_RANGE
-int prepare_hugepage_range(struct file *file,
- unsigned long addr, unsigned long len);
-
-static inline int is_hugepage_only_range(struct mm_struct *mm,
- unsigned long addr,
- unsigned long len)
-{
- return (REGION_NUMBER(addr) == RGN_HPAGE ||
- REGION_NUMBER((addr)+(len)-1) == RGN_HPAGE);
-}
-#define is_hugepage_only_range is_hugepage_only_range
-
-#define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH
-static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
- unsigned long addr, pte_t *ptep)
-{
- return *ptep;
-}
-
-#include <asm-generic/hugetlb.h>
-
-#endif /* _ASM_IA64_HUGETLB_H */
diff --git a/arch/ia64/include/asm/hw_irq.h b/arch/ia64/include/asm/hw_irq.h
deleted file mode 100644
index 5d267132f8cb..000000000000
--- a/arch/ia64/include/asm/hw_irq.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_HW_IRQ_H
-#define _ASM_IA64_HW_IRQ_H
-
-/*
- * Copyright (C) 2001-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/profile.h>
-
-#include <asm/ptrace.h>
-#include <asm/smp.h>
-
-typedef u8 ia64_vector;
-
-/*
- * 0 special
- *
- * 1,3-14 are reserved from firmware
- *
- * 16-255 (vectored external interrupts) are available
- *
- * 15 spurious interrupt (see IVR)
- *
- * 16 lowest priority, 255 highest priority
- *
- * 15 classes of 16 interrupts each.
- */
-#define IA64_MIN_VECTORED_IRQ 16
-#define IA64_MAX_VECTORED_IRQ 255
-#define IA64_NUM_VECTORS 256
-
-#define AUTO_ASSIGN -1
-
-#define IA64_SPURIOUS_INT_VECTOR 0x0f
-
-/*
- * Vectors 0x10-0x1f are used for low priority interrupts, e.g. CMCI.
- */
-#define IA64_CPEP_VECTOR 0x1c /* corrected platform error polling vector */
-#define IA64_CMCP_VECTOR 0x1d /* corrected machine-check polling vector */
-#define IA64_CPE_VECTOR 0x1e /* corrected platform error interrupt vector */
-#define IA64_CMC_VECTOR 0x1f /* corrected machine-check interrupt vector */
-/*
- * Vectors 0x20-0x2f are reserved for legacy ISA IRQs.
- * Use vectors 0x30-0xe7 as the default device vector range for ia64.
- * Platforms may choose to reduce this range in platform_irq_setup, but the
- * platform range must fall within
- * [IA64_DEF_FIRST_DEVICE_VECTOR..IA64_DEF_LAST_DEVICE_VECTOR]
- */
-extern int ia64_first_device_vector;
-extern int ia64_last_device_vector;
-
-#ifdef CONFIG_SMP
-/* Reserve the lower priority vector than device vectors for "move IRQ" IPI */
-#define IA64_IRQ_MOVE_VECTOR 0x30 /* "move IRQ" IPI */
-#define IA64_DEF_FIRST_DEVICE_VECTOR 0x31
-#else
-#define IA64_DEF_FIRST_DEVICE_VECTOR 0x30
-#endif
-#define IA64_DEF_LAST_DEVICE_VECTOR 0xe7
-#define IA64_FIRST_DEVICE_VECTOR ia64_first_device_vector
-#define IA64_LAST_DEVICE_VECTOR ia64_last_device_vector
-#define IA64_MAX_DEVICE_VECTORS (IA64_DEF_LAST_DEVICE_VECTOR - IA64_DEF_FIRST_DEVICE_VECTOR + 1)
-#define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1)
-
-#define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */
-#define IA64_TIMER_VECTOR 0xef /* use highest-prio group 15 interrupt for timer */
-#define IA64_MCA_WAKEUP_VECTOR 0xf0 /* MCA wakeup (must be >MCA_RENDEZ_VECTOR) */
-#define IA64_IPI_LOCAL_TLB_FLUSH 0xfc /* SMP flush local TLB */
-#define IA64_IPI_RESCHEDULE 0xfd /* SMP reschedule */
-#define IA64_IPI_VECTOR 0xfe /* inter-processor interrupt vector */
-
-/* Used for encoding redirected irqs */
-
-#define IA64_IRQ_REDIRECTED (1 << 31)
-
-/* IA64 inter-cpu interrupt related definitions */
-
-#define IA64_IPI_DEFAULT_BASE_ADDR 0xfee00000
-
-/* Delivery modes for inter-cpu interrupts */
-enum {
- IA64_IPI_DM_INT = 0x0, /* pend an external interrupt */
- IA64_IPI_DM_PMI = 0x2, /* pend a PMI */
- IA64_IPI_DM_NMI = 0x4, /* pend an NMI (vector 2) */
- IA64_IPI_DM_INIT = 0x5, /* pend an INIT interrupt */
- IA64_IPI_DM_EXTINT = 0x7, /* pend an 8259-compatible interrupt. */
-};
-
-extern __u8 isa_irq_to_vector_map[16];
-#define isa_irq_to_vector(x) isa_irq_to_vector_map[(x)]
-
-struct irq_cfg {
- ia64_vector vector;
- cpumask_t domain;
- cpumask_t old_domain;
- unsigned move_cleanup_count;
- u8 move_in_progress : 1;
-};
-extern spinlock_t vector_lock;
-extern struct irq_cfg irq_cfg[NR_IRQS];
-#define irq_to_domain(x) irq_cfg[(x)].domain
-DECLARE_PER_CPU(int[IA64_NUM_VECTORS], vector_irq);
-
-extern struct irq_chip irq_type_ia64_lsapic; /* CPU-internal interrupt controller */
-
-#define ia64_register_ipi ia64_native_register_ipi
-#define assign_irq_vector ia64_native_assign_irq_vector
-#define free_irq_vector ia64_native_free_irq_vector
-#define ia64_resend_irq ia64_native_resend_irq
-
-extern void ia64_native_register_ipi(void);
-extern int bind_irq_vector(int irq, int vector, cpumask_t domain);
-extern int ia64_native_assign_irq_vector (int irq); /* allocate a free vector */
-extern void ia64_native_free_irq_vector (int vector);
-extern int reserve_irq_vector (int vector);
-extern void __setup_vector_irq(int cpu);
-extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
-extern void destroy_and_reserve_irq (unsigned int irq);
-
-#ifdef CONFIG_SMP
-extern int irq_prepare_move(int irq, int cpu);
-extern void irq_complete_move(unsigned int irq);
-#else
-static inline int irq_prepare_move(int irq, int cpu) { return 0; }
-static inline void irq_complete_move(unsigned int irq) {}
-#endif
-
-static inline void ia64_native_resend_irq(unsigned int vector)
-{
- ia64_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
-}
-
-/*
- * Next follows the irq descriptor interface. On IA-64, each CPU supports 256 interrupt
- * vectors. On smaller systems, there is a one-to-one correspondence between interrupt
- * vectors and the Linux irq numbers. However, larger systems may have multiple interrupt
- * domains meaning that the translation from vector number to irq number depends on the
- * interrupt domain that a CPU belongs to. This API abstracts such platform-dependent
- * differences and provides a uniform means to translate between vector and irq numbers
- * and to obtain the irq descriptor for a given irq number.
- */
-
-/* Extract the IA-64 vector that corresponds to IRQ. */
-static inline ia64_vector
-irq_to_vector (int irq)
-{
- return irq_cfg[irq].vector;
-}
-
-/*
- * Convert the local IA-64 vector to the corresponding irq number. This translation is
- * done in the context of the interrupt domain that the currently executing CPU belongs
- * to.
- */
-static inline unsigned int
-local_vector_to_irq (ia64_vector vec)
-{
- return __this_cpu_read(vector_irq[vec]);
-}
-
-#endif /* _ASM_IA64_HW_IRQ_H */
diff --git a/arch/ia64/include/asm/idle.h b/arch/ia64/include/asm/idle.h
deleted file mode 100644
index 97c55b97e0ba..000000000000
--- a/arch/ia64/include/asm/idle.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_IDLE_H
-#define _ASM_IA64_IDLE_H
-
-static inline void enter_idle(void) { }
-static inline void exit_idle(void) { }
-
-#endif /* _ASM_IA64_IDLE_H */
diff --git a/arch/ia64/include/asm/intrinsics.h b/arch/ia64/include/asm/intrinsics.h
deleted file mode 100644
index 035b17fe12ef..000000000000
--- a/arch/ia64/include/asm/intrinsics.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Compiler-dependent intrinsics.
- *
- * Copyright (C) 2002-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#ifndef _ASM_IA64_INTRINSICS_H
-#define _ASM_IA64_INTRINSICS_H
-
-#include <uapi/asm/intrinsics.h>
-
-#endif /* _ASM_IA64_INTRINSICS_H */
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
deleted file mode 100644
index eedc0afa8cad..000000000000
--- a/arch/ia64/include/asm/io.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_IO_H
-#define _ASM_IA64_IO_H
-
-/*
- * This file contains the definitions for the emulated IO instructions
- * inb/inw/inl/outb/outw/outl and the "string versions" of the same
- * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
- * versions of the single-IO instructions (inb_p/inw_p/..).
- *
- * This file is not meant to be obfuscating: it's just complicated to
- * (a) handle it all in a way that makes gcc able to optimize it as
- * well as possible and (b) trying to avoid writing the same thing
- * over and over again with slight variations and possibly making a
- * mistake somewhere.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- */
-
-#include <asm/unaligned.h>
-#include <asm/early_ioremap.h>
-
-#define __IA64_UNCACHED_OFFSET RGN_BASE(RGN_UNCACHED)
-
-/*
- * The legacy I/O space defined by the ia64 architecture supports only 65536 ports, but
- * large machines may have multiple other I/O spaces so we can't place any a priori limit
- * on IO_SPACE_LIMIT. These additional spaces are described in ACPI.
- */
-#define IO_SPACE_LIMIT 0xffffffffffffffffUL
-
-#define MAX_IO_SPACES_BITS 8
-#define MAX_IO_SPACES (1UL << MAX_IO_SPACES_BITS)
-#define IO_SPACE_BITS 24
-#define IO_SPACE_SIZE (1UL << IO_SPACE_BITS)
-
-#define IO_SPACE_NR(port) ((port) >> IO_SPACE_BITS)
-#define IO_SPACE_BASE(space) ((space) << IO_SPACE_BITS)
-#define IO_SPACE_PORT(port) ((port) & (IO_SPACE_SIZE - 1))
-
-#define IO_SPACE_SPARSE_ENCODING(p) ((((p) >> 2) << 12) | ((p) & 0xfff))
-
-struct io_space {
- unsigned long mmio_base; /* base in MMIO space */
- int sparse;
-};
-
-extern struct io_space io_space[];
-extern unsigned int num_io_spaces;
-
-# ifdef __KERNEL__
-
-/*
- * All MMIO iomem cookies are in region 6; anything less is a PIO cookie:
- * 0xCxxxxxxxxxxxxxxx MMIO cookie (return from ioremap)
- * 0x000000001SPPPPPP PIO cookie (S=space number, P..P=port)
- *
- * ioread/writeX() uses the leading 1 in PIO cookies (PIO_OFFSET) to catch
- * code that uses bare port numbers without the prerequisite pci_iomap().
- */
-#define PIO_OFFSET (1UL << (MAX_IO_SPACES_BITS + IO_SPACE_BITS))
-#define PIO_MASK (PIO_OFFSET - 1)
-#define PIO_RESERVED __IA64_UNCACHED_OFFSET
-#define HAVE_ARCH_PIO_SIZE
-
-#include <asm/intrinsics.h>
-#include <asm/page.h>
-#include <asm-generic/iomap.h>
-
-/*
- * Change virtual addresses to physical addresses and vv.
- */
-static inline unsigned long
-virt_to_phys (volatile void *address)
-{
- return (unsigned long) address - PAGE_OFFSET;
-}
-#define virt_to_phys virt_to_phys
-
-static inline void*
-phys_to_virt (unsigned long address)
-{
- return (void *) (address + PAGE_OFFSET);
-}
-#define phys_to_virt phys_to_virt
-
-#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
-extern u64 kern_mem_attribute (unsigned long phys_addr, unsigned long size);
-extern int valid_phys_addr_range (phys_addr_t addr, size_t count); /* efi.c */
-extern int valid_mmap_phys_addr_range (unsigned long pfn, size_t count);
-
-# endif /* KERNEL */
-
-/*
- * Memory fence w/accept. This should never be used in code that is
- * not IA-64 specific.
- */
-#define __ia64_mf_a() ia64_mfa()
-
-static inline void*
-__ia64_mk_io_addr (unsigned long port)
-{
- struct io_space *space;
- unsigned long offset;
-
- space = &io_space[IO_SPACE_NR(port)];
- port = IO_SPACE_PORT(port);
- if (space->sparse)
- offset = IO_SPACE_SPARSE_ENCODING(port);
- else
- offset = port;
-
- return (void *) (space->mmio_base | offset);
-}
-
-/*
- * For the in/out routines, we need to do "mf.a" _after_ doing the I/O access to ensure
- * that the access has completed before executing other I/O accesses. Since we're doing
- * the accesses through an uncachable (UC) translation, the CPU will execute them in
- * program order. However, we still need to tell the compiler not to shuffle them around
- * during optimization, which is why we use "volatile" pointers.
- */
-
-#define inb inb
-static inline unsigned int inb(unsigned long port)
-{
- volatile unsigned char *addr = __ia64_mk_io_addr(port);
- unsigned char ret;
-
- ret = *addr;
- __ia64_mf_a();
- return ret;
-}
-
-#define inw inw
-static inline unsigned int inw(unsigned long port)
-{
- volatile unsigned short *addr = __ia64_mk_io_addr(port);
- unsigned short ret;
-
- ret = *addr;
- __ia64_mf_a();
- return ret;
-}
-
-#define inl inl
-static inline unsigned int inl(unsigned long port)
-{
- volatile unsigned int *addr = __ia64_mk_io_addr(port);
- unsigned int ret;
-
- ret = *addr;
- __ia64_mf_a();
- return ret;
-}
-
-#define outb outb
-static inline void outb(unsigned char val, unsigned long port)
-{
- volatile unsigned char *addr = __ia64_mk_io_addr(port);
-
- *addr = val;
- __ia64_mf_a();
-}
-
-#define outw outw
-static inline void outw(unsigned short val, unsigned long port)
-{
- volatile unsigned short *addr = __ia64_mk_io_addr(port);
-
- *addr = val;
- __ia64_mf_a();
-}
-
-#define outl outl
-static inline void outl(unsigned int val, unsigned long port)
-{
- volatile unsigned int *addr = __ia64_mk_io_addr(port);
-
- *addr = val;
- __ia64_mf_a();
-}
-
-#define insb insb
-static inline void insb(unsigned long port, void *dst, unsigned long count)
-{
- unsigned char *dp = dst;
-
- while (count--)
- *dp++ = inb(port);
-}
-
-#define insw insw
-static inline void insw(unsigned long port, void *dst, unsigned long count)
-{
- unsigned short *dp = dst;
-
- while (count--)
- put_unaligned(inw(port), dp++);
-}
-
-#define insl insl
-static inline void insl(unsigned long port, void *dst, unsigned long count)
-{
- unsigned int *dp = dst;
-
- while (count--)
- put_unaligned(inl(port), dp++);
-}
-
-#define outsb outsb
-static inline void outsb(unsigned long port, const void *src,
- unsigned long count)
-{
- const unsigned char *sp = src;
-
- while (count--)
- outb(*sp++, port);
-}
-
-#define outsw outsw
-static inline void outsw(unsigned long port, const void *src,
- unsigned long count)
-{
- const unsigned short *sp = src;
-
- while (count--)
- outw(get_unaligned(sp++), port);
-}
-
-#define outsl outsl
-static inline void outsl(unsigned long port, const void *src,
- unsigned long count)
-{
- const unsigned int *sp = src;
-
- while (count--)
- outl(get_unaligned(sp++), port);
-}
-
-# ifdef __KERNEL__
-
-#define _PAGE_IOREMAP pgprot_val(PAGE_KERNEL)
-
-extern void __iomem * ioremap_uc(unsigned long offset, unsigned long size);
-
-#define ioremap_prot ioremap_prot
-#define ioremap_cache ioremap
-#define ioremap_uc ioremap_uc
-#define iounmap iounmap
-
-/*
- * String version of IO memory access ops:
- */
-extern void memcpy_fromio(void *dst, const volatile void __iomem *src, long n);
-extern void memcpy_toio(volatile void __iomem *dst, const void *src, long n);
-extern void memset_io(volatile void __iomem *s, int c, long n);
-
-#define memcpy_fromio memcpy_fromio
-#define memcpy_toio memcpy_toio
-#define memset_io memset_io
-#define xlate_dev_mem_ptr xlate_dev_mem_ptr
-#include <asm-generic/io.h>
-#undef PCI_IOBASE
-
-# endif /* __KERNEL__ */
-
-#endif /* _ASM_IA64_IO_H */
diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h
deleted file mode 100644
index eb0db20c9d4c..000000000000
--- a/arch/ia64/include/asm/iommu.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_IOMMU_H
-#define _ASM_IA64_IOMMU_H 1
-
-#include <linux/acpi.h>
-
-/* 10 seconds */
-#define DMAR_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
-
-extern void no_iommu_init(void);
-#ifdef CONFIG_INTEL_IOMMU
-extern int force_iommu, no_iommu;
-extern int iommu_detected;
-
-static inline int __init
-arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr) { return 0; }
-#else
-#define no_iommu (1)
-#define iommu_detected (0)
-#endif
-
-#endif
diff --git a/arch/ia64/include/asm/iosapic.h b/arch/ia64/include/asm/iosapic.h
deleted file mode 100644
index a91aeb413e17..000000000000
--- a/arch/ia64/include/asm/iosapic.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_IA64_IOSAPIC_H
-#define __ASM_IA64_IOSAPIC_H
-
-#define IOSAPIC_REG_SELECT 0x0
-#define IOSAPIC_WINDOW 0x10
-#define IOSAPIC_EOI 0x40
-
-#define IOSAPIC_VERSION 0x1
-
-/*
- * Redirection table entry
- */
-#define IOSAPIC_RTE_LOW(i) (0x10+i*2)
-#define IOSAPIC_RTE_HIGH(i) (0x11+i*2)
-
-#define IOSAPIC_DEST_SHIFT 16
-
-/*
- * Delivery mode
- */
-#define IOSAPIC_DELIVERY_SHIFT 8
-#define IOSAPIC_FIXED 0x0
-#define IOSAPIC_LOWEST_PRIORITY 0x1
-#define IOSAPIC_PMI 0x2
-#define IOSAPIC_NMI 0x4
-#define IOSAPIC_INIT 0x5
-#define IOSAPIC_EXTINT 0x7
-
-/*
- * Interrupt polarity
- */
-#define IOSAPIC_POLARITY_SHIFT 13
-#define IOSAPIC_POL_HIGH 0
-#define IOSAPIC_POL_LOW 1
-
-/*
- * Trigger mode
- */
-#define IOSAPIC_TRIGGER_SHIFT 15
-#define IOSAPIC_EDGE 0
-#define IOSAPIC_LEVEL 1
-
-/*
- * Mask bit
- */
-
-#define IOSAPIC_MASK_SHIFT 16
-#define IOSAPIC_MASK (1<<IOSAPIC_MASK_SHIFT)
-
-#define IOSAPIC_VECTOR_MASK 0xffffff00
-
-#ifndef __ASSEMBLY__
-
-#define NR_IOSAPICS 256
-
-#define iosapic_pcat_compat_init ia64_native_iosapic_pcat_compat_init
-#define __iosapic_read __ia64_native_iosapic_read
-#define __iosapic_write __ia64_native_iosapic_write
-#define iosapic_get_irq_chip ia64_native_iosapic_get_irq_chip
-
-extern void __init ia64_native_iosapic_pcat_compat_init(void);
-extern struct irq_chip *ia64_native_iosapic_get_irq_chip(unsigned long trigger);
-
-static inline unsigned int
-__ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
-{
- writel(reg, iosapic + IOSAPIC_REG_SELECT);
- return readl(iosapic + IOSAPIC_WINDOW);
-}
-
-static inline void
-__ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
-{
- writel(reg, iosapic + IOSAPIC_REG_SELECT);
- writel(val, iosapic + IOSAPIC_WINDOW);
-}
-
-static inline void iosapic_eoi(char __iomem *iosapic, u32 vector)
-{
- writel(vector, iosapic + IOSAPIC_EOI);
-}
-
-extern void __init iosapic_system_init (int pcat_compat);
-extern int iosapic_init (unsigned long address, unsigned int gsi_base);
-extern int iosapic_remove (unsigned int gsi_base);
-extern int gsi_to_irq (unsigned int gsi);
-extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
- unsigned long trigger);
-extern void iosapic_unregister_intr (unsigned int irq);
-extern void iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
- unsigned long polarity,
- unsigned long trigger);
-extern int __init iosapic_register_platform_intr (u32 int_type,
- unsigned int gsi,
- int pmi_vector,
- u16 eid, u16 id,
- unsigned long polarity,
- unsigned long trigger);
-
-#ifdef CONFIG_NUMA
-extern void map_iosapic_to_node (unsigned int, int);
-#endif
-
-# endif /* !__ASSEMBLY__ */
-#endif /* __ASM_IA64_IOSAPIC_H */
diff --git a/arch/ia64/include/asm/irq.h b/arch/ia64/include/asm/irq.h
deleted file mode 100644
index 0eccf33dfe8b..000000000000
--- a/arch/ia64/include/asm/irq.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_IRQ_H
-#define _ASM_IA64_IRQ_H
-
-/*
- * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- *
- * 11/24/98 S.Eranian updated TIMER_IRQ and irq_canonicalize
- * 01/20/99 S.Eranian added keyboard interrupt
- * 02/29/00 D.Mosberger moved most things into hw_irq.h
- */
-
-#include <linux/types.h>
-#include <linux/cpumask.h>
-#include <asm/native/irq.h>
-
-#define NR_IRQS IA64_NATIVE_NR_IRQS
-
-static __inline__ int
-irq_canonicalize (int irq)
-{
- /*
- * We do the legacy thing here of pretending that irqs < 16
- * are 8259 irqs. This really shouldn't be necessary at all,
- * but we keep it here as serial.c still uses it...
- */
- return ((irq == 2) ? 9 : irq);
-}
-
-extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
-
-int create_irq(void);
-void destroy_irq(unsigned int irq);
-
-#endif /* _ASM_IA64_IRQ_H */
diff --git a/arch/ia64/include/asm/irq_regs.h b/arch/ia64/include/asm/irq_regs.h
deleted file mode 100644
index 3dd9c0b70270..000000000000
--- a/arch/ia64/include/asm/irq_regs.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/irq_regs.h>
diff --git a/arch/ia64/include/asm/irq_remapping.h b/arch/ia64/include/asm/irq_remapping.h
deleted file mode 100644
index 547a6e87018c..000000000000
--- a/arch/ia64/include/asm/irq_remapping.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __IA64_INTR_REMAPPING_H
-#define __IA64_INTR_REMAPPING_H
-#define irq_remapping_enabled 0
-#endif
diff --git a/arch/ia64/include/asm/irqflags.h b/arch/ia64/include/asm/irqflags.h
deleted file mode 100644
index 1dc30f12e545..000000000000
--- a/arch/ia64/include/asm/irqflags.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * IRQ flags defines.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- */
-
-#ifndef _ASM_IA64_IRQFLAGS_H
-#define _ASM_IA64_IRQFLAGS_H
-
-#include <asm/pal.h>
-#include <asm/kregs.h>
-
-#ifdef CONFIG_IA64_DEBUG_IRQ
-extern unsigned long last_cli_ip;
-static inline void arch_maybe_save_ip(unsigned long flags)
-{
- if (flags & IA64_PSR_I)
- last_cli_ip = ia64_getreg(_IA64_REG_IP);
-}
-#else
-#define arch_maybe_save_ip(flags) do {} while (0)
-#endif
-
-/*
- * - clearing psr.i is implicitly serialized (visible by next insn)
- * - setting psr.i requires data serialization
- * - we need a stop-bit before reading PSR because we sometimes
- * write a floating-point register right before reading the PSR
- * and that writes to PSR.mfl
- */
-
-static inline unsigned long arch_local_save_flags(void)
-{
- ia64_stop();
- return ia64_getreg(_IA64_REG_PSR);
-}
-
-static inline unsigned long arch_local_irq_save(void)
-{
- unsigned long flags = arch_local_save_flags();
-
- ia64_stop();
- ia64_rsm(IA64_PSR_I);
- arch_maybe_save_ip(flags);
- return flags;
-}
-
-static inline void arch_local_irq_disable(void)
-{
-#ifdef CONFIG_IA64_DEBUG_IRQ
- arch_local_irq_save();
-#else
- ia64_stop();
- ia64_rsm(IA64_PSR_I);
-#endif
-}
-
-static inline void arch_local_irq_enable(void)
-{
- ia64_stop();
- ia64_ssm(IA64_PSR_I);
- ia64_srlz_d();
-}
-
-static inline void arch_local_irq_restore(unsigned long flags)
-{
-#ifdef CONFIG_IA64_DEBUG_IRQ
- unsigned long old_psr = arch_local_save_flags();
-#endif
- ia64_intrin_local_irq_restore(flags & IA64_PSR_I);
- arch_maybe_save_ip(old_psr & ~flags);
-}
-
-static inline bool arch_irqs_disabled_flags(unsigned long flags)
-{
- return (flags & IA64_PSR_I) == 0;
-}
-
-static inline bool arch_irqs_disabled(void)
-{
- return arch_irqs_disabled_flags(arch_local_save_flags());
-}
-
-static inline void arch_safe_halt(void)
-{
- arch_local_irq_enable();
- ia64_pal_halt_light(); /* PAL_HALT_LIGHT */
-}
-
-
-#endif /* _ASM_IA64_IRQFLAGS_H */
diff --git a/arch/ia64/include/asm/kdebug.h b/arch/ia64/include/asm/kdebug.h
deleted file mode 100644
index 4f7e6dc974bc..000000000000
--- a/arch/ia64/include/asm/kdebug.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _IA64_KDEBUG_H
-#define _IA64_KDEBUG_H 1
-/*
- *
- * Copyright (C) Intel Corporation, 2005
- *
- * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
- * <anil.s.keshavamurthy@intel.com> adopted from
- * include/asm-x86_64/kdebug.h
- *
- * 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more
- * events.
- */
-
-enum die_val {
- DIE_BREAK = 1,
- DIE_FAULT,
- DIE_OOPS,
- DIE_MACHINE_HALT,
- DIE_MACHINE_RESTART,
- DIE_MCA_MONARCH_ENTER,
- DIE_MCA_MONARCH_PROCESS,
- DIE_MCA_MONARCH_LEAVE,
- DIE_MCA_SLAVE_ENTER,
- DIE_MCA_SLAVE_PROCESS,
- DIE_MCA_SLAVE_LEAVE,
- DIE_MCA_RENDZVOUS_ENTER,
- DIE_MCA_RENDZVOUS_PROCESS,
- DIE_MCA_RENDZVOUS_LEAVE,
- DIE_MCA_NEW_TIMEOUT,
- DIE_INIT_ENTER,
- DIE_INIT_MONARCH_ENTER,
- DIE_INIT_MONARCH_PROCESS,
- DIE_INIT_MONARCH_LEAVE,
- DIE_INIT_SLAVE_ENTER,
- DIE_INIT_SLAVE_PROCESS,
- DIE_INIT_SLAVE_LEAVE,
- DIE_KDEBUG_ENTER,
- DIE_KDEBUG_LEAVE,
- DIE_KDUMP_ENTER,
- DIE_KDUMP_LEAVE,
-};
-
-#endif
diff --git a/arch/ia64/include/asm/kexec.h b/arch/ia64/include/asm/kexec.h
deleted file mode 100644
index 294b1e1ebd2d..000000000000
--- a/arch/ia64/include/asm/kexec.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_KEXEC_H
-#define _ASM_IA64_KEXEC_H
-
-#include <asm/setup.h>
-
-/* Maximum physical address we can use pages from */
-#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
-/* Maximum address we can reach in physical address mode */
-#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
-/* Maximum address we can use for the control code buffer */
-#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
-
-#define KEXEC_CONTROL_PAGE_SIZE (8192 + 8192 + 4096)
-
-/* The native architecture */
-#define KEXEC_ARCH KEXEC_ARCH_IA_64
-
-#define kexec_flush_icache_page(page) do { \
- unsigned long page_addr = (unsigned long)page_address(page); \
- flush_icache_range(page_addr, page_addr + PAGE_SIZE); \
- } while(0)
-
-extern struct kimage *ia64_kimage;
-extern const unsigned int relocate_new_kernel_size;
-extern void relocate_new_kernel(unsigned long, unsigned long,
- struct ia64_boot_param *, unsigned long);
-static inline void
-crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs)
-{
-}
-extern struct resource efi_memmap_res;
-extern struct resource boot_param_res;
-extern void kdump_smp_send_stop(void);
-extern void kdump_smp_send_init(void);
-extern void kexec_disable_iosapic(void);
-extern void crash_save_this_cpu(void);
-struct rsvd_region;
-extern unsigned long kdump_find_rsvd_region(unsigned long size,
- struct rsvd_region *rsvd_regions, int n);
-extern void kdump_cpu_freeze(struct unw_frame_info *info, void *arg);
-extern int kdump_status[];
-extern atomic_t kdump_cpu_freezed;
-extern atomic_t kdump_in_progress;
-
-#endif /* _ASM_IA64_KEXEC_H */
diff --git a/arch/ia64/include/asm/kprobes.h b/arch/ia64/include/asm/kprobes.h
deleted file mode 100644
index 9e956768946c..000000000000
--- a/arch/ia64/include/asm/kprobes.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _ASM_KPROBES_H
-#define _ASM_KPROBES_H
-/*
- * Kernel Probes (KProbes)
- *
- * Copyright (C) IBM Corporation, 2002, 2004
- * Copyright (C) Intel Corporation, 2005
- *
- * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
- * <anil.s.keshavamurthy@intel.com> adapted from i386
- */
-#include <asm-generic/kprobes.h>
-#include <asm/break.h>
-
-#define BREAK_INST (long)(__IA64_BREAK_KPROBE << 6)
-
-#ifdef CONFIG_KPROBES
-
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/percpu.h>
-
-#define __ARCH_WANT_KPROBES_INSN_SLOT
-#define MAX_INSN_SIZE 2 /* last half is for kprobe-booster */
-#define NOP_M_INST (long)(1<<27)
-#define BRL_INST(i1, i2) ((long)((0xcL << 37) | /* brl */ \
- (0x1L << 12) | /* many */ \
- (((i1) & 1) << 36) | ((i2) << 13))) /* imm */
-
-typedef union cmp_inst {
- struct {
- unsigned long long qp : 6;
- unsigned long long p1 : 6;
- unsigned long long c : 1;
- unsigned long long r2 : 7;
- unsigned long long r3 : 7;
- unsigned long long p2 : 6;
- unsigned long long ta : 1;
- unsigned long long x2 : 2;
- unsigned long long tb : 1;
- unsigned long long opcode : 4;
- unsigned long long reserved : 23;
- }f;
- unsigned long long l;
-} cmp_inst_t;
-
-struct kprobe;
-
-typedef struct _bundle {
- struct {
- unsigned long long template : 5;
- unsigned long long slot0 : 41;
- unsigned long long slot1_p0 : 64-46;
- } quad0;
- struct {
- unsigned long long slot1_p1 : 41 - (64-46);
- unsigned long long slot2 : 41;
- } quad1;
-} __attribute__((__aligned__(16))) bundle_t;
-
-struct prev_kprobe {
- struct kprobe *kp;
- unsigned long status;
-};
-
-#define MAX_PARAM_RSE_SIZE (0x60+0x60/0x3f)
-/* per-cpu kprobe control block */
-#define ARCH_PREV_KPROBE_SZ 2
-struct kprobe_ctlblk {
- unsigned long kprobe_status;
- unsigned long *bsp;
- unsigned long cfm;
- atomic_t prev_kprobe_index;
- struct prev_kprobe prev_kprobe[ARCH_PREV_KPROBE_SZ];
-};
-
-#define kretprobe_blacklist_size 0
-
-#define SLOT0_OPCODE_SHIFT (37)
-#define SLOT1_p1_OPCODE_SHIFT (37 - (64-46))
-#define SLOT2_OPCODE_SHIFT (37)
-
-#define INDIRECT_CALL_OPCODE (1)
-#define IP_RELATIVE_CALL_OPCODE (5)
-#define IP_RELATIVE_BRANCH_OPCODE (4)
-#define IP_RELATIVE_PREDICT_OPCODE (7)
-#define LONG_BRANCH_OPCODE (0xC)
-#define LONG_CALL_OPCODE (0xD)
-#define flush_insn_slot(p) do { } while (0)
-
-typedef struct kprobe_opcode {
- bundle_t bundle;
-} kprobe_opcode_t;
-
-/* Architecture specific copy of original instruction*/
-struct arch_specific_insn {
- /* copy of the instruction to be emulated */
- kprobe_opcode_t *insn;
- #define INST_FLAG_FIX_RELATIVE_IP_ADDR 1
- #define INST_FLAG_FIX_BRANCH_REG 2
- #define INST_FLAG_BREAK_INST 4
- #define INST_FLAG_BOOSTABLE 8
- unsigned long inst_flag;
- unsigned short target_br_reg;
- unsigned short slot;
-};
-
-extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
-extern int kprobe_exceptions_notify(struct notifier_block *self,
- unsigned long val, void *data);
-
-extern void arch_remove_kprobe(struct kprobe *p);
-
-#endif /* CONFIG_KPROBES */
-#endif /* _ASM_KPROBES_H */
diff --git a/arch/ia64/include/asm/kregs.h b/arch/ia64/include/asm/kregs.h
deleted file mode 100644
index 44113b75e4eb..000000000000
--- a/arch/ia64/include/asm/kregs.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_KREGS_H
-#define _ASM_IA64_KREGS_H
-
-/*
- * Copyright (C) 2001-2002 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-/*
- * This file defines the kernel register usage convention used by Linux/ia64.
- */
-
-/*
- * Kernel registers:
- */
-#define IA64_KR_IO_BASE 0 /* ar.k0: legacy I/O base address */
-#define IA64_KR_TSSD 1 /* ar.k1: IVE uses this as the TSSD */
-#define IA64_KR_PER_CPU_DATA 3 /* ar.k3: physical per-CPU base */
-#define IA64_KR_CURRENT_STACK 4 /* ar.k4: what's mapped in IA64_TR_CURRENT_STACK */
-#define IA64_KR_FPU_OWNER 5 /* ar.k5: fpu-owner (UP only, at the moment) */
-#define IA64_KR_CURRENT 6 /* ar.k6: "current" task pointer */
-#define IA64_KR_PT_BASE 7 /* ar.k7: page table base address (physical) */
-
-#define _IA64_KR_PASTE(x,y) x##y
-#define _IA64_KR_PREFIX(n) _IA64_KR_PASTE(ar.k, n)
-#define IA64_KR(n) _IA64_KR_PREFIX(IA64_KR_##n)
-
-/*
- * Translation registers:
- */
-#define IA64_TR_KERNEL 0 /* itr0, dtr0: maps kernel image (code & data) */
-#define IA64_TR_PALCODE 1 /* itr1: maps PALcode as required by EFI */
-#define IA64_TR_CURRENT_STACK 1 /* dtr1: maps kernel's memory- & register-stacks */
-
-#define IA64_TR_ALLOC_BASE 2 /* itr&dtr: Base of dynamic TR resource*/
-#define IA64_TR_ALLOC_MAX 64 /* Max number for dynamic use*/
-
-/* Processor status register bits: */
-#define IA64_PSR_BE_BIT 1
-#define IA64_PSR_UP_BIT 2
-#define IA64_PSR_AC_BIT 3
-#define IA64_PSR_MFL_BIT 4
-#define IA64_PSR_MFH_BIT 5
-#define IA64_PSR_IC_BIT 13
-#define IA64_PSR_I_BIT 14
-#define IA64_PSR_PK_BIT 15
-#define IA64_PSR_DT_BIT 17
-#define IA64_PSR_DFL_BIT 18
-#define IA64_PSR_DFH_BIT 19
-#define IA64_PSR_SP_BIT 20
-#define IA64_PSR_PP_BIT 21
-#define IA64_PSR_DI_BIT 22
-#define IA64_PSR_SI_BIT 23
-#define IA64_PSR_DB_BIT 24
-#define IA64_PSR_LP_BIT 25
-#define IA64_PSR_TB_BIT 26
-#define IA64_PSR_RT_BIT 27
-/* The following are not affected by save_flags()/restore_flags(): */
-#define IA64_PSR_CPL0_BIT 32
-#define IA64_PSR_CPL1_BIT 33
-#define IA64_PSR_IS_BIT 34
-#define IA64_PSR_MC_BIT 35
-#define IA64_PSR_IT_BIT 36
-#define IA64_PSR_ID_BIT 37
-#define IA64_PSR_DA_BIT 38
-#define IA64_PSR_DD_BIT 39
-#define IA64_PSR_SS_BIT 40
-#define IA64_PSR_RI_BIT 41
-#define IA64_PSR_ED_BIT 43
-#define IA64_PSR_BN_BIT 44
-#define IA64_PSR_IA_BIT 45
-
-/* A mask of PSR bits that we generally don't want to inherit across a clone2() or an
- execve(). Only list flags here that need to be cleared/set for BOTH clone2() and
- execve(). */
-#define IA64_PSR_BITS_TO_CLEAR (IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_DB | IA64_PSR_LP | \
- IA64_PSR_TB | IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD | \
- IA64_PSR_SS | IA64_PSR_ED | IA64_PSR_IA)
-#define IA64_PSR_BITS_TO_SET (IA64_PSR_DFH | IA64_PSR_SP)
-
-#define IA64_PSR_BE (__IA64_UL(1) << IA64_PSR_BE_BIT)
-#define IA64_PSR_UP (__IA64_UL(1) << IA64_PSR_UP_BIT)
-#define IA64_PSR_AC (__IA64_UL(1) << IA64_PSR_AC_BIT)
-#define IA64_PSR_MFL (__IA64_UL(1) << IA64_PSR_MFL_BIT)
-#define IA64_PSR_MFH (__IA64_UL(1) << IA64_PSR_MFH_BIT)
-#define IA64_PSR_IC (__IA64_UL(1) << IA64_PSR_IC_BIT)
-#define IA64_PSR_I (__IA64_UL(1) << IA64_PSR_I_BIT)
-#define IA64_PSR_PK (__IA64_UL(1) << IA64_PSR_PK_BIT)
-#define IA64_PSR_DT (__IA64_UL(1) << IA64_PSR_DT_BIT)
-#define IA64_PSR_DFL (__IA64_UL(1) << IA64_PSR_DFL_BIT)
-#define IA64_PSR_DFH (__IA64_UL(1) << IA64_PSR_DFH_BIT)
-#define IA64_PSR_SP (__IA64_UL(1) << IA64_PSR_SP_BIT)
-#define IA64_PSR_PP (__IA64_UL(1) << IA64_PSR_PP_BIT)
-#define IA64_PSR_DI (__IA64_UL(1) << IA64_PSR_DI_BIT)
-#define IA64_PSR_SI (__IA64_UL(1) << IA64_PSR_SI_BIT)
-#define IA64_PSR_DB (__IA64_UL(1) << IA64_PSR_DB_BIT)
-#define IA64_PSR_LP (__IA64_UL(1) << IA64_PSR_LP_BIT)
-#define IA64_PSR_TB (__IA64_UL(1) << IA64_PSR_TB_BIT)
-#define IA64_PSR_RT (__IA64_UL(1) << IA64_PSR_RT_BIT)
-/* The following are not affected by save_flags()/restore_flags(): */
-#define IA64_PSR_CPL (__IA64_UL(3) << IA64_PSR_CPL0_BIT)
-#define IA64_PSR_IS (__IA64_UL(1) << IA64_PSR_IS_BIT)
-#define IA64_PSR_MC (__IA64_UL(1) << IA64_PSR_MC_BIT)
-#define IA64_PSR_IT (__IA64_UL(1) << IA64_PSR_IT_BIT)
-#define IA64_PSR_ID (__IA64_UL(1) << IA64_PSR_ID_BIT)
-#define IA64_PSR_DA (__IA64_UL(1) << IA64_PSR_DA_BIT)
-#define IA64_PSR_DD (__IA64_UL(1) << IA64_PSR_DD_BIT)
-#define IA64_PSR_SS (__IA64_UL(1) << IA64_PSR_SS_BIT)
-#define IA64_PSR_RI (__IA64_UL(3) << IA64_PSR_RI_BIT)
-#define IA64_PSR_ED (__IA64_UL(1) << IA64_PSR_ED_BIT)
-#define IA64_PSR_BN (__IA64_UL(1) << IA64_PSR_BN_BIT)
-#define IA64_PSR_IA (__IA64_UL(1) << IA64_PSR_IA_BIT)
-
-/* User mask bits: */
-#define IA64_PSR_UM (IA64_PSR_BE | IA64_PSR_UP | IA64_PSR_AC | IA64_PSR_MFL | IA64_PSR_MFH)
-
-/* Default Control Register */
-#define IA64_DCR_PP_BIT 0 /* privileged performance monitor default */
-#define IA64_DCR_BE_BIT 1 /* big-endian default */
-#define IA64_DCR_LC_BIT 2 /* ia32 lock-check enable */
-#define IA64_DCR_DM_BIT 8 /* defer TLB miss faults */
-#define IA64_DCR_DP_BIT 9 /* defer page-not-present faults */
-#define IA64_DCR_DK_BIT 10 /* defer key miss faults */
-#define IA64_DCR_DX_BIT 11 /* defer key permission faults */
-#define IA64_DCR_DR_BIT 12 /* defer access right faults */
-#define IA64_DCR_DA_BIT 13 /* defer access bit faults */
-#define IA64_DCR_DD_BIT 14 /* defer debug faults */
-
-#define IA64_DCR_PP (__IA64_UL(1) << IA64_DCR_PP_BIT)
-#define IA64_DCR_BE (__IA64_UL(1) << IA64_DCR_BE_BIT)
-#define IA64_DCR_LC (__IA64_UL(1) << IA64_DCR_LC_BIT)
-#define IA64_DCR_DM (__IA64_UL(1) << IA64_DCR_DM_BIT)
-#define IA64_DCR_DP (__IA64_UL(1) << IA64_DCR_DP_BIT)
-#define IA64_DCR_DK (__IA64_UL(1) << IA64_DCR_DK_BIT)
-#define IA64_DCR_DX (__IA64_UL(1) << IA64_DCR_DX_BIT)
-#define IA64_DCR_DR (__IA64_UL(1) << IA64_DCR_DR_BIT)
-#define IA64_DCR_DA (__IA64_UL(1) << IA64_DCR_DA_BIT)
-#define IA64_DCR_DD (__IA64_UL(1) << IA64_DCR_DD_BIT)
-
-/* Interrupt Status Register */
-#define IA64_ISR_X_BIT 32 /* execute access */
-#define IA64_ISR_W_BIT 33 /* write access */
-#define IA64_ISR_R_BIT 34 /* read access */
-#define IA64_ISR_NA_BIT 35 /* non-access */
-#define IA64_ISR_SP_BIT 36 /* speculative load exception */
-#define IA64_ISR_RS_BIT 37 /* mandatory register-stack exception */
-#define IA64_ISR_IR_BIT 38 /* invalid register frame exception */
-#define IA64_ISR_CODE_MASK 0xf
-
-#define IA64_ISR_X (__IA64_UL(1) << IA64_ISR_X_BIT)
-#define IA64_ISR_W (__IA64_UL(1) << IA64_ISR_W_BIT)
-#define IA64_ISR_R (__IA64_UL(1) << IA64_ISR_R_BIT)
-#define IA64_ISR_NA (__IA64_UL(1) << IA64_ISR_NA_BIT)
-#define IA64_ISR_SP (__IA64_UL(1) << IA64_ISR_SP_BIT)
-#define IA64_ISR_RS (__IA64_UL(1) << IA64_ISR_RS_BIT)
-#define IA64_ISR_IR (__IA64_UL(1) << IA64_ISR_IR_BIT)
-
-/* ISR code field for non-access instructions */
-#define IA64_ISR_CODE_TPA 0
-#define IA64_ISR_CODE_FC 1
-#define IA64_ISR_CODE_PROBE 2
-#define IA64_ISR_CODE_TAK 3
-#define IA64_ISR_CODE_LFETCH 4
-#define IA64_ISR_CODE_PROBEF 5
-
-#endif /* _ASM_IA64_kREGS_H */
diff --git a/arch/ia64/include/asm/libata-portmap.h b/arch/ia64/include/asm/libata-portmap.h
deleted file mode 100644
index 757f84e5dc6e..000000000000
--- a/arch/ia64/include/asm/libata-portmap.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_IA64_LIBATA_PORTMAP_H
-#define __ASM_IA64_LIBATA_PORTMAP_H
-
-#define ATA_PRIMARY_IRQ(dev) isa_irq_to_vector(14)
-
-#define ATA_SECONDARY_IRQ(dev) isa_irq_to_vector(15)
-
-#endif
diff --git a/arch/ia64/include/asm/linkage.h b/arch/ia64/include/asm/linkage.h
deleted file mode 100644
index 5178af560925..000000000000
--- a/arch/ia64/include/asm/linkage.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_LINKAGE_H
-#define __ASM_LINKAGE_H
-
-#ifndef __ASSEMBLY__
-
-#define asmlinkage CPP_ASMLINKAGE __attribute__((syscall_linkage))
-
-#else
-
-#include <asm/asmmacro.h>
-
-#endif
-
-#define cond_syscall(x) asm(".weak\t" #x "#\n" #x "#\t=\tsys_ni_syscall#")
-#define SYSCALL_ALIAS(alias, name) \
- asm ( #alias "# = " #name "#\n\t.globl " #alias "#")
-
-#endif
diff --git a/arch/ia64/include/asm/local.h b/arch/ia64/include/asm/local.h
deleted file mode 100644
index c11c530f74d0..000000000000
--- a/arch/ia64/include/asm/local.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/local.h>
diff --git a/arch/ia64/include/asm/mca.h b/arch/ia64/include/asm/mca.h
deleted file mode 100644
index 05805249296c..000000000000
--- a/arch/ia64/include/asm/mca.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * File: mca.h
- * Purpose: Machine check handling specific defines
- *
- * Copyright (C) 1999, 2004 Silicon Graphics, Inc.
- * Copyright (C) Vijay Chander <vijay@engr.sgi.com>
- * Copyright (C) Srinivasa Thirumalachar <sprasad@engr.sgi.com>
- * Copyright (C) Russ Anderson <rja@sgi.com>
- */
-
-#ifndef _ASM_IA64_MCA_H
-#define _ASM_IA64_MCA_H
-
-#if !defined(__ASSEMBLY__)
-
-#include <linux/percpu.h>
-#include <linux/threads.h>
-#include <linux/types.h>
-#include <asm/ptrace.h>
-
-#define IA64_MCA_RENDEZ_TIMEOUT (20 * 1000) /* value in milliseconds - 20 seconds */
-
-typedef struct ia64_fptr {
- unsigned long fp;
- unsigned long gp;
-} ia64_fptr_t;
-
-typedef union cmcv_reg_u {
- u64 cmcv_regval;
- struct {
- u64 cmcr_vector : 8;
- u64 cmcr_reserved1 : 4;
- u64 cmcr_ignored1 : 1;
- u64 cmcr_reserved2 : 3;
- u64 cmcr_mask : 1;
- u64 cmcr_ignored2 : 47;
- } cmcv_reg_s;
-
-} cmcv_reg_t;
-
-#define cmcv_mask cmcv_reg_s.cmcr_mask
-#define cmcv_vector cmcv_reg_s.cmcr_vector
-
-enum {
- IA64_MCA_RENDEZ_CHECKIN_NOTDONE = 0x0,
- IA64_MCA_RENDEZ_CHECKIN_DONE = 0x1,
- IA64_MCA_RENDEZ_CHECKIN_INIT = 0x2,
- IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA = 0x3,
-};
-
-/* Information maintained by the MC infrastructure */
-typedef struct ia64_mc_info_s {
- u64 imi_mca_handler;
- size_t imi_mca_handler_size;
- u64 imi_monarch_init_handler;
- size_t imi_monarch_init_handler_size;
- u64 imi_slave_init_handler;
- size_t imi_slave_init_handler_size;
- u8 imi_rendez_checkin[NR_CPUS];
-
-} ia64_mc_info_t;
-
-/* Handover state from SAL to OS and vice versa, for both MCA and INIT events.
- * Besides the handover state, it also contains some saved registers from the
- * time of the event.
- * Note: mca_asm.S depends on the precise layout of this structure.
- */
-
-struct ia64_sal_os_state {
-
- /* SAL to OS */
- unsigned long os_gp; /* GP of the os registered with the SAL, physical */
- unsigned long pal_proc; /* PAL_PROC entry point, physical */
- unsigned long sal_proc; /* SAL_PROC entry point, physical */
- unsigned long rv_rc; /* MCA - Rendezvous state, INIT - reason code */
- unsigned long proc_state_param; /* from R18 */
- unsigned long monarch; /* 1 for a monarch event, 0 for a slave */
-
- /* common */
- unsigned long sal_ra; /* Return address in SAL, physical */
- unsigned long sal_gp; /* GP of the SAL - physical */
- struct pal_min_state_area *pal_min_state; /* from R17. physical in asm, virtual in C */
- /* Previous values of IA64_KR(CURRENT) and IA64_KR(CURRENT_STACK).
- * Note: if the MCA/INIT recovery code wants to resume to a new context
- * then it must change these values to reflect the new kernel stack.
- */
- unsigned long prev_IA64_KR_CURRENT; /* previous value of IA64_KR(CURRENT) */
- unsigned long prev_IA64_KR_CURRENT_STACK;
- struct task_struct *prev_task; /* previous task, NULL if it is not useful */
- /* Some interrupt registers are not saved in minstate, pt_regs or
- * switch_stack. Because MCA/INIT can occur when interrupts are
- * disabled, we need to save the additional interrupt registers over
- * MCA/INIT and resume.
- */
- unsigned long isr;
- unsigned long ifa;
- unsigned long itir;
- unsigned long iipa;
- unsigned long iim;
- unsigned long iha;
-
- /* OS to SAL */
- unsigned long os_status; /* OS status to SAL, enum below */
- unsigned long context; /* 0 if return to same context
- 1 if return to new context */
-
- /* I-resources */
- unsigned long iip;
- unsigned long ipsr;
- unsigned long ifs;
-};
-
-enum {
- IA64_MCA_CORRECTED = 0x0, /* Error has been corrected by OS_MCA */
- IA64_MCA_WARM_BOOT = -1, /* Warm boot of the system need from SAL */
- IA64_MCA_COLD_BOOT = -2, /* Cold boot of the system need from SAL */
- IA64_MCA_HALT = -3 /* System to be halted by SAL */
-};
-
-enum {
- IA64_INIT_RESUME = 0x0, /* Resume after return from INIT */
- IA64_INIT_WARM_BOOT = -1, /* Warm boot of the system need from SAL */
-};
-
-enum {
- IA64_MCA_SAME_CONTEXT = 0x0, /* SAL to return to same context */
- IA64_MCA_NEW_CONTEXT = -1 /* SAL to return to new context */
-};
-
-/* Per-CPU MCA state that is too big for normal per-CPU variables. */
-
-struct ia64_mca_cpu {
- u64 mca_stack[KERNEL_STACK_SIZE/8];
- u64 init_stack[KERNEL_STACK_SIZE/8];
-};
-
-/* Array of physical addresses of each CPU's MCA area. */
-extern unsigned long __per_cpu_mca[NR_CPUS];
-
-extern int cpe_vector;
-extern int ia64_cpe_irq;
-extern void ia64_mca_init(void);
-extern void ia64_mca_irq_init(void);
-extern void ia64_mca_cpu_init(void *);
-extern void ia64_os_mca_dispatch(void);
-extern void ia64_os_mca_dispatch_end(void);
-extern void ia64_mca_ucmc_handler(struct pt_regs *, struct ia64_sal_os_state *);
-extern void ia64_init_handler(struct pt_regs *,
- struct switch_stack *,
- struct ia64_sal_os_state *);
-extern void ia64_os_init_on_kdump(void);
-extern void ia64_monarch_init_handler(void);
-extern void ia64_slave_init_handler(void);
-extern void ia64_mca_cmc_vector_setup(void);
-extern int ia64_reg_MCA_extension(int (*fn)(void *, struct ia64_sal_os_state *));
-extern void ia64_unreg_MCA_extension(void);
-extern unsigned long ia64_get_rnat(unsigned long *);
-extern void ia64_set_psr_mc(void);
-extern void ia64_mca_printk(const char * fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-struct ia64_mca_notify_die {
- struct ia64_sal_os_state *sos;
- int *monarch_cpu;
- int *data;
-};
-
-DECLARE_PER_CPU(u64, ia64_mca_pal_base);
-
-#else /* __ASSEMBLY__ */
-
-#define IA64_MCA_CORRECTED 0x0 /* Error has been corrected by OS_MCA */
-#define IA64_MCA_WARM_BOOT -1 /* Warm boot of the system need from SAL */
-#define IA64_MCA_COLD_BOOT -2 /* Cold boot of the system need from SAL */
-#define IA64_MCA_HALT -3 /* System to be halted by SAL */
-
-#define IA64_INIT_RESUME 0x0 /* Resume after return from INIT */
-#define IA64_INIT_WARM_BOOT -1 /* Warm boot of the system need from SAL */
-
-#define IA64_MCA_SAME_CONTEXT 0x0 /* SAL to return to same context */
-#define IA64_MCA_NEW_CONTEXT -1 /* SAL to return to new context */
-
-#endif /* !__ASSEMBLY__ */
-#endif /* _ASM_IA64_MCA_H */
diff --git a/arch/ia64/include/asm/mca_asm.h b/arch/ia64/include/asm/mca_asm.h
deleted file mode 100644
index e3ab1f41f1c3..000000000000
--- a/arch/ia64/include/asm/mca_asm.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * File: mca_asm.h
- * Purpose: Machine check handling specific defines
- *
- * Copyright (C) 1999 Silicon Graphics, Inc.
- * Copyright (C) Vijay Chander <vijay@engr.sgi.com>
- * Copyright (C) Srinivasa Thirumalachar <sprasad@engr.sgi.com>
- * Copyright (C) 2000 Hewlett-Packard Co.
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2002 Intel Corp.
- * Copyright (C) 2002 Jenna Hall <jenna.s.hall@intel.com>
- * Copyright (C) 2005 Silicon Graphics, Inc
- * Copyright (C) 2005 Keith Owens <kaos@sgi.com>
- */
-#ifndef _ASM_IA64_MCA_ASM_H
-#define _ASM_IA64_MCA_ASM_H
-
-#include <asm/percpu.h>
-
-#define PSR_IC 13
-#define PSR_I 14
-#define PSR_DT 17
-#define PSR_RT 27
-#define PSR_MC 35
-#define PSR_IT 36
-#define PSR_BN 44
-
-/*
- * This macro converts a instruction virtual address to a physical address
- * Right now for simulation purposes the virtual addresses are
- * direct mapped to physical addresses.
- * 1. Lop off bits 61 thru 63 in the virtual address
- */
-#define INST_VA_TO_PA(addr) \
- dep addr = 0, addr, 61, 3
-/*
- * This macro converts a data virtual address to a physical address
- * Right now for simulation purposes the virtual addresses are
- * direct mapped to physical addresses.
- * 1. Lop off bits 61 thru 63 in the virtual address
- */
-#define DATA_VA_TO_PA(addr) \
- tpa addr = addr
-/*
- * This macro converts a data physical address to a virtual address
- * Right now for simulation purposes the virtual addresses are
- * direct mapped to physical addresses.
- * 1. Put 0x7 in bits 61 thru 63.
- */
-#define DATA_PA_TO_VA(addr,temp) \
- mov temp = 0x7 ;; \
- dep addr = temp, addr, 61, 3
-
-#define GET_THIS_PADDR(reg, var) \
- mov reg = IA64_KR(PER_CPU_DATA);; \
- addl reg = THIS_CPU(var), reg
-
-/*
- * This macro jumps to the instruction at the given virtual address
- * and starts execution in physical mode with all the address
- * translations turned off.
- * 1. Save the current psr
- * 2. Make sure that all the upper 32 bits are off
- *
- * 3. Clear the interrupt enable and interrupt state collection bits
- * in the psr before updating the ipsr and iip.
- *
- * 4. Turn off the instruction, data and rse translation bits of the psr
- * and store the new value into ipsr
- * Also make sure that the interrupts are disabled.
- * Ensure that we are in little endian mode.
- * [psr.{rt, it, dt, i, be} = 0]
- *
- * 5. Get the physical address corresponding to the virtual address
- * of the next instruction bundle and put it in iip.
- * (Using magic numbers 24 and 40 in the deposint instruction since
- * the IA64_SDK code directly maps to lower 24bits as physical address
- * from a virtual address).
- *
- * 6. Do an rfi to move the values from ipsr to psr and iip to ip.
- */
-#define PHYSICAL_MODE_ENTER(temp1, temp2, start_addr, old_psr) \
- mov old_psr = psr; \
- ;; \
- dep old_psr = 0, old_psr, 32, 32; \
- \
- mov ar.rsc = 0 ; \
- ;; \
- srlz.d; \
- mov temp2 = ar.bspstore; \
- ;; \
- DATA_VA_TO_PA(temp2); \
- ;; \
- mov temp1 = ar.rnat; \
- ;; \
- mov ar.bspstore = temp2; \
- ;; \
- mov ar.rnat = temp1; \
- mov temp1 = psr; \
- mov temp2 = psr; \
- ;; \
- \
- dep temp2 = 0, temp2, PSR_IC, 2; \
- ;; \
- mov psr.l = temp2; \
- ;; \
- srlz.d; \
- dep temp1 = 0, temp1, 32, 32; \
- ;; \
- dep temp1 = 0, temp1, PSR_IT, 1; \
- ;; \
- dep temp1 = 0, temp1, PSR_DT, 1; \
- ;; \
- dep temp1 = 0, temp1, PSR_RT, 1; \
- ;; \
- dep temp1 = 0, temp1, PSR_I, 1; \
- ;; \
- dep temp1 = 0, temp1, PSR_IC, 1; \
- ;; \
- dep temp1 = -1, temp1, PSR_MC, 1; \
- ;; \
- mov cr.ipsr = temp1; \
- ;; \
- LOAD_PHYSICAL(p0, temp2, start_addr); \
- ;; \
- mov cr.iip = temp2; \
- mov cr.ifs = r0; \
- DATA_VA_TO_PA(sp); \
- DATA_VA_TO_PA(gp); \
- ;; \
- srlz.i; \
- ;; \
- nop 1; \
- nop 2; \
- nop 1; \
- nop 2; \
- rfi; \
- ;;
-
-/*
- * This macro jumps to the instruction at the given virtual address
- * and starts execution in virtual mode with all the address
- * translations turned on.
- * 1. Get the old saved psr
- *
- * 2. Clear the interrupt state collection bit in the current psr.
- *
- * 3. Set the instruction translation bit back in the old psr
- * Note we have to do this since we are right now saving only the
- * lower 32-bits of old psr.(Also the old psr has the data and
- * rse translation bits on)
- *
- * 4. Set ipsr to this old_psr with "it" bit set and "bn" = 1.
- *
- * 5. Reset the current thread pointer (r13).
- *
- * 6. Set iip to the virtual address of the next instruction bundle.
- *
- * 7. Do an rfi to move ipsr to psr and iip to ip.
- */
-
-#define VIRTUAL_MODE_ENTER(temp1, temp2, start_addr, old_psr) \
- mov temp2 = psr; \
- ;; \
- mov old_psr = temp2; \
- ;; \
- dep temp2 = 0, temp2, PSR_IC, 2; \
- ;; \
- mov psr.l = temp2; \
- mov ar.rsc = 0; \
- ;; \
- srlz.d; \
- mov r13 = ar.k6; \
- mov temp2 = ar.bspstore; \
- ;; \
- DATA_PA_TO_VA(temp2,temp1); \
- ;; \
- mov temp1 = ar.rnat; \
- ;; \
- mov ar.bspstore = temp2; \
- ;; \
- mov ar.rnat = temp1; \
- ;; \
- mov temp1 = old_psr; \
- ;; \
- mov temp2 = 1; \
- ;; \
- dep temp1 = temp2, temp1, PSR_IC, 1; \
- ;; \
- dep temp1 = temp2, temp1, PSR_IT, 1; \
- ;; \
- dep temp1 = temp2, temp1, PSR_DT, 1; \
- ;; \
- dep temp1 = temp2, temp1, PSR_RT, 1; \
- ;; \
- dep temp1 = temp2, temp1, PSR_BN, 1; \
- ;; \
- \
- mov cr.ipsr = temp1; \
- movl temp2 = start_addr; \
- ;; \
- mov cr.iip = temp2; \
- movl gp = __gp \
- ;; \
- DATA_PA_TO_VA(sp, temp1); \
- srlz.i; \
- ;; \
- nop 1; \
- nop 2; \
- nop 1; \
- rfi \
- ;;
-
-/*
- * The MCA and INIT stacks in struct ia64_mca_cpu look like normal kernel
- * stacks, except that the SAL/OS state and a switch_stack are stored near the
- * top of the MCA/INIT stack. To support concurrent entry to MCA or INIT, as
- * well as MCA over INIT, each event needs its own SAL/OS state. All entries
- * are 16 byte aligned.
- *
- * +---------------------------+
- * | pt_regs |
- * +---------------------------+
- * | switch_stack |
- * +---------------------------+
- * | SAL/OS state |
- * +---------------------------+
- * | 16 byte scratch area |
- * +---------------------------+ <-------- SP at start of C MCA handler
- * | ..... |
- * +---------------------------+
- * | RBS for MCA/INIT handler |
- * +---------------------------+
- * | struct task for MCA/INIT |
- * +---------------------------+ <-------- Bottom of MCA/INIT stack
- */
-
-#define ALIGN16(x) ((x)&~15)
-#define MCA_PT_REGS_OFFSET ALIGN16(KERNEL_STACK_SIZE-IA64_PT_REGS_SIZE)
-#define MCA_SWITCH_STACK_OFFSET ALIGN16(MCA_PT_REGS_OFFSET-IA64_SWITCH_STACK_SIZE)
-#define MCA_SOS_OFFSET ALIGN16(MCA_SWITCH_STACK_OFFSET-IA64_SAL_OS_STATE_SIZE)
-#define MCA_SP_OFFSET ALIGN16(MCA_SOS_OFFSET-16)
-
-#endif /* _ASM_IA64_MCA_ASM_H */
diff --git a/arch/ia64/include/asm/meminit.h b/arch/ia64/include/asm/meminit.h
deleted file mode 100644
index f1d5bf2ba847..000000000000
--- a/arch/ia64/include/asm/meminit.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef meminit_h
-#define meminit_h
-
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-
-/*
- * Entries defined so far:
- * - boot param structure itself
- * - memory map
- * - initrd (optional)
- * - command line string
- * - kernel code & data
- * - crash dumping code reserved region
- * - Kernel memory map built from EFI memory map
- * - ELF core header
- *
- * More could be added if necessary
- */
-#define IA64_MAX_RSVD_REGIONS 9
-
-struct rsvd_region {
- u64 start; /* virtual address of beginning of element */
- u64 end; /* virtual address of end of element + 1 */
-};
-
-extern struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1];
-
-extern void find_memory (void);
-extern void reserve_memory (void);
-extern void find_initrd (void);
-extern int filter_rsvd_memory (u64 start, u64 end, void *arg);
-extern int filter_memory (u64 start, u64 end, void *arg);
-extern unsigned long efi_memmap_init(u64 *s, u64 *e);
-extern int find_max_min_low_pfn (u64, u64, void *);
-
-extern unsigned long vmcore_find_descriptor_size(unsigned long address);
-
-/*
- * For rounding an address to the next IA64_GRANULE_SIZE or order
- */
-#define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1))
-#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
-
-#ifdef CONFIG_NUMA
- extern void call_pernode_memory (unsigned long start, unsigned long len, void *func);
-#else
-# define call_pernode_memory(start, len, func) (*func)(start, len, 0)
-#endif
-
-#define IGNORE_PFN0 1 /* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */
-
-extern int register_active_ranges(u64 start, u64 len, int nid);
-
-#endif /* meminit_h */
diff --git a/arch/ia64/include/asm/mman.h b/arch/ia64/include/asm/mman.h
deleted file mode 100644
index 15cf100add0e..000000000000
--- a/arch/ia64/include/asm/mman.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Based on <asm-i386/mman.h>.
- *
- * Modified 1998-2000, 2002
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-#ifndef _ASM_IA64_MMAN_H
-#define _ASM_IA64_MMAN_H
-
-#include <uapi/asm/mman.h>
-
-#ifndef __ASSEMBLY__
-#define arch_mmap_check ia64_mmap_check
-int ia64_mmap_check(unsigned long addr, unsigned long len,
- unsigned long flags);
-#endif
-#endif /* _ASM_IA64_MMAN_H */
diff --git a/arch/ia64/include/asm/mmiowb.h b/arch/ia64/include/asm/mmiowb.h
deleted file mode 100644
index d67aab4ea3b4..000000000000
--- a/arch/ia64/include/asm/mmiowb.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef _ASM_IA64_MMIOWB_H
-#define _ASM_IA64_MMIOWB_H
-
-/**
- * mmiowb - I/O write barrier
- *
- * Ensure ordering of I/O space writes. This will make sure that writes
- * following the barrier will arrive after all previous writes. For most
- * ia64 platforms, this is a simple 'mf.a' instruction.
- */
-#define mmiowb() ia64_mfa()
-
-#include <asm-generic/mmiowb.h>
-
-#endif /* _ASM_IA64_MMIOWB_H */
diff --git a/arch/ia64/include/asm/mmu.h b/arch/ia64/include/asm/mmu.h
deleted file mode 100644
index f75f44f531c2..000000000000
--- a/arch/ia64/include/asm/mmu.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __MMU_H
-#define __MMU_H
-
-/*
- * Type for a context number. We declare it volatile to ensure proper
- * ordering when it's accessed outside of spinlock'd critical sections
- * (e.g., as done in activate_mm() and init_new_context()).
- */
-typedef volatile unsigned long mm_context_t;
-
-typedef unsigned long nv_mm_context_t;
-
-#endif
diff --git a/arch/ia64/include/asm/mmu_context.h b/arch/ia64/include/asm/mmu_context.h
deleted file mode 100644
index 06257e355d00..000000000000
--- a/arch/ia64/include/asm/mmu_context.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_MMU_CONTEXT_H
-#define _ASM_IA64_MMU_CONTEXT_H
-
-/*
- * Copyright (C) 1998-2002 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-/*
- * Routines to manage the allocation of task context numbers. Task context
- * numbers are used to reduce or eliminate the need to perform TLB flushes
- * due to context switches. Context numbers are implemented using ia-64
- * region ids. Since the IA-64 TLB does not consider the region number when
- * performing a TLB lookup, we need to assign a unique region id to each
- * region in a process. We use the least significant three bits in aregion
- * id for this purpose.
- */
-
-#define IA64_REGION_ID_KERNEL 0 /* the kernel's region id (tlb.c depends on this being 0) */
-
-#define ia64_rid(ctx,addr) (((ctx) << 3) | (addr >> 61))
-
-# include <asm/page.h>
-# ifndef __ASSEMBLY__
-
-#include <linux/compiler.h>
-#include <linux/percpu.h>
-#include <linux/sched.h>
-#include <linux/mm_types.h>
-#include <linux/spinlock.h>
-
-#include <asm/processor.h>
-#include <asm-generic/mm_hooks.h>
-
-struct ia64_ctx {
- spinlock_t lock;
- unsigned int next; /* next context number to use */
- unsigned int limit; /* available free range */
- unsigned int max_ctx; /* max. context value supported by all CPUs */
- /* call wrap_mmu_context when next >= max */
- unsigned long *bitmap; /* bitmap size is max_ctx+1 */
- unsigned long *flushmap;/* pending rid to be flushed */
-};
-
-extern struct ia64_ctx ia64_ctx;
-DECLARE_PER_CPU(u8, ia64_need_tlb_flush);
-
-extern void mmu_context_init (void);
-extern void wrap_mmu_context (struct mm_struct *mm);
-
-/*
- * When the context counter wraps around all TLBs need to be flushed because
- * an old context number might have been reused. This is signalled by the
- * ia64_need_tlb_flush per-CPU variable, which is checked in the routine
- * below. Called by activate_mm(). <efocht@ess.nec.de>
- */
-static inline void
-delayed_tlb_flush (void)
-{
- extern void local_flush_tlb_all (void);
- unsigned long flags;
-
- if (unlikely(__ia64_per_cpu_var(ia64_need_tlb_flush))) {
- spin_lock_irqsave(&ia64_ctx.lock, flags);
- if (__ia64_per_cpu_var(ia64_need_tlb_flush)) {
- local_flush_tlb_all();
- __ia64_per_cpu_var(ia64_need_tlb_flush) = 0;
- }
- spin_unlock_irqrestore(&ia64_ctx.lock, flags);
- }
-}
-
-static inline nv_mm_context_t
-get_mmu_context (struct mm_struct *mm)
-{
- unsigned long flags;
- nv_mm_context_t context = mm->context;
-
- if (likely(context))
- goto out;
-
- spin_lock_irqsave(&ia64_ctx.lock, flags);
- /* re-check, now that we've got the lock: */
- context = mm->context;
- if (context == 0) {
- cpumask_clear(mm_cpumask(mm));
- if (ia64_ctx.next >= ia64_ctx.limit) {
- ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
- ia64_ctx.max_ctx, ia64_ctx.next);
- ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
- ia64_ctx.max_ctx, ia64_ctx.next);
- if (ia64_ctx.next >= ia64_ctx.max_ctx)
- wrap_mmu_context(mm);
- }
- mm->context = context = ia64_ctx.next++;
- __set_bit(context, ia64_ctx.bitmap);
- }
- spin_unlock_irqrestore(&ia64_ctx.lock, flags);
-out:
- /*
- * Ensure we're not starting to use "context" before any old
- * uses of it are gone from our TLB.
- */
- delayed_tlb_flush();
-
- return context;
-}
-
-/*
- * Initialize context number to some sane value. MM is guaranteed to be a
- * brand-new address-space, so no TLB flushing is needed, ever.
- */
-#define init_new_context init_new_context
-static inline int
-init_new_context (struct task_struct *p, struct mm_struct *mm)
-{
- mm->context = 0;
- return 0;
-}
-
-static inline void
-reload_context (nv_mm_context_t context)
-{
- unsigned long rid;
- unsigned long rid_incr = 0;
- unsigned long rr0, rr1, rr2, rr3, rr4;
-
-#ifdef CONFIG_HUGETLB_PAGE
- unsigned long old_rr4;
- old_rr4 = ia64_get_rr(RGN_BASE(RGN_HPAGE));
-#endif
- rid = context << 3; /* make space for encoding the region number */
- rid_incr = 1 << 8;
-
- /* encode the region id, preferred page size, and VHPT enable bit: */
- rr0 = (rid << 8) | (PAGE_SHIFT << 2) | 1;
- rr1 = rr0 + 1*rid_incr;
- rr2 = rr0 + 2*rid_incr;
- rr3 = rr0 + 3*rid_incr;
- rr4 = rr0 + 4*rid_incr;
-#ifdef CONFIG_HUGETLB_PAGE
- rr4 = (rr4 & (~(0xfcUL))) | (old_rr4 & 0xfc);
-
-# if RGN_HPAGE != 4
-# error "reload_context assumes RGN_HPAGE is 4"
-# endif
-#endif
-
- ia64_set_rr0_to_rr4(rr0, rr1, rr2, rr3, rr4);
- ia64_srlz_i(); /* srlz.i implies srlz.d */
-}
-
-/*
- * Must be called with preemption off
- */
-static inline void
-activate_context (struct mm_struct *mm)
-{
- nv_mm_context_t context;
-
- do {
- context = get_mmu_context(mm);
- if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
- cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
- reload_context(context);
- /*
- * in the unlikely event of a TLB-flush by another thread,
- * redo the load.
- */
- } while (unlikely(context != mm->context));
-}
-
-/*
- * Switch from address space PREV to address space NEXT.
- */
-#define activate_mm activate_mm
-static inline void
-activate_mm (struct mm_struct *prev, struct mm_struct *next)
-{
- /*
- * We may get interrupts here, but that's OK because interrupt
- * handlers cannot touch user-space.
- */
- ia64_set_kr(IA64_KR_PT_BASE, __pa(next->pgd));
- activate_context(next);
-}
-
-#define switch_mm(prev_mm,next_mm,next_task) activate_mm(prev_mm, next_mm)
-
-#include <asm-generic/mmu_context.h>
-
-# endif /* ! __ASSEMBLY__ */
-#endif /* _ASM_IA64_MMU_CONTEXT_H */
diff --git a/arch/ia64/include/asm/mmzone.h b/arch/ia64/include/asm/mmzone.h
deleted file mode 100644
index 767201f66c93..000000000000
--- a/arch/ia64/include/asm/mmzone.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000,2003 Silicon Graphics, Inc. All rights reserved.
- * Copyright (c) 2002 NEC Corp.
- * Copyright (c) 2002 Erich Focht <efocht@ess.nec.de>
- * Copyright (c) 2002 Kimio Suganuma <k-suganuma@da.jp.nec.com>
- */
-#ifndef _ASM_IA64_MMZONE_H
-#define _ASM_IA64_MMZONE_H
-
-#include <linux/numa.h>
-#include <asm/page.h>
-#include <asm/meminit.h>
-
-#ifdef CONFIG_NUMA
-
-static inline int pfn_to_nid(unsigned long pfn)
-{
- extern int paddr_to_nid(unsigned long);
- int nid = paddr_to_nid(pfn << PAGE_SHIFT);
- if (nid < 0)
- return 0;
- else
- return nid;
-}
-
-#define MAX_PHYSNODE_ID 2048
-#endif /* CONFIG_NUMA */
-
-#define NR_NODE_MEMBLKS (MAX_NUMNODES * 4)
-
-#endif /* _ASM_IA64_MMZONE_H */
diff --git a/arch/ia64/include/asm/module.h b/arch/ia64/include/asm/module.h
deleted file mode 100644
index 7271b9c5fc76..000000000000
--- a/arch/ia64/include/asm/module.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_MODULE_H
-#define _ASM_IA64_MODULE_H
-
-#include <asm-generic/module.h>
-
-/*
- * IA-64-specific support for kernel module loader.
- *
- * Copyright (C) 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-struct elf64_shdr; /* forward declration */
-
-struct mod_arch_specific {
- /* Used only at module load time. */
- struct elf64_shdr *core_plt; /* core PLT section */
- struct elf64_shdr *init_plt; /* init PLT section */
- struct elf64_shdr *got; /* global offset table */
- struct elf64_shdr *opd; /* official procedure descriptors */
- struct elf64_shdr *unwind; /* unwind-table section */
- unsigned long gp; /* global-pointer for module */
- unsigned int next_got_entry; /* index of next available got entry */
-
- /* Used at module run and cleanup time. */
- void *core_unw_table; /* core unwind-table cookie returned by unwinder */
- void *init_unw_table; /* init unwind-table cookie returned by unwinder */
- void *opd_addr; /* symbolize uses .opd to get to actual function */
- unsigned long opd_size;
-};
-
-#define ARCH_SHF_SMALL SHF_IA_64_SHORT
-
-#endif /* _ASM_IA64_MODULE_H */
diff --git a/arch/ia64/include/asm/module.lds.h b/arch/ia64/include/asm/module.lds.h
deleted file mode 100644
index eff68f362793..000000000000
--- a/arch/ia64/include/asm/module.lds.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-SECTIONS {
- /* Group unwind sections into a single section: */
- .IA_64.unwind_info : { *(.IA_64.unwind_info*) }
- .IA_64.unwind : { *(.IA_64.unwind*) }
- /*
- * Create place-holder sections to hold the PLTs, GOT, and
- * official procedure-descriptors (.opd).
- */
- .core.plt : { BYTE(0) }
- .init.plt : { BYTE(0) }
- .got : { BYTE(0) }
- .opd : { BYTE(0) }
-}
diff --git a/arch/ia64/include/asm/msidef.h b/arch/ia64/include/asm/msidef.h
deleted file mode 100644
index 18d0e4226748..000000000000
--- a/arch/ia64/include/asm/msidef.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IA64_MSI_DEF_H
-#define _IA64_MSI_DEF_H
-
-/*
- * Shifts for APIC-based data
- */
-
-#define MSI_DATA_VECTOR_SHIFT 0
-#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
-#define MSI_DATA_VECTOR_MASK 0xffffff00
-
-#define MSI_DATA_DELIVERY_MODE_SHIFT 8
-#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_MODE_SHIFT)
-#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_MODE_SHIFT)
-
-#define MSI_DATA_LEVEL_SHIFT 14
-#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
-#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
-
-#define MSI_DATA_TRIGGER_SHIFT 15
-#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
-#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
-
-/*
- * Shift/mask fields for APIC-based bus address
- */
-
-#define MSI_ADDR_DEST_ID_SHIFT 4
-#define MSI_ADDR_HEADER 0xfee00000
-
-#define MSI_ADDR_DEST_ID_MASK 0xfff0000f
-#define MSI_ADDR_DEST_ID_CPU(cpu) ((cpu) << MSI_ADDR_DEST_ID_SHIFT)
-
-#define MSI_ADDR_DEST_MODE_SHIFT 2
-#define MSI_ADDR_DEST_MODE_PHYS (0 << MSI_ADDR_DEST_MODE_SHIFT)
-#define MSI_ADDR_DEST_MODE_LOGIC (1 << MSI_ADDR_DEST_MODE_SHIFT)
-
-#define MSI_ADDR_REDIRECTION_SHIFT 3
-#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
-#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
-
-#endif/* _IA64_MSI_DEF_H */
diff --git a/arch/ia64/include/asm/native/inst.h b/arch/ia64/include/asm/native/inst.h
deleted file mode 100644
index e08662396029..000000000000
--- a/arch/ia64/include/asm/native/inst.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/******************************************************************************
- * arch/ia64/include/asm/native/inst.h
- *
- * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
- * VA Linux Systems Japan K.K.
- */
-
-#define DO_SAVE_MIN IA64_NATIVE_DO_SAVE_MIN
-
-#define MOV_FROM_IFA(reg) \
- mov reg = cr.ifa
-
-#define MOV_FROM_ITIR(reg) \
- mov reg = cr.itir
-
-#define MOV_FROM_ISR(reg) \
- mov reg = cr.isr
-
-#define MOV_FROM_IHA(reg) \
- mov reg = cr.iha
-
-#define MOV_FROM_IPSR(pred, reg) \
-(pred) mov reg = cr.ipsr
-
-#define MOV_FROM_IIM(reg) \
- mov reg = cr.iim
-
-#define MOV_FROM_IIP(reg) \
- mov reg = cr.iip
-
-#define MOV_FROM_IVR(reg, clob) \
- mov reg = cr.ivr
-
-#define MOV_FROM_PSR(pred, reg, clob) \
-(pred) mov reg = psr
-
-#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \
-(pred) mov reg = ar.itc
-
-#define MOV_TO_IFA(reg, clob) \
- mov cr.ifa = reg
-
-#define MOV_TO_ITIR(pred, reg, clob) \
-(pred) mov cr.itir = reg
-
-#define MOV_TO_IHA(pred, reg, clob) \
-(pred) mov cr.iha = reg
-
-#define MOV_TO_IPSR(pred, reg, clob) \
-(pred) mov cr.ipsr = reg
-
-#define MOV_TO_IFS(pred, reg, clob) \
-(pred) mov cr.ifs = reg
-
-#define MOV_TO_IIP(reg, clob) \
- mov cr.iip = reg
-
-#define MOV_TO_KR(kr, reg, clob0, clob1) \
- mov IA64_KR(kr) = reg
-
-#define ITC_I(pred, reg, clob) \
-(pred) itc.i reg
-
-#define ITC_D(pred, reg, clob) \
-(pred) itc.d reg
-
-#define ITC_I_AND_D(pred_i, pred_d, reg, clob) \
-(pred_i) itc.i reg; \
-(pred_d) itc.d reg
-
-#define THASH(pred, reg0, reg1, clob) \
-(pred) thash reg0 = reg1
-
-#define SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(clob0, clob1) \
- ssm psr.ic | PSR_DEFAULT_BITS \
- ;; \
- srlz.i /* guarantee that interruption collectin is on */ \
- ;;
-
-#define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1) \
- ssm psr.ic \
- ;; \
- srlz.d
-
-#define RSM_PSR_IC(clob) \
- rsm psr.ic
-
-#define SSM_PSR_I(pred, pred_clob, clob) \
-(pred) ssm psr.i
-
-#define RSM_PSR_I(pred, clob0, clob1) \
-(pred) rsm psr.i
-
-#define RSM_PSR_I_IC(clob0, clob1, clob2) \
- rsm psr.i | psr.ic
-
-#define RSM_PSR_DT \
- rsm psr.dt
-
-#define RSM_PSR_BE_I(clob0, clob1) \
- rsm psr.be | psr.i
-
-#define SSM_PSR_DT_AND_SRLZ_I \
- ssm psr.dt \
- ;; \
- srlz.i
-
-#define BSW_0(clob0, clob1, clob2) \
- bsw.0
-
-#define BSW_1(clob0, clob1) \
- bsw.1
-
-#define COVER \
- cover
-
-#define RFI \
- rfi
diff --git a/arch/ia64/include/asm/native/irq.h b/arch/ia64/include/asm/native/irq.h
deleted file mode 100644
index aa74915f8aa2..000000000000
--- a/arch/ia64/include/asm/native/irq.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/******************************************************************************
- * arch/ia64/include/asm/native/irq.h
- *
- * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
- * VA Linux Systems Japan K.K.
- */
-
-#ifndef _ASM_IA64_NATIVE_IRQ_H
-#define _ASM_IA64_NATIVE_IRQ_H
-
-#define NR_VECTORS 256
-
-#if (NR_VECTORS + 32 * NR_CPUS) < 1024
-#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
-#else
-#define IA64_NATIVE_NR_IRQS 1024
-#endif
-
-#endif /* _ASM_IA64_NATIVE_IRQ_H */
diff --git a/arch/ia64/include/asm/native/patchlist.h b/arch/ia64/include/asm/native/patchlist.h
deleted file mode 100644
index f13e7675758c..000000000000
--- a/arch/ia64/include/asm/native/patchlist.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/******************************************************************************
- * arch/ia64/include/asm/native/inst.h
- *
- * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
- * VA Linux Systems Japan K.K.
- */
-
-#define __paravirt_start_gate_fsyscall_patchlist \
- __ia64_native_start_gate_fsyscall_patchlist
-#define __paravirt_end_gate_fsyscall_patchlist \
- __ia64_native_end_gate_fsyscall_patchlist
-#define __paravirt_start_gate_brl_fsys_bubble_down_patchlist \
- __ia64_native_start_gate_brl_fsys_bubble_down_patchlist
-#define __paravirt_end_gate_brl_fsys_bubble_down_patchlist \
- __ia64_native_end_gate_brl_fsys_bubble_down_patchlist
-#define __paravirt_start_gate_vtop_patchlist \
- __ia64_native_start_gate_vtop_patchlist
-#define __paravirt_end_gate_vtop_patchlist \
- __ia64_native_end_gate_vtop_patchlist
-#define __paravirt_start_gate_mckinley_e9_patchlist \
- __ia64_native_start_gate_mckinley_e9_patchlist
-#define __paravirt_end_gate_mckinley_e9_patchlist \
- __ia64_native_end_gate_mckinley_e9_patchlist
diff --git a/arch/ia64/include/asm/nodedata.h b/arch/ia64/include/asm/nodedata.h
deleted file mode 100644
index 2fb337b0e9b7..000000000000
--- a/arch/ia64/include/asm/nodedata.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000 Silicon Graphics, Inc. All rights reserved.
- * Copyright (c) 2002 NEC Corp.
- * Copyright (c) 2002 Erich Focht <efocht@ess.nec.de>
- * Copyright (c) 2002 Kimio Suganuma <k-suganuma@da.jp.nec.com>
- */
-#ifndef _ASM_IA64_NODEDATA_H
-#define _ASM_IA64_NODEDATA_H
-
-#include <linux/numa.h>
-
-#include <asm/percpu.h>
-#include <asm/mmzone.h>
-
-#ifdef CONFIG_NUMA
-
-/*
- * Node Data. One of these structures is located on each node of a NUMA system.
- */
-
-struct pglist_data;
-struct ia64_node_data {
- short active_cpu_count;
- short node;
- struct pglist_data *pg_data_ptrs[MAX_NUMNODES];
-};
-
-
-/*
- * Return a pointer to the node_data structure for the executing cpu.
- */
-#define local_node_data (local_cpu_data->node_data)
-
-/*
- * Given a node id, return a pointer to the pg_data_t for the node.
- *
- * NODE_DATA - should be used in all code not related to system
- * initialization. It uses pernode data structures to minimize
- * offnode memory references. However, these structure are not
- * present during boot. This macro can be used once cpu_init
- * completes.
- */
-#define NODE_DATA(nid) (local_node_data->pg_data_ptrs[nid])
-
-/*
- * LOCAL_DATA_ADDR - This is to calculate the address of other node's
- * "local_node_data" at hot-plug phase. The local_node_data
- * is pointed by per_cpu_page. Kernel usually use it for
- * just executing cpu. However, when new node is hot-added,
- * the addresses of local data for other nodes are necessary
- * to update all of them.
- */
-#define LOCAL_DATA_ADDR(pgdat) \
- ((struct ia64_node_data *)((u64)(pgdat) + \
- L1_CACHE_ALIGN(sizeof(struct pglist_data))))
-
-#endif /* CONFIG_NUMA */
-
-#endif /* _ASM_IA64_NODEDATA_H */
diff --git a/arch/ia64/include/asm/numa.h b/arch/ia64/include/asm/numa.h
deleted file mode 100644
index c5c253cb9bd6..000000000000
--- a/arch/ia64/include/asm/numa.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * This file contains NUMA specific prototypes and definitions.
- *
- * 2002/08/05 Erich Focht <efocht@ess.nec.de>
- *
- */
-#ifndef _ASM_IA64_NUMA_H
-#define _ASM_IA64_NUMA_H
-
-
-#ifdef CONFIG_NUMA
-
-#include <linux/cache.h>
-#include <linux/cpumask.h>
-#include <linux/numa.h>
-#include <linux/smp.h>
-#include <linux/threads.h>
-
-#include <asm/mmzone.h>
-
-extern u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
-extern cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
-extern pg_data_t *pgdat_list[MAX_NUMNODES];
-
-/* Stuff below this line could be architecture independent */
-
-extern int num_node_memblks; /* total number of memory chunks */
-
-/*
- * List of node memory chunks. Filled when parsing SRAT table to
- * obtain information about memory nodes.
-*/
-
-struct node_memblk_s {
- unsigned long start_paddr;
- unsigned long size;
- int nid; /* which logical node contains this chunk? */
- int bank; /* which mem bank on this node */
-};
-
-struct node_cpuid_s {
- u16 phys_id; /* id << 8 | eid */
- int nid; /* logical node containing this CPU */
-};
-
-extern struct node_memblk_s node_memblk[NR_NODE_MEMBLKS];
-extern struct node_cpuid_s node_cpuid[NR_CPUS];
-
-/*
- * ACPI 2.0 SLIT (System Locality Information Table)
- * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
- *
- * This is a matrix with "distances" between nodes, they should be
- * proportional to the memory access latency ratios.
- */
-
-extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
-#define slit_distance(from,to) (numa_slit[(from) * MAX_NUMNODES + (to)])
-extern int __node_distance(int from, int to);
-#define node_distance(from,to) __node_distance(from, to)
-
-extern int paddr_to_nid(unsigned long paddr);
-
-#define local_nodeid (cpu_to_node_map[smp_processor_id()])
-
-#define numa_off 0
-
-extern void map_cpu_to_node(int cpu, int nid);
-extern void unmap_cpu_from_node(int cpu, int nid);
-extern void numa_clear_node(int cpu);
-
-#else /* !CONFIG_NUMA */
-#define map_cpu_to_node(cpu, nid) do{}while(0)
-#define unmap_cpu_from_node(cpu, nid) do{}while(0)
-#define paddr_to_nid(addr) 0
-#define numa_clear_node(cpu) do { } while (0)
-#endif /* CONFIG_NUMA */
-
-#endif /* _ASM_IA64_NUMA_H */
diff --git a/arch/ia64/include/asm/page.h b/arch/ia64/include/asm/page.h
deleted file mode 100644
index 310b09c3342d..000000000000
--- a/arch/ia64/include/asm/page.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_PAGE_H
-#define _ASM_IA64_PAGE_H
-/*
- * Pagetable related stuff.
- *
- * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <asm/intrinsics.h>
-#include <asm/types.h>
-
-/*
- * The top three bits of an IA64 address are its Region Number.
- * Different regions are assigned to different purposes.
- */
-#define RGN_SHIFT (61)
-#define RGN_BASE(r) (__IA64_UL_CONST(r)<<RGN_SHIFT)
-#define RGN_BITS (RGN_BASE(-1))
-
-#define RGN_KERNEL 7 /* Identity mapped region */
-#define RGN_UNCACHED 6 /* Identity mapped I/O region */
-#define RGN_GATE 5 /* Gate page, Kernel text, etc */
-#define RGN_HPAGE 4 /* For Huge TLB pages */
-
-/*
- * PAGE_SHIFT determines the actual kernel page size.
- */
-#if defined(CONFIG_IA64_PAGE_SIZE_4KB)
-# define PAGE_SHIFT 12
-#elif defined(CONFIG_IA64_PAGE_SIZE_8KB)
-# define PAGE_SHIFT 13
-#elif defined(CONFIG_IA64_PAGE_SIZE_16KB)
-# define PAGE_SHIFT 14
-#elif defined(CONFIG_IA64_PAGE_SIZE_64KB)
-# define PAGE_SHIFT 16
-#else
-# error Unsupported page size!
-#endif
-
-#define PAGE_SIZE (__IA64_UL_CONST(1) << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE - 1))
-
-#define PERCPU_PAGE_SHIFT 18 /* log2() of max. size of per-CPU area */
-#define PERCPU_PAGE_SIZE (__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT)
-
-
-#ifdef CONFIG_HUGETLB_PAGE
-# define HPAGE_REGION_BASE RGN_BASE(RGN_HPAGE)
-# define HPAGE_SHIFT hpage_shift
-# define HPAGE_SHIFT_DEFAULT 28 /* check ia64 SDM for architecture supported size */
-# define HPAGE_SIZE (__IA64_UL_CONST(1) << HPAGE_SHIFT)
-# define HPAGE_MASK (~(HPAGE_SIZE - 1))
-
-# define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-#endif /* CONFIG_HUGETLB_PAGE */
-
-#ifdef __ASSEMBLY__
-# define __pa(x) ((x) - PAGE_OFFSET)
-# define __va(x) ((x) + PAGE_OFFSET)
-#else /* !__ASSEMBLY */
-# define STRICT_MM_TYPECHECKS
-
-extern void clear_page (void *page);
-extern void copy_page (void *to, void *from);
-
-/*
- * clear_user_page() and copy_user_page() can't be inline functions because
- * flush_dcache_page() can't be defined until later...
- */
-#define clear_user_page(addr, vaddr, page) \
-do { \
- clear_page(addr); \
- flush_dcache_page(page); \
-} while (0)
-
-#define copy_user_page(to, from, vaddr, page) \
-do { \
- copy_page((to), (from)); \
- flush_dcache_page(page); \
-} while (0)
-
-
-#define vma_alloc_zeroed_movable_folio(vma, vaddr) \
-({ \
- struct folio *folio = vma_alloc_folio( \
- GFP_HIGHUSER_MOVABLE | __GFP_ZERO, 0, vma, vaddr, false); \
- if (folio) \
- flush_dcache_folio(folio); \
- folio; \
-})
-
-#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
-
-#include <asm-generic/memory_model.h>
-
-#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
-#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
-
-typedef union ia64_va {
- struct {
- unsigned long off : 61; /* intra-region offset */
- unsigned long reg : 3; /* region number */
- } f;
- unsigned long l;
- void *p;
-} ia64_va;
-
-/*
- * Note: These macros depend on the fact that PAGE_OFFSET has all
- * region bits set to 1 and all other bits set to zero. They are
- * expressed in this way to ensure they result in a single "dep"
- * instruction.
- */
-#define __pa(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg = 0; _v.l;})
-#define __va(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg = -1; _v.p;})
-
-#define REGION_NUMBER(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg;})
-#define REGION_OFFSET(x) ({ia64_va _v; _v.l = (long) (x); _v.f.off;})
-
-#ifdef CONFIG_HUGETLB_PAGE
-# define htlbpage_to_page(x) (((unsigned long) REGION_NUMBER(x) << 61) \
- | (REGION_OFFSET(x) >> (HPAGE_SHIFT-PAGE_SHIFT)))
-# define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
-extern unsigned int hpage_shift;
-#endif
-
-static __inline__ int
-get_order (unsigned long size)
-{
- long double d = size - 1;
- long order;
-
- order = ia64_getf_exp(d);
- order = order - PAGE_SHIFT - 0xffff + 1;
- if (order < 0)
- order = 0;
- return order;
-}
-
-#endif /* !__ASSEMBLY__ */
-
-#ifdef STRICT_MM_TYPECHECKS
- /*
- * These are used to make use of C type-checking..
- */
- typedef struct { unsigned long pte; } pte_t;
- typedef struct { unsigned long pmd; } pmd_t;
-#if CONFIG_PGTABLE_LEVELS == 4
- typedef struct { unsigned long pud; } pud_t;
-#endif
- typedef struct { unsigned long pgd; } pgd_t;
- typedef struct { unsigned long pgprot; } pgprot_t;
- typedef struct page *pgtable_t;
-
-# define pte_val(x) ((x).pte)
-# define pmd_val(x) ((x).pmd)
-#if CONFIG_PGTABLE_LEVELS == 4
-# define pud_val(x) ((x).pud)
-#endif
-# define pgd_val(x) ((x).pgd)
-# define pgprot_val(x) ((x).pgprot)
-
-# define __pte(x) ((pte_t) { (x) } )
-# define __pmd(x) ((pmd_t) { (x) } )
-# define __pgprot(x) ((pgprot_t) { (x) } )
-
-#else /* !STRICT_MM_TYPECHECKS */
- /*
- * .. while these make it easier on the compiler
- */
-# ifndef __ASSEMBLY__
- typedef unsigned long pte_t;
- typedef unsigned long pmd_t;
- typedef unsigned long pgd_t;
- typedef unsigned long pgprot_t;
- typedef struct page *pgtable_t;
-# endif
-
-# define pte_val(x) (x)
-# define pmd_val(x) (x)
-# define pgd_val(x) (x)
-# define pgprot_val(x) (x)
-
-# define __pte(x) (x)
-# define __pgd(x) (x)
-# define __pgprot(x) (x)
-#endif /* !STRICT_MM_TYPECHECKS */
-
-#define PAGE_OFFSET RGN_BASE(RGN_KERNEL)
-
-#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC
-
-#define GATE_ADDR RGN_BASE(RGN_GATE)
-
-/*
- * 0xa000000000000000+2*PERCPU_PAGE_SIZE
- * - 0xa000000000000000+3*PERCPU_PAGE_SIZE remain unmapped (guard page)
- */
-#define KERNEL_START (GATE_ADDR+__IA64_UL_CONST(0x100000000))
-#define PERCPU_ADDR (-PERCPU_PAGE_SIZE)
-#define LOAD_OFFSET (KERNEL_START - KERNEL_TR_PAGE_SIZE)
-
-#define __HAVE_ARCH_GATE_AREA 1
-
-#endif /* _ASM_IA64_PAGE_H */
diff --git a/arch/ia64/include/asm/pal.h b/arch/ia64/include/asm/pal.h
deleted file mode 100644
index e6b652f9e45e..000000000000
--- a/arch/ia64/include/asm/pal.h
+++ /dev/null
@@ -1,1827 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_PAL_H
-#define _ASM_IA64_PAL_H
-
-/*
- * Processor Abstraction Layer definitions.
- *
- * This is based on Intel IA-64 Architecture Software Developer's Manual rev 1.0
- * chapter 11 IA-64 Processor Abstraction Layer
- *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999 Srinivasa Prasad Thirumalachar <sprasad@sprasad.engr.sgi.com>
- * Copyright (C) 2008 Silicon Graphics, Inc. (SGI)
- *
- * 99/10/01 davidm Make sure we pass zero for reserved parameters.
- * 00/03/07 davidm Updated pal_cache_flush() to be in sync with PAL v2.6.
- * 00/03/23 cfleck Modified processor min-state save area to match updated PAL & SAL info
- * 00/05/24 eranian Updated to latest PAL spec, fix structures bugs, added
- * 00/05/25 eranian Support for stack calls, and static physical calls
- * 00/06/18 eranian Support for stacked physical calls
- * 06/10/26 rja Support for Intel Itanium Architecture Software Developer's
- * Manual Rev 2.2 (Jan 2006)
- */
-
-/*
- * Note that some of these calls use a static-register only calling
- * convention which has nothing to do with the regular calling
- * convention.
- */
-#define PAL_CACHE_FLUSH 1 /* flush i/d cache */
-#define PAL_CACHE_INFO 2 /* get detailed i/d cache info */
-#define PAL_CACHE_INIT 3 /* initialize i/d cache */
-#define PAL_CACHE_SUMMARY 4 /* get summary of cache hierarchy */
-#define PAL_MEM_ATTRIB 5 /* list supported memory attributes */
-#define PAL_PTCE_INFO 6 /* purge TLB info */
-#define PAL_VM_INFO 7 /* return supported virtual memory features */
-#define PAL_VM_SUMMARY 8 /* return summary on supported vm features */
-#define PAL_BUS_GET_FEATURES 9 /* return processor bus interface features settings */
-#define PAL_BUS_SET_FEATURES 10 /* set processor bus features */
-#define PAL_DEBUG_INFO 11 /* get number of debug registers */
-#define PAL_FIXED_ADDR 12 /* get fixed component of processors's directed address */
-#define PAL_FREQ_BASE 13 /* base frequency of the platform */
-#define PAL_FREQ_RATIOS 14 /* ratio of processor, bus and ITC frequency */
-#define PAL_PERF_MON_INFO 15 /* return performance monitor info */
-#define PAL_PLATFORM_ADDR 16 /* set processor interrupt block and IO port space addr */
-#define PAL_PROC_GET_FEATURES 17 /* get configurable processor features & settings */
-#define PAL_PROC_SET_FEATURES 18 /* enable/disable configurable processor features */
-#define PAL_RSE_INFO 19 /* return rse information */
-#define PAL_VERSION 20 /* return version of PAL code */
-#define PAL_MC_CLEAR_LOG 21 /* clear all processor log info */
-#define PAL_MC_DRAIN 22 /* drain operations which could result in an MCA */
-#define PAL_MC_EXPECTED 23 /* set/reset expected MCA indicator */
-#define PAL_MC_DYNAMIC_STATE 24 /* get processor dynamic state */
-#define PAL_MC_ERROR_INFO 25 /* get processor MCA info and static state */
-#define PAL_MC_RESUME 26 /* Return to interrupted process */
-#define PAL_MC_REGISTER_MEM 27 /* Register memory for PAL to use during MCAs and inits */
-#define PAL_HALT 28 /* enter the low power HALT state */
-#define PAL_HALT_LIGHT 29 /* enter the low power light halt state*/
-#define PAL_COPY_INFO 30 /* returns info needed to relocate PAL */
-#define PAL_CACHE_LINE_INIT 31 /* init tags & data of cache line */
-#define PAL_PMI_ENTRYPOINT 32 /* register PMI memory entry points with the processor */
-#define PAL_ENTER_IA_32_ENV 33 /* enter IA-32 system environment */
-#define PAL_VM_PAGE_SIZE 34 /* return vm TC and page walker page sizes */
-
-#define PAL_MEM_FOR_TEST 37 /* get amount of memory needed for late processor test */
-#define PAL_CACHE_PROT_INFO 38 /* get i/d cache protection info */
-#define PAL_REGISTER_INFO 39 /* return AR and CR register information*/
-#define PAL_SHUTDOWN 40 /* enter processor shutdown state */
-#define PAL_PREFETCH_VISIBILITY 41 /* Make Processor Prefetches Visible */
-#define PAL_LOGICAL_TO_PHYSICAL 42 /* returns information on logical to physical processor mapping */
-#define PAL_CACHE_SHARED_INFO 43 /* returns information on caches shared by logical processor */
-#define PAL_GET_HW_POLICY 48 /* Get current hardware resource sharing policy */
-#define PAL_SET_HW_POLICY 49 /* Set current hardware resource sharing policy */
-#define PAL_VP_INFO 50 /* Information about virtual processor features */
-#define PAL_MC_HW_TRACKING 51 /* Hardware tracking status */
-
-#define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */
-#define PAL_HALT_INFO 257 /* return the low power capabilities of processor */
-#define PAL_TEST_PROC 258 /* perform late processor self-test */
-#define PAL_CACHE_READ 259 /* read tag & data of cacheline for diagnostic testing */
-#define PAL_CACHE_WRITE 260 /* write tag & data of cacheline for diagnostic testing */
-#define PAL_VM_TR_READ 261 /* read contents of translation register */
-#define PAL_GET_PSTATE 262 /* get the current P-state */
-#define PAL_SET_PSTATE 263 /* set the P-state */
-#define PAL_BRAND_INFO 274 /* Processor branding information */
-
-#define PAL_GET_PSTATE_TYPE_LASTSET 0
-#define PAL_GET_PSTATE_TYPE_AVGANDRESET 1
-#define PAL_GET_PSTATE_TYPE_AVGNORESET 2
-#define PAL_GET_PSTATE_TYPE_INSTANT 3
-
-#define PAL_MC_ERROR_INJECT 276 /* Injects processor error or returns injection capabilities */
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-#include <asm/fpu.h>
-#include <asm/intrinsics.h>
-
-/*
- * Data types needed to pass information into PAL procedures and
- * interpret information returned by them.
- */
-
-/* Return status from the PAL procedure */
-typedef s64 pal_status_t;
-
-#define PAL_STATUS_SUCCESS 0 /* No error */
-#define PAL_STATUS_UNIMPLEMENTED (-1) /* Unimplemented procedure */
-#define PAL_STATUS_EINVAL (-2) /* Invalid argument */
-#define PAL_STATUS_ERROR (-3) /* Error */
-#define PAL_STATUS_CACHE_INIT_FAIL (-4) /* Could not initialize the
- * specified level and type of
- * cache without sideeffects
- * and "restrict" was 1
- */
-#define PAL_STATUS_REQUIRES_MEMORY (-9) /* Call requires PAL memory buffer */
-
-/* Processor cache level in the hierarchy */
-typedef u64 pal_cache_level_t;
-#define PAL_CACHE_LEVEL_L0 0 /* L0 */
-#define PAL_CACHE_LEVEL_L1 1 /* L1 */
-#define PAL_CACHE_LEVEL_L2 2 /* L2 */
-
-
-/* Processor cache type at a particular level in the hierarchy */
-
-typedef u64 pal_cache_type_t;
-#define PAL_CACHE_TYPE_INSTRUCTION 1 /* Instruction cache */
-#define PAL_CACHE_TYPE_DATA 2 /* Data or unified cache */
-#define PAL_CACHE_TYPE_INSTRUCTION_DATA 3 /* Both Data & Instruction */
-
-
-#define PAL_CACHE_FLUSH_INVALIDATE 1 /* Invalidate clean lines */
-#define PAL_CACHE_FLUSH_CHK_INTRS 2 /* check for interrupts/mc while flushing */
-
-/* Processor cache line size in bytes */
-typedef int pal_cache_line_size_t;
-
-/* Processor cache line state */
-typedef u64 pal_cache_line_state_t;
-#define PAL_CACHE_LINE_STATE_INVALID 0 /* Invalid */
-#define PAL_CACHE_LINE_STATE_SHARED 1 /* Shared */
-#define PAL_CACHE_LINE_STATE_EXCLUSIVE 2 /* Exclusive */
-#define PAL_CACHE_LINE_STATE_MODIFIED 3 /* Modified */
-
-typedef struct pal_freq_ratio {
- u32 den, num; /* numerator & denominator */
-} itc_ratio, proc_ratio;
-
-typedef union pal_cache_config_info_1_s {
- struct {
- u64 u : 1, /* 0 Unified cache ? */
- at : 2, /* 2-1 Cache mem attr*/
- reserved : 5, /* 7-3 Reserved */
- associativity : 8, /* 16-8 Associativity*/
- line_size : 8, /* 23-17 Line size */
- stride : 8, /* 31-24 Stride */
- store_latency : 8, /*39-32 Store latency*/
- load_latency : 8, /* 47-40 Load latency*/
- store_hints : 8, /* 55-48 Store hints*/
- load_hints : 8; /* 63-56 Load hints */
- } pcci1_bits;
- u64 pcci1_data;
-} pal_cache_config_info_1_t;
-
-typedef union pal_cache_config_info_2_s {
- struct {
- u32 cache_size; /*cache size in bytes*/
-
-
- u32 alias_boundary : 8, /* 39-32 aliased addr
- * separation for max
- * performance.
- */
- tag_ls_bit : 8, /* 47-40 LSb of addr*/
- tag_ms_bit : 8, /* 55-48 MSb of addr*/
- reserved : 8; /* 63-56 Reserved */
- } pcci2_bits;
- u64 pcci2_data;
-} pal_cache_config_info_2_t;
-
-
-typedef struct pal_cache_config_info_s {
- pal_status_t pcci_status;
- pal_cache_config_info_1_t pcci_info_1;
- pal_cache_config_info_2_t pcci_info_2;
- u64 pcci_reserved;
-} pal_cache_config_info_t;
-
-#define pcci_ld_hints pcci_info_1.pcci1_bits.load_hints
-#define pcci_st_hints pcci_info_1.pcci1_bits.store_hints
-#define pcci_ld_latency pcci_info_1.pcci1_bits.load_latency
-#define pcci_st_latency pcci_info_1.pcci1_bits.store_latency
-#define pcci_stride pcci_info_1.pcci1_bits.stride
-#define pcci_line_size pcci_info_1.pcci1_bits.line_size
-#define pcci_assoc pcci_info_1.pcci1_bits.associativity
-#define pcci_cache_attr pcci_info_1.pcci1_bits.at
-#define pcci_unified pcci_info_1.pcci1_bits.u
-#define pcci_tag_msb pcci_info_2.pcci2_bits.tag_ms_bit
-#define pcci_tag_lsb pcci_info_2.pcci2_bits.tag_ls_bit
-#define pcci_alias_boundary pcci_info_2.pcci2_bits.alias_boundary
-#define pcci_cache_size pcci_info_2.pcci2_bits.cache_size
-
-
-
-/* Possible values for cache attributes */
-
-#define PAL_CACHE_ATTR_WT 0 /* Write through cache */
-#define PAL_CACHE_ATTR_WB 1 /* Write back cache */
-#define PAL_CACHE_ATTR_WT_OR_WB 2 /* Either write thru or write
- * back depending on TLB
- * memory attributes
- */
-
-
-/* Possible values for cache hints */
-
-#define PAL_CACHE_HINT_TEMP_1 0 /* Temporal level 1 */
-#define PAL_CACHE_HINT_NTEMP_1 1 /* Non-temporal level 1 */
-#define PAL_CACHE_HINT_NTEMP_ALL 3 /* Non-temporal all levels */
-
-/* Processor cache protection information */
-typedef union pal_cache_protection_element_u {
- u32 pcpi_data;
- struct {
- u32 data_bits : 8, /* # data bits covered by
- * each unit of protection
- */
-
- tagprot_lsb : 6, /* Least -do- */
- tagprot_msb : 6, /* Most Sig. tag address
- * bit that this
- * protection covers.
- */
- prot_bits : 6, /* # of protection bits */
- method : 4, /* Protection method */
- t_d : 2; /* Indicates which part
- * of the cache this
- * protection encoding
- * applies.
- */
- } pcp_info;
-} pal_cache_protection_element_t;
-
-#define pcpi_cache_prot_part pcp_info.t_d
-#define pcpi_prot_method pcp_info.method
-#define pcpi_prot_bits pcp_info.prot_bits
-#define pcpi_tagprot_msb pcp_info.tagprot_msb
-#define pcpi_tagprot_lsb pcp_info.tagprot_lsb
-#define pcpi_data_bits pcp_info.data_bits
-
-/* Processor cache part encodings */
-#define PAL_CACHE_PROT_PART_DATA 0 /* Data protection */
-#define PAL_CACHE_PROT_PART_TAG 1 /* Tag protection */
-#define PAL_CACHE_PROT_PART_TAG_DATA 2 /* Tag+data protection (tag is
- * more significant )
- */
-#define PAL_CACHE_PROT_PART_DATA_TAG 3 /* Data+tag protection (data is
- * more significant )
- */
-#define PAL_CACHE_PROT_PART_MAX 6
-
-
-typedef struct pal_cache_protection_info_s {
- pal_status_t pcpi_status;
- pal_cache_protection_element_t pcp_info[PAL_CACHE_PROT_PART_MAX];
-} pal_cache_protection_info_t;
-
-
-/* Processor cache protection method encodings */
-#define PAL_CACHE_PROT_METHOD_NONE 0 /* No protection */
-#define PAL_CACHE_PROT_METHOD_ODD_PARITY 1 /* Odd parity */
-#define PAL_CACHE_PROT_METHOD_EVEN_PARITY 2 /* Even parity */
-#define PAL_CACHE_PROT_METHOD_ECC 3 /* ECC protection */
-
-
-/* Processor cache line identification in the hierarchy */
-typedef union pal_cache_line_id_u {
- u64 pclid_data;
- struct {
- u64 cache_type : 8, /* 7-0 cache type */
- level : 8, /* 15-8 level of the
- * cache in the
- * hierarchy.
- */
- way : 8, /* 23-16 way in the set
- */
- part : 8, /* 31-24 part of the
- * cache
- */
- reserved : 32; /* 63-32 is reserved*/
- } pclid_info_read;
- struct {
- u64 cache_type : 8, /* 7-0 cache type */
- level : 8, /* 15-8 level of the
- * cache in the
- * hierarchy.
- */
- way : 8, /* 23-16 way in the set
- */
- part : 8, /* 31-24 part of the
- * cache
- */
- mesi : 8, /* 39-32 cache line
- * state
- */
- start : 8, /* 47-40 lsb of data to
- * invert
- */
- length : 8, /* 55-48 #bits to
- * invert
- */
- trigger : 8; /* 63-56 Trigger error
- * by doing a load
- * after the write
- */
-
- } pclid_info_write;
-} pal_cache_line_id_u_t;
-
-#define pclid_read_part pclid_info_read.part
-#define pclid_read_way pclid_info_read.way
-#define pclid_read_level pclid_info_read.level
-#define pclid_read_cache_type pclid_info_read.cache_type
-
-#define pclid_write_trigger pclid_info_write.trigger
-#define pclid_write_length pclid_info_write.length
-#define pclid_write_start pclid_info_write.start
-#define pclid_write_mesi pclid_info_write.mesi
-#define pclid_write_part pclid_info_write.part
-#define pclid_write_way pclid_info_write.way
-#define pclid_write_level pclid_info_write.level
-#define pclid_write_cache_type pclid_info_write.cache_type
-
-/* Processor cache line part encodings */
-#define PAL_CACHE_LINE_ID_PART_DATA 0 /* Data */
-#define PAL_CACHE_LINE_ID_PART_TAG 1 /* Tag */
-#define PAL_CACHE_LINE_ID_PART_DATA_PROT 2 /* Data protection */
-#define PAL_CACHE_LINE_ID_PART_TAG_PROT 3 /* Tag protection */
-#define PAL_CACHE_LINE_ID_PART_DATA_TAG_PROT 4 /* Data+tag
- * protection
- */
-typedef struct pal_cache_line_info_s {
- pal_status_t pcli_status; /* Return status of the read cache line
- * info call.
- */
- u64 pcli_data; /* 64-bit data, tag, protection bits .. */
- u64 pcli_data_len; /* data length in bits */
- pal_cache_line_state_t pcli_cache_line_state; /* mesi state */
-
-} pal_cache_line_info_t;
-
-
-/* Machine Check related crap */
-
-/* Pending event status bits */
-typedef u64 pal_mc_pending_events_t;
-
-#define PAL_MC_PENDING_MCA (1 << 0)
-#define PAL_MC_PENDING_INIT (1 << 1)
-
-/* Error information type */
-typedef u64 pal_mc_info_index_t;
-
-#define PAL_MC_INFO_PROCESSOR 0 /* Processor */
-#define PAL_MC_INFO_CACHE_CHECK 1 /* Cache check */
-#define PAL_MC_INFO_TLB_CHECK 2 /* Tlb check */
-#define PAL_MC_INFO_BUS_CHECK 3 /* Bus check */
-#define PAL_MC_INFO_REQ_ADDR 4 /* Requestor address */
-#define PAL_MC_INFO_RESP_ADDR 5 /* Responder address */
-#define PAL_MC_INFO_TARGET_ADDR 6 /* Target address */
-#define PAL_MC_INFO_IMPL_DEP 7 /* Implementation
- * dependent
- */
-
-#define PAL_TLB_CHECK_OP_PURGE 8
-
-typedef struct pal_process_state_info_s {
- u64 reserved1 : 2,
- rz : 1, /* PAL_CHECK processor
- * rendezvous
- * successful.
- */
-
- ra : 1, /* PAL_CHECK attempted
- * a rendezvous.
- */
- me : 1, /* Distinct multiple
- * errors occurred
- */
-
- mn : 1, /* Min. state save
- * area has been
- * registered with PAL
- */
-
- sy : 1, /* Storage integrity
- * synched
- */
-
-
- co : 1, /* Continuable */
- ci : 1, /* MC isolated */
- us : 1, /* Uncontained storage
- * damage.
- */
-
-
- hd : 1, /* Non-essential hw
- * lost (no loss of
- * functionality)
- * causing the
- * processor to run in
- * degraded mode.
- */
-
- tl : 1, /* 1 => MC occurred
- * after an instr was
- * executed but before
- * the trap that
- * resulted from instr
- * execution was
- * generated.
- * (Trap Lost )
- */
- mi : 1, /* More information available
- * call PAL_MC_ERROR_INFO
- */
- pi : 1, /* Precise instruction pointer */
- pm : 1, /* Precise min-state save area */
-
- dy : 1, /* Processor dynamic
- * state valid
- */
-
-
- in : 1, /* 0 = MC, 1 = INIT */
- rs : 1, /* RSE valid */
- cm : 1, /* MC corrected */
- ex : 1, /* MC is expected */
- cr : 1, /* Control regs valid*/
- pc : 1, /* Perf cntrs valid */
- dr : 1, /* Debug regs valid */
- tr : 1, /* Translation regs
- * valid
- */
- rr : 1, /* Region regs valid */
- ar : 1, /* App regs valid */
- br : 1, /* Branch regs valid */
- pr : 1, /* Predicate registers
- * valid
- */
-
- fp : 1, /* fp registers valid*/
- b1 : 1, /* Preserved bank one
- * general registers
- * are valid
- */
- b0 : 1, /* Preserved bank zero
- * general registers
- * are valid
- */
- gr : 1, /* General registers
- * are valid
- * (excl. banked regs)
- */
- dsize : 16, /* size of dynamic
- * state returned
- * by the processor
- */
-
- se : 1, /* Shared error. MCA in a
- shared structure */
- reserved2 : 10,
- cc : 1, /* Cache check */
- tc : 1, /* TLB check */
- bc : 1, /* Bus check */
- rc : 1, /* Register file check */
- uc : 1; /* Uarch check */
-
-} pal_processor_state_info_t;
-
-typedef struct pal_cache_check_info_s {
- u64 op : 4, /* Type of cache
- * operation that
- * caused the machine
- * check.
- */
- level : 2, /* Cache level */
- reserved1 : 2,
- dl : 1, /* Failure in data part
- * of cache line
- */
- tl : 1, /* Failure in tag part
- * of cache line
- */
- dc : 1, /* Failure in dcache */
- ic : 1, /* Failure in icache */
- mesi : 3, /* Cache line state */
- mv : 1, /* mesi valid */
- way : 5, /* Way in which the
- * error occurred
- */
- wiv : 1, /* Way field valid */
- reserved2 : 1,
- dp : 1, /* Data poisoned on MBE */
- reserved3 : 6,
- hlth : 2, /* Health indicator */
-
- index : 20, /* Cache line index */
- reserved4 : 2,
-
- is : 1, /* instruction set (1 == ia32) */
- iv : 1, /* instruction set field valid */
- pl : 2, /* privilege level */
- pv : 1, /* privilege level field valid */
- mcc : 1, /* Machine check corrected */
- tv : 1, /* Target address
- * structure is valid
- */
- rq : 1, /* Requester identifier
- * structure is valid
- */
- rp : 1, /* Responder identifier
- * structure is valid
- */
- pi : 1; /* Precise instruction pointer
- * structure is valid
- */
-} pal_cache_check_info_t;
-
-typedef struct pal_tlb_check_info_s {
-
- u64 tr_slot : 8, /* Slot# of TR where
- * error occurred
- */
- trv : 1, /* tr_slot field is valid */
- reserved1 : 1,
- level : 2, /* TLB level where failure occurred */
- reserved2 : 4,
- dtr : 1, /* Fail in data TR */
- itr : 1, /* Fail in inst TR */
- dtc : 1, /* Fail in data TC */
- itc : 1, /* Fail in inst. TC */
- op : 4, /* Cache operation */
- reserved3 : 6,
- hlth : 2, /* Health indicator */
- reserved4 : 22,
-
- is : 1, /* instruction set (1 == ia32) */
- iv : 1, /* instruction set field valid */
- pl : 2, /* privilege level */
- pv : 1, /* privilege level field valid */
- mcc : 1, /* Machine check corrected */
- tv : 1, /* Target address
- * structure is valid
- */
- rq : 1, /* Requester identifier
- * structure is valid
- */
- rp : 1, /* Responder identifier
- * structure is valid
- */
- pi : 1; /* Precise instruction pointer
- * structure is valid
- */
-} pal_tlb_check_info_t;
-
-typedef struct pal_bus_check_info_s {
- u64 size : 5, /* Xaction size */
- ib : 1, /* Internal bus error */
- eb : 1, /* External bus error */
- cc : 1, /* Error occurred
- * during cache-cache
- * transfer.
- */
- type : 8, /* Bus xaction type*/
- sev : 5, /* Bus error severity*/
- hier : 2, /* Bus hierarchy level */
- dp : 1, /* Data poisoned on MBE */
- bsi : 8, /* Bus error status
- * info
- */
- reserved2 : 22,
-
- is : 1, /* instruction set (1 == ia32) */
- iv : 1, /* instruction set field valid */
- pl : 2, /* privilege level */
- pv : 1, /* privilege level field valid */
- mcc : 1, /* Machine check corrected */
- tv : 1, /* Target address
- * structure is valid
- */
- rq : 1, /* Requester identifier
- * structure is valid
- */
- rp : 1, /* Responder identifier
- * structure is valid
- */
- pi : 1; /* Precise instruction pointer
- * structure is valid
- */
-} pal_bus_check_info_t;
-
-typedef struct pal_reg_file_check_info_s {
- u64 id : 4, /* Register file identifier */
- op : 4, /* Type of register
- * operation that
- * caused the machine
- * check.
- */
- reg_num : 7, /* Register number */
- rnv : 1, /* reg_num valid */
- reserved2 : 38,
-
- is : 1, /* instruction set (1 == ia32) */
- iv : 1, /* instruction set field valid */
- pl : 2, /* privilege level */
- pv : 1, /* privilege level field valid */
- mcc : 1, /* Machine check corrected */
- reserved3 : 3,
- pi : 1; /* Precise instruction pointer
- * structure is valid
- */
-} pal_reg_file_check_info_t;
-
-typedef struct pal_uarch_check_info_s {
- u64 sid : 5, /* Structure identification */
- level : 3, /* Level of failure */
- array_id : 4, /* Array identification */
- op : 4, /* Type of
- * operation that
- * caused the machine
- * check.
- */
- way : 6, /* Way of structure */
- wv : 1, /* way valid */
- xv : 1, /* index valid */
- reserved1 : 6,
- hlth : 2, /* Health indicator */
- index : 8, /* Index or set of the uarch
- * structure that failed.
- */
- reserved2 : 24,
-
- is : 1, /* instruction set (1 == ia32) */
- iv : 1, /* instruction set field valid */
- pl : 2, /* privilege level */
- pv : 1, /* privilege level field valid */
- mcc : 1, /* Machine check corrected */
- tv : 1, /* Target address
- * structure is valid
- */
- rq : 1, /* Requester identifier
- * structure is valid
- */
- rp : 1, /* Responder identifier
- * structure is valid
- */
- pi : 1; /* Precise instruction pointer
- * structure is valid
- */
-} pal_uarch_check_info_t;
-
-typedef union pal_mc_error_info_u {
- u64 pmei_data;
- pal_processor_state_info_t pme_processor;
- pal_cache_check_info_t pme_cache;
- pal_tlb_check_info_t pme_tlb;
- pal_bus_check_info_t pme_bus;
- pal_reg_file_check_info_t pme_reg_file;
- pal_uarch_check_info_t pme_uarch;
-} pal_mc_error_info_t;
-
-#define pmci_proc_unknown_check pme_processor.uc
-#define pmci_proc_bus_check pme_processor.bc
-#define pmci_proc_tlb_check pme_processor.tc
-#define pmci_proc_cache_check pme_processor.cc
-#define pmci_proc_dynamic_state_size pme_processor.dsize
-#define pmci_proc_gpr_valid pme_processor.gr
-#define pmci_proc_preserved_bank0_gpr_valid pme_processor.b0
-#define pmci_proc_preserved_bank1_gpr_valid pme_processor.b1
-#define pmci_proc_fp_valid pme_processor.fp
-#define pmci_proc_predicate_regs_valid pme_processor.pr
-#define pmci_proc_branch_regs_valid pme_processor.br
-#define pmci_proc_app_regs_valid pme_processor.ar
-#define pmci_proc_region_regs_valid pme_processor.rr
-#define pmci_proc_translation_regs_valid pme_processor.tr
-#define pmci_proc_debug_regs_valid pme_processor.dr
-#define pmci_proc_perf_counters_valid pme_processor.pc
-#define pmci_proc_control_regs_valid pme_processor.cr
-#define pmci_proc_machine_check_expected pme_processor.ex
-#define pmci_proc_machine_check_corrected pme_processor.cm
-#define pmci_proc_rse_valid pme_processor.rs
-#define pmci_proc_machine_check_or_init pme_processor.in
-#define pmci_proc_dynamic_state_valid pme_processor.dy
-#define pmci_proc_operation pme_processor.op
-#define pmci_proc_trap_lost pme_processor.tl
-#define pmci_proc_hardware_damage pme_processor.hd
-#define pmci_proc_uncontained_storage_damage pme_processor.us
-#define pmci_proc_machine_check_isolated pme_processor.ci
-#define pmci_proc_continuable pme_processor.co
-#define pmci_proc_storage_intergrity_synced pme_processor.sy
-#define pmci_proc_min_state_save_area_regd pme_processor.mn
-#define pmci_proc_distinct_multiple_errors pme_processor.me
-#define pmci_proc_pal_attempted_rendezvous pme_processor.ra
-#define pmci_proc_pal_rendezvous_complete pme_processor.rz
-
-
-#define pmci_cache_level pme_cache.level
-#define pmci_cache_line_state pme_cache.mesi
-#define pmci_cache_line_state_valid pme_cache.mv
-#define pmci_cache_line_index pme_cache.index
-#define pmci_cache_instr_cache_fail pme_cache.ic
-#define pmci_cache_data_cache_fail pme_cache.dc
-#define pmci_cache_line_tag_fail pme_cache.tl
-#define pmci_cache_line_data_fail pme_cache.dl
-#define pmci_cache_operation pme_cache.op
-#define pmci_cache_way_valid pme_cache.wv
-#define pmci_cache_target_address_valid pme_cache.tv
-#define pmci_cache_way pme_cache.way
-#define pmci_cache_mc pme_cache.mc
-
-#define pmci_tlb_instr_translation_cache_fail pme_tlb.itc
-#define pmci_tlb_data_translation_cache_fail pme_tlb.dtc
-#define pmci_tlb_instr_translation_reg_fail pme_tlb.itr
-#define pmci_tlb_data_translation_reg_fail pme_tlb.dtr
-#define pmci_tlb_translation_reg_slot pme_tlb.tr_slot
-#define pmci_tlb_mc pme_tlb.mc
-
-#define pmci_bus_status_info pme_bus.bsi
-#define pmci_bus_req_address_valid pme_bus.rq
-#define pmci_bus_resp_address_valid pme_bus.rp
-#define pmci_bus_target_address_valid pme_bus.tv
-#define pmci_bus_error_severity pme_bus.sev
-#define pmci_bus_transaction_type pme_bus.type
-#define pmci_bus_cache_cache_transfer pme_bus.cc
-#define pmci_bus_transaction_size pme_bus.size
-#define pmci_bus_internal_error pme_bus.ib
-#define pmci_bus_external_error pme_bus.eb
-#define pmci_bus_mc pme_bus.mc
-
-/*
- * NOTE: this min_state_save area struct only includes the 1KB
- * architectural state save area. The other 3 KB is scratch space
- * for PAL.
- */
-
-struct pal_min_state_area {
- u64 pmsa_nat_bits; /* nat bits for saved GRs */
- u64 pmsa_gr[15]; /* GR1 - GR15 */
- u64 pmsa_bank0_gr[16]; /* GR16 - GR31 */
- u64 pmsa_bank1_gr[16]; /* GR16 - GR31 */
- u64 pmsa_pr; /* predicate registers */
- u64 pmsa_br0; /* branch register 0 */
- u64 pmsa_rsc; /* ar.rsc */
- u64 pmsa_iip; /* cr.iip */
- u64 pmsa_ipsr; /* cr.ipsr */
- u64 pmsa_ifs; /* cr.ifs */
- u64 pmsa_xip; /* previous iip */
- u64 pmsa_xpsr; /* previous psr */
- u64 pmsa_xfs; /* previous ifs */
- u64 pmsa_br1; /* branch register 1 */
- u64 pmsa_reserved[70]; /* pal_min_state_area should total to 1KB */
-};
-
-
-struct ia64_pal_retval {
- /*
- * A zero status value indicates call completed without error.
- * A negative status value indicates reason of call failure.
- * A positive status value indicates success but an
- * informational value should be printed (e.g., "reboot for
- * change to take effect").
- */
- s64 status;
- u64 v0;
- u64 v1;
- u64 v2;
-};
-
-/*
- * Note: Currently unused PAL arguments are generally labeled
- * "reserved" so the value specified in the PAL documentation
- * (generally 0) MUST be passed. Reserved parameters are not optional
- * parameters.
- */
-extern struct ia64_pal_retval ia64_pal_call_static (u64, u64, u64, u64);
-extern struct ia64_pal_retval ia64_pal_call_stacked (u64, u64, u64, u64);
-extern struct ia64_pal_retval ia64_pal_call_phys_static (u64, u64, u64, u64);
-extern struct ia64_pal_retval ia64_pal_call_phys_stacked (u64, u64, u64, u64);
-extern void ia64_save_scratch_fpregs (struct ia64_fpreg *);
-extern void ia64_load_scratch_fpregs (struct ia64_fpreg *);
-
-#define PAL_CALL(iprv,a0,a1,a2,a3) do { \
- struct ia64_fpreg fr[6]; \
- ia64_save_scratch_fpregs(fr); \
- iprv = ia64_pal_call_static(a0, a1, a2, a3); \
- ia64_load_scratch_fpregs(fr); \
-} while (0)
-
-#define PAL_CALL_STK(iprv,a0,a1,a2,a3) do { \
- struct ia64_fpreg fr[6]; \
- ia64_save_scratch_fpregs(fr); \
- iprv = ia64_pal_call_stacked(a0, a1, a2, a3); \
- ia64_load_scratch_fpregs(fr); \
-} while (0)
-
-#define PAL_CALL_PHYS(iprv,a0,a1,a2,a3) do { \
- struct ia64_fpreg fr[6]; \
- ia64_save_scratch_fpregs(fr); \
- iprv = ia64_pal_call_phys_static(a0, a1, a2, a3); \
- ia64_load_scratch_fpregs(fr); \
-} while (0)
-
-#define PAL_CALL_PHYS_STK(iprv,a0,a1,a2,a3) do { \
- struct ia64_fpreg fr[6]; \
- ia64_save_scratch_fpregs(fr); \
- iprv = ia64_pal_call_phys_stacked(a0, a1, a2, a3); \
- ia64_load_scratch_fpregs(fr); \
-} while (0)
-
-typedef int (*ia64_pal_handler) (u64, ...);
-extern ia64_pal_handler ia64_pal;
-extern void ia64_pal_handler_init (void *);
-
-extern ia64_pal_handler ia64_pal;
-
-extern pal_cache_config_info_t l0d_cache_config_info;
-extern pal_cache_config_info_t l0i_cache_config_info;
-extern pal_cache_config_info_t l1_cache_config_info;
-extern pal_cache_config_info_t l2_cache_config_info;
-
-extern pal_cache_protection_info_t l0d_cache_protection_info;
-extern pal_cache_protection_info_t l0i_cache_protection_info;
-extern pal_cache_protection_info_t l1_cache_protection_info;
-extern pal_cache_protection_info_t l2_cache_protection_info;
-
-extern pal_cache_config_info_t pal_cache_config_info_get(pal_cache_level_t,
- pal_cache_type_t);
-
-extern pal_cache_protection_info_t pal_cache_protection_info_get(pal_cache_level_t,
- pal_cache_type_t);
-
-
-extern void pal_error(int);
-
-
-/* Useful wrappers for the current list of pal procedures */
-
-typedef union pal_bus_features_u {
- u64 pal_bus_features_val;
- struct {
- u64 pbf_reserved1 : 29;
- u64 pbf_req_bus_parking : 1;
- u64 pbf_bus_lock_mask : 1;
- u64 pbf_enable_half_xfer_rate : 1;
- u64 pbf_reserved2 : 20;
- u64 pbf_enable_shared_line_replace : 1;
- u64 pbf_enable_exclusive_line_replace : 1;
- u64 pbf_disable_xaction_queueing : 1;
- u64 pbf_disable_resp_err_check : 1;
- u64 pbf_disable_berr_check : 1;
- u64 pbf_disable_bus_req_internal_err_signal : 1;
- u64 pbf_disable_bus_req_berr_signal : 1;
- u64 pbf_disable_bus_init_event_check : 1;
- u64 pbf_disable_bus_init_event_signal : 1;
- u64 pbf_disable_bus_addr_err_check : 1;
- u64 pbf_disable_bus_addr_err_signal : 1;
- u64 pbf_disable_bus_data_err_check : 1;
- } pal_bus_features_s;
-} pal_bus_features_u_t;
-
-extern void pal_bus_features_print (u64);
-
-/* Provide information about configurable processor bus features */
-static inline s64
-ia64_pal_bus_get_features (pal_bus_features_u_t *features_avail,
- pal_bus_features_u_t *features_status,
- pal_bus_features_u_t *features_control)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_PHYS(iprv, PAL_BUS_GET_FEATURES, 0, 0, 0);
- if (features_avail)
- features_avail->pal_bus_features_val = iprv.v0;
- if (features_status)
- features_status->pal_bus_features_val = iprv.v1;
- if (features_control)
- features_control->pal_bus_features_val = iprv.v2;
- return iprv.status;
-}
-
-/* Enables/disables specific processor bus features */
-static inline s64
-ia64_pal_bus_set_features (pal_bus_features_u_t feature_select)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_PHYS(iprv, PAL_BUS_SET_FEATURES, feature_select.pal_bus_features_val, 0, 0);
- return iprv.status;
-}
-
-/* Get detailed cache information */
-static inline s64
-ia64_pal_cache_config_info (u64 cache_level, u64 cache_type, pal_cache_config_info_t *conf)
-{
- struct ia64_pal_retval iprv;
-
- PAL_CALL(iprv, PAL_CACHE_INFO, cache_level, cache_type, 0);
-
- if (iprv.status == 0) {
- conf->pcci_status = iprv.status;
- conf->pcci_info_1.pcci1_data = iprv.v0;
- conf->pcci_info_2.pcci2_data = iprv.v1;
- conf->pcci_reserved = iprv.v2;
- }
- return iprv.status;
-
-}
-
-/* Get detailed cche protection information */
-static inline s64
-ia64_pal_cache_prot_info (u64 cache_level, u64 cache_type, pal_cache_protection_info_t *prot)
-{
- struct ia64_pal_retval iprv;
-
- PAL_CALL(iprv, PAL_CACHE_PROT_INFO, cache_level, cache_type, 0);
-
- if (iprv.status == 0) {
- prot->pcpi_status = iprv.status;
- prot->pcp_info[0].pcpi_data = iprv.v0 & 0xffffffff;
- prot->pcp_info[1].pcpi_data = iprv.v0 >> 32;
- prot->pcp_info[2].pcpi_data = iprv.v1 & 0xffffffff;
- prot->pcp_info[3].pcpi_data = iprv.v1 >> 32;
- prot->pcp_info[4].pcpi_data = iprv.v2 & 0xffffffff;
- prot->pcp_info[5].pcpi_data = iprv.v2 >> 32;
- }
- return iprv.status;
-}
-
-/*
- * Flush the processor instruction or data caches. *PROGRESS must be
- * initialized to zero before calling this for the first time..
- */
-static inline s64
-ia64_pal_cache_flush (u64 cache_type, u64 invalidate, u64 *progress, u64 *vector)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_CACHE_FLUSH, cache_type, invalidate, *progress);
- if (vector)
- *vector = iprv.v0;
- *progress = iprv.v1;
- return iprv.status;
-}
-
-
-/* Initialize the processor controlled caches */
-static inline s64
-ia64_pal_cache_init (u64 level, u64 cache_type, u64 rest)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_CACHE_INIT, level, cache_type, rest);
- return iprv.status;
-}
-
-/* Initialize the tags and data of a data or unified cache line of
- * processor controlled cache to known values without the availability
- * of backing memory.
- */
-static inline s64
-ia64_pal_cache_line_init (u64 physical_addr, u64 data_value)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_CACHE_LINE_INIT, physical_addr, data_value, 0);
- return iprv.status;
-}
-
-
-/* Read the data and tag of a processor controlled cache line for diags */
-static inline s64
-ia64_pal_cache_read (pal_cache_line_id_u_t line_id, u64 physical_addr)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_PHYS_STK(iprv, PAL_CACHE_READ, line_id.pclid_data,
- physical_addr, 0);
- return iprv.status;
-}
-
-/* Return summary information about the hierarchy of caches controlled by the processor */
-static inline long ia64_pal_cache_summary(unsigned long *cache_levels,
- unsigned long *unique_caches)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_CACHE_SUMMARY, 0, 0, 0);
- if (cache_levels)
- *cache_levels = iprv.v0;
- if (unique_caches)
- *unique_caches = iprv.v1;
- return iprv.status;
-}
-
-/* Write the data and tag of a processor-controlled cache line for diags */
-static inline s64
-ia64_pal_cache_write (pal_cache_line_id_u_t line_id, u64 physical_addr, u64 data)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_PHYS_STK(iprv, PAL_CACHE_WRITE, line_id.pclid_data,
- physical_addr, data);
- return iprv.status;
-}
-
-
-/* Return the parameters needed to copy relocatable PAL procedures from ROM to memory */
-static inline s64
-ia64_pal_copy_info (u64 copy_type, u64 num_procs, u64 num_iopics,
- u64 *buffer_size, u64 *buffer_align)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_COPY_INFO, copy_type, num_procs, num_iopics);
- if (buffer_size)
- *buffer_size = iprv.v0;
- if (buffer_align)
- *buffer_align = iprv.v1;
- return iprv.status;
-}
-
-/* Copy relocatable PAL procedures from ROM to memory */
-static inline s64
-ia64_pal_copy_pal (u64 target_addr, u64 alloc_size, u64 processor, u64 *pal_proc_offset)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_COPY_PAL, target_addr, alloc_size, processor);
- if (pal_proc_offset)
- *pal_proc_offset = iprv.v0;
- return iprv.status;
-}
-
-/* Return the number of instruction and data debug register pairs */
-static inline long ia64_pal_debug_info(unsigned long *inst_regs,
- unsigned long *data_regs)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_DEBUG_INFO, 0, 0, 0);
- if (inst_regs)
- *inst_regs = iprv.v0;
- if (data_regs)
- *data_regs = iprv.v1;
-
- return iprv.status;
-}
-
-#ifdef TBD
-/* Switch from IA64-system environment to IA-32 system environment */
-static inline s64
-ia64_pal_enter_ia32_env (ia32_env1, ia32_env2, ia32_env3)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_ENTER_IA_32_ENV, ia32_env1, ia32_env2, ia32_env3);
- return iprv.status;
-}
-#endif
-
-/* Get unique geographical address of this processor on its bus */
-static inline s64
-ia64_pal_fixed_addr (u64 *global_unique_addr)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_FIXED_ADDR, 0, 0, 0);
- if (global_unique_addr)
- *global_unique_addr = iprv.v0;
- return iprv.status;
-}
-
-/* Get base frequency of the platform if generated by the processor */
-static inline long ia64_pal_freq_base(unsigned long *platform_base_freq)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_FREQ_BASE, 0, 0, 0);
- if (platform_base_freq)
- *platform_base_freq = iprv.v0;
- return iprv.status;
-}
-
-/*
- * Get the ratios for processor frequency, bus frequency and interval timer to
- * the base frequency of the platform
- */
-static inline s64
-ia64_pal_freq_ratios (struct pal_freq_ratio *proc_ratio, struct pal_freq_ratio *bus_ratio,
- struct pal_freq_ratio *itc_ratio)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_FREQ_RATIOS, 0, 0, 0);
- if (proc_ratio)
- *(u64 *)proc_ratio = iprv.v0;
- if (bus_ratio)
- *(u64 *)bus_ratio = iprv.v1;
- if (itc_ratio)
- *(u64 *)itc_ratio = iprv.v2;
- return iprv.status;
-}
-
-/*
- * Get the current hardware resource sharing policy of the processor
- */
-static inline s64
-ia64_pal_get_hw_policy (u64 proc_num, u64 *cur_policy, u64 *num_impacted,
- u64 *la)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_GET_HW_POLICY, proc_num, 0, 0);
- if (cur_policy)
- *cur_policy = iprv.v0;
- if (num_impacted)
- *num_impacted = iprv.v1;
- if (la)
- *la = iprv.v2;
- return iprv.status;
-}
-
-/* Make the processor enter HALT or one of the implementation dependent low
- * power states where prefetching and execution are suspended and cache and
- * TLB coherency is not maintained.
- */
-static inline s64
-ia64_pal_halt (u64 halt_state)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_HALT, halt_state, 0, 0);
- return iprv.status;
-}
-
-typedef union pal_power_mgmt_info_u {
- u64 ppmi_data;
- struct {
- u64 exit_latency : 16,
- entry_latency : 16,
- power_consumption : 28,
- im : 1,
- co : 1,
- reserved : 2;
- } pal_power_mgmt_info_s;
-} pal_power_mgmt_info_u_t;
-
-/* Return information about processor's optional power management capabilities. */
-static inline s64
-ia64_pal_halt_info (pal_power_mgmt_info_u_t *power_buf)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_STK(iprv, PAL_HALT_INFO, (unsigned long) power_buf, 0, 0);
- return iprv.status;
-}
-
-/* Get the current P-state information */
-static inline s64
-ia64_pal_get_pstate (u64 *pstate_index, unsigned long type)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_STK(iprv, PAL_GET_PSTATE, type, 0, 0);
- *pstate_index = iprv.v0;
- return iprv.status;
-}
-
-/* Set the P-state */
-static inline s64
-ia64_pal_set_pstate (u64 pstate_index)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_STK(iprv, PAL_SET_PSTATE, pstate_index, 0, 0);
- return iprv.status;
-}
-
-/* Processor branding information*/
-static inline s64
-ia64_pal_get_brand_info (char *brand_info)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_STK(iprv, PAL_BRAND_INFO, 0, (u64)brand_info, 0);
- return iprv.status;
-}
-
-/* Cause the processor to enter LIGHT HALT state, where prefetching and execution are
- * suspended, but cache and TLB coherency is maintained.
- */
-static inline s64
-ia64_pal_halt_light (void)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_HALT_LIGHT, 0, 0, 0);
- return iprv.status;
-}
-
-/* Clear all the processor error logging registers and reset the indicator that allows
- * the error logging registers to be written. This procedure also checks the pending
- * machine check bit and pending INIT bit and reports their states.
- */
-static inline s64
-ia64_pal_mc_clear_log (u64 *pending_vector)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MC_CLEAR_LOG, 0, 0, 0);
- if (pending_vector)
- *pending_vector = iprv.v0;
- return iprv.status;
-}
-
-/* Ensure that all outstanding transactions in a processor are completed or that any
- * MCA due to thes outstanding transaction is taken.
- */
-static inline s64
-ia64_pal_mc_drain (void)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MC_DRAIN, 0, 0, 0);
- return iprv.status;
-}
-
-/* Return the machine check dynamic processor state */
-static inline s64
-ia64_pal_mc_dynamic_state (u64 info_type, u64 dy_buffer, u64 *size)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MC_DYNAMIC_STATE, info_type, dy_buffer, 0);
- if (size)
- *size = iprv.v0;
- return iprv.status;
-}
-
-/* Return processor machine check information */
-static inline s64
-ia64_pal_mc_error_info (u64 info_index, u64 type_index, u64 *size, u64 *error_info)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MC_ERROR_INFO, info_index, type_index, 0);
- if (size)
- *size = iprv.v0;
- if (error_info)
- *error_info = iprv.v1;
- return iprv.status;
-}
-
-/* Injects the requested processor error or returns info on
- * supported injection capabilities for current processor implementation
- */
-static inline s64
-ia64_pal_mc_error_inject_phys (u64 err_type_info, u64 err_struct_info,
- u64 err_data_buffer, u64 *capabilities, u64 *resources)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_PHYS_STK(iprv, PAL_MC_ERROR_INJECT, err_type_info,
- err_struct_info, err_data_buffer);
- if (capabilities)
- *capabilities= iprv.v0;
- if (resources)
- *resources= iprv.v1;
- return iprv.status;
-}
-
-static inline s64
-ia64_pal_mc_error_inject_virt (u64 err_type_info, u64 err_struct_info,
- u64 err_data_buffer, u64 *capabilities, u64 *resources)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_STK(iprv, PAL_MC_ERROR_INJECT, err_type_info,
- err_struct_info, err_data_buffer);
- if (capabilities)
- *capabilities= iprv.v0;
- if (resources)
- *resources= iprv.v1;
- return iprv.status;
-}
-
-/* Inform PALE_CHECK whether a machine check is expected so that PALE_CHECK willnot
- * attempt to correct any expected machine checks.
- */
-static inline s64
-ia64_pal_mc_expected (u64 expected, u64 *previous)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MC_EXPECTED, expected, 0, 0);
- if (previous)
- *previous = iprv.v0;
- return iprv.status;
-}
-
-typedef union pal_hw_tracking_u {
- u64 pht_data;
- struct {
- u64 itc :4, /* Instruction cache tracking */
- dct :4, /* Date cache tracking */
- itt :4, /* Instruction TLB tracking */
- ddt :4, /* Data TLB tracking */
- reserved:48;
- } pal_hw_tracking_s;
-} pal_hw_tracking_u_t;
-
-/*
- * Hardware tracking status.
- */
-static inline s64
-ia64_pal_mc_hw_tracking (u64 *status)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MC_HW_TRACKING, 0, 0, 0);
- if (status)
- *status = iprv.v0;
- return iprv.status;
-}
-
-/* Register a platform dependent location with PAL to which it can save
- * minimal processor state in the event of a machine check or initialization
- * event.
- */
-static inline s64
-ia64_pal_mc_register_mem (u64 physical_addr, u64 size, u64 *req_size)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MC_REGISTER_MEM, physical_addr, size, 0);
- if (req_size)
- *req_size = iprv.v0;
- return iprv.status;
-}
-
-/* Restore minimal architectural processor state, set CMC interrupt if necessary
- * and resume execution
- */
-static inline s64
-ia64_pal_mc_resume (u64 set_cmci, u64 save_ptr)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MC_RESUME, set_cmci, save_ptr, 0);
- return iprv.status;
-}
-
-/* Return the memory attributes implemented by the processor */
-static inline s64
-ia64_pal_mem_attrib (u64 *mem_attrib)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MEM_ATTRIB, 0, 0, 0);
- if (mem_attrib)
- *mem_attrib = iprv.v0 & 0xff;
- return iprv.status;
-}
-
-/* Return the amount of memory needed for second phase of processor
- * self-test and the required alignment of memory.
- */
-static inline s64
-ia64_pal_mem_for_test (u64 *bytes_needed, u64 *alignment)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_MEM_FOR_TEST, 0, 0, 0);
- if (bytes_needed)
- *bytes_needed = iprv.v0;
- if (alignment)
- *alignment = iprv.v1;
- return iprv.status;
-}
-
-typedef union pal_perf_mon_info_u {
- u64 ppmi_data;
- struct {
- u64 generic : 8,
- width : 8,
- cycles : 8,
- retired : 8,
- reserved : 32;
- } pal_perf_mon_info_s;
-} pal_perf_mon_info_u_t;
-
-/* Return the performance monitor information about what can be counted
- * and how to configure the monitors to count the desired events.
- */
-static inline s64
-ia64_pal_perf_mon_info (u64 *pm_buffer, pal_perf_mon_info_u_t *pm_info)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_PERF_MON_INFO, (unsigned long) pm_buffer, 0, 0);
- if (pm_info)
- pm_info->ppmi_data = iprv.v0;
- return iprv.status;
-}
-
-/* Specifies the physical address of the processor interrupt block
- * and I/O port space.
- */
-static inline s64
-ia64_pal_platform_addr (u64 type, u64 physical_addr)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_PLATFORM_ADDR, type, physical_addr, 0);
- return iprv.status;
-}
-
-/* Set the SAL PMI entrypoint in memory */
-static inline s64
-ia64_pal_pmi_entrypoint (u64 sal_pmi_entry_addr)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_PMI_ENTRYPOINT, sal_pmi_entry_addr, 0, 0);
- return iprv.status;
-}
-
-struct pal_features_s;
-/* Provide information about configurable processor features */
-static inline s64
-ia64_pal_proc_get_features (u64 *features_avail,
- u64 *features_status,
- u64 *features_control,
- u64 features_set)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, features_set, 0);
- if (iprv.status == 0) {
- *features_avail = iprv.v0;
- *features_status = iprv.v1;
- *features_control = iprv.v2;
- }
- return iprv.status;
-}
-
-/* Enable/disable processor dependent features */
-static inline s64
-ia64_pal_proc_set_features (u64 feature_select)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_PHYS(iprv, PAL_PROC_SET_FEATURES, feature_select, 0, 0);
- return iprv.status;
-}
-
-/*
- * Put everything in a struct so we avoid the global offset table whenever
- * possible.
- */
-typedef struct ia64_ptce_info_s {
- unsigned long base;
- u32 count[2];
- u32 stride[2];
-} ia64_ptce_info_t;
-
-/* Return the information required for the architected loop used to purge
- * (initialize) the entire TC
- */
-static inline s64
-ia64_get_ptce (ia64_ptce_info_t *ptce)
-{
- struct ia64_pal_retval iprv;
-
- if (!ptce)
- return -1;
-
- PAL_CALL(iprv, PAL_PTCE_INFO, 0, 0, 0);
- if (iprv.status == 0) {
- ptce->base = iprv.v0;
- ptce->count[0] = iprv.v1 >> 32;
- ptce->count[1] = iprv.v1 & 0xffffffff;
- ptce->stride[0] = iprv.v2 >> 32;
- ptce->stride[1] = iprv.v2 & 0xffffffff;
- }
- return iprv.status;
-}
-
-/* Return info about implemented application and control registers. */
-static inline s64
-ia64_pal_register_info (u64 info_request, u64 *reg_info_1, u64 *reg_info_2)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_REGISTER_INFO, info_request, 0, 0);
- if (reg_info_1)
- *reg_info_1 = iprv.v0;
- if (reg_info_2)
- *reg_info_2 = iprv.v1;
- return iprv.status;
-}
-
-typedef union pal_hints_u {
- unsigned long ph_data;
- struct {
- unsigned long si : 1,
- li : 1,
- reserved : 62;
- } pal_hints_s;
-} pal_hints_u_t;
-
-/* Return information about the register stack and RSE for this processor
- * implementation.
- */
-static inline long ia64_pal_rse_info(unsigned long *num_phys_stacked,
- pal_hints_u_t *hints)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_RSE_INFO, 0, 0, 0);
- if (num_phys_stacked)
- *num_phys_stacked = iprv.v0;
- if (hints)
- hints->ph_data = iprv.v1;
- return iprv.status;
-}
-
-/*
- * Set the current hardware resource sharing policy of the processor
- */
-static inline s64
-ia64_pal_set_hw_policy (u64 policy)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_SET_HW_POLICY, policy, 0, 0);
- return iprv.status;
-}
-
-/* Cause the processor to enter SHUTDOWN state, where prefetching and execution are
- * suspended, but cause cache and TLB coherency to be maintained.
- * This is usually called in IA-32 mode.
- */
-static inline s64
-ia64_pal_shutdown (void)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_SHUTDOWN, 0, 0, 0);
- return iprv.status;
-}
-
-/* Perform the second phase of processor self-test. */
-static inline s64
-ia64_pal_test_proc (u64 test_addr, u64 test_size, u64 attributes, u64 *self_test_state)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_TEST_PROC, test_addr, test_size, attributes);
- if (self_test_state)
- *self_test_state = iprv.v0;
- return iprv.status;
-}
-
-typedef union pal_version_u {
- u64 pal_version_val;
- struct {
- u64 pv_pal_b_rev : 8;
- u64 pv_pal_b_model : 8;
- u64 pv_reserved1 : 8;
- u64 pv_pal_vendor : 8;
- u64 pv_pal_a_rev : 8;
- u64 pv_pal_a_model : 8;
- u64 pv_reserved2 : 16;
- } pal_version_s;
-} pal_version_u_t;
-
-
-/*
- * Return PAL version information. While the documentation states that
- * PAL_VERSION can be called in either physical or virtual mode, some
- * implementations only allow physical calls. We don't call it very often,
- * so the overhead isn't worth eliminating.
- */
-static inline s64
-ia64_pal_version (pal_version_u_t *pal_min_version, pal_version_u_t *pal_cur_version)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_PHYS(iprv, PAL_VERSION, 0, 0, 0);
- if (pal_min_version)
- pal_min_version->pal_version_val = iprv.v0;
-
- if (pal_cur_version)
- pal_cur_version->pal_version_val = iprv.v1;
-
- return iprv.status;
-}
-
-typedef union pal_tc_info_u {
- u64 pti_val;
- struct {
- u64 num_sets : 8,
- associativity : 8,
- num_entries : 16,
- pf : 1,
- unified : 1,
- reduce_tr : 1,
- reserved : 29;
- } pal_tc_info_s;
-} pal_tc_info_u_t;
-
-#define tc_reduce_tr pal_tc_info_s.reduce_tr
-#define tc_unified pal_tc_info_s.unified
-#define tc_pf pal_tc_info_s.pf
-#define tc_num_entries pal_tc_info_s.num_entries
-#define tc_associativity pal_tc_info_s.associativity
-#define tc_num_sets pal_tc_info_s.num_sets
-
-
-/* Return information about the virtual memory characteristics of the processor
- * implementation.
- */
-static inline s64
-ia64_pal_vm_info (u64 tc_level, u64 tc_type, pal_tc_info_u_t *tc_info, u64 *tc_pages)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_VM_INFO, tc_level, tc_type, 0);
- if (tc_info)
- tc_info->pti_val = iprv.v0;
- if (tc_pages)
- *tc_pages = iprv.v1;
- return iprv.status;
-}
-
-/* Get page size information about the virtual memory characteristics of the processor
- * implementation.
- */
-static inline s64 ia64_pal_vm_page_size(u64 *tr_pages, u64 *vw_pages)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_VM_PAGE_SIZE, 0, 0, 0);
- if (tr_pages)
- *tr_pages = iprv.v0;
- if (vw_pages)
- *vw_pages = iprv.v1;
- return iprv.status;
-}
-
-typedef union pal_vm_info_1_u {
- u64 pvi1_val;
- struct {
- u64 vw : 1,
- phys_add_size : 7,
- key_size : 8,
- max_pkr : 8,
- hash_tag_id : 8,
- max_dtr_entry : 8,
- max_itr_entry : 8,
- max_unique_tcs : 8,
- num_tc_levels : 8;
- } pal_vm_info_1_s;
-} pal_vm_info_1_u_t;
-
-#define PAL_MAX_PURGES 0xFFFF /* all ones is means unlimited */
-
-typedef union pal_vm_info_2_u {
- u64 pvi2_val;
- struct {
- u64 impl_va_msb : 8,
- rid_size : 8,
- max_purges : 16,
- reserved : 32;
- } pal_vm_info_2_s;
-} pal_vm_info_2_u_t;
-
-/* Get summary information about the virtual memory characteristics of the processor
- * implementation.
- */
-static inline s64
-ia64_pal_vm_summary (pal_vm_info_1_u_t *vm_info_1, pal_vm_info_2_u_t *vm_info_2)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_VM_SUMMARY, 0, 0, 0);
- if (vm_info_1)
- vm_info_1->pvi1_val = iprv.v0;
- if (vm_info_2)
- vm_info_2->pvi2_val = iprv.v1;
- return iprv.status;
-}
-
-typedef union pal_vp_info_u {
- u64 pvi_val;
- struct {
- u64 index: 48, /* virtual feature set info */
- vmm_id: 16; /* feature set id */
- } pal_vp_info_s;
-} pal_vp_info_u_t;
-
-/*
- * Returns information about virtual processor features
- */
-static inline s64
-ia64_pal_vp_info (u64 feature_set, u64 vp_buffer, u64 *vp_info, u64 *vmm_id)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_VP_INFO, feature_set, vp_buffer, 0);
- if (vp_info)
- *vp_info = iprv.v0;
- if (vmm_id)
- *vmm_id = iprv.v1;
- return iprv.status;
-}
-
-typedef union pal_itr_valid_u {
- u64 piv_val;
- struct {
- u64 access_rights_valid : 1,
- priv_level_valid : 1,
- dirty_bit_valid : 1,
- mem_attr_valid : 1,
- reserved : 60;
- } pal_tr_valid_s;
-} pal_tr_valid_u_t;
-
-/* Read a translation register */
-static inline s64
-ia64_pal_tr_read (u64 reg_num, u64 tr_type, u64 *tr_buffer, pal_tr_valid_u_t *tr_valid)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL_PHYS_STK(iprv, PAL_VM_TR_READ, reg_num, tr_type,(u64)ia64_tpa(tr_buffer));
- if (tr_valid)
- tr_valid->piv_val = iprv.v0;
- return iprv.status;
-}
-
-/*
- * PAL_PREFETCH_VISIBILITY transaction types
- */
-#define PAL_VISIBILITY_VIRTUAL 0
-#define PAL_VISIBILITY_PHYSICAL 1
-
-/*
- * PAL_PREFETCH_VISIBILITY return codes
- */
-#define PAL_VISIBILITY_OK 1
-#define PAL_VISIBILITY_OK_REMOTE_NEEDED 0
-#define PAL_VISIBILITY_INVAL_ARG -2
-#define PAL_VISIBILITY_ERROR -3
-
-static inline s64
-ia64_pal_prefetch_visibility (s64 trans_type)
-{
- struct ia64_pal_retval iprv;
- PAL_CALL(iprv, PAL_PREFETCH_VISIBILITY, trans_type, 0, 0);
- return iprv.status;
-}
-
-/* data structure for getting information on logical to physical mappings */
-typedef union pal_log_overview_u {
- struct {
- u64 num_log :16, /* Total number of logical
- * processors on this die
- */
- tpc :8, /* Threads per core */
- reserved3 :8, /* Reserved */
- cpp :8, /* Cores per processor */
- reserved2 :8, /* Reserved */
- ppid :8, /* Physical processor ID */
- reserved1 :8; /* Reserved */
- } overview_bits;
- u64 overview_data;
-} pal_log_overview_t;
-
-typedef union pal_proc_n_log_info1_u{
- struct {
- u64 tid :16, /* Thread id */
- reserved2 :16, /* Reserved */
- cid :16, /* Core id */
- reserved1 :16; /* Reserved */
- } ppli1_bits;
- u64 ppli1_data;
-} pal_proc_n_log_info1_t;
-
-typedef union pal_proc_n_log_info2_u {
- struct {
- u64 la :16, /* Logical address */
- reserved :48; /* Reserved */
- } ppli2_bits;
- u64 ppli2_data;
-} pal_proc_n_log_info2_t;
-
-typedef struct pal_logical_to_physical_s
-{
- pal_log_overview_t overview;
- pal_proc_n_log_info1_t ppli1;
- pal_proc_n_log_info2_t ppli2;
-} pal_logical_to_physical_t;
-
-#define overview_num_log overview.overview_bits.num_log
-#define overview_tpc overview.overview_bits.tpc
-#define overview_cpp overview.overview_bits.cpp
-#define overview_ppid overview.overview_bits.ppid
-#define log1_tid ppli1.ppli1_bits.tid
-#define log1_cid ppli1.ppli1_bits.cid
-#define log2_la ppli2.ppli2_bits.la
-
-/* Get information on logical to physical processor mappings. */
-static inline s64
-ia64_pal_logical_to_phys(u64 proc_number, pal_logical_to_physical_t *mapping)
-{
- struct ia64_pal_retval iprv;
-
- PAL_CALL(iprv, PAL_LOGICAL_TO_PHYSICAL, proc_number, 0, 0);
-
- if (iprv.status == PAL_STATUS_SUCCESS)
- {
- mapping->overview.overview_data = iprv.v0;
- mapping->ppli1.ppli1_data = iprv.v1;
- mapping->ppli2.ppli2_data = iprv.v2;
- }
-
- return iprv.status;
-}
-
-typedef struct pal_cache_shared_info_s
-{
- u64 num_shared;
- pal_proc_n_log_info1_t ppli1;
- pal_proc_n_log_info2_t ppli2;
-} pal_cache_shared_info_t;
-
-/* Get information on logical to physical processor mappings. */
-static inline s64
-ia64_pal_cache_shared_info(u64 level,
- u64 type,
- u64 proc_number,
- pal_cache_shared_info_t *info)
-{
- struct ia64_pal_retval iprv;
-
- PAL_CALL(iprv, PAL_CACHE_SHARED_INFO, level, type, proc_number);
-
- if (iprv.status == PAL_STATUS_SUCCESS) {
- info->num_shared = iprv.v0;
- info->ppli1.ppli1_data = iprv.v1;
- info->ppli2.ppli2_data = iprv.v2;
- }
-
- return iprv.status;
-}
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_IA64_PAL_H */
diff --git a/arch/ia64/include/asm/param.h b/arch/ia64/include/asm/param.h
deleted file mode 100644
index f0b786227c40..000000000000
--- a/arch/ia64/include/asm/param.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Fundamental kernel parameters.
- *
- * Based on <asm-i386/param.h>.
- *
- * Modified 1998, 1999, 2002-2003
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-#ifndef _ASM_IA64_PARAM_H
-#define _ASM_IA64_PARAM_H
-
-#include <uapi/asm/param.h>
-
-# define HZ CONFIG_HZ
-# define USER_HZ HZ
-# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */
-#endif /* _ASM_IA64_PARAM_H */
diff --git a/arch/ia64/include/asm/parport.h b/arch/ia64/include/asm/parport.h
deleted file mode 100644
index 360ca9bf2f6f..000000000000
--- a/arch/ia64/include/asm/parport.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * parport.h: platform-specific PC-style parport initialisation
- *
- * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
- *
- * This file should only be included by drivers/parport/parport_pc.c.
- */
-
-#ifndef _ASM_IA64_PARPORT_H
-#define _ASM_IA64_PARPORT_H 1
-
-static int parport_pc_find_isa_ports(int autoirq, int autodma);
-
-static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
-{
- return parport_pc_find_isa_ports(autoirq, autodma);
-}
-
-#endif /* _ASM_IA64_PARPORT_H */
diff --git a/arch/ia64/include/asm/patch.h b/arch/ia64/include/asm/patch.h
deleted file mode 100644
index bd487ed22bf5..000000000000
--- a/arch/ia64/include/asm/patch.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_PATCH_H
-#define _ASM_IA64_PATCH_H
-
-/*
- * Copyright (C) 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * There are a number of reasons for patching instructions. Rather than duplicating code
- * all over the place, we put the common stuff here. Reasons for patching: in-kernel
- * module-loader, virtual-to-physical patch-list, McKinley Errata 9 workaround, and gate
- * shared library. Undoubtedly, some of these reasons will disappear and others will
- * be added over time.
- */
-#include <linux/elf.h>
-#include <linux/types.h>
-
-extern void ia64_patch (u64 insn_addr, u64 mask, u64 val); /* patch any insn slot */
-extern void ia64_patch_imm64 (u64 insn_addr, u64 val); /* patch "movl" w/abs. value*/
-extern void ia64_patch_imm60 (u64 insn_addr, u64 val); /* patch "brl" w/ip-rel value */
-
-extern void ia64_patch_mckinley_e9 (unsigned long start, unsigned long end);
-extern void ia64_patch_vtop (unsigned long start, unsigned long end);
-extern void ia64_patch_phys_stack_reg(unsigned long val);
-extern void ia64_patch_rse (unsigned long start, unsigned long end);
-extern void ia64_patch_gate (void);
-
-#endif /* _ASM_IA64_PATCH_H */
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
deleted file mode 100644
index fa8f545c24c9..000000000000
--- a/arch/ia64/include/asm/pci.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_PCI_H
-#define _ASM_IA64_PCI_H
-
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/scatterlist.h>
-
-#include <asm/io.h>
-#include <asm/hw_irq.h>
-
-struct pci_vector_struct {
- __u16 segment; /* PCI Segment number */
- __u16 bus; /* PCI Bus number */
- __u32 pci_id; /* ACPI split 16 bits device, 16 bits function (see section 6.1.1) */
- __u8 pin; /* PCI PIN (0 = A, 1 = B, 2 = C, 3 = D) */
- __u32 irq; /* IRQ assigned */
-};
-
-/*
- * Can be used to override the logic in pci_scan_bus for skipping already-configured bus
- * numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the
- * loader.
- */
-#define pcibios_assign_all_busses() 0
-
-#define PCIBIOS_MIN_IO 0x1000
-#define PCIBIOS_MIN_MEM 0x10000000
-
-#define HAVE_PCI_MMAP
-#define ARCH_GENERIC_PCI_MMAP_RESOURCE
-#define arch_can_pci_mmap_wc() 1
-
-#define HAVE_PCI_LEGACY
-extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
- struct vm_area_struct *vma,
- enum pci_mmap_state mmap_state);
-
-char *pci_get_legacy_mem(struct pci_bus *bus);
-int pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size);
-int pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size);
-
-struct pci_controller {
- struct acpi_device *companion;
- void *iommu;
- int segment;
- int node; /* nearest node with memory or NUMA_NO_NODE for global allocation */
-
- void *platform_data;
-};
-
-
-#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
-#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment)
-
-extern struct pci_ops pci_root_ops;
-
-static inline int pci_proc_domain(struct pci_bus *bus)
-{
- return (pci_domain_nr(bus) != 0);
-}
-
-#endif /* _ASM_IA64_PCI_H */
diff --git a/arch/ia64/include/asm/percpu.h b/arch/ia64/include/asm/percpu.h
deleted file mode 100644
index f357b9bb3576..000000000000
--- a/arch/ia64/include/asm/percpu.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_PERCPU_H
-#define _ASM_IA64_PERCPU_H
-
-/*
- * Copyright (C) 2002-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#ifdef __ASSEMBLY__
-# define THIS_CPU(var) (var) /* use this to mark accesses to per-CPU variables... */
-#else /* !__ASSEMBLY__ */
-
-
-#include <linux/threads.h>
-
-#ifdef CONFIG_SMP
-
-#ifdef HAVE_MODEL_SMALL_ATTRIBUTE
-# define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
-#endif
-
-#define __my_cpu_offset __ia64_per_cpu_var(local_per_cpu_offset)
-
-extern void *per_cpu_init(void);
-
-#else /* ! SMP */
-
-#define per_cpu_init() (__phys_per_cpu_start)
-
-#endif /* SMP */
-
-#define PER_CPU_BASE_SECTION ".data..percpu"
-
-/*
- * Be extremely careful when taking the address of this variable! Due to virtual
- * remapping, it is different from the canonical address returned by this_cpu_ptr(&var)!
- * On the positive side, using __ia64_per_cpu_var() instead of this_cpu_ptr() is slightly
- * more efficient.
- */
-#define __ia64_per_cpu_var(var) (*({ \
- __verify_pcpu_ptr(&(var)); \
- ((typeof(var) __kernel __force *)&(var)); \
-}))
-
-#include <asm-generic/percpu.h>
-
-/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */
-DECLARE_PER_CPU(unsigned long, local_per_cpu_offset);
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _ASM_IA64_PERCPU_H */
diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h
deleted file mode 100644
index 0fb2b6291d58..000000000000
--- a/arch/ia64/include/asm/pgalloc.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_PGALLOC_H
-#define _ASM_IA64_PGALLOC_H
-
-/*
- * This file contains the functions and defines necessary to allocate
- * page tables.
- *
- * This hopefully works with any (fixed) ia-64 page-size, as defined
- * in <asm/page.h> (currently 8192).
- *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2000, Goutham Rao <goutham.rao@intel.com>
- */
-
-
-#include <linux/compiler.h>
-#include <linux/mm.h>
-#include <linux/page-flags.h>
-#include <linux/threads.h>
-
-#include <asm-generic/pgalloc.h>
-
-#include <asm/mmu_context.h>
-
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
-{
- return (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-}
-
-#if CONFIG_PGTABLE_LEVELS == 4
-static inline void
-p4d_populate(struct mm_struct *mm, p4d_t * p4d_entry, pud_t * pud)
-{
- p4d_val(*p4d_entry) = __pa(pud);
-}
-
-#define __pud_free_tlb(tlb, pud, address) pud_free((tlb)->mm, pud)
-#endif /* CONFIG_PGTABLE_LEVELS == 4 */
-
-static inline void
-pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)
-{
- pud_val(*pud_entry) = __pa(pmd);
-}
-
-#define __pmd_free_tlb(tlb, pmd, address) pmd_free((tlb)->mm, pmd)
-
-static inline void
-pmd_populate(struct mm_struct *mm, pmd_t * pmd_entry, pgtable_t pte)
-{
- pmd_val(*pmd_entry) = page_to_phys(pte);
-}
-
-static inline void
-pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte)
-{
- pmd_val(*pmd_entry) = __pa(pte);
-}
-
-#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte)
-
-#endif /* _ASM_IA64_PGALLOC_H */
diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h
deleted file mode 100644
index 9be2d2ba6016..000000000000
--- a/arch/ia64/include/asm/pgtable.h
+++ /dev/null
@@ -1,545 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_PGTABLE_H
-#define _ASM_IA64_PGTABLE_H
-
-/*
- * This file contains the functions and defines necessary to modify and use
- * the IA-64 page table tree.
- *
- * This hopefully works with any (fixed) IA-64 page-size, as defined
- * in <asm/page.h>.
- *
- * Copyright (C) 1998-2005 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-
-#include <asm/mman.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/types.h>
-
-#define IA64_MAX_PHYS_BITS 50 /* max. number of physical address bits (architected) */
-
-/*
- * First, define the various bits in a PTE. Note that the PTE format
- * matches the VHPT short format, the firt doubleword of the VHPD long
- * format, and the first doubleword of the TLB insertion format.
- */
-#define _PAGE_P_BIT 0
-#define _PAGE_A_BIT 5
-#define _PAGE_D_BIT 6
-
-#define _PAGE_P (1 << _PAGE_P_BIT) /* page present bit */
-#define _PAGE_MA_WB (0x0 << 2) /* write back memory attribute */
-#define _PAGE_MA_UC (0x4 << 2) /* uncacheable memory attribute */
-#define _PAGE_MA_UCE (0x5 << 2) /* UC exported attribute */
-#define _PAGE_MA_WC (0x6 << 2) /* write coalescing memory attribute */
-#define _PAGE_MA_NAT (0x7 << 2) /* not-a-thing attribute */
-#define _PAGE_MA_MASK (0x7 << 2)
-#define _PAGE_PL_0 (0 << 7) /* privilege level 0 (kernel) */
-#define _PAGE_PL_1 (1 << 7) /* privilege level 1 (unused) */
-#define _PAGE_PL_2 (2 << 7) /* privilege level 2 (unused) */
-#define _PAGE_PL_3 (3 << 7) /* privilege level 3 (user) */
-#define _PAGE_PL_MASK (3 << 7)
-#define _PAGE_AR_R (0 << 9) /* read only */
-#define _PAGE_AR_RX (1 << 9) /* read & execute */
-#define _PAGE_AR_RW (2 << 9) /* read & write */
-#define _PAGE_AR_RWX (3 << 9) /* read, write & execute */
-#define _PAGE_AR_R_RW (4 << 9) /* read / read & write */
-#define _PAGE_AR_RX_RWX (5 << 9) /* read & exec / read, write & exec */
-#define _PAGE_AR_RWX_RW (6 << 9) /* read, write & exec / read & write */
-#define _PAGE_AR_X_RX (7 << 9) /* exec & promote / read & exec */
-#define _PAGE_AR_MASK (7 << 9)
-#define _PAGE_AR_SHIFT 9
-#define _PAGE_A (1 << _PAGE_A_BIT) /* page accessed bit */
-#define _PAGE_D (1 << _PAGE_D_BIT) /* page dirty bit */
-#define _PAGE_PPN_MASK (((__IA64_UL(1) << IA64_MAX_PHYS_BITS) - 1) & ~0xfffUL)
-#define _PAGE_ED (__IA64_UL(1) << 52) /* exception deferral */
-#define _PAGE_PROTNONE (__IA64_UL(1) << 63)
-
-/* We borrow bit 7 to store the exclusive marker in swap PTEs. */
-#define _PAGE_SWP_EXCLUSIVE (1 << 7)
-
-#define _PFN_MASK _PAGE_PPN_MASK
-/* Mask of bits which may be changed by pte_modify(); the odd bits are there for _PAGE_PROTNONE */
-#define _PAGE_CHG_MASK (_PAGE_P | _PAGE_PROTNONE | _PAGE_PL_MASK | _PAGE_AR_MASK | _PAGE_ED)
-
-#define _PAGE_SIZE_4K 12
-#define _PAGE_SIZE_8K 13
-#define _PAGE_SIZE_16K 14
-#define _PAGE_SIZE_64K 16
-#define _PAGE_SIZE_256K 18
-#define _PAGE_SIZE_1M 20
-#define _PAGE_SIZE_4M 22
-#define _PAGE_SIZE_16M 24
-#define _PAGE_SIZE_64M 26
-#define _PAGE_SIZE_256M 28
-#define _PAGE_SIZE_1G 30
-#define _PAGE_SIZE_4G 32
-
-#define __ACCESS_BITS _PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_MA_WB
-#define __DIRTY_BITS_NO_ED _PAGE_A | _PAGE_P | _PAGE_D | _PAGE_MA_WB
-#define __DIRTY_BITS _PAGE_ED | __DIRTY_BITS_NO_ED
-
-/*
- * How many pointers will a page table level hold expressed in shift
- */
-#define PTRS_PER_PTD_SHIFT (PAGE_SHIFT-3)
-
-/*
- * Definitions for fourth level:
- */
-#define PTRS_PER_PTE (__IA64_UL(1) << (PTRS_PER_PTD_SHIFT))
-
-/*
- * Definitions for third level:
- *
- * PMD_SHIFT determines the size of the area a third-level page table
- * can map.
- */
-#define PMD_SHIFT (PAGE_SHIFT + (PTRS_PER_PTD_SHIFT))
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-#define PTRS_PER_PMD (1UL << (PTRS_PER_PTD_SHIFT))
-
-#if CONFIG_PGTABLE_LEVELS == 4
-/*
- * Definitions for second level:
- *
- * PUD_SHIFT determines the size of the area a second-level page table
- * can map.
- */
-#define PUD_SHIFT (PMD_SHIFT + (PTRS_PER_PTD_SHIFT))
-#define PUD_SIZE (1UL << PUD_SHIFT)
-#define PUD_MASK (~(PUD_SIZE-1))
-#define PTRS_PER_PUD (1UL << (PTRS_PER_PTD_SHIFT))
-#endif
-
-/*
- * Definitions for first level:
- *
- * PGDIR_SHIFT determines what a first-level page table entry can map.
- */
-#if CONFIG_PGTABLE_LEVELS == 4
-#define PGDIR_SHIFT (PUD_SHIFT + (PTRS_PER_PTD_SHIFT))
-#else
-#define PGDIR_SHIFT (PMD_SHIFT + (PTRS_PER_PTD_SHIFT))
-#endif
-#define PGDIR_SIZE (__IA64_UL(1) << PGDIR_SHIFT)
-#define PGDIR_MASK (~(PGDIR_SIZE-1))
-#define PTRS_PER_PGD_SHIFT PTRS_PER_PTD_SHIFT
-#define PTRS_PER_PGD (1UL << PTRS_PER_PGD_SHIFT)
-#define USER_PTRS_PER_PGD (5*PTRS_PER_PGD/8) /* regions 0-4 are user regions */
-
-/*
- * All the normal masks have the "page accessed" bits on, as any time
- * they are used, the page is accessed. They are cleared only by the
- * page-out routines.
- */
-#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_A)
-#define PAGE_SHARED __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
-#define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
-#define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
-#define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
-#define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
-#define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
-#define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
-#define PAGE_KERNEL_UC __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX | \
- _PAGE_MA_UC)
-
-# ifndef __ASSEMBLY__
-
-#include <linux/sched/mm.h> /* for mm_struct */
-#include <linux/bitops.h>
-#include <asm/cacheflush.h>
-#include <asm/mmu_context.h>
-
-/*
- * Next come the mappings that determine how mmap() protection bits
- * (PROT_EXEC, PROT_READ, PROT_WRITE, PROT_NONE) get implemented. The
- * _P version gets used for a private shared memory segment, the _S
- * version gets used for a shared memory segment with MAP_SHARED on.
- * In a private shared memory segment, we do a copy-on-write if a task
- * attempts to write to the page.
- */
- /* xwr */
-#define pgd_ERROR(e) printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
-#if CONFIG_PGTABLE_LEVELS == 4
-#define pud_ERROR(e) printk("%s:%d: bad pud %016lx.\n", __FILE__, __LINE__, pud_val(e))
-#endif
-#define pmd_ERROR(e) printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
-#define pte_ERROR(e) printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
-
-
-/*
- * Some definitions to translate between mem_map, PTEs, and page addresses:
- */
-
-
-/* Quick test to see if ADDR is a (potentially) valid physical address. */
-static inline long
-ia64_phys_addr_valid (unsigned long addr)
-{
- return (addr & (local_cpu_data->unimpl_pa_mask)) == 0;
-}
-
-/*
- * Now come the defines and routines to manage and access the three-level
- * page table.
- */
-
-
-#define VMALLOC_START (RGN_BASE(RGN_GATE) + 0x200000000UL)
-#if defined(CONFIG_SPARSEMEM) && defined(CONFIG_SPARSEMEM_VMEMMAP)
-/* SPARSEMEM_VMEMMAP uses half of vmalloc... */
-# define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 10)))
-# define vmemmap ((struct page *)VMALLOC_END)
-#else
-# define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 9)))
-#endif
-
-/* fs/proc/kcore.c */
-#define kc_vaddr_to_offset(v) ((v) - RGN_BASE(RGN_GATE))
-#define kc_offset_to_vaddr(o) ((o) + RGN_BASE(RGN_GATE))
-
-#define RGN_MAP_SHIFT (PGDIR_SHIFT + PTRS_PER_PGD_SHIFT - 3)
-#define RGN_MAP_LIMIT ((1UL << RGN_MAP_SHIFT) - PAGE_SIZE) /* per region addr limit */
-
-#define PFN_PTE_SHIFT PAGE_SHIFT
-/*
- * Conversion functions: convert page frame number (pfn) and a protection value to a page
- * table entry (pte).
- */
-#define pfn_pte(pfn, pgprot) \
-({ pte_t __pte; pte_val(__pte) = ((pfn) << PAGE_SHIFT) | pgprot_val(pgprot); __pte; })
-
-/* Extract pfn from pte. */
-#define pte_pfn(_pte) ((pte_val(_pte) & _PFN_MASK) >> PAGE_SHIFT)
-
-#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
-
-/* This takes a physical page address that is used by the remapping functions */
-#define mk_pte_phys(physpage, pgprot) \
-({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; })
-
-#define pte_modify(_pte, newprot) \
- (__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
-
-#define pte_none(pte) (!pte_val(pte))
-#define pte_present(pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
-#define pte_clear(mm,addr,pte) (pte_val(*(pte)) = 0UL)
-/* pte_page() returns the "struct page *" corresponding to the PTE: */
-#define pte_page(pte) virt_to_page(((pte_val(pte) & _PFN_MASK) + PAGE_OFFSET))
-
-#define pmd_none(pmd) (!pmd_val(pmd))
-#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd)))
-#define pmd_present(pmd) (pmd_val(pmd) != 0UL)
-#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL)
-#define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val(pmd) & _PFN_MASK))
-#define pmd_pfn(pmd) ((pmd_val(pmd) & _PFN_MASK) >> PAGE_SHIFT)
-#define pmd_page(pmd) virt_to_page((pmd_val(pmd) + PAGE_OFFSET))
-
-#define pud_none(pud) (!pud_val(pud))
-#define pud_bad(pud) (!ia64_phys_addr_valid(pud_val(pud)))
-#define pud_present(pud) (pud_val(pud) != 0UL)
-#define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
-#define pud_pgtable(pud) ((pmd_t *) __va(pud_val(pud) & _PFN_MASK))
-#define pud_page(pud) virt_to_page((pud_val(pud) + PAGE_OFFSET))
-
-#if CONFIG_PGTABLE_LEVELS == 4
-#define p4d_none(p4d) (!p4d_val(p4d))
-#define p4d_bad(p4d) (!ia64_phys_addr_valid(p4d_val(p4d)))
-#define p4d_present(p4d) (p4d_val(p4d) != 0UL)
-#define p4d_clear(p4dp) (p4d_val(*(p4dp)) = 0UL)
-#define p4d_pgtable(p4d) ((pud_t *) __va(p4d_val(p4d) & _PFN_MASK))
-#define p4d_page(p4d) virt_to_page((p4d_val(p4d) + PAGE_OFFSET))
-#endif
-
-/*
- * The following have defined behavior only work if pte_present() is true.
- */
-#define pte_write(pte) ((unsigned) (((pte_val(pte) & _PAGE_AR_MASK) >> _PAGE_AR_SHIFT) - 2) <= 4)
-#define pte_exec(pte) ((pte_val(pte) & _PAGE_AR_RX) != 0)
-#define pte_dirty(pte) ((pte_val(pte) & _PAGE_D) != 0)
-#define pte_young(pte) ((pte_val(pte) & _PAGE_A) != 0)
-
-/*
- * Note: we convert AR_RWX to AR_RX and AR_RW to AR_R by clearing the 2nd bit in the
- * access rights:
- */
-#define pte_wrprotect(pte) (__pte(pte_val(pte) & ~_PAGE_AR_RW))
-#define pte_mkwrite_novma(pte) (__pte(pte_val(pte) | _PAGE_AR_RW))
-#define pte_mkold(pte) (__pte(pte_val(pte) & ~_PAGE_A))
-#define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_A))
-#define pte_mkclean(pte) (__pte(pte_val(pte) & ~_PAGE_D))
-#define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_D))
-#define pte_mkhuge(pte) (__pte(pte_val(pte)))
-
-/*
- * Because ia64's Icache and Dcache is not coherent (on a cpu), we need to
- * sync icache and dcache when we insert *new* executable page.
- * __ia64_sync_icache_dcache() check Pg_arch_1 bit and flush icache
- * if necessary.
- *
- * set_pte() is also called by the kernel, but we can expect that the kernel
- * flushes icache explicitly if necessary.
- */
-#define pte_present_exec_user(pte)\
- ((pte_val(pte) & (_PAGE_P | _PAGE_PL_MASK | _PAGE_AR_RX)) == \
- (_PAGE_P | _PAGE_PL_3 | _PAGE_AR_RX))
-
-extern void __ia64_sync_icache_dcache(pte_t pteval);
-static inline void set_pte(pte_t *ptep, pte_t pteval)
-{
- /* page is present && page is user && page is executable
- * && (page swapin or new page or page migration
- * || copy_on_write with page copying.)
- */
- if (pte_present_exec_user(pteval) &&
- (!pte_present(*ptep) ||
- pte_pfn(*ptep) != pte_pfn(pteval)))
- /* load_module() calles flush_icache_range() explicitly*/
- __ia64_sync_icache_dcache(pteval);
- *ptep = pteval;
-}
-
-/*
- * Make page protection values cacheable, uncacheable, or write-
- * combining. Note that "protection" is really a misnomer here as the
- * protection value contains the memory attribute bits, dirty bits, and
- * various other bits as well.
- */
-#define pgprot_cacheable(prot) __pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_WB)
-#define pgprot_noncached(prot) __pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_UC)
-#define pgprot_writecombine(prot) __pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_WC)
-
-struct file;
-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
- unsigned long size, pgprot_t vma_prot);
-#define __HAVE_PHYS_MEM_ACCESS_PROT
-
-static inline unsigned long
-pgd_index (unsigned long address)
-{
- unsigned long region = address >> 61;
- unsigned long l1index = (address >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1);
-
- return (region << (PAGE_SHIFT - 6)) | l1index;
-}
-#define pgd_index pgd_index
-
-/*
- * In the kernel's mapped region we know everything is in region number 5, so
- * as an optimisation its PGD already points to the area for that region.
- * However, this also means that we cannot use pgd_index() and we must
- * never add the region here.
- */
-#define pgd_offset_k(addr) \
- (init_mm.pgd + (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)))
-
-/* Look up a pgd entry in the gate area. On IA-64, the gate-area
- resides in the kernel-mapped segment, hence we use pgd_offset_k()
- here. */
-#define pgd_offset_gate(mm, addr) pgd_offset_k(addr)
-
-/* atomic versions of the some PTE manipulations: */
-
-static inline int
-ptep_test_and_clear_young (struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
-{
-#ifdef CONFIG_SMP
- if (!pte_young(*ptep))
- return 0;
- return test_and_clear_bit(_PAGE_A_BIT, ptep);
-#else
- pte_t pte = *ptep;
- if (!pte_young(pte))
- return 0;
- set_pte_at(vma->vm_mm, addr, ptep, pte_mkold(pte));
- return 1;
-#endif
-}
-
-static inline pte_t
-ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-#ifdef CONFIG_SMP
- return __pte(xchg((long *) ptep, 0));
-#else
- pte_t pte = *ptep;
- pte_clear(mm, addr, ptep);
- return pte;
-#endif
-}
-
-static inline void
-ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-#ifdef CONFIG_SMP
- unsigned long new, old;
-
- do {
- old = pte_val(*ptep);
- new = pte_val(pte_wrprotect(__pte (old)));
- } while (cmpxchg((unsigned long *) ptep, old, new) != old);
-#else
- pte_t old_pte = *ptep;
- set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
-#endif
-}
-
-static inline int
-pte_same (pte_t a, pte_t b)
-{
- return pte_val(a) == pte_val(b);
-}
-
-#define update_mmu_cache_range(vmf, vma, address, ptep, nr) do { } while (0)
-#define update_mmu_cache(vma, address, ptep) do { } while (0)
-
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-extern void paging_init (void);
-
-/*
- * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that
- * are !pte_none() && !pte_present().
- *
- * Note: The macros below rely on the fact that MAX_SWAPFILES_SHIFT <= number of
- * bits in the swap-type field of the swap pte. It would be nice to
- * enforce that, but we can't easily include <linux/swap.h> here.
- * (Of course, better still would be to define MAX_SWAPFILES_SHIFT here...).
- *
- * Format of swap pte:
- * bit 0 : present bit (must be zero)
- * bits 1- 6: swap type
- * bit 7 : exclusive marker
- * bits 8-62: swap offset
- * bit 63 : _PAGE_PROTNONE bit
- */
-#define __swp_type(entry) (((entry).val >> 1) & 0x3f)
-#define __swp_offset(entry) (((entry).val << 1) >> 9)
-#define __swp_entry(type, offset) ((swp_entry_t) { ((type & 0x3f) << 1) | \
- ((long) (offset) << 8) })
-#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
-#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
-
-static inline int pte_swp_exclusive(pte_t pte)
-{
- return pte_val(pte) & _PAGE_SWP_EXCLUSIVE;
-}
-
-static inline pte_t pte_swp_mkexclusive(pte_t pte)
-{
- pte_val(pte) |= _PAGE_SWP_EXCLUSIVE;
- return pte;
-}
-
-static inline pte_t pte_swp_clear_exclusive(pte_t pte)
-{
- pte_val(pte) &= ~_PAGE_SWP_EXCLUSIVE;
- return pte;
-}
-
-/*
- * ZERO_PAGE is a global shared page that is always zero: used
- * for zero-mapped memory areas etc..
- */
-extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
-extern struct page *zero_page_memmap_ptr;
-#define ZERO_PAGE(vaddr) (zero_page_memmap_ptr)
-
-/* We provide our own get_unmapped_area to cope with VA holes for userland */
-#define HAVE_ARCH_UNMAPPED_AREA
-
-#ifdef CONFIG_HUGETLB_PAGE
-#define HUGETLB_PGDIR_SHIFT (HPAGE_SHIFT + 2*(PAGE_SHIFT-3))
-#define HUGETLB_PGDIR_SIZE (__IA64_UL(1) << HUGETLB_PGDIR_SHIFT)
-#define HUGETLB_PGDIR_MASK (~(HUGETLB_PGDIR_SIZE-1))
-#endif
-
-
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-/*
- * Update PTEP with ENTRY, which is guaranteed to be a less
- * restrictive PTE. That is, ENTRY may have the ACCESSED, DIRTY, and
- * WRITABLE bits turned on, when the value at PTEP did not. The
- * WRITABLE bit may only be turned if SAFELY_WRITABLE is TRUE.
- *
- * SAFELY_WRITABLE is TRUE if we can update the value at PTEP without
- * having to worry about races. On SMP machines, there are only two
- * cases where this is true:
- *
- * (1) *PTEP has the PRESENT bit turned OFF
- * (2) ENTRY has the DIRTY bit turned ON
- *
- * On ia64, we could implement this routine with a cmpxchg()-loop
- * which ORs in the _PAGE_A/_PAGE_D bit if they're set in ENTRY.
- * However, like on x86, we can get a more streamlined version by
- * observing that it is OK to drop ACCESSED bit updates when
- * SAFELY_WRITABLE is FALSE. Besides being rare, all that would do is
- * result in an extra Access-bit fault, which would then turn on the
- * ACCESSED bit in the low-level fault handler (iaccess_bit or
- * daccess_bit in ivt.S).
- */
-#ifdef CONFIG_SMP
-# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __safely_writable) \
-({ \
- int __changed = !pte_same(*(__ptep), __entry); \
- if (__changed && __safely_writable) { \
- set_pte(__ptep, __entry); \
- flush_tlb_page(__vma, __addr); \
- } \
- __changed; \
-})
-#else
-# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __safely_writable) \
-({ \
- int __changed = !pte_same(*(__ptep), __entry); \
- if (__changed) { \
- set_pte_at((__vma)->vm_mm, (__addr), __ptep, __entry); \
- flush_tlb_page(__vma, __addr); \
- } \
- __changed; \
-})
-#endif
-# endif /* !__ASSEMBLY__ */
-
-/*
- * Identity-mapped regions use a large page size. We'll call such large pages
- * "granules". If you can think of a better name that's unambiguous, let me
- * know...
- */
-#if defined(CONFIG_IA64_GRANULE_64MB)
-# define IA64_GRANULE_SHIFT _PAGE_SIZE_64M
-#elif defined(CONFIG_IA64_GRANULE_16MB)
-# define IA64_GRANULE_SHIFT _PAGE_SIZE_16M
-#endif
-#define IA64_GRANULE_SIZE (1 << IA64_GRANULE_SHIFT)
-/*
- * log2() of the page size we use to map the kernel image (IA64_TR_KERNEL):
- */
-#define KERNEL_TR_PAGE_SHIFT _PAGE_SIZE_64M
-#define KERNEL_TR_PAGE_SIZE (1 << KERNEL_TR_PAGE_SHIFT)
-
-/* These tell get_user_pages() that the first gate page is accessible from user-level. */
-#define FIXADDR_USER_START GATE_ADDR
-#ifdef HAVE_BUGGY_SEGREL
-# define FIXADDR_USER_END (GATE_ADDR + 2*PAGE_SIZE)
-#else
-# define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE)
-#endif
-
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-#define __HAVE_ARCH_PTE_SAME
-#define __HAVE_ARCH_PGD_OFFSET_GATE
-
-
-#if CONFIG_PGTABLE_LEVELS == 3
-#include <asm-generic/pgtable-nopud.h>
-#endif
-#include <asm-generic/pgtable-nop4d.h>
-
-#endif /* _ASM_IA64_PGTABLE_H */
diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h
deleted file mode 100644
index 47e3801b526a..000000000000
--- a/arch/ia64/include/asm/processor.h
+++ /dev/null
@@ -1,660 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_PROCESSOR_H
-#define _ASM_IA64_PROCESSOR_H
-
-/*
- * Copyright (C) 1998-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- *
- * 11/24/98 S.Eranian added ia64_set_iva()
- * 12/03/99 D. Mosberger implement thread_saved_pc() via kernel unwind API
- * 06/16/00 A. Mallick added csd/ssd/tssd for ia32 support
- */
-
-
-#include <asm/intrinsics.h>
-#include <asm/kregs.h>
-#include <asm/ptrace.h>
-#include <asm/ustack.h>
-
-#define IA64_NUM_PHYS_STACK_REG 96
-#define IA64_NUM_DBG_REGS 8
-
-#define DEFAULT_MAP_BASE __IA64_UL_CONST(0x2000000000000000)
-#define DEFAULT_TASK_SIZE __IA64_UL_CONST(0xa000000000000000)
-
-/*
- * TASK_SIZE really is a mis-named. It really is the maximum user
- * space address (plus one). On IA-64, there are five regions of 2TB
- * each (assuming 8KB page size), for a total of 8TB of user virtual
- * address space.
- */
-#define TASK_SIZE DEFAULT_TASK_SIZE
-
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE (current->thread.map_base)
-
-#define IA64_THREAD_FPH_VALID (__IA64_UL(1) << 0) /* floating-point high state valid? */
-#define IA64_THREAD_DBG_VALID (__IA64_UL(1) << 1) /* debug registers valid? */
-#define IA64_THREAD_PM_VALID (__IA64_UL(1) << 2) /* performance registers valid? */
-#define IA64_THREAD_UAC_NOPRINT (__IA64_UL(1) << 3) /* don't log unaligned accesses */
-#define IA64_THREAD_UAC_SIGBUS (__IA64_UL(1) << 4) /* generate SIGBUS on unaligned acc. */
-#define IA64_THREAD_MIGRATION (__IA64_UL(1) << 5) /* require migration
- sync at ctx sw */
-#define IA64_THREAD_FPEMU_NOPRINT (__IA64_UL(1) << 6) /* don't log any fpswa faults */
-#define IA64_THREAD_FPEMU_SIGFPE (__IA64_UL(1) << 7) /* send a SIGFPE for fpswa faults */
-
-#define IA64_THREAD_UAC_SHIFT 3
-#define IA64_THREAD_UAC_MASK (IA64_THREAD_UAC_NOPRINT | IA64_THREAD_UAC_SIGBUS)
-#define IA64_THREAD_FPEMU_SHIFT 6
-#define IA64_THREAD_FPEMU_MASK (IA64_THREAD_FPEMU_NOPRINT | IA64_THREAD_FPEMU_SIGFPE)
-
-
-/*
- * This shift should be large enough to be able to represent 1000000000/itc_freq with good
- * accuracy while being small enough to fit 10*1000000000<<IA64_NSEC_PER_CYC_SHIFT in 64 bits
- * (this will give enough slack to represent 10 seconds worth of time as a scaled number).
- */
-#define IA64_NSEC_PER_CYC_SHIFT 30
-
-#ifndef __ASSEMBLY__
-
-#include <linux/cache.h>
-#include <linux/compiler.h>
-#include <linux/threads.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-
-#include <asm/fpu.h>
-#include <asm/page.h>
-#include <asm/percpu.h>
-#include <asm/rse.h>
-#include <asm/unwind.h>
-#include <linux/atomic.h>
-#ifdef CONFIG_NUMA
-#include <asm/nodedata.h>
-#endif
-
-/* like above but expressed as bitfields for more efficient access: */
-struct ia64_psr {
- __u64 reserved0 : 1;
- __u64 be : 1;
- __u64 up : 1;
- __u64 ac : 1;
- __u64 mfl : 1;
- __u64 mfh : 1;
- __u64 reserved1 : 7;
- __u64 ic : 1;
- __u64 i : 1;
- __u64 pk : 1;
- __u64 reserved2 : 1;
- __u64 dt : 1;
- __u64 dfl : 1;
- __u64 dfh : 1;
- __u64 sp : 1;
- __u64 pp : 1;
- __u64 di : 1;
- __u64 si : 1;
- __u64 db : 1;
- __u64 lp : 1;
- __u64 tb : 1;
- __u64 rt : 1;
- __u64 reserved3 : 4;
- __u64 cpl : 2;
- __u64 is : 1;
- __u64 mc : 1;
- __u64 it : 1;
- __u64 id : 1;
- __u64 da : 1;
- __u64 dd : 1;
- __u64 ss : 1;
- __u64 ri : 2;
- __u64 ed : 1;
- __u64 bn : 1;
- __u64 reserved4 : 19;
-};
-
-union ia64_isr {
- __u64 val;
- struct {
- __u64 code : 16;
- __u64 vector : 8;
- __u64 reserved1 : 8;
- __u64 x : 1;
- __u64 w : 1;
- __u64 r : 1;
- __u64 na : 1;
- __u64 sp : 1;
- __u64 rs : 1;
- __u64 ir : 1;
- __u64 ni : 1;
- __u64 so : 1;
- __u64 ei : 2;
- __u64 ed : 1;
- __u64 reserved2 : 20;
- };
-};
-
-union ia64_lid {
- __u64 val;
- struct {
- __u64 rv : 16;
- __u64 eid : 8;
- __u64 id : 8;
- __u64 ig : 32;
- };
-};
-
-union ia64_tpr {
- __u64 val;
- struct {
- __u64 ig0 : 4;
- __u64 mic : 4;
- __u64 rsv : 8;
- __u64 mmi : 1;
- __u64 ig1 : 47;
- };
-};
-
-union ia64_itir {
- __u64 val;
- struct {
- __u64 rv3 : 2; /* 0-1 */
- __u64 ps : 6; /* 2-7 */
- __u64 key : 24; /* 8-31 */
- __u64 rv4 : 32; /* 32-63 */
- };
-};
-
-union ia64_rr {
- __u64 val;
- struct {
- __u64 ve : 1; /* enable hw walker */
- __u64 reserved0: 1; /* reserved */
- __u64 ps : 6; /* log page size */
- __u64 rid : 24; /* region id */
- __u64 reserved1: 32; /* reserved */
- };
-};
-
-/*
- * CPU type, hardware bug flags, and per-CPU state. Frequently used
- * state comes earlier:
- */
-struct cpuinfo_ia64 {
- unsigned int softirq_pending;
- unsigned long itm_delta; /* # of clock cycles between clock ticks */
- unsigned long itm_next; /* interval timer mask value to use for next clock tick */
- unsigned long nsec_per_cyc; /* (1000000000<<IA64_NSEC_PER_CYC_SHIFT)/itc_freq */
- unsigned long unimpl_va_mask; /* mask of unimplemented virtual address bits (from PAL) */
- unsigned long unimpl_pa_mask; /* mask of unimplemented physical address bits (from PAL) */
- unsigned long itc_freq; /* frequency of ITC counter */
- unsigned long proc_freq; /* frequency of processor */
- unsigned long cyc_per_usec; /* itc_freq/1000000 */
- unsigned long ptce_base;
- unsigned int ptce_count[2];
- unsigned int ptce_stride[2];
- struct task_struct *ksoftirqd; /* kernel softirq daemon for this CPU */
-
-#ifdef CONFIG_SMP
- unsigned long loops_per_jiffy;
- int cpu;
- unsigned int socket_id; /* physical processor socket id */
- unsigned short core_id; /* core id */
- unsigned short thread_id; /* thread id */
- unsigned short num_log; /* Total number of logical processors on
- * this socket that were successfully booted */
- unsigned char cores_per_socket; /* Cores per processor socket */
- unsigned char threads_per_core; /* Threads per core */
-#endif
-
- /* CPUID-derived information: */
- unsigned long ppn;
- unsigned long features;
- unsigned char number;
- unsigned char revision;
- unsigned char model;
- unsigned char family;
- unsigned char archrev;
- char vendor[16];
- char *model_name;
-
-#ifdef CONFIG_NUMA
- struct ia64_node_data *node_data;
-#endif
-};
-
-DECLARE_PER_CPU(struct cpuinfo_ia64, ia64_cpu_info);
-
-/*
- * The "local" data variable. It refers to the per-CPU data of the currently executing
- * CPU, much like "current" points to the per-task data of the currently executing task.
- * Do not use the address of local_cpu_data, since it will be different from
- * cpu_data(smp_processor_id())!
- */
-#define local_cpu_data (&__ia64_per_cpu_var(ia64_cpu_info))
-#define cpu_data(cpu) (&per_cpu(ia64_cpu_info, cpu))
-
-extern void print_cpu_info (struct cpuinfo_ia64 *);
-
-#define SET_UNALIGN_CTL(task,value) \
-({ \
- (task)->thread.flags = (((task)->thread.flags & ~IA64_THREAD_UAC_MASK) \
- | (((value) << IA64_THREAD_UAC_SHIFT) & IA64_THREAD_UAC_MASK)); \
- 0; \
-})
-#define GET_UNALIGN_CTL(task,addr) \
-({ \
- put_user(((task)->thread.flags & IA64_THREAD_UAC_MASK) >> IA64_THREAD_UAC_SHIFT, \
- (int __user *) (addr)); \
-})
-
-#define SET_FPEMU_CTL(task,value) \
-({ \
- (task)->thread.flags = (((task)->thread.flags & ~IA64_THREAD_FPEMU_MASK) \
- | (((value) << IA64_THREAD_FPEMU_SHIFT) & IA64_THREAD_FPEMU_MASK)); \
- 0; \
-})
-#define GET_FPEMU_CTL(task,addr) \
-({ \
- put_user(((task)->thread.flags & IA64_THREAD_FPEMU_MASK) >> IA64_THREAD_FPEMU_SHIFT, \
- (int __user *) (addr)); \
-})
-
-struct thread_struct {
- __u32 flags; /* various thread flags (see IA64_THREAD_*) */
- /* writing on_ustack is performance-critical, so it's worth spending 8 bits on it... */
- __u8 on_ustack; /* executing on user-stacks? */
- __u8 pad[3];
- __u64 ksp; /* kernel stack pointer */
- __u64 map_base; /* base address for get_unmapped_area() */
- __u64 rbs_bot; /* the base address for the RBS */
- int last_fph_cpu; /* CPU that may hold the contents of f32-f127 */
- unsigned long dbr[IA64_NUM_DBG_REGS];
- unsigned long ibr[IA64_NUM_DBG_REGS];
- struct ia64_fpreg fph[96]; /* saved/loaded on demand */
-};
-
-#define INIT_THREAD { \
- .flags = 0, \
- .on_ustack = 0, \
- .ksp = 0, \
- .map_base = DEFAULT_MAP_BASE, \
- .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
- .last_fph_cpu = -1, \
- .dbr = {0, }, \
- .ibr = {0, }, \
- .fph = {{{{0}}}, } \
-}
-
-#define start_thread(regs,new_ip,new_sp) do { \
- regs->cr_ipsr = ((regs->cr_ipsr | (IA64_PSR_BITS_TO_SET | IA64_PSR_CPL)) \
- & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_RI | IA64_PSR_IS)); \
- regs->cr_iip = new_ip; \
- regs->ar_rsc = 0xf; /* eager mode, privilege level 3 */ \
- regs->ar_rnat = 0; \
- regs->ar_bspstore = current->thread.rbs_bot; \
- regs->ar_fpsr = FPSR_DEFAULT; \
- regs->loadrs = 0; \
- regs->r8 = get_dumpable(current->mm); /* set "don't zap registers" flag */ \
- regs->r12 = new_sp - 16; /* allocate 16 byte scratch area */ \
- if (unlikely(get_dumpable(current->mm) != SUID_DUMP_USER)) { \
- /* \
- * Zap scratch regs to avoid leaking bits between processes with different \
- * uid/privileges. \
- */ \
- regs->ar_pfs = 0; regs->b0 = 0; regs->pr = 0; \
- regs->r1 = 0; regs->r9 = 0; regs->r11 = 0; regs->r13 = 0; regs->r15 = 0; \
- } \
-} while (0)
-
-/* Forward declarations, a strange C thing... */
-struct mm_struct;
-struct task_struct;
-
-/* Get wait channel for task P. */
-extern unsigned long __get_wchan (struct task_struct *p);
-
-/* Return instruction pointer of blocked task TSK. */
-#define KSTK_EIP(tsk) \
- ({ \
- struct pt_regs *_regs = task_pt_regs(tsk); \
- _regs->cr_iip + ia64_psr(_regs)->ri; \
- })
-
-/* Return stack pointer of blocked task TSK. */
-#define KSTK_ESP(tsk) ((tsk)->thread.ksp)
-
-extern void ia64_getreg_unknown_kr (void);
-extern void ia64_setreg_unknown_kr (void);
-
-#define ia64_get_kr(regnum) \
-({ \
- unsigned long r = 0; \
- \
- switch (regnum) { \
- case 0: r = ia64_getreg(_IA64_REG_AR_KR0); break; \
- case 1: r = ia64_getreg(_IA64_REG_AR_KR1); break; \
- case 2: r = ia64_getreg(_IA64_REG_AR_KR2); break; \
- case 3: r = ia64_getreg(_IA64_REG_AR_KR3); break; \
- case 4: r = ia64_getreg(_IA64_REG_AR_KR4); break; \
- case 5: r = ia64_getreg(_IA64_REG_AR_KR5); break; \
- case 6: r = ia64_getreg(_IA64_REG_AR_KR6); break; \
- case 7: r = ia64_getreg(_IA64_REG_AR_KR7); break; \
- default: ia64_getreg_unknown_kr(); break; \
- } \
- r; \
-})
-
-#define ia64_set_kr(regnum, r) \
-({ \
- switch (regnum) { \
- case 0: ia64_setreg(_IA64_REG_AR_KR0, r); break; \
- case 1: ia64_setreg(_IA64_REG_AR_KR1, r); break; \
- case 2: ia64_setreg(_IA64_REG_AR_KR2, r); break; \
- case 3: ia64_setreg(_IA64_REG_AR_KR3, r); break; \
- case 4: ia64_setreg(_IA64_REG_AR_KR4, r); break; \
- case 5: ia64_setreg(_IA64_REG_AR_KR5, r); break; \
- case 6: ia64_setreg(_IA64_REG_AR_KR6, r); break; \
- case 7: ia64_setreg(_IA64_REG_AR_KR7, r); break; \
- default: ia64_setreg_unknown_kr(); break; \
- } \
-})
-
-/*
- * The following three macros can't be inline functions because we don't have struct
- * task_struct at this point.
- */
-
-/*
- * Return TRUE if task T owns the fph partition of the CPU we're running on.
- * Must be called from code that has preemption disabled.
- */
-#define ia64_is_local_fpu_owner(t) \
-({ \
- struct task_struct *__ia64_islfo_task = (t); \
- (__ia64_islfo_task->thread.last_fph_cpu == smp_processor_id() \
- && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER)); \
-})
-
-/*
- * Mark task T as owning the fph partition of the CPU we're running on.
- * Must be called from code that has preemption disabled.
- */
-#define ia64_set_local_fpu_owner(t) do { \
- struct task_struct *__ia64_slfo_task = (t); \
- __ia64_slfo_task->thread.last_fph_cpu = smp_processor_id(); \
- ia64_set_kr(IA64_KR_FPU_OWNER, (unsigned long) __ia64_slfo_task); \
-} while (0)
-
-/* Mark the fph partition of task T as being invalid on all CPUs. */
-#define ia64_drop_fpu(t) ((t)->thread.last_fph_cpu = -1)
-
-extern void __ia64_init_fpu (void);
-extern void __ia64_save_fpu (struct ia64_fpreg *fph);
-extern void __ia64_load_fpu (struct ia64_fpreg *fph);
-extern void ia64_save_debug_regs (unsigned long *save_area);
-extern void ia64_load_debug_regs (unsigned long *save_area);
-
-#define ia64_fph_enable() do { ia64_rsm(IA64_PSR_DFH); ia64_srlz_d(); } while (0)
-#define ia64_fph_disable() do { ia64_ssm(IA64_PSR_DFH); ia64_srlz_d(); } while (0)
-
-/* load fp 0.0 into fph */
-static inline void
-ia64_init_fpu (void) {
- ia64_fph_enable();
- __ia64_init_fpu();
- ia64_fph_disable();
-}
-
-/* save f32-f127 at FPH */
-static inline void
-ia64_save_fpu (struct ia64_fpreg *fph) {
- ia64_fph_enable();
- __ia64_save_fpu(fph);
- ia64_fph_disable();
-}
-
-/* load f32-f127 from FPH */
-static inline void
-ia64_load_fpu (struct ia64_fpreg *fph) {
- ia64_fph_enable();
- __ia64_load_fpu(fph);
- ia64_fph_disable();
-}
-
-static inline __u64
-ia64_clear_ic (void)
-{
- __u64 psr;
- psr = ia64_getreg(_IA64_REG_PSR);
- ia64_stop();
- ia64_rsm(IA64_PSR_I | IA64_PSR_IC);
- ia64_srlz_i();
- return psr;
-}
-
-/*
- * Restore the psr.
- */
-static inline void
-ia64_set_psr (__u64 psr)
-{
- ia64_stop();
- ia64_setreg(_IA64_REG_PSR_L, psr);
- ia64_srlz_i();
-}
-
-/*
- * Insert a translation into an instruction and/or data translation
- * register.
- */
-static inline void
-ia64_itr (__u64 target_mask, __u64 tr_num,
- __u64 vmaddr, __u64 pte,
- __u64 log_page_size)
-{
- ia64_setreg(_IA64_REG_CR_ITIR, (log_page_size << 2));
- ia64_setreg(_IA64_REG_CR_IFA, vmaddr);
- ia64_stop();
- if (target_mask & 0x1)
- ia64_itri(tr_num, pte);
- if (target_mask & 0x2)
- ia64_itrd(tr_num, pte);
-}
-
-/*
- * Insert a translation into the instruction and/or data translation
- * cache.
- */
-static inline void
-ia64_itc (__u64 target_mask, __u64 vmaddr, __u64 pte,
- __u64 log_page_size)
-{
- ia64_setreg(_IA64_REG_CR_ITIR, (log_page_size << 2));
- ia64_setreg(_IA64_REG_CR_IFA, vmaddr);
- ia64_stop();
- /* as per EAS2.6, itc must be the last instruction in an instruction group */
- if (target_mask & 0x1)
- ia64_itci(pte);
- if (target_mask & 0x2)
- ia64_itcd(pte);
-}
-
-/*
- * Purge a range of addresses from instruction and/or data translation
- * register(s).
- */
-static inline void
-ia64_ptr (__u64 target_mask, __u64 vmaddr, __u64 log_size)
-{
- if (target_mask & 0x1)
- ia64_ptri(vmaddr, (log_size << 2));
- if (target_mask & 0x2)
- ia64_ptrd(vmaddr, (log_size << 2));
-}
-
-/* Set the interrupt vector address. The address must be suitably aligned (32KB). */
-static inline void
-ia64_set_iva (void *ivt_addr)
-{
- ia64_setreg(_IA64_REG_CR_IVA, (__u64) ivt_addr);
- ia64_srlz_i();
-}
-
-/* Set the page table address and control bits. */
-static inline void
-ia64_set_pta (__u64 pta)
-{
- /* Note: srlz.i implies srlz.d */
- ia64_setreg(_IA64_REG_CR_PTA, pta);
- ia64_srlz_i();
-}
-
-static inline void
-ia64_eoi (void)
-{
- ia64_setreg(_IA64_REG_CR_EOI, 0);
- ia64_srlz_d();
-}
-
-#define cpu_relax() ia64_hint(ia64_hint_pause)
-
-static inline int
-ia64_get_irr(unsigned int vector)
-{
- unsigned int reg = vector / 64;
- unsigned int bit = vector % 64;
- unsigned long irr;
-
- switch (reg) {
- case 0: irr = ia64_getreg(_IA64_REG_CR_IRR0); break;
- case 1: irr = ia64_getreg(_IA64_REG_CR_IRR1); break;
- case 2: irr = ia64_getreg(_IA64_REG_CR_IRR2); break;
- case 3: irr = ia64_getreg(_IA64_REG_CR_IRR3); break;
- }
-
- return test_bit(bit, &irr);
-}
-
-static inline void
-ia64_set_lrr0 (unsigned long val)
-{
- ia64_setreg(_IA64_REG_CR_LRR0, val);
- ia64_srlz_d();
-}
-
-static inline void
-ia64_set_lrr1 (unsigned long val)
-{
- ia64_setreg(_IA64_REG_CR_LRR1, val);
- ia64_srlz_d();
-}
-
-
-/*
- * Given the address to which a spill occurred, return the unat bit
- * number that corresponds to this address.
- */
-static inline __u64
-ia64_unat_pos (void *spill_addr)
-{
- return ((__u64) spill_addr >> 3) & 0x3f;
-}
-
-/*
- * Set the NaT bit of an integer register which was spilled at address
- * SPILL_ADDR. UNAT is the mask to be updated.
- */
-static inline void
-ia64_set_unat (__u64 *unat, void *spill_addr, unsigned long nat)
-{
- __u64 bit = ia64_unat_pos(spill_addr);
- __u64 mask = 1UL << bit;
-
- *unat = (*unat & ~mask) | (nat << bit);
-}
-
-static inline __u64
-ia64_get_ivr (void)
-{
- __u64 r;
- ia64_srlz_d();
- r = ia64_getreg(_IA64_REG_CR_IVR);
- ia64_srlz_d();
- return r;
-}
-
-static inline void
-ia64_set_dbr (__u64 regnum, __u64 value)
-{
- __ia64_set_dbr(regnum, value);
-#ifdef CONFIG_ITANIUM
- ia64_srlz_d();
-#endif
-}
-
-static inline __u64
-ia64_get_dbr (__u64 regnum)
-{
- __u64 retval;
-
- retval = __ia64_get_dbr(regnum);
-#ifdef CONFIG_ITANIUM
- ia64_srlz_d();
-#endif
- return retval;
-}
-
-static inline __u64
-ia64_rotr (__u64 w, __u64 n)
-{
- return (w >> n) | (w << (64 - n));
-}
-
-#define ia64_rotl(w,n) ia64_rotr((w), (64) - (n))
-
-/*
- * Take a mapped kernel address and return the equivalent address
- * in the region 7 identity mapped virtual area.
- */
-static inline void *
-ia64_imva (void *addr)
-{
- void *result;
- result = (void *) ia64_tpa(addr);
- return __va(result);
-}
-
-#define ARCH_HAS_PREFETCH
-#define ARCH_HAS_PREFETCHW
-#define PREFETCH_STRIDE L1_CACHE_BYTES
-
-static inline void
-prefetch (const void *x)
-{
- ia64_lfetch(ia64_lfhint_none, x);
-}
-
-static inline void
-prefetchw (const void *x)
-{
- ia64_lfetch_excl(ia64_lfhint_none, x);
-}
-
-extern unsigned long boot_option_idle_override;
-
-enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_FORCE_MWAIT,
- IDLE_NOMWAIT, IDLE_POLL};
-
-void default_idle(void);
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _ASM_IA64_PROCESSOR_H */
diff --git a/arch/ia64/include/asm/ptrace.h b/arch/ia64/include/asm/ptrace.h
deleted file mode 100644
index 402874489890..000000000000
--- a/arch/ia64/include/asm/ptrace.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 1998-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 2003 Intel Co
- * Suresh Siddha <suresh.b.siddha@intel.com>
- * Fenghua Yu <fenghua.yu@intel.com>
- * Arun Sharma <arun.sharma@intel.com>
- *
- * 12/07/98 S. Eranian added pt_regs & switch_stack
- * 12/21/98 D. Mosberger updated to match latest code
- * 6/17/99 D. Mosberger added second unat member to "struct switch_stack"
- *
- */
-#ifndef _ASM_IA64_PTRACE_H
-#define _ASM_IA64_PTRACE_H
-
-#ifndef ASM_OFFSETS_C
-#include <asm/asm-offsets.h>
-#endif
-#include <uapi/asm/ptrace.h>
-
-/*
- * Base-2 logarithm of number of pages to allocate per task structure
- * (including register backing store and memory stack):
- */
-#if defined(CONFIG_IA64_PAGE_SIZE_4KB)
-# define KERNEL_STACK_SIZE_ORDER 3
-#elif defined(CONFIG_IA64_PAGE_SIZE_8KB)
-# define KERNEL_STACK_SIZE_ORDER 2
-#elif defined(CONFIG_IA64_PAGE_SIZE_16KB)
-# define KERNEL_STACK_SIZE_ORDER 1
-#else
-# define KERNEL_STACK_SIZE_ORDER 0
-#endif
-
-#define IA64_RBS_OFFSET ((IA64_TASK_SIZE + IA64_THREAD_INFO_SIZE + 31) & ~31)
-#define IA64_STK_OFFSET ((1 << KERNEL_STACK_SIZE_ORDER)*PAGE_SIZE)
-
-#define KERNEL_STACK_SIZE IA64_STK_OFFSET
-
-#ifndef __ASSEMBLY__
-
-#include <asm/current.h>
-#include <asm/page.h>
-
-/*
- * We use the ia64_psr(regs)->ri to determine which of the three
- * instructions in bundle (16 bytes) took the sample. Generate
- * the canonical representation by adding to instruction pointer.
- */
-# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
-# define instruction_pointer_set(regs, val) \
-({ \
- ia64_psr(regs)->ri = (val & 0xf); \
- regs->cr_iip = (val & ~0xfULL); \
-})
-
-static inline unsigned long user_stack_pointer(struct pt_regs *regs)
-{
- return regs->r12;
-}
-
-static inline int is_syscall_success(struct pt_regs *regs)
-{
- return regs->r10 != -1;
-}
-
-static inline long regs_return_value(struct pt_regs *regs)
-{
- if (is_syscall_success(regs))
- return regs->r8;
- else
- return -regs->r8;
-}
-
-/* Conserve space in histogram by encoding slot bits in address
- * bits 2 and 3 rather than bits 0 and 1.
- */
-#define profile_pc(regs) \
-({ \
- unsigned long __ip = instruction_pointer(regs); \
- (__ip & ~3UL) + ((__ip & 3UL) << 2); \
-})
-
- /* given a pointer to a task_struct, return the user's pt_regs */
-# define task_pt_regs(t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
-# define ia64_psr(regs) ((struct ia64_psr *) &(regs)->cr_ipsr)
-# define user_mode(regs) (((struct ia64_psr *) &(regs)->cr_ipsr)->cpl != 0)
-# define user_stack(task,regs) ((long) regs - (long) task == IA64_STK_OFFSET - sizeof(*regs))
-# define fsys_mode(task,regs) \
- ({ \
- struct task_struct *_task = (task); \
- struct pt_regs *_regs = (regs); \
- !user_mode(_regs) && user_stack(_task, _regs); \
- })
-
- /*
- * System call handlers that, upon successful completion, need to return a negative value
- * should call force_successful_syscall_return() right before returning. On architectures
- * where the syscall convention provides for a separate error flag (e.g., alpha, ia64,
- * ppc{,64}, sparc{,64}, possibly others), this macro can be used to ensure that the error
- * flag will not get set. On architectures which do not support a separate error flag,
- * the macro is a no-op and the spurious error condition needs to be filtered out by some
- * other means (e.g., in user-level, by passing an extra argument to the syscall handler,
- * or something along those lines).
- *
- * On ia64, we can clear the user's pt_regs->r8 to force a successful syscall.
- */
-# define force_successful_syscall_return() (task_pt_regs(current)->r8 = 0)
-
- struct task_struct; /* forward decl */
- struct unw_frame_info; /* forward decl */
-
- extern unsigned long ia64_get_user_rbs_end (struct task_struct *, struct pt_regs *,
- unsigned long *);
- extern long ia64_peek (struct task_struct *, struct switch_stack *, unsigned long,
- unsigned long, long *);
- extern long ia64_poke (struct task_struct *, struct switch_stack *, unsigned long,
- unsigned long, long);
- extern void ia64_flush_fph (struct task_struct *);
- extern void ia64_sync_fph (struct task_struct *);
- extern void ia64_sync_krbs(void);
- extern long ia64_sync_user_rbs (struct task_struct *, struct switch_stack *,
- unsigned long, unsigned long);
-
- /* get nat bits for scratch registers such that bit N==1 iff scratch register rN is a NaT */
- extern unsigned long ia64_get_scratch_nat_bits (struct pt_regs *pt, unsigned long scratch_unat);
- /* put nat bits for scratch registers such that scratch register rN is a NaT iff bit N==1 */
- extern unsigned long ia64_put_scratch_nat_bits (struct pt_regs *pt, unsigned long nat);
-
- extern void ia64_increment_ip (struct pt_regs *pt);
- extern void ia64_decrement_ip (struct pt_regs *pt);
-
- extern void ia64_ptrace_stop(void);
- #define arch_ptrace_stop() \
- ia64_ptrace_stop()
- #define arch_ptrace_stop_needed() \
- (!test_thread_flag(TIF_RESTORE_RSE))
-
- #define arch_has_single_step() (1)
- #define arch_has_block_step() (1)
-
-#endif /* !__ASSEMBLY__ */
-#endif /* _ASM_IA64_PTRACE_H */
diff --git a/arch/ia64/include/asm/sal.h b/arch/ia64/include/asm/sal.h
deleted file mode 100644
index 22749a201e92..000000000000
--- a/arch/ia64/include/asm/sal.h
+++ /dev/null
@@ -1,919 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_SAL_H
-#define _ASM_IA64_SAL_H
-
-/*
- * System Abstraction Layer definitions.
- *
- * This is based on version 2.5 of the manual "IA-64 System
- * Abstraction Layer".
- *
- * Copyright (C) 2001 Intel
- * Copyright (C) 2002 Jenna Hall <jenna.s.hall@intel.com>
- * Copyright (C) 2001 Fred Lewis <frederick.v.lewis@intel.com>
- * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Srinivasa Prasad Thirumalachar <sprasad@sprasad.engr.sgi.com>
- *
- * 02/01/04 J. Hall Updated Error Record Structures to conform to July 2001
- * revision of the SAL spec.
- * 01/01/03 fvlewis Updated Error Record Structures to conform with Nov. 2000
- * revision of the SAL spec.
- * 99/09/29 davidm Updated for SAL 2.6.
- * 00/03/29 cfleck Updated SAL Error Logging info for processor (SAL 2.6)
- * (plus examples of platform error info structures from smariset @ Intel)
- */
-
-#define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK_BIT 0
-#define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT_BIT 1
-#define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT_BIT 2
-#define IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT 3
-
-#define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK (1<<IA64_SAL_PLATFORM_FEATURE_BUS_LOCK_BIT)
-#define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT (1<<IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT_BIT)
-#define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT (1<<IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT_BIT)
-#define IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT (1<<IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT)
-
-#ifndef __ASSEMBLY__
-
-#include <linux/bcd.h>
-#include <linux/spinlock.h>
-#include <linux/efi.h>
-
-#include <asm/pal.h>
-#include <asm/fpu.h>
-
-extern unsigned long sal_systab_phys;
-extern spinlock_t sal_lock;
-
-/* SAL spec _requires_ eight args for each call. */
-#define __IA64_FW_CALL(entry,result,a0,a1,a2,a3,a4,a5,a6,a7) \
- result = (*entry)(a0,a1,a2,a3,a4,a5,a6,a7)
-
-# define IA64_FW_CALL(entry,result,args...) do { \
- unsigned long __ia64_sc_flags; \
- struct ia64_fpreg __ia64_sc_fr[6]; \
- ia64_save_scratch_fpregs(__ia64_sc_fr); \
- spin_lock_irqsave(&sal_lock, __ia64_sc_flags); \
- __IA64_FW_CALL(entry, result, args); \
- spin_unlock_irqrestore(&sal_lock, __ia64_sc_flags); \
- ia64_load_scratch_fpregs(__ia64_sc_fr); \
-} while (0)
-
-# define SAL_CALL(result,args...) \
- IA64_FW_CALL(ia64_sal, result, args);
-
-# define SAL_CALL_NOLOCK(result,args...) do { \
- unsigned long __ia64_scn_flags; \
- struct ia64_fpreg __ia64_scn_fr[6]; \
- ia64_save_scratch_fpregs(__ia64_scn_fr); \
- local_irq_save(__ia64_scn_flags); \
- __IA64_FW_CALL(ia64_sal, result, args); \
- local_irq_restore(__ia64_scn_flags); \
- ia64_load_scratch_fpregs(__ia64_scn_fr); \
-} while (0)
-
-# define SAL_CALL_REENTRANT(result,args...) do { \
- struct ia64_fpreg __ia64_scs_fr[6]; \
- ia64_save_scratch_fpregs(__ia64_scs_fr); \
- preempt_disable(); \
- __IA64_FW_CALL(ia64_sal, result, args); \
- preempt_enable(); \
- ia64_load_scratch_fpregs(__ia64_scs_fr); \
-} while (0)
-
-#define SAL_SET_VECTORS 0x01000000
-#define SAL_GET_STATE_INFO 0x01000001
-#define SAL_GET_STATE_INFO_SIZE 0x01000002
-#define SAL_CLEAR_STATE_INFO 0x01000003
-#define SAL_MC_RENDEZ 0x01000004
-#define SAL_MC_SET_PARAMS 0x01000005
-#define SAL_REGISTER_PHYSICAL_ADDR 0x01000006
-
-#define SAL_CACHE_FLUSH 0x01000008
-#define SAL_CACHE_INIT 0x01000009
-#define SAL_PCI_CONFIG_READ 0x01000010
-#define SAL_PCI_CONFIG_WRITE 0x01000011
-#define SAL_FREQ_BASE 0x01000012
-#define SAL_PHYSICAL_ID_INFO 0x01000013
-
-#define SAL_UPDATE_PAL 0x01000020
-
-struct ia64_sal_retval {
- /*
- * A zero status value indicates call completed without error.
- * A negative status value indicates reason of call failure.
- * A positive status value indicates success but an
- * informational value should be printed (e.g., "reboot for
- * change to take effect").
- */
- long status;
- unsigned long v0;
- unsigned long v1;
- unsigned long v2;
-};
-
-typedef struct ia64_sal_retval (*ia64_sal_handler) (u64, ...);
-
-enum {
- SAL_FREQ_BASE_PLATFORM = 0,
- SAL_FREQ_BASE_INTERVAL_TIMER = 1,
- SAL_FREQ_BASE_REALTIME_CLOCK = 2
-};
-
-/*
- * The SAL system table is followed by a variable number of variable
- * length descriptors. The structure of these descriptors follows
- * below.
- * The defininition follows SAL specs from July 2000
- */
-struct ia64_sal_systab {
- u8 signature[4]; /* should be "SST_" */
- u32 size; /* size of this table in bytes */
- u8 sal_rev_minor;
- u8 sal_rev_major;
- u16 entry_count; /* # of entries in variable portion */
- u8 checksum;
- u8 reserved1[7];
- u8 sal_a_rev_minor;
- u8 sal_a_rev_major;
- u8 sal_b_rev_minor;
- u8 sal_b_rev_major;
- /* oem_id & product_id: terminating NUL is missing if string is exactly 32 bytes long. */
- u8 oem_id[32];
- u8 product_id[32]; /* ASCII product id */
- u8 reserved2[8];
-};
-
-enum sal_systab_entry_type {
- SAL_DESC_ENTRY_POINT = 0,
- SAL_DESC_MEMORY = 1,
- SAL_DESC_PLATFORM_FEATURE = 2,
- SAL_DESC_TR = 3,
- SAL_DESC_PTC = 4,
- SAL_DESC_AP_WAKEUP = 5
-};
-
-/*
- * Entry type: Size:
- * 0 48
- * 1 32
- * 2 16
- * 3 32
- * 4 16
- * 5 16
- */
-#define SAL_DESC_SIZE(type) "\060\040\020\040\020\020"[(unsigned) type]
-
-typedef struct ia64_sal_desc_entry_point {
- u8 type;
- u8 reserved1[7];
- u64 pal_proc;
- u64 sal_proc;
- u64 gp;
- u8 reserved2[16];
-}ia64_sal_desc_entry_point_t;
-
-typedef struct ia64_sal_desc_memory {
- u8 type;
- u8 used_by_sal; /* needs to be mapped for SAL? */
- u8 mem_attr; /* current memory attribute setting */
- u8 access_rights; /* access rights set up by SAL */
- u8 mem_attr_mask; /* mask of supported memory attributes */
- u8 reserved1;
- u8 mem_type; /* memory type */
- u8 mem_usage; /* memory usage */
- u64 addr; /* physical address of memory */
- u32 length; /* length (multiple of 4KB pages) */
- u32 reserved2;
- u8 oem_reserved[8];
-} ia64_sal_desc_memory_t;
-
-typedef struct ia64_sal_desc_platform_feature {
- u8 type;
- u8 feature_mask;
- u8 reserved1[14];
-} ia64_sal_desc_platform_feature_t;
-
-typedef struct ia64_sal_desc_tr {
- u8 type;
- u8 tr_type; /* 0 == instruction, 1 == data */
- u8 regnum; /* translation register number */
- u8 reserved1[5];
- u64 addr; /* virtual address of area covered */
- u64 page_size; /* encoded page size */
- u8 reserved2[8];
-} ia64_sal_desc_tr_t;
-
-typedef struct ia64_sal_desc_ptc {
- u8 type;
- u8 reserved1[3];
- u32 num_domains; /* # of coherence domains */
- u64 domain_info; /* physical address of domain info table */
-} ia64_sal_desc_ptc_t;
-
-typedef struct ia64_sal_ptc_domain_info {
- u64 proc_count; /* number of processors in domain */
- u64 proc_list; /* physical address of LID array */
-} ia64_sal_ptc_domain_info_t;
-
-typedef struct ia64_sal_ptc_domain_proc_entry {
- u64 id : 8; /* id of processor */
- u64 eid : 8; /* eid of processor */
-} ia64_sal_ptc_domain_proc_entry_t;
-
-
-#define IA64_SAL_AP_EXTERNAL_INT 0
-
-typedef struct ia64_sal_desc_ap_wakeup {
- u8 type;
- u8 mechanism; /* 0 == external interrupt */
- u8 reserved1[6];
- u64 vector; /* interrupt vector in range 0x10-0xff */
-} ia64_sal_desc_ap_wakeup_t ;
-
-extern ia64_sal_handler ia64_sal;
-extern struct ia64_sal_desc_ptc *ia64_ptc_domain_info;
-
-extern unsigned short sal_revision; /* supported SAL spec revision */
-extern unsigned short sal_version; /* SAL version; OEM dependent */
-#define SAL_VERSION_CODE(major, minor) ((bin2bcd(major) << 8) | bin2bcd(minor))
-
-extern const char *ia64_sal_strerror (long status);
-extern void ia64_sal_init (struct ia64_sal_systab *sal_systab);
-
-/* SAL information type encodings */
-enum {
- SAL_INFO_TYPE_MCA = 0, /* Machine check abort information */
- SAL_INFO_TYPE_INIT = 1, /* Init information */
- SAL_INFO_TYPE_CMC = 2, /* Corrected machine check information */
- SAL_INFO_TYPE_CPE = 3 /* Corrected platform error information */
-};
-
-/* Encodings for machine check parameter types */
-enum {
- SAL_MC_PARAM_RENDEZ_INT = 1, /* Rendezvous interrupt */
- SAL_MC_PARAM_RENDEZ_WAKEUP = 2, /* Wakeup */
- SAL_MC_PARAM_CPE_INT = 3 /* Corrected Platform Error Int */
-};
-
-/* Encodings for rendezvous mechanisms */
-enum {
- SAL_MC_PARAM_MECHANISM_INT = 1, /* Use interrupt */
- SAL_MC_PARAM_MECHANISM_MEM = 2 /* Use memory synchronization variable*/
-};
-
-/* Encodings for vectors which can be registered by the OS with SAL */
-enum {
- SAL_VECTOR_OS_MCA = 0,
- SAL_VECTOR_OS_INIT = 1,
- SAL_VECTOR_OS_BOOT_RENDEZ = 2
-};
-
-/* Encodings for mca_opt parameter sent to SAL_MC_SET_PARAMS */
-#define SAL_MC_PARAM_RZ_ALWAYS 0x1
-#define SAL_MC_PARAM_BINIT_ESCALATE 0x10
-
-/*
- * Definition of the SAL Error Log from the SAL spec
- */
-
-/* SAL Error Record Section GUID Definitions */
-#define SAL_PROC_DEV_ERR_SECT_GUID \
- EFI_GUID(0xe429faf1, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-#define SAL_PLAT_MEM_DEV_ERR_SECT_GUID \
- EFI_GUID(0xe429faf2, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-#define SAL_PLAT_SEL_DEV_ERR_SECT_GUID \
- EFI_GUID(0xe429faf3, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-#define SAL_PLAT_PCI_BUS_ERR_SECT_GUID \
- EFI_GUID(0xe429faf4, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-#define SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID \
- EFI_GUID(0xe429faf5, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-#define SAL_PLAT_PCI_COMP_ERR_SECT_GUID \
- EFI_GUID(0xe429faf6, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-#define SAL_PLAT_SPECIFIC_ERR_SECT_GUID \
- EFI_GUID(0xe429faf7, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-#define SAL_PLAT_HOST_CTLR_ERR_SECT_GUID \
- EFI_GUID(0xe429faf8, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-#define SAL_PLAT_BUS_ERR_SECT_GUID \
- EFI_GUID(0xe429faf9, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-#define PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID \
- EFI_GUID(0x6cb0a200, 0x893a, 0x11da, 0x96, 0xd2, 0x0, 0x10, 0x83, 0xff, \
- 0xca, 0x4d)
-
-#define MAX_CACHE_ERRORS 6
-#define MAX_TLB_ERRORS 6
-#define MAX_BUS_ERRORS 1
-
-/* Definition of version according to SAL spec for logging purposes */
-typedef struct sal_log_revision {
- u8 minor; /* BCD (0..99) */
- u8 major; /* BCD (0..99) */
-} sal_log_revision_t;
-
-/* Definition of timestamp according to SAL spec for logging purposes */
-typedef struct sal_log_timestamp {
- u8 slh_second; /* Second (0..59) */
- u8 slh_minute; /* Minute (0..59) */
- u8 slh_hour; /* Hour (0..23) */
- u8 slh_reserved;
- u8 slh_day; /* Day (1..31) */
- u8 slh_month; /* Month (1..12) */
- u8 slh_year; /* Year (00..99) */
- u8 slh_century; /* Century (19, 20, 21, ...) */
-} sal_log_timestamp_t;
-
-/* Definition of log record header structures */
-typedef struct sal_log_record_header {
- u64 id; /* Unique monotonically increasing ID */
- sal_log_revision_t revision; /* Major and Minor revision of header */
- u8 severity; /* Error Severity */
- u8 validation_bits; /* 0: platform_guid, 1: !timestamp */
- u32 len; /* Length of this error log in bytes */
- sal_log_timestamp_t timestamp; /* Timestamp */
- efi_guid_t platform_guid; /* Unique OEM Platform ID */
-} sal_log_record_header_t;
-
-#define sal_log_severity_recoverable 0
-#define sal_log_severity_fatal 1
-#define sal_log_severity_corrected 2
-
-/*
- * Error Recovery Info (ERI) bit decode. From SAL Spec section B.2.2 Table B-3
- * Error Section Error_Recovery_Info Field Definition.
- */
-#define ERI_NOT_VALID 0x0 /* Error Recovery Field is not valid */
-#define ERI_NOT_ACCESSIBLE 0x30 /* Resource not accessible */
-#define ERI_CONTAINMENT_WARN 0x22 /* Corrupt data propagated */
-#define ERI_UNCORRECTED_ERROR 0x20 /* Uncorrected error */
-#define ERI_COMPONENT_RESET 0x24 /* Component must be reset */
-#define ERI_CORR_ERROR_LOG 0x21 /* Corrected error, needs logging */
-#define ERI_CORR_ERROR_THRESH 0x29 /* Corrected error threshold exceeded */
-
-/* Definition of log section header structures */
-typedef struct sal_log_sec_header {
- efi_guid_t guid; /* Unique Section ID */
- sal_log_revision_t revision; /* Major and Minor revision of Section */
- u8 error_recovery_info; /* Platform error recovery status */
- u8 reserved;
- u32 len; /* Section length */
-} sal_log_section_hdr_t;
-
-typedef struct sal_log_mod_error_info {
- struct {
- u64 check_info : 1,
- requestor_identifier : 1,
- responder_identifier : 1,
- target_identifier : 1,
- precise_ip : 1,
- reserved : 59;
- } valid;
- u64 check_info;
- u64 requestor_identifier;
- u64 responder_identifier;
- u64 target_identifier;
- u64 precise_ip;
-} sal_log_mod_error_info_t;
-
-typedef struct sal_processor_static_info {
- struct {
- u64 minstate : 1,
- br : 1,
- cr : 1,
- ar : 1,
- rr : 1,
- fr : 1,
- reserved : 58;
- } valid;
- struct pal_min_state_area min_state_area;
- u64 br[8];
- u64 cr[128];
- u64 ar[128];
- u64 rr[8];
- struct ia64_fpreg __attribute__ ((packed)) fr[128];
-} sal_processor_static_info_t;
-
-struct sal_cpuid_info {
- u64 regs[5];
- u64 reserved;
-};
-
-typedef struct sal_log_processor_info {
- sal_log_section_hdr_t header;
- struct {
- u64 proc_error_map : 1,
- proc_state_param : 1,
- proc_cr_lid : 1,
- psi_static_struct : 1,
- num_cache_check : 4,
- num_tlb_check : 4,
- num_bus_check : 4,
- num_reg_file_check : 4,
- num_ms_check : 4,
- cpuid_info : 1,
- reserved1 : 39;
- } valid;
- u64 proc_error_map;
- u64 proc_state_parameter;
- u64 proc_cr_lid;
- /*
- * The rest of this structure consists of variable-length arrays, which can't be
- * expressed in C.
- */
- sal_log_mod_error_info_t info[];
- /*
- * This is what the rest looked like if C supported variable-length arrays:
- *
- * sal_log_mod_error_info_t cache_check_info[.valid.num_cache_check];
- * sal_log_mod_error_info_t tlb_check_info[.valid.num_tlb_check];
- * sal_log_mod_error_info_t bus_check_info[.valid.num_bus_check];
- * sal_log_mod_error_info_t reg_file_check_info[.valid.num_reg_file_check];
- * sal_log_mod_error_info_t ms_check_info[.valid.num_ms_check];
- * struct sal_cpuid_info cpuid_info;
- * sal_processor_static_info_t processor_static_info;
- */
-} sal_log_processor_info_t;
-
-/* Given a sal_log_processor_info_t pointer, return a pointer to the processor_static_info: */
-#define SAL_LPI_PSI_INFO(l) \
-({ sal_log_processor_info_t *_l = (l); \
- ((sal_processor_static_info_t *) \
- ((char *) _l->info + ((_l->valid.num_cache_check + _l->valid.num_tlb_check \
- + _l->valid.num_bus_check + _l->valid.num_reg_file_check \
- + _l->valid.num_ms_check) * sizeof(sal_log_mod_error_info_t) \
- + sizeof(struct sal_cpuid_info)))); \
-})
-
-/* platform error log structures */
-
-typedef struct sal_log_mem_dev_err_info {
- sal_log_section_hdr_t header;
- struct {
- u64 error_status : 1,
- physical_addr : 1,
- addr_mask : 1,
- node : 1,
- card : 1,
- module : 1,
- bank : 1,
- device : 1,
- row : 1,
- column : 1,
- bit_position : 1,
- requestor_id : 1,
- responder_id : 1,
- target_id : 1,
- bus_spec_data : 1,
- oem_id : 1,
- oem_data : 1,
- reserved : 47;
- } valid;
- u64 error_status;
- u64 physical_addr;
- u64 addr_mask;
- u16 node;
- u16 card;
- u16 module;
- u16 bank;
- u16 device;
- u16 row;
- u16 column;
- u16 bit_position;
- u64 requestor_id;
- u64 responder_id;
- u64 target_id;
- u64 bus_spec_data;
- u8 oem_id[16];
- u8 oem_data[1]; /* Variable length data */
-} sal_log_mem_dev_err_info_t;
-
-typedef struct sal_log_sel_dev_err_info {
- sal_log_section_hdr_t header;
- struct {
- u64 record_id : 1,
- record_type : 1,
- generator_id : 1,
- evm_rev : 1,
- sensor_type : 1,
- sensor_num : 1,
- event_dir : 1,
- event_data1 : 1,
- event_data2 : 1,
- event_data3 : 1,
- reserved : 54;
- } valid;
- u16 record_id;
- u8 record_type;
- u8 timestamp[4];
- u16 generator_id;
- u8 evm_rev;
- u8 sensor_type;
- u8 sensor_num;
- u8 event_dir;
- u8 event_data1;
- u8 event_data2;
- u8 event_data3;
-} sal_log_sel_dev_err_info_t;
-
-typedef struct sal_log_pci_bus_err_info {
- sal_log_section_hdr_t header;
- struct {
- u64 err_status : 1,
- err_type : 1,
- bus_id : 1,
- bus_address : 1,
- bus_data : 1,
- bus_cmd : 1,
- requestor_id : 1,
- responder_id : 1,
- target_id : 1,
- oem_data : 1,
- reserved : 54;
- } valid;
- u64 err_status;
- u16 err_type;
- u16 bus_id;
- u32 reserved;
- u64 bus_address;
- u64 bus_data;
- u64 bus_cmd;
- u64 requestor_id;
- u64 responder_id;
- u64 target_id;
- u8 oem_data[1]; /* Variable length data */
-} sal_log_pci_bus_err_info_t;
-
-typedef struct sal_log_smbios_dev_err_info {
- sal_log_section_hdr_t header;
- struct {
- u64 event_type : 1,
- length : 1,
- time_stamp : 1,
- data : 1,
- reserved1 : 60;
- } valid;
- u8 event_type;
- u8 length;
- u8 time_stamp[6];
- u8 data[1]; /* data of variable length, length == slsmb_length */
-} sal_log_smbios_dev_err_info_t;
-
-typedef struct sal_log_pci_comp_err_info {
- sal_log_section_hdr_t header;
- struct {
- u64 err_status : 1,
- comp_info : 1,
- num_mem_regs : 1,
- num_io_regs : 1,
- reg_data_pairs : 1,
- oem_data : 1,
- reserved : 58;
- } valid;
- u64 err_status;
- struct {
- u16 vendor_id;
- u16 device_id;
- u8 class_code[3];
- u8 func_num;
- u8 dev_num;
- u8 bus_num;
- u8 seg_num;
- u8 reserved[5];
- } comp_info;
- u32 num_mem_regs;
- u32 num_io_regs;
- u64 reg_data_pairs[1];
- /*
- * array of address/data register pairs is num_mem_regs + num_io_regs elements
- * long. Each array element consists of a u64 address followed by a u64 data
- * value. The oem_data array immediately follows the reg_data_pairs array
- */
- u8 oem_data[1]; /* Variable length data */
-} sal_log_pci_comp_err_info_t;
-
-typedef struct sal_log_plat_specific_err_info {
- sal_log_section_hdr_t header;
- struct {
- u64 err_status : 1,
- guid : 1,
- oem_data : 1,
- reserved : 61;
- } valid;
- u64 err_status;
- efi_guid_t guid;
- u8 oem_data[1]; /* platform specific variable length data */
-} sal_log_plat_specific_err_info_t;
-
-typedef struct sal_log_host_ctlr_err_info {
- sal_log_section_hdr_t header;
- struct {
- u64 err_status : 1,
- requestor_id : 1,
- responder_id : 1,
- target_id : 1,
- bus_spec_data : 1,
- oem_data : 1,
- reserved : 58;
- } valid;
- u64 err_status;
- u64 requestor_id;
- u64 responder_id;
- u64 target_id;
- u64 bus_spec_data;
- u8 oem_data[1]; /* Variable length OEM data */
-} sal_log_host_ctlr_err_info_t;
-
-typedef struct sal_log_plat_bus_err_info {
- sal_log_section_hdr_t header;
- struct {
- u64 err_status : 1,
- requestor_id : 1,
- responder_id : 1,
- target_id : 1,
- bus_spec_data : 1,
- oem_data : 1,
- reserved : 58;
- } valid;
- u64 err_status;
- u64 requestor_id;
- u64 responder_id;
- u64 target_id;
- u64 bus_spec_data;
- u8 oem_data[1]; /* Variable length OEM data */
-} sal_log_plat_bus_err_info_t;
-
-/* Overall platform error section structure */
-typedef union sal_log_platform_err_info {
- sal_log_mem_dev_err_info_t mem_dev_err;
- sal_log_sel_dev_err_info_t sel_dev_err;
- sal_log_pci_bus_err_info_t pci_bus_err;
- sal_log_smbios_dev_err_info_t smbios_dev_err;
- sal_log_pci_comp_err_info_t pci_comp_err;
- sal_log_plat_specific_err_info_t plat_specific_err;
- sal_log_host_ctlr_err_info_t host_ctlr_err;
- sal_log_plat_bus_err_info_t plat_bus_err;
-} sal_log_platform_err_info_t;
-
-/* SAL log over-all, multi-section error record structure (processor+platform) */
-typedef struct err_rec {
- sal_log_record_header_t sal_elog_header;
- sal_log_processor_info_t proc_err;
- sal_log_platform_err_info_t plat_err;
- u8 oem_data_pad[1024];
-} ia64_err_rec_t;
-
-/*
- * Now define a couple of inline functions for improved type checking
- * and convenience.
- */
-
-extern s64 ia64_sal_cache_flush (u64 cache_type);
-extern void __init check_sal_cache_flush (void);
-
-/* Initialize all the processor and platform level instruction and data caches */
-static inline s64
-ia64_sal_cache_init (void)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL(isrv, SAL_CACHE_INIT, 0, 0, 0, 0, 0, 0, 0);
- return isrv.status;
-}
-
-/*
- * Clear the processor and platform information logged by SAL with respect to the machine
- * state at the time of MCA's, INITs, CMCs, or CPEs.
- */
-static inline s64
-ia64_sal_clear_state_info (u64 sal_info_type)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL_REENTRANT(isrv, SAL_CLEAR_STATE_INFO, sal_info_type, 0,
- 0, 0, 0, 0, 0);
- return isrv.status;
-}
-
-
-/* Get the processor and platform information logged by SAL with respect to the machine
- * state at the time of the MCAs, INITs, CMCs, or CPEs.
- */
-static inline u64
-ia64_sal_get_state_info (u64 sal_info_type, u64 *sal_info)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO, sal_info_type, 0,
- sal_info, 0, 0, 0, 0);
- if (isrv.status)
- return 0;
-
- return isrv.v0;
-}
-
-/*
- * Get the maximum size of the information logged by SAL with respect to the machine state
- * at the time of MCAs, INITs, CMCs, or CPEs.
- */
-static inline u64
-ia64_sal_get_state_info_size (u64 sal_info_type)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO_SIZE, sal_info_type, 0,
- 0, 0, 0, 0, 0);
- if (isrv.status)
- return 0;
- return isrv.v0;
-}
-
-/*
- * Causes the processor to go into a spin loop within SAL where SAL awaits a wakeup from
- * the monarch processor. Must not lock, because it will not return on any cpu until the
- * monarch processor sends a wake up.
- */
-static inline s64
-ia64_sal_mc_rendez (void)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL_NOLOCK(isrv, SAL_MC_RENDEZ, 0, 0, 0, 0, 0, 0, 0);
- return isrv.status;
-}
-
-/*
- * Allow the OS to specify the interrupt number to be used by SAL to interrupt OS during
- * the machine check rendezvous sequence as well as the mechanism to wake up the
- * non-monarch processor at the end of machine check processing.
- * Returns the complete ia64_sal_retval because some calls return more than just a status
- * value.
- */
-static inline struct ia64_sal_retval
-ia64_sal_mc_set_params (u64 param_type, u64 i_or_m, u64 i_or_m_val, u64 timeout, u64 rz_always)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL(isrv, SAL_MC_SET_PARAMS, param_type, i_or_m, i_or_m_val,
- timeout, rz_always, 0, 0);
- return isrv;
-}
-
-/* Read from PCI configuration space */
-static inline s64
-ia64_sal_pci_config_read (u64 pci_config_addr, int type, u64 size, u64 *value)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL(isrv, SAL_PCI_CONFIG_READ, pci_config_addr, size, type, 0, 0, 0, 0);
- if (value)
- *value = isrv.v0;
- return isrv.status;
-}
-
-/* Write to PCI configuration space */
-static inline s64
-ia64_sal_pci_config_write (u64 pci_config_addr, int type, u64 size, u64 value)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL(isrv, SAL_PCI_CONFIG_WRITE, pci_config_addr, size, value,
- type, 0, 0, 0);
- return isrv.status;
-}
-
-/*
- * Register physical addresses of locations needed by SAL when SAL procedures are invoked
- * in virtual mode.
- */
-static inline s64
-ia64_sal_register_physical_addr (u64 phys_entry, u64 phys_addr)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL(isrv, SAL_REGISTER_PHYSICAL_ADDR, phys_entry, phys_addr,
- 0, 0, 0, 0, 0);
- return isrv.status;
-}
-
-/*
- * Register software dependent code locations within SAL. These locations are handlers or
- * entry points where SAL will pass control for the specified event. These event handlers
- * are for the bott rendezvous, MCAs and INIT scenarios.
- */
-static inline s64
-ia64_sal_set_vectors (u64 vector_type,
- u64 handler_addr1, u64 gp1, u64 handler_len1,
- u64 handler_addr2, u64 gp2, u64 handler_len2)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL(isrv, SAL_SET_VECTORS, vector_type,
- handler_addr1, gp1, handler_len1,
- handler_addr2, gp2, handler_len2);
-
- return isrv.status;
-}
-
-/* Update the contents of PAL block in the non-volatile storage device */
-static inline s64
-ia64_sal_update_pal (u64 param_buf, u64 scratch_buf, u64 scratch_buf_size,
- u64 *error_code, u64 *scratch_buf_size_needed)
-{
- struct ia64_sal_retval isrv;
- SAL_CALL(isrv, SAL_UPDATE_PAL, param_buf, scratch_buf, scratch_buf_size,
- 0, 0, 0, 0);
- if (error_code)
- *error_code = isrv.v0;
- if (scratch_buf_size_needed)
- *scratch_buf_size_needed = isrv.v1;
- return isrv.status;
-}
-
-/* Get physical processor die mapping in the platform. */
-static inline s64
-ia64_sal_physical_id_info(u16 *splid)
-{
- struct ia64_sal_retval isrv;
-
- if (sal_revision < SAL_VERSION_CODE(3,2))
- return -1;
-
- SAL_CALL(isrv, SAL_PHYSICAL_ID_INFO, 0, 0, 0, 0, 0, 0, 0);
- if (splid)
- *splid = isrv.v0;
- return isrv.status;
-}
-
-extern unsigned long sal_platform_features;
-
-extern int (*salinfo_platform_oemdata)(const u8 *, u8 **, u64 *);
-
-struct sal_ret_values {
- long r8; long r9; long r10; long r11;
-};
-
-#define IA64_SAL_OEMFUNC_MIN 0x02000000
-#define IA64_SAL_OEMFUNC_MAX 0x03ffffff
-
-extern int ia64_sal_oemcall(struct ia64_sal_retval *, u64, u64, u64, u64, u64,
- u64, u64, u64);
-extern int ia64_sal_oemcall_nolock(struct ia64_sal_retval *, u64, u64, u64,
- u64, u64, u64, u64, u64);
-extern int ia64_sal_oemcall_reentrant(struct ia64_sal_retval *, u64, u64, u64,
- u64, u64, u64, u64, u64);
-extern long
-ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second,
- unsigned long *drift_info);
-#ifdef CONFIG_HOTPLUG_CPU
-/*
- * System Abstraction Layer Specification
- * Section 3.2.5.1: OS_BOOT_RENDEZ to SAL return State.
- * Note: region regs are stored first in head.S _start. Hence they must
- * stay up front.
- */
-struct sal_to_os_boot {
- u64 rr[8]; /* Region Registers */
- u64 br[6]; /* br0:
- * return addr into SAL boot rendez routine */
- u64 gr1; /* SAL:GP */
- u64 gr12; /* SAL:SP */
- u64 gr13; /* SAL: Task Pointer */
- u64 fpsr;
- u64 pfs;
- u64 rnat;
- u64 unat;
- u64 bspstore;
- u64 dcr; /* Default Control Register */
- u64 iva;
- u64 pta;
- u64 itv;
- u64 pmv;
- u64 cmcv;
- u64 lrr[2];
- u64 gr[4];
- u64 pr; /* Predicate registers */
- u64 lc; /* Loop Count */
- struct ia64_fpreg fp[20];
-};
-
-/*
- * Global array allocated for NR_CPUS at boot time
- */
-extern struct sal_to_os_boot sal_boot_rendez_state[NR_CPUS];
-
-extern void ia64_jump_to_sal(struct sal_to_os_boot *);
-#endif
-
-extern void ia64_sal_handler_init(void *entry_point, void *gpval);
-
-#define PALO_MAX_TLB_PURGES 0xFFFF
-#define PALO_SIG "PALO"
-
-struct palo_table {
- u8 signature[4]; /* Should be "PALO" */
- u32 length;
- u8 minor_revision;
- u8 major_revision;
- u8 checksum;
- u8 reserved1[5];
- u16 max_tlb_purges;
- u8 reserved2[6];
-};
-
-#define NPTCG_FROM_PAL 0
-#define NPTCG_FROM_PALO 1
-#define NPTCG_FROM_KERNEL_PARAMETER 2
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_IA64_SAL_H */
diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
deleted file mode 100644
index 8e0875cf6071..000000000000
--- a/arch/ia64/include/asm/sections.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_SECTIONS_H
-#define _ASM_IA64_SECTIONS_H
-
-/*
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/elf.h>
-#include <linux/uaccess.h>
-
-typedef struct fdesc func_desc_t;
-
-#include <asm-generic/sections.h>
-
-extern char __phys_per_cpu_start[];
-#ifdef CONFIG_SMP
-extern char __cpu0_per_cpu[];
-#endif
-extern char __start___vtop_patchlist[], __end___vtop_patchlist[];
-extern char __start___rse_patchlist[], __end___rse_patchlist[];
-extern char __start___mckinley_e9_bundles[], __end___mckinley_e9_bundles[];
-extern char __start___phys_stack_reg_patchlist[], __end___phys_stack_reg_patchlist[];
-extern char __start_gate_section[];
-extern char __start_gate_mckinley_e9_patchlist[], __end_gate_mckinley_e9_patchlist[];
-extern char __start_gate_vtop_patchlist[], __end_gate_vtop_patchlist[];
-extern char __start_gate_fsyscall_patchlist[], __end_gate_fsyscall_patchlist[];
-extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_bubble_down_patchlist[];
-extern char __start_unwind[], __end_unwind[];
-extern char __start_ivt_text[], __end_ivt_text[];
-
-#endif /* _ASM_IA64_SECTIONS_H */
diff --git a/arch/ia64/include/asm/serial.h b/arch/ia64/include/asm/serial.h
deleted file mode 100644
index 068be11583df..000000000000
--- a/arch/ia64/include/asm/serial.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Derived from the i386 version.
- */
-
-/*
- * This assumes you have a 1.8432 MHz clock for your UART.
- *
- * It'd be nice if someone built a serial card with a 24.576 MHz
- * clock, since the 16550A is capable of handling a top speed of 1.5
- * megabits/second; but this requires the faster clock.
- */
-#define BASE_BAUD ( 1843200 / 16 )
-
-/*
- * All legacy serial ports should be enumerated via ACPI namespace, so
- * we need not list them here.
- */
diff --git a/arch/ia64/include/asm/shmparam.h b/arch/ia64/include/asm/shmparam.h
deleted file mode 100644
index 43bd8324ab71..000000000000
--- a/arch/ia64/include/asm/shmparam.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_SHMPARAM_H
-#define _ASM_IA64_SHMPARAM_H
-
-/*
- * SHMLBA controls minimum alignment at which shared memory segments
- * get attached. The IA-64 architecture says that there may be a
- * performance degradation when there are virtual aliases within 1MB.
- * To reduce the chance of this, we set SHMLBA to 1MB. --davidm 00/12/20
- */
-#define SHMLBA (1024*1024)
-
-#endif /* _ASM_IA64_SHMPARAM_H */
diff --git a/arch/ia64/include/asm/signal.h b/arch/ia64/include/asm/signal.h
deleted file mode 100644
index 80f067f9b3ce..000000000000
--- a/arch/ia64/include/asm/signal.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Modified 1998-2001, 2003
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- *
- * Unfortunately, this file is being included by bits/signal.h in
- * glibc-2.x. Hence the #ifdef __KERNEL__ ugliness.
- */
-#ifndef _ASM_IA64_SIGNAL_H
-#define _ASM_IA64_SIGNAL_H
-
-#include <uapi/asm/signal.h>
-
-
-#define _NSIG 64
-#define _NSIG_BPW 64
-#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-
-# ifndef __ASSEMBLY__
-
-/* Most things should be clean enough to redefine this at will, if care
- is taken to make libc match. */
-
-typedef unsigned long old_sigset_t;
-
-typedef struct {
- unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-# include <asm/sigcontext.h>
-
-# endif /* !__ASSEMBLY__ */
-#endif /* _ASM_IA64_SIGNAL_H */
diff --git a/arch/ia64/include/asm/smp.h b/arch/ia64/include/asm/smp.h
deleted file mode 100644
index aa92234c0142..000000000000
--- a/arch/ia64/include/asm/smp.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * SMP Support
- *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * (c) Copyright 2001-2003, 2005 Hewlett-Packard Development Company, L.P.
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- */
-#ifndef _ASM_IA64_SMP_H
-#define _ASM_IA64_SMP_H
-
-#include <linux/init.h>
-#include <linux/threads.h>
-#include <linux/kernel.h>
-#include <linux/cpumask.h>
-#include <linux/bitops.h>
-#include <linux/irqreturn.h>
-
-#include <asm/param.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-
-static inline unsigned int
-ia64_get_lid (void)
-{
- union {
- struct {
- unsigned long reserved : 16;
- unsigned long eid : 8;
- unsigned long id : 8;
- unsigned long ignored : 32;
- } f;
- unsigned long bits;
- } lid;
-
- lid.bits = ia64_getreg(_IA64_REG_CR_LID);
- return lid.f.id << 8 | lid.f.eid;
-}
-
-#define hard_smp_processor_id() ia64_get_lid()
-
-#ifdef CONFIG_SMP
-
-#define raw_smp_processor_id() (current_thread_info()->cpu)
-
-extern struct smp_boot_data {
- int cpu_count;
- int cpu_phys_id[NR_CPUS];
-} smp_boot_data __initdata;
-
-extern char no_int_routing;
-
-extern cpumask_t cpu_core_map[NR_CPUS];
-DECLARE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
-extern int smp_num_siblings;
-extern void __iomem *ipi_base_addr;
-
-extern volatile int ia64_cpu_to_sapicid[];
-#define cpu_physical_id(i) ia64_cpu_to_sapicid[i]
-
-extern unsigned long ap_wakeup_vector;
-
-/*
- * Function to map hard smp processor id to logical id. Slow, so don't use this in
- * performance-critical code.
- */
-static inline int
-cpu_logical_id (int cpuid)
-{
- int i;
-
- for (i = 0; i < NR_CPUS; ++i)
- if (cpu_physical_id(i) == cpuid)
- break;
- return i;
-}
-
-/* Upping and downing of CPUs */
-extern int __cpu_disable (void);
-extern void __cpu_die (unsigned int cpu);
-extern void cpu_die (void) __attribute__ ((noreturn));
-extern void __init smp_build_cpu_map(void);
-
-extern void __init init_smp_config (void);
-extern void smp_do_timer (struct pt_regs *regs);
-
-extern irqreturn_t handle_IPI(int irq, void *dev_id);
-extern void smp_send_reschedule (int cpu);
-extern void identify_siblings (struct cpuinfo_ia64 *);
-extern int is_multithreading_enabled(void);
-
-extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
-
-#else /* CONFIG_SMP */
-
-#define cpu_logical_id(i) 0
-#define cpu_physical_id(i) ia64_get_lid()
-
-#endif /* CONFIG_SMP */
-#endif /* _ASM_IA64_SMP_H */
diff --git a/arch/ia64/include/asm/sn/intr.h b/arch/ia64/include/asm/sn/intr.h
deleted file mode 100644
index 3885a77b21df..000000000000
--- a/arch/ia64/include/asm/sn/intr.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_INTR_H
-#define _ASM_IA64_SN_INTR_H
-
-#define SGI_XPC_ACTIVATE 0x30
-#define SGI_XPC_NOTIFY 0xe7
-
-#endif /* _ASM_IA64_SN_INTR_H */
diff --git a/arch/ia64/include/asm/sn/sn_sal.h b/arch/ia64/include/asm/sn/sn_sal.h
deleted file mode 100644
index d437aa43343b..000000000000
--- a/arch/ia64/include/asm/sn/sn_sal.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef _ASM_IA64_SN_SN_SAL_H
-#define _ASM_IA64_SN_SN_SAL_H
-
-/*
- * System Abstraction Layer definitions for IA64
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000-2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <asm/sal.h>
-
-// SGI Specific Calls
-#define SN_SAL_GET_PARTITION_ADDR 0x02000009
-#define SN_SAL_MEMPROTECT 0x0200003e
-
-#define SN_SAL_WATCHLIST_ALLOC 0x02000070
-#define SN_SAL_WATCHLIST_FREE 0x02000071
-
-/*
- * SAL Error Codes
- */
-#define SALRET_MORE_PASSES 1
-#define SALRET_OK 0
-#define SALRET_NOT_IMPLEMENTED (-1)
-#define SALRET_INVALID_ARG (-2)
-#define SALRET_ERROR (-3)
-
-/*
- * Returns the physical address of the partition's reserved page through
- * an iterative number of calls.
- *
- * On first call, 'cookie' and 'len' should be set to 0, and 'addr'
- * set to the nasid of the partition whose reserved page's address is
- * being sought.
- * On subsequent calls, pass the values, that were passed back on the
- * previous call.
- *
- * While the return status equals SALRET_MORE_PASSES, keep calling
- * this function after first copying 'len' bytes starting at 'addr'
- * into 'buf'. Once the return status equals SALRET_OK, 'addr' will
- * be the physical address of the partition's reserved page. If the
- * return status equals neither of these, an error as occurred.
- */
-static inline s64
-sn_partition_reserved_page_pa(u64 buf, u64 *cookie, u64 *addr, u64 *len)
-{
- struct ia64_sal_retval rv;
- ia64_sal_oemcall_reentrant(&rv, SN_SAL_GET_PARTITION_ADDR, *cookie,
- *addr, buf, *len, 0, 0, 0);
- *cookie = rv.v0;
- *addr = rv.v1;
- *len = rv.v2;
- return rv.status;
-}
-
-/*
- * Change memory access protections for a physical address range.
- * nasid_array is not used on Altix, but may be in future architectures.
- * Available memory protection access classes are defined after the function.
- */
-static inline int
-sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
-{
- struct ia64_sal_retval ret_stuff;
-
- ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len,
- (u64)nasid_array, perms, 0, 0, 0);
- return ret_stuff.status;
-}
-#define SN_MEMPROT_ACCESS_CLASS_0 0x14a080
-#define SN_MEMPROT_ACCESS_CLASS_1 0x2520c2
-#define SN_MEMPROT_ACCESS_CLASS_2 0x14a1ca
-#define SN_MEMPROT_ACCESS_CLASS_3 0x14a290
-#define SN_MEMPROT_ACCESS_CLASS_6 0x084080
-#define SN_MEMPROT_ACCESS_CLASS_7 0x021080
-
-union sn_watchlist_u {
- u64 val;
- struct {
- u64 blade : 16,
- size : 32,
- filler : 16;
- };
-};
-
-static inline int
-sn_mq_watchlist_alloc(int blade, void *mq, unsigned int mq_size,
- unsigned long *intr_mmr_offset)
-{
- struct ia64_sal_retval rv;
- unsigned long addr;
- union sn_watchlist_u size_blade;
- int watchlist;
-
- addr = (unsigned long)mq;
- size_blade.size = mq_size;
- size_blade.blade = blade;
-
- /*
- * bios returns watchlist number or negative error number.
- */
- ia64_sal_oemcall_nolock(&rv, SN_SAL_WATCHLIST_ALLOC, addr,
- size_blade.val, (u64)intr_mmr_offset,
- (u64)&watchlist, 0, 0, 0);
- if (rv.status < 0)
- return rv.status;
-
- return watchlist;
-}
-
-static inline int
-sn_mq_watchlist_free(int blade, int watchlist_num)
-{
- struct ia64_sal_retval rv;
- ia64_sal_oemcall_nolock(&rv, SN_SAL_WATCHLIST_FREE, blade,
- watchlist_num, 0, 0, 0, 0, 0);
- return rv.status;
-}
-#endif /* _ASM_IA64_SN_SN_SAL_H */
diff --git a/arch/ia64/include/asm/sparsemem.h b/arch/ia64/include/asm/sparsemem.h
deleted file mode 100644
index a58f8b466d96..000000000000
--- a/arch/ia64/include/asm/sparsemem.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_SPARSEMEM_H
-#define _ASM_IA64_SPARSEMEM_H
-
-#ifdef CONFIG_SPARSEMEM
-#include <asm/page.h>
-/*
- * SECTION_SIZE_BITS 2^N: how big each section will be
- * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
- */
-
-#define SECTION_SIZE_BITS (30)
-#define MAX_PHYSMEM_BITS (50)
-#ifdef CONFIG_ARCH_FORCE_MAX_ORDER
-#if (CONFIG_ARCH_FORCE_MAX_ORDER + PAGE_SHIFT > SECTION_SIZE_BITS)
-#undef SECTION_SIZE_BITS
-#define SECTION_SIZE_BITS (CONFIG_ARCH_FORCE_MAX_ORDER + PAGE_SHIFT)
-#endif
-#endif
-
-#endif /* CONFIG_SPARSEMEM */
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-int memory_add_physaddr_to_nid(u64 addr);
-#define memory_add_physaddr_to_nid memory_add_physaddr_to_nid
-#endif
-
-#endif /* _ASM_IA64_SPARSEMEM_H */
diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h
deleted file mode 100644
index 0e5c1ad3239c..000000000000
--- a/arch/ia64/include/asm/spinlock.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_SPINLOCK_H
-#define _ASM_IA64_SPINLOCK_H
-
-/*
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- *
- * This file is used for SMP configurations only.
- */
-
-#include <linux/compiler.h>
-#include <linux/kernel.h>
-#include <linux/bitops.h>
-
-#include <linux/atomic.h>
-#include <asm/intrinsics.h>
-#include <asm/barrier.h>
-#include <asm/processor.h>
-
-#define arch_spin_lock_init(x) ((x)->lock = 0)
-
-/*
- * Ticket locks are conceptually two parts, one indicating the current head of
- * the queue, and the other indicating the current tail. The lock is acquired
- * by atomically noting the tail and incrementing it by one (thus adding
- * ourself to the queue and noting our position), then waiting until the head
- * becomes equal to the initial value of the tail.
- * The pad bits in the middle are used to prevent the next_ticket number
- * overflowing into the now_serving number.
- *
- * 31 17 16 15 14 0
- * +----------------------------------------------------+
- * | now_serving | padding | next_ticket |
- * +----------------------------------------------------+
- */
-
-#define TICKET_SHIFT 17
-#define TICKET_BITS 15
-#define TICKET_MASK ((1 << TICKET_BITS) - 1)
-
-static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock)
-{
- int *p = (int *)&lock->lock, ticket, serve;
-
- ticket = ia64_fetchadd(1, p, acq);
-
- if (!(((ticket >> TICKET_SHIFT) ^ ticket) & TICKET_MASK))
- return;
-
- ia64_invala();
-
- for (;;) {
- asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(p) : "memory");
-
- if (!(((serve >> TICKET_SHIFT) ^ ticket) & TICKET_MASK))
- return;
- cpu_relax();
- }
-}
-
-static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
-{
- int tmp = READ_ONCE(lock->lock);
-
- if (!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK))
- return ia64_cmpxchg(acq, &lock->lock, tmp, tmp + 1, sizeof (tmp)) == tmp;
- return 0;
-}
-
-static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
-{
- unsigned short *p = (unsigned short *)&lock->lock + 1, tmp;
-
- /* This could be optimised with ARCH_HAS_MMIOWB */
- mmiowb();
- asm volatile ("ld2.bias %0=[%1]" : "=r"(tmp) : "r"(p));
- WRITE_ONCE(*p, (tmp + 2) & ~1);
-}
-
-static inline int __ticket_spin_is_locked(arch_spinlock_t *lock)
-{
- long tmp = READ_ONCE(lock->lock);
-
- return !!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK);
-}
-
-static inline int __ticket_spin_is_contended(arch_spinlock_t *lock)
-{
- long tmp = READ_ONCE(lock->lock);
-
- return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1;
-}
-
-static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock)
-{
- return !(((lock.lock >> TICKET_SHIFT) ^ lock.lock) & TICKET_MASK);
-}
-
-static inline int arch_spin_is_locked(arch_spinlock_t *lock)
-{
- return __ticket_spin_is_locked(lock);
-}
-
-static inline int arch_spin_is_contended(arch_spinlock_t *lock)
-{
- return __ticket_spin_is_contended(lock);
-}
-#define arch_spin_is_contended arch_spin_is_contended
-
-static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
-{
- __ticket_spin_lock(lock);
-}
-
-static __always_inline int arch_spin_trylock(arch_spinlock_t *lock)
-{
- return __ticket_spin_trylock(lock);
-}
-
-static __always_inline void arch_spin_unlock(arch_spinlock_t *lock)
-{
- __ticket_spin_unlock(lock);
-}
-
-#ifdef ASM_SUPPORTED
-
-static __always_inline void
-arch_read_lock(arch_rwlock_t *lock)
-{
- unsigned long flags = 0;
-
- __asm__ __volatile__ (
- "tbit.nz p6, p0 = %1,%2\n"
- "br.few 3f\n"
- "1:\n"
- "fetchadd4.rel r2 = [%0], -1;;\n"
- "(p6) ssm psr.i\n"
- "2:\n"
- "hint @pause\n"
- "ld4 r2 = [%0];;\n"
- "cmp4.lt p7,p0 = r2, r0\n"
- "(p7) br.cond.spnt.few 2b\n"
- "(p6) rsm psr.i\n"
- ";;\n"
- "3:\n"
- "fetchadd4.acq r2 = [%0], 1;;\n"
- "cmp4.lt p7,p0 = r2, r0\n"
- "(p7) br.cond.spnt.few 1b\n"
- : : "r"(lock), "r"(flags), "i"(IA64_PSR_I_BIT)
- : "p6", "p7", "r2", "memory");
-}
-
-#else /* !ASM_SUPPORTED */
-
-#define arch_read_lock(rw) \
-do { \
- arch_rwlock_t *__read_lock_ptr = (rw); \
- \
- while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, acq) < 0)) { \
- ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \
- while (*(volatile int *)__read_lock_ptr < 0) \
- cpu_relax(); \
- } \
-} while (0)
-
-#endif /* !ASM_SUPPORTED */
-
-#define arch_read_unlock(rw) \
-do { \
- arch_rwlock_t *__read_lock_ptr = (rw); \
- ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \
-} while (0)
-
-#ifdef ASM_SUPPORTED
-
-static __always_inline void
-arch_write_lock(arch_rwlock_t *lock)
-{
- unsigned long flags = 0;
-
- __asm__ __volatile__ (
- "tbit.nz p6, p0 = %1, %2\n"
- "mov ar.ccv = r0\n"
- "dep r29 = -1, r0, 31, 1\n"
- "br.few 3f;;\n"
- "1:\n"
- "(p6) ssm psr.i\n"
- "2:\n"
- "hint @pause\n"
- "ld4 r2 = [%0];;\n"
- "cmp4.eq p0,p7 = r0, r2\n"
- "(p7) br.cond.spnt.few 2b\n"
- "(p6) rsm psr.i\n"
- ";;\n"
- "3:\n"
- "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n"
- "cmp4.eq p0,p7 = r0, r2\n"
- "(p7) br.cond.spnt.few 1b;;\n"
- : : "r"(lock), "r"(flags), "i"(IA64_PSR_I_BIT)
- : "ar.ccv", "p6", "p7", "r2", "r29", "memory");
-}
-
-#define arch_write_trylock(rw) \
-({ \
- register long result; \
- \
- __asm__ __volatile__ ( \
- "mov ar.ccv = r0\n" \
- "dep r29 = -1, r0, 31, 1;;\n" \
- "cmpxchg4.acq %0 = [%1], r29, ar.ccv\n" \
- : "=r"(result) : "r"(rw) : "ar.ccv", "r29", "memory"); \
- (result == 0); \
-})
-
-static inline void arch_write_unlock(arch_rwlock_t *x)
-{
- u8 *y = (u8 *)x;
- barrier();
- asm volatile ("st1.rel.nta [%0] = r0\n\t" :: "r"(y+3) : "memory" );
-}
-
-#else /* !ASM_SUPPORTED */
-
-#define arch_write_lock(l) \
-({ \
- __u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1); \
- __u32 *ia64_write_lock_ptr = (__u32 *) (l); \
- do { \
- while (*ia64_write_lock_ptr) \
- ia64_barrier(); \
- ia64_val = ia64_cmpxchg4_acq(ia64_write_lock_ptr, ia64_set_val, 0); \
- } while (ia64_val); \
-})
-
-#define arch_write_trylock(rw) \
-({ \
- __u64 ia64_val; \
- __u64 ia64_set_val = ia64_dep_mi(-1, 0, 31,1); \
- ia64_val = ia64_cmpxchg4_acq((__u32 *)(rw), ia64_set_val, 0); \
- (ia64_val == 0); \
-})
-
-static inline void arch_write_unlock(arch_rwlock_t *x)
-{
- barrier();
- x->write_lock = 0;
-}
-
-#endif /* !ASM_SUPPORTED */
-
-static inline int arch_read_trylock(arch_rwlock_t *x)
-{
- union {
- arch_rwlock_t lock;
- __u32 word;
- } old, new;
- old.lock = new.lock = *x;
- old.lock.write_lock = new.lock.write_lock = 0;
- ++new.lock.read_counter;
- return (u32)ia64_cmpxchg4_acq((__u32 *)(x), new.word, old.word) == old.word;
-}
-
-#endif /* _ASM_IA64_SPINLOCK_H */
diff --git a/arch/ia64/include/asm/spinlock_types.h b/arch/ia64/include/asm/spinlock_types.h
deleted file mode 100644
index 14b8a161c165..000000000000
--- a/arch/ia64/include/asm/spinlock_types.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_SPINLOCK_TYPES_H
-#define _ASM_IA64_SPINLOCK_TYPES_H
-
-#ifndef __LINUX_SPINLOCK_TYPES_RAW_H
-# error "please don't include this file directly"
-#endif
-
-typedef struct {
- volatile unsigned int lock;
-} arch_spinlock_t;
-
-#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
-
-typedef struct {
- volatile unsigned int read_counter : 31;
- volatile unsigned int write_lock : 1;
-} arch_rwlock_t;
-
-#define __ARCH_RW_LOCK_UNLOCKED { 0, 0 }
-
-#endif
diff --git a/arch/ia64/include/asm/string.h b/arch/ia64/include/asm/string.h
deleted file mode 100644
index 8b84df0dbfad..000000000000
--- a/arch/ia64/include/asm/string.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_STRING_H
-#define _ASM_IA64_STRING_H
-
-/*
- * Here is where we want to put optimized versions of the string
- * routines.
- *
- * Copyright (C) 1998-2000, 2002 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-
-#define __HAVE_ARCH_STRLEN 1 /* see arch/ia64/lib/strlen.S */
-#define __HAVE_ARCH_MEMSET 1 /* see arch/ia64/lib/memset.S */
-#define __HAVE_ARCH_MEMCPY 1 /* see arch/ia64/lib/memcpy.S */
-
-extern __kernel_size_t strlen (const char *);
-extern void *memcpy (void *, const void *, __kernel_size_t);
-extern void *memset (void *, int, __kernel_size_t);
-
-#endif /* _ASM_IA64_STRING_H */
diff --git a/arch/ia64/include/asm/switch_to.h b/arch/ia64/include/asm/switch_to.h
deleted file mode 100644
index a5a4e09468fa..000000000000
--- a/arch/ia64/include/asm/switch_to.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Low-level task switching. This is based on information published in
- * the Processor Abstraction Layer and the System Abstraction Layer
- * manual.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- */
-#ifndef _ASM_IA64_SWITCH_TO_H
-#define _ASM_IA64_SWITCH_TO_H
-
-#include <linux/percpu.h>
-
-struct task_struct;
-
-/*
- * Context switch from one thread to another. If the two threads have
- * different address spaces, schedule() has already taken care of
- * switching to the new address space by calling switch_mm().
- *
- * Disabling access to the fph partition and the debug-register
- * context switch MUST be done before calling ia64_switch_to() since a
- * newly created thread returns directly to
- * ia64_ret_from_syscall_clear_r8.
- */
-extern struct task_struct *ia64_switch_to (void *next_task);
-
-extern void ia64_save_extra (struct task_struct *task);
-extern void ia64_load_extra (struct task_struct *task);
-
-#define IA64_HAS_EXTRA_STATE(t) \
- ((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID))
-
-#define __switch_to(prev,next,last) do { \
- if (IA64_HAS_EXTRA_STATE(prev)) \
- ia64_save_extra(prev); \
- if (IA64_HAS_EXTRA_STATE(next)) \
- ia64_load_extra(next); \
- ia64_psr(task_pt_regs(next))->dfh = !ia64_is_local_fpu_owner(next); \
- (last) = ia64_switch_to((next)); \
-} while (0)
-
-#ifdef CONFIG_SMP
-/*
- * In the SMP case, we save the fph state when context-switching away from a thread that
- * modified fph. This way, when the thread gets scheduled on another CPU, the CPU can
- * pick up the state from task->thread.fph, avoiding the complication of having to fetch
- * the latest fph state from another CPU. In other words: eager save, lazy restore.
- */
-# define switch_to(prev,next,last) do { \
- if (ia64_psr(task_pt_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) { \
- ia64_psr(task_pt_regs(prev))->mfh = 0; \
- (prev)->thread.flags |= IA64_THREAD_FPH_VALID; \
- __ia64_save_fpu((prev)->thread.fph); \
- } \
- __switch_to(prev, next, last); \
- /* "next" in old context is "current" in new context */ \
- if (unlikely((current->thread.flags & IA64_THREAD_MIGRATION) && \
- (task_cpu(current) != \
- task_thread_info(current)->last_cpu))) { \
- task_thread_info(current)->last_cpu = task_cpu(current); \
- } \
-} while (0)
-#else
-# define switch_to(prev,next,last) __switch_to(prev, next, last)
-#endif
-
-#endif /* _ASM_IA64_SWITCH_TO_H */
diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h
deleted file mode 100644
index 2b02a3fb862a..000000000000
--- a/arch/ia64/include/asm/syscall.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Access to user system call parameters and results
- *
- * Copyright (C) 2008 Intel Corp. Shaohua Li <shaohua.li@intel.com>
- *
- * See asm-generic/syscall.h for descriptions of what we must do here.
- */
-
-#ifndef _ASM_SYSCALL_H
-#define _ASM_SYSCALL_H 1
-
-#include <uapi/linux/audit.h>
-#include <linux/sched.h>
-#include <linux/err.h>
-
-static inline long syscall_get_nr(struct task_struct *task,
- struct pt_regs *regs)
-{
- if ((long)regs->cr_ifs < 0) /* Not a syscall */
- return -1;
-
- return regs->r15;
-}
-
-static inline void syscall_rollback(struct task_struct *task,
- struct pt_regs *regs)
-{
- /* do nothing */
-}
-
-static inline long syscall_get_error(struct task_struct *task,
- struct pt_regs *regs)
-{
- return regs->r10 == -1 ? -regs->r8:0;
-}
-
-static inline long syscall_get_return_value(struct task_struct *task,
- struct pt_regs *regs)
-{
- return regs->r8;
-}
-
-static inline void syscall_set_return_value(struct task_struct *task,
- struct pt_regs *regs,
- int error, long val)
-{
- if (error) {
- /* error < 0, but ia64 uses > 0 return value */
- regs->r8 = -error;
- regs->r10 = -1;
- } else {
- regs->r8 = val;
- regs->r10 = 0;
- }
-}
-
-extern void syscall_get_arguments(struct task_struct *task,
- struct pt_regs *regs, unsigned long *args);
-
-static inline int syscall_get_arch(struct task_struct *task)
-{
- return AUDIT_ARCH_IA64;
-}
-#endif /* _ASM_SYSCALL_H */
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h
deleted file mode 100644
index 21b257117e0a..000000000000
--- a/arch/ia64/include/asm/thread_info.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2002-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#ifndef _ASM_IA64_THREAD_INFO_H
-#define _ASM_IA64_THREAD_INFO_H
-
-#ifndef ASM_OFFSETS_C
-#include <asm/asm-offsets.h>
-#endif
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-
-#define THREAD_SIZE KERNEL_STACK_SIZE
-
-#ifndef __ASSEMBLY__
-
-/*
- * On IA-64, we want to keep the task structure and kernel stack together, so they can be
- * mapped by a single TLB entry and so they can be addressed by the "current" pointer
- * without having to do pointer masking.
- */
-struct thread_info {
- struct task_struct *task; /* XXX not really needed, except for dup_task_struct() */
- __u32 flags; /* thread_info flags (see TIF_*) */
- __u32 cpu; /* current CPU */
- __u32 last_cpu; /* Last CPU thread ran on */
- __u32 status; /* Thread synchronous flags */
- int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- __u64 utime;
- __u64 stime;
- __u64 gtime;
- __u64 hardirq_time;
- __u64 softirq_time;
- __u64 idle_time;
- __u64 ac_stamp;
- __u64 ac_leave;
- __u64 ac_stime;
- __u64 ac_utime;
-#endif
-};
-
-#define INIT_THREAD_INFO(tsk) \
-{ \
- .task = &tsk, \
- .flags = 0, \
- .cpu = 0, \
- .preempt_count = INIT_PREEMPT_COUNT, \
-}
-
-#ifndef ASM_OFFSETS_C
-/* how to get the thread information struct from C */
-#define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE))
-#define arch_alloc_thread_stack_node(tsk, node) \
- ((unsigned long *) ((char *) (tsk) + IA64_TASK_SIZE))
-#define task_thread_info(tsk) ((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE))
-#else
-#define current_thread_info() ((struct thread_info *) 0)
-#define arch_alloc_thread_stack_node(tsk, node) ((unsigned long *) 0)
-#define task_thread_info(tsk) ((struct thread_info *) 0)
-#endif
-#define arch_free_thread_stack(tsk) /* nothing */
-#define task_stack_page(tsk) ((void *)(tsk))
-
-#define __HAVE_THREAD_FUNCTIONS
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-#define setup_thread_stack(p, org) \
- *task_thread_info(p) = *task_thread_info(org); \
- task_thread_info(p)->ac_stime = 0; \
- task_thread_info(p)->ac_utime = 0; \
- task_thread_info(p)->task = (p);
-#else
-#define setup_thread_stack(p, org) \
- *task_thread_info(p) = *task_thread_info(org); \
- task_thread_info(p)->task = (p);
-#endif
-#define end_of_stack(p) (unsigned long *)((void *)(p) + IA64_RBS_OFFSET)
-
-#define alloc_task_struct_node(node) \
-({ \
- struct page *page = alloc_pages_node(node, GFP_KERNEL | __GFP_COMP, \
- KERNEL_STACK_SIZE_ORDER); \
- struct task_struct *ret = page ? page_address(page) : NULL; \
- \
- ret; \
-})
-#define free_task_struct(tsk) free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER)
-
-#endif /* !__ASSEMBLY */
-
-/*
- * thread information flags
- * - these are process state flags that various assembly files may need to access
- * - pending work-to-be-done flags are in least-significant 16 bits, other flags
- * in top 16 bits
- */
-#define TIF_SIGPENDING 0 /* signal pending */
-#define TIF_NEED_RESCHED 1 /* rescheduling necessary */
-#define TIF_SYSCALL_TRACE 2 /* syscall trace active */
-#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */
-#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
-#define TIF_NOTIFY_SIGNAL 5 /* signal notification exist */
-#define TIF_NOTIFY_RESUME 6 /* resumption notification requested */
-#define TIF_MEMDIE 17 /* is terminating due to OOM killer */
-#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */
-#define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */
-#define TIF_RESTORE_RSE 21 /* user RBS is newer than kernel RBS */
-#define TIF_POLLING_NRFLAG 22 /* idle is polling for TIF_NEED_RESCHED */
-
-#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
-#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
-#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
-#define _TIF_SYSCALL_TRACEAUDIT (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP)
-#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
-#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
-#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
-#define _TIF_MCA_INIT (1 << TIF_MCA_INIT)
-#define _TIF_DB_DISABLED (1 << TIF_DB_DISABLED)
-#define _TIF_RESTORE_RSE (1 << TIF_RESTORE_RSE)
-#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
-
-/* "work to do on user-return" bits */
-#define TIF_ALLWORK_MASK (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SYSCALL_AUDIT|\
- _TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_NOTIFY_SIGNAL)
-/* like TIF_ALLWORK_BITS but sans TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT */
-#define TIF_WORK_MASK (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT))
-
-#endif /* _ASM_IA64_THREAD_INFO_H */
diff --git a/arch/ia64/include/asm/timex.h b/arch/ia64/include/asm/timex.h
deleted file mode 100644
index 7ccc077a60be..000000000000
--- a/arch/ia64/include/asm/timex.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_TIMEX_H
-#define _ASM_IA64_TIMEX_H
-
-/*
- * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-/*
- * 2001/01/18 davidm Removed CLOCK_TICK_RATE. It makes no sense on IA-64.
- * Also removed cacheflush_time as it's entirely unused.
- */
-
-#include <asm/intrinsics.h>
-#include <asm/processor.h>
-
-typedef unsigned long cycles_t;
-
-extern void (*ia64_udelay)(unsigned long usecs);
-
-/*
- * For performance reasons, we don't want to define CLOCK_TICK_TRATE as
- * local_cpu_data->itc_rate. Fortunately, we don't have to, either: according to George
- * Anzinger, 1/CLOCK_TICK_RATE is taken as the resolution of the timer clock. The time
- * calculation assumes that you will use enough of these so that your tick size <= 1/HZ.
- * If the calculation shows that your CLOCK_TICK_RATE can not supply exactly 1/HZ ticks,
- * the actual value is calculated and used to update the wall clock each jiffie. Setting
- * the CLOCK_TICK_RATE to x*HZ insures that the calculation will find no errors. Hence we
- * pick a multiple of HZ which gives us a (totally virtual) CLOCK_TICK_RATE of about
- * 100MHz.
- */
-#define CLOCK_TICK_RATE (HZ * 100000UL)
-
-static inline cycles_t
-get_cycles (void)
-{
- cycles_t ret;
-
- ret = ia64_getreg(_IA64_REG_AR_ITC);
- return ret;
-}
-#define get_cycles get_cycles
-
-extern void ia64_cpu_local_tick (void);
-extern unsigned long long ia64_native_sched_clock (void);
-
-#endif /* _ASM_IA64_TIMEX_H */
diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h
deleted file mode 100644
index a15fe0809aae..000000000000
--- a/arch/ia64/include/asm/tlb.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_TLB_H
-#define _ASM_IA64_TLB_H
-/*
- * Based on <asm-generic/tlb.h>.
- *
- * Copyright (C) 2002-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-/*
- * Removing a translation from a page table (including TLB-shootdown) is a four-step
- * procedure:
- *
- * (1) Flush (virtual) caches --- ensures virtual memory is coherent with kernel memory
- * (this is a no-op on ia64).
- * (2) Clear the relevant portions of the page-table
- * (3) Flush the TLBs --- ensures that stale content is gone from CPU TLBs
- * (4) Release the pages that were freed up in step (2).
- *
- * Note that the ordering of these steps is crucial to avoid races on MP machines.
- *
- * The Linux kernel defines several platform-specific hooks for TLB-shootdown. When
- * unmapping a portion of the virtual address space, these hooks are called according to
- * the following template:
- *
- * tlb <- tlb_gather_mmu(mm); // start unmap for address space MM
- * {
- * for each vma that needs a shootdown do {
- * tlb_start_vma(tlb, vma);
- * for each page-table-entry PTE that needs to be removed do {
- * tlb_remove_tlb_entry(tlb, pte, address);
- * if (pte refers to a normal page) {
- * tlb_remove_page(tlb, page);
- * }
- * }
- * tlb_end_vma(tlb, vma);
- * }
- * }
- * tlb_finish_mmu(tlb); // finish unmap for address space MM
- */
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/swap.h>
-
-#include <asm/processor.h>
-#include <asm/tlbflush.h>
-
-#include <asm-generic/tlb.h>
-
-#endif /* _ASM_IA64_TLB_H */
diff --git a/arch/ia64/include/asm/tlbflush.h b/arch/ia64/include/asm/tlbflush.h
deleted file mode 100644
index ceac10c4d6e2..000000000000
--- a/arch/ia64/include/asm/tlbflush.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_TLBFLUSH_H
-#define _ASM_IA64_TLBFLUSH_H
-
-/*
- * Copyright (C) 2002 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-
-#include <linux/mm.h>
-
-#include <asm/intrinsics.h>
-#include <asm/mmu_context.h>
-#include <asm/page.h>
-
-struct ia64_tr_entry {
- u64 ifa;
- u64 itir;
- u64 pte;
- u64 rr;
-}; /*Record for tr entry!*/
-
-extern int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size);
-extern void ia64_ptr_entry(u64 target_mask, int slot);
-extern struct ia64_tr_entry *ia64_idtrs[NR_CPUS];
-
-/*
- region register macros
-*/
-#define RR_TO_VE(val) (((val) >> 0) & 0x0000000000000001)
-#define RR_VE(val) (((val) & 0x0000000000000001) << 0)
-#define RR_VE_MASK 0x0000000000000001L
-#define RR_VE_SHIFT 0
-#define RR_TO_PS(val) (((val) >> 2) & 0x000000000000003f)
-#define RR_PS(val) (((val) & 0x000000000000003f) << 2)
-#define RR_PS_MASK 0x00000000000000fcL
-#define RR_PS_SHIFT 2
-#define RR_RID_MASK 0x00000000ffffff00L
-#define RR_TO_RID(val) ((val >> 8) & 0xffffff)
-
-/*
- * Now for some TLB flushing routines. This is the kind of stuff that
- * can be very expensive, so try to avoid them whenever possible.
- */
-extern void setup_ptcg_sem(int max_purges, int from_palo);
-
-/*
- * Flush everything (kernel mapping may also have changed due to
- * vmalloc/vfree).
- */
-extern void local_flush_tlb_all (void);
-
-#ifdef CONFIG_SMP
- extern void smp_flush_tlb_all (void);
- extern void smp_flush_tlb_mm (struct mm_struct *mm);
- extern void smp_flush_tlb_cpumask (cpumask_t xcpumask);
-# define flush_tlb_all() smp_flush_tlb_all()
-#else
-# define flush_tlb_all() local_flush_tlb_all()
-# define smp_flush_tlb_cpumask(m) local_flush_tlb_all()
-#endif
-
-static inline void
-local_finish_flush_tlb_mm (struct mm_struct *mm)
-{
- if (mm == current->active_mm)
- activate_context(mm);
-}
-
-/*
- * Flush a specified user mapping. This is called, e.g., as a result of fork() and
- * exit(). fork() ends up here because the copy-on-write mechanism needs to write-protect
- * the PTEs of the parent task.
- */
-static inline void
-flush_tlb_mm (struct mm_struct *mm)
-{
- if (!mm)
- return;
-
- set_bit(mm->context, ia64_ctx.flushmap);
- mm->context = 0;
-
- if (atomic_read(&mm->mm_users) == 0)
- return; /* happens as a result of exit_mmap() */
-
-#ifdef CONFIG_SMP
- smp_flush_tlb_mm(mm);
-#else
- local_finish_flush_tlb_mm(mm);
-#endif
-}
-
-extern void flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end);
-
-/*
- * Page-granular tlb flush.
- */
-static inline void
-flush_tlb_page (struct vm_area_struct *vma, unsigned long addr)
-{
-#ifdef CONFIG_SMP
- flush_tlb_range(vma, (addr & PAGE_MASK), (addr & PAGE_MASK) + PAGE_SIZE);
-#else
- if (vma->vm_mm == current->active_mm)
- ia64_ptcl(addr, (PAGE_SHIFT << 2));
- else
- vma->vm_mm->context = 0;
-#endif
-}
-
-/*
- * Flush the local TLB. Invoked from another cpu using an IPI.
- */
-#ifdef CONFIG_SMP
-void smp_local_flush_tlb(void);
-#else
-#define smp_local_flush_tlb()
-#endif
-
-static inline void flush_tlb_kernel_range(unsigned long start,
- unsigned long end)
-{
- flush_tlb_all(); /* XXX fix me */
-}
-
-#endif /* _ASM_IA64_TLBFLUSH_H */
diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h
deleted file mode 100644
index 43567240b0d6..000000000000
--- a/arch/ia64/include/asm/topology.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2002, Erich Focht, NEC
- *
- * All rights reserved.
- */
-#ifndef _ASM_IA64_TOPOLOGY_H
-#define _ASM_IA64_TOPOLOGY_H
-
-#include <asm/acpi.h>
-#include <asm/numa.h>
-#include <asm/smp.h>
-
-#ifdef CONFIG_NUMA
-
-/* Nodes w/o CPUs are preferred for memory allocations, see build_zonelists */
-#define PENALTY_FOR_NODE_WITH_CPUS 255
-
-/*
- * Nodes within this distance are eligible for reclaim by zone_reclaim() when
- * zone_reclaim_mode is enabled.
- */
-#define RECLAIM_DISTANCE 15
-
-/*
- * Returns a bitmask of CPUs on Node 'node'.
- */
-#define cpumask_of_node(node) ((node) == -1 ? \
- cpu_all_mask : \
- &node_to_cpu_mask[node])
-
-/*
- * Determines the node for a given pci bus
- */
-#define pcibus_to_node(bus) PCI_CONTROLLER(bus)->node
-
-void build_cpu_to_node_map(void);
-
-#endif /* CONFIG_NUMA */
-
-#ifdef CONFIG_SMP
-#define topology_physical_package_id(cpu) (cpu_data(cpu)->socket_id)
-#define topology_core_id(cpu) (cpu_data(cpu)->core_id)
-#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
-#define topology_sibling_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
-#endif
-
-extern void arch_fix_phys_package_id(int num, u32 slot);
-
-#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
- cpu_all_mask : \
- cpumask_of_node(pcibus_to_node(bus)))
-
-#include <asm-generic/topology.h>
-
-#endif /* _ASM_IA64_TOPOLOGY_H */
diff --git a/arch/ia64/include/asm/types.h b/arch/ia64/include/asm/types.h
deleted file mode 100644
index 5ddc7703de99..000000000000
--- a/arch/ia64/include/asm/types.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file is never included by application software unless explicitly
- * requested (e.g., via linux/types.h) in which case the application is
- * Linux specific so (user-) name space pollution is not a major issue.
- * However, for interoperability, libraries still need to be careful to
- * avoid naming clashes.
- *
- * Based on <asm-alpha/types.h>.
- *
- * Modified 1998-2000, 2002
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-#ifndef _ASM_IA64_TYPES_H
-#define _ASM_IA64_TYPES_H
-
-#include <asm-generic/int-ll64.h>
-#include <uapi/asm/types.h>
-
-#ifdef __ASSEMBLY__
-#else
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
-
-struct fnptr {
- unsigned long ip;
- unsigned long gp;
-};
-
-#endif /* !__ASSEMBLY__ */
-#endif /* _ASM_IA64_TYPES_H */
diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h
deleted file mode 100644
index 60adadeb3e9e..000000000000
--- a/arch/ia64/include/asm/uaccess.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_UACCESS_H
-#define _ASM_IA64_UACCESS_H
-
-/*
- * This file defines various macros to transfer memory areas across
- * the user/kernel boundary. This needs to be done carefully because
- * this code is executed in kernel mode and uses user-specified
- * addresses. Thus, we need to be careful not to let the user to
- * trick us into accessing kernel memory that would normally be
- * inaccessible. This code is also fairly performance sensitive,
- * so we want to spend as little time doing safety checks as
- * possible.
- *
- * To make matters a bit more interesting, these macros sometimes also
- * called from within the kernel itself, in which case the address
- * validity check must be skipped. The get_fs() macro tells us what
- * to do: if get_fs()==USER_DS, checking is performed, if
- * get_fs()==KERNEL_DS, checking is bypassed.
- *
- * Note that even if the memory area specified by the user is in a
- * valid address range, it is still possible that we'll get a page
- * fault while accessing it. This is handled by filling out an
- * exception handler fixup entry for each instruction that has the
- * potential to fault. When such a fault occurs, the page fault
- * handler checks to see whether the faulting instruction has a fixup
- * associated and, if so, sets r8 to -EFAULT and clears r9 to 0 and
- * then resumes execution at the continuation point.
- *
- * Based on <asm-alpha/uaccess.h>.
- *
- * Copyright (C) 1998, 1999, 2001-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/compiler.h>
-#include <linux/page-flags.h>
-
-#include <asm/intrinsics.h>
-#include <linux/pgtable.h>
-#include <asm/io.h>
-#include <asm/extable.h>
-
-/*
- * When accessing user memory, we need to make sure the entire area really is
- * in user-level space. We also need to make sure that the address doesn't
- * point inside the virtually mapped linear page table.
- */
-static inline int __access_ok(const void __user *p, unsigned long size)
-{
- unsigned long limit = TASK_SIZE;
- unsigned long addr = (unsigned long)p;
-
- return likely((size <= limit) && (addr <= (limit - size)) &&
- likely(REGION_OFFSET(addr) < RGN_MAP_LIMIT));
-}
-#define __access_ok __access_ok
-#include <asm-generic/access_ok.h>
-
-/*
- * These are the main single-value transfer routines. They automatically
- * use the right size if we just have the right pointer type.
- *
- * Careful to not
- * (a) re-use the arguments for side effects (sizeof/typeof is ok)
- * (b) require any knowledge of processes at this stage
- */
-#define put_user(x, ptr) __put_user_check((__typeof__(*(ptr))) (x), (ptr), sizeof(*(ptr)))
-#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr)))
-
-/*
- * The "__xxx" versions do not do address space checking, useful when
- * doing multiple accesses to the same area (the programmer has to do the
- * checks by hand with "access_ok()")
- */
-#define __put_user(x, ptr) __put_user_nocheck((__typeof__(*(ptr))) (x), (ptr), sizeof(*(ptr)))
-#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
-
-#ifdef ASM_SUPPORTED
- struct __large_struct { unsigned long buf[100]; };
-# define __m(x) (*(struct __large_struct __user *)(x))
-
-/* We need to declare the __ex_table section before we can use it in .xdata. */
-asm (".section \"__ex_table\", \"a\"\n\t.previous");
-
-# define __get_user_size(val, addr, n, err) \
-do { \
- register long __gu_r8 asm ("r8") = 0; \
- register long __gu_r9 asm ("r9"); \
- asm ("\n[1:]\tld"#n" %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \
- "\t.xdata4 \"__ex_table\", 1b-., 1f-.+4\n" \
- "[1:]" \
- : "=r"(__gu_r9), "=r"(__gu_r8) : "m"(__m(addr)), "1"(__gu_r8)); \
- (err) = __gu_r8; \
- (val) = __gu_r9; \
-} while (0)
-
-/*
- * The "__put_user_size()" macro tells gcc it reads from memory instead of writing it. This
- * is because they do not write to any memory gcc knows about, so there are no aliasing
- * issues.
- */
-# define __put_user_size(val, addr, n, err) \
-do { \
- register long __pu_r8 asm ("r8") = 0; \
- asm volatile ("\n[1:]\tst"#n" %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \
- "\t.xdata4 \"__ex_table\", 1b-., 1f-.\n" \
- "[1:]" \
- : "=r"(__pu_r8) : "m"(__m(addr)), "rO"(val), "0"(__pu_r8)); \
- (err) = __pu_r8; \
-} while (0)
-
-#else /* !ASM_SUPPORTED */
-# define RELOC_TYPE 2 /* ip-rel */
-# define __get_user_size(val, addr, n, err) \
-do { \
- __ld_user("__ex_table", (unsigned long) addr, n, RELOC_TYPE); \
- (err) = ia64_getreg(_IA64_REG_R8); \
- (val) = ia64_getreg(_IA64_REG_R9); \
-} while (0)
-# define __put_user_size(val, addr, n, err) \
-do { \
- __st_user("__ex_table", (unsigned long) addr, n, RELOC_TYPE, \
- (__force unsigned long) (val)); \
- (err) = ia64_getreg(_IA64_REG_R8); \
-} while (0)
-#endif /* !ASM_SUPPORTED */
-
-extern void __get_user_unknown (void);
-
-/*
- * Evaluating arguments X, PTR, SIZE, and SEGMENT may involve subroutine-calls, which
- * could clobber r8 and r9 (among others). Thus, be careful not to evaluate it while
- * using r8/r9.
- */
-#define __do_get_user(check, x, ptr, size) \
-({ \
- const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
- __typeof__ (size) __gu_size = (size); \
- long __gu_err = -EFAULT; \
- unsigned long __gu_val = 0; \
- if (!check || __access_ok(__gu_ptr, size)) \
- switch (__gu_size) { \
- case 1: __get_user_size(__gu_val, __gu_ptr, 1, __gu_err); break; \
- case 2: __get_user_size(__gu_val, __gu_ptr, 2, __gu_err); break; \
- case 4: __get_user_size(__gu_val, __gu_ptr, 4, __gu_err); break; \
- case 8: __get_user_size(__gu_val, __gu_ptr, 8, __gu_err); break; \
- default: __get_user_unknown(); break; \
- } \
- (x) = (__force __typeof__(*(__gu_ptr))) __gu_val; \
- __gu_err; \
-})
-
-#define __get_user_nocheck(x, ptr, size) __do_get_user(0, x, ptr, size)
-#define __get_user_check(x, ptr, size) __do_get_user(1, x, ptr, size)
-
-extern void __put_user_unknown (void);
-
-/*
- * Evaluating arguments X, PTR, SIZE, and SEGMENT may involve subroutine-calls, which
- * could clobber r8 (among others). Thus, be careful not to evaluate them while using r8.
- */
-#define __do_put_user(check, x, ptr, size) \
-({ \
- __typeof__ (x) __pu_x = (x); \
- __typeof__ (*(ptr)) __user *__pu_ptr = (ptr); \
- __typeof__ (size) __pu_size = (size); \
- long __pu_err = -EFAULT; \
- \
- if (!check || __access_ok(__pu_ptr, __pu_size)) \
- switch (__pu_size) { \
- case 1: __put_user_size(__pu_x, __pu_ptr, 1, __pu_err); break; \
- case 2: __put_user_size(__pu_x, __pu_ptr, 2, __pu_err); break; \
- case 4: __put_user_size(__pu_x, __pu_ptr, 4, __pu_err); break; \
- case 8: __put_user_size(__pu_x, __pu_ptr, 8, __pu_err); break; \
- default: __put_user_unknown(); break; \
- } \
- __pu_err; \
-})
-
-#define __put_user_nocheck(x, ptr, size) __do_put_user(0, x, ptr, size)
-#define __put_user_check(x, ptr, size) __do_put_user(1, x, ptr, size)
-
-/*
- * Complex access routines
- */
-extern unsigned long __must_check __copy_user (void __user *to, const void __user *from,
- unsigned long count);
-
-static inline unsigned long
-raw_copy_to_user(void __user *to, const void *from, unsigned long count)
-{
- return __copy_user(to, (__force void __user *) from, count);
-}
-
-static inline unsigned long
-raw_copy_from_user(void *to, const void __user *from, unsigned long count)
-{
- return __copy_user((__force void __user *) to, from, count);
-}
-
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
-
-extern unsigned long __do_clear_user (void __user *, unsigned long);
-
-#define __clear_user(to, n) __do_clear_user(to, n)
-
-#define clear_user(to, n) \
-({ \
- unsigned long __cu_len = (n); \
- if (__access_ok(to, __cu_len)) \
- __cu_len = __do_clear_user(to, __cu_len); \
- __cu_len; \
-})
-
-
-/*
- * Returns: -EFAULT if exception before terminator, N if the entire buffer filled, else
- * strlen.
- */
-extern long __must_check __strncpy_from_user (char *to, const char __user *from, long to_len);
-
-#define strncpy_from_user(to, from, n) \
-({ \
- const char __user * __sfu_from = (from); \
- long __sfu_ret = -EFAULT; \
- if (__access_ok(__sfu_from, 0)) \
- __sfu_ret = __strncpy_from_user((to), __sfu_from, (n)); \
- __sfu_ret; \
-})
-
-/*
- * Returns: 0 if exception before NUL or reaching the supplied limit
- * (N), a value greater than N if the limit would be exceeded, else
- * strlen.
- */
-extern unsigned long __strnlen_user (const char __user *, long);
-
-#define strnlen_user(str, len) \
-({ \
- const char __user *__su_str = (str); \
- unsigned long __su_ret = 0; \
- if (__access_ok(__su_str, 0)) \
- __su_ret = __strnlen_user(__su_str, len); \
- __su_ret; \
-})
-
-#define ARCH_HAS_TRANSLATE_MEM_PTR 1
-static __inline__ void *
-xlate_dev_mem_ptr(phys_addr_t p)
-{
- struct page *page;
- void *ptr;
-
- page = pfn_to_page(p >> PAGE_SHIFT);
- if (PageUncached(page))
- ptr = (void *)p + __IA64_UNCACHED_OFFSET;
- else
- ptr = __va(p);
-
- return ptr;
-}
-
-#endif /* _ASM_IA64_UACCESS_H */
diff --git a/arch/ia64/include/asm/uncached.h b/arch/ia64/include/asm/uncached.h
deleted file mode 100644
index 98f447fc77b7..000000000000
--- a/arch/ia64/include/asm/uncached.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2001-2008 Silicon Graphics, Inc. All rights reserved.
- *
- * Prototypes for the uncached page allocator
- */
-
-extern unsigned long uncached_alloc_page(int starting_nid, int n_pages);
-extern void uncached_free_page(unsigned long uc_addr, int n_pages);
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
deleted file mode 100644
index 9ba6110b10b9..000000000000
--- a/arch/ia64/include/asm/unistd.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * IA-64 Linux syscall numbers and inline-functions.
- *
- * Copyright (C) 1998-2005 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#ifndef _ASM_IA64_UNISTD_H
-#define _ASM_IA64_UNISTD_H
-
-#include <uapi/asm/unistd.h>
-
-#define NR_syscalls __NR_syscalls /* length of syscall table */
-
-#define __ARCH_WANT_NEW_STAT
-#define __ARCH_WANT_SYS_UTIME
-
-#if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
-
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <linux/compiler.h>
-
-extern long __ia64_syscall (long a0, long a1, long a2, long a3, long a4, long nr);
-
-asmlinkage unsigned long sys_mmap(
- unsigned long addr, unsigned long len,
- int prot, int flags,
- int fd, long off);
-asmlinkage unsigned long sys_mmap2(
- unsigned long addr, unsigned long len,
- int prot, int flags,
- int fd, long pgoff);
-struct pt_regs;
-asmlinkage long sys_ia64_pipe(void);
-
-#endif /* !__ASSEMBLY__ */
-#endif /* _ASM_IA64_UNISTD_H */
diff --git a/arch/ia64/include/asm/unwind.h b/arch/ia64/include/asm/unwind.h
deleted file mode 100644
index c5bd4b3e3a36..000000000000
--- a/arch/ia64/include/asm/unwind.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_UNWIND_H
-#define _ASM_IA64_UNWIND_H
-
-/*
- * Copyright (C) 1999-2000, 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * A simple API for unwinding kernel stacks. This is used for
- * debugging and error reporting purposes. The kernel doesn't need
- * full-blown stack unwinding with all the bells and whitles, so there
- * is not much point in implementing the full IA-64 unwind API (though
- * it would of course be possible to implement the kernel API on top
- * of it).
- */
-
-struct task_struct; /* forward declaration */
-struct switch_stack; /* forward declaration */
-
-enum unw_application_register {
- UNW_AR_BSP,
- UNW_AR_BSPSTORE,
- UNW_AR_PFS,
- UNW_AR_RNAT,
- UNW_AR_UNAT,
- UNW_AR_LC,
- UNW_AR_EC,
- UNW_AR_FPSR,
- UNW_AR_RSC,
- UNW_AR_CCV,
- UNW_AR_CSD,
- UNW_AR_SSD
-};
-
-/*
- * The following declarations are private to the unwind
- * implementation:
- */
-
-struct unw_stack {
- unsigned long limit;
- unsigned long top;
-};
-
-#define UNW_FLAG_INTERRUPT_FRAME (1UL << 0)
-
-/*
- * No user of this module should every access this structure directly
- * as it is subject to change. It is declared here solely so we can
- * use automatic variables.
- */
-struct unw_frame_info {
- struct unw_stack regstk;
- struct unw_stack memstk;
- unsigned int flags;
- short hint;
- short prev_script;
-
- /* current frame info: */
- unsigned long bsp; /* backing store pointer value */
- unsigned long sp; /* stack pointer value */
- unsigned long psp; /* previous sp value */
- unsigned long ip; /* instruction pointer value */
- unsigned long pr; /* current predicate values */
- unsigned long *cfm_loc; /* cfm save location (or NULL) */
- unsigned long pt; /* struct pt_regs location */
-
- struct task_struct *task;
- struct switch_stack *sw;
-
- /* preserved state: */
- unsigned long *bsp_loc; /* previous bsp save location */
- unsigned long *bspstore_loc;
- unsigned long *pfs_loc;
- unsigned long *rnat_loc;
- unsigned long *rp_loc;
- unsigned long *pri_unat_loc;
- unsigned long *unat_loc;
- unsigned long *pr_loc;
- unsigned long *lc_loc;
- unsigned long *fpsr_loc;
- struct unw_ireg {
- unsigned long *loc;
- struct unw_ireg_nat {
- unsigned long type : 3; /* enum unw_nat_type */
- signed long off : 61; /* NaT word is at loc+nat.off */
- } nat;
- } r4, r5, r6, r7;
- unsigned long *b1_loc, *b2_loc, *b3_loc, *b4_loc, *b5_loc;
- struct ia64_fpreg *f2_loc, *f3_loc, *f4_loc, *f5_loc, *fr_loc[16];
-};
-
-/*
- * The official API follows below:
- */
-
-struct unw_table_entry {
- u64 start_offset;
- u64 end_offset;
- u64 info_offset;
-};
-
-/*
- * Initialize unwind support.
- */
-extern void unw_init (void);
-
-extern void *unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned long gp,
- const void *table_start, const void *table_end);
-
-extern void unw_remove_unwind_table (void *handle);
-
-/*
- * Prepare to unwind blocked task t.
- */
-extern void unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t);
-
-extern void unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t,
- struct switch_stack *sw);
-
-/*
- * Prepare to unwind the currently running thread.
- */
-extern void unw_init_running (void (*callback)(struct unw_frame_info *info, void *arg), void *arg);
-
-/*
- * Unwind to previous to frame. Returns 0 if successful, negative
- * number in case of an error.
- */
-extern int unw_unwind (struct unw_frame_info *info);
-
-/*
- * Unwind until the return pointer is in user-land (or until an error
- * occurs). Returns 0 if successful, negative number in case of
- * error.
- */
-extern int unw_unwind_to_user (struct unw_frame_info *info);
-
-#define unw_is_intr_frame(info) (((info)->flags & UNW_FLAG_INTERRUPT_FRAME) != 0)
-
-static inline int
-unw_get_ip (struct unw_frame_info *info, unsigned long *valp)
-{
- *valp = (info)->ip;
- return 0;
-}
-
-static inline int
-unw_get_sp (struct unw_frame_info *info, unsigned long *valp)
-{
- *valp = (info)->sp;
- return 0;
-}
-
-static inline int
-unw_get_psp (struct unw_frame_info *info, unsigned long *valp)
-{
- *valp = (info)->psp;
- return 0;
-}
-
-static inline int
-unw_get_bsp (struct unw_frame_info *info, unsigned long *valp)
-{
- *valp = (info)->bsp;
- return 0;
-}
-
-static inline int
-unw_get_cfm (struct unw_frame_info *info, unsigned long *valp)
-{
- *valp = *(info)->cfm_loc;
- return 0;
-}
-
-static inline int
-unw_set_cfm (struct unw_frame_info *info, unsigned long val)
-{
- *(info)->cfm_loc = val;
- return 0;
-}
-
-static inline int
-unw_get_rp (struct unw_frame_info *info, unsigned long *val)
-{
- if (!info->rp_loc)
- return -1;
- *val = *info->rp_loc;
- return 0;
-}
-
-extern int unw_access_gr (struct unw_frame_info *, int, unsigned long *, char *, int);
-extern int unw_access_br (struct unw_frame_info *, int, unsigned long *, int);
-extern int unw_access_fr (struct unw_frame_info *, int, struct ia64_fpreg *, int);
-extern int unw_access_ar (struct unw_frame_info *, int, unsigned long *, int);
-extern int unw_access_pr (struct unw_frame_info *, unsigned long *, int);
-
-static inline int
-unw_set_gr (struct unw_frame_info *i, int n, unsigned long v, char nat)
-{
- return unw_access_gr(i, n, &v, &nat, 1);
-}
-
-static inline int
-unw_set_br (struct unw_frame_info *i, int n, unsigned long v)
-{
- return unw_access_br(i, n, &v, 1);
-}
-
-static inline int
-unw_set_fr (struct unw_frame_info *i, int n, struct ia64_fpreg v)
-{
- return unw_access_fr(i, n, &v, 1);
-}
-
-static inline int
-unw_set_ar (struct unw_frame_info *i, int n, unsigned long v)
-{
- return unw_access_ar(i, n, &v, 1);
-}
-
-static inline int
-unw_set_pr (struct unw_frame_info *i, unsigned long v)
-{
- return unw_access_pr(i, &v, 1);
-}
-
-#define unw_get_gr(i,n,v,nat) unw_access_gr(i,n,v,nat,0)
-#define unw_get_br(i,n,v) unw_access_br(i,n,v,0)
-#define unw_get_fr(i,n,v) unw_access_fr(i,n,v,0)
-#define unw_get_ar(i,n,v) unw_access_ar(i,n,v,0)
-#define unw_get_pr(i,v) unw_access_pr(i,v,0)
-
-#endif /* _ASM_UNWIND_H */
diff --git a/arch/ia64/include/asm/user.h b/arch/ia64/include/asm/user.h
deleted file mode 100644
index ec03d3ab8715..000000000000
--- a/arch/ia64/include/asm/user.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_USER_H
-#define _ASM_IA64_USER_H
-
-/*
- * Core file format: The core file is written in such a way that gdb
- * can understand it and provide useful information to the user (under
- * linux we use the `trad-core' bfd). The file contents are as
- * follows:
- *
- * upage: 1 page consisting of a user struct that tells gdb
- * what is present in the file. Directly after this is a
- * copy of the task_struct, which is currently not used by gdb,
- * but it may come in handy at some point. All of the registers
- * are stored as part of the upage. The upage should always be
- * only one page long.
- * data: The data segment follows next. We use current->end_text to
- * current->brk to pick up all of the user variables, plus any memory
- * that may have been sbrk'ed. No attempt is made to determine if a
- * page is demand-zero or if a page is totally unused, we just cover
- * the entire range. All of the addresses are rounded in such a way
- * that an integral number of pages is written.
- * stack: We need the stack information in order to get a meaningful
- * backtrace. We need to write the data from usp to
- * current->start_stack, so we round each of these in order to be able
- * to write an integer number of pages.
- *
- * Modified 1998, 1999, 2001
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-#include <linux/ptrace.h>
-#include <linux/types.h>
-
-#include <asm/page.h>
-
-#define EF_SIZE 3072 /* XXX fix me */
-
-struct user {
- unsigned long regs[EF_SIZE/8+32]; /* integer and fp regs */
- size_t u_tsize; /* text size (pages) */
- size_t u_dsize; /* data size (pages) */
- size_t u_ssize; /* stack size (pages) */
- unsigned long start_code; /* text starting address */
- unsigned long start_data; /* data starting address */
- unsigned long start_stack; /* stack starting address */
- long int signal; /* signal causing core dump */
- unsigned long u_ar0; /* help gdb find registers */
- unsigned long magic; /* identifies a core file */
- char u_comm[32]; /* user command name */
-};
-
-#endif /* _ASM_IA64_USER_H */
diff --git a/arch/ia64/include/asm/ustack.h b/arch/ia64/include/asm/ustack.h
deleted file mode 100644
index 112d40a0fec2..000000000000
--- a/arch/ia64/include/asm/ustack.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_USTACK_H
-#define _ASM_IA64_USTACK_H
-
-#include <asm/page.h>
-#include <uapi/asm/ustack.h>
-
-/* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
-#define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
-#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
-#define STACK_TOP_MAX STACK_TOP
-#endif /* _ASM_IA64_USTACK_H */
diff --git a/arch/ia64/include/asm/uv/uv.h b/arch/ia64/include/asm/uv/uv.h
deleted file mode 100644
index 48d4526bf4cd..000000000000
--- a/arch/ia64/include/asm/uv/uv.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_UV_UV_H
-#define _ASM_IA64_UV_UV_H
-
-#ifdef CONFIG_IA64_SGI_UV
-extern bool ia64_is_uv;
-
-static inline int is_uv_system(void)
-{
- return ia64_is_uv;
-}
-
-void __init uv_probe_system_type(void);
-void __init uv_setup(char **cmdline_p);
-#else /* CONFIG_IA64_SGI_UV */
-static inline int is_uv_system(void)
-{
- return false;
-}
-
-static inline void __init uv_probe_system_type(void)
-{
-}
-
-static inline void __init uv_setup(char **cmdline_p)
-{
-}
-#endif /* CONFIG_IA64_SGI_UV */
-
-#endif /* _ASM_IA64_UV_UV_H */
diff --git a/arch/ia64/include/asm/uv/uv_hub.h b/arch/ia64/include/asm/uv/uv_hub.h
deleted file mode 100644
index 809ddb6896db..000000000000
--- a/arch/ia64/include/asm/uv/uv_hub.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * SGI UV architectural definitions
- *
- * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef __ASM_IA64_UV_HUB_H__
-#define __ASM_IA64_UV_HUB_H__
-
-#include <linux/numa.h>
-#include <linux/percpu.h>
-#include <asm/types.h>
-#include <asm/percpu.h>
-
-
-/*
- * Addressing Terminology
- *
- * M - The low M bits of a physical address represent the offset
- * into the blade local memory. RAM memory on a blade is physically
- * contiguous (although various IO spaces may punch holes in
- * it)..
- *
- * N - Number of bits in the node portion of a socket physical
- * address.
- *
- * NASID - network ID of a router, Mbrick or Cbrick. Nasid values of
- * routers always have low bit of 1, C/MBricks have low bit
- * equal to 0. Most addressing macros that target UV hub chips
- * right shift the NASID by 1 to exclude the always-zero bit.
- * NASIDs contain up to 15 bits.
- *
- * GNODE - NASID right shifted by 1 bit. Most mmrs contain gnodes instead
- * of nasids.
- *
- * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant
- * of the nasid for socket usage.
- *
- *
- * NumaLink Global Physical Address Format:
- * +--------------------------------+---------------------+
- * |00..000| GNODE | NodeOffset |
- * +--------------------------------+---------------------+
- * |<-------53 - M bits --->|<--------M bits ----->
- *
- * M - number of node offset bits (35 .. 40)
- *
- *
- * Memory/UV-HUB Processor Socket Address Format:
- * +----------------+---------------+---------------------+
- * |00..000000000000| PNODE | NodeOffset |
- * +----------------+---------------+---------------------+
- * <--- N bits --->|<--------M bits ----->
- *
- * M - number of node offset bits (35 .. 40)
- * N - number of PNODE bits (0 .. 10)
- *
- * Note: M + N cannot currently exceed 44 (x86_64) or 46 (IA64).
- * The actual values are configuration dependent and are set at
- * boot time. M & N values are set by the hardware/BIOS at boot.
- */
-
-
-/*
- * Maximum number of bricks in all partitions and in all coherency domains.
- * This is the total number of bricks accessible in the numalink fabric. It
- * includes all C & M bricks. Routers are NOT included.
- *
- * This value is also the value of the maximum number of non-router NASIDs
- * in the numalink fabric.
- *
- * NOTE: a brick may contain 1 or 2 OS nodes. Don't get these confused.
- */
-#define UV_MAX_NUMALINK_BLADES 16384
-
-/*
- * Maximum number of C/Mbricks within a software SSI (hardware may support
- * more).
- */
-#define UV_MAX_SSI_BLADES 1
-
-/*
- * The largest possible NASID of a C or M brick (+ 2)
- */
-#define UV_MAX_NASID_VALUE (UV_MAX_NUMALINK_NODES * 2)
-
-/*
- * The following defines attributes of the HUB chip. These attributes are
- * frequently referenced and are kept in the per-cpu data areas of each cpu.
- * They are kept together in a struct to minimize cache misses.
- */
-struct uv_hub_info_s {
- unsigned long global_mmr_base;
- unsigned long gpa_mask;
- unsigned long gnode_upper;
- unsigned long lowmem_remap_top;
- unsigned long lowmem_remap_base;
- unsigned short pnode;
- unsigned short pnode_mask;
- unsigned short coherency_domain_number;
- unsigned short numa_blade_id;
- unsigned char blade_processor_id;
- unsigned char m_val;
- unsigned char n_val;
-};
-DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
-#define uv_hub_info this_cpu_ptr(&__uv_hub_info)
-#define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu))
-
-/*
- * Local & Global MMR space macros.
- * Note: macros are intended to be used ONLY by inline functions
- * in this file - not by other kernel code.
- * n - NASID (full 15-bit global nasid)
- * g - GNODE (full 15-bit global nasid, right shifted 1)
- * p - PNODE (local part of nsids, right shifted 1)
- */
-#define UV_NASID_TO_PNODE(n) (((n) >> 1) & uv_hub_info->pnode_mask)
-#define UV_PNODE_TO_NASID(p) (((p) << 1) | uv_hub_info->gnode_upper)
-
-#define UV_LOCAL_MMR_BASE 0xf4000000UL
-#define UV_GLOBAL_MMR32_BASE 0xf8000000UL
-#define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base)
-
-#define UV_GLOBAL_MMR32_PNODE_SHIFT 15
-#define UV_GLOBAL_MMR64_PNODE_SHIFT 26
-
-#define UV_GLOBAL_MMR32_PNODE_BITS(p) ((p) << (UV_GLOBAL_MMR32_PNODE_SHIFT))
-
-#define UV_GLOBAL_MMR64_PNODE_BITS(p) \
- ((unsigned long)(p) << UV_GLOBAL_MMR64_PNODE_SHIFT)
-
-/*
- * Macros for converting between kernel virtual addresses, socket local physical
- * addresses, and UV global physical addresses.
- * Note: use the standard __pa() & __va() macros for converting
- * between socket virtual and socket physical addresses.
- */
-
-/* socket phys RAM --> UV global physical address */
-static inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr)
-{
- if (paddr < uv_hub_info->lowmem_remap_top)
- paddr += uv_hub_info->lowmem_remap_base;
- return paddr | uv_hub_info->gnode_upper;
-}
-
-
-/* socket virtual --> UV global physical address */
-static inline unsigned long uv_gpa(void *v)
-{
- return __pa(v) | uv_hub_info->gnode_upper;
-}
-
-/* socket virtual --> UV global physical address */
-static inline void *uv_vgpa(void *v)
-{
- return (void *)uv_gpa(v);
-}
-
-/* UV global physical address --> socket virtual */
-static inline void *uv_va(unsigned long gpa)
-{
- return __va(gpa & uv_hub_info->gpa_mask);
-}
-
-/* pnode, offset --> socket virtual */
-static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
-{
- return __va(((unsigned long)pnode << uv_hub_info->m_val) | offset);
-}
-
-
-/*
- * Access global MMRs using the low memory MMR32 space. This region supports
- * faster MMR access but not all MMRs are accessible in this space.
- */
-static inline unsigned long *uv_global_mmr32_address(int pnode,
- unsigned long offset)
-{
- return __va(UV_GLOBAL_MMR32_BASE |
- UV_GLOBAL_MMR32_PNODE_BITS(pnode) | offset);
-}
-
-static inline void uv_write_global_mmr32(int pnode, unsigned long offset,
- unsigned long val)
-{
- *uv_global_mmr32_address(pnode, offset) = val;
-}
-
-static inline unsigned long uv_read_global_mmr32(int pnode,
- unsigned long offset)
-{
- return *uv_global_mmr32_address(pnode, offset);
-}
-
-/*
- * Access Global MMR space using the MMR space located at the top of physical
- * memory.
- */
-static inline unsigned long *uv_global_mmr64_address(int pnode,
- unsigned long offset)
-{
- return __va(UV_GLOBAL_MMR64_BASE |
- UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset);
-}
-
-static inline void uv_write_global_mmr64(int pnode, unsigned long offset,
- unsigned long val)
-{
- *uv_global_mmr64_address(pnode, offset) = val;
-}
-
-static inline unsigned long uv_read_global_mmr64(int pnode,
- unsigned long offset)
-{
- return *uv_global_mmr64_address(pnode, offset);
-}
-
-/*
- * Access hub local MMRs. Faster than using global space but only local MMRs
- * are accessible.
- */
-static inline unsigned long *uv_local_mmr_address(unsigned long offset)
-{
- return __va(UV_LOCAL_MMR_BASE | offset);
-}
-
-static inline unsigned long uv_read_local_mmr(unsigned long offset)
-{
- return *uv_local_mmr_address(offset);
-}
-
-static inline void uv_write_local_mmr(unsigned long offset, unsigned long val)
-{
- *uv_local_mmr_address(offset) = val;
-}
-
-/*
- * Structures and definitions for converting between cpu, node, pnode, and blade
- * numbers.
- */
-
-/* Blade-local cpu number of current cpu. Numbered 0 .. <# cpus on the blade> */
-static inline int uv_blade_processor_id(void)
-{
- return smp_processor_id();
-}
-
-/* Blade number of current cpu. Numnbered 0 .. <#blades -1> */
-static inline int uv_numa_blade_id(void)
-{
- return 0;
-}
-
-/* Convert a cpu number to the UV blade number */
-static inline int uv_cpu_to_blade_id(int cpu)
-{
- return 0;
-}
-
-/* Convert linux node number to the UV blade number */
-static inline int uv_node_to_blade_id(int nid)
-{
- return 0;
-}
-
-/* Convert a blade id to the PNODE of the blade */
-static inline int uv_blade_to_pnode(int bid)
-{
- return 0;
-}
-
-/* Determine the number of possible cpus on a blade */
-static inline int uv_blade_nr_possible_cpus(int bid)
-{
- return num_possible_cpus();
-}
-
-/* Determine the number of online cpus on a blade */
-static inline int uv_blade_nr_online_cpus(int bid)
-{
- return num_online_cpus();
-}
-
-/* Convert a cpu id to the PNODE of the blade containing the cpu */
-static inline int uv_cpu_to_pnode(int cpu)
-{
- return 0;
-}
-
-/* Convert a linux node number to the PNODE of the blade */
-static inline int uv_node_to_pnode(int nid)
-{
- return 0;
-}
-
-/* Maximum possible number of blades */
-static inline int uv_num_possible_blades(void)
-{
- return 1;
-}
-
-static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
-{
- /* not currently needed on ia64 */
-}
-
-
-#endif /* __ASM_IA64_UV_HUB__ */
-
diff --git a/arch/ia64/include/asm/uv/uv_mmrs.h b/arch/ia64/include/asm/uv/uv_mmrs.h
deleted file mode 100644
index fe0b8f05e1a8..000000000000
--- a/arch/ia64/include/asm/uv/uv_mmrs.h
+++ /dev/null
@@ -1,825 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * SGI UV MMR definitions
- *
- * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_UV_UV_MMRS_H
-#define _ASM_IA64_UV_UV_MMRS_H
-
-#define UV_MMR_ENABLE (1UL << 63)
-
-/* ========================================================================= */
-/* UVH_BAU_DATA_CONFIG */
-/* ========================================================================= */
-#define UVH_BAU_DATA_CONFIG 0x61680UL
-#define UVH_BAU_DATA_CONFIG_32 0x0438
-
-#define UVH_BAU_DATA_CONFIG_VECTOR_SHFT 0
-#define UVH_BAU_DATA_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_BAU_DATA_CONFIG_DM_SHFT 8
-#define UVH_BAU_DATA_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_BAU_DATA_CONFIG_DESTMODE_SHFT 11
-#define UVH_BAU_DATA_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_BAU_DATA_CONFIG_STATUS_SHFT 12
-#define UVH_BAU_DATA_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_BAU_DATA_CONFIG_P_SHFT 13
-#define UVH_BAU_DATA_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_BAU_DATA_CONFIG_T_SHFT 15
-#define UVH_BAU_DATA_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_BAU_DATA_CONFIG_M_SHFT 16
-#define UVH_BAU_DATA_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_BAU_DATA_CONFIG_APIC_ID_SHFT 32
-#define UVH_BAU_DATA_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_bau_data_config_u {
- unsigned long v;
- struct uvh_bau_data_config_s {
- unsigned long vector_ : 8; /* RW */
- unsigned long dm : 3; /* RW */
- unsigned long destmode : 1; /* RW */
- unsigned long status : 1; /* RO */
- unsigned long p : 1; /* RO */
- unsigned long rsvd_14 : 1; /* */
- unsigned long t : 1; /* RO */
- unsigned long m : 1; /* RW */
- unsigned long rsvd_17_31: 15; /* */
- unsigned long apic_id : 32; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_EVENT_OCCURRED0 */
-/* ========================================================================= */
-#define UVH_EVENT_OCCURRED0 0x70000UL
-#define UVH_EVENT_OCCURRED0_32 0x005e8
-
-#define UVH_EVENT_OCCURRED0_LB_HCERR_SHFT 0
-#define UVH_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL
-#define UVH_EVENT_OCCURRED0_GR0_HCERR_SHFT 1
-#define UVH_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000002UL
-#define UVH_EVENT_OCCURRED0_GR1_HCERR_SHFT 2
-#define UVH_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000004UL
-#define UVH_EVENT_OCCURRED0_LH_HCERR_SHFT 3
-#define UVH_EVENT_OCCURRED0_LH_HCERR_MASK 0x0000000000000008UL
-#define UVH_EVENT_OCCURRED0_RH_HCERR_SHFT 4
-#define UVH_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000010UL
-#define UVH_EVENT_OCCURRED0_XN_HCERR_SHFT 5
-#define UVH_EVENT_OCCURRED0_XN_HCERR_MASK 0x0000000000000020UL
-#define UVH_EVENT_OCCURRED0_SI_HCERR_SHFT 6
-#define UVH_EVENT_OCCURRED0_SI_HCERR_MASK 0x0000000000000040UL
-#define UVH_EVENT_OCCURRED0_LB_AOERR0_SHFT 7
-#define UVH_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000080UL
-#define UVH_EVENT_OCCURRED0_GR0_AOERR0_SHFT 8
-#define UVH_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000000100UL
-#define UVH_EVENT_OCCURRED0_GR1_AOERR0_SHFT 9
-#define UVH_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000000200UL
-#define UVH_EVENT_OCCURRED0_LH_AOERR0_SHFT 10
-#define UVH_EVENT_OCCURRED0_LH_AOERR0_MASK 0x0000000000000400UL
-#define UVH_EVENT_OCCURRED0_RH_AOERR0_SHFT 11
-#define UVH_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL
-#define UVH_EVENT_OCCURRED0_XN_AOERR0_SHFT 12
-#define UVH_EVENT_OCCURRED0_XN_AOERR0_MASK 0x0000000000001000UL
-#define UVH_EVENT_OCCURRED0_SI_AOERR0_SHFT 13
-#define UVH_EVENT_OCCURRED0_SI_AOERR0_MASK 0x0000000000002000UL
-#define UVH_EVENT_OCCURRED0_LB_AOERR1_SHFT 14
-#define UVH_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000004000UL
-#define UVH_EVENT_OCCURRED0_GR0_AOERR1_SHFT 15
-#define UVH_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000000008000UL
-#define UVH_EVENT_OCCURRED0_GR1_AOERR1_SHFT 16
-#define UVH_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000000010000UL
-#define UVH_EVENT_OCCURRED0_LH_AOERR1_SHFT 17
-#define UVH_EVENT_OCCURRED0_LH_AOERR1_MASK 0x0000000000020000UL
-#define UVH_EVENT_OCCURRED0_RH_AOERR1_SHFT 18
-#define UVH_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000040000UL
-#define UVH_EVENT_OCCURRED0_XN_AOERR1_SHFT 19
-#define UVH_EVENT_OCCURRED0_XN_AOERR1_MASK 0x0000000000080000UL
-#define UVH_EVENT_OCCURRED0_SI_AOERR1_SHFT 20
-#define UVH_EVENT_OCCURRED0_SI_AOERR1_MASK 0x0000000000100000UL
-#define UVH_EVENT_OCCURRED0_RH_VPI_INT_SHFT 21
-#define UVH_EVENT_OCCURRED0_RH_VPI_INT_MASK 0x0000000000200000UL
-#define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 22
-#define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 23
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000000800000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 24
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000001000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 25
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000002000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 26
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000004000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 27
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000000008000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 28
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000000010000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 29
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000000020000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 30
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000000040000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 31
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000000080000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 32
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000000100000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 33
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000000200000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 34
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000000400000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 35
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000000800000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 36
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000001000000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 37
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000002000000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 38
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000004000000000UL
-#define UVH_EVENT_OCCURRED0_L1_NMI_INT_SHFT 39
-#define UVH_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0000008000000000UL
-#define UVH_EVENT_OCCURRED0_STOP_CLOCK_SHFT 40
-#define UVH_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0000010000000000UL
-#define UVH_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 41
-#define UVH_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0000020000000000UL
-#define UVH_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 42
-#define UVH_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0000040000000000UL
-#define UVH_EVENT_OCCURRED0_LTC_INT_SHFT 43
-#define UVH_EVENT_OCCURRED0_LTC_INT_MASK 0x0000080000000000UL
-#define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 44
-#define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL
-#define UVH_EVENT_OCCURRED0_IPI_INT_SHFT 45
-#define UVH_EVENT_OCCURRED0_IPI_INT_MASK 0x0000200000000000UL
-#define UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT 46
-#define UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0000400000000000UL
-#define UVH_EVENT_OCCURRED0_EXTIO_INT1_SHFT 47
-#define UVH_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0000800000000000UL
-#define UVH_EVENT_OCCURRED0_EXTIO_INT2_SHFT 48
-#define UVH_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0001000000000000UL
-#define UVH_EVENT_OCCURRED0_EXTIO_INT3_SHFT 49
-#define UVH_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0002000000000000UL
-#define UVH_EVENT_OCCURRED0_PROFILE_INT_SHFT 50
-#define UVH_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0004000000000000UL
-#define UVH_EVENT_OCCURRED0_RTC0_SHFT 51
-#define UVH_EVENT_OCCURRED0_RTC0_MASK 0x0008000000000000UL
-#define UVH_EVENT_OCCURRED0_RTC1_SHFT 52
-#define UVH_EVENT_OCCURRED0_RTC1_MASK 0x0010000000000000UL
-#define UVH_EVENT_OCCURRED0_RTC2_SHFT 53
-#define UVH_EVENT_OCCURRED0_RTC2_MASK 0x0020000000000000UL
-#define UVH_EVENT_OCCURRED0_RTC3_SHFT 54
-#define UVH_EVENT_OCCURRED0_RTC3_MASK 0x0040000000000000UL
-#define UVH_EVENT_OCCURRED0_BAU_DATA_SHFT 55
-#define UVH_EVENT_OCCURRED0_BAU_DATA_MASK 0x0080000000000000UL
-#define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_SHFT 56
-#define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_MASK 0x0100000000000000UL
-union uvh_event_occurred0_u {
- unsigned long v;
- struct uvh_event_occurred0_s {
- unsigned long lb_hcerr : 1; /* RW, W1C */
- unsigned long gr0_hcerr : 1; /* RW, W1C */
- unsigned long gr1_hcerr : 1; /* RW, W1C */
- unsigned long lh_hcerr : 1; /* RW, W1C */
- unsigned long rh_hcerr : 1; /* RW, W1C */
- unsigned long xn_hcerr : 1; /* RW, W1C */
- unsigned long si_hcerr : 1; /* RW, W1C */
- unsigned long lb_aoerr0 : 1; /* RW, W1C */
- unsigned long gr0_aoerr0 : 1; /* RW, W1C */
- unsigned long gr1_aoerr0 : 1; /* RW, W1C */
- unsigned long lh_aoerr0 : 1; /* RW, W1C */
- unsigned long rh_aoerr0 : 1; /* RW, W1C */
- unsigned long xn_aoerr0 : 1; /* RW, W1C */
- unsigned long si_aoerr0 : 1; /* RW, W1C */
- unsigned long lb_aoerr1 : 1; /* RW, W1C */
- unsigned long gr0_aoerr1 : 1; /* RW, W1C */
- unsigned long gr1_aoerr1 : 1; /* RW, W1C */
- unsigned long lh_aoerr1 : 1; /* RW, W1C */
- unsigned long rh_aoerr1 : 1; /* RW, W1C */
- unsigned long xn_aoerr1 : 1; /* RW, W1C */
- unsigned long si_aoerr1 : 1; /* RW, W1C */
- unsigned long rh_vpi_int : 1; /* RW, W1C */
- unsigned long system_shutdown_int : 1; /* RW, W1C */
- unsigned long lb_irq_int_0 : 1; /* RW, W1C */
- unsigned long lb_irq_int_1 : 1; /* RW, W1C */
- unsigned long lb_irq_int_2 : 1; /* RW, W1C */
- unsigned long lb_irq_int_3 : 1; /* RW, W1C */
- unsigned long lb_irq_int_4 : 1; /* RW, W1C */
- unsigned long lb_irq_int_5 : 1; /* RW, W1C */
- unsigned long lb_irq_int_6 : 1; /* RW, W1C */
- unsigned long lb_irq_int_7 : 1; /* RW, W1C */
- unsigned long lb_irq_int_8 : 1; /* RW, W1C */
- unsigned long lb_irq_int_9 : 1; /* RW, W1C */
- unsigned long lb_irq_int_10 : 1; /* RW, W1C */
- unsigned long lb_irq_int_11 : 1; /* RW, W1C */
- unsigned long lb_irq_int_12 : 1; /* RW, W1C */
- unsigned long lb_irq_int_13 : 1; /* RW, W1C */
- unsigned long lb_irq_int_14 : 1; /* RW, W1C */
- unsigned long lb_irq_int_15 : 1; /* RW, W1C */
- unsigned long l1_nmi_int : 1; /* RW, W1C */
- unsigned long stop_clock : 1; /* RW, W1C */
- unsigned long asic_to_l1 : 1; /* RW, W1C */
- unsigned long l1_to_asic : 1; /* RW, W1C */
- unsigned long ltc_int : 1; /* RW, W1C */
- unsigned long la_seq_trigger : 1; /* RW, W1C */
- unsigned long ipi_int : 1; /* RW, W1C */
- unsigned long extio_int0 : 1; /* RW, W1C */
- unsigned long extio_int1 : 1; /* RW, W1C */
- unsigned long extio_int2 : 1; /* RW, W1C */
- unsigned long extio_int3 : 1; /* RW, W1C */
- unsigned long profile_int : 1; /* RW, W1C */
- unsigned long rtc0 : 1; /* RW, W1C */
- unsigned long rtc1 : 1; /* RW, W1C */
- unsigned long rtc2 : 1; /* RW, W1C */
- unsigned long rtc3 : 1; /* RW, W1C */
- unsigned long bau_data : 1; /* RW, W1C */
- unsigned long power_management_req : 1; /* RW, W1C */
- unsigned long rsvd_57_63 : 7; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_EVENT_OCCURRED0_ALIAS */
-/* ========================================================================= */
-#define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL
-#define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0
-
-/* ========================================================================= */
-/* UVH_GR0_TLB_INT0_CONFIG */
-/* ========================================================================= */
-#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL
-
-#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_SHFT 0
-#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_GR0_TLB_INT0_CONFIG_DM_SHFT 8
-#define UVH_GR0_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_SHFT 11
-#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_GR0_TLB_INT0_CONFIG_STATUS_SHFT 12
-#define UVH_GR0_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_GR0_TLB_INT0_CONFIG_P_SHFT 13
-#define UVH_GR0_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_GR0_TLB_INT0_CONFIG_T_SHFT 15
-#define UVH_GR0_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_GR0_TLB_INT0_CONFIG_M_SHFT 16
-#define UVH_GR0_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_SHFT 32
-#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_gr0_tlb_int0_config_u {
- unsigned long v;
- struct uvh_gr0_tlb_int0_config_s {
- unsigned long vector_ : 8; /* RW */
- unsigned long dm : 3; /* RW */
- unsigned long destmode : 1; /* RW */
- unsigned long status : 1; /* RO */
- unsigned long p : 1; /* RO */
- unsigned long rsvd_14 : 1; /* */
- unsigned long t : 1; /* RO */
- unsigned long m : 1; /* RW */
- unsigned long rsvd_17_31: 15; /* */
- unsigned long apic_id : 32; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_GR0_TLB_INT1_CONFIG */
-/* ========================================================================= */
-#define UVH_GR0_TLB_INT1_CONFIG 0x61b40UL
-
-#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_SHFT 0
-#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_GR0_TLB_INT1_CONFIG_DM_SHFT 8
-#define UVH_GR0_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_SHFT 11
-#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_GR0_TLB_INT1_CONFIG_STATUS_SHFT 12
-#define UVH_GR0_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_GR0_TLB_INT1_CONFIG_P_SHFT 13
-#define UVH_GR0_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_GR0_TLB_INT1_CONFIG_T_SHFT 15
-#define UVH_GR0_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_GR0_TLB_INT1_CONFIG_M_SHFT 16
-#define UVH_GR0_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_SHFT 32
-#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_gr0_tlb_int1_config_u {
- unsigned long v;
- struct uvh_gr0_tlb_int1_config_s {
- unsigned long vector_ : 8; /* RW */
- unsigned long dm : 3; /* RW */
- unsigned long destmode : 1; /* RW */
- unsigned long status : 1; /* RO */
- unsigned long p : 1; /* RO */
- unsigned long rsvd_14 : 1; /* */
- unsigned long t : 1; /* RO */
- unsigned long m : 1; /* RW */
- unsigned long rsvd_17_31: 15; /* */
- unsigned long apic_id : 32; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_GR1_TLB_INT0_CONFIG */
-/* ========================================================================= */
-#define UVH_GR1_TLB_INT0_CONFIG 0x61f00UL
-
-#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_SHFT 0
-#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_GR1_TLB_INT0_CONFIG_DM_SHFT 8
-#define UVH_GR1_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_SHFT 11
-#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_GR1_TLB_INT0_CONFIG_STATUS_SHFT 12
-#define UVH_GR1_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_GR1_TLB_INT0_CONFIG_P_SHFT 13
-#define UVH_GR1_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_GR1_TLB_INT0_CONFIG_T_SHFT 15
-#define UVH_GR1_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_GR1_TLB_INT0_CONFIG_M_SHFT 16
-#define UVH_GR1_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_SHFT 32
-#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_gr1_tlb_int0_config_u {
- unsigned long v;
- struct uvh_gr1_tlb_int0_config_s {
- unsigned long vector_ : 8; /* RW */
- unsigned long dm : 3; /* RW */
- unsigned long destmode : 1; /* RW */
- unsigned long status : 1; /* RO */
- unsigned long p : 1; /* RO */
- unsigned long rsvd_14 : 1; /* */
- unsigned long t : 1; /* RO */
- unsigned long m : 1; /* RW */
- unsigned long rsvd_17_31: 15; /* */
- unsigned long apic_id : 32; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_GR1_TLB_INT1_CONFIG */
-/* ========================================================================= */
-#define UVH_GR1_TLB_INT1_CONFIG 0x61f40UL
-
-#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_SHFT 0
-#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_GR1_TLB_INT1_CONFIG_DM_SHFT 8
-#define UVH_GR1_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_SHFT 11
-#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_GR1_TLB_INT1_CONFIG_STATUS_SHFT 12
-#define UVH_GR1_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_GR1_TLB_INT1_CONFIG_P_SHFT 13
-#define UVH_GR1_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_GR1_TLB_INT1_CONFIG_T_SHFT 15
-#define UVH_GR1_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_GR1_TLB_INT1_CONFIG_M_SHFT 16
-#define UVH_GR1_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_SHFT 32
-#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_gr1_tlb_int1_config_u {
- unsigned long v;
- struct uvh_gr1_tlb_int1_config_s {
- unsigned long vector_ : 8; /* RW */
- unsigned long dm : 3; /* RW */
- unsigned long destmode : 1; /* RW */
- unsigned long status : 1; /* RO */
- unsigned long p : 1; /* RO */
- unsigned long rsvd_14 : 1; /* */
- unsigned long t : 1; /* RO */
- unsigned long m : 1; /* RW */
- unsigned long rsvd_17_31: 15; /* */
- unsigned long apic_id : 32; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_INT_CMPB */
-/* ========================================================================= */
-#define UVH_INT_CMPB 0x22080UL
-
-#define UVH_INT_CMPB_REAL_TIME_CMPB_SHFT 0
-#define UVH_INT_CMPB_REAL_TIME_CMPB_MASK 0x00ffffffffffffffUL
-
-union uvh_int_cmpb_u {
- unsigned long v;
- struct uvh_int_cmpb_s {
- unsigned long real_time_cmpb : 56; /* RW */
- unsigned long rsvd_56_63 : 8; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_INT_CMPC */
-/* ========================================================================= */
-#define UVH_INT_CMPC 0x22100UL
-
-#define UVH_INT_CMPC_REAL_TIME_CMPC_SHFT 0
-#define UVH_INT_CMPC_REAL_TIME_CMPC_MASK 0x00ffffffffffffffUL
-
-union uvh_int_cmpc_u {
- unsigned long v;
- struct uvh_int_cmpc_s {
- unsigned long real_time_cmpc : 56; /* RW */
- unsigned long rsvd_56_63 : 8; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_INT_CMPD */
-/* ========================================================================= */
-#define UVH_INT_CMPD 0x22180UL
-
-#define UVH_INT_CMPD_REAL_TIME_CMPD_SHFT 0
-#define UVH_INT_CMPD_REAL_TIME_CMPD_MASK 0x00ffffffffffffffUL
-
-union uvh_int_cmpd_u {
- unsigned long v;
- struct uvh_int_cmpd_s {
- unsigned long real_time_cmpd : 56; /* RW */
- unsigned long rsvd_56_63 : 8; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_NODE_ID */
-/* ========================================================================= */
-#define UVH_NODE_ID 0x0UL
-
-#define UVH_NODE_ID_FORCE1_SHFT 0
-#define UVH_NODE_ID_FORCE1_MASK 0x0000000000000001UL
-#define UVH_NODE_ID_MANUFACTURER_SHFT 1
-#define UVH_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL
-#define UVH_NODE_ID_PART_NUMBER_SHFT 12
-#define UVH_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL
-#define UVH_NODE_ID_REVISION_SHFT 28
-#define UVH_NODE_ID_REVISION_MASK 0x00000000f0000000UL
-#define UVH_NODE_ID_NODE_ID_SHFT 32
-#define UVH_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL
-#define UVH_NODE_ID_NODES_PER_BIT_SHFT 48
-#define UVH_NODE_ID_NODES_PER_BIT_MASK 0x007f000000000000UL
-#define UVH_NODE_ID_NI_PORT_SHFT 56
-#define UVH_NODE_ID_NI_PORT_MASK 0x0f00000000000000UL
-
-union uvh_node_id_u {
- unsigned long v;
- struct uvh_node_id_s {
- unsigned long force1 : 1; /* RO */
- unsigned long manufacturer : 11; /* RO */
- unsigned long part_number : 16; /* RO */
- unsigned long revision : 4; /* RO */
- unsigned long node_id : 15; /* RW */
- unsigned long rsvd_47 : 1; /* */
- unsigned long nodes_per_bit : 7; /* RW */
- unsigned long rsvd_55 : 1; /* */
- unsigned long ni_port : 4; /* RO */
- unsigned long rsvd_60_63 : 4; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR */
-/* ========================================================================= */
-#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR 0x16000d0UL
-
-#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT 24
-#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_MASK 0x00003fffff000000UL
-
-union uvh_rh_gam_alias210_redirect_config_0_mmr_u {
- unsigned long v;
- struct uvh_rh_gam_alias210_redirect_config_0_mmr_s {
- unsigned long rsvd_0_23 : 24; /* */
- unsigned long dest_base : 22; /* RW */
- unsigned long rsvd_46_63: 18; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR */
-/* ========================================================================= */
-#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR 0x16000e0UL
-
-#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_SHFT 24
-#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_MASK 0x00003fffff000000UL
-
-union uvh_rh_gam_alias210_redirect_config_1_mmr_u {
- unsigned long v;
- struct uvh_rh_gam_alias210_redirect_config_1_mmr_s {
- unsigned long rsvd_0_23 : 24; /* */
- unsigned long dest_base : 22; /* RW */
- unsigned long rsvd_46_63: 18; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR */
-/* ========================================================================= */
-#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR 0x16000f0UL
-
-#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_SHFT 24
-#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_MASK 0x00003fffff000000UL
-
-union uvh_rh_gam_alias210_redirect_config_2_mmr_u {
- unsigned long v;
- struct uvh_rh_gam_alias210_redirect_config_2_mmr_s {
- unsigned long rsvd_0_23 : 24; /* */
- unsigned long dest_base : 22; /* RW */
- unsigned long rsvd_46_63: 18; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */
-/* ========================================================================= */
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL
-
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 48
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0001000000000000UL
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
-
-union uvh_rh_gam_gru_overlay_config_mmr_u {
- unsigned long v;
- struct uvh_rh_gam_gru_overlay_config_mmr_s {
- unsigned long rsvd_0_27: 28; /* */
- unsigned long base : 18; /* RW */
- unsigned long rsvd_46_47: 2; /* */
- unsigned long gr4 : 1; /* RW */
- unsigned long rsvd_49_51: 3; /* */
- unsigned long n_gru : 4; /* RW */
- unsigned long rsvd_56_62: 7; /* */
- unsigned long enable : 1; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR */
-/* ========================================================================= */
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR 0x1600028UL
-
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_SHFT 46
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_MASK 0x0000400000000000UL
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
-
-union uvh_rh_gam_mmr_overlay_config_mmr_u {
- unsigned long v;
- struct uvh_rh_gam_mmr_overlay_config_mmr_s {
- unsigned long rsvd_0_25: 26; /* */
- unsigned long base : 20; /* RW */
- unsigned long dual_hub : 1; /* RW */
- unsigned long rsvd_47_62: 16; /* */
- unsigned long enable : 1; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RTC */
-/* ========================================================================= */
-#define UVH_RTC 0x340000UL
-
-#define UVH_RTC_REAL_TIME_CLOCK_SHFT 0
-#define UVH_RTC_REAL_TIME_CLOCK_MASK 0x00ffffffffffffffUL
-
-union uvh_rtc_u {
- unsigned long v;
- struct uvh_rtc_s {
- unsigned long real_time_clock : 56; /* RW */
- unsigned long rsvd_56_63 : 8; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RTC1_INT_CONFIG */
-/* ========================================================================= */
-#define UVH_RTC1_INT_CONFIG 0x615c0UL
-
-#define UVH_RTC1_INT_CONFIG_VECTOR_SHFT 0
-#define UVH_RTC1_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_RTC1_INT_CONFIG_DM_SHFT 8
-#define UVH_RTC1_INT_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_RTC1_INT_CONFIG_DESTMODE_SHFT 11
-#define UVH_RTC1_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_RTC1_INT_CONFIG_STATUS_SHFT 12
-#define UVH_RTC1_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_RTC1_INT_CONFIG_P_SHFT 13
-#define UVH_RTC1_INT_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_RTC1_INT_CONFIG_T_SHFT 15
-#define UVH_RTC1_INT_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_RTC1_INT_CONFIG_M_SHFT 16
-#define UVH_RTC1_INT_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_RTC1_INT_CONFIG_APIC_ID_SHFT 32
-#define UVH_RTC1_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_rtc1_int_config_u {
- unsigned long v;
- struct uvh_rtc1_int_config_s {
- unsigned long vector_ : 8; /* RW */
- unsigned long dm : 3; /* RW */
- unsigned long destmode : 1; /* RW */
- unsigned long status : 1; /* RO */
- unsigned long p : 1; /* RO */
- unsigned long rsvd_14 : 1; /* */
- unsigned long t : 1; /* RO */
- unsigned long m : 1; /* RW */
- unsigned long rsvd_17_31: 15; /* */
- unsigned long apic_id : 32; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RTC2_INT_CONFIG */
-/* ========================================================================= */
-#define UVH_RTC2_INT_CONFIG 0x61600UL
-
-#define UVH_RTC2_INT_CONFIG_VECTOR_SHFT 0
-#define UVH_RTC2_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_RTC2_INT_CONFIG_DM_SHFT 8
-#define UVH_RTC2_INT_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_RTC2_INT_CONFIG_DESTMODE_SHFT 11
-#define UVH_RTC2_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_RTC2_INT_CONFIG_STATUS_SHFT 12
-#define UVH_RTC2_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_RTC2_INT_CONFIG_P_SHFT 13
-#define UVH_RTC2_INT_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_RTC2_INT_CONFIG_T_SHFT 15
-#define UVH_RTC2_INT_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_RTC2_INT_CONFIG_M_SHFT 16
-#define UVH_RTC2_INT_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_RTC2_INT_CONFIG_APIC_ID_SHFT 32
-#define UVH_RTC2_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_rtc2_int_config_u {
- unsigned long v;
- struct uvh_rtc2_int_config_s {
- unsigned long vector_ : 8; /* RW */
- unsigned long dm : 3; /* RW */
- unsigned long destmode : 1; /* RW */
- unsigned long status : 1; /* RO */
- unsigned long p : 1; /* RO */
- unsigned long rsvd_14 : 1; /* */
- unsigned long t : 1; /* RO */
- unsigned long m : 1; /* RW */
- unsigned long rsvd_17_31: 15; /* */
- unsigned long apic_id : 32; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RTC3_INT_CONFIG */
-/* ========================================================================= */
-#define UVH_RTC3_INT_CONFIG 0x61640UL
-
-#define UVH_RTC3_INT_CONFIG_VECTOR_SHFT 0
-#define UVH_RTC3_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_RTC3_INT_CONFIG_DM_SHFT 8
-#define UVH_RTC3_INT_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_RTC3_INT_CONFIG_DESTMODE_SHFT 11
-#define UVH_RTC3_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_RTC3_INT_CONFIG_STATUS_SHFT 12
-#define UVH_RTC3_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_RTC3_INT_CONFIG_P_SHFT 13
-#define UVH_RTC3_INT_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_RTC3_INT_CONFIG_T_SHFT 15
-#define UVH_RTC3_INT_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_RTC3_INT_CONFIG_M_SHFT 16
-#define UVH_RTC3_INT_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_RTC3_INT_CONFIG_APIC_ID_SHFT 32
-#define UVH_RTC3_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_rtc3_int_config_u {
- unsigned long v;
- struct uvh_rtc3_int_config_s {
- unsigned long vector_ : 8; /* RW */
- unsigned long dm : 3; /* RW */
- unsigned long destmode : 1; /* RW */
- unsigned long status : 1; /* RO */
- unsigned long p : 1; /* RO */
- unsigned long rsvd_14 : 1; /* */
- unsigned long t : 1; /* RO */
- unsigned long m : 1; /* RW */
- unsigned long rsvd_17_31: 15; /* */
- unsigned long apic_id : 32; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_RTC_INC_RATIO */
-/* ========================================================================= */
-#define UVH_RTC_INC_RATIO 0x350000UL
-
-#define UVH_RTC_INC_RATIO_FRACTION_SHFT 0
-#define UVH_RTC_INC_RATIO_FRACTION_MASK 0x00000000000fffffUL
-#define UVH_RTC_INC_RATIO_RATIO_SHFT 20
-#define UVH_RTC_INC_RATIO_RATIO_MASK 0x0000000000700000UL
-
-union uvh_rtc_inc_ratio_u {
- unsigned long v;
- struct uvh_rtc_inc_ratio_s {
- unsigned long fraction : 20; /* RW */
- unsigned long ratio : 3; /* RW */
- unsigned long rsvd_23_63: 41; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_SI_ADDR_MAP_CONFIG */
-/* ========================================================================= */
-#define UVH_SI_ADDR_MAP_CONFIG 0xc80000UL
-
-#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_SHFT 0
-#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_MASK 0x000000000000003fUL
-#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_SHFT 8
-#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_MASK 0x0000000000000f00UL
-
-union uvh_si_addr_map_config_u {
- unsigned long v;
- struct uvh_si_addr_map_config_s {
- unsigned long m_skt : 6; /* RW */
- unsigned long rsvd_6_7: 2; /* */
- unsigned long n_skt : 4; /* RW */
- unsigned long rsvd_12_63: 52; /* */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_SI_ALIAS0_OVERLAY_CONFIG */
-/* ========================================================================= */
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG 0xc80008UL
-
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_SHFT 24
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_SHFT 48
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_SHFT 63
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL
-
-union uvh_si_alias0_overlay_config_u {
- unsigned long v;
- struct uvh_si_alias0_overlay_config_s {
- unsigned long rsvd_0_23: 24; /* */
- unsigned long base : 8; /* RW */
- unsigned long rsvd_32_47: 16; /* */
- unsigned long m_alias : 5; /* RW */
- unsigned long rsvd_53_62: 10; /* */
- unsigned long enable : 1; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_SI_ALIAS1_OVERLAY_CONFIG */
-/* ========================================================================= */
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG 0xc80010UL
-
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_SHFT 24
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_SHFT 48
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_SHFT 63
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL
-
-union uvh_si_alias1_overlay_config_u {
- unsigned long v;
- struct uvh_si_alias1_overlay_config_s {
- unsigned long rsvd_0_23: 24; /* */
- unsigned long base : 8; /* RW */
- unsigned long rsvd_32_47: 16; /* */
- unsigned long m_alias : 5; /* RW */
- unsigned long rsvd_53_62: 10; /* */
- unsigned long enable : 1; /* RW */
- } s;
-};
-
-/* ========================================================================= */
-/* UVH_SI_ALIAS2_OVERLAY_CONFIG */
-/* ========================================================================= */
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG 0xc80018UL
-
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_SHFT 24
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_SHFT 48
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_SHFT 63
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL
-
-union uvh_si_alias2_overlay_config_u {
- unsigned long v;
- struct uvh_si_alias2_overlay_config_s {
- unsigned long rsvd_0_23: 24; /* */
- unsigned long base : 8; /* RW */
- unsigned long rsvd_32_47: 16; /* */
- unsigned long m_alias : 5; /* RW */
- unsigned long rsvd_53_62: 10; /* */
- unsigned long enable : 1; /* RW */
- } s;
-};
-
-
-#endif /* _ASM_IA64_UV_UV_MMRS_H */
diff --git a/arch/ia64/include/asm/vermagic.h b/arch/ia64/include/asm/vermagic.h
deleted file mode 100644
index 29c7424f4c25..000000000000
--- a/arch/ia64/include/asm/vermagic.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#ifndef _ASM_VERMAGIC_H
-#define _ASM_VERMAGIC_H
-
-#include <linux/stringify.h>
-
-#define MODULE_ARCH_VERMAGIC "ia64" \
- "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__)
-
-#endif /* _ASM_VERMAGIC_H */
diff --git a/arch/ia64/include/asm/vga.h b/arch/ia64/include/asm/vga.h
deleted file mode 100644
index 64ce0b971a0a..000000000000
--- a/arch/ia64/include/asm/vga.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Access to VGA videoram
- *
- * (c) 1998 Martin Mares <mj@ucw.cz>
- * (c) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * (c) 1999 Don Dugger <don.dugger@intel.com>
- */
-
-#ifndef __ASM_IA64_VGA_H_
-#define __ASM_IA64_VGA_H_
-
-/*
- * On the PC, we can just recalculate addresses and then access the
- * videoram directly without any black magic.
- */
-
-extern unsigned long vga_console_iobase;
-extern unsigned long vga_console_membase;
-
-#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap(vga_console_membase + (x), s))
-
-#define vga_readb(x) (*(x))
-#define vga_writeb(x,y) (*(y) = (x))
-
-#endif /* __ASM_IA64_VGA_H_ */
diff --git a/arch/ia64/include/asm/vmalloc.h b/arch/ia64/include/asm/vmalloc.h
deleted file mode 100644
index a2b51141ad28..000000000000
--- a/arch/ia64/include/asm/vmalloc.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _ASM_IA64_VMALLOC_H
-#define _ASM_IA64_VMALLOC_H
-
-#endif /* _ASM_IA64_VMALLOC_H */
diff --git a/arch/ia64/include/asm/xor.h b/arch/ia64/include/asm/xor.h
deleted file mode 100644
index 6785f70d3208..000000000000
--- a/arch/ia64/include/asm/xor.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Optimized RAID-5 checksumming functions for IA-64.
- */
-
-
-extern void xor_ia64_2(unsigned long bytes, unsigned long * __restrict p1,
- const unsigned long * __restrict p2);
-extern void xor_ia64_3(unsigned long bytes, unsigned long * __restrict p1,
- const unsigned long * __restrict p2,
- const unsigned long * __restrict p3);
-extern void xor_ia64_4(unsigned long bytes, unsigned long * __restrict p1,
- const unsigned long * __restrict p2,
- const unsigned long * __restrict p3,
- const unsigned long * __restrict p4);
-extern void xor_ia64_5(unsigned long bytes, unsigned long * __restrict p1,
- const unsigned long * __restrict p2,
- const unsigned long * __restrict p3,
- const unsigned long * __restrict p4,
- const unsigned long * __restrict p5);
-
-static struct xor_block_template xor_block_ia64 = {
- .name = "ia64",
- .do_2 = xor_ia64_2,
- .do_3 = xor_ia64_3,
- .do_4 = xor_ia64_4,
- .do_5 = xor_ia64_5,
-};
-
-#define XOR_TRY_TEMPLATES xor_speed(&xor_block_ia64)
diff --git a/arch/ia64/include/asm/xtp.h b/arch/ia64/include/asm/xtp.h
deleted file mode 100644
index 5bf1d70ad860..000000000000
--- a/arch/ia64/include/asm/xtp.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_XTP_H
-#define _ASM_IA64_XTP_H
-
-#include <asm/io.h>
-
-#ifdef CONFIG_SMP
-
-#define XTP_OFFSET 0x1e0008
-
-#define SMP_IRQ_REDIRECTION (1 << 0)
-#define SMP_IPI_REDIRECTION (1 << 1)
-
-extern unsigned char smp_int_redirect;
-
-/*
- * XTP control functions:
- * min_xtp : route all interrupts to this CPU
- * normal_xtp: nominal XTP value
- * max_xtp : never deliver interrupts to this CPU.
- */
-
-static inline void
-min_xtp (void)
-{
- if (smp_int_redirect & SMP_IRQ_REDIRECTION)
- writeb(0x00, ipi_base_addr + XTP_OFFSET); /* XTP to min */
-}
-
-static inline void
-normal_xtp (void)
-{
- if (smp_int_redirect & SMP_IRQ_REDIRECTION)
- writeb(0x08, ipi_base_addr + XTP_OFFSET); /* XTP normal */
-}
-
-static inline void
-max_xtp (void)
-{
- if (smp_int_redirect & SMP_IRQ_REDIRECTION)
- writeb(0x0f, ipi_base_addr + XTP_OFFSET); /* Set XTP to max */
-}
-
-#endif /* CONFIG_SMP */
-
-#endif /* _ASM_IA64_XTP_Hy */
diff --git a/arch/ia64/include/uapi/asm/Kbuild b/arch/ia64/include/uapi/asm/Kbuild
deleted file mode 100644
index 3a1341e3535a..000000000000
--- a/arch/ia64/include/uapi/asm/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-generated-y += unistd_64.h
diff --git a/arch/ia64/include/uapi/asm/auxvec.h b/arch/ia64/include/uapi/asm/auxvec.h
deleted file mode 100644
index 09969a5d2e0a..000000000000
--- a/arch/ia64/include/uapi/asm/auxvec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_AUXVEC_H
-#define _ASM_IA64_AUXVEC_H
-
-/*
- * Architecture-neutral AT_ values are in the range 0-17. Leave some room for more of
- * them, start the architecture-specific ones at 32.
- */
-#define AT_SYSINFO 32
-#define AT_SYSINFO_EHDR 33
-
-#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */
-
-#endif /* _ASM_IA64_AUXVEC_H */
diff --git a/arch/ia64/include/uapi/asm/bitsperlong.h b/arch/ia64/include/uapi/asm/bitsperlong.h
deleted file mode 100644
index 1146d55563db..000000000000
--- a/arch/ia64/include/uapi/asm/bitsperlong.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef __ASM_IA64_BITSPERLONG_H
-#define __ASM_IA64_BITSPERLONG_H
-
-#define __BITS_PER_LONG 64
-
-#include <asm-generic/bitsperlong.h>
-
-#endif /* __ASM_IA64_BITSPERLONG_H */
diff --git a/arch/ia64/include/uapi/asm/break.h b/arch/ia64/include/uapi/asm/break.h
deleted file mode 100644
index 4ca110f0a94b..000000000000
--- a/arch/ia64/include/uapi/asm/break.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_BREAK_H
-#define _ASM_IA64_BREAK_H
-
-/*
- * IA-64 Linux break numbers.
- *
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-/*
- * OS-specific debug break numbers:
- */
-#define __IA64_BREAK_KDB 0x80100
-#define __IA64_BREAK_KPROBE 0x81000 /* .. 0x81fff */
-
-/*
- * OS-specific break numbers:
- */
-#define __IA64_BREAK_SYSCALL 0x100000
-
-#endif /* _ASM_IA64_BREAK_H */
diff --git a/arch/ia64/include/uapi/asm/byteorder.h b/arch/ia64/include/uapi/asm/byteorder.h
deleted file mode 100644
index f85d0faaaf34..000000000000
--- a/arch/ia64/include/uapi/asm/byteorder.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_BYTEORDER_H
-#define _ASM_IA64_BYTEORDER_H
-
-#include <linux/byteorder/little_endian.h>
-
-#endif /* _ASM_IA64_BYTEORDER_H */
diff --git a/arch/ia64/include/uapi/asm/cmpxchg.h b/arch/ia64/include/uapi/asm/cmpxchg.h
deleted file mode 100644
index a59b5de6eec6..000000000000
--- a/arch/ia64/include/uapi/asm/cmpxchg.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _UAPI_ASM_IA64_CMPXCHG_H
-#define _UAPI_ASM_IA64_CMPXCHG_H
-
-/*
- * Compare/Exchange, forked from asm/intrinsics.h
- * which was:
- *
- * Copyright (C) 2002-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-/* include compiler specific intrinsics */
-#include <asm/ia64regs.h>
-#include <asm/gcc_intrin.h>
-
-/*
- * This function doesn't exist, so you'll get a linker error if
- * something tries to do an invalid xchg().
- */
-extern void ia64_xchg_called_with_bad_pointer(void);
-
-#define __arch_xchg(x, ptr, size) \
-({ \
- unsigned long __xchg_result; \
- \
- switch (size) { \
- case 1: \
- __xchg_result = ia64_xchg1((__u8 __force *)ptr, x); \
- break; \
- \
- case 2: \
- __xchg_result = ia64_xchg2((__u16 __force *)ptr, x); \
- break; \
- \
- case 4: \
- __xchg_result = ia64_xchg4((__u32 __force *)ptr, x); \
- break; \
- \
- case 8: \
- __xchg_result = ia64_xchg8((__u64 __force *)ptr, x); \
- break; \
- default: \
- ia64_xchg_called_with_bad_pointer(); \
- } \
- (__typeof__ (*(ptr)) __force) __xchg_result; \
-})
-
-#ifndef __KERNEL__
-#define xchg(ptr, x) \
-({(__typeof__(*(ptr))) __arch_xchg((unsigned long) (x), (ptr), sizeof(*(ptr)));})
-#endif
-
-/*
- * Atomic compare and exchange. Compare OLD with MEM, if identical,
- * store NEW in MEM. Return the initial value in MEM. Success is
- * indicated by comparing RETURN with OLD.
- */
-
-/*
- * This function doesn't exist, so you'll get a linker error
- * if something tries to do an invalid cmpxchg().
- */
-extern long ia64_cmpxchg_called_with_bad_pointer(void);
-
-#define ia64_cmpxchg(sem, ptr, old, new, size) \
-({ \
- __u64 _o_, _r_; \
- \
- switch (size) { \
- case 1: \
- _o_ = (__u8) (long __force) (old); \
- break; \
- case 2: \
- _o_ = (__u16) (long __force) (old); \
- break; \
- case 4: \
- _o_ = (__u32) (long __force) (old); \
- break; \
- case 8: \
- _o_ = (__u64) (long __force) (old); \
- break; \
- default: \
- break; \
- } \
- switch (size) { \
- case 1: \
- _r_ = ia64_cmpxchg1_##sem((__u8 __force *) ptr, new, _o_); \
- break; \
- \
- case 2: \
- _r_ = ia64_cmpxchg2_##sem((__u16 __force *) ptr, new, _o_); \
- break; \
- \
- case 4: \
- _r_ = ia64_cmpxchg4_##sem((__u32 __force *) ptr, new, _o_); \
- break; \
- \
- case 8: \
- _r_ = ia64_cmpxchg8_##sem((__u64 __force *) ptr, new, _o_); \
- break; \
- \
- default: \
- _r_ = ia64_cmpxchg_called_with_bad_pointer(); \
- break; \
- } \
- (__typeof__(old) __force) _r_; \
-})
-
-#define cmpxchg_acq(ptr, o, n) \
- ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr)))
-#define cmpxchg_rel(ptr, o, n) \
- ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr)))
-
-/*
- * Worse still - early processor implementations actually just ignored
- * the acquire/release and did a full fence all the time. Unfortunately
- * this meant a lot of badly written code that used .acq when they really
- * wanted .rel became legacy out in the wild - so when we made a cpu
- * that strictly did the .acq or .rel ... all that code started breaking - so
- * we had to back-pedal and keep the "legacy" behavior of a full fence :-(
- */
-
-#ifndef __KERNEL__
-/* for compatibility with other platforms: */
-#define cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n))
-#define cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n))
-
-#define cmpxchg_local cmpxchg
-#define cmpxchg64_local cmpxchg64
-#endif
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _UAPI_ASM_IA64_CMPXCHG_H */
diff --git a/arch/ia64/include/uapi/asm/fcntl.h b/arch/ia64/include/uapi/asm/fcntl.h
deleted file mode 100644
index 7b95523efe5a..000000000000
--- a/arch/ia64/include/uapi/asm/fcntl.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_FCNTL_H
-#define _ASM_IA64_FCNTL_H
-/*
- * Modified 1998-2000
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co.
- */
-
-#define force_o_largefile() \
- (personality(current->personality) != PER_LINUX32)
-
-#include <linux/personality.h>
-#include <asm-generic/fcntl.h>
-
-#endif /* _ASM_IA64_FCNTL_H */
diff --git a/arch/ia64/include/uapi/asm/fpu.h b/arch/ia64/include/uapi/asm/fpu.h
deleted file mode 100644
index 0df392982ce8..000000000000
--- a/arch/ia64/include/uapi/asm/fpu.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_FPU_H
-#define _ASM_IA64_FPU_H
-
-/*
- * Copyright (C) 1998, 1999, 2002, 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/types.h>
-
-/* floating point status register: */
-#define FPSR_TRAP_VD (1 << 0) /* invalid op trap disabled */
-#define FPSR_TRAP_DD (1 << 1) /* denormal trap disabled */
-#define FPSR_TRAP_ZD (1 << 2) /* zero-divide trap disabled */
-#define FPSR_TRAP_OD (1 << 3) /* overflow trap disabled */
-#define FPSR_TRAP_UD (1 << 4) /* underflow trap disabled */
-#define FPSR_TRAP_ID (1 << 5) /* inexact trap disabled */
-#define FPSR_S0(x) ((x) << 6)
-#define FPSR_S1(x) ((x) << 19)
-#define FPSR_S2(x) (__IA64_UL(x) << 32)
-#define FPSR_S3(x) (__IA64_UL(x) << 45)
-
-/* floating-point status field controls: */
-#define FPSF_FTZ (1 << 0) /* flush-to-zero */
-#define FPSF_WRE (1 << 1) /* widest-range exponent */
-#define FPSF_PC(x) (((x) & 0x3) << 2) /* precision control */
-#define FPSF_RC(x) (((x) & 0x3) << 4) /* rounding control */
-#define FPSF_TD (1 << 6) /* trap disabled */
-
-/* floating-point status field flags: */
-#define FPSF_V (1 << 7) /* invalid operation flag */
-#define FPSF_D (1 << 8) /* denormal/unnormal operand flag */
-#define FPSF_Z (1 << 9) /* zero divide (IEEE) flag */
-#define FPSF_O (1 << 10) /* overflow (IEEE) flag */
-#define FPSF_U (1 << 11) /* underflow (IEEE) flag */
-#define FPSF_I (1 << 12) /* inexact (IEEE) flag) */
-
-/* floating-point rounding control: */
-#define FPRC_NEAREST 0x0
-#define FPRC_NEGINF 0x1
-#define FPRC_POSINF 0x2
-#define FPRC_TRUNC 0x3
-
-#define FPSF_DEFAULT (FPSF_PC (0x3) | FPSF_RC (FPRC_NEAREST))
-
-/* This default value is the same as HP-UX uses. Don't change it
- without a very good reason. */
-#define FPSR_DEFAULT (FPSR_TRAP_VD | FPSR_TRAP_DD | FPSR_TRAP_ZD \
- | FPSR_TRAP_OD | FPSR_TRAP_UD | FPSR_TRAP_ID \
- | FPSR_S0 (FPSF_DEFAULT) \
- | FPSR_S1 (FPSF_DEFAULT | FPSF_TD | FPSF_WRE) \
- | FPSR_S2 (FPSF_DEFAULT | FPSF_TD) \
- | FPSR_S3 (FPSF_DEFAULT | FPSF_TD))
-
-# ifndef __ASSEMBLY__
-
-struct ia64_fpreg {
- union {
- unsigned long bits[2];
- long double __dummy; /* force 16-byte alignment */
- } u;
-};
-
-# endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_IA64_FPU_H */
diff --git a/arch/ia64/include/uapi/asm/gcc_intrin.h b/arch/ia64/include/uapi/asm/gcc_intrin.h
deleted file mode 100644
index ecfa3eadb217..000000000000
--- a/arch/ia64/include/uapi/asm/gcc_intrin.h
+++ /dev/null
@@ -1,619 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- *
- * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
- * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
- */
-#ifndef _UAPI_ASM_IA64_GCC_INTRIN_H
-#define _UAPI_ASM_IA64_GCC_INTRIN_H
-
-#include <linux/types.h>
-#include <linux/compiler.h>
-
-/* define this macro to get some asm stmts included in 'c' files */
-#define ASM_SUPPORTED
-
-/* Optimization barrier */
-/* The "volatile" is due to gcc bugs */
-#define ia64_barrier() asm volatile ("":::"memory")
-
-#define ia64_stop() asm volatile (";;"::)
-
-#define ia64_invala_gr(regnum) asm volatile ("invala.e r%0" :: "i"(regnum))
-
-#define ia64_invala_fr(regnum) asm volatile ("invala.e f%0" :: "i"(regnum))
-
-#define ia64_flushrs() asm volatile ("flushrs;;":::"memory")
-
-#define ia64_loadrs() asm volatile ("loadrs;;":::"memory")
-
-extern void ia64_bad_param_for_setreg (void);
-extern void ia64_bad_param_for_getreg (void);
-
-
-#define ia64_setreg(regnum, val) \
-({ \
- switch (regnum) { \
- case _IA64_REG_PSR_L: \
- asm volatile ("mov psr.l=%0" :: "r"(val) : "memory"); \
- break; \
- case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \
- asm volatile ("mov ar%0=%1" :: \
- "i" (regnum - _IA64_REG_AR_KR0), \
- "r"(val): "memory"); \
- break; \
- case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \
- asm volatile ("mov cr%0=%1" :: \
- "i" (regnum - _IA64_REG_CR_DCR), \
- "r"(val): "memory" ); \
- break; \
- case _IA64_REG_SP: \
- asm volatile ("mov r12=%0" :: \
- "r"(val): "memory"); \
- break; \
- case _IA64_REG_GP: \
- asm volatile ("mov gp=%0" :: "r"(val) : "memory"); \
- break; \
- default: \
- ia64_bad_param_for_setreg(); \
- break; \
- } \
-})
-
-#define ia64_getreg(regnum) \
-({ \
- __u64 ia64_intri_res; \
- \
- switch (regnum) { \
- case _IA64_REG_GP: \
- asm volatile ("mov %0=gp" : "=r"(ia64_intri_res)); \
- break; \
- case _IA64_REG_IP: \
- asm volatile ("mov %0=ip" : "=r"(ia64_intri_res)); \
- break; \
- case _IA64_REG_PSR: \
- asm volatile ("mov %0=psr" : "=r"(ia64_intri_res)); \
- break; \
- case _IA64_REG_TP: /* for current() */ \
- ia64_intri_res = ia64_r13; \
- break; \
- case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \
- asm volatile ("mov %0=ar%1" : "=r" (ia64_intri_res) \
- : "i"(regnum - _IA64_REG_AR_KR0)); \
- break; \
- case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \
- asm volatile ("mov %0=cr%1" : "=r" (ia64_intri_res) \
- : "i" (regnum - _IA64_REG_CR_DCR)); \
- break; \
- case _IA64_REG_SP: \
- asm volatile ("mov %0=sp" : "=r" (ia64_intri_res)); \
- break; \
- default: \
- ia64_bad_param_for_getreg(); \
- break; \
- } \
- ia64_intri_res; \
-})
-
-#define ia64_hint_pause 0
-
-#define ia64_hint(mode) \
-({ \
- switch (mode) { \
- case ia64_hint_pause: \
- asm volatile ("hint @pause" ::: "memory"); \
- break; \
- } \
-})
-
-
-/* Integer values for mux1 instruction */
-#define ia64_mux1_brcst 0
-#define ia64_mux1_mix 8
-#define ia64_mux1_shuf 9
-#define ia64_mux1_alt 10
-#define ia64_mux1_rev 11
-
-#define ia64_mux1(x, mode) \
-({ \
- __u64 ia64_intri_res; \
- \
- switch (mode) { \
- case ia64_mux1_brcst: \
- asm ("mux1 %0=%1,@brcst" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- case ia64_mux1_mix: \
- asm ("mux1 %0=%1,@mix" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- case ia64_mux1_shuf: \
- asm ("mux1 %0=%1,@shuf" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- case ia64_mux1_alt: \
- asm ("mux1 %0=%1,@alt" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- case ia64_mux1_rev: \
- asm ("mux1 %0=%1,@rev" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- } \
- ia64_intri_res; \
-})
-
-#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-# define ia64_popcnt(x) __builtin_popcountl(x)
-#else
-# define ia64_popcnt(x) \
- ({ \
- __u64 ia64_intri_res; \
- asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
- \
- ia64_intri_res; \
- })
-#endif
-
-#define ia64_getf_exp(x) \
-({ \
- long ia64_intri_res; \
- \
- asm ("getf.exp %0=%1" : "=r"(ia64_intri_res) : "f"(x)); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_shrp(a, b, count) \
-({ \
- __u64 ia64_intri_res; \
- asm ("shrp %0=%1,%2,%3" : "=r"(ia64_intri_res) : "r"(a), "r"(b), "i"(count)); \
- ia64_intri_res; \
-})
-
-#define ia64_ldfs(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldfs %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_ldfd(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldfd %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_ldfe(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldfe %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_ldf8(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldf8 %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_ldf_fill(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldf.fill %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_st4_rel_nta(m, val) \
-({ \
- asm volatile ("st4.rel.nta [%0] = %1\n\t" :: "r"(m), "r"(val)); \
-})
-
-#define ia64_stfs(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stfs [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_stfd(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stfd [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_stfe(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stfe [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_stf8(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stf8 [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_stf_spill(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stf.spill [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_fetchadd4_acq(p, inc) \
-({ \
- \
- __u64 ia64_intri_res; \
- asm volatile ("fetchadd4.acq %0=[%1],%2" \
- : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
- : "memory"); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_fetchadd4_rel(p, inc) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("fetchadd4.rel %0=[%1],%2" \
- : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
- : "memory"); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_fetchadd8_acq(p, inc) \
-({ \
- \
- __u64 ia64_intri_res; \
- asm volatile ("fetchadd8.acq %0=[%1],%2" \
- : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
- : "memory"); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_fetchadd8_rel(p, inc) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("fetchadd8.rel %0=[%1],%2" \
- : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
- : "memory"); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_xchg1(ptr,x) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("xchg1 %0=[%1],%2" \
- : "=r" (ia64_intri_res) : "r" (ptr), "r" (x) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_xchg2(ptr,x) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("xchg2 %0=[%1],%2" : "=r" (ia64_intri_res) \
- : "r" (ptr), "r" (x) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_xchg4(ptr,x) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("xchg4 %0=[%1],%2" : "=r" (ia64_intri_res) \
- : "r" (ptr), "r" (x) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_xchg8(ptr,x) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("xchg8 %0=[%1],%2" : "=r" (ia64_intri_res) \
- : "r" (ptr), "r" (x) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg1_acq(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg1.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg1_rel(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg1.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg2_acq(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg2.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg2_rel(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- \
- asm volatile ("cmpxchg2.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg4_acq(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg4_rel(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg4.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg8_acq(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg8.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg8_rel(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- \
- asm volatile ("cmpxchg8.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_mf() asm volatile ("mf" ::: "memory")
-#define ia64_mfa() asm volatile ("mf.a" ::: "memory")
-
-#define ia64_invala() asm volatile ("invala" ::: "memory")
-
-#define ia64_thash(addr) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
- ia64_intri_res; \
-})
-
-#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory")
-#define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory");
-
-#ifdef HAVE_SERIALIZE_DIRECTIVE
-# define ia64_dv_serialize_data() asm volatile (".serialize.data");
-# define ia64_dv_serialize_instruction() asm volatile (".serialize.instruction");
-#else
-# define ia64_dv_serialize_data()
-# define ia64_dv_serialize_instruction()
-#endif
-
-#define ia64_nop(x) asm volatile ("nop %0"::"i"(x));
-
-#define ia64_itci(addr) asm volatile ("itc.i %0;;" :: "r"(addr) : "memory")
-
-#define ia64_itcd(addr) asm volatile ("itc.d %0;;" :: "r"(addr) : "memory")
-
-
-#define ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1" \
- :: "r"(trnum), "r"(addr) : "memory")
-
-#define ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1" \
- :: "r"(trnum), "r"(addr) : "memory")
-
-#define ia64_tpa(addr) \
-({ \
- unsigned long ia64_pa; \
- asm volatile ("tpa %0 = %1" : "=r"(ia64_pa) : "r"(addr) : "memory"); \
- ia64_pa; \
-})
-
-#define __ia64_set_dbr(index, val) \
- asm volatile ("mov dbr[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_set_ibr(index, val) \
- asm volatile ("mov ibr[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_set_pkr(index, val) \
- asm volatile ("mov pkr[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_set_pmc(index, val) \
- asm volatile ("mov pmc[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_set_pmd(index, val) \
- asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_set_rr(index, val) \
- asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
-
-#define ia64_get_cpuid(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index)); \
- ia64_intri_res; \
-})
-
-#define __ia64_get_dbr(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=dbr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-#define ia64_get_ibr(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=ibr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-#define ia64_get_pkr(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=pkr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-#define ia64_get_pmc(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=pmc[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-
-#define ia64_get_pmd(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-#define ia64_get_rr(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index)); \
- ia64_intri_res; \
-})
-
-#define ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
-
-
-#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
-
-#define ia64_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory")
-#define ia64_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory")
-#define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory")
-#define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory")
-
-#define ia64_ptce(addr) asm volatile ("ptc.e %0" :: "r"(addr))
-
-#define ia64_ptcga(addr, size) \
-do { \
- asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory"); \
- ia64_dv_serialize_data(); \
-} while (0)
-
-#define ia64_ptcl(addr, size) \
-do { \
- asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(size) : "memory"); \
- ia64_dv_serialize_data(); \
-} while (0)
-
-#define ia64_ptri(addr, size) \
- asm volatile ("ptr.i %0,%1" :: "r"(addr), "r"(size) : "memory")
-
-#define ia64_ptrd(addr, size) \
- asm volatile ("ptr.d %0,%1" :: "r"(addr), "r"(size) : "memory")
-
-#define ia64_ttag(addr) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("ttag %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
- ia64_intri_res; \
-})
-
-
-/* Values for lfhint in ia64_lfetch and ia64_lfetch_fault */
-
-#define ia64_lfhint_none 0
-#define ia64_lfhint_nt1 1
-#define ia64_lfhint_nt2 2
-#define ia64_lfhint_nta 3
-
-#define ia64_lfetch(lfhint, y) \
-({ \
- switch (lfhint) { \
- case ia64_lfhint_none: \
- asm volatile ("lfetch [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nt1: \
- asm volatile ("lfetch.nt1 [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nt2: \
- asm volatile ("lfetch.nt2 [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nta: \
- asm volatile ("lfetch.nta [%0]" : : "r"(y)); \
- break; \
- } \
-})
-
-#define ia64_lfetch_excl(lfhint, y) \
-({ \
- switch (lfhint) { \
- case ia64_lfhint_none: \
- asm volatile ("lfetch.excl [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nt1: \
- asm volatile ("lfetch.excl.nt1 [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nt2: \
- asm volatile ("lfetch.excl.nt2 [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nta: \
- asm volatile ("lfetch.excl.nta [%0]" :: "r"(y)); \
- break; \
- } \
-})
-
-#define ia64_lfetch_fault(lfhint, y) \
-({ \
- switch (lfhint) { \
- case ia64_lfhint_none: \
- asm volatile ("lfetch.fault [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nt1: \
- asm volatile ("lfetch.fault.nt1 [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nt2: \
- asm volatile ("lfetch.fault.nt2 [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nta: \
- asm volatile ("lfetch.fault.nta [%0]" : : "r"(y)); \
- break; \
- } \
-})
-
-#define ia64_lfetch_fault_excl(lfhint, y) \
-({ \
- switch (lfhint) { \
- case ia64_lfhint_none: \
- asm volatile ("lfetch.fault.excl [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nt1: \
- asm volatile ("lfetch.fault.excl.nt1 [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nt2: \
- asm volatile ("lfetch.fault.excl.nt2 [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nta: \
- asm volatile ("lfetch.fault.excl.nta [%0]" :: "r"(y)); \
- break; \
- } \
-})
-
-#define ia64_intrin_local_irq_restore(x) \
-do { \
- asm volatile (";; cmp.ne p6,p7=%0,r0;;" \
- "(p6) ssm psr.i;" \
- "(p7) rsm psr.i;;" \
- "(p6) srlz.d" \
- :: "r"((x)) : "p6", "p7", "memory"); \
-} while (0)
-
-#endif /* _UAPI_ASM_IA64_GCC_INTRIN_H */
diff --git a/arch/ia64/include/uapi/asm/ia64regs.h b/arch/ia64/include/uapi/asm/ia64regs.h
deleted file mode 100644
index d7d10cec8b9f..000000000000
--- a/arch/ia64/include/uapi/asm/ia64regs.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Copyright (C) 2002,2003 Intel Corp.
- * Jun Nakajima <jun.nakajima@intel.com>
- * Suresh Siddha <suresh.b.siddha@intel.com>
- */
-
-#ifndef _ASM_IA64_IA64REGS_H
-#define _ASM_IA64_IA64REGS_H
-
-/*
- * Register Names for getreg() and setreg().
- *
- * The "magic" numbers happen to match the values used by the Intel compiler's
- * getreg()/setreg() intrinsics.
- */
-
-/* Special Registers */
-
-#define _IA64_REG_IP 1016 /* getreg only */
-#define _IA64_REG_PSR 1019
-#define _IA64_REG_PSR_L 1019
-
-/* General Integer Registers */
-
-#define _IA64_REG_GP 1025 /* R1 */
-#define _IA64_REG_R8 1032 /* R8 */
-#define _IA64_REG_R9 1033 /* R9 */
-#define _IA64_REG_SP 1036 /* R12 */
-#define _IA64_REG_TP 1037 /* R13 */
-
-/* Application Registers */
-
-#define _IA64_REG_AR_KR0 3072
-#define _IA64_REG_AR_KR1 3073
-#define _IA64_REG_AR_KR2 3074
-#define _IA64_REG_AR_KR3 3075
-#define _IA64_REG_AR_KR4 3076
-#define _IA64_REG_AR_KR5 3077
-#define _IA64_REG_AR_KR6 3078
-#define _IA64_REG_AR_KR7 3079
-#define _IA64_REG_AR_RSC 3088
-#define _IA64_REG_AR_BSP 3089
-#define _IA64_REG_AR_BSPSTORE 3090
-#define _IA64_REG_AR_RNAT 3091
-#define _IA64_REG_AR_FCR 3093
-#define _IA64_REG_AR_EFLAG 3096
-#define _IA64_REG_AR_CSD 3097
-#define _IA64_REG_AR_SSD 3098
-#define _IA64_REG_AR_CFLAG 3099
-#define _IA64_REG_AR_FSR 3100
-#define _IA64_REG_AR_FIR 3101
-#define _IA64_REG_AR_FDR 3102
-#define _IA64_REG_AR_CCV 3104
-#define _IA64_REG_AR_UNAT 3108
-#define _IA64_REG_AR_FPSR 3112
-#define _IA64_REG_AR_ITC 3116
-#define _IA64_REG_AR_PFS 3136
-#define _IA64_REG_AR_LC 3137
-#define _IA64_REG_AR_EC 3138
-
-/* Control Registers */
-
-#define _IA64_REG_CR_DCR 4096
-#define _IA64_REG_CR_ITM 4097
-#define _IA64_REG_CR_IVA 4098
-#define _IA64_REG_CR_PTA 4104
-#define _IA64_REG_CR_IPSR 4112
-#define _IA64_REG_CR_ISR 4113
-#define _IA64_REG_CR_IIP 4115
-#define _IA64_REG_CR_IFA 4116
-#define _IA64_REG_CR_ITIR 4117
-#define _IA64_REG_CR_IIPA 4118
-#define _IA64_REG_CR_IFS 4119
-#define _IA64_REG_CR_IIM 4120
-#define _IA64_REG_CR_IHA 4121
-#define _IA64_REG_CR_LID 4160
-#define _IA64_REG_CR_IVR 4161 /* getreg only */
-#define _IA64_REG_CR_TPR 4162
-#define _IA64_REG_CR_EOI 4163
-#define _IA64_REG_CR_IRR0 4164 /* getreg only */
-#define _IA64_REG_CR_IRR1 4165 /* getreg only */
-#define _IA64_REG_CR_IRR2 4166 /* getreg only */
-#define _IA64_REG_CR_IRR3 4167 /* getreg only */
-#define _IA64_REG_CR_ITV 4168
-#define _IA64_REG_CR_PMV 4169
-#define _IA64_REG_CR_CMCV 4170
-#define _IA64_REG_CR_LRR0 4176
-#define _IA64_REG_CR_LRR1 4177
-
-/* Indirect Registers for getindreg() and setindreg() */
-
-#define _IA64_REG_INDR_CPUID 9000 /* getindreg only */
-#define _IA64_REG_INDR_DBR 9001
-#define _IA64_REG_INDR_IBR 9002
-#define _IA64_REG_INDR_PKR 9003
-#define _IA64_REG_INDR_PMC 9004
-#define _IA64_REG_INDR_PMD 9005
-#define _IA64_REG_INDR_RR 9006
-
-#endif /* _ASM_IA64_IA64REGS_H */
diff --git a/arch/ia64/include/uapi/asm/intrinsics.h b/arch/ia64/include/uapi/asm/intrinsics.h
deleted file mode 100644
index 63f27c4ec739..000000000000
--- a/arch/ia64/include/uapi/asm/intrinsics.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Compiler-dependent intrinsics.
- *
- * Copyright (C) 2002-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#ifndef _UAPI_ASM_IA64_INTRINSICS_H
-#define _UAPI_ASM_IA64_INTRINSICS_H
-
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-/* include compiler specific intrinsics */
-#include <asm/ia64regs.h>
-#include <asm/gcc_intrin.h>
-#include <asm/cmpxchg.h>
-
-#define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \
-do { \
- ia64_set_rr(0x0000000000000000UL, (val0)); \
- ia64_set_rr(0x2000000000000000UL, (val1)); \
- ia64_set_rr(0x4000000000000000UL, (val2)); \
- ia64_set_rr(0x6000000000000000UL, (val3)); \
- ia64_set_rr(0x8000000000000000UL, (val4)); \
-} while (0)
-
-/*
- * Force an unresolved reference if someone tries to use
- * ia64_fetch_and_add() with a bad value.
- */
-extern unsigned long __bad_size_for_ia64_fetch_and_add (void);
-extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
-
-#define IA64_FETCHADD(tmp,v,n,sz,sem) \
-({ \
- switch (sz) { \
- case 4: \
- tmp = ia64_fetchadd4_##sem((unsigned int *) v, n); \
- break; \
- \
- case 8: \
- tmp = ia64_fetchadd8_##sem((unsigned long *) v, n); \
- break; \
- \
- default: \
- __bad_size_for_ia64_fetch_and_add(); \
- } \
-})
-
-#define ia64_fetchadd(i,v,sem) \
-({ \
- __u64 _tmp; \
- volatile __typeof__(*(v)) *_v = (v); \
- /* Can't use a switch () here: gcc isn't always smart enough for that... */ \
- if ((i) == -16) \
- IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v)), sem); \
- else if ((i) == -8) \
- IA64_FETCHADD(_tmp, _v, -8, sizeof(*(v)), sem); \
- else if ((i) == -4) \
- IA64_FETCHADD(_tmp, _v, -4, sizeof(*(v)), sem); \
- else if ((i) == -1) \
- IA64_FETCHADD(_tmp, _v, -1, sizeof(*(v)), sem); \
- else if ((i) == 1) \
- IA64_FETCHADD(_tmp, _v, 1, sizeof(*(v)), sem); \
- else if ((i) == 4) \
- IA64_FETCHADD(_tmp, _v, 4, sizeof(*(v)), sem); \
- else if ((i) == 8) \
- IA64_FETCHADD(_tmp, _v, 8, sizeof(*(v)), sem); \
- else if ((i) == 16) \
- IA64_FETCHADD(_tmp, _v, 16, sizeof(*(v)), sem); \
- else \
- _tmp = __bad_increment_for_ia64_fetch_and_add(); \
- (__typeof__(*(v))) (_tmp); /* return old value */ \
-})
-
-#define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */
-
-#endif
-
-#endif /* _UAPI_ASM_IA64_INTRINSICS_H */
diff --git a/arch/ia64/include/uapi/asm/mman.h b/arch/ia64/include/uapi/asm/mman.h
deleted file mode 100644
index ce0cc3d7509e..000000000000
--- a/arch/ia64/include/uapi/asm/mman.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Based on <asm-i386/mman.h>.
- *
- * Modified 1998-2000, 2002
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-#ifndef _UAPI_ASM_IA64_MMAN_H
-#define _UAPI_ASM_IA64_MMAN_H
-
-
-#include <asm-generic/mman.h>
-
-#define MAP_GROWSUP 0x0200 /* register stack-like segment */
-
-
-#endif /* _UAPI_ASM_IA64_MMAN_H */
diff --git a/arch/ia64/include/uapi/asm/param.h b/arch/ia64/include/uapi/asm/param.h
deleted file mode 100644
index 123ab45940b4..000000000000
--- a/arch/ia64/include/uapi/asm/param.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Fundamental kernel parameters.
- *
- * Based on <asm-i386/param.h>.
- *
- * Modified 1998, 1999, 2002-2003
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-#ifndef _UAPI_ASM_IA64_PARAM_H
-#define _UAPI_ASM_IA64_PARAM_H
-
-
-#define EXEC_PAGESIZE 65536
-
-#ifndef NOGROUP
-# define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#ifndef __KERNEL__
- /*
- * Technically, this is wrong, but some old apps still refer to it. The proper way to
- * get the HZ value is via sysconf(_SC_CLK_TCK).
- */
-# define HZ 1024
-#endif
-
-#endif /* _UAPI_ASM_IA64_PARAM_H */
diff --git a/arch/ia64/include/uapi/asm/posix_types.h b/arch/ia64/include/uapi/asm/posix_types.h
deleted file mode 100644
index bded40f7defe..000000000000
--- a/arch/ia64/include/uapi/asm/posix_types.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_POSIX_TYPES_H
-#define _ASM_IA64_POSIX_TYPES_H
-
-typedef unsigned long __kernel_sigset_t; /* at least 32 bits */
-
-#include <asm-generic/posix_types.h>
-
-#endif /* _ASM_IA64_POSIX_TYPES_H */
diff --git a/arch/ia64/include/uapi/asm/ptrace.h b/arch/ia64/include/uapi/asm/ptrace.h
deleted file mode 100644
index f52655b44414..000000000000
--- a/arch/ia64/include/uapi/asm/ptrace.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Copyright (C) 1998-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 2003 Intel Co
- * Suresh Siddha <suresh.b.siddha@intel.com>
- * Fenghua Yu <fenghua.yu@intel.com>
- * Arun Sharma <arun.sharma@intel.com>
- *
- * 12/07/98 S. Eranian added pt_regs & switch_stack
- * 12/21/98 D. Mosberger updated to match latest code
- * 6/17/99 D. Mosberger added second unat member to "struct switch_stack"
- *
- */
-#ifndef _UAPI_ASM_IA64_PTRACE_H
-#define _UAPI_ASM_IA64_PTRACE_H
-
-/*
- * When a user process is blocked, its state looks as follows:
- *
- * +----------------------+ ------- IA64_STK_OFFSET
- * | | ^
- * | struct pt_regs | |
- * | | |
- * +----------------------+ |
- * | | |
- * | memory stack | |
- * | (growing downwards) | |
- * //.....................// |
- * |
- * //.....................// |
- * | | |
- * +----------------------+ |
- * | struct switch_stack | |
- * | | |
- * +----------------------+ |
- * | | |
- * //.....................// |
- * |
- * //.....................// |
- * | | |
- * | register stack | |
- * | (growing upwards) | |
- * | | |
- * +----------------------+ | --- IA64_RBS_OFFSET
- * | struct thread_info | | ^
- * +----------------------+ | |
- * | | | |
- * | struct task_struct | | |
- * current -> | | | |
- * +----------------------+ -------
- *
- * Note that ar.ec is not saved explicitly in pt_reg or switch_stack.
- * This is because ar.ec is saved as part of ar.pfs.
- */
-
-
-#include <asm/fpu.h>
-
-
-#ifndef __ASSEMBLY__
-
-/*
- * This struct defines the way the registers are saved on system
- * calls.
- *
- * We don't save all floating point register because the kernel
- * is compiled to use only a very small subset, so the other are
- * untouched.
- *
- * THIS STRUCTURE MUST BE A MULTIPLE 16-BYTE IN SIZE
- * (because the memory stack pointer MUST ALWAYS be aligned this way)
- *
- */
-struct pt_regs {
- /* The following registers are saved by SAVE_MIN: */
- unsigned long b6; /* scratch */
- unsigned long b7; /* scratch */
-
- unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */
- unsigned long ar_ssd; /* reserved for future use (scratch) */
-
- unsigned long r8; /* scratch (return value register 0) */
- unsigned long r9; /* scratch (return value register 1) */
- unsigned long r10; /* scratch (return value register 2) */
- unsigned long r11; /* scratch (return value register 3) */
-
- unsigned long cr_ipsr; /* interrupted task's psr */
- unsigned long cr_iip; /* interrupted task's instruction pointer */
- /*
- * interrupted task's function state; if bit 63 is cleared, it
- * contains syscall's ar.pfs.pfm:
- */
- unsigned long cr_ifs;
-
- unsigned long ar_unat; /* interrupted task's NaT register (preserved) */
- unsigned long ar_pfs; /* prev function state */
- unsigned long ar_rsc; /* RSE configuration */
- /* The following two are valid only if cr_ipsr.cpl > 0 || ti->flags & _TIF_MCA_INIT */
- unsigned long ar_rnat; /* RSE NaT */
- unsigned long ar_bspstore; /* RSE bspstore */
-
- unsigned long pr; /* 64 predicate registers (1 bit each) */
- unsigned long b0; /* return pointer (bp) */
- unsigned long loadrs; /* size of dirty partition << 16 */
-
- unsigned long r1; /* the gp pointer */
- unsigned long r12; /* interrupted task's memory stack pointer */
- unsigned long r13; /* thread pointer */
-
- unsigned long ar_fpsr; /* floating point status (preserved) */
- unsigned long r15; /* scratch */
-
- /* The remaining registers are NOT saved for system calls. */
-
- unsigned long r14; /* scratch */
- unsigned long r2; /* scratch */
- unsigned long r3; /* scratch */
-
- /* The following registers are saved by SAVE_REST: */
- unsigned long r16; /* scratch */
- unsigned long r17; /* scratch */
- unsigned long r18; /* scratch */
- unsigned long r19; /* scratch */
- unsigned long r20; /* scratch */
- unsigned long r21; /* scratch */
- unsigned long r22; /* scratch */
- unsigned long r23; /* scratch */
- unsigned long r24; /* scratch */
- unsigned long r25; /* scratch */
- unsigned long r26; /* scratch */
- unsigned long r27; /* scratch */
- unsigned long r28; /* scratch */
- unsigned long r29; /* scratch */
- unsigned long r30; /* scratch */
- unsigned long r31; /* scratch */
-
- unsigned long ar_ccv; /* compare/exchange value (scratch) */
-
- /*
- * Floating point registers that the kernel considers scratch:
- */
- struct ia64_fpreg f6; /* scratch */
- struct ia64_fpreg f7; /* scratch */
- struct ia64_fpreg f8; /* scratch */
- struct ia64_fpreg f9; /* scratch */
- struct ia64_fpreg f10; /* scratch */
- struct ia64_fpreg f11; /* scratch */
-};
-
-/*
- * This structure contains the addition registers that need to
- * preserved across a context switch. This generally consists of
- * "preserved" registers.
- */
-struct switch_stack {
- unsigned long caller_unat; /* user NaT collection register (preserved) */
- unsigned long ar_fpsr; /* floating-point status register */
-
- struct ia64_fpreg f2; /* preserved */
- struct ia64_fpreg f3; /* preserved */
- struct ia64_fpreg f4; /* preserved */
- struct ia64_fpreg f5; /* preserved */
-
- struct ia64_fpreg f12; /* scratch, but untouched by kernel */
- struct ia64_fpreg f13; /* scratch, but untouched by kernel */
- struct ia64_fpreg f14; /* scratch, but untouched by kernel */
- struct ia64_fpreg f15; /* scratch, but untouched by kernel */
- struct ia64_fpreg f16; /* preserved */
- struct ia64_fpreg f17; /* preserved */
- struct ia64_fpreg f18; /* preserved */
- struct ia64_fpreg f19; /* preserved */
- struct ia64_fpreg f20; /* preserved */
- struct ia64_fpreg f21; /* preserved */
- struct ia64_fpreg f22; /* preserved */
- struct ia64_fpreg f23; /* preserved */
- struct ia64_fpreg f24; /* preserved */
- struct ia64_fpreg f25; /* preserved */
- struct ia64_fpreg f26; /* preserved */
- struct ia64_fpreg f27; /* preserved */
- struct ia64_fpreg f28; /* preserved */
- struct ia64_fpreg f29; /* preserved */
- struct ia64_fpreg f30; /* preserved */
- struct ia64_fpreg f31; /* preserved */
-
- unsigned long r4; /* preserved */
- unsigned long r5; /* preserved */
- unsigned long r6; /* preserved */
- unsigned long r7; /* preserved */
-
- unsigned long b0; /* so we can force a direct return in copy_thread */
- unsigned long b1;
- unsigned long b2;
- unsigned long b3;
- unsigned long b4;
- unsigned long b5;
-
- unsigned long ar_pfs; /* previous function state */
- unsigned long ar_lc; /* loop counter (preserved) */
- unsigned long ar_unat; /* NaT bits for r4-r7 */
- unsigned long ar_rnat; /* RSE NaT collection register */
- unsigned long ar_bspstore; /* RSE dirty base (preserved) */
- unsigned long pr; /* 64 predicate registers (1 bit each) */
-};
-
-
-/* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
-struct pt_all_user_regs {
- unsigned long nat;
- unsigned long cr_iip;
- unsigned long cfm;
- unsigned long cr_ipsr;
- unsigned long pr;
-
- unsigned long gr[32];
- unsigned long br[8];
- unsigned long ar[128];
- struct ia64_fpreg fr[128];
-};
-
-#endif /* !__ASSEMBLY__ */
-
-/* indices to application-registers array in pt_all_user_regs */
-#define PT_AUR_RSC 16
-#define PT_AUR_BSP 17
-#define PT_AUR_BSPSTORE 18
-#define PT_AUR_RNAT 19
-#define PT_AUR_CCV 32
-#define PT_AUR_UNAT 36
-#define PT_AUR_FPSR 40
-#define PT_AUR_PFS 64
-#define PT_AUR_LC 65
-#define PT_AUR_EC 66
-
-/*
- * The numbers chosen here are somewhat arbitrary but absolutely MUST
- * not overlap with any of the number assigned in <linux/ptrace.h>.
- */
-#define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */
-#define PTRACE_OLD_GETSIGINFO 13 /* (replaced by PTRACE_GETSIGINFO in <linux/ptrace.h>) */
-#define PTRACE_OLD_SETSIGINFO 14 /* (replaced by PTRACE_SETSIGINFO in <linux/ptrace.h>) */
-#define PTRACE_GETREGS 18 /* get all registers (pt_all_user_regs) in one shot */
-#define PTRACE_SETREGS 19 /* set all registers (pt_all_user_regs) in one shot */
-
-#define PTRACE_OLDSETOPTIONS 21
-
-#endif /* _UAPI_ASM_IA64_PTRACE_H */
diff --git a/arch/ia64/include/uapi/asm/ptrace_offsets.h b/arch/ia64/include/uapi/asm/ptrace_offsets.h
deleted file mode 100644
index 2847c18139ef..000000000000
--- a/arch/ia64/include/uapi/asm/ptrace_offsets.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_PTRACE_OFFSETS_H
-#define _ASM_IA64_PTRACE_OFFSETS_H
-
-/*
- * Copyright (C) 1999, 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-/*
- * The "uarea" that can be accessed via PEEKUSER and POKEUSER is a
- * virtual structure that would have the following definition:
- *
- * struct uarea {
- * struct ia64_fpreg fph[96]; // f32-f127
- * unsigned long nat_bits;
- * unsigned long empty1;
- * struct ia64_fpreg f2; // f2-f5
- * :
- * struct ia64_fpreg f5;
- * struct ia64_fpreg f10; // f10-f31
- * :
- * struct ia64_fpreg f31;
- * unsigned long r4; // r4-r7
- * :
- * unsigned long r7;
- * unsigned long b1; // b1-b5
- * :
- * unsigned long b5;
- * unsigned long ar_ec;
- * unsigned long ar_lc;
- * unsigned long empty2[5];
- * unsigned long cr_ipsr;
- * unsigned long cr_iip;
- * unsigned long cfm;
- * unsigned long ar_unat;
- * unsigned long ar_pfs;
- * unsigned long ar_rsc;
- * unsigned long ar_rnat;
- * unsigned long ar_bspstore;
- * unsigned long pr;
- * unsigned long b6;
- * unsigned long ar_bsp;
- * unsigned long r1;
- * unsigned long r2;
- * unsigned long r3;
- * unsigned long r12;
- * unsigned long r13;
- * unsigned long r14;
- * unsigned long r15;
- * unsigned long r8;
- * unsigned long r9;
- * unsigned long r10;
- * unsigned long r11;
- * unsigned long r16;
- * :
- * unsigned long r31;
- * unsigned long ar_ccv;
- * unsigned long ar_fpsr;
- * unsigned long b0;
- * unsigned long b7;
- * unsigned long f6;
- * unsigned long f7;
- * unsigned long f8;
- * unsigned long f9;
- * unsigned long ar_csd;
- * unsigned long ar_ssd;
- * unsigned long rsvd1[710];
- * unsigned long dbr[8];
- * unsigned long rsvd2[504];
- * unsigned long ibr[8];
- * unsigned long rsvd3[504];
- * unsigned long pmd[4];
- * }
- */
-
-/* fph: */
-#define PT_F32 0x0000
-#define PT_F33 0x0010
-#define PT_F34 0x0020
-#define PT_F35 0x0030
-#define PT_F36 0x0040
-#define PT_F37 0x0050
-#define PT_F38 0x0060
-#define PT_F39 0x0070
-#define PT_F40 0x0080
-#define PT_F41 0x0090
-#define PT_F42 0x00a0
-#define PT_F43 0x00b0
-#define PT_F44 0x00c0
-#define PT_F45 0x00d0
-#define PT_F46 0x00e0
-#define PT_F47 0x00f0
-#define PT_F48 0x0100
-#define PT_F49 0x0110
-#define PT_F50 0x0120
-#define PT_F51 0x0130
-#define PT_F52 0x0140
-#define PT_F53 0x0150
-#define PT_F54 0x0160
-#define PT_F55 0x0170
-#define PT_F56 0x0180
-#define PT_F57 0x0190
-#define PT_F58 0x01a0
-#define PT_F59 0x01b0
-#define PT_F60 0x01c0
-#define PT_F61 0x01d0
-#define PT_F62 0x01e0
-#define PT_F63 0x01f0
-#define PT_F64 0x0200
-#define PT_F65 0x0210
-#define PT_F66 0x0220
-#define PT_F67 0x0230
-#define PT_F68 0x0240
-#define PT_F69 0x0250
-#define PT_F70 0x0260
-#define PT_F71 0x0270
-#define PT_F72 0x0280
-#define PT_F73 0x0290
-#define PT_F74 0x02a0
-#define PT_F75 0x02b0
-#define PT_F76 0x02c0
-#define PT_F77 0x02d0
-#define PT_F78 0x02e0
-#define PT_F79 0x02f0
-#define PT_F80 0x0300
-#define PT_F81 0x0310
-#define PT_F82 0x0320
-#define PT_F83 0x0330
-#define PT_F84 0x0340
-#define PT_F85 0x0350
-#define PT_F86 0x0360
-#define PT_F87 0x0370
-#define PT_F88 0x0380
-#define PT_F89 0x0390
-#define PT_F90 0x03a0
-#define PT_F91 0x03b0
-#define PT_F92 0x03c0
-#define PT_F93 0x03d0
-#define PT_F94 0x03e0
-#define PT_F95 0x03f0
-#define PT_F96 0x0400
-#define PT_F97 0x0410
-#define PT_F98 0x0420
-#define PT_F99 0x0430
-#define PT_F100 0x0440
-#define PT_F101 0x0450
-#define PT_F102 0x0460
-#define PT_F103 0x0470
-#define PT_F104 0x0480
-#define PT_F105 0x0490
-#define PT_F106 0x04a0
-#define PT_F107 0x04b0
-#define PT_F108 0x04c0
-#define PT_F109 0x04d0
-#define PT_F110 0x04e0
-#define PT_F111 0x04f0
-#define PT_F112 0x0500
-#define PT_F113 0x0510
-#define PT_F114 0x0520
-#define PT_F115 0x0530
-#define PT_F116 0x0540
-#define PT_F117 0x0550
-#define PT_F118 0x0560
-#define PT_F119 0x0570
-#define PT_F120 0x0580
-#define PT_F121 0x0590
-#define PT_F122 0x05a0
-#define PT_F123 0x05b0
-#define PT_F124 0x05c0
-#define PT_F125 0x05d0
-#define PT_F126 0x05e0
-#define PT_F127 0x05f0
-
-#define PT_NAT_BITS 0x0600
-
-#define PT_F2 0x0610
-#define PT_F3 0x0620
-#define PT_F4 0x0630
-#define PT_F5 0x0640
-#define PT_F10 0x0650
-#define PT_F11 0x0660
-#define PT_F12 0x0670
-#define PT_F13 0x0680
-#define PT_F14 0x0690
-#define PT_F15 0x06a0
-#define PT_F16 0x06b0
-#define PT_F17 0x06c0
-#define PT_F18 0x06d0
-#define PT_F19 0x06e0
-#define PT_F20 0x06f0
-#define PT_F21 0x0700
-#define PT_F22 0x0710
-#define PT_F23 0x0720
-#define PT_F24 0x0730
-#define PT_F25 0x0740
-#define PT_F26 0x0750
-#define PT_F27 0x0760
-#define PT_F28 0x0770
-#define PT_F29 0x0780
-#define PT_F30 0x0790
-#define PT_F31 0x07a0
-#define PT_R4 0x07b0
-#define PT_R5 0x07b8
-#define PT_R6 0x07c0
-#define PT_R7 0x07c8
-
-#define PT_B1 0x07d8
-#define PT_B2 0x07e0
-#define PT_B3 0x07e8
-#define PT_B4 0x07f0
-#define PT_B5 0x07f8
-
-#define PT_AR_EC 0x0800
-#define PT_AR_LC 0x0808
-
-#define PT_CR_IPSR 0x0830
-#define PT_CR_IIP 0x0838
-#define PT_CFM 0x0840
-#define PT_AR_UNAT 0x0848
-#define PT_AR_PFS 0x0850
-#define PT_AR_RSC 0x0858
-#define PT_AR_RNAT 0x0860
-#define PT_AR_BSPSTORE 0x0868
-#define PT_PR 0x0870
-#define PT_B6 0x0878
-#define PT_AR_BSP 0x0880 /* note: this points to the *end* of the backing store! */
-#define PT_R1 0x0888
-#define PT_R2 0x0890
-#define PT_R3 0x0898
-#define PT_R12 0x08a0
-#define PT_R13 0x08a8
-#define PT_R14 0x08b0
-#define PT_R15 0x08b8
-#define PT_R8 0x08c0
-#define PT_R9 0x08c8
-#define PT_R10 0x08d0
-#define PT_R11 0x08d8
-#define PT_R16 0x08e0
-#define PT_R17 0x08e8
-#define PT_R18 0x08f0
-#define PT_R19 0x08f8
-#define PT_R20 0x0900
-#define PT_R21 0x0908
-#define PT_R22 0x0910
-#define PT_R23 0x0918
-#define PT_R24 0x0920
-#define PT_R25 0x0928
-#define PT_R26 0x0930
-#define PT_R27 0x0938
-#define PT_R28 0x0940
-#define PT_R29 0x0948
-#define PT_R30 0x0950
-#define PT_R31 0x0958
-#define PT_AR_CCV 0x0960
-#define PT_AR_FPSR 0x0968
-#define PT_B0 0x0970
-#define PT_B7 0x0978
-#define PT_F6 0x0980
-#define PT_F7 0x0990
-#define PT_F8 0x09a0
-#define PT_F9 0x09b0
-#define PT_AR_CSD 0x09c0
-#define PT_AR_SSD 0x09c8
-
-#define PT_DBR 0x2000 /* data breakpoint registers */
-#define PT_IBR 0x3000 /* instruction breakpoint registers */
-#define PT_PMD 0x4000 /* performance monitoring counters */
-
-#endif /* _ASM_IA64_PTRACE_OFFSETS_H */
diff --git a/arch/ia64/include/uapi/asm/resource.h b/arch/ia64/include/uapi/asm/resource.h
deleted file mode 100644
index d488d2b22ac4..000000000000
--- a/arch/ia64/include/uapi/asm/resource.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_RESOURCE_H
-#define _ASM_IA64_RESOURCE_H
-
-#include <asm/ustack.h>
-#include <asm-generic/resource.h>
-
-#endif /* _ASM_IA64_RESOURCE_H */
diff --git a/arch/ia64/include/uapi/asm/rse.h b/arch/ia64/include/uapi/asm/rse.h
deleted file mode 100644
index 6d260af571c5..000000000000
--- a/arch/ia64/include/uapi/asm/rse.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_RSE_H
-#define _ASM_IA64_RSE_H
-
-/*
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Register stack engine related helper functions. This file may be
- * used in applications, so be careful about the name-space and give
- * some consideration to non-GNU C compilers (though __inline__ is
- * fine).
- */
-
-static __inline__ unsigned long
-ia64_rse_slot_num (unsigned long *addr)
-{
- return (((unsigned long) addr) >> 3) & 0x3f;
-}
-
-/*
- * Return TRUE if ADDR is the address of an RNAT slot.
- */
-static __inline__ unsigned long
-ia64_rse_is_rnat_slot (unsigned long *addr)
-{
- return ia64_rse_slot_num(addr) == 0x3f;
-}
-
-/*
- * Returns the address of the RNAT slot that covers the slot at
- * address SLOT_ADDR.
- */
-static __inline__ unsigned long *
-ia64_rse_rnat_addr (unsigned long *slot_addr)
-{
- return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
-}
-
-/*
- * Calculate the number of registers in the dirty partition starting at BSPSTORE and
- * ending at BSP. This isn't simply (BSP-BSPSTORE)/8 because every 64th slot stores
- * ar.rnat.
- */
-static __inline__ unsigned long
-ia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp)
-{
- unsigned long slots = (bsp - bspstore);
-
- return slots - (ia64_rse_slot_num(bspstore) + slots)/0x40;
-}
-
-/*
- * The inverse of the above: given bspstore and the number of
- * registers, calculate ar.bsp.
- */
-static __inline__ unsigned long *
-ia64_rse_skip_regs (unsigned long *addr, long num_regs)
-{
- long delta = ia64_rse_slot_num(addr) + num_regs;
-
- if (num_regs < 0)
- delta -= 0x3e;
- return addr + num_regs + delta/0x3f;
-}
-
-#endif /* _ASM_IA64_RSE_H */
diff --git a/arch/ia64/include/uapi/asm/setup.h b/arch/ia64/include/uapi/asm/setup.h
deleted file mode 100644
index 8d13ce8fb03a..000000000000
--- a/arch/ia64/include/uapi/asm/setup.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef __IA64_SETUP_H
-#define __IA64_SETUP_H
-
-#define COMMAND_LINE_SIZE 2048
-
-extern struct ia64_boot_param {
- __u64 command_line; /* physical address of command line arguments */
- __u64 efi_systab; /* physical address of EFI system table */
- __u64 efi_memmap; /* physical address of EFI memory map */
- __u64 efi_memmap_size; /* size of EFI memory map */
- __u64 efi_memdesc_size; /* size of an EFI memory map descriptor */
- __u32 efi_memdesc_version; /* memory descriptor version */
- struct {
- __u16 num_cols; /* number of columns on console output device */
- __u16 num_rows; /* number of rows on console output device */
- __u16 orig_x; /* cursor's x position */
- __u16 orig_y; /* cursor's y position */
- } console_info;
- __u64 fpswa; /* physical address of the fpswa interface */
- __u64 initrd_start;
- __u64 initrd_size;
-} *ia64_boot_param;
-
-#endif
diff --git a/arch/ia64/include/uapi/asm/sigcontext.h b/arch/ia64/include/uapi/asm/sigcontext.h
deleted file mode 100644
index 1bb6f0f2bd73..000000000000
--- a/arch/ia64/include/uapi/asm/sigcontext.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_SIGCONTEXT_H
-#define _ASM_IA64_SIGCONTEXT_H
-
-/*
- * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1998, 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <asm/fpu.h>
-
-#define IA64_SC_FLAG_ONSTACK_BIT 0 /* is handler running on signal stack? */
-#define IA64_SC_FLAG_IN_SYSCALL_BIT 1 /* did signal interrupt a syscall? */
-#define IA64_SC_FLAG_FPH_VALID_BIT 2 /* is state in f[32]-f[127] valid? */
-
-#define IA64_SC_FLAG_ONSTACK (1 << IA64_SC_FLAG_ONSTACK_BIT)
-#define IA64_SC_FLAG_IN_SYSCALL (1 << IA64_SC_FLAG_IN_SYSCALL_BIT)
-#define IA64_SC_FLAG_FPH_VALID (1 << IA64_SC_FLAG_FPH_VALID_BIT)
-
-# ifndef __ASSEMBLY__
-
-/*
- * Note on handling of register backing store: sc_ar_bsp contains the address that would
- * be found in ar.bsp after executing a "cover" instruction the context in which the
- * signal was raised. If signal delivery required switching to an alternate signal stack
- * (sc_rbs_base is not NULL), the "dirty" partition (as it would exist after executing the
- * imaginary "cover" instruction) is backed by the *alternate* signal stack, not the
- * original one. In this case, sc_rbs_base contains the base address of the new register
- * backing store. The number of registers in the dirty partition can be calculated as:
- *
- * ndirty = ia64_rse_num_regs(sc_rbs_base, sc_rbs_base + (sc_loadrs >> 16))
- *
- */
-
-struct sigcontext {
- unsigned long sc_flags; /* see manifest constants above */
- unsigned long sc_nat; /* bit i == 1 iff scratch reg gr[i] is a NaT */
- stack_t sc_stack; /* previously active stack */
-
- unsigned long sc_ip; /* instruction pointer */
- unsigned long sc_cfm; /* current frame marker */
- unsigned long sc_um; /* user mask bits */
- unsigned long sc_ar_rsc; /* register stack configuration register */
- unsigned long sc_ar_bsp; /* backing store pointer */
- unsigned long sc_ar_rnat; /* RSE NaT collection register */
- unsigned long sc_ar_ccv; /* compare and exchange compare value register */
- unsigned long sc_ar_unat; /* ar.unat of interrupted context */
- unsigned long sc_ar_fpsr; /* floating-point status register */
- unsigned long sc_ar_pfs; /* previous function state */
- unsigned long sc_ar_lc; /* loop count register */
- unsigned long sc_pr; /* predicate registers */
- unsigned long sc_br[8]; /* branch registers */
- /* Note: sc_gr[0] is used as the "uc_link" member of ucontext_t */
- unsigned long sc_gr[32]; /* general registers (static partition) */
- struct ia64_fpreg sc_fr[128]; /* floating-point registers */
-
- unsigned long sc_rbs_base; /* NULL or new base of sighandler's rbs */
- unsigned long sc_loadrs; /* see description above */
-
- unsigned long sc_ar25; /* cmp8xchg16 uses this */
- unsigned long sc_ar26; /* rsvd for scratch use */
- unsigned long sc_rsvd[12]; /* reserved for future use */
- /*
- * The mask must come last so we can increase _NSIG_WORDS
- * without breaking binary compatibility.
- */
- sigset_t sc_mask; /* signal mask to restore after handler returns */
-};
-
-# endif /* __ASSEMBLY__ */
-#endif /* _ASM_IA64_SIGCONTEXT_H */
diff --git a/arch/ia64/include/uapi/asm/siginfo.h b/arch/ia64/include/uapi/asm/siginfo.h
deleted file mode 100644
index 796af1ccaa7e..000000000000
--- a/arch/ia64/include/uapi/asm/siginfo.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Based on <asm-i386/siginfo.h>.
- *
- * Modified 1998-2002
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-#ifndef _UAPI_ASM_IA64_SIGINFO_H
-#define _UAPI_ASM_IA64_SIGINFO_H
-
-
-#include <asm-generic/siginfo.h>
-
-#define si_imm _sifields._sigfault._imm /* as per UNIX SysV ABI spec */
-#define si_flags _sifields._sigfault._flags
-/*
- * si_isr is valid for SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP provided that
- * si_code is non-zero and __ISR_VALID is set in si_flags.
- */
-#define si_isr _sifields._sigfault._isr
-
-/*
- * Flag values for si_flags:
- */
-#define __ISR_VALID_BIT 0
-#define __ISR_VALID (1 << __ISR_VALID_BIT)
-
-#endif /* _UAPI_ASM_IA64_SIGINFO_H */
diff --git a/arch/ia64/include/uapi/asm/signal.h b/arch/ia64/include/uapi/asm/signal.h
deleted file mode 100644
index 63d574e802a2..000000000000
--- a/arch/ia64/include/uapi/asm/signal.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Modified 1998-2001, 2003
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- *
- * Unfortunately, this file is being included by bits/signal.h in
- * glibc-2.x. Hence the #ifdef __KERNEL__ ugliness.
- */
-#ifndef _UAPI_ASM_IA64_SIGNAL_H
-#define _UAPI_ASM_IA64_SIGNAL_H
-
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-/* signal 31 is no longer "unused", but the SIGUNUSED macro remains for backwards compatibility */
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-#define SA_RESTORER 0x04000000
-
-/*
- * The minimum stack size needs to be fairly large because we want to
- * be sure that an app compiled for today's CPUs will continue to run
- * on all future CPU models. The CPU model matters because the signal
- * frame needs to have space for the complete machine state, including
- * all physical stacked registers. The number of physical stacked
- * registers is CPU model dependent, but given that the width of
- * ar.rsc.loadrs is 14 bits, we can assume that they'll never take up
- * more than 16KB of space.
- */
-#if 1
- /*
- * This is a stupid typo: the value was _meant_ to be 131072 (0x20000), but I typed it
- * in wrong. ;-( To preserve backwards compatibility, we leave the kernel at the
- * incorrect value and fix libc only.
- */
-# define MINSIGSTKSZ 131027 /* min. stack size for sigaltstack() */
-#else
-# define MINSIGSTKSZ 131072 /* min. stack size for sigaltstack() */
-#endif
-#define SIGSTKSZ 262144 /* default stack size for sigaltstack() */
-
-
-#include <asm-generic/signal-defs.h>
-
-# ifndef __ASSEMBLY__
-
-# include <linux/types.h>
-
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- __kernel_size_t ss_size;
-} stack_t;
-
-
-# endif /* !__ASSEMBLY__ */
-#endif /* _UAPI_ASM_IA64_SIGNAL_H */
diff --git a/arch/ia64/include/uapi/asm/stat.h b/arch/ia64/include/uapi/asm/stat.h
deleted file mode 100644
index 3265ed5aac0f..000000000000
--- a/arch/ia64/include/uapi/asm/stat.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_STAT_H
-#define _ASM_IA64_STAT_H
-
-/*
- * Modified 1998, 1999
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-struct stat {
- unsigned long st_dev;
- unsigned long st_ino;
- unsigned long st_nlink;
- unsigned int st_mode;
- unsigned int st_uid;
- unsigned int st_gid;
- unsigned int __pad0;
- unsigned long st_rdev;
- unsigned long st_size;
- unsigned long st_atime;
- unsigned long st_atime_nsec;
- unsigned long st_mtime;
- unsigned long st_mtime_nsec;
- unsigned long st_ctime;
- unsigned long st_ctime_nsec;
- unsigned long st_blksize;
- long st_blocks;
- unsigned long __unused[3];
-};
-
-#define STAT_HAVE_NSEC 1
-
-struct ia64_oldstat {
- unsigned int st_dev;
- unsigned int st_ino;
- unsigned int st_mode;
- unsigned int st_nlink;
- unsigned int st_uid;
- unsigned int st_gid;
- unsigned int st_rdev;
- unsigned int __pad1;
- unsigned long st_size;
- unsigned long st_atime;
- unsigned long st_mtime;
- unsigned long st_ctime;
- unsigned int st_blksize;
- int st_blocks;
- unsigned int __unused1;
- unsigned int __unused2;
-};
-
-#endif /* _ASM_IA64_STAT_H */
diff --git a/arch/ia64/include/uapi/asm/statfs.h b/arch/ia64/include/uapi/asm/statfs.h
deleted file mode 100644
index de3bae4f137d..000000000000
--- a/arch/ia64/include/uapi/asm/statfs.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_STATFS_H
-#define _ASM_IA64_STATFS_H
-
-/*
- * Based on <asm-i386/statfs.h>.
- *
- * Modified 1998, 1999, 2003
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-/*
- * We need compat_statfs64 to be packed, because the i386 ABI won't
- * add padding at the end to bring it to a multiple of 8 bytes, but
- * the IA64 ABI will.
- */
-#define ARCH_PACK_COMPAT_STATFS64 __attribute__((packed,aligned(4)))
-
-#include <asm-generic/statfs.h>
-
-#endif /* _ASM_IA64_STATFS_H */
diff --git a/arch/ia64/include/uapi/asm/swab.h b/arch/ia64/include/uapi/asm/swab.h
deleted file mode 100644
index 79f3fef1a05e..000000000000
--- a/arch/ia64/include/uapi/asm/swab.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_SWAB_H
-#define _ASM_IA64_SWAB_H
-
-/*
- * Modified 1998, 1999
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co.
- */
-
-#include <linux/types.h>
-#include <asm/intrinsics.h>
-#include <linux/compiler.h>
-
-static __inline__ __attribute_const__ __u64 __arch_swab64(__u64 x)
-{
- __u64 result;
-
- result = ia64_mux1(x, ia64_mux1_rev);
- return result;
-}
-#define __arch_swab64 __arch_swab64
-
-static __inline__ __attribute_const__ __u32 __arch_swab32(__u32 x)
-{
- return __arch_swab64(x) >> 32;
-}
-#define __arch_swab32 __arch_swab32
-
-static __inline__ __attribute_const__ __u16 __arch_swab16(__u16 x)
-{
- return __arch_swab64(x) >> 48;
-}
-#define __arch_swab16 __arch_swab16
-
-#endif /* _ASM_IA64_SWAB_H */
diff --git a/arch/ia64/include/uapi/asm/types.h b/arch/ia64/include/uapi/asm/types.h
deleted file mode 100644
index 2000de474be6..000000000000
--- a/arch/ia64/include/uapi/asm/types.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * This file is never included by application software unless explicitly
- * requested (e.g., via linux/types.h) in which case the application is
- * Linux specific so (user-) name space pollution is not a major issue.
- * However, for interoperability, libraries still need to be careful to
- * avoid naming clashes.
- *
- * Based on <asm-alpha/types.h>.
- *
- * Modified 1998-2000, 2002
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-#ifndef _UAPI_ASM_IA64_TYPES_H
-#define _UAPI_ASM_IA64_TYPES_H
-
-
-#ifndef __KERNEL__
-#include <asm-generic/int-l64.h>
-#endif
-
-#ifdef __ASSEMBLY__
-# define __IA64_UL(x) (x)
-# define __IA64_UL_CONST(x) x
-
-#else
-# define __IA64_UL(x) ((unsigned long)(x))
-# define __IA64_UL_CONST(x) x##UL
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _UAPI_ASM_IA64_TYPES_H */
diff --git a/arch/ia64/include/uapi/asm/ucontext.h b/arch/ia64/include/uapi/asm/ucontext.h
deleted file mode 100644
index 46f51e535e04..000000000000
--- a/arch/ia64/include/uapi/asm/ucontext.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _ASM_IA64_UCONTEXT_H
-#define _ASM_IA64_UCONTEXT_H
-
-struct ucontext {
- struct sigcontext uc_mcontext;
-};
-
-#define uc_link uc_mcontext.sc_gr[0] /* wrong type; nobody cares */
-#define uc_sigmask uc_mcontext.sc_sigmask
-#define uc_stack uc_mcontext.sc_stack
-
-#endif /* _ASM_IA64_UCONTEXT_H */
diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h
deleted file mode 100644
index 013e0bcacc39..000000000000
--- a/arch/ia64/include/uapi/asm/unistd.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * IA-64 Linux syscall numbers and inline-functions.
- *
- * Copyright (C) 1998-2005 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#ifndef _UAPI_ASM_IA64_UNISTD_H
-#define _UAPI_ASM_IA64_UNISTD_H
-
-
-#include <asm/break.h>
-
-#define __BREAK_SYSCALL __IA64_BREAK_SYSCALL
-
-#define __NR_Linux 1024
-
-#define __NR_umount __NR_umount2
-
-#include <asm/unistd_64.h>
-
-#endif /* _UAPI_ASM_IA64_UNISTD_H */
diff --git a/arch/ia64/include/uapi/asm/ustack.h b/arch/ia64/include/uapi/asm/ustack.h
deleted file mode 100644
index 703cc5f546ff..000000000000
--- a/arch/ia64/include/uapi/asm/ustack.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _UAPI_ASM_IA64_USTACK_H
-#define _UAPI_ASM_IA64_USTACK_H
-
-/*
- * Constants for the user stack size
- */
-
-
-/* Make a default stack size of 2GiB */
-#define DEFAULT_USER_STACK_SIZE (1UL << 31)
-
-#endif /* _UAPI_ASM_IA64_USTACK_H */
diff --git a/arch/ia64/install.sh b/arch/ia64/install.sh
deleted file mode 100755
index 2d4b66a9f362..000000000000
--- a/arch/ia64/install.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License. See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1995 by Linus Torvalds
-#
-# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
-#
-# "make install" script for ia64 architecture
-#
-# Arguments:
-# $1 - kernel version
-# $2 - kernel image file
-# $3 - kernel map file
-# $4 - default install path (blank if root directory)
-
-if [ -f $4/vmlinuz ]; then
- mv $4/vmlinuz $4/vmlinuz.old
-fi
-
-if [ -f $4/System.map ]; then
- mv $4/System.map $4/System.old
-fi
-
-cat $2 > $4/vmlinuz
-cp $3 $4/System.map
-
-test -x /usr/sbin/elilo && /usr/sbin/elilo
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
deleted file mode 100644
index d7e1cabee2ec..000000000000
--- a/arch/ia64/kernel/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-
-ifdef CONFIG_DYNAMIC_FTRACE
-CFLAGS_REMOVE_ftrace.o = -pg
-endif
-
-extra-y := vmlinux.lds
-
-obj-y := head.o entry.o efi.o efi_stub.o gate-data.o fsys.o irq.o irq_ia64.o \
- irq_lsapic.o ivt.o pal.o patch.o process.o ptrace.o sal.o \
- salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
- unwind.o mca.o mca_asm.o topology.o dma-mapping.o iosapic.o acpi.o \
- acpi-ext.o
-
-obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
-
-obj-$(CONFIG_IA64_PALINFO) += palinfo.o
-obj-$(CONFIG_MODULES) += module.o
-obj-$(CONFIG_SMP) += smp.o smpboot.o
-obj-$(CONFIG_NUMA) += numa.o
-obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
-obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
-obj-$(CONFIG_KPROBES) += kprobes.o
-obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
-obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
-obj-$(CONFIG_AUDIT) += audit.o
-obj-y += msi_ia64.o
-mca_recovery-y += mca_drv.o mca_drv_asm.o
-obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
-obj-$(CONFIG_STACKTRACE) += stacktrace.o
-
-obj-$(CONFIG_IA64_ESI) += esi.o esi_stub.o # must be in kernel proper
-obj-$(CONFIG_INTEL_IOMMU) += pci-dma.o
-
-obj-$(CONFIG_ELF_CORE) += elfcore.o
-
-# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
-CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31
-
-# The gate DSO image is built using a special linker script.
-include $(srctree)/$(src)/Makefile.gate
diff --git a/arch/ia64/kernel/Makefile.gate b/arch/ia64/kernel/Makefile.gate
deleted file mode 100644
index 846867bff6d6..000000000000
--- a/arch/ia64/kernel/Makefile.gate
+++ /dev/null
@@ -1,29 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# The gate DSO image is built using a special linker script.
-
-targets += gate.so gate.lds gate.o gate-dummy.o
-
-obj-y += gate-syms.o
-
-CPPFLAGS_gate.lds := -P -C -U$(ARCH)
-
-quiet_cmd_gate = GATE $@
- cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
-
-GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
- -Wl,--hash-style=sysv
-$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
- $(call if_changed,gate)
-
-GATECFLAGS_gate-dummy.o = -r
-$(obj)/gate-dummy.o: $(obj)/gate.lds $(obj)/gate.o FORCE
- $(call if_changed,gate)
-
-LDFLAGS_gate-syms.o := -r -R
-$(obj)/gate-syms.o: $(obj)/gate-dummy.o FORCE
- $(call if_changed,ld)
-
-# gate-data.o contains the gate DSO image as data in section .data..gate.
-# We must build gate.so before we can assemble it.
-# Note: kbuild does not track this dependency due to usage of .incbin
-$(obj)/gate-data.o: $(obj)/gate.so
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c
deleted file mode 100644
index 42cd21480833..000000000000
--- a/arch/ia64/kernel/acpi-ext.c
+++ /dev/null
@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * (c) Copyright 2003, 2006 Hewlett-Packard Development Company, L.P.
- * Alex Williamson <alex.williamson@hp.com>
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/acpi.h>
-
-#include <asm/acpi-ext.h>
-
-/*
- * Device CSRs that do not appear in PCI config space should be described
- * via ACPI. This would normally be done with Address Space Descriptors
- * marked as "consumer-only," but old versions of Windows and Linux ignore
- * the producer/consumer flag, so HP invented a vendor-defined resource to
- * describe the location and size of CSR space.
- */
-
-struct acpi_vendor_uuid hp_ccsr_uuid = {
- .subtype = 2,
- .data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a,
- 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad },
-};
-
-static acpi_status hp_ccsr_locate(acpi_handle obj, u64 *base, u64 *length)
-{
- acpi_status status;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- struct acpi_resource *resource;
- struct acpi_resource_vendor_typed *vendor;
-
- status = acpi_get_vendor_resource(obj, METHOD_NAME__CRS, &hp_ccsr_uuid,
- &buffer);
-
- resource = buffer.pointer;
- vendor = &resource->data.vendor_typed;
-
- if (ACPI_FAILURE(status) || vendor->byte_length < 16) {
- status = AE_NOT_FOUND;
- goto exit;
- }
-
- memcpy(base, vendor->byte_data, sizeof(*base));
- memcpy(length, vendor->byte_data + 8, sizeof(*length));
-
- exit:
- kfree(buffer.pointer);
- return status;
-}
-
-struct csr_space {
- u64 base;
- u64 length;
-};
-
-static acpi_status find_csr_space(struct acpi_resource *resource, void *data)
-{
- struct csr_space *space = data;
- struct acpi_resource_address64 addr;
- acpi_status status;
-
- status = acpi_resource_to_address64(resource, &addr);
- if (ACPI_SUCCESS(status) &&
- addr.resource_type == ACPI_MEMORY_RANGE &&
- addr.address.address_length &&
- addr.producer_consumer == ACPI_CONSUMER) {
- space->base = addr.address.minimum;
- space->length = addr.address.address_length;
- return AE_CTRL_TERMINATE;
- }
- return AE_OK; /* keep looking */
-}
-
-static acpi_status hp_crs_locate(acpi_handle obj, u64 *base, u64 *length)
-{
- struct csr_space space = { 0, 0 };
-
- acpi_walk_resources(obj, METHOD_NAME__CRS, find_csr_space, &space);
- if (!space.length)
- return AE_NOT_FOUND;
-
- *base = space.base;
- *length = space.length;
- return AE_OK;
-}
-
-acpi_status hp_acpi_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
-{
- acpi_status status;
-
- status = hp_ccsr_locate(obj, csr_base, csr_length);
- if (ACPI_SUCCESS(status))
- return status;
-
- return hp_crs_locate(obj, csr_base, csr_length);
-}
-EXPORT_SYMBOL(hp_acpi_csr_space);
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
deleted file mode 100644
index 41e8fe55cd98..000000000000
--- a/arch/ia64/kernel/acpi.c
+++ /dev/null
@@ -1,913 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * acpi.c - Architecture-Specific Low-Level ACPI Support
- *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 2000, 2002-2003 Hewlett-Packard Co.
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2000 Intel Corp.
- * Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
- * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- * Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com>
- * Copyright (C) 2001 Takayoshi Kochi <t-kochi@bq.jp.nec.com>
- * Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
- * Copyright (C) 2004 Ashok Raj <ashok.raj@intel.com>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/irq.h>
-#include <linux/acpi.h>
-#include <linux/efi.h>
-#include <linux/mmzone.h>
-#include <linux/nodemask.h>
-#include <linux/slab.h>
-#include <acpi/processor.h>
-#include <asm/io.h>
-#include <asm/iosapic.h>
-#include <asm/page.h>
-#include <asm/numa.h>
-#include <asm/sal.h>
-#include <asm/cyclone.h>
-
-#define PREFIX "ACPI: "
-
-int acpi_lapic;
-unsigned int acpi_cpei_override;
-unsigned int acpi_cpei_phys_cpuid;
-
-#define ACPI_MAX_PLATFORM_INTERRUPTS 256
-
-/* Array to record platform interrupt vectors for generic interrupt routing. */
-int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = {
- [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1
-};
-
-enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
-
-/*
- * Interrupt routing API for device drivers. Provides interrupt vector for
- * a generic platform event. Currently only CPEI is implemented.
- */
-int acpi_request_vector(u32 int_type)
-{
- int vector = -1;
-
- if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {
- /* corrected platform error interrupt */
- vector = platform_intr_list[int_type];
- } else
- printk(KERN_ERR
- "acpi_request_vector(): invalid interrupt type\n");
- return vector;
-}
-
-void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size)
-{
- return __va(phys);
-}
-
-void __init __acpi_unmap_table(void __iomem *map, unsigned long size)
-{
-}
-
-/* --------------------------------------------------------------------------
- Boot-time Table Parsing
- -------------------------------------------------------------------------- */
-
-static int available_cpus __initdata;
-struct acpi_table_madt *acpi_madt __initdata;
-static u8 has_8259;
-
-static int __init
-acpi_parse_lapic_addr_ovr(union acpi_subtable_headers * header,
- const unsigned long end)
-{
- struct acpi_madt_local_apic_override *lapic;
-
- lapic = (struct acpi_madt_local_apic_override *)header;
-
- if (BAD_MADT_ENTRY(lapic, end))
- return -EINVAL;
-
- if (lapic->address) {
- iounmap(ipi_base_addr);
- ipi_base_addr = ioremap(lapic->address, 0);
- }
- return 0;
-}
-
-static int __init
-acpi_parse_lsapic(union acpi_subtable_headers *header, const unsigned long end)
-{
- struct acpi_madt_local_sapic *lsapic;
-
- lsapic = (struct acpi_madt_local_sapic *)header;
-
- /*Skip BAD_MADT_ENTRY check, as lsapic size could vary */
-
- if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
-#ifdef CONFIG_SMP
- smp_boot_data.cpu_phys_id[available_cpus] =
- (lsapic->id << 8) | lsapic->eid;
-#endif
- ++available_cpus;
- }
-
- total_cpus++;
- return 0;
-}
-
-static int __init
-acpi_parse_lapic_nmi(union acpi_subtable_headers * header, const unsigned long end)
-{
- struct acpi_madt_local_apic_nmi *lacpi_nmi;
-
- lacpi_nmi = (struct acpi_madt_local_apic_nmi *)header;
-
- if (BAD_MADT_ENTRY(lacpi_nmi, end))
- return -EINVAL;
-
- /* TBD: Support lapic_nmi entries */
- return 0;
-}
-
-static int __init
-acpi_parse_iosapic(union acpi_subtable_headers * header, const unsigned long end)
-{
- struct acpi_madt_io_sapic *iosapic;
-
- iosapic = (struct acpi_madt_io_sapic *)header;
-
- if (BAD_MADT_ENTRY(iosapic, end))
- return -EINVAL;
-
- return iosapic_init(iosapic->address, iosapic->global_irq_base);
-}
-
-static unsigned int __initdata acpi_madt_rev;
-
-static int __init
-acpi_parse_plat_int_src(union acpi_subtable_headers * header,
- const unsigned long end)
-{
- struct acpi_madt_interrupt_source *plintsrc;
- int vector;
-
- plintsrc = (struct acpi_madt_interrupt_source *)header;
-
- if (BAD_MADT_ENTRY(plintsrc, end))
- return -EINVAL;
-
- /*
- * Get vector assignment for this interrupt, set attributes,
- * and program the IOSAPIC routing table.
- */
- vector = iosapic_register_platform_intr(plintsrc->type,
- plintsrc->global_irq,
- plintsrc->io_sapic_vector,
- plintsrc->eid,
- plintsrc->id,
- ((plintsrc->inti_flags & ACPI_MADT_POLARITY_MASK) ==
- ACPI_MADT_POLARITY_ACTIVE_HIGH) ?
- IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
- ((plintsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) ==
- ACPI_MADT_TRIGGER_EDGE) ?
- IOSAPIC_EDGE : IOSAPIC_LEVEL);
-
- platform_intr_list[plintsrc->type] = vector;
- if (acpi_madt_rev > 1) {
- acpi_cpei_override = plintsrc->flags & ACPI_MADT_CPEI_OVERRIDE;
- }
-
- /*
- * Save the physical id, so we can check when its being removed
- */
- acpi_cpei_phys_cpuid = ((plintsrc->id << 8) | (plintsrc->eid)) & 0xffff;
-
- return 0;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-unsigned int can_cpei_retarget(void)
-{
- extern int cpe_vector;
- extern unsigned int force_cpei_retarget;
-
- /*
- * Only if CPEI is supported and the override flag
- * is present, otherwise return that its re-targettable
- * if we are in polling mode.
- */
- if (cpe_vector > 0) {
- if (acpi_cpei_override || force_cpei_retarget)
- return 1;
- else
- return 0;
- }
- return 1;
-}
-
-unsigned int is_cpu_cpei_target(unsigned int cpu)
-{
- unsigned int logical_id;
-
- logical_id = cpu_logical_id(acpi_cpei_phys_cpuid);
-
- if (logical_id == cpu)
- return 1;
- else
- return 0;
-}
-
-void set_cpei_target_cpu(unsigned int cpu)
-{
- acpi_cpei_phys_cpuid = cpu_physical_id(cpu);
-}
-#endif
-
-unsigned int get_cpei_target_cpu(void)
-{
- return acpi_cpei_phys_cpuid;
-}
-
-static int __init
-acpi_parse_int_src_ovr(union acpi_subtable_headers * header,
- const unsigned long end)
-{
- struct acpi_madt_interrupt_override *p;
-
- p = (struct acpi_madt_interrupt_override *)header;
-
- if (BAD_MADT_ENTRY(p, end))
- return -EINVAL;
-
- iosapic_override_isa_irq(p->source_irq, p->global_irq,
- ((p->inti_flags & ACPI_MADT_POLARITY_MASK) ==
- ACPI_MADT_POLARITY_ACTIVE_LOW) ?
- IOSAPIC_POL_LOW : IOSAPIC_POL_HIGH,
- ((p->inti_flags & ACPI_MADT_TRIGGER_MASK) ==
- ACPI_MADT_TRIGGER_LEVEL) ?
- IOSAPIC_LEVEL : IOSAPIC_EDGE);
- return 0;
-}
-
-static int __init
-acpi_parse_nmi_src(union acpi_subtable_headers * header, const unsigned long end)
-{
- struct acpi_madt_nmi_source *nmi_src;
-
- nmi_src = (struct acpi_madt_nmi_source *)header;
-
- if (BAD_MADT_ENTRY(nmi_src, end))
- return -EINVAL;
-
- /* TBD: Support nimsrc entries */
- return 0;
-}
-
-static void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
- if (!strncmp(oem_id, "IBM", 3) && (!strncmp(oem_table_id, "SERMOW", 6))) {
-
- /*
- * Unfortunately ITC_DRIFT is not yet part of the
- * official SAL spec, so the ITC_DRIFT bit is not
- * set by the BIOS on this hardware.
- */
- sal_platform_features |= IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT;
-
- cyclone_setup();
- }
-}
-
-static int __init acpi_parse_madt(struct acpi_table_header *table)
-{
- acpi_madt = (struct acpi_table_madt *)table;
-
- acpi_madt_rev = acpi_madt->header.revision;
-
- /* remember the value for reference after free_initmem() */
-#ifdef CONFIG_ITANIUM
- has_8259 = 1; /* Firmware on old Itanium systems is broken */
-#else
- has_8259 = acpi_madt->flags & ACPI_MADT_PCAT_COMPAT;
-#endif
- iosapic_system_init(has_8259);
-
- /* Get base address of IPI Message Block */
-
- if (acpi_madt->address)
- ipi_base_addr = ioremap(acpi_madt->address, 0);
-
- printk(KERN_INFO PREFIX "Local APIC address %p\n", ipi_base_addr);
-
- acpi_madt_oem_check(acpi_madt->header.oem_id,
- acpi_madt->header.oem_table_id);
-
- return 0;
-}
-
-#ifdef CONFIG_ACPI_NUMA
-
-#undef SLIT_DEBUG
-
-#define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
-
-static int __initdata srat_num_cpus; /* number of cpus */
-static u32 pxm_flag[PXM_FLAG_LEN];
-#define pxm_bit_set(bit) (set_bit(bit,(void *)pxm_flag))
-#define pxm_bit_test(bit) (test_bit(bit,(void *)pxm_flag))
-static struct acpi_table_slit __initdata *slit_table;
-cpumask_t early_cpu_possible_map = CPU_MASK_NONE;
-
-static int __init
-get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
-{
- int pxm;
-
- pxm = pa->proximity_domain_lo;
- if (acpi_srat_revision >= 2)
- pxm += pa->proximity_domain_hi[0] << 8;
- return pxm;
-}
-
-static int __init
-get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
-{
- int pxm;
-
- pxm = ma->proximity_domain;
- if (acpi_srat_revision <= 1)
- pxm &= 0xff;
-
- return pxm;
-}
-
-/*
- * ACPI 2.0 SLIT (System Locality Information Table)
- * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
- */
-void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
-{
- u32 len;
-
- len = sizeof(struct acpi_table_header) + 8
- + slit->locality_count * slit->locality_count;
- if (slit->header.length != len) {
- printk(KERN_ERR
- "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
- len, slit->header.length);
- return;
- }
- slit_table = slit;
-}
-
-void __init
-acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
-{
- int pxm;
-
- if (!(pa->flags & ACPI_SRAT_CPU_ENABLED))
- return;
-
- if (srat_num_cpus >= ARRAY_SIZE(node_cpuid)) {
- printk_once(KERN_WARNING
- "node_cpuid[%ld] is too small, may not be able to use all cpus\n",
- ARRAY_SIZE(node_cpuid));
- return;
- }
- pxm = get_processor_proximity_domain(pa);
-
- /* record this node in proximity bitmap */
- pxm_bit_set(pxm);
-
- node_cpuid[srat_num_cpus].phys_id =
- (pa->apic_id << 8) | (pa->local_sapic_eid);
- /* nid should be overridden as logical node id later */
- node_cpuid[srat_num_cpus].nid = pxm;
- cpumask_set_cpu(srat_num_cpus, &early_cpu_possible_map);
- srat_num_cpus++;
-}
-
-int __init
-acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
-{
- unsigned long paddr, size;
- int pxm;
- struct node_memblk_s *p, *q, *pend;
-
- pxm = get_memory_proximity_domain(ma);
-
- /* fill node memory chunk structure */
- paddr = ma->base_address;
- size = ma->length;
-
- /* Ignore disabled entries */
- if (!(ma->flags & ACPI_SRAT_MEM_ENABLED))
- return -1;
-
- if (num_node_memblks >= NR_NODE_MEMBLKS) {
- pr_err("NUMA: too many memblk ranges\n");
- return -EINVAL;
- }
-
- /* record this node in proximity bitmap */
- pxm_bit_set(pxm);
-
- /* Insertion sort based on base address */
- pend = &node_memblk[num_node_memblks];
- for (p = &node_memblk[0]; p < pend; p++) {
- if (paddr < p->start_paddr)
- break;
- }
- if (p < pend) {
- for (q = pend - 1; q >= p; q--)
- *(q + 1) = *q;
- }
- p->start_paddr = paddr;
- p->size = size;
- p->nid = pxm;
- num_node_memblks++;
- return 0;
-}
-
-void __init acpi_numa_fixup(void)
-{
- int i, j, node_from, node_to;
-
- /* If there's no SRAT, fix the phys_id and mark node 0 online */
- if (srat_num_cpus == 0) {
- node_set_online(0);
- node_cpuid[0].phys_id = hard_smp_processor_id();
- slit_distance(0, 0) = LOCAL_DISTANCE;
- goto out;
- }
-
- /*
- * MCD - This can probably be dropped now. No need for pxm ID to node ID
- * mapping with sparse node numbering iff MAX_PXM_DOMAINS <= MAX_NUMNODES.
- */
- nodes_clear(node_online_map);
- for (i = 0; i < MAX_PXM_DOMAINS; i++) {
- if (pxm_bit_test(i)) {
- int nid = acpi_map_pxm_to_node(i);
- node_set_online(nid);
- }
- }
-
- /* set logical node id in memory chunk structure */
- for (i = 0; i < num_node_memblks; i++)
- node_memblk[i].nid = pxm_to_node(node_memblk[i].nid);
-
- /* assign memory bank numbers for each chunk on each node */
- for_each_online_node(i) {
- int bank;
-
- bank = 0;
- for (j = 0; j < num_node_memblks; j++)
- if (node_memblk[j].nid == i)
- node_memblk[j].bank = bank++;
- }
-
- /* set logical node id in cpu structure */
- for_each_possible_early_cpu(i)
- node_cpuid[i].nid = pxm_to_node(node_cpuid[i].nid);
-
- printk(KERN_INFO "Number of logical nodes in system = %d\n",
- num_online_nodes());
- printk(KERN_INFO "Number of memory chunks in system = %d\n",
- num_node_memblks);
-
- if (!slit_table) {
- for (i = 0; i < MAX_NUMNODES; i++)
- for (j = 0; j < MAX_NUMNODES; j++)
- slit_distance(i, j) = i == j ?
- LOCAL_DISTANCE : REMOTE_DISTANCE;
- goto out;
- }
-
- memset(numa_slit, -1, sizeof(numa_slit));
- for (i = 0; i < slit_table->locality_count; i++) {
- if (!pxm_bit_test(i))
- continue;
- node_from = pxm_to_node(i);
- for (j = 0; j < slit_table->locality_count; j++) {
- if (!pxm_bit_test(j))
- continue;
- node_to = pxm_to_node(j);
- slit_distance(node_from, node_to) =
- slit_table->entry[i * slit_table->locality_count + j];
- }
- }
-
-#ifdef SLIT_DEBUG
- printk("ACPI 2.0 SLIT locality table:\n");
- for_each_online_node(i) {
- for_each_online_node(j)
- printk("%03d ", node_distance(i, j));
- printk("\n");
- }
-#endif
-out:
- node_possible_map = node_online_map;
-}
-#endif /* CONFIG_ACPI_NUMA */
-
-/*
- * success: return IRQ number (>=0)
- * failure: return < 0
- */
-int acpi_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
-{
- if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM)
- return gsi;
-
- if (has_8259 && gsi < 16)
- return isa_irq_to_vector(gsi);
-
- return iosapic_register_intr(gsi,
- (polarity ==
- ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH :
- IOSAPIC_POL_LOW,
- (triggering ==
- ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE :
- IOSAPIC_LEVEL);
-}
-EXPORT_SYMBOL_GPL(acpi_register_gsi);
-
-void acpi_unregister_gsi(u32 gsi)
-{
- if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM)
- return;
-
- if (has_8259 && gsi < 16)
- return;
-
- iosapic_unregister_intr(gsi);
-}
-EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
-
-static int __init acpi_parse_fadt(struct acpi_table_header *table)
-{
- struct acpi_table_header *fadt_header;
- struct acpi_table_fadt *fadt;
-
- fadt_header = (struct acpi_table_header *)table;
- if (fadt_header->revision != 3)
- return -ENODEV; /* Only deal with ACPI 2.0 FADT */
-
- fadt = (struct acpi_table_fadt *)fadt_header;
-
- acpi_register_gsi(NULL, fadt->sci_interrupt, ACPI_LEVEL_SENSITIVE,
- ACPI_ACTIVE_LOW);
- return 0;
-}
-
-int __init early_acpi_boot_init(void)
-{
- int ret;
-
- /*
- * do a partial walk of MADT to determine how many CPUs
- * we have including offline CPUs
- */
- if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
- printk(KERN_ERR PREFIX "Can't find MADT\n");
- return 0;
- }
-
- ret = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
- acpi_parse_lsapic, NR_CPUS);
- if (ret < 1)
- printk(KERN_ERR PREFIX
- "Error parsing MADT - no LAPIC entries\n");
- else
- acpi_lapic = 1;
-
-#ifdef CONFIG_SMP
- if (available_cpus == 0) {
- printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
- printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
- smp_boot_data.cpu_phys_id[available_cpus] =
- hard_smp_processor_id();
- available_cpus = 1; /* We've got at least one of these, no? */
- }
- smp_boot_data.cpu_count = available_cpus;
-#endif
- /* Make boot-up look pretty */
- printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus,
- total_cpus);
-
- return 0;
-}
-
-int __init acpi_boot_init(void)
-{
-
- /*
- * MADT
- * ----
- * Parse the Multiple APIC Description Table (MADT), if exists.
- * Note that this table provides platform SMP configuration
- * information -- the successor to MPS tables.
- */
-
- if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
- printk(KERN_ERR PREFIX "Can't find MADT\n");
- goto skip_madt;
- }
-
- /* Local APIC */
-
- if (acpi_table_parse_madt
- (ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, acpi_parse_lapic_addr_ovr, 0) < 0)
- printk(KERN_ERR PREFIX
- "Error parsing LAPIC address override entry\n");
-
- if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0)
- < 0)
- printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
-
- /* I/O APIC */
-
- if (acpi_table_parse_madt
- (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) {
- printk(KERN_ERR PREFIX
- "Error parsing MADT - no IOSAPIC entries\n");
- }
-
- /* System-Level Interrupt Routing */
-
- if (acpi_table_parse_madt
- (ACPI_MADT_TYPE_INTERRUPT_SOURCE, acpi_parse_plat_int_src,
- ACPI_MAX_PLATFORM_INTERRUPTS) < 0)
- printk(KERN_ERR PREFIX
- "Error parsing platform interrupt source entry\n");
-
- if (acpi_table_parse_madt
- (ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr, 0) < 0)
- printk(KERN_ERR PREFIX
- "Error parsing interrupt source overrides entry\n");
-
- if (acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src, 0) < 0)
- printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
- skip_madt:
-
- /*
- * FADT says whether a legacy keyboard controller is present.
- * The FADT also contains an SCI_INT line, by which the system
- * gets interrupts such as power and sleep buttons. If it's not
- * on a Legacy interrupt, it needs to be setup.
- */
- if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt))
- printk(KERN_ERR PREFIX "Can't find FADT\n");
-
-#ifdef CONFIG_ACPI_NUMA
-#ifdef CONFIG_SMP
- if (srat_num_cpus == 0) {
- int cpu, i = 1;
- for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++)
- if (smp_boot_data.cpu_phys_id[cpu] !=
- hard_smp_processor_id())
- node_cpuid[i++].phys_id =
- smp_boot_data.cpu_phys_id[cpu];
- }
-#endif
- build_cpu_to_node_map();
-#endif
- return 0;
-}
-
-int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
-{
- int tmp;
-
- if (has_8259 && gsi < 16)
- *irq = isa_irq_to_vector(gsi);
- else {
- tmp = gsi_to_irq(gsi);
- if (tmp == -1)
- return -1;
- *irq = tmp;
- }
- return 0;
-}
-
-int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
-{
- if (isa_irq >= 16)
- return -1;
- *gsi = isa_irq;
- return 0;
-}
-
-/*
- * ACPI based hotplug CPU support
- */
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
-{
-#ifdef CONFIG_ACPI_NUMA
- /*
- * We don't have cpu-only-node hotadd. But if the system equips
- * SRAT table, pxm is already found and node is ready.
- * So, just pxm_to_nid(pxm) is OK.
- * This code here is for the system which doesn't have full SRAT
- * table for possible cpus.
- */
- node_cpuid[cpu].phys_id = physid;
- node_cpuid[cpu].nid = acpi_get_node(handle);
-#endif
- return 0;
-}
-
-int additional_cpus __initdata = -1;
-
-static __init int setup_additional_cpus(char *s)
-{
- if (s)
- additional_cpus = simple_strtol(s, NULL, 0);
-
- return 0;
-}
-
-early_param("additional_cpus", setup_additional_cpus);
-
-/*
- * cpu_possible_mask should be static, it cannot change as CPUs
- * are onlined, or offlined. The reason is per-cpu data-structures
- * are allocated by some modules at init time, and dont expect to
- * do this dynamically on cpu arrival/departure.
- * cpu_present_mask on the other hand can change dynamically.
- * In case when cpu_hotplug is not compiled, then we resort to current
- * behaviour, which is cpu_possible == cpu_present.
- * - Ashok Raj
- *
- * Three ways to find out the number of additional hotplug CPUs:
- * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
- * - The user can overwrite it with additional_cpus=NUM
- * - Otherwise don't reserve additional CPUs.
- */
-__init void prefill_possible_map(void)
-{
- int i;
- int possible, disabled_cpus;
-
- disabled_cpus = total_cpus - available_cpus;
-
- if (additional_cpus == -1) {
- if (disabled_cpus > 0)
- additional_cpus = disabled_cpus;
- else
- additional_cpus = 0;
- }
-
- possible = available_cpus + additional_cpus;
-
- if (possible > nr_cpu_ids)
- possible = nr_cpu_ids;
-
- printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n",
- possible, max((possible - available_cpus), 0));
-
- for (i = 0; i < possible; i++)
- set_cpu_possible(i, true);
-}
-
-static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
-{
- int cpu;
-
- cpu = cpumask_first_zero(cpu_present_mask);
- if (cpu >= nr_cpu_ids)
- return -EINVAL;
-
- acpi_map_cpu2node(handle, cpu, physid);
-
- set_cpu_present(cpu, true);
- ia64_cpu_to_sapicid[cpu] = physid;
-
- acpi_processor_set_pdc(handle);
-
- *pcpu = cpu;
- return (0);
-}
-
-/* wrapper to silence section mismatch warning */
-int __ref acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id,
- int *pcpu)
-{
- return _acpi_map_lsapic(handle, physid, pcpu);
-}
-EXPORT_SYMBOL(acpi_map_cpu);
-
-int acpi_unmap_cpu(int cpu)
-{
- ia64_cpu_to_sapicid[cpu] = -1;
- set_cpu_present(cpu, false);
-
-#ifdef CONFIG_ACPI_NUMA
- /* NUMA specific cleanup's */
-#endif
-
- return (0);
-}
-EXPORT_SYMBOL(acpi_unmap_cpu);
-#endif /* CONFIG_ACPI_HOTPLUG_CPU */
-
-#ifdef CONFIG_ACPI_NUMA
-static acpi_status acpi_map_iosapic(acpi_handle handle, u32 depth,
- void *context, void **ret)
-{
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- struct acpi_madt_io_sapic *iosapic;
- unsigned int gsi_base;
- int node;
-
- /* Only care about objects w/ a method that returns the MADT */
- if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
- return AE_OK;
-
- if (!buffer.length || !buffer.pointer)
- return AE_OK;
-
- obj = buffer.pointer;
- if (obj->type != ACPI_TYPE_BUFFER ||
- obj->buffer.length < sizeof(*iosapic)) {
- kfree(buffer.pointer);
- return AE_OK;
- }
-
- iosapic = (struct acpi_madt_io_sapic *)obj->buffer.pointer;
-
- if (iosapic->header.type != ACPI_MADT_TYPE_IO_SAPIC) {
- kfree(buffer.pointer);
- return AE_OK;
- }
-
- gsi_base = iosapic->global_irq_base;
-
- kfree(buffer.pointer);
-
- /* OK, it's an IOSAPIC MADT entry; associate it with a node */
- node = acpi_get_node(handle);
- if (node == NUMA_NO_NODE || !node_online(node) ||
- cpumask_empty(cpumask_of_node(node)))
- return AE_OK;
-
- /* We know a gsi to node mapping! */
- map_iosapic_to_node(gsi_base, node);
- return AE_OK;
-}
-
-static int __init
-acpi_map_iosapics (void)
-{
- acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
- return 0;
-}
-
-fs_initcall(acpi_map_iosapics);
-#endif /* CONFIG_ACPI_NUMA */
-
-int __ref acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
-{
- int err;
-
- if ((err = iosapic_init(phys_addr, gsi_base)))
- return err;
-
-#ifdef CONFIG_ACPI_NUMA
- acpi_map_iosapic(handle, 0, NULL, NULL);
-#endif /* CONFIG_ACPI_NUMA */
-
- return 0;
-}
-
-EXPORT_SYMBOL(acpi_register_ioapic);
-
-int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
-{
- return iosapic_remove(gsi_base);
-}
-
-EXPORT_SYMBOL(acpi_unregister_ioapic);
-
-/*
- * acpi_suspend_lowlevel() - save kernel state and suspend.
- *
- * TBD when IA64 starts to support suspend...
- */
-int acpi_suspend_lowlevel(void) { return 0; }
-
-void acpi_proc_quirk_mwait_check(void)
-{
-}
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
deleted file mode 100644
index be3b90fef2e9..000000000000
--- a/arch/ia64/kernel/asm-offsets.c
+++ /dev/null
@@ -1,289 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Generate definitions needed by assembly language modules.
- * This code generates raw asm output which is post-processed
- * to extract and format the required data.
- */
-
-#define ASM_OFFSETS_C 1
-
-#include <linux/sched/signal.h>
-#include <linux/pid.h>
-#include <linux/clocksource.h>
-#include <linux/kbuild.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/siginfo.h>
-#include <asm/sigcontext.h>
-#include <asm/mca.h>
-
-#include "../kernel/sigframe.h"
-#include "../kernel/fsyscall_gtod_data.h"
-
-void foo(void)
-{
- DEFINE(IA64_TASK_SIZE, sizeof (struct task_struct));
- DEFINE(IA64_THREAD_INFO_SIZE, sizeof (struct thread_info));
- DEFINE(IA64_PT_REGS_SIZE, sizeof (struct pt_regs));
- DEFINE(IA64_SWITCH_STACK_SIZE, sizeof (struct switch_stack));
- DEFINE(IA64_SIGINFO_SIZE, sizeof (struct siginfo));
- DEFINE(IA64_CPU_SIZE, sizeof (struct cpuinfo_ia64));
- DEFINE(SIGFRAME_SIZE, sizeof (struct sigframe));
- DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info));
-
- BUILD_BUG_ON(sizeof(struct upid) != 16);
- DEFINE(IA64_UPID_SHIFT, 4);
-
- BLANK();
-
- DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
- DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
- DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- DEFINE(TI_AC_STAMP, offsetof(struct thread_info, ac_stamp));
- DEFINE(TI_AC_LEAVE, offsetof(struct thread_info, ac_leave));
- DEFINE(TI_AC_STIME, offsetof(struct thread_info, ac_stime));
- DEFINE(TI_AC_UTIME, offsetof(struct thread_info, ac_utime));
-#endif
-
- BLANK();
-
- DEFINE(IA64_TASK_BLOCKED_OFFSET,offsetof (struct task_struct, blocked));
- DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid));
- DEFINE(IA64_TASK_THREAD_PID_OFFSET,offsetof (struct task_struct, thread_pid));
- DEFINE(IA64_PID_LEVEL_OFFSET, offsetof (struct pid, level));
- DEFINE(IA64_PID_UPID_OFFSET, offsetof (struct pid, numbers[0]));
- DEFINE(IA64_TASK_PENDING_OFFSET,offsetof (struct task_struct, pending));
- DEFINE(IA64_TASK_PID_OFFSET, offsetof (struct task_struct, pid));
- DEFINE(IA64_TASK_REAL_PARENT_OFFSET, offsetof (struct task_struct, real_parent));
- DEFINE(IA64_TASK_SIGNAL_OFFSET,offsetof (struct task_struct, signal));
- DEFINE(IA64_TASK_TGID_OFFSET, offsetof (struct task_struct, tgid));
- DEFINE(IA64_TASK_THREAD_KSP_OFFSET, offsetof (struct task_struct, thread.ksp));
- DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct task_struct, thread.on_ustack));
-
- BLANK();
-
-
- DEFINE(IA64_SIGNAL_GROUP_STOP_COUNT_OFFSET,offsetof (struct signal_struct,
- group_stop_count));
- DEFINE(IA64_SIGNAL_SHARED_PENDING_OFFSET,offsetof (struct signal_struct, shared_pending));
- DEFINE(IA64_SIGNAL_PIDS_TGID_OFFSET, offsetof (struct signal_struct, pids[PIDTYPE_TGID]));
-
- BLANK();
-
- DEFINE(IA64_PT_REGS_B6_OFFSET, offsetof (struct pt_regs, b6));
- DEFINE(IA64_PT_REGS_B7_OFFSET, offsetof (struct pt_regs, b7));
- DEFINE(IA64_PT_REGS_AR_CSD_OFFSET, offsetof (struct pt_regs, ar_csd));
- DEFINE(IA64_PT_REGS_AR_SSD_OFFSET, offsetof (struct pt_regs, ar_ssd));
- DEFINE(IA64_PT_REGS_R8_OFFSET, offsetof (struct pt_regs, r8));
- DEFINE(IA64_PT_REGS_R9_OFFSET, offsetof (struct pt_regs, r9));
- DEFINE(IA64_PT_REGS_R10_OFFSET, offsetof (struct pt_regs, r10));
- DEFINE(IA64_PT_REGS_R11_OFFSET, offsetof (struct pt_regs, r11));
- DEFINE(IA64_PT_REGS_CR_IPSR_OFFSET, offsetof (struct pt_regs, cr_ipsr));
- DEFINE(IA64_PT_REGS_CR_IIP_OFFSET, offsetof (struct pt_regs, cr_iip));
- DEFINE(IA64_PT_REGS_CR_IFS_OFFSET, offsetof (struct pt_regs, cr_ifs));
- DEFINE(IA64_PT_REGS_AR_UNAT_OFFSET, offsetof (struct pt_regs, ar_unat));
- DEFINE(IA64_PT_REGS_AR_PFS_OFFSET, offsetof (struct pt_regs, ar_pfs));
- DEFINE(IA64_PT_REGS_AR_RSC_OFFSET, offsetof (struct pt_regs, ar_rsc));
- DEFINE(IA64_PT_REGS_AR_RNAT_OFFSET, offsetof (struct pt_regs, ar_rnat));
-
- DEFINE(IA64_PT_REGS_AR_BSPSTORE_OFFSET, offsetof (struct pt_regs, ar_bspstore));
- DEFINE(IA64_PT_REGS_PR_OFFSET, offsetof (struct pt_regs, pr));
- DEFINE(IA64_PT_REGS_B0_OFFSET, offsetof (struct pt_regs, b0));
- DEFINE(IA64_PT_REGS_LOADRS_OFFSET, offsetof (struct pt_regs, loadrs));
- DEFINE(IA64_PT_REGS_R1_OFFSET, offsetof (struct pt_regs, r1));
- DEFINE(IA64_PT_REGS_R12_OFFSET, offsetof (struct pt_regs, r12));
- DEFINE(IA64_PT_REGS_R13_OFFSET, offsetof (struct pt_regs, r13));
- DEFINE(IA64_PT_REGS_AR_FPSR_OFFSET, offsetof (struct pt_regs, ar_fpsr));
- DEFINE(IA64_PT_REGS_R15_OFFSET, offsetof (struct pt_regs, r15));
- DEFINE(IA64_PT_REGS_R14_OFFSET, offsetof (struct pt_regs, r14));
- DEFINE(IA64_PT_REGS_R2_OFFSET, offsetof (struct pt_regs, r2));
- DEFINE(IA64_PT_REGS_R3_OFFSET, offsetof (struct pt_regs, r3));
- DEFINE(IA64_PT_REGS_R16_OFFSET, offsetof (struct pt_regs, r16));
- DEFINE(IA64_PT_REGS_R17_OFFSET, offsetof (struct pt_regs, r17));
- DEFINE(IA64_PT_REGS_R18_OFFSET, offsetof (struct pt_regs, r18));
- DEFINE(IA64_PT_REGS_R19_OFFSET, offsetof (struct pt_regs, r19));
- DEFINE(IA64_PT_REGS_R20_OFFSET, offsetof (struct pt_regs, r20));
- DEFINE(IA64_PT_REGS_R21_OFFSET, offsetof (struct pt_regs, r21));
- DEFINE(IA64_PT_REGS_R22_OFFSET, offsetof (struct pt_regs, r22));
- DEFINE(IA64_PT_REGS_R23_OFFSET, offsetof (struct pt_regs, r23));
- DEFINE(IA64_PT_REGS_R24_OFFSET, offsetof (struct pt_regs, r24));
- DEFINE(IA64_PT_REGS_R25_OFFSET, offsetof (struct pt_regs, r25));
- DEFINE(IA64_PT_REGS_R26_OFFSET, offsetof (struct pt_regs, r26));
- DEFINE(IA64_PT_REGS_R27_OFFSET, offsetof (struct pt_regs, r27));
- DEFINE(IA64_PT_REGS_R28_OFFSET, offsetof (struct pt_regs, r28));
- DEFINE(IA64_PT_REGS_R29_OFFSET, offsetof (struct pt_regs, r29));
- DEFINE(IA64_PT_REGS_R30_OFFSET, offsetof (struct pt_regs, r30));
- DEFINE(IA64_PT_REGS_R31_OFFSET, offsetof (struct pt_regs, r31));
- DEFINE(IA64_PT_REGS_AR_CCV_OFFSET, offsetof (struct pt_regs, ar_ccv));
- DEFINE(IA64_PT_REGS_F6_OFFSET, offsetof (struct pt_regs, f6));
- DEFINE(IA64_PT_REGS_F7_OFFSET, offsetof (struct pt_regs, f7));
- DEFINE(IA64_PT_REGS_F8_OFFSET, offsetof (struct pt_regs, f8));
- DEFINE(IA64_PT_REGS_F9_OFFSET, offsetof (struct pt_regs, f9));
- DEFINE(IA64_PT_REGS_F10_OFFSET, offsetof (struct pt_regs, f10));
- DEFINE(IA64_PT_REGS_F11_OFFSET, offsetof (struct pt_regs, f11));
-
- BLANK();
-
- DEFINE(IA64_SWITCH_STACK_CALLER_UNAT_OFFSET, offsetof (struct switch_stack, caller_unat));
- DEFINE(IA64_SWITCH_STACK_AR_FPSR_OFFSET, offsetof (struct switch_stack, ar_fpsr));
- DEFINE(IA64_SWITCH_STACK_F2_OFFSET, offsetof (struct switch_stack, f2));
- DEFINE(IA64_SWITCH_STACK_F3_OFFSET, offsetof (struct switch_stack, f3));
- DEFINE(IA64_SWITCH_STACK_F4_OFFSET, offsetof (struct switch_stack, f4));
- DEFINE(IA64_SWITCH_STACK_F5_OFFSET, offsetof (struct switch_stack, f5));
- DEFINE(IA64_SWITCH_STACK_F12_OFFSET, offsetof (struct switch_stack, f12));
- DEFINE(IA64_SWITCH_STACK_F13_OFFSET, offsetof (struct switch_stack, f13));
- DEFINE(IA64_SWITCH_STACK_F14_OFFSET, offsetof (struct switch_stack, f14));
- DEFINE(IA64_SWITCH_STACK_F15_OFFSET, offsetof (struct switch_stack, f15));
- DEFINE(IA64_SWITCH_STACK_F16_OFFSET, offsetof (struct switch_stack, f16));
- DEFINE(IA64_SWITCH_STACK_F17_OFFSET, offsetof (struct switch_stack, f17));
- DEFINE(IA64_SWITCH_STACK_F18_OFFSET, offsetof (struct switch_stack, f18));
- DEFINE(IA64_SWITCH_STACK_F19_OFFSET, offsetof (struct switch_stack, f19));
- DEFINE(IA64_SWITCH_STACK_F20_OFFSET, offsetof (struct switch_stack, f20));
- DEFINE(IA64_SWITCH_STACK_F21_OFFSET, offsetof (struct switch_stack, f21));
- DEFINE(IA64_SWITCH_STACK_F22_OFFSET, offsetof (struct switch_stack, f22));
- DEFINE(IA64_SWITCH_STACK_F23_OFFSET, offsetof (struct switch_stack, f23));
- DEFINE(IA64_SWITCH_STACK_F24_OFFSET, offsetof (struct switch_stack, f24));
- DEFINE(IA64_SWITCH_STACK_F25_OFFSET, offsetof (struct switch_stack, f25));
- DEFINE(IA64_SWITCH_STACK_F26_OFFSET, offsetof (struct switch_stack, f26));
- DEFINE(IA64_SWITCH_STACK_F27_OFFSET, offsetof (struct switch_stack, f27));
- DEFINE(IA64_SWITCH_STACK_F28_OFFSET, offsetof (struct switch_stack, f28));
- DEFINE(IA64_SWITCH_STACK_F29_OFFSET, offsetof (struct switch_stack, f29));
- DEFINE(IA64_SWITCH_STACK_F30_OFFSET, offsetof (struct switch_stack, f30));
- DEFINE(IA64_SWITCH_STACK_F31_OFFSET, offsetof (struct switch_stack, f31));
- DEFINE(IA64_SWITCH_STACK_R4_OFFSET, offsetof (struct switch_stack, r4));
- DEFINE(IA64_SWITCH_STACK_R5_OFFSET, offsetof (struct switch_stack, r5));
- DEFINE(IA64_SWITCH_STACK_R6_OFFSET, offsetof (struct switch_stack, r6));
- DEFINE(IA64_SWITCH_STACK_R7_OFFSET, offsetof (struct switch_stack, r7));
- DEFINE(IA64_SWITCH_STACK_B0_OFFSET, offsetof (struct switch_stack, b0));
- DEFINE(IA64_SWITCH_STACK_B1_OFFSET, offsetof (struct switch_stack, b1));
- DEFINE(IA64_SWITCH_STACK_B2_OFFSET, offsetof (struct switch_stack, b2));
- DEFINE(IA64_SWITCH_STACK_B3_OFFSET, offsetof (struct switch_stack, b3));
- DEFINE(IA64_SWITCH_STACK_B4_OFFSET, offsetof (struct switch_stack, b4));
- DEFINE(IA64_SWITCH_STACK_B5_OFFSET, offsetof (struct switch_stack, b5));
- DEFINE(IA64_SWITCH_STACK_AR_PFS_OFFSET, offsetof (struct switch_stack, ar_pfs));
- DEFINE(IA64_SWITCH_STACK_AR_LC_OFFSET, offsetof (struct switch_stack, ar_lc));
- DEFINE(IA64_SWITCH_STACK_AR_UNAT_OFFSET, offsetof (struct switch_stack, ar_unat));
- DEFINE(IA64_SWITCH_STACK_AR_RNAT_OFFSET, offsetof (struct switch_stack, ar_rnat));
- DEFINE(IA64_SWITCH_STACK_AR_BSPSTORE_OFFSET, offsetof (struct switch_stack, ar_bspstore));
- DEFINE(IA64_SWITCH_STACK_PR_OFFSET, offsetof (struct switch_stack, pr));
-
- BLANK();
-
- DEFINE(IA64_SIGCONTEXT_IP_OFFSET, offsetof (struct sigcontext, sc_ip));
- DEFINE(IA64_SIGCONTEXT_AR_BSP_OFFSET, offsetof (struct sigcontext, sc_ar_bsp));
- DEFINE(IA64_SIGCONTEXT_AR_FPSR_OFFSET, offsetof (struct sigcontext, sc_ar_fpsr));
- DEFINE(IA64_SIGCONTEXT_AR_RNAT_OFFSET, offsetof (struct sigcontext, sc_ar_rnat));
- DEFINE(IA64_SIGCONTEXT_AR_UNAT_OFFSET, offsetof (struct sigcontext, sc_ar_unat));
- DEFINE(IA64_SIGCONTEXT_B0_OFFSET, offsetof (struct sigcontext, sc_br[0]));
- DEFINE(IA64_SIGCONTEXT_CFM_OFFSET, offsetof (struct sigcontext, sc_cfm));
- DEFINE(IA64_SIGCONTEXT_FLAGS_OFFSET, offsetof (struct sigcontext, sc_flags));
- DEFINE(IA64_SIGCONTEXT_FR6_OFFSET, offsetof (struct sigcontext, sc_fr[6]));
- DEFINE(IA64_SIGCONTEXT_PR_OFFSET, offsetof (struct sigcontext, sc_pr));
- DEFINE(IA64_SIGCONTEXT_R12_OFFSET, offsetof (struct sigcontext, sc_gr[12]));
- DEFINE(IA64_SIGCONTEXT_RBS_BASE_OFFSET,offsetof (struct sigcontext, sc_rbs_base));
- DEFINE(IA64_SIGCONTEXT_LOADRS_OFFSET, offsetof (struct sigcontext, sc_loadrs));
-
- BLANK();
-
- DEFINE(IA64_SIGPENDING_SIGNAL_OFFSET, offsetof (struct sigpending, signal));
-
- BLANK();
-
- DEFINE(IA64_SIGFRAME_ARG0_OFFSET, offsetof (struct sigframe, arg0));
- DEFINE(IA64_SIGFRAME_ARG1_OFFSET, offsetof (struct sigframe, arg1));
- DEFINE(IA64_SIGFRAME_ARG2_OFFSET, offsetof (struct sigframe, arg2));
- DEFINE(IA64_SIGFRAME_HANDLER_OFFSET, offsetof (struct sigframe, handler));
- DEFINE(IA64_SIGFRAME_SIGCONTEXT_OFFSET, offsetof (struct sigframe, sc));
- BLANK();
- /* for assembly files which can't include sched.h: */
- DEFINE(IA64_CLONE_VFORK, CLONE_VFORK);
- DEFINE(IA64_CLONE_VM, CLONE_VM);
-
- BLANK();
- DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET,
- offsetof (struct cpuinfo_ia64, nsec_per_cyc));
- DEFINE(IA64_CPUINFO_PTCE_BASE_OFFSET,
- offsetof (struct cpuinfo_ia64, ptce_base));
- DEFINE(IA64_CPUINFO_PTCE_COUNT_OFFSET,
- offsetof (struct cpuinfo_ia64, ptce_count));
- DEFINE(IA64_CPUINFO_PTCE_STRIDE_OFFSET,
- offsetof (struct cpuinfo_ia64, ptce_stride));
- BLANK();
- DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET,
- offsetof (struct __kernel_old_timespec, tv_nsec));
- DEFINE(IA64_TIME_SN_SPEC_SNSEC_OFFSET,
- offsetof (struct time_sn_spec, snsec));
-
- DEFINE(CLONE_SETTLS_BIT, 19);
-#if CLONE_SETTLS != (1<<19)
-# error "CLONE_SETTLS_BIT incorrect, please fix"
-#endif
-
- BLANK();
- DEFINE(IA64_MCA_CPU_MCA_STACK_OFFSET,
- offsetof (struct ia64_mca_cpu, mca_stack));
- DEFINE(IA64_MCA_CPU_INIT_STACK_OFFSET,
- offsetof (struct ia64_mca_cpu, init_stack));
- BLANK();
- DEFINE(IA64_SAL_OS_STATE_OS_GP_OFFSET,
- offsetof (struct ia64_sal_os_state, os_gp));
- DEFINE(IA64_SAL_OS_STATE_PROC_STATE_PARAM_OFFSET,
- offsetof (struct ia64_sal_os_state, proc_state_param));
- DEFINE(IA64_SAL_OS_STATE_SAL_RA_OFFSET,
- offsetof (struct ia64_sal_os_state, sal_ra));
- DEFINE(IA64_SAL_OS_STATE_SAL_GP_OFFSET,
- offsetof (struct ia64_sal_os_state, sal_gp));
- DEFINE(IA64_SAL_OS_STATE_PAL_MIN_STATE_OFFSET,
- offsetof (struct ia64_sal_os_state, pal_min_state));
- DEFINE(IA64_SAL_OS_STATE_OS_STATUS_OFFSET,
- offsetof (struct ia64_sal_os_state, os_status));
- DEFINE(IA64_SAL_OS_STATE_CONTEXT_OFFSET,
- offsetof (struct ia64_sal_os_state, context));
- DEFINE(IA64_SAL_OS_STATE_SIZE,
- sizeof (struct ia64_sal_os_state));
- BLANK();
-
- DEFINE(IA64_PMSA_GR_OFFSET,
- offsetof(struct pal_min_state_area, pmsa_gr));
- DEFINE(IA64_PMSA_BANK1_GR_OFFSET,
- offsetof(struct pal_min_state_area, pmsa_bank1_gr));
- DEFINE(IA64_PMSA_PR_OFFSET,
- offsetof(struct pal_min_state_area, pmsa_pr));
- DEFINE(IA64_PMSA_BR0_OFFSET,
- offsetof(struct pal_min_state_area, pmsa_br0));
- DEFINE(IA64_PMSA_RSC_OFFSET,
- offsetof(struct pal_min_state_area, pmsa_rsc));
- DEFINE(IA64_PMSA_IIP_OFFSET,
- offsetof(struct pal_min_state_area, pmsa_iip));
- DEFINE(IA64_PMSA_IPSR_OFFSET,
- offsetof(struct pal_min_state_area, pmsa_ipsr));
- DEFINE(IA64_PMSA_IFS_OFFSET,
- offsetof(struct pal_min_state_area, pmsa_ifs));
- DEFINE(IA64_PMSA_XIP_OFFSET,
- offsetof(struct pal_min_state_area, pmsa_xip));
- BLANK();
-
- /* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */
- DEFINE(IA64_GTOD_SEQ_OFFSET,
- offsetof (struct fsyscall_gtod_data_t, seq));
- DEFINE(IA64_GTOD_WALL_TIME_OFFSET,
- offsetof (struct fsyscall_gtod_data_t, wall_time));
- DEFINE(IA64_GTOD_MONO_TIME_OFFSET,
- offsetof (struct fsyscall_gtod_data_t, monotonic_time));
- DEFINE(IA64_CLKSRC_MASK_OFFSET,
- offsetof (struct fsyscall_gtod_data_t, clk_mask));
- DEFINE(IA64_CLKSRC_MULT_OFFSET,
- offsetof (struct fsyscall_gtod_data_t, clk_mult));
- DEFINE(IA64_CLKSRC_SHIFT_OFFSET,
- offsetof (struct fsyscall_gtod_data_t, clk_shift));
- DEFINE(IA64_CLKSRC_MMIO_OFFSET,
- offsetof (struct fsyscall_gtod_data_t, clk_fsys_mmio));
- DEFINE(IA64_CLKSRC_CYCLE_LAST_OFFSET,
- offsetof (struct fsyscall_gtod_data_t, clk_cycle_last));
- DEFINE(IA64_ITC_JITTER_OFFSET,
- offsetof (struct itc_jitter_data_t, itc_jitter));
- DEFINE(IA64_ITC_LASTCYCLE_OFFSET,
- offsetof (struct itc_jitter_data_t, itc_lastcycle));
-
-}
diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c
deleted file mode 100644
index ec61f20ca61f..000000000000
--- a/arch/ia64/kernel/audit.c
+++ /dev/null
@@ -1,63 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/audit.h>
-#include <asm/unistd.h>
-
-static unsigned dir_class[] = {
-#include <asm-generic/audit_dir_write.h>
-~0U
-};
-
-static unsigned read_class[] = {
-#include <asm-generic/audit_read.h>
-~0U
-};
-
-static unsigned write_class[] = {
-#include <asm-generic/audit_write.h>
-~0U
-};
-
-static unsigned chattr_class[] = {
-#include <asm-generic/audit_change_attr.h>
-~0U
-};
-
-static unsigned signal_class[] = {
-#include <asm-generic/audit_signal.h>
-~0U
-};
-
-int audit_classify_arch(int arch)
-{
- return 0;
-}
-
-int audit_classify_syscall(int abi, unsigned syscall)
-{
- switch(syscall) {
- case __NR_open:
- return AUDITSC_OPEN;
- case __NR_openat:
- return AUDITSC_OPENAT;
- case __NR_execve:
- return AUDITSC_EXECVE;
- case __NR_openat2:
- return AUDITSC_OPENAT2;
- default:
- return AUDITSC_NATIVE;
- }
-}
-
-static int __init audit_classes_init(void)
-{
- audit_register_class(AUDIT_CLASS_WRITE, write_class);
- audit_register_class(AUDIT_CLASS_READ, read_class);
- audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
- audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
- audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
- return 0;
-}
-
-__initcall(audit_classes_init);
diff --git a/arch/ia64/kernel/brl_emu.c b/arch/ia64/kernel/brl_emu.c
deleted file mode 100644
index 782c481d7052..000000000000
--- a/arch/ia64/kernel/brl_emu.c
+++ /dev/null
@@ -1,217 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Emulation of the "brl" instruction for IA64 processors that
- * don't support it in hardware.
- * Author: Stephan Zeisset, Intel Corp. <Stephan.Zeisset@intel.com>
- *
- * 02/22/02 D. Mosberger Clear si_flgs, si_isr, and si_imm to avoid
- * leaking kernel bits.
- */
-
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/uaccess.h>
-#include <asm/processor.h>
-
-extern char ia64_set_b1, ia64_set_b2, ia64_set_b3, ia64_set_b4, ia64_set_b5;
-
-struct illegal_op_return {
- unsigned long fkt, arg1, arg2, arg3;
-};
-
-/*
- * The unimplemented bits of a virtual address must be set
- * to the value of the most significant implemented bit.
- * unimpl_va_mask includes all unimplemented bits and
- * the most significant implemented bit, so the result
- * of an and operation with the mask must be all 0's
- * or all 1's for the address to be valid.
- */
-#define unimplemented_virtual_address(va) ( \
- ((va) & local_cpu_data->unimpl_va_mask) != 0 && \
- ((va) & local_cpu_data->unimpl_va_mask) != local_cpu_data->unimpl_va_mask \
-)
-
-/*
- * The unimplemented bits of a physical address must be 0.
- * unimpl_pa_mask includes all unimplemented bits, so the result
- * of an and operation with the mask must be all 0's for the
- * address to be valid.
- */
-#define unimplemented_physical_address(pa) ( \
- ((pa) & local_cpu_data->unimpl_pa_mask) != 0 \
-)
-
-/*
- * Handle an illegal operation fault that was caused by an
- * unimplemented "brl" instruction.
- * If we are not successful (e.g because the illegal operation
- * wasn't caused by a "brl" after all), we return -1.
- * If we are successful, we return either 0 or the address
- * of a "fixup" function for manipulating preserved register
- * state.
- */
-
-struct illegal_op_return
-ia64_emulate_brl (struct pt_regs *regs, unsigned long ar_ec)
-{
- unsigned long bundle[2];
- unsigned long opcode, btype, qp, offset, cpl;
- unsigned long next_ip;
- struct illegal_op_return rv;
- long tmp_taken, unimplemented_address;
-
- rv.fkt = (unsigned long) -1;
-
- /*
- * Decode the instruction bundle.
- */
-
- if (copy_from_user(bundle, (void *) (regs->cr_iip), sizeof(bundle)))
- return rv;
-
- next_ip = (unsigned long) regs->cr_iip + 16;
-
- /* "brl" must be in slot 2. */
- if (ia64_psr(regs)->ri != 1) return rv;
-
- /* Must be "mlx" template */
- if ((bundle[0] & 0x1e) != 0x4) return rv;
-
- opcode = (bundle[1] >> 60);
- btype = ((bundle[1] >> 29) & 0x7);
- qp = ((bundle[1] >> 23) & 0x3f);
- offset = ((bundle[1] & 0x0800000000000000L) << 4)
- | ((bundle[1] & 0x00fffff000000000L) >> 32)
- | ((bundle[1] & 0x00000000007fffffL) << 40)
- | ((bundle[0] & 0xffff000000000000L) >> 24);
-
- tmp_taken = regs->pr & (1L << qp);
-
- switch(opcode) {
-
- case 0xC:
- /*
- * Long Branch.
- */
- if (btype != 0) return rv;
- rv.fkt = 0;
- if (!(tmp_taken)) {
- /*
- * Qualifying predicate is 0.
- * Skip instruction.
- */
- regs->cr_iip = next_ip;
- ia64_psr(regs)->ri = 0;
- return rv;
- }
- break;
-
- case 0xD:
- /*
- * Long Call.
- */
- rv.fkt = 0;
- if (!(tmp_taken)) {
- /*
- * Qualifying predicate is 0.
- * Skip instruction.
- */
- regs->cr_iip = next_ip;
- ia64_psr(regs)->ri = 0;
- return rv;
- }
-
- /*
- * BR[btype] = IP+16
- */
- switch(btype) {
- case 0:
- regs->b0 = next_ip;
- break;
- case 1:
- rv.fkt = (unsigned long) &ia64_set_b1;
- break;
- case 2:
- rv.fkt = (unsigned long) &ia64_set_b2;
- break;
- case 3:
- rv.fkt = (unsigned long) &ia64_set_b3;
- break;
- case 4:
- rv.fkt = (unsigned long) &ia64_set_b4;
- break;
- case 5:
- rv.fkt = (unsigned long) &ia64_set_b5;
- break;
- case 6:
- regs->b6 = next_ip;
- break;
- case 7:
- regs->b7 = next_ip;
- break;
- }
- rv.arg1 = next_ip;
-
- /*
- * AR[PFS].pfm = CFM
- * AR[PFS].pec = AR[EC]
- * AR[PFS].ppl = PSR.cpl
- */
- cpl = ia64_psr(regs)->cpl;
- regs->ar_pfs = ((regs->cr_ifs & 0x3fffffffff)
- | (ar_ec << 52) | (cpl << 62));
-
- /*
- * CFM.sof -= CFM.sol
- * CFM.sol = 0
- * CFM.sor = 0
- * CFM.rrb.gr = 0
- * CFM.rrb.fr = 0
- * CFM.rrb.pr = 0
- */
- regs->cr_ifs = ((regs->cr_ifs & 0xffffffc00000007f)
- - ((regs->cr_ifs >> 7) & 0x7f));
-
- break;
-
- default:
- /*
- * Unknown opcode.
- */
- return rv;
-
- }
-
- regs->cr_iip += offset;
- ia64_psr(regs)->ri = 0;
-
- if (ia64_psr(regs)->it == 0)
- unimplemented_address = unimplemented_physical_address(regs->cr_iip);
- else
- unimplemented_address = unimplemented_virtual_address(regs->cr_iip);
-
- if (unimplemented_address) {
- /*
- * The target address contains unimplemented bits.
- */
- printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n");
- force_sig_fault(SIGILL, ILL_BADIADDR, (void __user *)NULL,
- 0, 0, 0);
- } else if (ia64_psr(regs)->tb) {
- /*
- * Branch Tracing is enabled.
- * Force a taken branch signal.
- */
- force_sig_fault(SIGTRAP, TRAP_BRANCH, (void __user *)NULL,
- 0, 0, 0);
- } else if (ia64_psr(regs)->ss) {
- /*
- * Single Step is enabled.
- * Force a trace signal.
- */
- force_sig_fault(SIGTRAP, TRAP_TRACE, (void __user *)NULL,
- 0, 0, 0);
- }
- return rv;
-}
diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c
deleted file mode 100644
index 88b3ce3e66cd..000000000000
--- a/arch/ia64/kernel/crash.c
+++ /dev/null
@@ -1,257 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * arch/ia64/kernel/crash.c
- *
- * Architecture specific (ia64) functions for kexec based crash dumps.
- *
- * Created by: Khalid Aziz <khalid.aziz@hp.com>
- * Copyright (C) 2005 Hewlett-Packard Development Company, L.P.
- * Copyright (C) 2005 Intel Corp Zou Nan hai <nanhai.zou@intel.com>
- *
- */
-#include <linux/smp.h>
-#include <linux/delay.h>
-#include <linux/crash_dump.h>
-#include <linux/memblock.h>
-#include <linux/kexec.h>
-#include <linux/elfcore.h>
-#include <linux/reboot.h>
-#include <linux/sysctl.h>
-#include <linux/init.h>
-#include <linux/kdebug.h>
-
-#include <asm/mca.h>
-
-int kdump_status[NR_CPUS];
-static atomic_t kdump_cpu_frozen;
-atomic_t kdump_in_progress;
-static int kdump_freeze_monarch;
-static int kdump_on_init = 1;
-static int kdump_on_fatal_mca = 1;
-
-extern void ia64_dump_cpu_regs(void *);
-
-static DEFINE_PER_CPU(struct elf_prstatus, elf_prstatus);
-
-void
-crash_save_this_cpu(void)
-{
- void *buf;
- unsigned long cfm, sof, sol;
-
- int cpu = smp_processor_id();
- struct elf_prstatus *prstatus = &per_cpu(elf_prstatus, cpu);
-
- elf_greg_t *dst = (elf_greg_t *)&(prstatus->pr_reg);
- memset(prstatus, 0, sizeof(*prstatus));
- prstatus->common.pr_pid = current->pid;
-
- ia64_dump_cpu_regs(dst);
- cfm = dst[43];
- sol = (cfm >> 7) & 0x7f;
- sof = cfm & 0x7f;
- dst[46] = (unsigned long)ia64_rse_skip_regs((unsigned long *)dst[46],
- sof - sol);
-
- buf = (u64 *) per_cpu_ptr(crash_notes, cpu);
- if (!buf)
- return;
- buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS, prstatus,
- sizeof(*prstatus));
- final_note(buf);
-}
-
-#ifdef CONFIG_SMP
-static int
-kdump_wait_cpu_freeze(void)
-{
- int cpu_num = num_online_cpus() - 1;
- int timeout = 1000;
- while(timeout-- > 0) {
- if (atomic_read(&kdump_cpu_frozen) == cpu_num)
- return 0;
- udelay(1000);
- }
- return 1;
-}
-#endif
-
-void
-machine_crash_shutdown(struct pt_regs *pt)
-{
- /* This function is only called after the system
- * has paniced or is otherwise in a critical state.
- * The minimum amount of code to allow a kexec'd kernel
- * to run successfully needs to happen here.
- *
- * In practice this means shooting down the other cpus in
- * an SMP system.
- */
- kexec_disable_iosapic();
-#ifdef CONFIG_SMP
- /*
- * If kdump_on_init is set and an INIT is asserted here, kdump will
- * be started again via INIT monarch.
- */
- local_irq_disable();
- ia64_set_psr_mc(); /* mask MCA/INIT */
- if (atomic_inc_return(&kdump_in_progress) != 1)
- unw_init_running(kdump_cpu_freeze, NULL);
-
- /*
- * Now this cpu is ready for kdump.
- * Stop all others by IPI or INIT. They could receive INIT from
- * outside and might be INIT monarch, but only thing they have to
- * do is falling into kdump_cpu_freeze().
- *
- * If an INIT is asserted here:
- * - All receivers might be slaves, since some of cpus could already
- * be frozen and INIT might be masked on monarch. In this case,
- * all slaves will be frozen soon since kdump_in_progress will let
- * them into DIE_INIT_SLAVE_LEAVE.
- * - One might be a monarch, but INIT rendezvous will fail since
- * at least this cpu already have INIT masked so it never join
- * to the rendezvous. In this case, all slaves and monarch will
- * be frozen soon with no wait since the INIT rendezvous is skipped
- * by kdump_in_progress.
- */
- kdump_smp_send_stop();
- /* not all cpu response to IPI, send INIT to freeze them */
- if (kdump_wait_cpu_freeze()) {
- kdump_smp_send_init();
- /* wait again, don't go ahead if possible */
- kdump_wait_cpu_freeze();
- }
-#endif
-}
-
-static void
-machine_kdump_on_init(void)
-{
- crash_save_vmcoreinfo();
- local_irq_disable();
- kexec_disable_iosapic();
- machine_kexec(ia64_kimage);
-}
-
-void
-kdump_cpu_freeze(struct unw_frame_info *info, void *arg)
-{
- int cpuid;
-
- local_irq_disable();
- cpuid = smp_processor_id();
- crash_save_this_cpu();
- current->thread.ksp = (__u64)info->sw - 16;
-
- ia64_set_psr_mc(); /* mask MCA/INIT and stop reentrance */
-
- atomic_inc(&kdump_cpu_frozen);
- kdump_status[cpuid] = 1;
- mb();
- for (;;)
- cpu_relax();
-}
-
-static int
-kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
-{
- struct ia64_mca_notify_die *nd;
- struct die_args *args = data;
-
- if (atomic_read(&kdump_in_progress)) {
- switch (val) {
- case DIE_INIT_MONARCH_LEAVE:
- if (!kdump_freeze_monarch)
- break;
- fallthrough;
- case DIE_INIT_SLAVE_LEAVE:
- case DIE_INIT_MONARCH_ENTER:
- case DIE_MCA_RENDZVOUS_LEAVE:
- unw_init_running(kdump_cpu_freeze, NULL);
- break;
- }
- }
-
- if (!kdump_on_init && !kdump_on_fatal_mca)
- return NOTIFY_DONE;
-
- if (!ia64_kimage) {
- if (val == DIE_INIT_MONARCH_LEAVE)
- ia64_mca_printk(KERN_NOTICE
- "%s: kdump not configured\n",
- __func__);
- return NOTIFY_DONE;
- }
-
- if (val != DIE_INIT_MONARCH_LEAVE &&
- val != DIE_INIT_MONARCH_PROCESS &&
- val != DIE_MCA_MONARCH_LEAVE)
- return NOTIFY_DONE;
-
- nd = (struct ia64_mca_notify_die *)args->err;
-
- switch (val) {
- case DIE_INIT_MONARCH_PROCESS:
- /* Reason code 1 means machine check rendezvous*/
- if (kdump_on_init && (nd->sos->rv_rc != 1)) {
- if (atomic_inc_return(&kdump_in_progress) != 1)
- kdump_freeze_monarch = 1;
- }
- break;
- case DIE_INIT_MONARCH_LEAVE:
- /* Reason code 1 means machine check rendezvous*/
- if (kdump_on_init && (nd->sos->rv_rc != 1))
- machine_kdump_on_init();
- break;
- case DIE_MCA_MONARCH_LEAVE:
- /* *(nd->data) indicate if MCA is recoverable */
- if (kdump_on_fatal_mca && !(*(nd->data))) {
- if (atomic_inc_return(&kdump_in_progress) == 1)
- machine_kdump_on_init();
- /* We got fatal MCA while kdump!? No way!! */
- }
- break;
- }
- return NOTIFY_DONE;
-}
-
-#ifdef CONFIG_SYSCTL
-static struct ctl_table kdump_ctl_table[] = {
- {
- .procname = "kdump_on_init",
- .data = &kdump_on_init,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec,
- },
- {
- .procname = "kdump_on_fatal_mca",
- .data = &kdump_on_fatal_mca,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec,
- },
- { }
-};
-#endif
-
-static int
-machine_crash_setup(void)
-{
- /* be notified before default_monarch_init_process */
- static struct notifier_block kdump_init_notifier_nb = {
- .notifier_call = kdump_init_notifier,
- .priority = 1,
- };
- int ret;
- if((ret = register_die_notifier(&kdump_init_notifier_nb)) != 0)
- return ret;
-#ifdef CONFIG_SYSCTL
- register_sysctl("kernel", kdump_ctl_table);
-#endif
- return 0;
-}
-
-__initcall(machine_crash_setup);
-
diff --git a/arch/ia64/kernel/crash_dump.c b/arch/ia64/kernel/crash_dump.c
deleted file mode 100644
index 4ef68e2aa757..000000000000
--- a/arch/ia64/kernel/crash_dump.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * kernel/crash_dump.c - Memory preserving reboot related code.
- *
- * Created by: Simon Horman <horms@verge.net.au>
- * Original code moved from kernel/crash.c
- * Original code comment copied from the i386 version of this file
- */
-
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/crash_dump.h>
-#include <linux/uio.h>
-#include <asm/page.h>
-
-ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
- size_t csize, unsigned long offset)
-{
- void *vaddr;
-
- if (!csize)
- return 0;
- vaddr = __va(pfn<<PAGE_SHIFT);
- csize = copy_to_iter(vaddr + offset, csize, iter);
- return csize;
-}
-
diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c
deleted file mode 100644
index 258d7b70c0f3..000000000000
--- a/arch/ia64/kernel/cyclone.c
+++ /dev/null
@@ -1,125 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/module.h>
-#include <linux/smp.h>
-#include <linux/time.h>
-#include <linux/errno.h>
-#include <linux/timex.h>
-#include <linux/clocksource.h>
-#include <linux/io.h>
-
-/* IBM Summit (EXA) Cyclone counter code*/
-#define CYCLONE_CBAR_ADDR 0xFEB00CD0
-#define CYCLONE_PMCC_OFFSET 0x51A0
-#define CYCLONE_MPMC_OFFSET 0x51D0
-#define CYCLONE_MPCS_OFFSET 0x51A8
-#define CYCLONE_TIMER_FREQ 100000000
-
-int use_cyclone;
-void __init cyclone_setup(void)
-{
- use_cyclone = 1;
-}
-
-static void __iomem *cyclone_mc;
-
-static u64 read_cyclone(struct clocksource *cs)
-{
- return (u64)readq((void __iomem *)cyclone_mc);
-}
-
-static struct clocksource clocksource_cyclone = {
- .name = "cyclone",
- .rating = 300,
- .read = read_cyclone,
- .mask = (1LL << 40) - 1,
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-int __init init_cyclone_clock(void)
-{
- u64 __iomem *reg;
- u64 base; /* saved cyclone base address */
- u64 offset; /* offset from pageaddr to cyclone_timer register */
- int i;
- u32 __iomem *cyclone_timer; /* Cyclone MPMC0 register */
-
- if (!use_cyclone)
- return 0;
-
- printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n");
-
- /* find base address */
- offset = (CYCLONE_CBAR_ADDR);
- reg = ioremap(offset, sizeof(u64));
- if(!reg){
- printk(KERN_ERR "Summit chipset: Could not find valid CBAR"
- " register.\n");
- use_cyclone = 0;
- return -ENODEV;
- }
- base = readq(reg);
- iounmap(reg);
- if(!base){
- printk(KERN_ERR "Summit chipset: Could not find valid CBAR"
- " value.\n");
- use_cyclone = 0;
- return -ENODEV;
- }
-
- /* setup PMCC */
- offset = (base + CYCLONE_PMCC_OFFSET);
- reg = ioremap(offset, sizeof(u64));
- if(!reg){
- printk(KERN_ERR "Summit chipset: Could not find valid PMCC"
- " register.\n");
- use_cyclone = 0;
- return -ENODEV;
- }
- writel(0x00000001,reg);
- iounmap(reg);
-
- /* setup MPCS */
- offset = (base + CYCLONE_MPCS_OFFSET);
- reg = ioremap(offset, sizeof(u64));
- if(!reg){
- printk(KERN_ERR "Summit chipset: Could not find valid MPCS"
- " register.\n");
- use_cyclone = 0;
- return -ENODEV;
- }
- writel(0x00000001,reg);
- iounmap(reg);
-
- /* map in cyclone_timer */
- offset = (base + CYCLONE_MPMC_OFFSET);
- cyclone_timer = ioremap(offset, sizeof(u32));
- if(!cyclone_timer){
- printk(KERN_ERR "Summit chipset: Could not find valid MPMC"
- " register.\n");
- use_cyclone = 0;
- return -ENODEV;
- }
-
- /*quick test to make sure its ticking*/
- for(i=0; i<3; i++){
- u32 old = readl(cyclone_timer);
- int stall = 100;
- while(stall--) barrier();
- if(readl(cyclone_timer) == old){
- printk(KERN_ERR "Summit chipset: Counter not counting!"
- " DISABLED\n");
- iounmap(cyclone_timer);
- cyclone_timer = NULL;
- use_cyclone = 0;
- return -ENODEV;
- }
- }
- /* initialize last tick */
- cyclone_mc = cyclone_timer;
- clocksource_cyclone.archdata.fsys_mmio = cyclone_timer;
- clocksource_register_hz(&clocksource_cyclone, CYCLONE_TIMER_FREQ);
-
- return 0;
-}
-
-__initcall(init_cyclone_clock);
diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c
deleted file mode 100644
index cd0c166bfbc2..000000000000
--- a/arch/ia64/kernel/dma-mapping.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/dma-map-ops.h>
-#include <linux/export.h>
-
-/* Set this to 1 if there is a HW IOMMU in the system */
-int iommu_detected __read_mostly;
-
-const struct dma_map_ops *dma_ops;
-EXPORT_SYMBOL(dma_ops);
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
deleted file mode 100644
index 033f5aead88a..000000000000
--- a/arch/ia64/kernel/efi.c
+++ /dev/null
@@ -1,1360 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Extensible Firmware Interface
- *
- * Based on Extensible Firmware Interface Specification version 0.9
- * April 30, 1999
- *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999-2003 Hewlett-Packard Co.
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- * (c) Copyright 2006 Hewlett-Packard Development Company, L.P.
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- *
- * All EFI Runtime Services are not implemented yet as EFI only
- * supports physical mode addressing on SoftSDV. This is to be fixed
- * in a future version. --drummond 1999-07-20
- *
- * Implemented EFI runtime services and virtual mode calls. --davidm
- *
- * Goutham Rao: <goutham.rao@intel.com>
- * Skip non-WB memory and ignore empty memory ranges.
- */
-#include <linux/module.h>
-#include <linux/memblock.h>
-#include <linux/crash_dump.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/efi.h>
-#include <linux/kexec.h>
-#include <linux/mm.h>
-
-#include <asm/efi.h>
-#include <asm/io.h>
-#include <asm/kregs.h>
-#include <asm/meminit.h>
-#include <asm/processor.h>
-#include <asm/mca.h>
-#include <asm/sal.h>
-#include <asm/setup.h>
-#include <asm/tlbflush.h>
-
-#define EFI_DEBUG 0
-
-#define ESI_TABLE_GUID \
- EFI_GUID(0x43EA58DC, 0xCF28, 0x4b06, 0xB3, \
- 0x91, 0xB7, 0x50, 0x59, 0x34, 0x2B, 0xD4)
-
-static unsigned long mps_phys = EFI_INVALID_TABLE_ADDR;
-static __initdata unsigned long palo_phys;
-
-unsigned long __initdata esi_phys = EFI_INVALID_TABLE_ADDR;
-unsigned long hcdp_phys = EFI_INVALID_TABLE_ADDR;
-unsigned long sal_systab_phys = EFI_INVALID_TABLE_ADDR;
-
-static const efi_config_table_type_t arch_tables[] __initconst = {
- {ESI_TABLE_GUID, &esi_phys, "ESI" },
- {HCDP_TABLE_GUID, &hcdp_phys, "HCDP" },
- {MPS_TABLE_GUID, &mps_phys, "MPS" },
- {PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID, &palo_phys, "PALO" },
- {SAL_SYSTEM_TABLE_GUID, &sal_systab_phys, "SALsystab" },
- {},
-};
-
-extern efi_status_t efi_call_phys (void *, ...);
-
-static efi_runtime_services_t *runtime;
-static u64 mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL;
-
-#define efi_call_virt(f, args...) (*(f))(args)
-
-#define STUB_GET_TIME(prefix, adjust_arg) \
-static efi_status_t \
-prefix##_get_time (efi_time_t *tm, efi_time_cap_t *tc) \
-{ \
- struct ia64_fpreg fr[6]; \
- efi_time_cap_t *atc = NULL; \
- efi_status_t ret; \
- \
- if (tc) \
- atc = adjust_arg(tc); \
- ia64_save_scratch_fpregs(fr); \
- ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), \
- adjust_arg(tm), atc); \
- ia64_load_scratch_fpregs(fr); \
- return ret; \
-}
-
-#define STUB_SET_TIME(prefix, adjust_arg) \
-static efi_status_t \
-prefix##_set_time (efi_time_t *tm) \
-{ \
- struct ia64_fpreg fr[6]; \
- efi_status_t ret; \
- \
- ia64_save_scratch_fpregs(fr); \
- ret = efi_call_##prefix((efi_set_time_t *) __va(runtime->set_time), \
- adjust_arg(tm)); \
- ia64_load_scratch_fpregs(fr); \
- return ret; \
-}
-
-#define STUB_GET_WAKEUP_TIME(prefix, adjust_arg) \
-static efi_status_t \
-prefix##_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, \
- efi_time_t *tm) \
-{ \
- struct ia64_fpreg fr[6]; \
- efi_status_t ret; \
- \
- ia64_save_scratch_fpregs(fr); \
- ret = efi_call_##prefix( \
- (efi_get_wakeup_time_t *) __va(runtime->get_wakeup_time), \
- adjust_arg(enabled), adjust_arg(pending), adjust_arg(tm)); \
- ia64_load_scratch_fpregs(fr); \
- return ret; \
-}
-
-#define STUB_SET_WAKEUP_TIME(prefix, adjust_arg) \
-static efi_status_t \
-prefix##_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm) \
-{ \
- struct ia64_fpreg fr[6]; \
- efi_time_t *atm = NULL; \
- efi_status_t ret; \
- \
- if (tm) \
- atm = adjust_arg(tm); \
- ia64_save_scratch_fpregs(fr); \
- ret = efi_call_##prefix( \
- (efi_set_wakeup_time_t *) __va(runtime->set_wakeup_time), \
- enabled, atm); \
- ia64_load_scratch_fpregs(fr); \
- return ret; \
-}
-
-#define STUB_GET_VARIABLE(prefix, adjust_arg) \
-static efi_status_t \
-prefix##_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr, \
- unsigned long *data_size, void *data) \
-{ \
- struct ia64_fpreg fr[6]; \
- u32 *aattr = NULL; \
- efi_status_t ret; \
- \
- if (attr) \
- aattr = adjust_arg(attr); \
- ia64_save_scratch_fpregs(fr); \
- ret = efi_call_##prefix( \
- (efi_get_variable_t *) __va(runtime->get_variable), \
- adjust_arg(name), adjust_arg(vendor), aattr, \
- adjust_arg(data_size), adjust_arg(data)); \
- ia64_load_scratch_fpregs(fr); \
- return ret; \
-}
-
-#define STUB_GET_NEXT_VARIABLE(prefix, adjust_arg) \
-static efi_status_t \
-prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, \
- efi_guid_t *vendor) \
-{ \
- struct ia64_fpreg fr[6]; \
- efi_status_t ret; \
- \
- ia64_save_scratch_fpregs(fr); \
- ret = efi_call_##prefix( \
- (efi_get_next_variable_t *) __va(runtime->get_next_variable), \
- adjust_arg(name_size), adjust_arg(name), adjust_arg(vendor)); \
- ia64_load_scratch_fpregs(fr); \
- return ret; \
-}
-
-#define STUB_SET_VARIABLE(prefix, adjust_arg) \
-static efi_status_t \
-prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, \
- u32 attr, unsigned long data_size, \
- void *data) \
-{ \
- struct ia64_fpreg fr[6]; \
- efi_status_t ret; \
- \
- ia64_save_scratch_fpregs(fr); \
- ret = efi_call_##prefix( \
- (efi_set_variable_t *) __va(runtime->set_variable), \
- adjust_arg(name), adjust_arg(vendor), attr, data_size, \
- adjust_arg(data)); \
- ia64_load_scratch_fpregs(fr); \
- return ret; \
-}
-
-#define STUB_GET_NEXT_HIGH_MONO_COUNT(prefix, adjust_arg) \
-static efi_status_t \
-prefix##_get_next_high_mono_count (u32 *count) \
-{ \
- struct ia64_fpreg fr[6]; \
- efi_status_t ret; \
- \
- ia64_save_scratch_fpregs(fr); \
- ret = efi_call_##prefix((efi_get_next_high_mono_count_t *) \
- __va(runtime->get_next_high_mono_count), \
- adjust_arg(count)); \
- ia64_load_scratch_fpregs(fr); \
- return ret; \
-}
-
-#define STUB_RESET_SYSTEM(prefix, adjust_arg) \
-static void \
-prefix##_reset_system (int reset_type, efi_status_t status, \
- unsigned long data_size, efi_char16_t *data) \
-{ \
- struct ia64_fpreg fr[6]; \
- efi_char16_t *adata = NULL; \
- \
- if (data) \
- adata = adjust_arg(data); \
- \
- ia64_save_scratch_fpregs(fr); \
- efi_call_##prefix( \
- (efi_reset_system_t *) __va(runtime->reset_system), \
- reset_type, status, data_size, adata); \
- /* should not return, but just in case... */ \
- ia64_load_scratch_fpregs(fr); \
-}
-
-#define phys_ptr(arg) ((__typeof__(arg)) ia64_tpa(arg))
-
-STUB_GET_TIME(phys, phys_ptr)
-STUB_SET_TIME(phys, phys_ptr)
-STUB_GET_WAKEUP_TIME(phys, phys_ptr)
-STUB_SET_WAKEUP_TIME(phys, phys_ptr)
-STUB_GET_VARIABLE(phys, phys_ptr)
-STUB_GET_NEXT_VARIABLE(phys, phys_ptr)
-STUB_SET_VARIABLE(phys, phys_ptr)
-STUB_GET_NEXT_HIGH_MONO_COUNT(phys, phys_ptr)
-STUB_RESET_SYSTEM(phys, phys_ptr)
-
-#define id(arg) arg
-
-STUB_GET_TIME(virt, id)
-STUB_SET_TIME(virt, id)
-STUB_GET_WAKEUP_TIME(virt, id)
-STUB_SET_WAKEUP_TIME(virt, id)
-STUB_GET_VARIABLE(virt, id)
-STUB_GET_NEXT_VARIABLE(virt, id)
-STUB_SET_VARIABLE(virt, id)
-STUB_GET_NEXT_HIGH_MONO_COUNT(virt, id)
-STUB_RESET_SYSTEM(virt, id)
-
-void
-efi_gettimeofday (struct timespec64 *ts)
-{
- efi_time_t tm;
-
- if ((*efi.get_time)(&tm, NULL) != EFI_SUCCESS) {
- memset(ts, 0, sizeof(*ts));
- return;
- }
-
- ts->tv_sec = mktime64(tm.year, tm.month, tm.day,
- tm.hour, tm.minute, tm.second);
- ts->tv_nsec = tm.nanosecond;
-}
-
-static int
-is_memory_available (efi_memory_desc_t *md)
-{
- if (!(md->attribute & EFI_MEMORY_WB))
- return 0;
-
- switch (md->type) {
- case EFI_LOADER_CODE:
- case EFI_LOADER_DATA:
- case EFI_BOOT_SERVICES_CODE:
- case EFI_BOOT_SERVICES_DATA:
- case EFI_CONVENTIONAL_MEMORY:
- return 1;
- }
- return 0;
-}
-
-typedef struct kern_memdesc {
- u64 attribute;
- u64 start;
- u64 num_pages;
-} kern_memdesc_t;
-
-static kern_memdesc_t *kern_memmap;
-
-#define efi_md_size(md) (md->num_pages << EFI_PAGE_SHIFT)
-
-static inline u64
-kmd_end(kern_memdesc_t *kmd)
-{
- return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT));
-}
-
-static inline u64
-efi_md_end(efi_memory_desc_t *md)
-{
- return (md->phys_addr + efi_md_size(md));
-}
-
-static inline int
-efi_wb(efi_memory_desc_t *md)
-{
- return (md->attribute & EFI_MEMORY_WB);
-}
-
-static inline int
-efi_uc(efi_memory_desc_t *md)
-{
- return (md->attribute & EFI_MEMORY_UC);
-}
-
-static void
-walk (efi_freemem_callback_t callback, void *arg, u64 attr)
-{
- kern_memdesc_t *k;
- u64 start, end, voff;
-
- voff = (attr == EFI_MEMORY_WB) ? PAGE_OFFSET : __IA64_UNCACHED_OFFSET;
- for (k = kern_memmap; k->start != ~0UL; k++) {
- if (k->attribute != attr)
- continue;
- start = PAGE_ALIGN(k->start);
- end = (k->start + (k->num_pages << EFI_PAGE_SHIFT)) & PAGE_MASK;
- if (start < end)
- if ((*callback)(start + voff, end + voff, arg) < 0)
- return;
- }
-}
-
-/*
- * Walk the EFI memory map and call CALLBACK once for each EFI memory
- * descriptor that has memory that is available for OS use.
- */
-void
-efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
-{
- walk(callback, arg, EFI_MEMORY_WB);
-}
-
-/*
- * Walk the EFI memory map and call CALLBACK once for each EFI memory
- * descriptor that has memory that is available for uncached allocator.
- */
-void
-efi_memmap_walk_uc (efi_freemem_callback_t callback, void *arg)
-{
- walk(callback, arg, EFI_MEMORY_UC);
-}
-
-/*
- * Look for the PAL_CODE region reported by EFI and map it using an
- * ITR to enable safe PAL calls in virtual mode. See IA-64 Processor
- * Abstraction Layer chapter 11 in ADAG
- */
-void *
-efi_get_pal_addr (void)
-{
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- u64 efi_desc_size;
- int pal_code_count = 0;
- u64 vaddr, mask;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
- if (md->type != EFI_PAL_CODE)
- continue;
-
- if (++pal_code_count > 1) {
- printk(KERN_ERR "Too many EFI Pal Code memory ranges, "
- "dropped @ %llx\n", md->phys_addr);
- continue;
- }
- /*
- * The only ITLB entry in region 7 that is used is the one
- * installed by __start(). That entry covers a 64MB range.
- */
- mask = ~((1 << KERNEL_TR_PAGE_SHIFT) - 1);
- vaddr = PAGE_OFFSET + md->phys_addr;
-
- /*
- * We must check that the PAL mapping won't overlap with the
- * kernel mapping.
- *
- * PAL code is guaranteed to be aligned on a power of 2 between
- * 4k and 256KB and that only one ITR is needed to map it. This
- * implies that the PAL code is always aligned on its size,
- * i.e., the closest matching page size supported by the TLB.
- * Therefore PAL code is guaranteed never to cross a 64MB unless
- * it is bigger than 64MB (very unlikely!). So for now the
- * following test is enough to determine whether or not we need
- * a dedicated ITR for the PAL code.
- */
- if ((vaddr & mask) == (KERNEL_START & mask)) {
- printk(KERN_INFO "%s: no need to install ITR for PAL code\n",
- __func__);
- continue;
- }
-
- if (efi_md_size(md) > IA64_GRANULE_SIZE)
- panic("Whoa! PAL code size bigger than a granule!");
-
-#if EFI_DEBUG
- mask = ~((1 << IA64_GRANULE_SHIFT) - 1);
-
- printk(KERN_INFO "CPU %d: mapping PAL code "
- "[0x%llx-0x%llx) into [0x%llx-0x%llx)\n",
- smp_processor_id(), md->phys_addr,
- md->phys_addr + efi_md_size(md),
- vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
-#endif
- return __va(md->phys_addr);
- }
- printk(KERN_WARNING "%s: no PAL-code memory-descriptor found\n",
- __func__);
- return NULL;
-}
-
-
-static u8 __init palo_checksum(u8 *buffer, u32 length)
-{
- u8 sum = 0;
- u8 *end = buffer + length;
-
- while (buffer < end)
- sum = (u8) (sum + *(buffer++));
-
- return sum;
-}
-
-/*
- * Parse and handle PALO table which is published at:
- * http://www.dig64.org/home/DIG64_PALO_R1_0.pdf
- */
-static void __init handle_palo(unsigned long phys_addr)
-{
- struct palo_table *palo = __va(phys_addr);
- u8 checksum;
-
- if (strncmp(palo->signature, PALO_SIG, sizeof(PALO_SIG) - 1)) {
- printk(KERN_INFO "PALO signature incorrect.\n");
- return;
- }
-
- checksum = palo_checksum((u8 *)palo, palo->length);
- if (checksum) {
- printk(KERN_INFO "PALO checksum incorrect.\n");
- return;
- }
-
- setup_ptcg_sem(palo->max_tlb_purges, NPTCG_FROM_PALO);
-}
-
-void
-efi_map_pal_code (void)
-{
- void *pal_vaddr = efi_get_pal_addr ();
- u64 psr;
-
- if (!pal_vaddr)
- return;
-
- /*
- * Cannot write to CRx with PSR.ic=1
- */
- psr = ia64_clear_ic();
- ia64_itr(0x1, IA64_TR_PALCODE,
- GRANULEROUNDDOWN((unsigned long) pal_vaddr),
- pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)),
- IA64_GRANULE_SHIFT);
- ia64_set_psr(psr); /* restore psr */
-}
-
-void __init
-efi_init (void)
-{
- const efi_system_table_t *efi_systab;
- void *efi_map_start, *efi_map_end;
- u64 efi_desc_size;
- char *cp;
-
- set_bit(EFI_BOOT, &efi.flags);
- set_bit(EFI_64BIT, &efi.flags);
-
- /*
- * It's too early to be able to use the standard kernel command line
- * support...
- */
- for (cp = boot_command_line; *cp; ) {
- if (memcmp(cp, "mem=", 4) == 0) {
- mem_limit = memparse(cp + 4, &cp);
- } else if (memcmp(cp, "max_addr=", 9) == 0) {
- max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
- } else if (memcmp(cp, "min_addr=", 9) == 0) {
- min_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
- } else {
- while (*cp != ' ' && *cp)
- ++cp;
- while (*cp == ' ')
- ++cp;
- }
- }
- if (min_addr != 0UL)
- printk(KERN_INFO "Ignoring memory below %lluMB\n",
- min_addr >> 20);
- if (max_addr != ~0UL)
- printk(KERN_INFO "Ignoring memory above %lluMB\n",
- max_addr >> 20);
-
- efi_systab = __va(ia64_boot_param->efi_systab);
-
- /*
- * Verify the EFI Table
- */
- if (efi_systab == NULL)
- panic("Whoa! Can't find EFI system table.\n");
- if (efi_systab_check_header(&efi_systab->hdr))
- panic("Whoa! EFI system table signature incorrect\n");
-
- efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor);
-
- palo_phys = EFI_INVALID_TABLE_ADDR;
-
- if (efi_config_parse_tables(__va(efi_systab->tables),
- efi_systab->nr_tables,
- arch_tables) != 0)
- return;
-
- if (palo_phys != EFI_INVALID_TABLE_ADDR)
- handle_palo(palo_phys);
-
- runtime = __va(efi_systab->runtime);
- efi.get_time = phys_get_time;
- efi.set_time = phys_set_time;
- efi.get_wakeup_time = phys_get_wakeup_time;
- efi.set_wakeup_time = phys_set_wakeup_time;
- efi.get_variable = phys_get_variable;
- efi.get_next_variable = phys_get_next_variable;
- efi.set_variable = phys_set_variable;
- efi.get_next_high_mono_count = phys_get_next_high_mono_count;
- efi.reset_system = phys_reset_system;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
-#if EFI_DEBUG
- /* print EFI memory map: */
- {
- efi_memory_desc_t *md;
- void *p;
- unsigned int i;
-
- for (i = 0, p = efi_map_start; p < efi_map_end;
- ++i, p += efi_desc_size)
- {
- const char *unit;
- unsigned long size;
- char buf[64];
-
- md = p;
- size = md->num_pages << EFI_PAGE_SHIFT;
-
- if ((size >> 40) > 0) {
- size >>= 40;
- unit = "TB";
- } else if ((size >> 30) > 0) {
- size >>= 30;
- unit = "GB";
- } else if ((size >> 20) > 0) {
- size >>= 20;
- unit = "MB";
- } else {
- size >>= 10;
- unit = "KB";
- }
-
- printk("mem%02d: %s "
- "range=[0x%016llx-0x%016llx) (%4lu%s)\n",
- i, efi_md_typeattr_format(buf, sizeof(buf), md),
- md->phys_addr,
- md->phys_addr + efi_md_size(md), size, unit);
- }
- }
-#endif
-
- efi_map_pal_code();
- efi_enter_virtual_mode();
-}
-
-void
-efi_enter_virtual_mode (void)
-{
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- efi_status_t status;
- u64 efi_desc_size;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
- if (md->attribute & EFI_MEMORY_RUNTIME) {
- /*
- * Some descriptors have multiple bits set, so the
- * order of the tests is relevant.
- */
- if (md->attribute & EFI_MEMORY_WB) {
- md->virt_addr = (u64) __va(md->phys_addr);
- } else if (md->attribute & EFI_MEMORY_UC) {
- md->virt_addr = (u64) ioremap(md->phys_addr, 0);
- } else if (md->attribute & EFI_MEMORY_WC) {
-#if 0
- md->virt_addr = ia64_remap(md->phys_addr,
- (_PAGE_A |
- _PAGE_P |
- _PAGE_D |
- _PAGE_MA_WC |
- _PAGE_PL_0 |
- _PAGE_AR_RW));
-#else
- printk(KERN_INFO "EFI_MEMORY_WC mapping\n");
- md->virt_addr = (u64) ioremap(md->phys_addr, 0);
-#endif
- } else if (md->attribute & EFI_MEMORY_WT) {
-#if 0
- md->virt_addr = ia64_remap(md->phys_addr,
- (_PAGE_A |
- _PAGE_P |
- _PAGE_D |
- _PAGE_MA_WT |
- _PAGE_PL_0 |
- _PAGE_AR_RW));
-#else
- printk(KERN_INFO "EFI_MEMORY_WT mapping\n");
- md->virt_addr = (u64) ioremap(md->phys_addr, 0);
-#endif
- }
- }
- }
-
- status = efi_call_phys(__va(runtime->set_virtual_address_map),
- ia64_boot_param->efi_memmap_size,
- efi_desc_size,
- ia64_boot_param->efi_memdesc_version,
- ia64_boot_param->efi_memmap);
- if (status != EFI_SUCCESS) {
- printk(KERN_WARNING "warning: unable to switch EFI into "
- "virtual mode (status=%lu)\n", status);
- return;
- }
-
- set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
-
- /*
- * Now that EFI is in virtual mode, we call the EFI functions more
- * efficiently:
- */
- efi.get_time = virt_get_time;
- efi.set_time = virt_set_time;
- efi.get_wakeup_time = virt_get_wakeup_time;
- efi.set_wakeup_time = virt_set_wakeup_time;
- efi.get_variable = virt_get_variable;
- efi.get_next_variable = virt_get_next_variable;
- efi.set_variable = virt_set_variable;
- efi.get_next_high_mono_count = virt_get_next_high_mono_count;
- efi.reset_system = virt_reset_system;
-}
-
-/*
- * Walk the EFI memory map looking for the I/O port range. There can only be
- * one entry of this type, other I/O port ranges should be described via ACPI.
- */
-u64
-efi_get_iobase (void)
-{
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- u64 efi_desc_size;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
- if (md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {
- if (md->attribute & EFI_MEMORY_UC)
- return md->phys_addr;
- }
- }
- return 0;
-}
-
-static struct kern_memdesc *
-kern_memory_descriptor (unsigned long phys_addr)
-{
- struct kern_memdesc *md;
-
- for (md = kern_memmap; md->start != ~0UL; md++) {
- if (phys_addr - md->start < (md->num_pages << EFI_PAGE_SHIFT))
- return md;
- }
- return NULL;
-}
-
-static efi_memory_desc_t *
-efi_memory_descriptor (unsigned long phys_addr)
-{
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- u64 efi_desc_size;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
-
- if (phys_addr - md->phys_addr < efi_md_size(md))
- return md;
- }
- return NULL;
-}
-
-static int
-efi_memmap_intersects (unsigned long phys_addr, unsigned long size)
-{
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- u64 efi_desc_size;
- unsigned long end;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- end = phys_addr + size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
- if (md->phys_addr < end && efi_md_end(md) > phys_addr)
- return 1;
- }
- return 0;
-}
-
-int
-efi_mem_type (unsigned long phys_addr)
-{
- efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);
-
- if (md)
- return md->type;
- return -EINVAL;
-}
-
-u64
-efi_mem_attributes (unsigned long phys_addr)
-{
- efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);
-
- if (md)
- return md->attribute;
- return 0;
-}
-EXPORT_SYMBOL(efi_mem_attributes);
-
-u64
-efi_mem_attribute (unsigned long phys_addr, unsigned long size)
-{
- unsigned long end = phys_addr + size;
- efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);
- u64 attr;
-
- if (!md)
- return 0;
-
- /*
- * EFI_MEMORY_RUNTIME is not a memory attribute; it just tells
- * the kernel that firmware needs this region mapped.
- */
- attr = md->attribute & ~EFI_MEMORY_RUNTIME;
- do {
- unsigned long md_end = efi_md_end(md);
-
- if (end <= md_end)
- return attr;
-
- md = efi_memory_descriptor(md_end);
- if (!md || (md->attribute & ~EFI_MEMORY_RUNTIME) != attr)
- return 0;
- } while (md);
- return 0; /* never reached */
-}
-
-u64
-kern_mem_attribute (unsigned long phys_addr, unsigned long size)
-{
- unsigned long end = phys_addr + size;
- struct kern_memdesc *md;
- u64 attr;
-
- /*
- * This is a hack for ioremap calls before we set up kern_memmap.
- * Maybe we should do efi_memmap_init() earlier instead.
- */
- if (!kern_memmap) {
- attr = efi_mem_attribute(phys_addr, size);
- if (attr & EFI_MEMORY_WB)
- return EFI_MEMORY_WB;
- return 0;
- }
-
- md = kern_memory_descriptor(phys_addr);
- if (!md)
- return 0;
-
- attr = md->attribute;
- do {
- unsigned long md_end = kmd_end(md);
-
- if (end <= md_end)
- return attr;
-
- md = kern_memory_descriptor(md_end);
- if (!md || md->attribute != attr)
- return 0;
- } while (md);
- return 0; /* never reached */
-}
-
-int
-valid_phys_addr_range (phys_addr_t phys_addr, unsigned long size)
-{
- u64 attr;
-
- /*
- * /dev/mem reads and writes use copy_to_user(), which implicitly
- * uses a granule-sized kernel identity mapping. It's really
- * only safe to do this for regions in kern_memmap. For more
- * details, see Documentation/arch/ia64/aliasing.rst.
- */
- attr = kern_mem_attribute(phys_addr, size);
- if (attr & EFI_MEMORY_WB || attr & EFI_MEMORY_UC)
- return 1;
- return 0;
-}
-
-int
-valid_mmap_phys_addr_range (unsigned long pfn, unsigned long size)
-{
- unsigned long phys_addr = pfn << PAGE_SHIFT;
- u64 attr;
-
- attr = efi_mem_attribute(phys_addr, size);
-
- /*
- * /dev/mem mmap uses normal user pages, so we don't need the entire
- * granule, but the entire region we're mapping must support the same
- * attribute.
- */
- if (attr & EFI_MEMORY_WB || attr & EFI_MEMORY_UC)
- return 1;
-
- /*
- * Intel firmware doesn't tell us about all the MMIO regions, so
- * in general we have to allow mmap requests. But if EFI *does*
- * tell us about anything inside this region, we should deny it.
- * The user can always map a smaller region to avoid the overlap.
- */
- if (efi_memmap_intersects(phys_addr, size))
- return 0;
-
- return 1;
-}
-
-pgprot_t
-phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size,
- pgprot_t vma_prot)
-{
- unsigned long phys_addr = pfn << PAGE_SHIFT;
- u64 attr;
-
- /*
- * For /dev/mem mmap, we use user mappings, but if the region is
- * in kern_memmap (and hence may be covered by a kernel mapping),
- * we must use the same attribute as the kernel mapping.
- */
- attr = kern_mem_attribute(phys_addr, size);
- if (attr & EFI_MEMORY_WB)
- return pgprot_cacheable(vma_prot);
- else if (attr & EFI_MEMORY_UC)
- return pgprot_noncached(vma_prot);
-
- /*
- * Some chipsets don't support UC access to memory. If
- * WB is supported, we prefer that.
- */
- if (efi_mem_attribute(phys_addr, size) & EFI_MEMORY_WB)
- return pgprot_cacheable(vma_prot);
-
- return pgprot_noncached(vma_prot);
-}
-
-int __init
-efi_uart_console_only(void)
-{
- efi_status_t status;
- char *s, name[] = "ConOut";
- efi_guid_t guid = EFI_GLOBAL_VARIABLE_GUID;
- efi_char16_t *utf16, name_utf16[32];
- unsigned char data[1024];
- unsigned long size = sizeof(data);
- struct efi_generic_dev_path *hdr, *end_addr;
- int uart = 0;
-
- /* Convert to UTF-16 */
- utf16 = name_utf16;
- s = name;
- while (*s)
- *utf16++ = *s++ & 0x7f;
- *utf16 = 0;
-
- status = efi.get_variable(name_utf16, &guid, NULL, &size, data);
- if (status != EFI_SUCCESS) {
- printk(KERN_ERR "No EFI %s variable?\n", name);
- return 0;
- }
-
- hdr = (struct efi_generic_dev_path *) data;
- end_addr = (struct efi_generic_dev_path *) ((u8 *) data + size);
- while (hdr < end_addr) {
- if (hdr->type == EFI_DEV_MSG &&
- hdr->sub_type == EFI_DEV_MSG_UART)
- uart = 1;
- else if (hdr->type == EFI_DEV_END_PATH ||
- hdr->type == EFI_DEV_END_PATH2) {
- if (!uart)
- return 0;
- if (hdr->sub_type == EFI_DEV_END_ENTIRE)
- return 1;
- uart = 0;
- }
- hdr = (struct efi_generic_dev_path *)((u8 *) hdr + hdr->length);
- }
- printk(KERN_ERR "Malformed %s value\n", name);
- return 0;
-}
-
-/*
- * Look for the first granule aligned memory descriptor memory
- * that is big enough to hold EFI memory map. Make sure this
- * descriptor is at least granule sized so it does not get trimmed
- */
-struct kern_memdesc *
-find_memmap_space (void)
-{
- u64 contig_low=0, contig_high=0;
- u64 as = 0, ae;
- void *efi_map_start, *efi_map_end, *p, *q;
- efi_memory_desc_t *md, *pmd = NULL, *check_md;
- u64 space_needed, efi_desc_size;
- unsigned long total_mem = 0;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- /*
- * Worst case: we need 3 kernel descriptors for each efi descriptor
- * (if every entry has a WB part in the middle, and UC head and tail),
- * plus one for the end marker.
- */
- space_needed = sizeof(kern_memdesc_t) *
- (3 * (ia64_boot_param->efi_memmap_size/efi_desc_size) + 1);
-
- for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) {
- md = p;
- if (!efi_wb(md)) {
- continue;
- }
- if (pmd == NULL || !efi_wb(pmd) ||
- efi_md_end(pmd) != md->phys_addr) {
- contig_low = GRANULEROUNDUP(md->phys_addr);
- contig_high = efi_md_end(md);
- for (q = p + efi_desc_size; q < efi_map_end;
- q += efi_desc_size) {
- check_md = q;
- if (!efi_wb(check_md))
- break;
- if (contig_high != check_md->phys_addr)
- break;
- contig_high = efi_md_end(check_md);
- }
- contig_high = GRANULEROUNDDOWN(contig_high);
- }
- if (!is_memory_available(md) || md->type == EFI_LOADER_DATA)
- continue;
-
- /* Round ends inward to granule boundaries */
- as = max(contig_low, md->phys_addr);
- ae = min(contig_high, efi_md_end(md));
-
- /* keep within max_addr= and min_addr= command line arg */
- as = max(as, min_addr);
- ae = min(ae, max_addr);
- if (ae <= as)
- continue;
-
- /* avoid going over mem= command line arg */
- if (total_mem + (ae - as) > mem_limit)
- ae -= total_mem + (ae - as) - mem_limit;
-
- if (ae <= as)
- continue;
-
- if (ae - as > space_needed)
- break;
- }
- if (p >= efi_map_end)
- panic("Can't allocate space for kernel memory descriptors");
-
- return __va(as);
-}
-
-/*
- * Walk the EFI memory map and gather all memory available for kernel
- * to use. We can allocate partial granules only if the unavailable
- * parts exist, and are WB.
- */
-unsigned long
-efi_memmap_init(u64 *s, u64 *e)
-{
- struct kern_memdesc *k, *prev = NULL;
- u64 contig_low=0, contig_high=0;
- u64 as, ae, lim;
- void *efi_map_start, *efi_map_end, *p, *q;
- efi_memory_desc_t *md, *pmd = NULL, *check_md;
- u64 efi_desc_size;
- unsigned long total_mem = 0;
-
- k = kern_memmap = find_memmap_space();
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) {
- md = p;
- if (!efi_wb(md)) {
- if (efi_uc(md) &&
- (md->type == EFI_CONVENTIONAL_MEMORY ||
- md->type == EFI_BOOT_SERVICES_DATA)) {
- k->attribute = EFI_MEMORY_UC;
- k->start = md->phys_addr;
- k->num_pages = md->num_pages;
- k++;
- }
- continue;
- }
- if (pmd == NULL || !efi_wb(pmd) ||
- efi_md_end(pmd) != md->phys_addr) {
- contig_low = GRANULEROUNDUP(md->phys_addr);
- contig_high = efi_md_end(md);
- for (q = p + efi_desc_size; q < efi_map_end;
- q += efi_desc_size) {
- check_md = q;
- if (!efi_wb(check_md))
- break;
- if (contig_high != check_md->phys_addr)
- break;
- contig_high = efi_md_end(check_md);
- }
- contig_high = GRANULEROUNDDOWN(contig_high);
- }
- if (!is_memory_available(md))
- continue;
-
- /*
- * Round ends inward to granule boundaries
- * Give trimmings to uncached allocator
- */
- if (md->phys_addr < contig_low) {
- lim = min(efi_md_end(md), contig_low);
- if (efi_uc(md)) {
- if (k > kern_memmap &&
- (k-1)->attribute == EFI_MEMORY_UC &&
- kmd_end(k-1) == md->phys_addr) {
- (k-1)->num_pages +=
- (lim - md->phys_addr)
- >> EFI_PAGE_SHIFT;
- } else {
- k->attribute = EFI_MEMORY_UC;
- k->start = md->phys_addr;
- k->num_pages = (lim - md->phys_addr)
- >> EFI_PAGE_SHIFT;
- k++;
- }
- }
- as = contig_low;
- } else
- as = md->phys_addr;
-
- if (efi_md_end(md) > contig_high) {
- lim = max(md->phys_addr, contig_high);
- if (efi_uc(md)) {
- if (lim == md->phys_addr && k > kern_memmap &&
- (k-1)->attribute == EFI_MEMORY_UC &&
- kmd_end(k-1) == md->phys_addr) {
- (k-1)->num_pages += md->num_pages;
- } else {
- k->attribute = EFI_MEMORY_UC;
- k->start = lim;
- k->num_pages = (efi_md_end(md) - lim)
- >> EFI_PAGE_SHIFT;
- k++;
- }
- }
- ae = contig_high;
- } else
- ae = efi_md_end(md);
-
- /* keep within max_addr= and min_addr= command line arg */
- as = max(as, min_addr);
- ae = min(ae, max_addr);
- if (ae <= as)
- continue;
-
- /* avoid going over mem= command line arg */
- if (total_mem + (ae - as) > mem_limit)
- ae -= total_mem + (ae - as) - mem_limit;
-
- if (ae <= as)
- continue;
- if (prev && kmd_end(prev) == md->phys_addr) {
- prev->num_pages += (ae - as) >> EFI_PAGE_SHIFT;
- total_mem += ae - as;
- continue;
- }
- k->attribute = EFI_MEMORY_WB;
- k->start = as;
- k->num_pages = (ae - as) >> EFI_PAGE_SHIFT;
- total_mem += ae - as;
- prev = k++;
- }
- k->start = ~0L; /* end-marker */
-
- /* reserve the memory we are using for kern_memmap */
- *s = (u64)kern_memmap;
- *e = (u64)++k;
-
- return total_mem;
-}
-
-void
-efi_initialize_iomem_resources(struct resource *code_resource,
- struct resource *data_resource,
- struct resource *bss_resource)
-{
- struct resource *res;
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- u64 efi_desc_size;
- char *name;
- unsigned long flags, desc;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- res = NULL;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
-
- if (md->num_pages == 0) /* should not happen */
- continue;
-
- flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- desc = IORES_DESC_NONE;
-
- switch (md->type) {
-
- case EFI_MEMORY_MAPPED_IO:
- case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
- continue;
-
- case EFI_LOADER_CODE:
- case EFI_LOADER_DATA:
- case EFI_BOOT_SERVICES_DATA:
- case EFI_BOOT_SERVICES_CODE:
- case EFI_CONVENTIONAL_MEMORY:
- if (md->attribute & EFI_MEMORY_WP) {
- name = "System ROM";
- flags |= IORESOURCE_READONLY;
- } else if (md->attribute == EFI_MEMORY_UC) {
- name = "Uncached RAM";
- } else {
- name = "System RAM";
- flags |= IORESOURCE_SYSRAM;
- }
- break;
-
- case EFI_ACPI_MEMORY_NVS:
- name = "ACPI Non-volatile Storage";
- desc = IORES_DESC_ACPI_NV_STORAGE;
- break;
-
- case EFI_UNUSABLE_MEMORY:
- name = "reserved";
- flags |= IORESOURCE_DISABLED;
- break;
-
- case EFI_PERSISTENT_MEMORY:
- name = "Persistent Memory";
- desc = IORES_DESC_PERSISTENT_MEMORY;
- break;
-
- case EFI_RESERVED_TYPE:
- case EFI_RUNTIME_SERVICES_CODE:
- case EFI_RUNTIME_SERVICES_DATA:
- case EFI_ACPI_RECLAIM_MEMORY:
- default:
- name = "reserved";
- break;
- }
-
- if ((res = kzalloc(sizeof(struct resource),
- GFP_KERNEL)) == NULL) {
- printk(KERN_ERR
- "failed to allocate resource for iomem\n");
- return;
- }
-
- res->name = name;
- res->start = md->phys_addr;
- res->end = md->phys_addr + efi_md_size(md) - 1;
- res->flags = flags;
- res->desc = desc;
-
- if (insert_resource(&iomem_resource, res) < 0)
- kfree(res);
- else {
- /*
- * We don't know which region contains
- * kernel data so we try it repeatedly and
- * let the resource manager test it.
- */
- insert_resource(res, code_resource);
- insert_resource(res, data_resource);
- insert_resource(res, bss_resource);
-#ifdef CONFIG_KEXEC
- insert_resource(res, &efi_memmap_res);
- insert_resource(res, &boot_param_res);
- if (crashk_res.end > crashk_res.start)
- insert_resource(res, &crashk_res);
-#endif
- }
- }
-}
-
-#ifdef CONFIG_KEXEC
-/* find a block of memory aligned to 64M exclude reserved regions
- rsvd_regions are sorted
- */
-unsigned long __init
-kdump_find_rsvd_region (unsigned long size, struct rsvd_region *r, int n)
-{
- int i;
- u64 start, end;
- u64 alignment = 1UL << _PAGE_SIZE_64M;
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- u64 efi_desc_size;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
- if (!efi_wb(md))
- continue;
- start = ALIGN(md->phys_addr, alignment);
- end = efi_md_end(md);
- for (i = 0; i < n; i++) {
- if (__pa(r[i].start) >= start && __pa(r[i].end) < end) {
- if (__pa(r[i].start) > start + size)
- return start;
- start = ALIGN(__pa(r[i].end), alignment);
- if (i < n-1 &&
- __pa(r[i+1].start) < start + size)
- continue;
- else
- break;
- }
- }
- if (end > start + size)
- return start;
- }
-
- printk(KERN_WARNING
- "Cannot reserve 0x%lx byte of memory for crashdump\n", size);
- return ~0UL;
-}
-#endif
-
-#ifdef CONFIG_CRASH_DUMP
-/* locate the size find a the descriptor at a certain address */
-unsigned long __init
-vmcore_find_descriptor_size (unsigned long address)
-{
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- u64 efi_desc_size;
- unsigned long ret = 0;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
- if (efi_wb(md) && md->type == EFI_LOADER_DATA
- && md->phys_addr == address) {
- ret = efi_md_size(md);
- break;
- }
- }
-
- if (ret == 0)
- printk(KERN_WARNING "Cannot locate EFI vmcore descriptor\n");
-
- return ret;
-}
-#endif
-
-char *efi_systab_show_arch(char *str)
-{
- if (mps_phys != EFI_INVALID_TABLE_ADDR)
- str += sprintf(str, "MPS=0x%lx\n", mps_phys);
- if (hcdp_phys != EFI_INVALID_TABLE_ADDR)
- str += sprintf(str, "HCDP=0x%lx\n", hcdp_phys);
- return str;
-}
diff --git a/arch/ia64/kernel/efi_stub.S b/arch/ia64/kernel/efi_stub.S
deleted file mode 100644
index 1fd61b78fb29..000000000000
--- a/arch/ia64/kernel/efi_stub.S
+++ /dev/null
@@ -1,87 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * EFI call stub.
- *
- * Copyright (C) 1999-2001 Hewlett-Packard Co
- * David Mosberger <davidm@hpl.hp.com>
- *
- * This stub allows us to make EFI calls in physical mode with interrupts
- * turned off. We need this because we can't call SetVirtualMap() until
- * the kernel has booted far enough to allow allocation of struct vm_area_struct
- * entries (which we would need to map stuff with memory attributes other
- * than uncached or writeback...). Since the GetTime() service gets called
- * earlier than that, we need to be able to make physical mode EFI calls from
- * the kernel.
- */
-
-/*
- * PSR settings as per SAL spec (Chapter 8 in the "IA-64 System
- * Abstraction Layer Specification", revision 2.6e). Note that
- * psr.dfl and psr.dfh MUST be cleared, despite what this manual says.
- * Otherwise, SAL dies whenever it's trying to do an IA-32 BIOS call
- * (the br.ia instruction fails unless psr.dfl and psr.dfh are
- * cleared). Fortunately, SAL promises not to touch the floating
- * point regs, so at least we don't have to save f2-f127.
- */
-#define PSR_BITS_TO_CLEAR \
- (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT | \
- IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \
- IA64_PSR_DFL | IA64_PSR_DFH)
-
-#define PSR_BITS_TO_SET \
- (IA64_PSR_BN)
-
-#include <asm/processor.h>
-#include <asm/asmmacro.h>
-
-/*
- * Inputs:
- * in0 = address of function descriptor of EFI routine to call
- * in1..in7 = arguments to routine
- *
- * Outputs:
- * r8 = EFI_STATUS returned by called function
- */
-
-GLOBAL_ENTRY(efi_call_phys)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
- alloc loc1=ar.pfs,8,7,7,0
- ld8 r2=[in0],8 // load EFI function's entry point
- mov loc0=rp
- .body
- ;;
- mov loc2=gp // save global pointer
- mov loc4=ar.rsc // save RSE configuration
- mov ar.rsc=0 // put RSE in enforced lazy, LE mode
- ;;
- ld8 gp=[in0] // load EFI function's global pointer
- movl r16=PSR_BITS_TO_CLEAR
- mov loc3=psr // save processor status word
- movl r17=PSR_BITS_TO_SET
- ;;
- or loc3=loc3,r17
- mov b6=r2
- ;;
- andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared
- br.call.sptk.many rp=ia64_switch_mode_phys
-.ret0: mov out4=in5
- mov out0=in1
- mov out1=in2
- mov out2=in3
- mov out3=in4
- mov out5=in6
- mov out6=in7
- mov loc5=r19
- mov loc6=r20
- br.call.sptk.many rp=b6 // call the EFI function
-.ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode
- mov r16=loc3
- mov r19=loc5
- mov r20=loc6
- br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
-.ret2: mov ar.rsc=loc4 // restore RSE configuration
- mov ar.pfs=loc1
- mov rp=loc0
- mov gp=loc2
- br.ret.sptk.many rp
-END(efi_call_phys)
diff --git a/arch/ia64/kernel/elfcore.c b/arch/ia64/kernel/elfcore.c
deleted file mode 100644
index 8895df121540..000000000000
--- a/arch/ia64/kernel/elfcore.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/elf.h>
-#include <linux/coredump.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-
-#include <asm/elf.h>
-
-
-Elf64_Half elf_core_extra_phdrs(struct coredump_params *cprm)
-{
- return GATE_EHDR->e_phnum;
-}
-
-int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)
-{
- const struct elf_phdr *const gate_phdrs =
- (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
- int i;
- Elf64_Off ofs = 0;
-
- for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
- struct elf_phdr phdr = gate_phdrs[i];
-
- if (phdr.p_type == PT_LOAD) {
- phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);
- phdr.p_filesz = phdr.p_memsz;
- if (ofs == 0) {
- ofs = phdr.p_offset = offset;
- offset += phdr.p_filesz;
- } else {
- phdr.p_offset = ofs;
- }
- } else {
- phdr.p_offset += ofs;
- }
- phdr.p_paddr = 0; /* match other core phdrs */
- if (!dump_emit(cprm, &phdr, sizeof(phdr)))
- return 0;
- }
- return 1;
-}
-
-int elf_core_write_extra_data(struct coredump_params *cprm)
-{
- const struct elf_phdr *const gate_phdrs =
- (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
- int i;
-
- for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
- if (gate_phdrs[i].p_type == PT_LOAD) {
- void *addr = (void *)gate_phdrs[i].p_vaddr;
- size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz);
-
- if (!dump_emit(cprm, addr, memsz))
- return 0;
- break;
- }
- }
- return 1;
-}
-
-size_t elf_core_extra_data_size(struct coredump_params *cprm)
-{
- const struct elf_phdr *const gate_phdrs =
- (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
- int i;
- size_t size = 0;
-
- for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
- if (gate_phdrs[i].p_type == PT_LOAD) {
- size += PAGE_ALIGN(gate_phdrs[i].p_memsz);
- break;
- }
- }
- return size;
-}
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
deleted file mode 100644
index ac06d44b9b27..000000000000
--- a/arch/ia64/kernel/entry.S
+++ /dev/null
@@ -1,1427 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/ia64/kernel/entry.S
- *
- * Kernel entry points.
- *
- * Copyright (C) 1998-2003, 2005 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999, 2002-2003
- * Asit Mallick <Asit.K.Mallick@intel.com>
- * Don Dugger <Don.Dugger@intel.com>
- * Suresh Siddha <suresh.b.siddha@intel.com>
- * Fenghua Yu <fenghua.yu@intel.com>
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- */
-/*
- * ia64_switch_to now places correct virtual mapping in in TR2 for
- * kernel stack. This allows us to handle interrupts without changing
- * to physical mode.
- *
- * Jonathan Nicklin <nicklin@missioncriticallinux.com>
- * Patrick O'Rourke <orourke@missioncriticallinux.com>
- * 11/07/2000
- */
-/*
- * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
- * VA Linux Systems Japan K.K.
- * pv_ops.
- */
-/*
- * Global (preserved) predicate usage on syscall entry/exit path:
- *
- * pKStk: See entry.h.
- * pUStk: See entry.h.
- * pSys: See entry.h.
- * pNonSys: !pSys
- */
-
-#include <linux/export.h>
-#include <linux/pgtable.h>
-#include <asm/asmmacro.h>
-#include <asm/cache.h>
-#include <asm/errno.h>
-#include <asm/kregs.h>
-#include <asm/asm-offsets.h>
-#include <asm/percpu.h>
-#include <asm/processor.h>
-#include <asm/thread_info.h>
-#include <asm/unistd.h>
-#include <asm/ftrace.h>
-
-#include "minstate.h"
-
- /*
- * execve() is special because in case of success, we need to
- * setup a null register window frame.
- */
-ENTRY(ia64_execve)
- /*
- * Allocate 8 input registers since ptrace() may clobber them
- */
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
- alloc loc1=ar.pfs,8,2,3,0
- mov loc0=rp
- .body
- mov out0=in0 // filename
- ;; // stop bit between alloc and call
- mov out1=in1 // argv
- mov out2=in2 // envp
- br.call.sptk.many rp=sys_execve
-.ret0:
- cmp4.ge p6,p7=r8,r0
- mov ar.pfs=loc1 // restore ar.pfs
- sxt4 r8=r8 // return 64-bit result
- ;;
- stf.spill [sp]=f0
- mov rp=loc0
-(p6) mov ar.pfs=r0 // clear ar.pfs on success
-(p7) br.ret.sptk.many rp
-
- /*
- * In theory, we'd have to zap this state only to prevent leaking of
- * security sensitive state (e.g., if current->mm->dumpable is zero). However,
- * this executes in less than 20 cycles even on Itanium, so it's not worth
- * optimizing for...).
- */
- mov ar.unat=0; mov ar.lc=0
- mov r4=0; mov f2=f0; mov b1=r0
- mov r5=0; mov f3=f0; mov b2=r0
- mov r6=0; mov f4=f0; mov b3=r0
- mov r7=0; mov f5=f0; mov b4=r0
- ldf.fill f12=[sp]; mov f13=f0; mov b5=r0
- ldf.fill f14=[sp]; ldf.fill f15=[sp]; mov f16=f0
- ldf.fill f17=[sp]; ldf.fill f18=[sp]; mov f19=f0
- ldf.fill f20=[sp]; ldf.fill f21=[sp]; mov f22=f0
- ldf.fill f23=[sp]; ldf.fill f24=[sp]; mov f25=f0
- ldf.fill f26=[sp]; ldf.fill f27=[sp]; mov f28=f0
- ldf.fill f29=[sp]; ldf.fill f30=[sp]; mov f31=f0
- br.ret.sptk.many rp
-END(ia64_execve)
-
-/*
- * sys_clone2(u64 flags, u64 ustack_base, u64 ustack_size, u64 parent_tidptr, u64 child_tidptr,
- * u64 tls)
- */
-GLOBAL_ENTRY(sys_clone2)
- /*
- * Allocate 8 input registers since ptrace() may clobber them
- */
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
- alloc r16=ar.pfs,8,2,6,0
- DO_SAVE_SWITCH_STACK
- mov loc0=rp
- mov loc1=r16 // save ar.pfs across ia64_clone
- .body
- mov out0=in0
- mov out1=in1
- mov out2=in2
- mov out3=in3
- mov out4=in4
- mov out5=in5
- br.call.sptk.many rp=ia64_clone
-.ret1: .restore sp
- adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
- mov ar.pfs=loc1
- mov rp=loc0
- br.ret.sptk.many rp
-END(sys_clone2)
-
-/*
- * sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls)
- * Deprecated. Use sys_clone2() instead.
- */
-GLOBAL_ENTRY(sys_clone)
- /*
- * Allocate 8 input registers since ptrace() may clobber them
- */
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
- alloc r16=ar.pfs,8,2,6,0
- DO_SAVE_SWITCH_STACK
- mov loc0=rp
- mov loc1=r16 // save ar.pfs across ia64_clone
- .body
- mov out0=in0
- mov out1=in1
- mov out2=16 // stacksize (compensates for 16-byte scratch area)
- mov out3=in3
- mov out4=in4
- mov out5=in5
- br.call.sptk.many rp=ia64_clone
-.ret2: .restore sp
- adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
- mov ar.pfs=loc1
- mov rp=loc0
- br.ret.sptk.many rp
-END(sys_clone)
-
-/*
- * prev_task <- ia64_switch_to(struct task_struct *next)
- * With Ingo's new scheduler, interrupts are disabled when this routine gets
- * called. The code starting at .map relies on this. The rest of the code
- * doesn't care about the interrupt masking status.
- */
-GLOBAL_ENTRY(ia64_switch_to)
- .prologue
- alloc r16=ar.pfs,1,0,0,0
- DO_SAVE_SWITCH_STACK
- .body
-
- adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13
- movl r25=init_task
- mov r27=IA64_KR(CURRENT_STACK)
- adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
- dep r20=0,in0,61,3 // physical address of "next"
- ;;
- st8 [r22]=sp // save kernel stack pointer of old task
- shr.u r26=r20,IA64_GRANULE_SHIFT
- cmp.eq p7,p6=r25,in0
- ;;
- /*
- * If we've already mapped this task's page, we can skip doing it again.
- */
-(p6) cmp.eq p7,p6=r26,r27
-(p6) br.cond.dpnt .map
- ;;
-.done:
- ld8 sp=[r21] // load kernel stack pointer of new task
- MOV_TO_KR(CURRENT, in0, r8, r9) // update "current" application register
- mov r8=r13 // return pointer to previously running task
- mov r13=in0 // set "current" pointer
- ;;
- DO_LOAD_SWITCH_STACK
-
-#ifdef CONFIG_SMP
- sync.i // ensure "fc"s done by this CPU are visible on other CPUs
-#endif
- br.ret.sptk.many rp // boogie on out in new context
-
-.map:
- RSM_PSR_IC(r25) // interrupts (psr.i) are already disabled here
- movl r25=PAGE_KERNEL
- ;;
- srlz.d
- or r23=r25,r20 // construct PA | page properties
- mov r25=IA64_GRANULE_SHIFT<<2
- ;;
- MOV_TO_ITIR(p0, r25, r8)
- MOV_TO_IFA(in0, r8) // VA of next task...
- ;;
- mov r25=IA64_TR_CURRENT_STACK
- MOV_TO_KR(CURRENT_STACK, r26, r8, r9) // remember last page we mapped...
- ;;
- itr.d dtr[r25]=r23 // wire in new mapping...
- SSM_PSR_IC_AND_SRLZ_D(r8, r9) // reenable the psr.ic bit
- br.cond.sptk .done
-END(ia64_switch_to)
-
-/*
- * Note that interrupts are enabled during save_switch_stack and load_switch_stack. This
- * means that we may get an interrupt with "sp" pointing to the new kernel stack while
- * ar.bspstore is still pointing to the old kernel backing store area. Since ar.rsc,
- * ar.rnat, ar.bsp, and ar.bspstore are all preserved by interrupts, this is not a
- * problem. Also, we don't need to specify unwind information for preserved registers
- * that are not modified in save_switch_stack as the right unwind information is already
- * specified at the call-site of save_switch_stack.
- */
-
-/*
- * save_switch_stack:
- * - r16 holds ar.pfs
- * - b7 holds address to return to
- * - rp (b0) holds return address to save
- */
-GLOBAL_ENTRY(save_switch_stack)
- .prologue
- .altrp b7
- flushrs // flush dirty regs to backing store (must be first in insn group)
- .save @priunat,r17
- mov r17=ar.unat // preserve caller's
- .body
-#ifdef CONFIG_ITANIUM
- adds r2=16+128,sp
- adds r3=16+64,sp
- adds r14=SW(R4)+16,sp
- ;;
- st8.spill [r14]=r4,16 // spill r4
- lfetch.fault.excl.nt1 [r3],128
- ;;
- lfetch.fault.excl.nt1 [r2],128
- lfetch.fault.excl.nt1 [r3],128
- ;;
- lfetch.fault.excl [r2]
- lfetch.fault.excl [r3]
- adds r15=SW(R5)+16,sp
-#else
- add r2=16+3*128,sp
- add r3=16,sp
- add r14=SW(R4)+16,sp
- ;;
- st8.spill [r14]=r4,SW(R6)-SW(R4) // spill r4 and prefetch offset 0x1c0
- lfetch.fault.excl.nt1 [r3],128 // prefetch offset 0x010
- ;;
- lfetch.fault.excl.nt1 [r3],128 // prefetch offset 0x090
- lfetch.fault.excl.nt1 [r2],128 // prefetch offset 0x190
- ;;
- lfetch.fault.excl.nt1 [r3] // prefetch offset 0x110
- lfetch.fault.excl.nt1 [r2] // prefetch offset 0x210
- adds r15=SW(R5)+16,sp
-#endif
- ;;
- st8.spill [r15]=r5,SW(R7)-SW(R5) // spill r5
- mov.m ar.rsc=0 // put RSE in mode: enforced lazy, little endian, pl 0
- add r2=SW(F2)+16,sp // r2 = &sw->f2
- ;;
- st8.spill [r14]=r6,SW(B0)-SW(R6) // spill r6
- mov.m r18=ar.fpsr // preserve fpsr
- add r3=SW(F3)+16,sp // r3 = &sw->f3
- ;;
- stf.spill [r2]=f2,32
- mov.m r19=ar.rnat
- mov r21=b0
-
- stf.spill [r3]=f3,32
- st8.spill [r15]=r7,SW(B2)-SW(R7) // spill r7
- mov r22=b1
- ;;
- // since we're done with the spills, read and save ar.unat:
- mov.m r29=ar.unat
- mov.m r20=ar.bspstore
- mov r23=b2
- stf.spill [r2]=f4,32
- stf.spill [r3]=f5,32
- mov r24=b3
- ;;
- st8 [r14]=r21,SW(B1)-SW(B0) // save b0
- st8 [r15]=r23,SW(B3)-SW(B2) // save b2
- mov r25=b4
- mov r26=b5
- ;;
- st8 [r14]=r22,SW(B4)-SW(B1) // save b1
- st8 [r15]=r24,SW(AR_PFS)-SW(B3) // save b3
- mov r21=ar.lc // I-unit
- stf.spill [r2]=f12,32
- stf.spill [r3]=f13,32
- ;;
- st8 [r14]=r25,SW(B5)-SW(B4) // save b4
- st8 [r15]=r16,SW(AR_LC)-SW(AR_PFS) // save ar.pfs
- stf.spill [r2]=f14,32
- stf.spill [r3]=f15,32
- ;;
- st8 [r14]=r26 // save b5
- st8 [r15]=r21 // save ar.lc
- stf.spill [r2]=f16,32
- stf.spill [r3]=f17,32
- ;;
- stf.spill [r2]=f18,32
- stf.spill [r3]=f19,32
- ;;
- stf.spill [r2]=f20,32
- stf.spill [r3]=f21,32
- ;;
- stf.spill [r2]=f22,32
- stf.spill [r3]=f23,32
- ;;
- stf.spill [r2]=f24,32
- stf.spill [r3]=f25,32
- ;;
- stf.spill [r2]=f26,32
- stf.spill [r3]=f27,32
- ;;
- stf.spill [r2]=f28,32
- stf.spill [r3]=f29,32
- ;;
- stf.spill [r2]=f30,SW(AR_UNAT)-SW(F30)
- stf.spill [r3]=f31,SW(PR)-SW(F31)
- add r14=SW(CALLER_UNAT)+16,sp
- ;;
- st8 [r2]=r29,SW(AR_RNAT)-SW(AR_UNAT) // save ar.unat
- st8 [r14]=r17,SW(AR_FPSR)-SW(CALLER_UNAT) // save caller_unat
- mov r21=pr
- ;;
- st8 [r2]=r19,SW(AR_BSPSTORE)-SW(AR_RNAT) // save ar.rnat
- st8 [r3]=r21 // save predicate registers
- ;;
- st8 [r2]=r20 // save ar.bspstore
- st8 [r14]=r18 // save fpsr
- mov ar.rsc=3 // put RSE back into eager mode, pl 0
- br.cond.sptk.many b7
-END(save_switch_stack)
-
-/*
- * load_switch_stack:
- * - "invala" MUST be done at call site (normally in DO_LOAD_SWITCH_STACK)
- * - b7 holds address to return to
- * - must not touch r8-r11
- */
-GLOBAL_ENTRY(load_switch_stack)
- .prologue
- .altrp b7
-
- .body
- lfetch.fault.nt1 [sp]
- adds r2=SW(AR_BSPSTORE)+16,sp
- adds r3=SW(AR_UNAT)+16,sp
- mov ar.rsc=0 // put RSE into enforced lazy mode
- adds r14=SW(CALLER_UNAT)+16,sp
- adds r15=SW(AR_FPSR)+16,sp
- ;;
- ld8 r27=[r2],(SW(B0)-SW(AR_BSPSTORE)) // bspstore
- ld8 r29=[r3],(SW(B1)-SW(AR_UNAT)) // unat
- ;;
- ld8 r21=[r2],16 // restore b0
- ld8 r22=[r3],16 // restore b1
- ;;
- ld8 r23=[r2],16 // restore b2
- ld8 r24=[r3],16 // restore b3
- ;;
- ld8 r25=[r2],16 // restore b4
- ld8 r26=[r3],16 // restore b5
- ;;
- ld8 r16=[r2],(SW(PR)-SW(AR_PFS)) // ar.pfs
- ld8 r17=[r3],(SW(AR_RNAT)-SW(AR_LC)) // ar.lc
- ;;
- ld8 r28=[r2] // restore pr
- ld8 r30=[r3] // restore rnat
- ;;
- ld8 r18=[r14],16 // restore caller's unat
- ld8 r19=[r15],24 // restore fpsr
- ;;
- ldf.fill f2=[r14],32
- ldf.fill f3=[r15],32
- ;;
- ldf.fill f4=[r14],32
- ldf.fill f5=[r15],32
- ;;
- ldf.fill f12=[r14],32
- ldf.fill f13=[r15],32
- ;;
- ldf.fill f14=[r14],32
- ldf.fill f15=[r15],32
- ;;
- ldf.fill f16=[r14],32
- ldf.fill f17=[r15],32
- ;;
- ldf.fill f18=[r14],32
- ldf.fill f19=[r15],32
- mov b0=r21
- ;;
- ldf.fill f20=[r14],32
- ldf.fill f21=[r15],32
- mov b1=r22
- ;;
- ldf.fill f22=[r14],32
- ldf.fill f23=[r15],32
- mov b2=r23
- ;;
- mov ar.bspstore=r27
- mov ar.unat=r29 // establish unat holding the NaT bits for r4-r7
- mov b3=r24
- ;;
- ldf.fill f24=[r14],32
- ldf.fill f25=[r15],32
- mov b4=r25
- ;;
- ldf.fill f26=[r14],32
- ldf.fill f27=[r15],32
- mov b5=r26
- ;;
- ldf.fill f28=[r14],32
- ldf.fill f29=[r15],32
- mov ar.pfs=r16
- ;;
- ldf.fill f30=[r14],32
- ldf.fill f31=[r15],24
- mov ar.lc=r17
- ;;
- ld8.fill r4=[r14],16
- ld8.fill r5=[r15],16
- mov pr=r28,-1
- ;;
- ld8.fill r6=[r14],16
- ld8.fill r7=[r15],16
-
- mov ar.unat=r18 // restore caller's unat
- mov ar.rnat=r30 // must restore after bspstore but before rsc!
- mov ar.fpsr=r19 // restore fpsr
- mov ar.rsc=3 // put RSE back into eager mode, pl 0
- br.cond.sptk.many b7
-END(load_switch_stack)
-
- /*
- * Invoke a system call, but do some tracing before and after the call.
- * We MUST preserve the current register frame throughout this routine
- * because some system calls (such as ia64_execve) directly
- * manipulate ar.pfs.
- */
-GLOBAL_ENTRY(ia64_trace_syscall)
- PT_REGS_UNWIND_INFO(0)
- /*
- * We need to preserve the scratch registers f6-f11 in case the system
- * call is sigreturn.
- */
- adds r16=PT(F6)+16,sp
- adds r17=PT(F7)+16,sp
- ;;
- stf.spill [r16]=f6,32
- stf.spill [r17]=f7,32
- ;;
- stf.spill [r16]=f8,32
- stf.spill [r17]=f9,32
- ;;
- stf.spill [r16]=f10
- stf.spill [r17]=f11
- br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args
- cmp.lt p6,p0=r8,r0 // check tracehook
- adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8
- adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10
- mov r10=0
-(p6) br.cond.sptk strace_error // syscall failed ->
- adds r16=PT(F6)+16,sp
- adds r17=PT(F7)+16,sp
- ;;
- ldf.fill f6=[r16],32
- ldf.fill f7=[r17],32
- ;;
- ldf.fill f8=[r16],32
- ldf.fill f9=[r17],32
- ;;
- ldf.fill f10=[r16]
- ldf.fill f11=[r17]
- // the syscall number may have changed, so re-load it and re-calculate the
- // syscall entry-point:
- adds r15=PT(R15)+16,sp // r15 = &pt_regs.r15 (syscall #)
- ;;
- ld8 r15=[r15]
- mov r3=NR_syscalls - 1
- ;;
- adds r15=-1024,r15
- movl r16=sys_call_table
- ;;
- shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024)
- cmp.leu p6,p7=r15,r3
- ;;
-(p6) ld8 r20=[r20] // load address of syscall entry point
-(p7) movl r20=sys_ni_syscall
- ;;
- mov b6=r20
- br.call.sptk.many rp=b6 // do the syscall
-.strace_check_retval:
- cmp.lt p6,p0=r8,r0 // syscall failed?
- adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8
- adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10
- mov r10=0
-(p6) br.cond.sptk strace_error // syscall failed ->
- ;; // avoid RAW on r10
-.strace_save_retval:
-.mem.offset 0,0; st8.spill [r2]=r8 // store return value in slot for r8
-.mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10
- br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
-.ret3:
-(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
-(pUStk) rsm psr.i // disable interrupts
- br.cond.sptk ia64_work_pending_syscall_end
-
-strace_error:
- ld8 r3=[r2] // load pt_regs.r8
- sub r9=0,r8 // negate return value to get errno value
- ;;
- cmp.ne p6,p0=r3,r0 // is pt_regs.r8!=0?
- adds r3=16,r2 // r3=&pt_regs.r10
- ;;
-(p6) mov r10=-1
-(p6) mov r8=r9
- br.cond.sptk .strace_save_retval
-END(ia64_trace_syscall)
-
- /*
- * When traced and returning from sigreturn, we invoke syscall_trace but then
- * go straight to ia64_leave_kernel rather than ia64_leave_syscall.
- */
-GLOBAL_ENTRY(ia64_strace_leave_kernel)
- PT_REGS_UNWIND_INFO(0)
-{ /*
- * Some versions of gas generate bad unwind info if the first instruction of a
- * procedure doesn't go into the first slot of a bundle. This is a workaround.
- */
- nop.m 0
- nop.i 0
- br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
-}
-.ret4: br.cond.sptk ia64_leave_kernel
-END(ia64_strace_leave_kernel)
-
-ENTRY(call_payload)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(0)
- /* call the kernel_thread payload; fn is in r4, arg - in r5 */
- alloc loc1=ar.pfs,0,3,1,0
- mov loc0=rp
- mov loc2=gp
- mov out0=r5 // arg
- ld8 r14 = [r4], 8 // fn.address
- ;;
- mov b6 = r14
- ld8 gp = [r4] // fn.gp
- ;;
- br.call.sptk.many rp=b6 // fn(arg)
-.ret12: mov gp=loc2
- mov rp=loc0
- mov ar.pfs=loc1
- /* ... and if it has returned, we are going to userland */
- cmp.ne pKStk,pUStk=r0,r0
- br.ret.sptk.many rp
-END(call_payload)
-
-GLOBAL_ENTRY(ia64_ret_from_clone)
- PT_REGS_UNWIND_INFO(0)
-{ /*
- * Some versions of gas generate bad unwind info if the first instruction of a
- * procedure doesn't go into the first slot of a bundle. This is a workaround.
- */
- nop.m 0
- nop.i 0
- /*
- * We need to call schedule_tail() to complete the scheduling process.
- * Called by ia64_switch_to() after ia64_clone()->copy_thread(). r8 contains the
- * address of the previously executing task.
- */
- br.call.sptk.many rp=ia64_invoke_schedule_tail
-}
-.ret8:
-(pKStk) br.call.sptk.many rp=call_payload
- adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
- ;;
- ld4 r2=[r2]
- ;;
- mov r8=0
- and r2=_TIF_SYSCALL_TRACEAUDIT,r2
- ;;
- cmp.ne p6,p0=r2,r0
-(p6) br.cond.spnt .strace_check_retval
- ;; // added stop bits to prevent r8 dependency
-END(ia64_ret_from_clone)
- // fall through
-GLOBAL_ENTRY(ia64_ret_from_syscall)
- PT_REGS_UNWIND_INFO(0)
- cmp.ge p6,p7=r8,r0 // syscall executed successfully?
- adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8
- mov r10=r0 // clear error indication in r10
-(p7) br.cond.spnt handle_syscall_error // handle potential syscall failure
-END(ia64_ret_from_syscall)
- // fall through
-
-/*
- * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
- * need to switch to bank 0 and doesn't restore the scratch registers.
- * To avoid leaking kernel bits, the scratch registers are set to
- * the following known-to-be-safe values:
- *
- * r1: restored (global pointer)
- * r2: cleared
- * r3: 1 (when returning to user-level)
- * r8-r11: restored (syscall return value(s))
- * r12: restored (user-level stack pointer)
- * r13: restored (user-level thread pointer)
- * r14: set to __kernel_syscall_via_epc
- * r15: restored (syscall #)
- * r16-r17: cleared
- * r18: user-level b6
- * r19: cleared
- * r20: user-level ar.fpsr
- * r21: user-level b0
- * r22: cleared
- * r23: user-level ar.bspstore
- * r24: user-level ar.rnat
- * r25: user-level ar.unat
- * r26: user-level ar.pfs
- * r27: user-level ar.rsc
- * r28: user-level ip
- * r29: user-level psr
- * r30: user-level cfm
- * r31: user-level pr
- * f6-f11: cleared
- * pr: restored (user-level pr)
- * b0: restored (user-level rp)
- * b6: restored
- * b7: set to __kernel_syscall_via_epc
- * ar.unat: restored (user-level ar.unat)
- * ar.pfs: restored (user-level ar.pfs)
- * ar.rsc: restored (user-level ar.rsc)
- * ar.rnat: restored (user-level ar.rnat)
- * ar.bspstore: restored (user-level ar.bspstore)
- * ar.fpsr: restored (user-level ar.fpsr)
- * ar.ccv: cleared
- * ar.csd: cleared
- * ar.ssd: cleared
- */
-GLOBAL_ENTRY(ia64_leave_syscall)
- PT_REGS_UNWIND_INFO(0)
- /*
- * work.need_resched etc. mustn't get changed by this CPU before it returns to
- * user- or fsys-mode, hence we disable interrupts early on.
- *
- * p6 controls whether current_thread_info()->flags needs to be check for
- * extra work. We always check for extra work when returning to user-level.
- * With CONFIG_PREEMPTION, we also check for extra work when the preempt_count
- * is 0. After extra work processing has been completed, execution
- * resumes at ia64_work_processed_syscall with p6 set to 1 if the extra-work-check
- * needs to be redone.
- */
-#ifdef CONFIG_PREEMPTION
- RSM_PSR_I(p0, r2, r18) // disable interrupts
- cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall
-(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
- ;;
- .pred.rel.mutex pUStk,pKStk
-(pKStk) ld4 r21=[r20] // r21 <- preempt_count
-(pUStk) mov r21=0 // r21 <- 0
- ;;
- cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0)
-#else /* !CONFIG_PREEMPTION */
- RSM_PSR_I(pUStk, r2, r18)
- cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall
-(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
-#endif
-.global ia64_work_processed_syscall;
-ia64_work_processed_syscall:
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- adds r2=PT(LOADRS)+16,r12
- MOV_FROM_ITC(pUStk, p9, r22, r19) // fetch time at leave
- adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
- ;;
-(p6) ld4 r31=[r18] // load current_thread_info()->flags
- ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs"
- adds r3=PT(AR_BSPSTORE)+16,r12 // deferred
- ;;
-#else
- adds r2=PT(LOADRS)+16,r12
- adds r3=PT(AR_BSPSTORE)+16,r12
- adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
- ;;
-(p6) ld4 r31=[r18] // load current_thread_info()->flags
- ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs"
- nop.i 0
- ;;
-#endif
- mov r16=ar.bsp // M2 get existing backing store pointer
- ld8 r18=[r2],PT(R9)-PT(B6) // load b6
-(p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE?
- ;;
- ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage)
-(p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending?
-(p6) br.cond.spnt .work_pending_syscall
- ;;
- // start restoring the state saved on the kernel stack (struct pt_regs):
- ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
- ld8 r11=[r3],PT(CR_IIP)-PT(R11)
-(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE!
- ;;
- invala // M0|1 invalidate ALAT
- RSM_PSR_I_IC(r28, r29, r30) // M2 turn off interrupts and interruption collection
- cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs
-
- ld8 r29=[r2],16 // M0|1 load cr.ipsr
- ld8 r28=[r3],16 // M0|1 load cr.iip
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-(pUStk) add r14=TI_AC_LEAVE+IA64_TASK_SIZE,r13
- ;;
- ld8 r30=[r2],16 // M0|1 load cr.ifs
- ld8 r25=[r3],16 // M0|1 load ar.unat
-(pUStk) add r15=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
- ;;
-#else
- mov r22=r0 // A clear r22
- ;;
- ld8 r30=[r2],16 // M0|1 load cr.ifs
- ld8 r25=[r3],16 // M0|1 load ar.unat
-(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
- ;;
-#endif
- ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs
- MOV_FROM_PSR(pKStk, r22, r21) // M2 read PSR now that interrupts are disabled
- nop 0
- ;;
- ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
- ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc
- mov f6=f0 // F clear f6
- ;;
- ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage)
- ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates
- mov f7=f0 // F clear f7
- ;;
- ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr
- ld8.fill r1=[r3],16 // M0|1 load r1
-(pUStk) mov r17=1 // A
- ;;
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-(pUStk) st1 [r15]=r17 // M2|3
-#else
-(pUStk) st1 [r14]=r17 // M2|3
-#endif
- ld8.fill r13=[r3],16 // M0|1
- mov f8=f0 // F clear f8
- ;;
- ld8.fill r12=[r2] // M0|1 restore r12 (sp)
- ld8.fill r15=[r3] // M0|1 restore r15
- mov b6=r18 // I0 restore b6
-
- LOAD_PHYS_STACK_REG_SIZE(r17)
- mov f9=f0 // F clear f9
-(pKStk) br.cond.dpnt.many skip_rbs_switch // B
-
- srlz.d // M0 ensure interruption collection is off (for cover)
- shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition
- COVER // B add current frame into dirty partition & set cr.ifs
- ;;
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- mov r19=ar.bsp // M2 get new backing store pointer
- st8 [r14]=r22 // M save time at leave
- mov f10=f0 // F clear f10
-
- mov r22=r0 // A clear r22
- movl r14=__kernel_syscall_via_epc // X
- ;;
-#else
- mov r19=ar.bsp // M2 get new backing store pointer
- mov f10=f0 // F clear f10
-
- nop.m 0
- movl r14=__kernel_syscall_via_epc // X
- ;;
-#endif
- mov.m ar.csd=r0 // M2 clear ar.csd
- mov.m ar.ccv=r0 // M2 clear ar.ccv
- mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc)
-
- mov.m ar.ssd=r0 // M2 clear ar.ssd
- mov f11=f0 // F clear f11
- br.cond.sptk.many rbs_switch // B
-END(ia64_leave_syscall)
-
-GLOBAL_ENTRY(ia64_leave_kernel)
- PT_REGS_UNWIND_INFO(0)
- /*
- * work.need_resched etc. mustn't get changed by this CPU before it returns to
- * user- or fsys-mode, hence we disable interrupts early on.
- *
- * p6 controls whether current_thread_info()->flags needs to be check for
- * extra work. We always check for extra work when returning to user-level.
- * With CONFIG_PREEMPTION, we also check for extra work when the preempt_count
- * is 0. After extra work processing has been completed, execution
- * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
- * needs to be redone.
- */
-#ifdef CONFIG_PREEMPTION
- RSM_PSR_I(p0, r17, r31) // disable interrupts
- cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel
-(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
- ;;
- .pred.rel.mutex pUStk,pKStk
-(pKStk) ld4 r21=[r20] // r21 <- preempt_count
-(pUStk) mov r21=0 // r21 <- 0
- ;;
- cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0)
-#else
- RSM_PSR_I(pUStk, r17, r31)
- cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel
-(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
-#endif
-.work_processed_kernel:
- adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
- ;;
-(p6) ld4 r31=[r17] // load current_thread_info()->flags
- adds r21=PT(PR)+16,r12
- ;;
-
- lfetch [r21],PT(CR_IPSR)-PT(PR)
- adds r2=PT(B6)+16,r12
- adds r3=PT(R16)+16,r12
- ;;
- lfetch [r21]
- ld8 r28=[r2],8 // load b6
- adds r29=PT(R24)+16,r12
-
- ld8.fill r16=[r3],PT(AR_CSD)-PT(R16)
- adds r30=PT(AR_CCV)+16,r12
-(p6) and r19=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE?
- ;;
- ld8.fill r24=[r29]
- ld8 r15=[r30] // load ar.ccv
-(p6) cmp4.ne.unc p6,p0=r19, r0 // any special work pending?
- ;;
- ld8 r29=[r2],16 // load b7
- ld8 r30=[r3],16 // load ar.csd
-(p6) br.cond.spnt .work_pending
- ;;
- ld8 r31=[r2],16 // load ar.ssd
- ld8.fill r8=[r3],16
- ;;
- ld8.fill r9=[r2],16
- ld8.fill r10=[r3],PT(R17)-PT(R10)
- ;;
- ld8.fill r11=[r2],PT(R18)-PT(R11)
- ld8.fill r17=[r3],16
- ;;
- ld8.fill r18=[r2],16
- ld8.fill r19=[r3],16
- ;;
- ld8.fill r20=[r2],16
- ld8.fill r21=[r3],16
- mov ar.csd=r30
- mov ar.ssd=r31
- ;;
- RSM_PSR_I_IC(r23, r22, r25) // initiate turning off of interrupt and interruption collection
- invala // invalidate ALAT
- ;;
- ld8.fill r22=[r2],24
- ld8.fill r23=[r3],24
- mov b6=r28
- ;;
- ld8.fill r25=[r2],16
- ld8.fill r26=[r3],16
- mov b7=r29
- ;;
- ld8.fill r27=[r2],16
- ld8.fill r28=[r3],16
- ;;
- ld8.fill r29=[r2],16
- ld8.fill r30=[r3],24
- ;;
- ld8.fill r31=[r2],PT(F9)-PT(R31)
- adds r3=PT(F10)-PT(F6),r3
- ;;
- ldf.fill f9=[r2],PT(F6)-PT(F9)
- ldf.fill f10=[r3],PT(F8)-PT(F10)
- ;;
- ldf.fill f6=[r2],PT(F7)-PT(F6)
- ;;
- ldf.fill f7=[r2],PT(F11)-PT(F7)
- ldf.fill f8=[r3],32
- ;;
- srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned)
- mov ar.ccv=r15
- ;;
- ldf.fill f11=[r2]
- BSW_0(r2, r3, r15) // switch back to bank 0 (no stop bit required beforehand...)
- ;;
-(pUStk) mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
- adds r16=PT(CR_IPSR)+16,r12
- adds r17=PT(CR_IIP)+16,r12
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- .pred.rel.mutex pUStk,pKStk
- MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled
- MOV_FROM_ITC(pUStk, p9, r22, r29) // M fetch time at leave
- nop.i 0
- ;;
-#else
- MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled
- nop.i 0
- nop.i 0
- ;;
-#endif
- ld8 r29=[r16],16 // load cr.ipsr
- ld8 r28=[r17],16 // load cr.iip
- ;;
- ld8 r30=[r16],16 // load cr.ifs
- ld8 r25=[r17],16 // load ar.unat
- ;;
- ld8 r26=[r16],16 // load ar.pfs
- ld8 r27=[r17],16 // load ar.rsc
- cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs
- ;;
- ld8 r24=[r16],16 // load ar.rnat (may be garbage)
- ld8 r23=[r17],16 // load ar.bspstore (may be garbage)
- ;;
- ld8 r31=[r16],16 // load predicates
- ld8 r21=[r17],16 // load b0
- ;;
- ld8 r19=[r16],16 // load ar.rsc value for "loadrs"
- ld8.fill r1=[r17],16 // load r1
- ;;
- ld8.fill r12=[r16],16
- ld8.fill r13=[r17],16
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-(pUStk) adds r3=TI_AC_LEAVE+IA64_TASK_SIZE,r18
-#else
-(pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
-#endif
- ;;
- ld8 r20=[r16],16 // ar.fpsr
- ld8.fill r15=[r17],16
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-(pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 // deferred
-#endif
- ;;
- ld8.fill r14=[r16],16
- ld8.fill r2=[r17]
-(pUStk) mov r17=1
- ;;
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- // mmi_ : ld8 st1 shr;; mmi_ : st8 st1 shr;;
- // mib : mov add br -> mib : ld8 add br
- // bbb_ : br nop cover;; mbb_ : mov br cover;;
- //
- // no one require bsp in r16 if (pKStk) branch is selected.
-(pUStk) st8 [r3]=r22 // save time at leave
-(pUStk) st1 [r18]=r17 // restore current->thread.on_ustack
- shr.u r18=r19,16 // get byte size of existing "dirty" partition
- ;;
- ld8.fill r3=[r16] // deferred
- LOAD_PHYS_STACK_REG_SIZE(r17)
-(pKStk) br.cond.dpnt skip_rbs_switch
- mov r16=ar.bsp // get existing backing store pointer
-#else
- ld8.fill r3=[r16]
-(pUStk) st1 [r18]=r17 // restore current->thread.on_ustack
- shr.u r18=r19,16 // get byte size of existing "dirty" partition
- ;;
- mov r16=ar.bsp // get existing backing store pointer
- LOAD_PHYS_STACK_REG_SIZE(r17)
-(pKStk) br.cond.dpnt skip_rbs_switch
-#endif
-
- /*
- * Restore user backing store.
- *
- * NOTE: alloc, loadrs, and cover can't be predicated.
- */
-(pNonSys) br.cond.dpnt dont_preserve_current_frame
- COVER // add current frame into dirty partition and set cr.ifs
- ;;
- mov r19=ar.bsp // get new backing store pointer
-rbs_switch:
- sub r16=r16,r18 // krbs = old bsp - size of dirty partition
- cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs
- ;;
- sub r19=r19,r16 // calculate total byte size of dirty partition
- add r18=64,r18 // don't force in0-in7 into memory...
- ;;
- shl r19=r19,16 // shift size of dirty partition into loadrs position
- ;;
-dont_preserve_current_frame:
- /*
- * To prevent leaking bits between the kernel and user-space,
- * we must clear the stacked registers in the "invalid" partition here.
- * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium,
- * 5 registers/cycle on McKinley).
- */
-# define pRecurse p6
-# define pReturn p7
-#ifdef CONFIG_ITANIUM
-# define Nregs 10
-#else
-# define Nregs 14
-#endif
- alloc loc0=ar.pfs,2,Nregs-2,2,0
- shr.u loc1=r18,9 // RNaTslots <= floor(dirtySize / (64*8))
- sub r17=r17,r18 // r17 = (physStackedSize + 8) - dirtySize
- ;;
- mov ar.rsc=r19 // load ar.rsc to be used for "loadrs"
- shladd in0=loc1,3,r17
- mov in1=0
- ;;
- TEXT_ALIGN(32)
-rse_clear_invalid:
-#ifdef CONFIG_ITANIUM
- // cycle 0
- { .mii
- alloc loc0=ar.pfs,2,Nregs-2,2,0
- cmp.lt pRecurse,p0=Nregs*8,in0 // if more than Nregs regs left to clear, (re)curse
- add out0=-Nregs*8,in0
-}{ .mfb
- add out1=1,in1 // increment recursion count
- nop.f 0
- nop.b 0 // can't do br.call here because of alloc (WAW on CFM)
- ;;
-}{ .mfi // cycle 1
- mov loc1=0
- nop.f 0
- mov loc2=0
-}{ .mib
- mov loc3=0
- mov loc4=0
-(pRecurse) br.call.sptk.many b0=rse_clear_invalid
-
-}{ .mfi // cycle 2
- mov loc5=0
- nop.f 0
- cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret
-}{ .mib
- mov loc6=0
- mov loc7=0
-(pReturn) br.ret.sptk.many b0
-}
-#else /* !CONFIG_ITANIUM */
- alloc loc0=ar.pfs,2,Nregs-2,2,0
- cmp.lt pRecurse,p0=Nregs*8,in0 // if more than Nregs regs left to clear, (re)curse
- add out0=-Nregs*8,in0
- add out1=1,in1 // increment recursion count
- mov loc1=0
- mov loc2=0
- ;;
- mov loc3=0
- mov loc4=0
- mov loc5=0
- mov loc6=0
- mov loc7=0
-(pRecurse) br.call.dptk.few b0=rse_clear_invalid
- ;;
- mov loc8=0
- mov loc9=0
- cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret
- mov loc10=0
- mov loc11=0
-(pReturn) br.ret.dptk.many b0
-#endif /* !CONFIG_ITANIUM */
-# undef pRecurse
-# undef pReturn
- ;;
- alloc r17=ar.pfs,0,0,0,0 // drop current register frame
- ;;
- loadrs
- ;;
-skip_rbs_switch:
- mov ar.unat=r25 // M2
-(pKStk) extr.u r22=r22,21,1 // I0 extract current value of psr.pp from r22
-(pLvSys)mov r19=r0 // A clear r19 for leave_syscall, no-op otherwise
- ;;
-(pUStk) mov ar.bspstore=r23 // M2
-(pKStk) dep r29=r22,r29,21,1 // I0 update ipsr.pp with psr.pp
-(pLvSys)mov r16=r0 // A clear r16 for leave_syscall, no-op otherwise
- ;;
- MOV_TO_IPSR(p0, r29, r25) // M2
- mov ar.pfs=r26 // I0
-(pLvSys)mov r17=r0 // A clear r17 for leave_syscall, no-op otherwise
-
- MOV_TO_IFS(p9, r30, r25)// M2
- mov b0=r21 // I0
-(pLvSys)mov r18=r0 // A clear r18 for leave_syscall, no-op otherwise
-
- mov ar.fpsr=r20 // M2
- MOV_TO_IIP(r28, r25) // M2
- nop 0
- ;;
-(pUStk) mov ar.rnat=r24 // M2 must happen with RSE in lazy mode
- nop 0
-(pLvSys)mov r2=r0
-
- mov ar.rsc=r27 // M2
- mov pr=r31,-1 // I0
- RFI // B
-
- /*
- * On entry:
- * r20 = &current->thread_info->pre_count (if CONFIG_PREEMPTION)
- * r31 = current->thread_info->flags
- * On exit:
- * p6 = TRUE if work-pending-check needs to be redone
- *
- * Interrupts are disabled on entry, reenabled depend on work, and
- * disabled on exit.
- */
-.work_pending_syscall:
- add r2=-8,r2
- add r3=-8,r3
- ;;
- st8 [r2]=r8
- st8 [r3]=r10
-.work_pending:
- tbit.z p6,p0=r31,TIF_NEED_RESCHED // is resched not needed?
-(p6) br.cond.sptk.few .notify
- br.call.spnt.many rp=preempt_schedule_irq
-.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 (re-check)
-(pLvSys)br.cond.sptk.few ia64_work_pending_syscall_end
- br.cond.sptk.many .work_processed_kernel
-
-.notify:
-(pUStk) br.call.spnt.many rp=notify_resume_user
-.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 (don't re-check)
-(pLvSys)br.cond.sptk.few ia64_work_pending_syscall_end
- br.cond.sptk.many .work_processed_kernel
-
-.global ia64_work_pending_syscall_end;
-ia64_work_pending_syscall_end:
- adds r2=PT(R8)+16,r12
- adds r3=PT(R10)+16,r12
- ;;
- ld8 r8=[r2]
- ld8 r10=[r3]
- br.cond.sptk.many ia64_work_processed_syscall
-END(ia64_leave_kernel)
-
-ENTRY(handle_syscall_error)
- /*
- * Some system calls (e.g., ptrace, mmap) can return arbitrary values which could
- * lead us to mistake a negative return value as a failed syscall. Those syscall
- * must deposit a non-zero value in pt_regs.r8 to indicate an error. If
- * pt_regs.r8 is zero, we assume that the call completed successfully.
- */
- PT_REGS_UNWIND_INFO(0)
- ld8 r3=[r2] // load pt_regs.r8
- ;;
- cmp.eq p6,p7=r3,r0 // is pt_regs.r8==0?
- ;;
-(p7) mov r10=-1
-(p7) sub r8=0,r8 // negate return value to get errno
- br.cond.sptk ia64_leave_syscall
-END(handle_syscall_error)
-
- /*
- * Invoke schedule_tail(task) while preserving in0-in7, which may be needed
- * in case a system call gets restarted.
- */
-GLOBAL_ENTRY(ia64_invoke_schedule_tail)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
- alloc loc1=ar.pfs,8,2,1,0
- mov loc0=rp
- mov out0=r8 // Address of previous task
- ;;
- br.call.sptk.many rp=schedule_tail
-.ret11: mov ar.pfs=loc1
- mov rp=loc0
- br.ret.sptk.many rp
-END(ia64_invoke_schedule_tail)
-
- /*
- * Setup stack and call do_notify_resume_user(), keeping interrupts
- * disabled.
- *
- * Note that pSys and pNonSys need to be set up by the caller.
- * We declare 8 input registers so the system call args get preserved,
- * in case we need to restart a system call.
- */
-GLOBAL_ENTRY(notify_resume_user)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
- alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
- mov r9=ar.unat
- mov loc0=rp // save return address
- mov out0=0 // there is no "oldset"
- adds out1=8,sp // out1=&sigscratch->ar_pfs
-(pSys) mov out2=1 // out2==1 => we're in a syscall
- ;;
-(pNonSys) mov out2=0 // out2==0 => not a syscall
- .fframe 16
- .spillsp ar.unat, 16
- st8 [sp]=r9,-16 // allocate space for ar.unat and save it
- st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch
- .body
- br.call.sptk.many rp=do_notify_resume_user
-.ret15: .restore sp
- adds sp=16,sp // pop scratch stack space
- ;;
- ld8 r9=[sp] // load new unat from sigscratch->scratch_unat
- mov rp=loc0
- ;;
- mov ar.unat=r9
- mov ar.pfs=loc1
- br.ret.sptk.many rp
-END(notify_resume_user)
-
-ENTRY(sys_rt_sigreturn)
- PT_REGS_UNWIND_INFO(0)
- /*
- * Allocate 8 input registers since ptrace() may clobber them
- */
- alloc r2=ar.pfs,8,0,1,0
- .prologue
- PT_REGS_SAVES(16)
- adds sp=-16,sp
- .body
- cmp.eq pNonSys,pSys=r0,r0 // sigreturn isn't a normal syscall...
- ;;
- /*
- * leave_kernel() restores f6-f11 from pt_regs, but since the streamlined
- * syscall-entry path does not save them we save them here instead. Note: we
- * don't need to save any other registers that are not saved by the stream-lined
- * syscall path, because restore_sigcontext() restores them.
- */
- adds r16=PT(F6)+32,sp
- adds r17=PT(F7)+32,sp
- ;;
- stf.spill [r16]=f6,32
- stf.spill [r17]=f7,32
- ;;
- stf.spill [r16]=f8,32
- stf.spill [r17]=f9,32
- ;;
- stf.spill [r16]=f10
- stf.spill [r17]=f11
- adds out0=16,sp // out0 = &sigscratch
- br.call.sptk.many rp=ia64_rt_sigreturn
-.ret19: .restore sp,0
- adds sp=16,sp
- ;;
- ld8 r9=[sp] // load new ar.unat
- mov.sptk b7=r8,ia64_leave_kernel
- ;;
- mov ar.unat=r9
- br.many b7
-END(sys_rt_sigreturn)
-
-GLOBAL_ENTRY(ia64_prepare_handle_unaligned)
- .prologue
- /*
- * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
- */
- mov r16=r0
- DO_SAVE_SWITCH_STACK
- br.call.sptk.many rp=ia64_handle_unaligned // stack frame setup in ivt
-.ret21: .body
- DO_LOAD_SWITCH_STACK
- br.cond.sptk.many rp // goes to ia64_leave_kernel
-END(ia64_prepare_handle_unaligned)
-
- //
- // unw_init_running(void (*callback)(info, arg), void *arg)
- //
-# define EXTRA_FRAME_SIZE ((UNW_FRAME_INFO_SIZE+15)&~15)
-
-GLOBAL_ENTRY(unw_init_running)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
- alloc loc1=ar.pfs,2,3,3,0
- ;;
- ld8 loc2=[in0],8
- mov loc0=rp
- mov r16=loc1
- DO_SAVE_SWITCH_STACK
- .body
-
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
- .fframe IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE
- SWITCH_STACK_SAVES(EXTRA_FRAME_SIZE)
- adds sp=-EXTRA_FRAME_SIZE,sp
- .body
- ;;
- adds out0=16,sp // &info
- mov out1=r13 // current
- adds out2=16+EXTRA_FRAME_SIZE,sp // &switch_stack
- br.call.sptk.many rp=unw_init_frame_info
-1: adds out0=16,sp // &info
- mov b6=loc2
- mov loc2=gp // save gp across indirect function call
- ;;
- ld8 gp=[in0]
- mov out1=in1 // arg
- br.call.sptk.many rp=b6 // invoke the callback function
-1: mov gp=loc2 // restore gp
-
- // For now, we don't allow changing registers from within
- // unw_init_running; if we ever want to allow that, we'd
- // have to do a load_switch_stack here:
- .restore sp
- adds sp=IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE,sp
-
- mov ar.pfs=loc1
- mov rp=loc0
- br.ret.sptk.many rp
-END(unw_init_running)
-EXPORT_SYMBOL(unw_init_running)
-
-#ifdef CONFIG_FUNCTION_TRACER
-#ifdef CONFIG_DYNAMIC_FTRACE
-GLOBAL_ENTRY(_mcount)
- br ftrace_stub
-END(_mcount)
-EXPORT_SYMBOL(_mcount)
-
-.here:
- br.ret.sptk.many b0
-
-GLOBAL_ENTRY(ftrace_caller)
- alloc out0 = ar.pfs, 8, 0, 4, 0
- mov out3 = r0
- ;;
- mov out2 = b0
- add r3 = 0x20, r3
- mov out1 = r1;
- br.call.sptk.many b0 = ftrace_patch_gp
- //this might be called from module, so we must patch gp
-ftrace_patch_gp:
- movl gp=__gp
- mov b0 = r3
- ;;
-.global ftrace_call;
-ftrace_call:
-{
- .mlx
- nop.m 0x0
- movl r3 = .here;;
-}
- alloc loc0 = ar.pfs, 4, 4, 2, 0
- ;;
- mov loc1 = b0
- mov out0 = b0
- mov loc2 = r8
- mov loc3 = r15
- ;;
- adds out0 = -MCOUNT_INSN_SIZE, out0
- mov out1 = in2
- mov b6 = r3
-
- br.call.sptk.many b0 = b6
- ;;
- mov ar.pfs = loc0
- mov b0 = loc1
- mov r8 = loc2
- mov r15 = loc3
- br ftrace_stub
- ;;
-END(ftrace_caller)
-
-#else
-GLOBAL_ENTRY(_mcount)
- movl r2 = ftrace_stub
- movl r3 = ftrace_trace_function;;
- ld8 r3 = [r3];;
- ld8 r3 = [r3];;
- cmp.eq p7,p0 = r2, r3
-(p7) br.sptk.many ftrace_stub
- ;;
-
- alloc loc0 = ar.pfs, 4, 4, 2, 0
- ;;
- mov loc1 = b0
- mov out0 = b0
- mov loc2 = r8
- mov loc3 = r15
- ;;
- adds out0 = -MCOUNT_INSN_SIZE, out0
- mov out1 = in2
- mov b6 = r3
-
- br.call.sptk.many b0 = b6
- ;;
- mov ar.pfs = loc0
- mov b0 = loc1
- mov r8 = loc2
- mov r15 = loc3
- br ftrace_stub
- ;;
-END(_mcount)
-#endif
-
-GLOBAL_ENTRY(ftrace_stub)
- mov r3 = b0
- movl r2 = _mcount_ret_helper
- ;;
- mov b6 = r2
- mov b7 = r3
- br.ret.sptk.many b6
-
-_mcount_ret_helper:
- mov b0 = r42
- mov r1 = r41
- mov ar.pfs = r40
- br b7
-END(ftrace_stub)
-
-#endif /* CONFIG_FUNCTION_TRACER */
-
-#define __SYSCALL(nr, entry) data8 entry
- .rodata
- .align 8
- .globl sys_call_table
-sys_call_table:
-#include <asm/syscall_table.h>
diff --git a/arch/ia64/kernel/entry.h b/arch/ia64/kernel/entry.h
deleted file mode 100644
index 6463dc316263..000000000000
--- a/arch/ia64/kernel/entry.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/*
- * Preserved registers that are shared between code in ivt.S and
- * entry.S. Be careful not to step on these!
- */
-#define PRED_LEAVE_SYSCALL 1 /* TRUE iff leave from syscall */
-#define PRED_KERNEL_STACK 2 /* returning to kernel-stacks? */
-#define PRED_USER_STACK 3 /* returning to user-stacks? */
-#define PRED_SYSCALL 4 /* inside a system call? */
-#define PRED_NON_SYSCALL 5 /* complement of PRED_SYSCALL */
-
-#ifdef __ASSEMBLY__
-# define PASTE2(x,y) x##y
-# define PASTE(x,y) PASTE2(x,y)
-
-# define pLvSys PASTE(p,PRED_LEAVE_SYSCALL)
-# define pKStk PASTE(p,PRED_KERNEL_STACK)
-# define pUStk PASTE(p,PRED_USER_STACK)
-# define pSys PASTE(p,PRED_SYSCALL)
-# define pNonSys PASTE(p,PRED_NON_SYSCALL)
-#endif
-
-#define PT(f) (IA64_PT_REGS_##f##_OFFSET)
-#define SW(f) (IA64_SWITCH_STACK_##f##_OFFSET)
-#define SOS(f) (IA64_SAL_OS_STATE_##f##_OFFSET)
-
-#define PT_REGS_SAVES(off) \
- .unwabi 3, 'i'; \
- .fframe IA64_PT_REGS_SIZE+16+(off); \
- .spillsp rp, PT(CR_IIP)+16+(off); \
- .spillsp ar.pfs, PT(CR_IFS)+16+(off); \
- .spillsp ar.unat, PT(AR_UNAT)+16+(off); \
- .spillsp ar.fpsr, PT(AR_FPSR)+16+(off); \
- .spillsp pr, PT(PR)+16+(off);
-
-#define PT_REGS_UNWIND_INFO(off) \
- .prologue; \
- PT_REGS_SAVES(off); \
- .body
-
-#define SWITCH_STACK_SAVES(off) \
- .savesp ar.unat,SW(CALLER_UNAT)+16+(off); \
- .savesp ar.fpsr,SW(AR_FPSR)+16+(off); \
- .spillsp f2,SW(F2)+16+(off); .spillsp f3,SW(F3)+16+(off); \
- .spillsp f4,SW(F4)+16+(off); .spillsp f5,SW(F5)+16+(off); \
- .spillsp f16,SW(F16)+16+(off); .spillsp f17,SW(F17)+16+(off); \
- .spillsp f18,SW(F18)+16+(off); .spillsp f19,SW(F19)+16+(off); \
- .spillsp f20,SW(F20)+16+(off); .spillsp f21,SW(F21)+16+(off); \
- .spillsp f22,SW(F22)+16+(off); .spillsp f23,SW(F23)+16+(off); \
- .spillsp f24,SW(F24)+16+(off); .spillsp f25,SW(F25)+16+(off); \
- .spillsp f26,SW(F26)+16+(off); .spillsp f27,SW(F27)+16+(off); \
- .spillsp f28,SW(F28)+16+(off); .spillsp f29,SW(F29)+16+(off); \
- .spillsp f30,SW(F30)+16+(off); .spillsp f31,SW(F31)+16+(off); \
- .spillsp r4,SW(R4)+16+(off); .spillsp r5,SW(R5)+16+(off); \
- .spillsp r6,SW(R6)+16+(off); .spillsp r7,SW(R7)+16+(off); \
- .spillsp b0,SW(B0)+16+(off); .spillsp b1,SW(B1)+16+(off); \
- .spillsp b2,SW(B2)+16+(off); .spillsp b3,SW(B3)+16+(off); \
- .spillsp b4,SW(B4)+16+(off); .spillsp b5,SW(B5)+16+(off); \
- .spillsp ar.pfs,SW(AR_PFS)+16+(off); .spillsp ar.lc,SW(AR_LC)+16+(off); \
- .spillsp @priunat,SW(AR_UNAT)+16+(off); \
- .spillsp ar.rnat,SW(AR_RNAT)+16+(off); \
- .spillsp ar.bspstore,SW(AR_BSPSTORE)+16+(off); \
- .spillsp pr,SW(PR)+16+(off)
-
-#define DO_SAVE_SWITCH_STACK \
- movl r28=1f; \
- ;; \
- .fframe IA64_SWITCH_STACK_SIZE; \
- adds sp=-IA64_SWITCH_STACK_SIZE,sp; \
- mov.ret.sptk b7=r28,1f; \
- SWITCH_STACK_SAVES(0); \
- br.cond.sptk.many save_switch_stack; \
-1:
-
-#define DO_LOAD_SWITCH_STACK \
- movl r28=1f; \
- ;; \
- invala; \
- mov.ret.sptk b7=r28,1f; \
- br.cond.sptk.many load_switch_stack; \
-1: .restore sp; \
- adds sp=IA64_SWITCH_STACK_SIZE,sp
diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c
deleted file mode 100644
index dd5bfed52031..000000000000
--- a/arch/ia64/kernel/err_inject.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * err_inject.c -
- * 1.) Inject errors to a processor.
- * 2.) Query error injection capabilities.
- * This driver along with user space code can be acting as an error
- * injection tool.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Written by: Fenghua Yu <fenghua.yu@intel.com>, Intel Corporation
- * Copyright (C) 2006, Intel Corp. All rights reserved.
- *
- */
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/cpu.h>
-#include <linux/module.h>
-
-#define ERR_INJ_DEBUG
-
-#define ERR_DATA_BUFFER_SIZE 3 // Three 8-byte;
-
-#define define_one_ro(name) \
-static DEVICE_ATTR(name, 0444, show_##name, NULL)
-
-#define define_one_rw(name) \
-static DEVICE_ATTR(name, 0644, show_##name, store_##name)
-
-static u64 call_start[NR_CPUS];
-static u64 phys_addr[NR_CPUS];
-static u64 err_type_info[NR_CPUS];
-static u64 err_struct_info[NR_CPUS];
-static struct {
- u64 data1;
- u64 data2;
- u64 data3;
-} __attribute__((__aligned__(16))) err_data_buffer[NR_CPUS];
-static s64 status[NR_CPUS];
-static u64 capabilities[NR_CPUS];
-static u64 resources[NR_CPUS];
-
-#define show(name) \
-static ssize_t \
-show_##name(struct device *dev, struct device_attribute *attr, \
- char *buf) \
-{ \
- u32 cpu=dev->id; \
- return sprintf(buf, "%llx\n", name[cpu]); \
-}
-
-#define store(name) \
-static ssize_t \
-store_##name(struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t size) \
-{ \
- unsigned int cpu=dev->id; \
- name[cpu] = simple_strtoull(buf, NULL, 16); \
- return size; \
-}
-
-show(call_start)
-
-/* It's user's responsibility to call the PAL procedure on a specific
- * processor. The cpu number in driver is only used for storing data.
- */
-static ssize_t
-store_call_start(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t size)
-{
- unsigned int cpu=dev->id;
- unsigned long call_start = simple_strtoull(buf, NULL, 16);
-
-#ifdef ERR_INJ_DEBUG
- printk(KERN_DEBUG "pal_mc_err_inject for cpu%d:\n", cpu);
- printk(KERN_DEBUG "err_type_info=%llx,\n", err_type_info[cpu]);
- printk(KERN_DEBUG "err_struct_info=%llx,\n", err_struct_info[cpu]);
- printk(KERN_DEBUG "err_data_buffer=%llx, %llx, %llx.\n",
- err_data_buffer[cpu].data1,
- err_data_buffer[cpu].data2,
- err_data_buffer[cpu].data3);
-#endif
- switch (call_start) {
- case 0: /* Do nothing. */
- break;
- case 1: /* Call pal_mc_error_inject in physical mode. */
- status[cpu]=ia64_pal_mc_error_inject_phys(err_type_info[cpu],
- err_struct_info[cpu],
- ia64_tpa(&err_data_buffer[cpu]),
- &capabilities[cpu],
- &resources[cpu]);
- break;
- case 2: /* Call pal_mc_error_inject in virtual mode. */
- status[cpu]=ia64_pal_mc_error_inject_virt(err_type_info[cpu],
- err_struct_info[cpu],
- ia64_tpa(&err_data_buffer[cpu]),
- &capabilities[cpu],
- &resources[cpu]);
- break;
- default:
- status[cpu] = -EINVAL;
- break;
- }
-
-#ifdef ERR_INJ_DEBUG
- printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]);
- printk(KERN_DEBUG "capabilities=%llx,\n", capabilities[cpu]);
- printk(KERN_DEBUG "resources=%llx\n", resources[cpu]);
-#endif
- return size;
-}
-
-show(err_type_info)
-store(err_type_info)
-
-static ssize_t
-show_virtual_to_phys(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- unsigned int cpu=dev->id;
- return sprintf(buf, "%llx\n", phys_addr[cpu]);
-}
-
-static ssize_t
-store_virtual_to_phys(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t size)
-{
- unsigned int cpu=dev->id;
- u64 virt_addr=simple_strtoull(buf, NULL, 16);
- int ret;
-
- ret = get_user_pages_fast(virt_addr, 1, FOLL_WRITE, NULL);
- if (ret<=0) {
-#ifdef ERR_INJ_DEBUG
- printk("Virtual address %llx is not existing.\n", virt_addr);
-#endif
- return -EINVAL;
- }
-
- phys_addr[cpu] = ia64_tpa(virt_addr);
- return size;
-}
-
-show(err_struct_info)
-store(err_struct_info)
-
-static ssize_t
-show_err_data_buffer(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- unsigned int cpu=dev->id;
-
- return sprintf(buf, "%llx, %llx, %llx\n",
- err_data_buffer[cpu].data1,
- err_data_buffer[cpu].data2,
- err_data_buffer[cpu].data3);
-}
-
-static ssize_t
-store_err_data_buffer(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
-{
- unsigned int cpu=dev->id;
- int ret;
-
-#ifdef ERR_INJ_DEBUG
- printk("write err_data_buffer=[%llx,%llx,%llx] on cpu%d\n",
- err_data_buffer[cpu].data1,
- err_data_buffer[cpu].data2,
- err_data_buffer[cpu].data3,
- cpu);
-#endif
- ret = sscanf(buf, "%llx, %llx, %llx",
- &err_data_buffer[cpu].data1,
- &err_data_buffer[cpu].data2,
- &err_data_buffer[cpu].data3);
- if (ret!=ERR_DATA_BUFFER_SIZE)
- return -EINVAL;
-
- return size;
-}
-
-show(status)
-show(capabilities)
-show(resources)
-
-define_one_rw(call_start);
-define_one_rw(err_type_info);
-define_one_rw(err_struct_info);
-define_one_rw(err_data_buffer);
-define_one_rw(virtual_to_phys);
-define_one_ro(status);
-define_one_ro(capabilities);
-define_one_ro(resources);
-
-static struct attribute *default_attrs[] = {
- &dev_attr_call_start.attr,
- &dev_attr_virtual_to_phys.attr,
- &dev_attr_err_type_info.attr,
- &dev_attr_err_struct_info.attr,
- &dev_attr_err_data_buffer.attr,
- &dev_attr_status.attr,
- &dev_attr_capabilities.attr,
- &dev_attr_resources.attr,
- NULL
-};
-
-static struct attribute_group err_inject_attr_group = {
- .attrs = default_attrs,
- .name = "err_inject"
-};
-/* Add/Remove err_inject interface for CPU device */
-static int err_inject_add_dev(unsigned int cpu)
-{
- struct device *sys_dev = get_cpu_device(cpu);
-
- return sysfs_create_group(&sys_dev->kobj, &err_inject_attr_group);
-}
-
-static int err_inject_remove_dev(unsigned int cpu)
-{
- struct device *sys_dev = get_cpu_device(cpu);
-
- sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group);
- return 0;
-}
-
-static enum cpuhp_state hp_online;
-
-static int __init err_inject_init(void)
-{
- int ret;
-#ifdef ERR_INJ_DEBUG
- printk(KERN_INFO "Enter error injection driver.\n");
-#endif
-
- ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "ia64/err_inj:online",
- err_inject_add_dev, err_inject_remove_dev);
- if (ret >= 0) {
- hp_online = ret;
- ret = 0;
- }
- return ret;
-}
-
-static void __exit err_inject_exit(void)
-{
-#ifdef ERR_INJ_DEBUG
- printk(KERN_INFO "Exit error injection driver.\n");
-#endif
- cpuhp_remove_state(hp_online);
-}
-
-module_init(err_inject_init);
-module_exit(err_inject_exit);
-
-MODULE_AUTHOR("Fenghua Yu <fenghua.yu@intel.com>");
-MODULE_DESCRIPTION("MC error injection kernel sysfs interface");
-MODULE_LICENSE("GPL");
diff --git a/arch/ia64/kernel/esi.c b/arch/ia64/kernel/esi.c
deleted file mode 100644
index 4df57c93e0a8..000000000000
--- a/arch/ia64/kernel/esi.c
+++ /dev/null
@@ -1,193 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Extensible SAL Interface (ESI) support routines.
- *
- * Copyright (C) 2006 Hewlett-Packard Co
- * Alex Williamson <alex.williamson@hp.com>
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-#include <asm/esi.h>
-#include <asm/sal.h>
-
-MODULE_AUTHOR("Alex Williamson <alex.williamson@hp.com>");
-MODULE_DESCRIPTION("Extensible SAL Interface (ESI) support");
-MODULE_LICENSE("GPL");
-
-#define MODULE_NAME "esi"
-
-enum esi_systab_entry_type {
- ESI_DESC_ENTRY_POINT = 0
-};
-
-/*
- * Entry type: Size:
- * 0 48
- */
-#define ESI_DESC_SIZE(type) "\060"[(unsigned) (type)]
-
-typedef struct ia64_esi_desc_entry_point {
- u8 type;
- u8 reserved1[15];
- u64 esi_proc;
- u64 gp;
- efi_guid_t guid;
-} ia64_esi_desc_entry_point_t;
-
-struct pdesc {
- void *addr;
- void *gp;
-};
-
-static struct ia64_sal_systab *esi_systab;
-
-extern unsigned long esi_phys;
-
-static int __init esi_init (void)
-{
- struct ia64_sal_systab *systab;
- char *p;
- int i;
-
- if (esi_phys == EFI_INVALID_TABLE_ADDR)
- return -ENODEV;
-
- systab = __va(esi_phys);
-
- if (strncmp(systab->signature, "ESIT", 4) != 0) {
- printk(KERN_ERR "bad signature in ESI system table!");
- return -ENODEV;
- }
-
- p = (char *) (systab + 1);
- for (i = 0; i < systab->entry_count; i++) {
- /*
- * The first byte of each entry type contains the type
- * descriptor.
- */
- switch (*p) {
- case ESI_DESC_ENTRY_POINT:
- break;
- default:
- printk(KERN_WARNING "Unknown table type %d found in "
- "ESI table, ignoring rest of table\n", *p);
- return -ENODEV;
- }
-
- p += ESI_DESC_SIZE(*p);
- }
-
- esi_systab = systab;
- return 0;
-}
-
-
-int ia64_esi_call (efi_guid_t guid, struct ia64_sal_retval *isrvp,
- enum esi_proc_type proc_type, u64 func,
- u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6,
- u64 arg7)
-{
- struct ia64_fpreg fr[6];
- unsigned long flags = 0;
- int i;
- char *p;
-
- if (!esi_systab)
- return -1;
-
- p = (char *) (esi_systab + 1);
- for (i = 0; i < esi_systab->entry_count; i++) {
- if (*p == ESI_DESC_ENTRY_POINT) {
- ia64_esi_desc_entry_point_t *esi = (void *)p;
- if (!efi_guidcmp(guid, esi->guid)) {
- ia64_sal_handler esi_proc;
- struct pdesc pdesc;
-
- pdesc.addr = __va(esi->esi_proc);
- pdesc.gp = __va(esi->gp);
-
- esi_proc = (ia64_sal_handler) &pdesc;
-
- ia64_save_scratch_fpregs(fr);
- if (proc_type == ESI_PROC_SERIALIZED)
- spin_lock_irqsave(&sal_lock, flags);
- else if (proc_type == ESI_PROC_MP_SAFE)
- local_irq_save(flags);
- else
- preempt_disable();
- *isrvp = (*esi_proc)(func, arg1, arg2, arg3,
- arg4, arg5, arg6, arg7);
- if (proc_type == ESI_PROC_SERIALIZED)
- spin_unlock_irqrestore(&sal_lock,
- flags);
- else if (proc_type == ESI_PROC_MP_SAFE)
- local_irq_restore(flags);
- else
- preempt_enable();
- ia64_load_scratch_fpregs(fr);
- return 0;
- }
- }
- p += ESI_DESC_SIZE(*p);
- }
- return -1;
-}
-EXPORT_SYMBOL_GPL(ia64_esi_call);
-
-int ia64_esi_call_phys (efi_guid_t guid, struct ia64_sal_retval *isrvp,
- u64 func, u64 arg1, u64 arg2, u64 arg3, u64 arg4,
- u64 arg5, u64 arg6, u64 arg7)
-{
- struct ia64_fpreg fr[6];
- unsigned long flags;
- u64 esi_params[8];
- char *p;
- int i;
-
- if (!esi_systab)
- return -1;
-
- p = (char *) (esi_systab + 1);
- for (i = 0; i < esi_systab->entry_count; i++) {
- if (*p == ESI_DESC_ENTRY_POINT) {
- ia64_esi_desc_entry_point_t *esi = (void *)p;
- if (!efi_guidcmp(guid, esi->guid)) {
- ia64_sal_handler esi_proc;
- struct pdesc pdesc;
-
- pdesc.addr = (void *)esi->esi_proc;
- pdesc.gp = (void *)esi->gp;
-
- esi_proc = (ia64_sal_handler) &pdesc;
-
- esi_params[0] = func;
- esi_params[1] = arg1;
- esi_params[2] = arg2;
- esi_params[3] = arg3;
- esi_params[4] = arg4;
- esi_params[5] = arg5;
- esi_params[6] = arg6;
- esi_params[7] = arg7;
- ia64_save_scratch_fpregs(fr);
- spin_lock_irqsave(&sal_lock, flags);
- *isrvp = esi_call_phys(esi_proc, esi_params);
- spin_unlock_irqrestore(&sal_lock, flags);
- ia64_load_scratch_fpregs(fr);
- return 0;
- }
- }
- p += ESI_DESC_SIZE(*p);
- }
- return -1;
-}
-EXPORT_SYMBOL_GPL(ia64_esi_call_phys);
-
-static void __exit esi_exit (void)
-{
-}
-
-module_init(esi_init);
-module_exit(esi_exit); /* makes module removable... */
diff --git a/arch/ia64/kernel/esi_stub.S b/arch/ia64/kernel/esi_stub.S
deleted file mode 100644
index 9928c5b2957c..000000000000
--- a/arch/ia64/kernel/esi_stub.S
+++ /dev/null
@@ -1,99 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * ESI call stub.
- *
- * Copyright (C) 2005 Hewlett-Packard Co
- * Alex Williamson <alex.williamson@hp.com>
- *
- * Based on EFI call stub by David Mosberger. The stub is virtually
- * identical to the one for EFI phys-mode calls, except that ESI
- * calls may have up to 8 arguments, so they get passed to this routine
- * through memory.
- *
- * This stub allows us to make ESI calls in physical mode with interrupts
- * turned off. ESI calls may not support calling from virtual mode.
- *
- * Google for "Extensible SAL specification" for a document describing the
- * ESI standard.
- */
-
-/*
- * PSR settings as per SAL spec (Chapter 8 in the "IA-64 System
- * Abstraction Layer Specification", revision 2.6e). Note that
- * psr.dfl and psr.dfh MUST be cleared, despite what this manual says.
- * Otherwise, SAL dies whenever it's trying to do an IA-32 BIOS call
- * (the br.ia instruction fails unless psr.dfl and psr.dfh are
- * cleared). Fortunately, SAL promises not to touch the floating
- * point regs, so at least we don't have to save f2-f127.
- */
-#define PSR_BITS_TO_CLEAR \
- (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT | \
- IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \
- IA64_PSR_DFL | IA64_PSR_DFH)
-
-#define PSR_BITS_TO_SET \
- (IA64_PSR_BN)
-
-#include <linux/export.h>
-#include <asm/processor.h>
-#include <asm/asmmacro.h>
-
-/*
- * Inputs:
- * in0 = address of function descriptor of ESI routine to call
- * in1 = address of array of ESI parameters
- *
- * Outputs:
- * r8 = result returned by called function
- */
-GLOBAL_ENTRY(esi_call_phys)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
- alloc loc1=ar.pfs,2,7,8,0
- ld8 r2=[in0],8 // load ESI function's entry point
- mov loc0=rp
- .body
- ;;
- ld8 out0=[in1],8 // ESI params loaded from array
- ;; // passing all as inputs doesn't work
- ld8 out1=[in1],8
- ;;
- ld8 out2=[in1],8
- ;;
- ld8 out3=[in1],8
- ;;
- ld8 out4=[in1],8
- ;;
- ld8 out5=[in1],8
- ;;
- ld8 out6=[in1],8
- ;;
- ld8 out7=[in1]
- mov loc2=gp // save global pointer
- mov loc4=ar.rsc // save RSE configuration
- mov ar.rsc=0 // put RSE in enforced lazy, LE mode
- ;;
- ld8 gp=[in0] // load ESI function's global pointer
- movl r16=PSR_BITS_TO_CLEAR
- mov loc3=psr // save processor status word
- movl r17=PSR_BITS_TO_SET
- ;;
- or loc3=loc3,r17
- mov b6=r2
- ;;
- andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared
- br.call.sptk.many rp=ia64_switch_mode_phys
-.ret0: mov loc5=r19 // old ar.bsp
- mov loc6=r20 // old sp
- br.call.sptk.many rp=b6 // call the ESI function
-.ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode
- mov r16=loc3 // save virtual mode psr
- mov r19=loc5 // save virtual mode bspstore
- mov r20=loc6 // save virtual mode sp
- br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
-.ret2: mov ar.rsc=loc4 // restore RSE configuration
- mov ar.pfs=loc1
- mov rp=loc0
- mov gp=loc2
- br.ret.sptk.many rp
-END(esi_call_phys)
-EXPORT_SYMBOL_GPL(esi_call_phys)
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
deleted file mode 100644
index cc4733e9990a..000000000000
--- a/arch/ia64/kernel/fsys.S
+++ /dev/null
@@ -1,837 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file contains the light-weight system call handlers (fsyscall-handlers).
- *
- * Copyright (C) 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 25-Sep-03 davidm Implement fsys_rt_sigprocmask().
- * 18-Feb-03 louisk Implement fsys_gettimeofday().
- * 28-Feb-03 davidm Fixed several bugs in fsys_gettimeofday(). Tuned it some more,
- * probably broke it along the way... ;-)
- * 13-Jul-04 clameter Implement fsys_clock_gettime and revise fsys_gettimeofday to make
- * it capable of using memory based clocks without falling back to C code.
- * 08-Feb-07 Fenghua Yu Implement fsys_getcpu.
- *
- */
-
-#include <asm/asmmacro.h>
-#include <asm/errno.h>
-#include <asm/asm-offsets.h>
-#include <asm/percpu.h>
-#include <asm/thread_info.h>
-#include <asm/sal.h>
-#include <asm/signal.h>
-#include <asm/unistd.h>
-
-#include "entry.h"
-#include <asm/native/inst.h>
-
-/*
- * See Documentation/arch/ia64/fsys.rst for details on fsyscalls.
- *
- * On entry to an fsyscall handler:
- * r10 = 0 (i.e., defaults to "successful syscall return")
- * r11 = saved ar.pfs (a user-level value)
- * r15 = system call number
- * r16 = "current" task pointer (in normal kernel-mode, this is in r13)
- * r32-r39 = system call arguments
- * b6 = return address (a user-level value)
- * ar.pfs = previous frame-state (a user-level value)
- * PSR.be = cleared to zero (i.e., little-endian byte order is in effect)
- * all other registers may contain values passed in from user-mode
- *
- * On return from an fsyscall handler:
- * r11 = saved ar.pfs (as passed into the fsyscall handler)
- * r15 = system call number (as passed into the fsyscall handler)
- * r32-r39 = system call arguments (as passed into the fsyscall handler)
- * b6 = return address (as passed into the fsyscall handler)
- * ar.pfs = previous frame-state (as passed into the fsyscall handler)
- */
-
-ENTRY(fsys_ni_syscall)
- .prologue
- .altrp b6
- .body
- mov r8=ENOSYS
- mov r10=-1
- FSYS_RETURN
-END(fsys_ni_syscall)
-
-ENTRY(fsys_getpid)
- .prologue
- .altrp b6
- .body
- add r17=IA64_TASK_SIGNAL_OFFSET,r16
- ;;
- ld8 r17=[r17] // r17 = current->signal
- add r9=TI_FLAGS+IA64_TASK_SIZE,r16
- ;;
- ld4 r9=[r9]
- add r17=IA64_SIGNAL_PIDS_TGID_OFFSET,r17
- ;;
- and r9=TIF_ALLWORK_MASK,r9
- ld8 r17=[r17] // r17 = current->signal->pids[PIDTYPE_TGID]
- ;;
- add r8=IA64_PID_LEVEL_OFFSET,r17
- ;;
- ld4 r8=[r8] // r8 = pid->level
- add r17=IA64_PID_UPID_OFFSET,r17 // r17 = &pid->numbers[0]
- ;;
- shl r8=r8,IA64_UPID_SHIFT
- ;;
- add r17=r17,r8 // r17 = &pid->numbers[pid->level]
- ;;
- ld4 r8=[r17] // r8 = pid->numbers[pid->level].nr
- ;;
- mov r17=0
- ;;
- cmp.ne p8,p0=0,r9
-(p8) br.spnt.many fsys_fallback_syscall
- FSYS_RETURN
-END(fsys_getpid)
-
-ENTRY(fsys_set_tid_address)
- .prologue
- .altrp b6
- .body
- add r9=TI_FLAGS+IA64_TASK_SIZE,r16
- add r17=IA64_TASK_THREAD_PID_OFFSET,r16
- ;;
- ld4 r9=[r9]
- tnat.z p6,p7=r32 // check argument register for being NaT
- ld8 r17=[r17] // r17 = current->thread_pid
- ;;
- and r9=TIF_ALLWORK_MASK,r9
- add r8=IA64_PID_LEVEL_OFFSET,r17
- add r18=IA64_TASK_CLEAR_CHILD_TID_OFFSET,r16
- ;;
- ld4 r8=[r8] // r8 = pid->level
- add r17=IA64_PID_UPID_OFFSET,r17 // r17 = &pid->numbers[0]
- ;;
- shl r8=r8,IA64_UPID_SHIFT
- ;;
- add r17=r17,r8 // r17 = &pid->numbers[pid->level]
- ;;
- ld4 r8=[r17] // r8 = pid->numbers[pid->level].nr
- ;;
- cmp.ne p8,p0=0,r9
- mov r17=-1
- ;;
-(p6) st8 [r18]=r32
-(p7) st8 [r18]=r17
-(p8) br.spnt.many fsys_fallback_syscall
- ;;
- mov r17=0 // i must not leak kernel bits...
- mov r18=0 // i must not leak kernel bits...
- FSYS_RETURN
-END(fsys_set_tid_address)
-
-#if IA64_GTOD_SEQ_OFFSET !=0
-#error fsys_gettimeofday incompatible with changes to struct fsyscall_gtod_data_t
-#endif
-#if IA64_ITC_JITTER_OFFSET !=0
-#error fsys_gettimeofday incompatible with changes to struct itc_jitter_data_t
-#endif
-#define CLOCK_REALTIME 0
-#define CLOCK_MONOTONIC 1
-#define CLOCK_DIVIDE_BY_1000 0x4000
-#define CLOCK_ADD_MONOTONIC 0x8000
-
-ENTRY(fsys_gettimeofday)
- .prologue
- .altrp b6
- .body
- mov r31 = r32
- tnat.nz p6,p0 = r33 // guard against NaT argument
-(p6) br.cond.spnt.few .fail_einval
- mov r30 = CLOCK_DIVIDE_BY_1000
- ;;
-.gettime:
- // Register map
- // Incoming r31 = pointer to address where to place result
- // r30 = flags determining how time is processed
- // r2,r3 = temp r4-r7 preserved
- // r8 = result nanoseconds
- // r9 = result seconds
- // r10 = temporary storage for clock difference
- // r11 = preserved: saved ar.pfs
- // r12 = preserved: memory stack
- // r13 = preserved: thread pointer
- // r14 = address of mask / mask value
- // r15 = preserved: system call number
- // r16 = preserved: current task pointer
- // r17 = (not used)
- // r18 = (not used)
- // r19 = address of itc_lastcycle
- // r20 = struct fsyscall_gtod_data (= address of gtod_lock.sequence)
- // r21 = address of mmio_ptr
- // r22 = address of wall_time or monotonic_time
- // r23 = address of shift / value
- // r24 = address mult factor / cycle_last value
- // r25 = itc_lastcycle value
- // r26 = address clocksource cycle_last
- // r27 = (not used)
- // r28 = sequence number at the beginning of critical section
- // r29 = address of itc_jitter
- // r30 = time processing flags / memory address
- // r31 = pointer to result
- // Predicates
- // p6,p7 short term use
- // p8 = timesource ar.itc
- // p9 = timesource mmio64
- // p10 = timesource mmio32 - not used
- // p11 = timesource not to be handled by asm code
- // p12 = memory time source ( = p9 | p10) - not used
- // p13 = do cmpxchg with itc_lastcycle
- // p14 = Divide by 1000
- // p15 = Add monotonic
- //
- // Note that instructions are optimized for McKinley. McKinley can
- // process two bundles simultaneously and therefore we continuously
- // try to feed the CPU two bundles and then a stop.
-
- add r2 = TI_FLAGS+IA64_TASK_SIZE,r16
- tnat.nz p6,p0 = r31 // guard against Nat argument
-(p6) br.cond.spnt.few .fail_einval
- movl r20 = fsyscall_gtod_data // load fsyscall gettimeofday data address
- ;;
- ld4 r2 = [r2] // process work pending flags
- movl r29 = itc_jitter_data // itc_jitter
- add r22 = IA64_GTOD_WALL_TIME_OFFSET,r20 // wall_time
- add r21 = IA64_CLKSRC_MMIO_OFFSET,r20
- mov pr = r30,0xc000 // Set predicates according to function
- ;;
- and r2 = TIF_ALLWORK_MASK,r2
- add r19 = IA64_ITC_LASTCYCLE_OFFSET,r29
-(p15) add r22 = IA64_GTOD_MONO_TIME_OFFSET,r20 // monotonic_time
- ;;
- add r26 = IA64_CLKSRC_CYCLE_LAST_OFFSET,r20 // clksrc_cycle_last
- cmp.ne p6, p0 = 0, r2 // Fallback if work is scheduled
-(p6) br.cond.spnt.many fsys_fallback_syscall
- ;;
- // Begin critical section
-.time_redo:
- ld4.acq r28 = [r20] // gtod_lock.sequence, Must take first
- ;;
- and r28 = ~1,r28 // And make sequence even to force retry if odd
- ;;
- ld8 r30 = [r21] // clocksource->mmio_ptr
- add r24 = IA64_CLKSRC_MULT_OFFSET,r20
- ld4 r2 = [r29] // itc_jitter value
- add r23 = IA64_CLKSRC_SHIFT_OFFSET,r20
- add r14 = IA64_CLKSRC_MASK_OFFSET,r20
- ;;
- ld4 r3 = [r24] // clocksource mult value
- ld8 r14 = [r14] // clocksource mask value
- cmp.eq p8,p9 = 0,r30 // use cpu timer if no mmio_ptr
- ;;
- setf.sig f7 = r3 // Setup for mult scaling of counter
-(p8) cmp.ne p13,p0 = r2,r0 // need itc_jitter compensation, set p13
- ld4 r23 = [r23] // clocksource shift value
- ld8 r24 = [r26] // get clksrc_cycle_last value
-(p9) cmp.eq p13,p0 = 0,r30 // if mmio_ptr, clear p13 jitter control
- ;;
- .pred.rel.mutex p8,p9
- MOV_FROM_ITC(p8, p6, r2, r10) // CPU_TIMER. 36 clocks latency!!!
-(p9) ld8 r2 = [r30] // MMIO_TIMER. Could also have latency issues..
-(p13) ld8 r25 = [r19] // get itc_lastcycle value
- ld8 r9 = [r22],IA64_TIME_SN_SPEC_SNSEC_OFFSET // sec
- ;;
- ld8 r8 = [r22],-IA64_TIME_SN_SPEC_SNSEC_OFFSET // snsec
-(p13) sub r3 = r25,r2 // Diff needed before comparison (thanks davidm)
- ;;
-(p13) cmp.gt.unc p6,p7 = r3,r0 // check if it is less than last. p6,p7 cleared
- sub r10 = r2,r24 // current_cycle - last_cycle
- ;;
-(p6) sub r10 = r25,r24 // time we got was less than last_cycle
-(p7) mov ar.ccv = r25 // more than last_cycle. Prep for cmpxchg
- ;;
-(p7) cmpxchg8.rel r3 = [r19],r2,ar.ccv
- ;;
-(p7) cmp.ne p7,p0 = r25,r3 // if cmpxchg not successful
- ;;
-(p7) sub r10 = r3,r24 // then use new last_cycle instead
- ;;
- and r10 = r10,r14 // Apply mask
- ;;
- setf.sig f8 = r10
- nop.i 123
- ;;
- // fault check takes 5 cycles and we have spare time
-EX(.fail_efault, probe.w.fault r31, 3)
- xmpy.l f8 = f8,f7 // nsec_per_cyc*(counter-last_counter)
- ;;
- getf.sig r2 = f8
- mf
- ;;
- ld4 r10 = [r20] // gtod_lock.sequence
- add r8 = r8,r2 // Add xtime.nsecs
- ;;
- shr.u r8 = r8,r23 // shift by factor
- cmp4.ne p7,p0 = r28,r10
-(p7) br.cond.dpnt.few .time_redo // sequence number changed, redo
- // End critical section.
- // Now r8=tv->tv_nsec and r9=tv->tv_sec
- mov r10 = r0
- movl r2 = 1000000000
- add r23 = IA64_TIMESPEC_TV_NSEC_OFFSET, r31
-(p14) movl r3 = 2361183241434822607 // Prep for / 1000 hack
- ;;
-.time_normalize:
- mov r21 = r8
- cmp.ge p6,p0 = r8,r2
-(p14) shr.u r20 = r8, 3 // We can repeat this if necessary just wasting time
- ;;
-(p14) setf.sig f8 = r20
-(p6) sub r8 = r8,r2
-(p6) add r9 = 1,r9 // two nops before the branch.
-(p14) setf.sig f7 = r3 // Chances for repeats are 1 in 10000 for gettod
-(p6) br.cond.dpnt.few .time_normalize
- ;;
- // Divided by 8 though shift. Now divide by 125
- // The compiler was able to do that with a multiply
- // and a shift and we do the same
-EX(.fail_efault, probe.w.fault r23, 3) // This also costs 5 cycles
-(p14) xmpy.hu f8 = f8, f7 // xmpy has 5 cycles latency so use it
- ;;
-(p14) getf.sig r2 = f8
- ;;
- mov r8 = r0
-(p14) shr.u r21 = r2, 4
- ;;
-EX(.fail_efault, st8 [r31] = r9)
-EX(.fail_efault, st8 [r23] = r21)
- FSYS_RETURN
-.fail_einval:
- mov r8 = EINVAL
- mov r10 = -1
- FSYS_RETURN
-.fail_efault:
- mov r8 = EFAULT
- mov r10 = -1
- FSYS_RETURN
-END(fsys_gettimeofday)
-
-ENTRY(fsys_clock_gettime)
- .prologue
- .altrp b6
- .body
- cmp4.ltu p6, p0 = CLOCK_MONOTONIC, r32
- // Fallback if this is not CLOCK_REALTIME or CLOCK_MONOTONIC
-(p6) br.spnt.few fsys_fallback_syscall
- mov r31 = r33
- shl r30 = r32,15
- br.many .gettime
-END(fsys_clock_gettime)
-
-/*
- * fsys_getcpu doesn't use the third parameter in this implementation. It reads
- * current_thread_info()->cpu and corresponding node in cpu_to_node_map.
- */
-ENTRY(fsys_getcpu)
- .prologue
- .altrp b6
- .body
- ;;
- add r2=TI_FLAGS+IA64_TASK_SIZE,r16
- tnat.nz p6,p0 = r32 // guard against NaT argument
- add r3=TI_CPU+IA64_TASK_SIZE,r16
- ;;
- ld4 r3=[r3] // M r3 = thread_info->cpu
- ld4 r2=[r2] // M r2 = thread_info->flags
-(p6) br.cond.spnt.few .fail_einval // B
- ;;
- tnat.nz p7,p0 = r33 // I guard against NaT argument
-(p7) br.cond.spnt.few .fail_einval // B
- ;;
- cmp.ne p6,p0=r32,r0
- cmp.ne p7,p0=r33,r0
- ;;
-#ifdef CONFIG_NUMA
- movl r17=cpu_to_node_map
- ;;
-EX(.fail_efault, (p6) probe.w.fault r32, 3) // M This takes 5 cycles
-EX(.fail_efault, (p7) probe.w.fault r33, 3) // M This takes 5 cycles
- shladd r18=r3,1,r17
- ;;
- ld2 r20=[r18] // r20 = cpu_to_node_map[cpu]
- and r2 = TIF_ALLWORK_MASK,r2
- ;;
- cmp.ne p8,p0=0,r2
-(p8) br.spnt.many fsys_fallback_syscall
- ;;
- ;;
-EX(.fail_efault, (p6) st4 [r32] = r3)
-EX(.fail_efault, (p7) st2 [r33] = r20)
- mov r8=0
- ;;
-#else
-EX(.fail_efault, (p6) probe.w.fault r32, 3) // M This takes 5 cycles
-EX(.fail_efault, (p7) probe.w.fault r33, 3) // M This takes 5 cycles
- and r2 = TIF_ALLWORK_MASK,r2
- ;;
- cmp.ne p8,p0=0,r2
-(p8) br.spnt.many fsys_fallback_syscall
- ;;
-EX(.fail_efault, (p6) st4 [r32] = r3)
-EX(.fail_efault, (p7) st2 [r33] = r0)
- mov r8=0
- ;;
-#endif
- FSYS_RETURN
-END(fsys_getcpu)
-
-ENTRY(fsys_fallback_syscall)
- .prologue
- .altrp b6
- .body
- /*
- * We only get here from light-weight syscall handlers. Thus, we already
- * know that r15 contains a valid syscall number. No need to re-check.
- */
- adds r17=-1024,r15
- movl r14=sys_call_table
- ;;
- RSM_PSR_I(p0, r26, r27)
- shladd r18=r17,3,r14
- ;;
- ld8 r18=[r18] // load normal (heavy-weight) syscall entry-point
- MOV_FROM_PSR(p0, r29, r26) // read psr (12 cyc load latency)
- mov r27=ar.rsc
- mov r21=ar.fpsr
- mov r26=ar.pfs
-END(fsys_fallback_syscall)
- /* FALL THROUGH */
-GLOBAL_ENTRY(fsys_bubble_down)
- .prologue
- .altrp b6
- .body
- /*
- * We get here for syscalls that don't have a lightweight
- * handler. For those, we need to bubble down into the kernel
- * and that requires setting up a minimal pt_regs structure,
- * and initializing the CPU state more or less as if an
- * interruption had occurred. To make syscall-restarts work,
- * we setup pt_regs such that cr_iip points to the second
- * instruction in syscall_via_break. Decrementing the IP
- * hence will restart the syscall via break and not
- * decrementing IP will return us to the caller, as usual.
- * Note that we preserve the value of psr.pp rather than
- * initializing it from dcr.pp. This makes it possible to
- * distinguish fsyscall execution from other privileged
- * execution.
- *
- * On entry:
- * - normal fsyscall handler register usage, except
- * that we also have:
- * - r18: address of syscall entry point
- * - r21: ar.fpsr
- * - r26: ar.pfs
- * - r27: ar.rsc
- * - r29: psr
- *
- * We used to clear some PSR bits here but that requires slow
- * serialization. Fortunately, that isn't really necessary.
- * The rationale is as follows: we used to clear bits
- * ~PSR_PRESERVED_BITS in PSR.L. Since
- * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we
- * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}.
- * However,
- *
- * PSR.BE : already is turned off in __kernel_syscall_via_epc()
- * PSR.AC : don't care (kernel normally turns PSR.AC on)
- * PSR.I : already turned off by the time fsys_bubble_down gets
- * invoked
- * PSR.DFL: always 0 (kernel never turns it on)
- * PSR.DFH: don't care --- kernel never touches f32-f127 on its own
- * initiative
- * PSR.DI : always 0 (kernel never turns it on)
- * PSR.SI : always 0 (kernel never turns it on)
- * PSR.DB : don't care --- kernel never enables kernel-level
- * breakpoints
- * PSR.TB : must be 0 already; if it wasn't zero on entry to
- * __kernel_syscall_via_epc, the branch to fsys_bubble_down
- * will trigger a taken branch; the taken-trap-handler then
- * converts the syscall into a break-based system-call.
- */
- /*
- * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc.
- * The rest we have to synthesize.
- */
-# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) \
- | (0x1 << IA64_PSR_RI_BIT) \
- | IA64_PSR_BN | IA64_PSR_I)
-
- invala // M0|1
- movl r14=ia64_ret_from_syscall // X
-
- nop.m 0
- movl r28=__kernel_syscall_via_break // X create cr.iip
- ;;
-
- mov r2=r16 // A get task addr to addl-addressable register
- adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A
- mov r31=pr // I0 save pr (2 cyc)
- ;;
- st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag
- addl r22=IA64_RBS_OFFSET,r2 // A compute base of RBS
- add r3=TI_FLAGS+IA64_TASK_SIZE,r2 // A
- ;;
- ld4 r3=[r3] // M0|1 r3 = current_thread_info()->flags
- lfetch.fault.excl.nt1 [r22] // M0|1 prefetch register backing-store
- nop.i 0
- ;;
- mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- MOV_FROM_ITC(p0, p6, r30, r23) // M get cycle for accounting
-#else
- nop.m 0
-#endif
- nop.i 0
- ;;
- mov r23=ar.bspstore // M2 (12 cyc) save ar.bspstore
- mov.m r24=ar.rnat // M2 (5 cyc) read ar.rnat (dual-issues!)
- nop.i 0
- ;;
- mov ar.bspstore=r22 // M2 (6 cyc) switch to kernel RBS
- movl r8=PSR_ONE_BITS // X
- ;;
- mov r25=ar.unat // M2 (5 cyc) save ar.unat
- mov r19=b6 // I0 save b6 (2 cyc)
- mov r20=r1 // A save caller's gp in r20
- ;;
- or r29=r8,r29 // A construct cr.ipsr value to save
- mov b6=r18 // I0 copy syscall entry-point to b6 (7 cyc)
- addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack
-
- mov r18=ar.bsp // M2 save (kernel) ar.bsp (12 cyc)
- cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1
- br.call.sptk.many b7=ia64_syscall_setup // B
- ;;
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- // mov.m r30=ar.itc is called in advance
- add r16=TI_AC_STAMP+IA64_TASK_SIZE,r2
- add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r2
- ;;
- ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP // time at last check in kernel
- ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE // time at leave kernel
- ;;
- ld8 r20=[r16],TI_AC_STAMP-TI_AC_STIME // cumulated stime
- ld8 r21=[r17] // cumulated utime
- sub r22=r19,r18 // stime before leave kernel
- ;;
- st8 [r16]=r30,TI_AC_STIME-TI_AC_STAMP // update stamp
- sub r18=r30,r19 // elapsed time in user mode
- ;;
- add r20=r20,r22 // sum stime
- add r21=r21,r18 // sum utime
- ;;
- st8 [r16]=r20 // update stime
- st8 [r17]=r21 // update utime
- ;;
-#endif
- mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
- mov rp=r14 // I0 set the real return addr
- and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A
- ;;
- SSM_PSR_I(p0, p6, r22) // M2 we're on kernel stacks now, reenable irqs
- cmp.eq p8,p0=r3,r0 // A
-(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
-
- nop.m 0
-(p8) br.call.sptk.many b6=b6 // B (ignore return address)
- br.cond.spnt ia64_trace_syscall // B
-END(fsys_bubble_down)
-
- .rodata
- .align 8
- .globl fsyscall_table
-
- data8 fsys_bubble_down
-fsyscall_table:
- data8 fsys_ni_syscall
- data8 0 // exit // 1025
- data8 0 // read
- data8 0 // write
- data8 0 // open
- data8 0 // close
- data8 0 // creat // 1030
- data8 0 // link
- data8 0 // unlink
- data8 0 // execve
- data8 0 // chdir
- data8 0 // fchdir // 1035
- data8 0 // utimes
- data8 0 // mknod
- data8 0 // chmod
- data8 0 // chown
- data8 0 // lseek // 1040
- data8 fsys_getpid // getpid
- data8 0 // getppid
- data8 0 // mount
- data8 0 // umount
- data8 0 // setuid // 1045
- data8 0 // getuid
- data8 0 // geteuid
- data8 0 // ptrace
- data8 0 // access
- data8 0 // sync // 1050
- data8 0 // fsync
- data8 0 // fdatasync
- data8 0 // kill
- data8 0 // rename
- data8 0 // mkdir // 1055
- data8 0 // rmdir
- data8 0 // dup
- data8 0 // pipe
- data8 0 // times
- data8 0 // brk // 1060
- data8 0 // setgid
- data8 0 // getgid
- data8 0 // getegid
- data8 0 // acct
- data8 0 // ioctl // 1065
- data8 0 // fcntl
- data8 0 // umask
- data8 0 // chroot
- data8 0 // ustat
- data8 0 // dup2 // 1070
- data8 0 // setreuid
- data8 0 // setregid
- data8 0 // getresuid
- data8 0 // setresuid
- data8 0 // getresgid // 1075
- data8 0 // setresgid
- data8 0 // getgroups
- data8 0 // setgroups
- data8 0 // getpgid
- data8 0 // setpgid // 1080
- data8 0 // setsid
- data8 0 // getsid
- data8 0 // sethostname
- data8 0 // setrlimit
- data8 0 // getrlimit // 1085
- data8 0 // getrusage
- data8 fsys_gettimeofday // gettimeofday
- data8 0 // settimeofday
- data8 0 // select
- data8 0 // poll // 1090
- data8 0 // symlink
- data8 0 // readlink
- data8 0 // uselib
- data8 0 // swapon
- data8 0 // swapoff // 1095
- data8 0 // reboot
- data8 0 // truncate
- data8 0 // ftruncate
- data8 0 // fchmod
- data8 0 // fchown // 1100
- data8 0 // getpriority
- data8 0 // setpriority
- data8 0 // statfs
- data8 0 // fstatfs
- data8 0 // gettid // 1105
- data8 0 // semget
- data8 0 // semop
- data8 0 // semctl
- data8 0 // msgget
- data8 0 // msgsnd // 1110
- data8 0 // msgrcv
- data8 0 // msgctl
- data8 0 // shmget
- data8 0 // shmat
- data8 0 // shmdt // 1115
- data8 0 // shmctl
- data8 0 // syslog
- data8 0 // setitimer
- data8 0 // getitimer
- data8 0 // 1120
- data8 0
- data8 0
- data8 0 // vhangup
- data8 0 // lchown
- data8 0 // remap_file_pages // 1125
- data8 0 // wait4
- data8 0 // sysinfo
- data8 0 // clone
- data8 0 // setdomainname
- data8 0 // newuname // 1130
- data8 0 // adjtimex
- data8 0
- data8 0 // init_module
- data8 0 // delete_module
- data8 0 // 1135
- data8 0
- data8 0 // quotactl
- data8 0 // bdflush
- data8 0 // sysfs
- data8 0 // personality // 1140
- data8 0 // afs_syscall
- data8 0 // setfsuid
- data8 0 // setfsgid
- data8 0 // getdents
- data8 0 // flock // 1145
- data8 0 // readv
- data8 0 // writev
- data8 0 // pread64
- data8 0 // pwrite64
- data8 0 // sysctl // 1150
- data8 0 // mmap
- data8 0 // munmap
- data8 0 // mlock
- data8 0 // mlockall
- data8 0 // mprotect // 1155
- data8 0 // mremap
- data8 0 // msync
- data8 0 // munlock
- data8 0 // munlockall
- data8 0 // sched_getparam // 1160
- data8 0 // sched_setparam
- data8 0 // sched_getscheduler
- data8 0 // sched_setscheduler
- data8 0 // sched_yield
- data8 0 // sched_get_priority_max // 1165
- data8 0 // sched_get_priority_min
- data8 0 // sched_rr_get_interval
- data8 0 // nanosleep
- data8 0 // nfsservctl
- data8 0 // prctl // 1170
- data8 0 // getpagesize
- data8 0 // mmap2
- data8 0 // pciconfig_read
- data8 0 // pciconfig_write
- data8 0 // perfmonctl // 1175
- data8 0 // sigaltstack
- data8 0 // rt_sigaction
- data8 0 // rt_sigpending
- data8 0 // rt_sigprocmask
- data8 0 // rt_sigqueueinfo // 1180
- data8 0 // rt_sigreturn
- data8 0 // rt_sigsuspend
- data8 0 // rt_sigtimedwait
- data8 0 // getcwd
- data8 0 // capget // 1185
- data8 0 // capset
- data8 0 // sendfile
- data8 0
- data8 0
- data8 0 // socket // 1190
- data8 0 // bind
- data8 0 // connect
- data8 0 // listen
- data8 0 // accept
- data8 0 // getsockname // 1195
- data8 0 // getpeername
- data8 0 // socketpair
- data8 0 // send
- data8 0 // sendto
- data8 0 // recv // 1200
- data8 0 // recvfrom
- data8 0 // shutdown
- data8 0 // setsockopt
- data8 0 // getsockopt
- data8 0 // sendmsg // 1205
- data8 0 // recvmsg
- data8 0 // pivot_root
- data8 0 // mincore
- data8 0 // madvise
- data8 0 // newstat // 1210
- data8 0 // newlstat
- data8 0 // newfstat
- data8 0 // clone2
- data8 0 // getdents64
- data8 0 // getunwind // 1215
- data8 0 // readahead
- data8 0 // setxattr
- data8 0 // lsetxattr
- data8 0 // fsetxattr
- data8 0 // getxattr // 1220
- data8 0 // lgetxattr
- data8 0 // fgetxattr
- data8 0 // listxattr
- data8 0 // llistxattr
- data8 0 // flistxattr // 1225
- data8 0 // removexattr
- data8 0 // lremovexattr
- data8 0 // fremovexattr
- data8 0 // tkill
- data8 0 // futex // 1230
- data8 0 // sched_setaffinity
- data8 0 // sched_getaffinity
- data8 fsys_set_tid_address // set_tid_address
- data8 0 // fadvise64_64
- data8 0 // tgkill // 1235
- data8 0 // exit_group
- data8 0 // lookup_dcookie
- data8 0 // io_setup
- data8 0 // io_destroy
- data8 0 // io_getevents // 1240
- data8 0 // io_submit
- data8 0 // io_cancel
- data8 0 // epoll_create
- data8 0 // epoll_ctl
- data8 0 // epoll_wait // 1245
- data8 0 // restart_syscall
- data8 0 // semtimedop
- data8 0 // timer_create
- data8 0 // timer_settime
- data8 0 // timer_gettime // 1250
- data8 0 // timer_getoverrun
- data8 0 // timer_delete
- data8 0 // clock_settime
- data8 fsys_clock_gettime // clock_gettime
- data8 0 // clock_getres // 1255
- data8 0 // clock_nanosleep
- data8 0 // fstatfs64
- data8 0 // statfs64
- data8 0 // mbind
- data8 0 // get_mempolicy // 1260
- data8 0 // set_mempolicy
- data8 0 // mq_open
- data8 0 // mq_unlink
- data8 0 // mq_timedsend
- data8 0 // mq_timedreceive // 1265
- data8 0 // mq_notify
- data8 0 // mq_getsetattr
- data8 0 // kexec_load
- data8 0 // vserver
- data8 0 // waitid // 1270
- data8 0 // add_key
- data8 0 // request_key
- data8 0 // keyctl
- data8 0 // ioprio_set
- data8 0 // ioprio_get // 1275
- data8 0 // move_pages
- data8 0 // inotify_init
- data8 0 // inotify_add_watch
- data8 0 // inotify_rm_watch
- data8 0 // migrate_pages // 1280
- data8 0 // openat
- data8 0 // mkdirat
- data8 0 // mknodat
- data8 0 // fchownat
- data8 0 // futimesat // 1285
- data8 0 // newfstatat
- data8 0 // unlinkat
- data8 0 // renameat
- data8 0 // linkat
- data8 0 // symlinkat // 1290
- data8 0 // readlinkat
- data8 0 // fchmodat
- data8 0 // faccessat
- data8 0
- data8 0 // 1295
- data8 0 // unshare
- data8 0 // splice
- data8 0 // set_robust_list
- data8 0 // get_robust_list
- data8 0 // sync_file_range // 1300
- data8 0 // tee
- data8 0 // vmsplice
- data8 0
- data8 fsys_getcpu // getcpu // 1304
-
- // fill in zeros for the remaining entries
- .zero:
- .space fsyscall_table + 8*NR_syscalls - .zero, 0
diff --git a/arch/ia64/kernel/fsyscall_gtod_data.h b/arch/ia64/kernel/fsyscall_gtod_data.h
deleted file mode 100644
index cc2861445965..000000000000
--- a/arch/ia64/kernel/fsyscall_gtod_data.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
- * Contributed by Peter Keilty <peter.keilty@hp.com>
- *
- * fsyscall gettimeofday data
- */
-
-/* like timespec, but includes "shifted nanoseconds" */
-struct time_sn_spec {
- u64 sec;
- u64 snsec;
-};
-
-struct fsyscall_gtod_data_t {
- seqcount_t seq;
- struct time_sn_spec wall_time;
- struct time_sn_spec monotonic_time;
- u64 clk_mask;
- u32 clk_mult;
- u32 clk_shift;
- void *clk_fsys_mmio;
- u64 clk_cycle_last;
-} ____cacheline_aligned;
-
-struct itc_jitter_data_t {
- int itc_jitter;
- u64 itc_lastcycle;
-} ____cacheline_aligned;
-
diff --git a/arch/ia64/kernel/ftrace.c b/arch/ia64/kernel/ftrace.c
deleted file mode 100644
index d6360fd404ab..000000000000
--- a/arch/ia64/kernel/ftrace.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Dynamic function tracing support.
- *
- * Copyright (C) 2008 Shaohua Li <shaohua.li@intel.com>
- *
- * For licencing details, see COPYING.
- *
- * Defines low-level handling of mcount calls when the kernel
- * is compiled with the -pg flag. When using dynamic ftrace, the
- * mcount call-sites get patched lazily with NOP till they are
- * enabled. All code mutation routines here take effect atomically.
- */
-
-#include <linux/uaccess.h>
-#include <linux/ftrace.h>
-
-#include <asm/cacheflush.h>
-#include <asm/patch.h>
-
-/* In IA64, each function will be added below two bundles with -pg option */
-static unsigned char __attribute__((aligned(8)))
-ftrace_orig_code[MCOUNT_INSN_SIZE] = {
- 0x02, 0x40, 0x31, 0x10, 0x80, 0x05, /* alloc r40=ar.pfs,12,8,0 */
- 0xb0, 0x02, 0x00, 0x00, 0x42, 0x40, /* mov r43=r0;; */
- 0x05, 0x00, 0xc4, 0x00, /* mov r42=b0 */
- 0x11, 0x48, 0x01, 0x02, 0x00, 0x21, /* mov r41=r1 */
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
- 0x08, 0x00, 0x00, 0x50 /* br.call.sptk.many b0 = _mcount;; */
-};
-
-struct ftrace_orig_insn {
- u64 dummy1, dummy2, dummy3;
- u64 dummy4:64-41+13;
- u64 imm20:20;
- u64 dummy5:3;
- u64 sign:1;
- u64 dummy6:4;
-};
-
-/* mcount stub will be converted below for nop */
-static unsigned char ftrace_nop_code[MCOUNT_INSN_SIZE] = {
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0x0 */
- 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, /* mov r3=ip */
- 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0 */
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0x0 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* nop.x 0x0;; */
- 0x00, 0x00, 0x04, 0x00
-};
-
-static unsigned char *ftrace_nop_replace(void)
-{
- return ftrace_nop_code;
-}
-
-/*
- * mcount stub will be converted below for call
- * Note: Just the last instruction is changed against nop
- * */
-static unsigned char __attribute__((aligned(8)))
-ftrace_call_code[MCOUNT_INSN_SIZE] = {
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0x0 */
- 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, /* mov r3=ip */
- 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0 */
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0x0 */
- 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, /* brl.many .;;*/
- 0xf8, 0xff, 0xff, 0xc8
-};
-
-struct ftrace_call_insn {
- u64 dummy1, dummy2;
- u64 dummy3:48;
- u64 imm39_l:16;
- u64 imm39_h:23;
- u64 dummy4:13;
- u64 imm20:20;
- u64 dummy5:3;
- u64 i:1;
- u64 dummy6:4;
-};
-
-static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
-{
- struct ftrace_call_insn *code = (void *)ftrace_call_code;
- unsigned long offset = addr - (ip + 0x10);
-
- code->imm39_l = offset >> 24;
- code->imm39_h = offset >> 40;
- code->imm20 = offset >> 4;
- code->i = offset >> 63;
- return ftrace_call_code;
-}
-
-static int
-ftrace_modify_code(unsigned long ip, unsigned char *old_code,
- unsigned char *new_code, int do_check)
-{
- unsigned char replaced[MCOUNT_INSN_SIZE];
-
- /*
- * Note:
- * We are paranoid about modifying text, as if a bug was to happen, it
- * could cause us to read or write to someplace that could cause harm.
- * Carefully read and modify the code with probe_kernel_*(), and make
- * sure what we read is what we expected it to be before modifying it.
- */
-
- if (!do_check)
- goto skip_check;
-
- /* read the text we want to modify */
- if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE))
- return -EFAULT;
-
- /* Make sure it is what we expect it to be */
- if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
- return -EINVAL;
-
-skip_check:
- /* replace the text with the new text */
- if (copy_to_kernel_nofault(((void *)ip), new_code, MCOUNT_INSN_SIZE))
- return -EPERM;
- flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
-
- return 0;
-}
-
-static int ftrace_make_nop_check(struct dyn_ftrace *rec, unsigned long addr)
-{
- unsigned char __attribute__((aligned(8))) replaced[MCOUNT_INSN_SIZE];
- unsigned long ip = rec->ip;
-
- if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE))
- return -EFAULT;
- if (rec->flags & FTRACE_FL_CONVERTED) {
- struct ftrace_call_insn *call_insn, *tmp_call;
-
- call_insn = (void *)ftrace_call_code;
- tmp_call = (void *)replaced;
- call_insn->imm39_l = tmp_call->imm39_l;
- call_insn->imm39_h = tmp_call->imm39_h;
- call_insn->imm20 = tmp_call->imm20;
- call_insn->i = tmp_call->i;
- if (memcmp(replaced, ftrace_call_code, MCOUNT_INSN_SIZE) != 0)
- return -EINVAL;
- return 0;
- } else {
- struct ftrace_orig_insn *call_insn, *tmp_call;
-
- call_insn = (void *)ftrace_orig_code;
- tmp_call = (void *)replaced;
- call_insn->sign = tmp_call->sign;
- call_insn->imm20 = tmp_call->imm20;
- if (memcmp(replaced, ftrace_orig_code, MCOUNT_INSN_SIZE) != 0)
- return -EINVAL;
- return 0;
- }
-}
-
-int ftrace_make_nop(struct module *mod,
- struct dyn_ftrace *rec, unsigned long addr)
-{
- int ret;
- char *new;
-
- ret = ftrace_make_nop_check(rec, addr);
- if (ret)
- return ret;
- new = ftrace_nop_replace();
- return ftrace_modify_code(rec->ip, NULL, new, 0);
-}
-
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
-{
- unsigned long ip = rec->ip;
- unsigned char *old, *new;
-
- old= ftrace_nop_replace();
- new = ftrace_call_replace(ip, addr);
- return ftrace_modify_code(ip, old, new, 1);
-}
-
-/* in IA64, _mcount can't directly call ftrace_stub. Only jump is ok */
-int ftrace_update_ftrace_func(ftrace_func_t func)
-{
- unsigned long ip;
- unsigned long addr = ((struct fnptr *)ftrace_call)->ip;
-
- if (func == ftrace_stub)
- return 0;
- ip = ((struct fnptr *)func)->ip;
-
- ia64_patch_imm64(addr + 2, ip);
-
- flush_icache_range(addr, addr + 16);
- return 0;
-}
diff --git a/arch/ia64/kernel/gate-data.S b/arch/ia64/kernel/gate-data.S
deleted file mode 100644
index b3ef1c72e132..000000000000
--- a/arch/ia64/kernel/gate-data.S
+++ /dev/null
@@ -1,3 +0,0 @@
- .section .data..gate, "aw"
-
- .incbin "arch/ia64/kernel/gate.so"
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
deleted file mode 100644
index 9f235cd551ab..000000000000
--- a/arch/ia64/kernel/gate.S
+++ /dev/null
@@ -1,380 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file contains the code that gets mapped at the upper end of each task's text
- * region. For now, it contains the signal trampoline code only.
- *
- * Copyright (C) 1999-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-
-#include <asm/asmmacro.h>
-#include <asm/errno.h>
-#include <asm/asm-offsets.h>
-#include <asm/sigcontext.h>
-#include <asm/unistd.h>
-#include <asm/kregs.h>
-#include <asm/page.h>
-#include <asm/native/inst.h>
-
-/*
- * We can't easily refer to symbols inside the kernel. To avoid full runtime relocation,
- * complications with the linker (which likes to create PLT stubs for branches
- * to targets outside the shared object) and to avoid multi-phase kernel builds, we
- * simply create minimalistic "patch lists" in special ELF sections.
- */
- .section ".data..patch.fsyscall_table", "a"
- .previous
-#define LOAD_FSYSCALL_TABLE(reg) \
-[1:] movl reg=0; \
- .xdata4 ".data..patch.fsyscall_table", 1b-.
-
- .section ".data..patch.brl_fsys_bubble_down", "a"
- .previous
-#define BRL_COND_FSYS_BUBBLE_DOWN(pr) \
-[1:](pr)brl.cond.sptk 0; \
- ;; \
- .xdata4 ".data..patch.brl_fsys_bubble_down", 1b-.
-
-GLOBAL_ENTRY(__kernel_syscall_via_break)
- .prologue
- .altrp b6
- .body
- /*
- * Note: for (fast) syscall restart to work, the break instruction must be
- * the first one in the bundle addressed by syscall_via_break.
- */
-{ .mib
- break 0x100000
- nop.i 0
- br.ret.sptk.many b6
-}
-END(__kernel_syscall_via_break)
-
-# define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET)
-# define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET)
-# define ARG2_OFF (16 + IA64_SIGFRAME_ARG2_OFFSET)
-# define SIGHANDLER_OFF (16 + IA64_SIGFRAME_HANDLER_OFFSET)
-# define SIGCONTEXT_OFF (16 + IA64_SIGFRAME_SIGCONTEXT_OFFSET)
-
-# define FLAGS_OFF IA64_SIGCONTEXT_FLAGS_OFFSET
-# define CFM_OFF IA64_SIGCONTEXT_CFM_OFFSET
-# define FR6_OFF IA64_SIGCONTEXT_FR6_OFFSET
-# define BSP_OFF IA64_SIGCONTEXT_AR_BSP_OFFSET
-# define RNAT_OFF IA64_SIGCONTEXT_AR_RNAT_OFFSET
-# define UNAT_OFF IA64_SIGCONTEXT_AR_UNAT_OFFSET
-# define FPSR_OFF IA64_SIGCONTEXT_AR_FPSR_OFFSET
-# define PR_OFF IA64_SIGCONTEXT_PR_OFFSET
-# define RP_OFF IA64_SIGCONTEXT_IP_OFFSET
-# define SP_OFF IA64_SIGCONTEXT_R12_OFFSET
-# define RBS_BASE_OFF IA64_SIGCONTEXT_RBS_BASE_OFFSET
-# define LOADRS_OFF IA64_SIGCONTEXT_LOADRS_OFFSET
-# define base0 r2
-# define base1 r3
- /*
- * When we get here, the memory stack looks like this:
- *
- * +===============================+
- * | |
- * // struct sigframe //
- * | |
- * +-------------------------------+ <-- sp+16
- * | 16 byte of scratch |
- * | space |
- * +-------------------------------+ <-- sp
- *
- * The register stack looks _exactly_ the way it looked at the time the signal
- * occurred. In other words, we're treading on a potential mine-field: each
- * incoming general register may be a NaT value (including sp, in which case the
- * process ends up dying with a SIGSEGV).
- *
- * The first thing need to do is a cover to get the registers onto the backing
- * store. Once that is done, we invoke the signal handler which may modify some
- * of the machine state. After returning from the signal handler, we return
- * control to the previous context by executing a sigreturn system call. A signal
- * handler may call the rt_sigreturn() function to directly return to a given
- * sigcontext. However, the user-level sigreturn() needs to do much more than
- * calling the rt_sigreturn() system call as it needs to unwind the stack to
- * restore preserved registers that may have been saved on the signal handler's
- * call stack.
- */
-
-#define SIGTRAMP_SAVES \
- .unwabi 3, 's'; /* mark this as a sigtramp handler (saves scratch regs) */ \
- .unwabi @svr4, 's'; /* backwards compatibility with old unwinders (remove in v2.7) */ \
- .savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF; \
- .savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF; \
- .savesp pr, PR_OFF+SIGCONTEXT_OFF; \
- .savesp rp, RP_OFF+SIGCONTEXT_OFF; \
- .savesp ar.pfs, CFM_OFF+SIGCONTEXT_OFF; \
- .vframesp SP_OFF+SIGCONTEXT_OFF
-
-GLOBAL_ENTRY(__kernel_sigtramp)
- // describe the state that is active when we get here:
- .prologue
- SIGTRAMP_SAVES
- .body
-
- .label_state 1
-
- adds base0=SIGHANDLER_OFF,sp
- adds base1=RBS_BASE_OFF+SIGCONTEXT_OFF,sp
- br.call.sptk.many rp=1f
-1:
- ld8 r17=[base0],(ARG0_OFF-SIGHANDLER_OFF) // get pointer to signal handler's plabel
- ld8 r15=[base1] // get address of new RBS base (or NULL)
- cover // push args in interrupted frame onto backing store
- ;;
- cmp.ne p1,p0=r15,r0 // do we need to switch rbs? (note: pr is saved by kernel)
- mov.m r9=ar.bsp // fetch ar.bsp
- .spillsp.p p1, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
-(p1) br.cond.spnt setup_rbs // yup -> (clobbers p8, r14-r16, and r18-r20)
-back_from_setup_rbs:
- alloc r8=ar.pfs,0,0,3,0
- ld8 out0=[base0],16 // load arg0 (signum)
- adds base1=(ARG1_OFF-(RBS_BASE_OFF+SIGCONTEXT_OFF)),base1
- ;;
- ld8 out1=[base1] // load arg1 (siginfop)
- ld8 r10=[r17],8 // get signal handler entry point
- ;;
- ld8 out2=[base0] // load arg2 (sigcontextp)
- ld8 gp=[r17] // get signal handler's global pointer
- adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
- ;;
- .spillsp ar.bsp, BSP_OFF+SIGCONTEXT_OFF
- st8 [base0]=r9 // save sc_ar_bsp
- adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
- adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
- ;;
- stf.spill [base0]=f6,32
- stf.spill [base1]=f7,32
- ;;
- stf.spill [base0]=f8,32
- stf.spill [base1]=f9,32
- mov b6=r10
- ;;
- stf.spill [base0]=f10,32
- stf.spill [base1]=f11,32
- ;;
- stf.spill [base0]=f12,32
- stf.spill [base1]=f13,32
- ;;
- stf.spill [base0]=f14,32
- stf.spill [base1]=f15,32
- br.call.sptk.many rp=b6 // call the signal handler
-.ret0: adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
- ;;
- ld8 r15=[base0] // fetch sc_ar_bsp
- mov r14=ar.bsp
- ;;
- cmp.ne p1,p0=r14,r15 // do we need to restore the rbs?
-(p1) br.cond.spnt restore_rbs // yup -> (clobbers r14-r18, f6 & f7)
- ;;
-back_from_restore_rbs:
- adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
- adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
- ;;
- ldf.fill f6=[base0],32
- ldf.fill f7=[base1],32
- ;;
- ldf.fill f8=[base0],32
- ldf.fill f9=[base1],32
- ;;
- ldf.fill f10=[base0],32
- ldf.fill f11=[base1],32
- ;;
- ldf.fill f12=[base0],32
- ldf.fill f13=[base1],32
- ;;
- ldf.fill f14=[base0],32
- ldf.fill f15=[base1],32
- mov r15=__NR_rt_sigreturn
- .restore sp // pop .prologue
- break __BREAK_SYSCALL
-
- .prologue
- SIGTRAMP_SAVES
-setup_rbs:
- mov ar.rsc=0 // put RSE into enforced lazy mode
- ;;
- .save ar.rnat, r19
- mov r19=ar.rnat // save RNaT before switching backing store area
- adds r14=(RNAT_OFF+SIGCONTEXT_OFF),sp
-
- mov r18=ar.bspstore
- mov ar.bspstore=r15 // switch over to new register backing store area
- ;;
-
- .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
- st8 [r14]=r19 // save sc_ar_rnat
- .body
- mov.m r16=ar.bsp // sc_loadrs <- (new bsp - new bspstore) << 16
- adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp
- ;;
- invala
- sub r15=r16,r15
- extr.u r20=r18,3,6
- ;;
- mov ar.rsc=0xf // set RSE into eager mode, pl 3
- cmp.eq p8,p0=63,r20
- shl r15=r15,16
- ;;
- st8 [r14]=r15 // save sc_loadrs
-(p8) st8 [r18]=r19 // if bspstore points at RNaT slot, store RNaT there now
- .restore sp // pop .prologue
- br.cond.sptk back_from_setup_rbs
-
- .prologue
- SIGTRAMP_SAVES
- .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
- .body
-restore_rbs:
- // On input:
- // r14 = bsp1 (bsp at the time of return from signal handler)
- // r15 = bsp0 (bsp at the time the signal occurred)
- //
- // Here, we need to calculate bspstore0, the value that ar.bspstore needs
- // to be set to, based on bsp0 and the size of the dirty partition on
- // the alternate stack (sc_loadrs >> 16). This can be done with the
- // following algorithm:
- //
- // bspstore0 = rse_skip_regs(bsp0, -rse_num_regs(bsp1 - (loadrs >> 19), bsp1));
- //
- // This is what the code below does.
- //
- alloc r2=ar.pfs,0,0,0,0 // alloc null frame
- adds r16=(LOADRS_OFF+SIGCONTEXT_OFF),sp
- adds r18=(RNAT_OFF+SIGCONTEXT_OFF),sp
- ;;
- ld8 r17=[r16]
- ld8 r16=[r18] // get new rnat
- extr.u r18=r15,3,6 // r18 <- rse_slot_num(bsp0)
- ;;
- mov ar.rsc=r17 // put RSE into enforced lazy mode
- shr.u r17=r17,16
- ;;
- sub r14=r14,r17 // r14 (bspstore1) <- bsp1 - (sc_loadrs >> 16)
- shr.u r17=r17,3 // r17 <- (sc_loadrs >> 19)
- ;;
- loadrs // restore dirty partition
- extr.u r14=r14,3,6 // r14 <- rse_slot_num(bspstore1)
- ;;
- add r14=r14,r17 // r14 <- rse_slot_num(bspstore1) + (sc_loadrs >> 19)
- ;;
- shr.u r14=r14,6 // r14 <- (rse_slot_num(bspstore1) + (sc_loadrs >> 19))/0x40
- ;;
- sub r14=r14,r17 // r14 <- -rse_num_regs(bspstore1, bsp1)
- movl r17=0x8208208208208209
- ;;
- add r18=r18,r14 // r18 (delta) <- rse_slot_num(bsp0) - rse_num_regs(bspstore1,bsp1)
- setf.sig f7=r17
- cmp.lt p7,p0=r14,r0 // p7 <- (r14 < 0)?
- ;;
-(p7) adds r18=-62,r18 // delta -= 62
- ;;
- setf.sig f6=r18
- ;;
- xmpy.h f6=f6,f7
- ;;
- getf.sig r17=f6
- ;;
- add r17=r17,r18
- shr r18=r18,63
- ;;
- shr r17=r17,5
- ;;
- sub r17=r17,r18 // r17 = delta/63
- ;;
- add r17=r14,r17 // r17 <- delta/63 - rse_num_regs(bspstore1, bsp1)
- ;;
- shladd r15=r17,3,r15 // r15 <- bsp0 + 8*(delta/63 - rse_num_regs(bspstore1, bsp1))
- ;;
- mov ar.bspstore=r15 // switch back to old register backing store area
- ;;
- mov ar.rnat=r16 // restore RNaT
- mov ar.rsc=0xf // (will be restored later on from sc_ar_rsc)
- // invala not necessary as that will happen when returning to user-mode
- br.cond.sptk back_from_restore_rbs
-END(__kernel_sigtramp)
-
-/*
- * On entry:
- * r11 = saved ar.pfs
- * r15 = system call #
- * b0 = saved return address
- * b6 = return address
- * On exit:
- * r11 = saved ar.pfs
- * r15 = system call #
- * b0 = saved return address
- * all other "scratch" registers: undefined
- * all "preserved" registers: same as on entry
- */
-
-GLOBAL_ENTRY(__kernel_syscall_via_epc)
- .prologue
- .altrp b6
- .body
-{
- /*
- * Note: the kernel cannot assume that the first two instructions in this
- * bundle get executed. The remaining code must be safe even if
- * they do not get executed.
- */
- adds r17=-1024,r15 // A
- mov r10=0 // A default to successful syscall execution
- epc // B causes split-issue
-}
- ;;
- RSM_PSR_BE_I(r20, r22) // M2 (5 cyc to srlz.d)
- LOAD_FSYSCALL_TABLE(r14) // X
- ;;
- mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
- shladd r18=r17,3,r14 // A
- mov r19=NR_syscalls-1 // A
- ;;
- lfetch [r18] // M0|1
- MOV_FROM_PSR(p0, r29, r8) // M2 (12 cyc)
- // If r17 is a NaT, p6 will be zero
- cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
- ;;
- mov r21=ar.fpsr // M2 (12 cyc)
- tnat.nz p10,p9=r15 // I0
- mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
- ;;
- srlz.d // M0 (forces split-issue) ensure PSR.BE==0
-(p6) ld8 r18=[r18] // M0|1
- nop.i 0
- ;;
- nop.m 0
-(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
- nop.i 0
- ;;
- SSM_PSR_I(p8, p14, r25)
-(p6) mov b7=r18 // I0
-(p8) br.dptk.many b7 // B
-
- mov r27=ar.rsc // M2 (12 cyc)
-/*
- * brl.cond doesn't work as intended because the linker would convert this branch
- * into a branch to a PLT. Perhaps there will be a way to avoid this with some
- * future version of the linker. In the meantime, we just use an indirect branch
- * instead.
- */
-#ifdef CONFIG_ITANIUM
-(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
- ;;
-(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
- ;;
-(p6) mov b7=r14
-(p6) br.sptk.many b7
-#else
- BRL_COND_FSYS_BUBBLE_DOWN(p6)
-#endif
- SSM_PSR_I(p0, p14, r10)
- mov r10=-1
-(p10) mov r8=EINVAL
-(p9) mov r8=ENOSYS
- FSYS_RETURN
-
-END(__kernel_syscall_via_epc)
diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S
deleted file mode 100644
index 461c7e69d465..000000000000
--- a/arch/ia64/kernel/gate.lds.S
+++ /dev/null
@@ -1,108 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Linker script for gate DSO. The gate pages are an ELF shared object
- * prelinked to its virtual address, with only one read-only segment and
- * one execute-only segment (both fit in one page). This script controls
- * its layout.
- */
-
-#include <asm/page.h>
-
-SECTIONS
-{
- . = GATE_ADDR + SIZEOF_HEADERS;
-
- .hash : { *(.hash) } :readable
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
-
- .note : { *(.note*) } :readable :note
-
- .dynamic : { *(.dynamic) } :readable :dynamic
-
- /*
- * This linker script is used both with -r and with -shared. For
- * the layouts to match, we need to skip more than enough space for
- * the dynamic symbol table et al. If this amount is insufficient,
- * ld -shared will barf. Just increase it here.
- */
- . = GATE_ADDR + 0x600;
-
- .data..patch : {
- __start_gate_mckinley_e9_patchlist = .;
- *(.data..patch.mckinley_e9)
- __end_gate_mckinley_e9_patchlist = .;
-
- __start_gate_vtop_patchlist = .;
- *(.data..patch.vtop)
- __end_gate_vtop_patchlist = .;
-
- __start_gate_fsyscall_patchlist = .;
- *(.data..patch.fsyscall_table)
- __end_gate_fsyscall_patchlist = .;
-
- __start_gate_brl_fsys_bubble_down_patchlist = .;
- *(.data..patch.brl_fsys_bubble_down)
- __end_gate_brl_fsys_bubble_down_patchlist = .;
- } :readable
-
- .IA_64.unwind_info : { *(.IA_64.unwind_info*) }
- .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind
-#ifdef HAVE_BUGGY_SEGREL
- .text (GATE_ADDR + PAGE_SIZE) : { *(.text) *(.text.*) } :readable
-#else
- . = ALIGN(PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1));
- .text : { *(.text) *(.text.*) } :epc
-#endif
-
- /DISCARD/ : {
- *(.got.plt) *(.got)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(__ex_table)
- *(__mca_table)
- }
-}
-
-/*
- * ld does not recognize this name token; use the constant.
- */
-#define PT_IA_64_UNWIND 0x70000001
-
-/*
- * We must supply the ELF program headers explicitly to get just one
- * PT_LOAD segment, and set the flags explicitly to make segments read-only.
- */
-PHDRS
-{
- readable PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */
-#ifndef HAVE_BUGGY_SEGREL
- epc PT_LOAD FILEHDR PHDRS FLAGS(1); /* PF_X */
-#endif
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- note PT_NOTE FLAGS(4); /* PF_R */
- unwind PT_IA_64_UNWIND;
-}
-
-/*
- * This controls what symbols we export from the DSO.
- */
-VERSION
-{
- LINUX_2.5 {
- global:
- __kernel_syscall_via_break;
- __kernel_syscall_via_epc;
- __kernel_sigtramp;
-
- local: *;
- };
-}
-
-/* The ELF entry point can be used to set the AT_SYSINFO value. */
-ENTRY(__kernel_syscall_via_epc)
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
deleted file mode 100644
index 85c8a57da402..000000000000
--- a/arch/ia64/kernel/head.S
+++ /dev/null
@@ -1,1167 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Here is where the ball gets rolling as far as the kernel is concerned.
- * When control is transferred to _start, the bootload has already
- * loaded us to the correct address. All that's left to do here is
- * to set up the kernel's global pointer and jump to the kernel
- * entry point.
- *
- * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999 Intel Corp.
- * Copyright (C) 1999 Asit Mallick <Asit.K.Mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <Don.Dugger@intel.com>
- * Copyright (C) 2002 Fenghua Yu <fenghua.yu@intel.com>
- * -Optimize __ia64_save_fpu() and __ia64_load_fpu() for Itanium 2.
- * Copyright (C) 2004 Ashok Raj <ashok.raj@intel.com>
- * Support for CPU Hotplug
- */
-
-#include <linux/export.h>
-#include <linux/pgtable.h>
-#include <asm/asmmacro.h>
-#include <asm/fpu.h>
-#include <asm/kregs.h>
-#include <asm/mmu_context.h>
-#include <asm/asm-offsets.h>
-#include <asm/pal.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/mca_asm.h>
-#include <linux/init.h>
-#include <linux/linkage.h>
-
-#ifdef CONFIG_HOTPLUG_CPU
-#define SAL_PSR_BITS_TO_SET \
- (IA64_PSR_AC | IA64_PSR_BN | IA64_PSR_MFH | IA64_PSR_MFL)
-
-#define SAVE_FROM_REG(src, ptr, dest) \
- mov dest=src;; \
- st8 [ptr]=dest,0x08
-
-#define RESTORE_REG(reg, ptr, _tmp) \
- ld8 _tmp=[ptr],0x08;; \
- mov reg=_tmp
-
-#define SAVE_BREAK_REGS(ptr, _idx, _breg, _dest)\
- mov ar.lc=IA64_NUM_DBG_REGS-1;; \
- mov _idx=0;; \
-1: \
- SAVE_FROM_REG(_breg[_idx], ptr, _dest);; \
- add _idx=1,_idx;; \
- br.cloop.sptk.many 1b
-
-#define RESTORE_BREAK_REGS(ptr, _idx, _breg, _tmp, _lbl)\
- mov ar.lc=IA64_NUM_DBG_REGS-1;; \
- mov _idx=0;; \
-_lbl: RESTORE_REG(_breg[_idx], ptr, _tmp);; \
- add _idx=1, _idx;; \
- br.cloop.sptk.many _lbl
-
-#define SAVE_ONE_RR(num, _reg, _tmp) \
- movl _tmp=(num<<61);; \
- mov _reg=rr[_tmp]
-
-#define SAVE_REGION_REGS(_tmp, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \
- SAVE_ONE_RR(0,_r0, _tmp);; \
- SAVE_ONE_RR(1,_r1, _tmp);; \
- SAVE_ONE_RR(2,_r2, _tmp);; \
- SAVE_ONE_RR(3,_r3, _tmp);; \
- SAVE_ONE_RR(4,_r4, _tmp);; \
- SAVE_ONE_RR(5,_r5, _tmp);; \
- SAVE_ONE_RR(6,_r6, _tmp);; \
- SAVE_ONE_RR(7,_r7, _tmp);;
-
-#define STORE_REGION_REGS(ptr, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \
- st8 [ptr]=_r0, 8;; \
- st8 [ptr]=_r1, 8;; \
- st8 [ptr]=_r2, 8;; \
- st8 [ptr]=_r3, 8;; \
- st8 [ptr]=_r4, 8;; \
- st8 [ptr]=_r5, 8;; \
- st8 [ptr]=_r6, 8;; \
- st8 [ptr]=_r7, 8;;
-
-#define RESTORE_REGION_REGS(ptr, _idx1, _idx2, _tmp) \
- mov ar.lc=0x08-1;; \
- movl _idx1=0x00;; \
-RestRR: \
- dep.z _idx2=_idx1,61,3;; \
- ld8 _tmp=[ptr],8;; \
- mov rr[_idx2]=_tmp;; \
- srlz.d;; \
- add _idx1=1,_idx1;; \
- br.cloop.sptk.few RestRR
-
-#define SET_AREA_FOR_BOOTING_CPU(reg1, reg2) \
- movl reg1=sal_state_for_booting_cpu;; \
- ld8 reg2=[reg1];;
-
-/*
- * Adjust region registers saved before starting to save
- * break regs and rest of the states that need to be preserved.
- */
-#define SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(_reg1,_reg2,_pred) \
- SAVE_FROM_REG(b0,_reg1,_reg2);; \
- SAVE_FROM_REG(b1,_reg1,_reg2);; \
- SAVE_FROM_REG(b2,_reg1,_reg2);; \
- SAVE_FROM_REG(b3,_reg1,_reg2);; \
- SAVE_FROM_REG(b4,_reg1,_reg2);; \
- SAVE_FROM_REG(b5,_reg1,_reg2);; \
- st8 [_reg1]=r1,0x08;; \
- st8 [_reg1]=r12,0x08;; \
- st8 [_reg1]=r13,0x08;; \
- SAVE_FROM_REG(ar.fpsr,_reg1,_reg2);; \
- SAVE_FROM_REG(ar.pfs,_reg1,_reg2);; \
- SAVE_FROM_REG(ar.rnat,_reg1,_reg2);; \
- SAVE_FROM_REG(ar.unat,_reg1,_reg2);; \
- SAVE_FROM_REG(ar.bspstore,_reg1,_reg2);; \
- SAVE_FROM_REG(cr.dcr,_reg1,_reg2);; \
- SAVE_FROM_REG(cr.iva,_reg1,_reg2);; \
- SAVE_FROM_REG(cr.pta,_reg1,_reg2);; \
- SAVE_FROM_REG(cr.itv,_reg1,_reg2);; \
- SAVE_FROM_REG(cr.pmv,_reg1,_reg2);; \
- SAVE_FROM_REG(cr.cmcv,_reg1,_reg2);; \
- SAVE_FROM_REG(cr.lrr0,_reg1,_reg2);; \
- SAVE_FROM_REG(cr.lrr1,_reg1,_reg2);; \
- st8 [_reg1]=r4,0x08;; \
- st8 [_reg1]=r5,0x08;; \
- st8 [_reg1]=r6,0x08;; \
- st8 [_reg1]=r7,0x08;; \
- st8 [_reg1]=_pred,0x08;; \
- SAVE_FROM_REG(ar.lc, _reg1, _reg2);; \
- stf.spill.nta [_reg1]=f2,16;; \
- stf.spill.nta [_reg1]=f3,16;; \
- stf.spill.nta [_reg1]=f4,16;; \
- stf.spill.nta [_reg1]=f5,16;; \
- stf.spill.nta [_reg1]=f16,16;; \
- stf.spill.nta [_reg1]=f17,16;; \
- stf.spill.nta [_reg1]=f18,16;; \
- stf.spill.nta [_reg1]=f19,16;; \
- stf.spill.nta [_reg1]=f20,16;; \
- stf.spill.nta [_reg1]=f21,16;; \
- stf.spill.nta [_reg1]=f22,16;; \
- stf.spill.nta [_reg1]=f23,16;; \
- stf.spill.nta [_reg1]=f24,16;; \
- stf.spill.nta [_reg1]=f25,16;; \
- stf.spill.nta [_reg1]=f26,16;; \
- stf.spill.nta [_reg1]=f27,16;; \
- stf.spill.nta [_reg1]=f28,16;; \
- stf.spill.nta [_reg1]=f29,16;; \
- stf.spill.nta [_reg1]=f30,16;; \
- stf.spill.nta [_reg1]=f31,16;;
-
-#else
-#define SET_AREA_FOR_BOOTING_CPU(a1, a2)
-#define SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(a1,a2, a3)
-#define SAVE_REGION_REGS(_tmp, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7)
-#define STORE_REGION_REGS(ptr, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7)
-#endif
-
-#define SET_ONE_RR(num, pgsize, _tmp1, _tmp2, vhpt) \
- movl _tmp1=(num << 61);; \
- mov _tmp2=((ia64_rid(IA64_REGION_ID_KERNEL, (num<<61)) << 8) | (pgsize << 2) | vhpt);; \
- mov rr[_tmp1]=_tmp2
-
- __PAGE_ALIGNED_DATA
-
- .global empty_zero_page
-EXPORT_SYMBOL_GPL(empty_zero_page)
-empty_zero_page:
- .skip PAGE_SIZE
-
- .global swapper_pg_dir
-swapper_pg_dir:
- .skip PAGE_SIZE
-
- .rodata
-halt_msg:
- stringz "Halting kernel\n"
-
- __REF
-
- .global start_ap
-
- /*
- * Start the kernel. When the bootloader passes control to _start(), r28
- * points to the address of the boot parameter area. Execution reaches
- * here in physical mode.
- */
-GLOBAL_ENTRY(_start)
-start_ap:
- .prologue
- .save rp, r0 // terminate unwind chain with a NULL rp
- .body
-
- rsm psr.i | psr.ic
- ;;
- srlz.i
- ;;
- {
- flushrs // must be first insn in group
- srlz.i
- }
- ;;
- /*
- * Save the region registers, predicate before they get clobbered
- */
- SAVE_REGION_REGS(r2, r8,r9,r10,r11,r12,r13,r14,r15);
- mov r25=pr;;
-
- /*
- * Initialize kernel region registers:
- * rr[0]: VHPT enabled, page size = PAGE_SHIFT
- * rr[1]: VHPT enabled, page size = PAGE_SHIFT
- * rr[2]: VHPT enabled, page size = PAGE_SHIFT
- * rr[3]: VHPT enabled, page size = PAGE_SHIFT
- * rr[4]: VHPT enabled, page size = PAGE_SHIFT
- * rr[5]: VHPT enabled, page size = PAGE_SHIFT
- * rr[6]: VHPT disabled, page size = IA64_GRANULE_SHIFT
- * rr[7]: VHPT disabled, page size = IA64_GRANULE_SHIFT
- * We initialize all of them to prevent inadvertently assuming
- * something about the state of address translation early in boot.
- */
- SET_ONE_RR(0, PAGE_SHIFT, r2, r16, 1);;
- SET_ONE_RR(1, PAGE_SHIFT, r2, r16, 1);;
- SET_ONE_RR(2, PAGE_SHIFT, r2, r16, 1);;
- SET_ONE_RR(3, PAGE_SHIFT, r2, r16, 1);;
- SET_ONE_RR(4, PAGE_SHIFT, r2, r16, 1);;
- SET_ONE_RR(5, PAGE_SHIFT, r2, r16, 1);;
- SET_ONE_RR(6, IA64_GRANULE_SHIFT, r2, r16, 0);;
- SET_ONE_RR(7, IA64_GRANULE_SHIFT, r2, r16, 0);;
- /*
- * Now pin mappings into the TLB for kernel text and data
- */
- mov r18=KERNEL_TR_PAGE_SHIFT<<2
- movl r17=KERNEL_START
- ;;
- mov cr.itir=r18
- mov cr.ifa=r17
- mov r16=IA64_TR_KERNEL
- mov r3=ip
- movl r18=PAGE_KERNEL
- ;;
- dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT
- ;;
- or r18=r2,r18
- ;;
- srlz.i
- ;;
- itr.i itr[r16]=r18
- ;;
- itr.d dtr[r16]=r18
- ;;
- srlz.i
-
- /*
- * Switch into virtual mode:
- */
- movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
- |IA64_PSR_DI)
- ;;
- mov cr.ipsr=r16
- movl r17=1f
- ;;
- mov cr.iip=r17
- mov cr.ifs=r0
- ;;
- rfi
- ;;
-1: // now we are in virtual mode
-
- SET_AREA_FOR_BOOTING_CPU(r2, r16);
-
- STORE_REGION_REGS(r16, r8,r9,r10,r11,r12,r13,r14,r15);
- SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(r16,r17,r25)
- ;;
-
- // set IVT entry point---can't access I/O ports without it
- movl r3=ia64_ivt
- ;;
- mov cr.iva=r3
- movl r2=FPSR_DEFAULT
- ;;
- srlz.i
- movl gp=__gp
-
- mov ar.fpsr=r2
- ;;
-
-#define isAP p2 // are we an Application Processor?
-#define isBP p3 // are we the Bootstrap Processor?
-
-#ifdef CONFIG_SMP
- /*
- * Find the init_task for the currently booting CPU. At poweron, and in
- * UP mode, task_for_booting_cpu is NULL.
- */
- movl r3=task_for_booting_cpu
- ;;
- ld8 r3=[r3]
- movl r2=init_task
- ;;
- cmp.eq isBP,isAP=r3,r0
- ;;
-(isAP) mov r2=r3
-#else
- movl r2=init_task
- cmp.eq isBP,isAP=r0,r0
-#endif
- ;;
- tpa r3=r2 // r3 == phys addr of task struct
- mov r16=-1
-(isBP) br.cond.dpnt .load_current // BP stack is on region 5 --- no need to map it
-
- // load mapping for stack (virtaddr in r2, physaddr in r3)
- rsm psr.ic
- movl r17=PAGE_KERNEL
- ;;
- srlz.d
- dep r18=0,r3,0,12
- ;;
- or r18=r17,r18
- dep r2=-1,r3,61,3 // IMVA of task
- ;;
- mov r17=rr[r2]
- shr.u r16=r3,IA64_GRANULE_SHIFT
- ;;
- dep r17=0,r17,8,24
- ;;
- mov cr.itir=r17
- mov cr.ifa=r2
-
- mov r19=IA64_TR_CURRENT_STACK
- ;;
- itr.d dtr[r19]=r18
- ;;
- ssm psr.ic
- srlz.d
- ;;
-
-.load_current:
- // load the "current" pointer (r13) and ar.k6 with the current task
- mov IA64_KR(CURRENT)=r2 // virtual address
- mov IA64_KR(CURRENT_STACK)=r16
- mov r13=r2
- /*
- * Reserve space at the top of the stack for "struct pt_regs". Kernel
- * threads don't store interesting values in that structure, but the space
- * still needs to be there because time-critical stuff such as the context
- * switching can be implemented more efficiently (for example, __switch_to()
- * always sets the psr.dfh bit of the task it is switching to).
- */
-
- addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16,r2
- addl r2=IA64_RBS_OFFSET,r2 // initialize the RSE
- mov ar.rsc=0 // place RSE in enforced lazy mode
- ;;
- loadrs // clear the dirty partition
- movl r19=__phys_per_cpu_start
- mov r18=PERCPU_PAGE_SIZE
- ;;
-#ifndef CONFIG_SMP
- add r19=r19,r18
- ;;
-#else
-(isAP) br.few 2f
- movl r20=__cpu0_per_cpu
- ;;
- shr.u r18=r18,3
-1:
- ld8 r21=[r19],8;;
- st8[r20]=r21,8
- adds r18=-1,r18;;
- cmp4.lt p7,p6=0,r18
-(p7) br.cond.dptk.few 1b
- mov r19=r20
- ;;
-2:
-#endif
- tpa r19=r19
- ;;
- .pred.rel.mutex isBP,isAP
-(isBP) mov IA64_KR(PER_CPU_DATA)=r19 // per-CPU base for cpu0
-(isAP) mov IA64_KR(PER_CPU_DATA)=r0 // clear physical per-CPU base
- ;;
- mov ar.bspstore=r2 // establish the new RSE stack
- ;;
- mov ar.rsc=0x3 // place RSE in eager mode
-
-(isBP) dep r28=-1,r28,61,3 // make address virtual
-(isBP) movl r2=ia64_boot_param
- ;;
-(isBP) st8 [r2]=r28 // save the address of the boot param area passed by the bootloader
-
-#ifdef CONFIG_SMP
-(isAP) br.call.sptk.many rp=start_secondary
-.ret0:
-(isAP) br.cond.sptk self
-#endif
-
- // This is executed by the bootstrap processor (bsp) only:
-
- br.call.sptk.many rp=start_kernel
-.ret2: addl r3=@ltoff(halt_msg),gp
- ;;
- alloc r2=ar.pfs,8,0,2,0
- ;;
- ld8 out0=[r3]
- br.call.sptk.many b0=console_print
-
-self: hint @pause
- br.sptk.many self // endless loop
-END(_start)
-
- .text
-
-GLOBAL_ENTRY(ia64_save_debug_regs)
- alloc r16=ar.pfs,1,0,0,0
- mov r20=ar.lc // preserve ar.lc
- mov ar.lc=IA64_NUM_DBG_REGS-1
- mov r18=0
- add r19=IA64_NUM_DBG_REGS*8,in0
- ;;
-1: mov r16=dbr[r18]
-#ifdef CONFIG_ITANIUM
- ;;
- srlz.d
-#endif
- mov r17=ibr[r18]
- add r18=1,r18
- ;;
- st8.nta [in0]=r16,8
- st8.nta [r19]=r17,8
- br.cloop.sptk.many 1b
- ;;
- mov ar.lc=r20 // restore ar.lc
- br.ret.sptk.many rp
-END(ia64_save_debug_regs)
-
-GLOBAL_ENTRY(ia64_load_debug_regs)
- alloc r16=ar.pfs,1,0,0,0
- lfetch.nta [in0]
- mov r20=ar.lc // preserve ar.lc
- add r19=IA64_NUM_DBG_REGS*8,in0
- mov ar.lc=IA64_NUM_DBG_REGS-1
- mov r18=-1
- ;;
-1: ld8.nta r16=[in0],8
- ld8.nta r17=[r19],8
- add r18=1,r18
- ;;
- mov dbr[r18]=r16
-#ifdef CONFIG_ITANIUM
- ;;
- srlz.d // Errata 132 (NoFix status)
-#endif
- mov ibr[r18]=r17
- br.cloop.sptk.many 1b
- ;;
- mov ar.lc=r20 // restore ar.lc
- br.ret.sptk.many rp
-END(ia64_load_debug_regs)
-
-GLOBAL_ENTRY(__ia64_save_fpu)
- alloc r2=ar.pfs,1,4,0,0
- adds loc0=96*16-16,in0
- adds loc1=96*16-16-128,in0
- ;;
- stf.spill.nta [loc0]=f127,-256
- stf.spill.nta [loc1]=f119,-256
- ;;
- stf.spill.nta [loc0]=f111,-256
- stf.spill.nta [loc1]=f103,-256
- ;;
- stf.spill.nta [loc0]=f95,-256
- stf.spill.nta [loc1]=f87,-256
- ;;
- stf.spill.nta [loc0]=f79,-256
- stf.spill.nta [loc1]=f71,-256
- ;;
- stf.spill.nta [loc0]=f63,-256
- stf.spill.nta [loc1]=f55,-256
- adds loc2=96*16-32,in0
- ;;
- stf.spill.nta [loc0]=f47,-256
- stf.spill.nta [loc1]=f39,-256
- adds loc3=96*16-32-128,in0
- ;;
- stf.spill.nta [loc2]=f126,-256
- stf.spill.nta [loc3]=f118,-256
- ;;
- stf.spill.nta [loc2]=f110,-256
- stf.spill.nta [loc3]=f102,-256
- ;;
- stf.spill.nta [loc2]=f94,-256
- stf.spill.nta [loc3]=f86,-256
- ;;
- stf.spill.nta [loc2]=f78,-256
- stf.spill.nta [loc3]=f70,-256
- ;;
- stf.spill.nta [loc2]=f62,-256
- stf.spill.nta [loc3]=f54,-256
- adds loc0=96*16-48,in0
- ;;
- stf.spill.nta [loc2]=f46,-256
- stf.spill.nta [loc3]=f38,-256
- adds loc1=96*16-48-128,in0
- ;;
- stf.spill.nta [loc0]=f125,-256
- stf.spill.nta [loc1]=f117,-256
- ;;
- stf.spill.nta [loc0]=f109,-256
- stf.spill.nta [loc1]=f101,-256
- ;;
- stf.spill.nta [loc0]=f93,-256
- stf.spill.nta [loc1]=f85,-256
- ;;
- stf.spill.nta [loc0]=f77,-256
- stf.spill.nta [loc1]=f69,-256
- ;;
- stf.spill.nta [loc0]=f61,-256
- stf.spill.nta [loc1]=f53,-256
- adds loc2=96*16-64,in0
- ;;
- stf.spill.nta [loc0]=f45,-256
- stf.spill.nta [loc1]=f37,-256
- adds loc3=96*16-64-128,in0
- ;;
- stf.spill.nta [loc2]=f124,-256
- stf.spill.nta [loc3]=f116,-256
- ;;
- stf.spill.nta [loc2]=f108,-256
- stf.spill.nta [loc3]=f100,-256
- ;;
- stf.spill.nta [loc2]=f92,-256
- stf.spill.nta [loc3]=f84,-256
- ;;
- stf.spill.nta [loc2]=f76,-256
- stf.spill.nta [loc3]=f68,-256
- ;;
- stf.spill.nta [loc2]=f60,-256
- stf.spill.nta [loc3]=f52,-256
- adds loc0=96*16-80,in0
- ;;
- stf.spill.nta [loc2]=f44,-256
- stf.spill.nta [loc3]=f36,-256
- adds loc1=96*16-80-128,in0
- ;;
- stf.spill.nta [loc0]=f123,-256
- stf.spill.nta [loc1]=f115,-256
- ;;
- stf.spill.nta [loc0]=f107,-256
- stf.spill.nta [loc1]=f99,-256
- ;;
- stf.spill.nta [loc0]=f91,-256
- stf.spill.nta [loc1]=f83,-256
- ;;
- stf.spill.nta [loc0]=f75,-256
- stf.spill.nta [loc1]=f67,-256
- ;;
- stf.spill.nta [loc0]=f59,-256
- stf.spill.nta [loc1]=f51,-256
- adds loc2=96*16-96,in0
- ;;
- stf.spill.nta [loc0]=f43,-256
- stf.spill.nta [loc1]=f35,-256
- adds loc3=96*16-96-128,in0
- ;;
- stf.spill.nta [loc2]=f122,-256
- stf.spill.nta [loc3]=f114,-256
- ;;
- stf.spill.nta [loc2]=f106,-256
- stf.spill.nta [loc3]=f98,-256
- ;;
- stf.spill.nta [loc2]=f90,-256
- stf.spill.nta [loc3]=f82,-256
- ;;
- stf.spill.nta [loc2]=f74,-256
- stf.spill.nta [loc3]=f66,-256
- ;;
- stf.spill.nta [loc2]=f58,-256
- stf.spill.nta [loc3]=f50,-256
- adds loc0=96*16-112,in0
- ;;
- stf.spill.nta [loc2]=f42,-256
- stf.spill.nta [loc3]=f34,-256
- adds loc1=96*16-112-128,in0
- ;;
- stf.spill.nta [loc0]=f121,-256
- stf.spill.nta [loc1]=f113,-256
- ;;
- stf.spill.nta [loc0]=f105,-256
- stf.spill.nta [loc1]=f97,-256
- ;;
- stf.spill.nta [loc0]=f89,-256
- stf.spill.nta [loc1]=f81,-256
- ;;
- stf.spill.nta [loc0]=f73,-256
- stf.spill.nta [loc1]=f65,-256
- ;;
- stf.spill.nta [loc0]=f57,-256
- stf.spill.nta [loc1]=f49,-256
- adds loc2=96*16-128,in0
- ;;
- stf.spill.nta [loc0]=f41,-256
- stf.spill.nta [loc1]=f33,-256
- adds loc3=96*16-128-128,in0
- ;;
- stf.spill.nta [loc2]=f120,-256
- stf.spill.nta [loc3]=f112,-256
- ;;
- stf.spill.nta [loc2]=f104,-256
- stf.spill.nta [loc3]=f96,-256
- ;;
- stf.spill.nta [loc2]=f88,-256
- stf.spill.nta [loc3]=f80,-256
- ;;
- stf.spill.nta [loc2]=f72,-256
- stf.spill.nta [loc3]=f64,-256
- ;;
- stf.spill.nta [loc2]=f56,-256
- stf.spill.nta [loc3]=f48,-256
- ;;
- stf.spill.nta [loc2]=f40
- stf.spill.nta [loc3]=f32
- br.ret.sptk.many rp
-END(__ia64_save_fpu)
-
-GLOBAL_ENTRY(__ia64_load_fpu)
- alloc r2=ar.pfs,1,2,0,0
- adds r3=128,in0
- adds r14=256,in0
- adds r15=384,in0
- mov loc0=512
- mov loc1=-1024+16
- ;;
- ldf.fill.nta f32=[in0],loc0
- ldf.fill.nta f40=[ r3],loc0
- ldf.fill.nta f48=[r14],loc0
- ldf.fill.nta f56=[r15],loc0
- ;;
- ldf.fill.nta f64=[in0],loc0
- ldf.fill.nta f72=[ r3],loc0
- ldf.fill.nta f80=[r14],loc0
- ldf.fill.nta f88=[r15],loc0
- ;;
- ldf.fill.nta f96=[in0],loc1
- ldf.fill.nta f104=[ r3],loc1
- ldf.fill.nta f112=[r14],loc1
- ldf.fill.nta f120=[r15],loc1
- ;;
- ldf.fill.nta f33=[in0],loc0
- ldf.fill.nta f41=[ r3],loc0
- ldf.fill.nta f49=[r14],loc0
- ldf.fill.nta f57=[r15],loc0
- ;;
- ldf.fill.nta f65=[in0],loc0
- ldf.fill.nta f73=[ r3],loc0
- ldf.fill.nta f81=[r14],loc0
- ldf.fill.nta f89=[r15],loc0
- ;;
- ldf.fill.nta f97=[in0],loc1
- ldf.fill.nta f105=[ r3],loc1
- ldf.fill.nta f113=[r14],loc1
- ldf.fill.nta f121=[r15],loc1
- ;;
- ldf.fill.nta f34=[in0],loc0
- ldf.fill.nta f42=[ r3],loc0
- ldf.fill.nta f50=[r14],loc0
- ldf.fill.nta f58=[r15],loc0
- ;;
- ldf.fill.nta f66=[in0],loc0
- ldf.fill.nta f74=[ r3],loc0
- ldf.fill.nta f82=[r14],loc0
- ldf.fill.nta f90=[r15],loc0
- ;;
- ldf.fill.nta f98=[in0],loc1
- ldf.fill.nta f106=[ r3],loc1
- ldf.fill.nta f114=[r14],loc1
- ldf.fill.nta f122=[r15],loc1
- ;;
- ldf.fill.nta f35=[in0],loc0
- ldf.fill.nta f43=[ r3],loc0
- ldf.fill.nta f51=[r14],loc0
- ldf.fill.nta f59=[r15],loc0
- ;;
- ldf.fill.nta f67=[in0],loc0
- ldf.fill.nta f75=[ r3],loc0
- ldf.fill.nta f83=[r14],loc0
- ldf.fill.nta f91=[r15],loc0
- ;;
- ldf.fill.nta f99=[in0],loc1
- ldf.fill.nta f107=[ r3],loc1
- ldf.fill.nta f115=[r14],loc1
- ldf.fill.nta f123=[r15],loc1
- ;;
- ldf.fill.nta f36=[in0],loc0
- ldf.fill.nta f44=[ r3],loc0
- ldf.fill.nta f52=[r14],loc0
- ldf.fill.nta f60=[r15],loc0
- ;;
- ldf.fill.nta f68=[in0],loc0
- ldf.fill.nta f76=[ r3],loc0
- ldf.fill.nta f84=[r14],loc0
- ldf.fill.nta f92=[r15],loc0
- ;;
- ldf.fill.nta f100=[in0],loc1
- ldf.fill.nta f108=[ r3],loc1
- ldf.fill.nta f116=[r14],loc1
- ldf.fill.nta f124=[r15],loc1
- ;;
- ldf.fill.nta f37=[in0],loc0
- ldf.fill.nta f45=[ r3],loc0
- ldf.fill.nta f53=[r14],loc0
- ldf.fill.nta f61=[r15],loc0
- ;;
- ldf.fill.nta f69=[in0],loc0
- ldf.fill.nta f77=[ r3],loc0
- ldf.fill.nta f85=[r14],loc0
- ldf.fill.nta f93=[r15],loc0
- ;;
- ldf.fill.nta f101=[in0],loc1
- ldf.fill.nta f109=[ r3],loc1
- ldf.fill.nta f117=[r14],loc1
- ldf.fill.nta f125=[r15],loc1
- ;;
- ldf.fill.nta f38 =[in0],loc0
- ldf.fill.nta f46 =[ r3],loc0
- ldf.fill.nta f54 =[r14],loc0
- ldf.fill.nta f62 =[r15],loc0
- ;;
- ldf.fill.nta f70 =[in0],loc0
- ldf.fill.nta f78 =[ r3],loc0
- ldf.fill.nta f86 =[r14],loc0
- ldf.fill.nta f94 =[r15],loc0
- ;;
- ldf.fill.nta f102=[in0],loc1
- ldf.fill.nta f110=[ r3],loc1
- ldf.fill.nta f118=[r14],loc1
- ldf.fill.nta f126=[r15],loc1
- ;;
- ldf.fill.nta f39 =[in0],loc0
- ldf.fill.nta f47 =[ r3],loc0
- ldf.fill.nta f55 =[r14],loc0
- ldf.fill.nta f63 =[r15],loc0
- ;;
- ldf.fill.nta f71 =[in0],loc0
- ldf.fill.nta f79 =[ r3],loc0
- ldf.fill.nta f87 =[r14],loc0
- ldf.fill.nta f95 =[r15],loc0
- ;;
- ldf.fill.nta f103=[in0]
- ldf.fill.nta f111=[ r3]
- ldf.fill.nta f119=[r14]
- ldf.fill.nta f127=[r15]
- br.ret.sptk.many rp
-END(__ia64_load_fpu)
-
-GLOBAL_ENTRY(__ia64_init_fpu)
- stf.spill [sp]=f0 // M3
- mov f32=f0 // F
- nop.b 0
-
- ldfps f33,f34=[sp] // M0
- ldfps f35,f36=[sp] // M1
- mov f37=f0 // F
- ;;
-
- setf.s f38=r0 // M2
- setf.s f39=r0 // M3
- mov f40=f0 // F
-
- ldfps f41,f42=[sp] // M0
- ldfps f43,f44=[sp] // M1
- mov f45=f0 // F
-
- setf.s f46=r0 // M2
- setf.s f47=r0 // M3
- mov f48=f0 // F
-
- ldfps f49,f50=[sp] // M0
- ldfps f51,f52=[sp] // M1
- mov f53=f0 // F
-
- setf.s f54=r0 // M2
- setf.s f55=r0 // M3
- mov f56=f0 // F
-
- ldfps f57,f58=[sp] // M0
- ldfps f59,f60=[sp] // M1
- mov f61=f0 // F
-
- setf.s f62=r0 // M2
- setf.s f63=r0 // M3
- mov f64=f0 // F
-
- ldfps f65,f66=[sp] // M0
- ldfps f67,f68=[sp] // M1
- mov f69=f0 // F
-
- setf.s f70=r0 // M2
- setf.s f71=r0 // M3
- mov f72=f0 // F
-
- ldfps f73,f74=[sp] // M0
- ldfps f75,f76=[sp] // M1
- mov f77=f0 // F
-
- setf.s f78=r0 // M2
- setf.s f79=r0 // M3
- mov f80=f0 // F
-
- ldfps f81,f82=[sp] // M0
- ldfps f83,f84=[sp] // M1
- mov f85=f0 // F
-
- setf.s f86=r0 // M2
- setf.s f87=r0 // M3
- mov f88=f0 // F
-
- /*
- * When the instructions are cached, it would be faster to initialize
- * the remaining registers with simply mov instructions (F-unit).
- * This gets the time down to ~29 cycles. However, this would use up
- * 33 bundles, whereas continuing with the above pattern yields
- * 10 bundles and ~30 cycles.
- */
-
- ldfps f89,f90=[sp] // M0
- ldfps f91,f92=[sp] // M1
- mov f93=f0 // F
-
- setf.s f94=r0 // M2
- setf.s f95=r0 // M3
- mov f96=f0 // F
-
- ldfps f97,f98=[sp] // M0
- ldfps f99,f100=[sp] // M1
- mov f101=f0 // F
-
- setf.s f102=r0 // M2
- setf.s f103=r0 // M3
- mov f104=f0 // F
-
- ldfps f105,f106=[sp] // M0
- ldfps f107,f108=[sp] // M1
- mov f109=f0 // F
-
- setf.s f110=r0 // M2
- setf.s f111=r0 // M3
- mov f112=f0 // F
-
- ldfps f113,f114=[sp] // M0
- ldfps f115,f116=[sp] // M1
- mov f117=f0 // F
-
- setf.s f118=r0 // M2
- setf.s f119=r0 // M3
- mov f120=f0 // F
-
- ldfps f121,f122=[sp] // M0
- ldfps f123,f124=[sp] // M1
- mov f125=f0 // F
-
- setf.s f126=r0 // M2
- setf.s f127=r0 // M3
- br.ret.sptk.many rp // F
-END(__ia64_init_fpu)
-
-/*
- * Switch execution mode from virtual to physical
- *
- * Inputs:
- * r16 = new psr to establish
- * Output:
- * r19 = old virtual address of ar.bsp
- * r20 = old virtual address of sp
- *
- * Note: RSE must already be in enforced lazy mode
- */
-GLOBAL_ENTRY(ia64_switch_mode_phys)
- {
- rsm psr.i | psr.ic // disable interrupts and interrupt collection
- mov r15=ip
- }
- ;;
- {
- flushrs // must be first insn in group
- srlz.i
- }
- ;;
- mov cr.ipsr=r16 // set new PSR
- add r3=1f-ia64_switch_mode_phys,r15
-
- mov r19=ar.bsp
- mov r20=sp
- mov r14=rp // get return address into a general register
- ;;
-
- // going to physical mode, use tpa to translate virt->phys
- tpa r17=r19
- tpa r3=r3
- tpa sp=sp
- tpa r14=r14
- ;;
-
- mov r18=ar.rnat // save ar.rnat
- mov ar.bspstore=r17 // this steps on ar.rnat
- mov cr.iip=r3
- mov cr.ifs=r0
- ;;
- mov ar.rnat=r18 // restore ar.rnat
- rfi // must be last insn in group
- ;;
-1: mov rp=r14
- br.ret.sptk.many rp
-END(ia64_switch_mode_phys)
-
-/*
- * Switch execution mode from physical to virtual
- *
- * Inputs:
- * r16 = new psr to establish
- * r19 = new bspstore to establish
- * r20 = new sp to establish
- *
- * Note: RSE must already be in enforced lazy mode
- */
-GLOBAL_ENTRY(ia64_switch_mode_virt)
- {
- rsm psr.i | psr.ic // disable interrupts and interrupt collection
- mov r15=ip
- }
- ;;
- {
- flushrs // must be first insn in group
- srlz.i
- }
- ;;
- mov cr.ipsr=r16 // set new PSR
- add r3=1f-ia64_switch_mode_virt,r15
-
- mov r14=rp // get return address into a general register
- ;;
-
- // going to virtual
- // - for code addresses, set upper bits of addr to KERNEL_START
- // - for stack addresses, copy from input argument
- movl r18=KERNEL_START
- dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
- dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
- mov sp=r20
- ;;
- or r3=r3,r18
- or r14=r14,r18
- ;;
-
- mov r18=ar.rnat // save ar.rnat
- mov ar.bspstore=r19 // this steps on ar.rnat
- mov cr.iip=r3
- mov cr.ifs=r0
- ;;
- mov ar.rnat=r18 // restore ar.rnat
- rfi // must be last insn in group
- ;;
-1: mov rp=r14
- br.ret.sptk.many rp
-END(ia64_switch_mode_virt)
-
-GLOBAL_ENTRY(ia64_delay_loop)
- .prologue
-{ nop 0 // work around GAS unwind info generation bug...
- .save ar.lc,r2
- mov r2=ar.lc
- .body
- ;;
- mov ar.lc=r32
-}
- ;;
- // force loop to be 32-byte aligned (GAS bug means we cannot use .align
- // inside function body without corrupting unwind info).
-{ nop 0 }
-1: br.cloop.sptk.few 1b
- ;;
- mov ar.lc=r2
- br.ret.sptk.many rp
-END(ia64_delay_loop)
-
-/*
- * Return a CPU-local timestamp in nano-seconds. This timestamp is
- * NOT synchronized across CPUs its return value must never be
- * compared against the values returned on another CPU. The usage in
- * kernel/sched/core.c ensures that.
- *
- * The return-value of sched_clock() is NOT supposed to wrap-around.
- * If it did, it would cause some scheduling hiccups (at the worst).
- * Fortunately, with a 64-bit cycle-counter ticking at 100GHz, even
- * that would happen only once every 5+ years.
- *
- * The code below basically calculates:
- *
- * (ia64_get_itc() * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT
- *
- * except that the multiplication and the shift are done with 128-bit
- * intermediate precision so that we can produce a full 64-bit result.
- */
-GLOBAL_ENTRY(ia64_native_sched_clock)
- addl r8=THIS_CPU(ia64_cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
- mov.m r9=ar.itc // fetch cycle-counter (35 cyc)
- ;;
- ldf8 f8=[r8]
- ;;
- setf.sig f9=r9 // certain to stall, so issue it _after_ ldf8...
- ;;
- xmpy.lu f10=f9,f8 // calculate low 64 bits of 128-bit product (4 cyc)
- xmpy.hu f11=f9,f8 // calculate high 64 bits of 128-bit product
- ;;
- getf.sig r8=f10 // (5 cyc)
- getf.sig r9=f11
- ;;
- shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
- br.ret.sptk.many rp
-END(ia64_native_sched_clock)
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-GLOBAL_ENTRY(cycle_to_nsec)
- alloc r16=ar.pfs,1,0,0,0
- addl r8=THIS_CPU(ia64_cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
- ;;
- ldf8 f8=[r8]
- ;;
- setf.sig f9=r32
- ;;
- xmpy.lu f10=f9,f8 // calculate low 64 bits of 128-bit product (4 cyc)
- xmpy.hu f11=f9,f8 // calculate high 64 bits of 128-bit product
- ;;
- getf.sig r8=f10 // (5 cyc)
- getf.sig r9=f11
- ;;
- shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
- br.ret.sptk.many rp
-END(cycle_to_nsec)
-#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
-
-#ifdef CONFIG_IA64_BRL_EMU
-
-/*
- * Assembly routines used by brl_emu.c to set preserved register state.
- */
-
-#define SET_REG(reg) \
- GLOBAL_ENTRY(ia64_set_##reg); \
- alloc r16=ar.pfs,1,0,0,0; \
- mov reg=r32; \
- ;; \
- br.ret.sptk.many rp; \
- END(ia64_set_##reg)
-
-SET_REG(b1);
-SET_REG(b2);
-SET_REG(b3);
-SET_REG(b4);
-SET_REG(b5);
-
-#endif /* CONFIG_IA64_BRL_EMU */
-
-#ifdef CONFIG_SMP
-
-#ifdef CONFIG_HOTPLUG_CPU
-GLOBAL_ENTRY(ia64_jump_to_sal)
- alloc r16=ar.pfs,1,0,0,0;;
- rsm psr.i | psr.ic
-{
- flushrs
- srlz.i
-}
- tpa r25=in0
- movl r18=tlb_purge_done;;
- DATA_VA_TO_PA(r18);;
- mov b1=r18 // Return location
- movl r18=ia64_do_tlb_purge;;
- DATA_VA_TO_PA(r18);;
- mov b2=r18 // doing tlb_flush work
- mov ar.rsc=0 // Put RSE in enforced lazy, LE mode
- movl r17=1f;;
- DATA_VA_TO_PA(r17);;
- mov cr.iip=r17
- movl r16=SAL_PSR_BITS_TO_SET;;
- mov cr.ipsr=r16
- mov cr.ifs=r0;;
- rfi;; // note: this unmask MCA/INIT (psr.mc)
-1:
- /*
- * Invalidate all TLB data/inst
- */
- br.sptk.many b2;; // jump to tlb purge code
-
-tlb_purge_done:
- RESTORE_REGION_REGS(r25, r17,r18,r19);;
- RESTORE_REG(b0, r25, r17);;
- RESTORE_REG(b1, r25, r17);;
- RESTORE_REG(b2, r25, r17);;
- RESTORE_REG(b3, r25, r17);;
- RESTORE_REG(b4, r25, r17);;
- RESTORE_REG(b5, r25, r17);;
- ld8 r1=[r25],0x08;;
- ld8 r12=[r25],0x08;;
- ld8 r13=[r25],0x08;;
- RESTORE_REG(ar.fpsr, r25, r17);;
- RESTORE_REG(ar.pfs, r25, r17);;
- RESTORE_REG(ar.rnat, r25, r17);;
- RESTORE_REG(ar.unat, r25, r17);;
- RESTORE_REG(ar.bspstore, r25, r17);;
- RESTORE_REG(cr.dcr, r25, r17);;
- RESTORE_REG(cr.iva, r25, r17);;
- RESTORE_REG(cr.pta, r25, r17);;
- srlz.d;; // required not to violate RAW dependency
- RESTORE_REG(cr.itv, r25, r17);;
- RESTORE_REG(cr.pmv, r25, r17);;
- RESTORE_REG(cr.cmcv, r25, r17);;
- RESTORE_REG(cr.lrr0, r25, r17);;
- RESTORE_REG(cr.lrr1, r25, r17);;
- ld8 r4=[r25],0x08;;
- ld8 r5=[r25],0x08;;
- ld8 r6=[r25],0x08;;
- ld8 r7=[r25],0x08;;
- ld8 r17=[r25],0x08;;
- mov pr=r17,-1;;
- RESTORE_REG(ar.lc, r25, r17);;
- /*
- * Now Restore floating point regs
- */
- ldf.fill.nta f2=[r25],16;;
- ldf.fill.nta f3=[r25],16;;
- ldf.fill.nta f4=[r25],16;;
- ldf.fill.nta f5=[r25],16;;
- ldf.fill.nta f16=[r25],16;;
- ldf.fill.nta f17=[r25],16;;
- ldf.fill.nta f18=[r25],16;;
- ldf.fill.nta f19=[r25],16;;
- ldf.fill.nta f20=[r25],16;;
- ldf.fill.nta f21=[r25],16;;
- ldf.fill.nta f22=[r25],16;;
- ldf.fill.nta f23=[r25],16;;
- ldf.fill.nta f24=[r25],16;;
- ldf.fill.nta f25=[r25],16;;
- ldf.fill.nta f26=[r25],16;;
- ldf.fill.nta f27=[r25],16;;
- ldf.fill.nta f28=[r25],16;;
- ldf.fill.nta f29=[r25],16;;
- ldf.fill.nta f30=[r25],16;;
- ldf.fill.nta f31=[r25],16;;
-
- /*
- * Now that we have done all the register restores
- * we are now ready for the big DIVE to SAL Land
- */
- ssm psr.ic;;
- srlz.d;;
- br.ret.sptk.many b0;;
-END(ia64_jump_to_sal)
-#endif /* CONFIG_HOTPLUG_CPU */
-
-#endif /* CONFIG_SMP */
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
deleted file mode 100644
index 99300850abc1..000000000000
--- a/arch/ia64/kernel/iosapic.c
+++ /dev/null
@@ -1,1137 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * I/O SAPIC support.
- *
- * Copyright (C) 1999 Intel Corp.
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 2000-2002 J.I. Lee <jung-ik.lee@intel.com>
- * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co.
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
- *
- * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O
- * APIC code. In particular, we now have separate
- * handlers for edge and level triggered
- * interrupts.
- * 00/10/27 Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector
- * allocation PCI to vector mapping, shared PCI
- * interrupts.
- * 00/10/27 D. Mosberger Document things a bit more to make them more
- * understandable. Clean up much of the old
- * IOSAPIC cruft.
- * 01/07/27 J.I. Lee PCI irq routing, Platform/Legacy interrupts
- * and fixes for ACPI S5(SoftOff) support.
- * 02/01/23 J.I. Lee iosapic pgm fixes for PCI irq routing from _PRT
- * 02/01/07 E. Focht <efocht@ess.nec.de> Redirectable interrupt
- * vectors in iosapic_set_affinity(),
- * initializations for /proc/irq/#/smp_affinity
- * 02/04/02 P. Diefenbaugh Cleaned up ACPI PCI IRQ routing.
- * 02/04/18 J.I. Lee bug fix in iosapic_init_pci_irq
- * 02/04/30 J.I. Lee bug fix in find_iosapic to fix ACPI PCI IRQ to
- * IOSAPIC mapping error
- * 02/07/29 T. Kochi Allocate interrupt vectors dynamically
- * 02/08/04 T. Kochi Cleaned up terminology (irq, global system
- * interrupt, vector, etc.)
- * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's
- * pci_irq code.
- * 03/02/19 B. Helgaas Make pcat_compat system-wide, not per-IOSAPIC.
- * Remove iosapic_address & gsi_base from
- * external interfaces. Rationalize
- * __init/__devinit attributes.
- * 04/12/04 Ashok Raj <ashok.raj@intel.com> Intel Corporation 2004
- * Updated to work with irq migration necessary
- * for CPU Hotplug
- */
-/*
- * Here is what the interrupt logic between a PCI device and the kernel looks
- * like:
- *
- * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC,
- * INTD). The device is uniquely identified by its bus-, and slot-number
- * (the function number does not matter here because all functions share
- * the same interrupt lines).
- *
- * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC
- * controller. Multiple interrupt lines may have to share the same
- * IOSAPIC pin (if they're level triggered and use the same polarity).
- * Each interrupt line has a unique Global System Interrupt (GSI) number
- * which can be calculated as the sum of the controller's base GSI number
- * and the IOSAPIC pin number to which the line connects.
- *
- * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the
- * IOSAPIC pin into the IA-64 interrupt vector. This interrupt vector is then
- * sent to the CPU.
- *
- * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is
- * used as architecture-independent interrupt handling mechanism in Linux.
- * As an IRQ is a number, we have to have
- * IA-64 interrupt vector number <-> IRQ number mapping. On smaller
- * systems, we use one-to-one mapping between IA-64 vector and IRQ.
- *
- * To sum up, there are three levels of mappings involved:
- *
- * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ
- *
- * Note: The term "IRQ" is loosely used everywhere in Linux kernel to
- * describe interrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ
- * (isa_irq) is the only exception in this source code.
- */
-
-#include <linux/acpi.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/smp.h>
-#include <linux/string.h>
-#include <linux/memblock.h>
-
-#include <asm/delay.h>
-#include <asm/hw_irq.h>
-#include <asm/io.h>
-#include <asm/iosapic.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/xtp.h>
-
-#undef DEBUG_INTERRUPT_ROUTING
-
-#ifdef DEBUG_INTERRUPT_ROUTING
-#define DBG(fmt...) printk(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-static DEFINE_SPINLOCK(iosapic_lock);
-
-/*
- * These tables map IA-64 vectors to the IOSAPIC pin that generates this
- * vector.
- */
-
-#define NO_REF_RTE 0
-
-static struct iosapic {
- char __iomem *addr; /* base address of IOSAPIC */
- unsigned int gsi_base; /* GSI base */
- unsigned short num_rte; /* # of RTEs on this IOSAPIC */
- int rtes_inuse; /* # of RTEs in use on this IOSAPIC */
-#ifdef CONFIG_NUMA
- unsigned short node; /* numa node association via pxm */
-#endif
- spinlock_t lock; /* lock for indirect reg access */
-} iosapic_lists[NR_IOSAPICS];
-
-struct iosapic_rte_info {
- struct list_head rte_list; /* RTEs sharing the same vector */
- char rte_index; /* IOSAPIC RTE index */
- int refcnt; /* reference counter */
- struct iosapic *iosapic;
-} ____cacheline_aligned;
-
-static struct iosapic_intr_info {
- struct list_head rtes; /* RTEs using this vector (empty =>
- * not an IOSAPIC interrupt) */
- int count; /* # of registered RTEs */
- u32 low32; /* current value of low word of
- * Redirection table entry */
- unsigned int dest; /* destination CPU physical ID */
- unsigned char dmode : 3; /* delivery mode (see iosapic.h) */
- unsigned char polarity: 1; /* interrupt polarity
- * (see iosapic.h) */
- unsigned char trigger : 1; /* trigger mode (see iosapic.h) */
-} iosapic_intr_info[NR_IRQS];
-
-static unsigned char pcat_compat; /* 8259 compatibility flag */
-
-static inline void
-iosapic_write(struct iosapic *iosapic, unsigned int reg, u32 val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&iosapic->lock, flags);
- __iosapic_write(iosapic->addr, reg, val);
- spin_unlock_irqrestore(&iosapic->lock, flags);
-}
-
-/*
- * Find an IOSAPIC associated with a GSI
- */
-static inline int
-find_iosapic (unsigned int gsi)
-{
- int i;
-
- for (i = 0; i < NR_IOSAPICS; i++) {
- if ((unsigned) (gsi - iosapic_lists[i].gsi_base) <
- iosapic_lists[i].num_rte)
- return i;
- }
-
- return -1;
-}
-
-static inline int __gsi_to_irq(unsigned int gsi)
-{
- int irq;
- struct iosapic_intr_info *info;
- struct iosapic_rte_info *rte;
-
- for (irq = 0; irq < NR_IRQS; irq++) {
- info = &iosapic_intr_info[irq];
- list_for_each_entry(rte, &info->rtes, rte_list)
- if (rte->iosapic->gsi_base + rte->rte_index == gsi)
- return irq;
- }
- return -1;
-}
-
-int
-gsi_to_irq (unsigned int gsi)
-{
- unsigned long flags;
- int irq;
-
- spin_lock_irqsave(&iosapic_lock, flags);
- irq = __gsi_to_irq(gsi);
- spin_unlock_irqrestore(&iosapic_lock, flags);
- return irq;
-}
-
-static struct iosapic_rte_info *find_rte(unsigned int irq, unsigned int gsi)
-{
- struct iosapic_rte_info *rte;
-
- list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
- if (rte->iosapic->gsi_base + rte->rte_index == gsi)
- return rte;
- return NULL;
-}
-
-static void
-set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask)
-{
- unsigned long pol, trigger, dmode;
- u32 low32, high32;
- int rte_index;
- char redir;
- struct iosapic_rte_info *rte;
- ia64_vector vector = irq_to_vector(irq);
-
- DBG(KERN_DEBUG"IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
-
- rte = find_rte(irq, gsi);
- if (!rte)
- return; /* not an IOSAPIC interrupt */
-
- rte_index = rte->rte_index;
- pol = iosapic_intr_info[irq].polarity;
- trigger = iosapic_intr_info[irq].trigger;
- dmode = iosapic_intr_info[irq].dmode;
-
- redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
-
-#ifdef CONFIG_SMP
- set_irq_affinity_info(irq, (int)(dest & 0xffff), redir);
-#endif
-
- low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
- (trigger << IOSAPIC_TRIGGER_SHIFT) |
- (dmode << IOSAPIC_DELIVERY_SHIFT) |
- ((mask ? 1 : 0) << IOSAPIC_MASK_SHIFT) |
- vector);
-
- /* dest contains both id and eid */
- high32 = (dest << IOSAPIC_DEST_SHIFT);
-
- iosapic_write(rte->iosapic, IOSAPIC_RTE_HIGH(rte_index), high32);
- iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
- iosapic_intr_info[irq].low32 = low32;
- iosapic_intr_info[irq].dest = dest;
-}
-
-static void
-iosapic_nop (struct irq_data *data)
-{
- /* do nothing... */
-}
-
-
-#ifdef CONFIG_KEXEC
-void
-kexec_disable_iosapic(void)
-{
- struct iosapic_intr_info *info;
- struct iosapic_rte_info *rte;
- ia64_vector vec;
- int irq;
-
- for (irq = 0; irq < NR_IRQS; irq++) {
- info = &iosapic_intr_info[irq];
- vec = irq_to_vector(irq);
- list_for_each_entry(rte, &info->rtes,
- rte_list) {
- iosapic_write(rte->iosapic,
- IOSAPIC_RTE_LOW(rte->rte_index),
- IOSAPIC_MASK|vec);
- iosapic_eoi(rte->iosapic->addr, vec);
- }
- }
-}
-#endif
-
-static void
-mask_irq (struct irq_data *data)
-{
- unsigned int irq = data->irq;
- u32 low32;
- int rte_index;
- struct iosapic_rte_info *rte;
-
- if (!iosapic_intr_info[irq].count)
- return; /* not an IOSAPIC interrupt! */
-
- /* set only the mask bit */
- low32 = iosapic_intr_info[irq].low32 |= IOSAPIC_MASK;
- list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) {
- rte_index = rte->rte_index;
- iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
- }
-}
-
-static void
-unmask_irq (struct irq_data *data)
-{
- unsigned int irq = data->irq;
- u32 low32;
- int rte_index;
- struct iosapic_rte_info *rte;
-
- if (!iosapic_intr_info[irq].count)
- return; /* not an IOSAPIC interrupt! */
-
- low32 = iosapic_intr_info[irq].low32 &= ~IOSAPIC_MASK;
- list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) {
- rte_index = rte->rte_index;
- iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
- }
-}
-
-
-static int
-iosapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
- bool force)
-{
-#ifdef CONFIG_SMP
- unsigned int irq = data->irq;
- u32 high32, low32;
- int cpu, dest, rte_index;
- int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
- struct iosapic_rte_info *rte;
- struct iosapic *iosapic;
-
- irq &= (~IA64_IRQ_REDIRECTED);
-
- cpu = cpumask_first_and(cpu_online_mask, mask);
- if (cpu >= nr_cpu_ids)
- return -1;
-
- if (irq_prepare_move(irq, cpu))
- return -1;
-
- dest = cpu_physical_id(cpu);
-
- if (!iosapic_intr_info[irq].count)
- return -1; /* not an IOSAPIC interrupt */
-
- set_irq_affinity_info(irq, dest, redir);
-
- /* dest contains both id and eid */
- high32 = dest << IOSAPIC_DEST_SHIFT;
-
- low32 = iosapic_intr_info[irq].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT);
- if (redir)
- /* change delivery mode to lowest priority */
- low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
- else
- /* change delivery mode to fixed */
- low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
- low32 &= IOSAPIC_VECTOR_MASK;
- low32 |= irq_to_vector(irq);
-
- iosapic_intr_info[irq].low32 = low32;
- iosapic_intr_info[irq].dest = dest;
- list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) {
- iosapic = rte->iosapic;
- rte_index = rte->rte_index;
- iosapic_write(iosapic, IOSAPIC_RTE_HIGH(rte_index), high32);
- iosapic_write(iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
- }
-
-#endif
- return 0;
-}
-
-/*
- * Handlers for level-triggered interrupts.
- */
-
-static unsigned int
-iosapic_startup_level_irq (struct irq_data *data)
-{
- unmask_irq(data);
- return 0;
-}
-
-static void
-iosapic_unmask_level_irq (struct irq_data *data)
-{
- unsigned int irq = data->irq;
- ia64_vector vec = irq_to_vector(irq);
- struct iosapic_rte_info *rte;
- int do_unmask_irq = 0;
-
- irq_complete_move(irq);
- if (unlikely(irqd_is_setaffinity_pending(data))) {
- do_unmask_irq = 1;
- mask_irq(data);
- } else
- unmask_irq(data);
-
- list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
- iosapic_eoi(rte->iosapic->addr, vec);
-
- if (unlikely(do_unmask_irq)) {
- irq_move_masked_irq(data);
- unmask_irq(data);
- }
-}
-
-#define iosapic_shutdown_level_irq mask_irq
-#define iosapic_enable_level_irq unmask_irq
-#define iosapic_disable_level_irq mask_irq
-#define iosapic_ack_level_irq iosapic_nop
-
-static struct irq_chip irq_type_iosapic_level = {
- .name = "IO-SAPIC-level",
- .irq_startup = iosapic_startup_level_irq,
- .irq_shutdown = iosapic_shutdown_level_irq,
- .irq_enable = iosapic_enable_level_irq,
- .irq_disable = iosapic_disable_level_irq,
- .irq_ack = iosapic_ack_level_irq,
- .irq_mask = mask_irq,
- .irq_unmask = iosapic_unmask_level_irq,
- .irq_set_affinity = iosapic_set_affinity
-};
-
-/*
- * Handlers for edge-triggered interrupts.
- */
-
-static unsigned int
-iosapic_startup_edge_irq (struct irq_data *data)
-{
- unmask_irq(data);
- /*
- * IOSAPIC simply drops interrupts pended while the
- * corresponding pin was masked, so we can't know if an
- * interrupt is pending already. Let's hope not...
- */
- return 0;
-}
-
-static void
-iosapic_ack_edge_irq (struct irq_data *data)
-{
- irq_complete_move(data->irq);
- irq_move_irq(data);
-}
-
-#define iosapic_enable_edge_irq unmask_irq
-#define iosapic_disable_edge_irq iosapic_nop
-
-static struct irq_chip irq_type_iosapic_edge = {
- .name = "IO-SAPIC-edge",
- .irq_startup = iosapic_startup_edge_irq,
- .irq_shutdown = iosapic_disable_edge_irq,
- .irq_enable = iosapic_enable_edge_irq,
- .irq_disable = iosapic_disable_edge_irq,
- .irq_ack = iosapic_ack_edge_irq,
- .irq_mask = mask_irq,
- .irq_unmask = unmask_irq,
- .irq_set_affinity = iosapic_set_affinity
-};
-
-static unsigned int
-iosapic_version (char __iomem *addr)
-{
- /*
- * IOSAPIC Version Register return 32 bit structure like:
- * {
- * unsigned int version : 8;
- * unsigned int reserved1 : 8;
- * unsigned int max_redir : 8;
- * unsigned int reserved2 : 8;
- * }
- */
- return __iosapic_read(addr, IOSAPIC_VERSION);
-}
-
-static int iosapic_find_sharable_irq(unsigned long trigger, unsigned long pol)
-{
- int i, irq = -ENOSPC, min_count = -1;
- struct iosapic_intr_info *info;
-
- /*
- * shared vectors for edge-triggered interrupts are not
- * supported yet
- */
- if (trigger == IOSAPIC_EDGE)
- return -EINVAL;
-
- for (i = 0; i < NR_IRQS; i++) {
- info = &iosapic_intr_info[i];
- if (info->trigger == trigger && info->polarity == pol &&
- (info->dmode == IOSAPIC_FIXED ||
- info->dmode == IOSAPIC_LOWEST_PRIORITY) &&
- can_request_irq(i, IRQF_SHARED)) {
- if (min_count == -1 || info->count < min_count) {
- irq = i;
- min_count = info->count;
- }
- }
- }
- return irq;
-}
-
-/*
- * if the given vector is already owned by other,
- * assign a new vector for the other and make the vector available
- */
-static void __init
-iosapic_reassign_vector (int irq)
-{
- int new_irq;
-
- if (iosapic_intr_info[irq].count) {
- new_irq = create_irq();
- if (new_irq < 0)
- panic("%s: out of interrupt vectors!\n", __func__);
- printk(KERN_INFO "Reassigning vector %d to %d\n",
- irq_to_vector(irq), irq_to_vector(new_irq));
- memcpy(&iosapic_intr_info[new_irq], &iosapic_intr_info[irq],
- sizeof(struct iosapic_intr_info));
- INIT_LIST_HEAD(&iosapic_intr_info[new_irq].rtes);
- list_move(iosapic_intr_info[irq].rtes.next,
- &iosapic_intr_info[new_irq].rtes);
- memset(&iosapic_intr_info[irq], 0,
- sizeof(struct iosapic_intr_info));
- iosapic_intr_info[irq].low32 = IOSAPIC_MASK;
- INIT_LIST_HEAD(&iosapic_intr_info[irq].rtes);
- }
-}
-
-static inline int irq_is_shared (int irq)
-{
- return (iosapic_intr_info[irq].count > 1);
-}
-
-struct irq_chip*
-ia64_native_iosapic_get_irq_chip(unsigned long trigger)
-{
- if (trigger == IOSAPIC_EDGE)
- return &irq_type_iosapic_edge;
- else
- return &irq_type_iosapic_level;
-}
-
-static int
-register_intr (unsigned int gsi, int irq, unsigned char delivery,
- unsigned long polarity, unsigned long trigger)
-{
- struct irq_chip *chip, *irq_type;
- int index;
- struct iosapic_rte_info *rte;
-
- index = find_iosapic(gsi);
- if (index < 0) {
- printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
- __func__, gsi);
- return -ENODEV;
- }
-
- rte = find_rte(irq, gsi);
- if (!rte) {
- rte = kzalloc(sizeof (*rte), GFP_ATOMIC);
- if (!rte) {
- printk(KERN_WARNING "%s: cannot allocate memory\n",
- __func__);
- return -ENOMEM;
- }
-
- rte->iosapic = &iosapic_lists[index];
- rte->rte_index = gsi - rte->iosapic->gsi_base;
- rte->refcnt++;
- list_add_tail(&rte->rte_list, &iosapic_intr_info[irq].rtes);
- iosapic_intr_info[irq].count++;
- iosapic_lists[index].rtes_inuse++;
- }
- else if (rte->refcnt == NO_REF_RTE) {
- struct iosapic_intr_info *info = &iosapic_intr_info[irq];
- if (info->count > 0 &&
- (info->trigger != trigger || info->polarity != polarity)){
- printk (KERN_WARNING
- "%s: cannot override the interrupt\n",
- __func__);
- return -EINVAL;
- }
- rte->refcnt++;
- iosapic_intr_info[irq].count++;
- iosapic_lists[index].rtes_inuse++;
- }
-
- iosapic_intr_info[irq].polarity = polarity;
- iosapic_intr_info[irq].dmode = delivery;
- iosapic_intr_info[irq].trigger = trigger;
-
- irq_type = iosapic_get_irq_chip(trigger);
-
- chip = irq_get_chip(irq);
- if (irq_type != NULL && chip != irq_type) {
- if (chip != &no_irq_chip)
- printk(KERN_WARNING
- "%s: changing vector %d from %s to %s\n",
- __func__, irq_to_vector(irq),
- chip->name, irq_type->name);
- chip = irq_type;
- }
- irq_set_chip_handler_name_locked(irq_get_irq_data(irq), chip,
- trigger == IOSAPIC_EDGE ? handle_edge_irq : handle_level_irq,
- NULL);
- return 0;
-}
-
-static unsigned int
-get_target_cpu (unsigned int gsi, int irq)
-{
-#ifdef CONFIG_SMP
- static int cpu = -1;
- extern int cpe_vector;
- cpumask_t domain = irq_to_domain(irq);
-
- /*
- * In case of vector shared by multiple RTEs, all RTEs that
- * share the vector need to use the same destination CPU.
- */
- if (iosapic_intr_info[irq].count)
- return iosapic_intr_info[irq].dest;
-
- /*
- * If the platform supports redirection via XTP, let it
- * distribute interrupts.
- */
- if (smp_int_redirect & SMP_IRQ_REDIRECTION)
- return cpu_physical_id(smp_processor_id());
-
- /*
- * Some interrupts (ACPI SCI, for instance) are registered
- * before the BSP is marked as online.
- */
- if (!cpu_online(smp_processor_id()))
- return cpu_physical_id(smp_processor_id());
-
- if (cpe_vector > 0 && irq_to_vector(irq) == IA64_CPEP_VECTOR)
- return get_cpei_target_cpu();
-
-#ifdef CONFIG_NUMA
- {
- int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0;
- const struct cpumask *cpu_mask;
-
- iosapic_index = find_iosapic(gsi);
- if (iosapic_index < 0 ||
- iosapic_lists[iosapic_index].node == MAX_NUMNODES)
- goto skip_numa_setup;
-
- cpu_mask = cpumask_of_node(iosapic_lists[iosapic_index].node);
- num_cpus = 0;
- for_each_cpu_and(numa_cpu, cpu_mask, &domain) {
- if (cpu_online(numa_cpu))
- num_cpus++;
- }
-
- if (!num_cpus)
- goto skip_numa_setup;
-
- /* Use irq assignment to distribute across cpus in node */
- cpu_index = irq % num_cpus;
-
- for_each_cpu_and(numa_cpu, cpu_mask, &domain)
- if (cpu_online(numa_cpu) && i++ >= cpu_index)
- break;
-
- if (numa_cpu < nr_cpu_ids)
- return cpu_physical_id(numa_cpu);
- }
-skip_numa_setup:
-#endif
- /*
- * Otherwise, round-robin interrupt vectors across all the
- * processors. (It'd be nice if we could be smarter in the
- * case of NUMA.)
- */
- do {
- if (++cpu >= nr_cpu_ids)
- cpu = 0;
- } while (!cpu_online(cpu) || !cpumask_test_cpu(cpu, &domain));
-
- return cpu_physical_id(cpu);
-#else /* CONFIG_SMP */
- return cpu_physical_id(smp_processor_id());
-#endif
-}
-
-static inline unsigned char choose_dmode(void)
-{
-#ifdef CONFIG_SMP
- if (smp_int_redirect & SMP_IRQ_REDIRECTION)
- return IOSAPIC_LOWEST_PRIORITY;
-#endif
- return IOSAPIC_FIXED;
-}
-
-/*
- * ACPI can describe IOSAPIC interrupts via static tables and namespace
- * methods. This provides an interface to register those interrupts and
- * program the IOSAPIC RTE.
- */
-int
-iosapic_register_intr (unsigned int gsi,
- unsigned long polarity, unsigned long trigger)
-{
- int irq, mask = 1, err;
- unsigned int dest;
- unsigned long flags;
- struct iosapic_rte_info *rte;
- u32 low32;
- unsigned char dmode;
- struct irq_desc *desc;
-
- /*
- * If this GSI has already been registered (i.e., it's a
- * shared interrupt, or we lost a race to register it),
- * don't touch the RTE.
- */
- spin_lock_irqsave(&iosapic_lock, flags);
- irq = __gsi_to_irq(gsi);
- if (irq > 0) {
- rte = find_rte(irq, gsi);
- if(iosapic_intr_info[irq].count == 0) {
- assign_irq_vector(irq);
- irq_init_desc(irq);
- } else if (rte->refcnt != NO_REF_RTE) {
- rte->refcnt++;
- goto unlock_iosapic_lock;
- }
- } else
- irq = create_irq();
-
- /* If vector is running out, we try to find a sharable vector */
- if (irq < 0) {
- irq = iosapic_find_sharable_irq(trigger, polarity);
- if (irq < 0)
- goto unlock_iosapic_lock;
- }
-
- desc = irq_to_desc(irq);
- raw_spin_lock(&desc->lock);
- dest = get_target_cpu(gsi, irq);
- dmode = choose_dmode();
- err = register_intr(gsi, irq, dmode, polarity, trigger);
- if (err < 0) {
- raw_spin_unlock(&desc->lock);
- irq = err;
- goto unlock_iosapic_lock;
- }
-
- /*
- * If the vector is shared and already unmasked for other
- * interrupt sources, don't mask it.
- */
- low32 = iosapic_intr_info[irq].low32;
- if (irq_is_shared(irq) && !(low32 & IOSAPIC_MASK))
- mask = 0;
- set_rte(gsi, irq, dest, mask);
-
- printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
- gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
- (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
- cpu_logical_id(dest), dest, irq_to_vector(irq));
-
- raw_spin_unlock(&desc->lock);
- unlock_iosapic_lock:
- spin_unlock_irqrestore(&iosapic_lock, flags);
- return irq;
-}
-
-void
-iosapic_unregister_intr (unsigned int gsi)
-{
- unsigned long flags;
- int irq, index;
- u32 low32;
- unsigned long trigger, polarity;
- unsigned int dest;
- struct iosapic_rte_info *rte;
-
- /*
- * If the irq associated with the gsi is not found,
- * iosapic_unregister_intr() is unbalanced. We need to check
- * this again after getting locks.
- */
- irq = gsi_to_irq(gsi);
- if (irq < 0) {
- printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n",
- gsi);
- WARN_ON(1);
- return;
- }
-
- spin_lock_irqsave(&iosapic_lock, flags);
- if ((rte = find_rte(irq, gsi)) == NULL) {
- printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n",
- gsi);
- WARN_ON(1);
- goto out;
- }
-
- if (--rte->refcnt > 0)
- goto out;
-
- rte->refcnt = NO_REF_RTE;
-
- /* Mask the interrupt */
- low32 = iosapic_intr_info[irq].low32 | IOSAPIC_MASK;
- iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte->rte_index), low32);
-
- iosapic_intr_info[irq].count--;
- index = find_iosapic(gsi);
- iosapic_lists[index].rtes_inuse--;
- WARN_ON(iosapic_lists[index].rtes_inuse < 0);
-
- trigger = iosapic_intr_info[irq].trigger;
- polarity = iosapic_intr_info[irq].polarity;
- dest = iosapic_intr_info[irq].dest;
- printk(KERN_INFO
- "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n",
- gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
- (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
- cpu_logical_id(dest), dest, irq_to_vector(irq));
-
- if (iosapic_intr_info[irq].count == 0) {
-#ifdef CONFIG_SMP
- /* Clear affinity */
- irq_data_update_affinity(irq_get_irq_data(irq), cpu_all_mask);
-#endif
- /* Clear the interrupt information */
- iosapic_intr_info[irq].dest = 0;
- iosapic_intr_info[irq].dmode = 0;
- iosapic_intr_info[irq].polarity = 0;
- iosapic_intr_info[irq].trigger = 0;
- iosapic_intr_info[irq].low32 |= IOSAPIC_MASK;
-
- /* Destroy and reserve IRQ */
- destroy_and_reserve_irq(irq);
- }
- out:
- spin_unlock_irqrestore(&iosapic_lock, flags);
-}
-
-/*
- * ACPI calls this when it finds an entry for a platform interrupt.
- */
-int __init
-iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
- int iosapic_vector, u16 eid, u16 id,
- unsigned long polarity, unsigned long trigger)
-{
- static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"};
- unsigned char delivery;
- int irq, vector, mask = 0;
- unsigned int dest = ((id << 8) | eid) & 0xffff;
-
- switch (int_type) {
- case ACPI_INTERRUPT_PMI:
- irq = vector = iosapic_vector;
- bind_irq_vector(irq, vector, CPU_MASK_ALL);
- /*
- * since PMI vector is alloc'd by FW(ACPI) not by kernel,
- * we need to make sure the vector is available
- */
- iosapic_reassign_vector(irq);
- delivery = IOSAPIC_PMI;
- break;
- case ACPI_INTERRUPT_INIT:
- irq = create_irq();
- if (irq < 0)
- panic("%s: out of interrupt vectors!\n", __func__);
- vector = irq_to_vector(irq);
- delivery = IOSAPIC_INIT;
- break;
- case ACPI_INTERRUPT_CPEI:
- irq = vector = IA64_CPE_VECTOR;
- BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL));
- delivery = IOSAPIC_FIXED;
- mask = 1;
- break;
- default:
- printk(KERN_ERR "%s: invalid int type 0x%x\n", __func__,
- int_type);
- return -1;
- }
-
- register_intr(gsi, irq, delivery, polarity, trigger);
-
- printk(KERN_INFO
- "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x)"
- " vector %d\n",
- int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
- int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
- (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
- cpu_logical_id(dest), dest, vector);
-
- set_rte(gsi, irq, dest, mask);
- return vector;
-}
-
-/*
- * ACPI calls this when it finds an entry for a legacy ISA IRQ override.
- */
-void iosapic_override_isa_irq(unsigned int isa_irq, unsigned int gsi,
- unsigned long polarity, unsigned long trigger)
-{
- int vector, irq;
- unsigned int dest = cpu_physical_id(smp_processor_id());
- unsigned char dmode;
-
- irq = vector = isa_irq_to_vector(isa_irq);
- BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL));
- dmode = choose_dmode();
- register_intr(gsi, irq, dmode, polarity, trigger);
-
- DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
- isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
- polarity == IOSAPIC_POL_HIGH ? "high" : "low",
- cpu_logical_id(dest), dest, vector);
-
- set_rte(gsi, irq, dest, 1);
-}
-
-void __init
-ia64_native_iosapic_pcat_compat_init(void)
-{
- if (pcat_compat) {
- /*
- * Disable the compatibility mode interrupts (8259 style),
- * needs IN/OUT support enabled.
- */
- printk(KERN_INFO
- "%s: Disabling PC-AT compatible 8259 interrupts\n",
- __func__);
- outb(0xff, 0xA1);
- outb(0xff, 0x21);
- }
-}
-
-void __init
-iosapic_system_init (int system_pcat_compat)
-{
- int irq;
-
- for (irq = 0; irq < NR_IRQS; ++irq) {
- iosapic_intr_info[irq].low32 = IOSAPIC_MASK;
- /* mark as unused */
- INIT_LIST_HEAD(&iosapic_intr_info[irq].rtes);
-
- iosapic_intr_info[irq].count = 0;
- }
-
- pcat_compat = system_pcat_compat;
- if (pcat_compat)
- iosapic_pcat_compat_init();
-}
-
-static inline int
-iosapic_alloc (void)
-{
- int index;
-
- for (index = 0; index < NR_IOSAPICS; index++)
- if (!iosapic_lists[index].addr)
- return index;
-
- printk(KERN_WARNING "%s: failed to allocate iosapic\n", __func__);
- return -1;
-}
-
-static inline void
-iosapic_free (int index)
-{
- memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));
-}
-
-static inline int
-iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
-{
- int index;
- unsigned int gsi_end, base, end;
-
- /* check gsi range */
- gsi_end = gsi_base + ((ver >> 16) & 0xff);
- for (index = 0; index < NR_IOSAPICS; index++) {
- if (!iosapic_lists[index].addr)
- continue;
-
- base = iosapic_lists[index].gsi_base;
- end = base + iosapic_lists[index].num_rte - 1;
-
- if (gsi_end < base || end < gsi_base)
- continue; /* OK */
-
- return -EBUSY;
- }
- return 0;
-}
-
-static int
-iosapic_delete_rte(unsigned int irq, unsigned int gsi)
-{
- struct iosapic_rte_info *rte, *temp;
-
- list_for_each_entry_safe(rte, temp, &iosapic_intr_info[irq].rtes,
- rte_list) {
- if (rte->iosapic->gsi_base + rte->rte_index == gsi) {
- if (rte->refcnt)
- return -EBUSY;
-
- list_del(&rte->rte_list);
- kfree(rte);
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-int iosapic_init(unsigned long phys_addr, unsigned int gsi_base)
-{
- int num_rte, err, index;
- unsigned int isa_irq, ver;
- char __iomem *addr;
- unsigned long flags;
-
- spin_lock_irqsave(&iosapic_lock, flags);
- index = find_iosapic(gsi_base);
- if (index >= 0) {
- spin_unlock_irqrestore(&iosapic_lock, flags);
- return -EBUSY;
- }
-
- addr = ioremap(phys_addr, 0);
- if (addr == NULL) {
- spin_unlock_irqrestore(&iosapic_lock, flags);
- return -ENOMEM;
- }
- ver = iosapic_version(addr);
- if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
- iounmap(addr);
- spin_unlock_irqrestore(&iosapic_lock, flags);
- return err;
- }
-
- /*
- * The MAX_REDIR register holds the highest input pin number
- * (starting from 0). We add 1 so that we can use it for
- * number of pins (= RTEs)
- */
- num_rte = ((ver >> 16) & 0xff) + 1;
-
- index = iosapic_alloc();
- iosapic_lists[index].addr = addr;
- iosapic_lists[index].gsi_base = gsi_base;
- iosapic_lists[index].num_rte = num_rte;
-#ifdef CONFIG_NUMA
- iosapic_lists[index].node = MAX_NUMNODES;
-#endif
- spin_lock_init(&iosapic_lists[index].lock);
- spin_unlock_irqrestore(&iosapic_lock, flags);
-
- if ((gsi_base == 0) && pcat_compat) {
- /*
- * Map the legacy ISA devices into the IOSAPIC data. Some of
- * these may get reprogrammed later on with data from the ACPI
- * Interrupt Source Override table.
- */
- for (isa_irq = 0; isa_irq < 16; ++isa_irq)
- iosapic_override_isa_irq(isa_irq, isa_irq,
- IOSAPIC_POL_HIGH,
- IOSAPIC_EDGE);
- }
- return 0;
-}
-
-int iosapic_remove(unsigned int gsi_base)
-{
- int i, irq, index, err = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&iosapic_lock, flags);
- index = find_iosapic(gsi_base);
- if (index < 0) {
- printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
- __func__, gsi_base);
- goto out;
- }
-
- if (iosapic_lists[index].rtes_inuse) {
- err = -EBUSY;
- printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
- __func__, gsi_base);
- goto out;
- }
-
- for (i = gsi_base; i < gsi_base + iosapic_lists[index].num_rte; i++) {
- irq = __gsi_to_irq(i);
- if (irq < 0)
- continue;
-
- err = iosapic_delete_rte(irq, i);
- if (err)
- goto out;
- }
-
- iounmap(iosapic_lists[index].addr);
- iosapic_free(index);
- out:
- spin_unlock_irqrestore(&iosapic_lock, flags);
- return err;
-}
-
-#ifdef CONFIG_NUMA
-void map_iosapic_to_node(unsigned int gsi_base, int node)
-{
- int index;
-
- index = find_iosapic(gsi_base);
- if (index < 0) {
- printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
- __func__, gsi_base);
- return;
- }
- iosapic_lists[index].node = node;
- return;
-}
-#endif
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
deleted file mode 100644
index 275b9ea58c64..000000000000
--- a/arch/ia64/kernel/irq.c
+++ /dev/null
@@ -1,181 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/ia64/kernel/irq.c
- *
- * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
- *
- * This file contains the code used by various IRQ handling routines:
- * asking for different IRQs should be done through these routines
- * instead of just grabbing them. Thus setups with different IRQ numbers
- * shouldn't result in any weird surprises, and installing new handlers
- * should be easier.
- *
- * Copyright (C) Ashok Raj<ashok.raj@intel.com>, Intel Corporation 2004
- *
- * 4/14/2004: Added code to handle cpu migration and do safe irq
- * migration without losing interrupts for iosapic
- * architecture.
- */
-
-#include <asm/delay.h>
-#include <linux/uaccess.h>
-#include <linux/module.h>
-#include <linux/seq_file.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-
-#include <asm/mca.h>
-#include <asm/xtp.h>
-
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-void ack_bad_irq(unsigned int irq)
-{
- printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
-}
-
-/*
- * Interrupt statistics:
- */
-
-atomic_t irq_err_count;
-
-/*
- * /proc/interrupts printing:
- */
-int arch_show_interrupts(struct seq_file *p, int prec)
-{
- seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
- return 0;
-}
-
-#ifdef CONFIG_SMP
-static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
-
-void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
-{
- if (irq < NR_IRQS) {
- irq_data_update_affinity(irq_get_irq_data(irq),
- cpumask_of(cpu_logical_id(hwid)));
- irq_redir[irq] = (char) (redir & 0xff);
- }
-}
-#endif /* CONFIG_SMP */
-
-int __init arch_early_irq_init(void)
-{
- ia64_mca_irq_init();
- return 0;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-unsigned int vectors_in_migration[NR_IRQS];
-
-/*
- * Since cpu_online_mask is already updated, we just need to check for
- * affinity that has zeros
- */
-static void migrate_irqs(void)
-{
- int irq, new_cpu;
-
- for (irq=0; irq < NR_IRQS; irq++) {
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_data *data = irq_desc_get_irq_data(desc);
- struct irq_chip *chip = irq_data_get_irq_chip(data);
-
- if (irqd_irq_disabled(data))
- continue;
-
- /*
- * No handling for now.
- * TBD: Implement a disable function so we can now
- * tell CPU not to respond to these local intr sources.
- * such as ITV,CPEI,MCA etc.
- */
- if (irqd_is_per_cpu(data))
- continue;
-
- if (cpumask_any_and(irq_data_get_affinity_mask(data),
- cpu_online_mask) >= nr_cpu_ids) {
- /*
- * Save it for phase 2 processing
- */
- vectors_in_migration[irq] = irq;
-
- new_cpu = cpumask_any(cpu_online_mask);
-
- /*
- * Al three are essential, currently WARN_ON.. maybe panic?
- */
- if (chip && chip->irq_disable &&
- chip->irq_enable && chip->irq_set_affinity) {
- chip->irq_disable(data);
- chip->irq_set_affinity(data,
- cpumask_of(new_cpu), false);
- chip->irq_enable(data);
- } else {
- WARN_ON((!chip || !chip->irq_disable ||
- !chip->irq_enable ||
- !chip->irq_set_affinity));
- }
- }
- }
-}
-
-void fixup_irqs(void)
-{
- unsigned int irq;
- extern void ia64_process_pending_intr(void);
- extern volatile int time_keeper_id;
-
- /* Mask ITV to disable timer */
- ia64_set_itv(1 << 16);
-
- /*
- * Find a new timesync master
- */
- if (smp_processor_id() == time_keeper_id) {
- time_keeper_id = cpumask_first(cpu_online_mask);
- printk ("CPU %d is now promoted to time-keeper master\n", time_keeper_id);
- }
-
- /*
- * Phase 1: Locate IRQs bound to this cpu and
- * relocate them for cpu removal.
- */
- migrate_irqs();
-
- /*
- * Phase 2: Perform interrupt processing for all entries reported in
- * local APIC.
- */
- ia64_process_pending_intr();
-
- /*
- * Phase 3: Now handle any interrupts not captured in local APIC.
- * This is to account for cases that device interrupted during the time the
- * rte was being disabled and re-programmed.
- */
- for (irq=0; irq < NR_IRQS; irq++) {
- if (vectors_in_migration[irq]) {
- struct pt_regs *old_regs = set_irq_regs(NULL);
-
- vectors_in_migration[irq]=0;
- generic_handle_irq(irq);
- set_irq_regs(old_regs);
- }
- }
-
- /*
- * Now let processor die. We do irq disable and max_xtp() to
- * ensure there is no more interrupts routed to this processor.
- * But the local timer interrupt can have 1 pending which we
- * take care in timer_interrupt().
- */
- max_xtp();
- local_irq_disable();
-}
-#endif
diff --git a/arch/ia64/kernel/irq.h b/arch/ia64/kernel/irq.h
deleted file mode 100644
index 4d16f3cbeb1d..000000000000
--- a/arch/ia64/kernel/irq.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-extern void register_percpu_irq(ia64_vector vec, irq_handler_t handler,
- unsigned long flags, const char *name);
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
deleted file mode 100644
index 46e33c5cb53d..000000000000
--- a/arch/ia64/kernel/irq_ia64.c
+++ /dev/null
@@ -1,645 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/ia64/kernel/irq_ia64.c
- *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 6/10/99: Updated to bring in sync with x86 version to facilitate
- * support for SMP and different interrupt controllers.
- *
- * 09/15/00 Goutham Rao <goutham.rao@intel.com> Implemented pci_irq_to_vector
- * PCI to vector allocation routine.
- * 04/14/2004 Ashok Raj <ashok.raj@intel.com>
- * Added CPU Hotplug handling for IPF.
- */
-
-#include <linux/module.h>
-#include <linux/pgtable.h>
-
-#include <linux/jiffies.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/kernel_stat.h>
-#include <linux/ptrace.h>
-#include <linux/signal.h>
-#include <linux/smp.h>
-#include <linux/threads.h>
-#include <linux/bitops.h>
-#include <linux/irq.h>
-#include <linux/ratelimit.h>
-#include <linux/acpi.h>
-#include <linux/sched.h>
-
-#include <asm/delay.h>
-#include <asm/intrinsics.h>
-#include <asm/io.h>
-#include <asm/hw_irq.h>
-#include <asm/tlbflush.h>
-
-#define IRQ_DEBUG 0
-
-#define IRQ_VECTOR_UNASSIGNED (0)
-
-#define IRQ_UNUSED (0)
-#define IRQ_USED (1)
-#define IRQ_RSVD (2)
-
-int ia64_first_device_vector = IA64_DEF_FIRST_DEVICE_VECTOR;
-int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR;
-
-/* default base addr of IPI table */
-void __iomem *ipi_base_addr = ((void __iomem *)
- (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR));
-
-static cpumask_t vector_allocation_domain(int cpu);
-
-/*
- * Legacy IRQ to IA-64 vector translation table.
- */
-__u8 isa_irq_to_vector_map[16] = {
- /* 8259 IRQ translation, first 16 entries */
- 0x2f, 0x20, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29,
- 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21
-};
-EXPORT_SYMBOL(isa_irq_to_vector_map);
-
-DEFINE_SPINLOCK(vector_lock);
-
-struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = {
- [0 ... NR_IRQS - 1] = {
- .vector = IRQ_VECTOR_UNASSIGNED,
- .domain = CPU_MASK_NONE
- }
-};
-
-DEFINE_PER_CPU(int[IA64_NUM_VECTORS], vector_irq) = {
- [0 ... IA64_NUM_VECTORS - 1] = -1
-};
-
-static cpumask_t vector_table[IA64_NUM_VECTORS] = {
- [0 ... IA64_NUM_VECTORS - 1] = CPU_MASK_NONE
-};
-
-static int irq_status[NR_IRQS] = {
- [0 ... NR_IRQS -1] = IRQ_UNUSED
-};
-
-static inline int find_unassigned_irq(void)
-{
- int irq;
-
- for (irq = IA64_FIRST_DEVICE_VECTOR; irq < NR_IRQS; irq++)
- if (irq_status[irq] == IRQ_UNUSED)
- return irq;
- return -ENOSPC;
-}
-
-static inline int find_unassigned_vector(cpumask_t domain)
-{
- cpumask_t mask;
- int pos, vector;
-
- cpumask_and(&mask, &domain, cpu_online_mask);
- if (cpumask_empty(&mask))
- return -EINVAL;
-
- for (pos = 0; pos < IA64_NUM_DEVICE_VECTORS; pos++) {
- vector = IA64_FIRST_DEVICE_VECTOR + pos;
- cpumask_and(&mask, &domain, &vector_table[vector]);
- if (!cpumask_empty(&mask))
- continue;
- return vector;
- }
- return -ENOSPC;
-}
-
-static int __bind_irq_vector(int irq, int vector, cpumask_t domain)
-{
- cpumask_t mask;
- int cpu;
- struct irq_cfg *cfg = &irq_cfg[irq];
-
- BUG_ON((unsigned)irq >= NR_IRQS);
- BUG_ON((unsigned)vector >= IA64_NUM_VECTORS);
-
- cpumask_and(&mask, &domain, cpu_online_mask);
- if (cpumask_empty(&mask))
- return -EINVAL;
- if ((cfg->vector == vector) && cpumask_equal(&cfg->domain, &domain))
- return 0;
- if (cfg->vector != IRQ_VECTOR_UNASSIGNED)
- return -EBUSY;
- for_each_cpu(cpu, &mask)
- per_cpu(vector_irq, cpu)[vector] = irq;
- cfg->vector = vector;
- cfg->domain = domain;
- irq_status[irq] = IRQ_USED;
- cpumask_or(&vector_table[vector], &vector_table[vector], &domain);
- return 0;
-}
-
-int bind_irq_vector(int irq, int vector, cpumask_t domain)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&vector_lock, flags);
- ret = __bind_irq_vector(irq, vector, domain);
- spin_unlock_irqrestore(&vector_lock, flags);
- return ret;
-}
-
-static void __clear_irq_vector(int irq)
-{
- int vector, cpu;
- cpumask_t domain;
- struct irq_cfg *cfg = &irq_cfg[irq];
-
- BUG_ON((unsigned)irq >= NR_IRQS);
- BUG_ON(cfg->vector == IRQ_VECTOR_UNASSIGNED);
- vector = cfg->vector;
- domain = cfg->domain;
- for_each_cpu_and(cpu, &cfg->domain, cpu_online_mask)
- per_cpu(vector_irq, cpu)[vector] = -1;
- cfg->vector = IRQ_VECTOR_UNASSIGNED;
- cfg->domain = CPU_MASK_NONE;
- irq_status[irq] = IRQ_UNUSED;
- cpumask_andnot(&vector_table[vector], &vector_table[vector], &domain);
-}
-
-static void clear_irq_vector(int irq)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&vector_lock, flags);
- __clear_irq_vector(irq);
- spin_unlock_irqrestore(&vector_lock, flags);
-}
-
-int
-ia64_native_assign_irq_vector (int irq)
-{
- unsigned long flags;
- int vector, cpu;
- cpumask_t domain = CPU_MASK_NONE;
-
- vector = -ENOSPC;
-
- spin_lock_irqsave(&vector_lock, flags);
- for_each_online_cpu(cpu) {
- domain = vector_allocation_domain(cpu);
- vector = find_unassigned_vector(domain);
- if (vector >= 0)
- break;
- }
- if (vector < 0)
- goto out;
- if (irq == AUTO_ASSIGN)
- irq = vector;
- BUG_ON(__bind_irq_vector(irq, vector, domain));
- out:
- spin_unlock_irqrestore(&vector_lock, flags);
- return vector;
-}
-
-void
-ia64_native_free_irq_vector (int vector)
-{
- if (vector < IA64_FIRST_DEVICE_VECTOR ||
- vector > IA64_LAST_DEVICE_VECTOR)
- return;
- clear_irq_vector(vector);
-}
-
-int
-reserve_irq_vector (int vector)
-{
- if (vector < IA64_FIRST_DEVICE_VECTOR ||
- vector > IA64_LAST_DEVICE_VECTOR)
- return -EINVAL;
- return !!bind_irq_vector(vector, vector, CPU_MASK_ALL);
-}
-
-/*
- * Initialize vector_irq on a new cpu. This function must be called
- * with vector_lock held.
- */
-void __setup_vector_irq(int cpu)
-{
- int irq, vector;
-
- /* Clear vector_irq */
- for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
- per_cpu(vector_irq, cpu)[vector] = -1;
- /* Mark the inuse vectors */
- for (irq = 0; irq < NR_IRQS; ++irq) {
- if (!cpumask_test_cpu(cpu, &irq_cfg[irq].domain))
- continue;
- vector = irq_to_vector(irq);
- per_cpu(vector_irq, cpu)[vector] = irq;
- }
-}
-
-#ifdef CONFIG_SMP
-
-static enum vector_domain_type {
- VECTOR_DOMAIN_NONE,
- VECTOR_DOMAIN_PERCPU
-} vector_domain_type = VECTOR_DOMAIN_NONE;
-
-static cpumask_t vector_allocation_domain(int cpu)
-{
- if (vector_domain_type == VECTOR_DOMAIN_PERCPU)
- return *cpumask_of(cpu);
- return CPU_MASK_ALL;
-}
-
-static int __irq_prepare_move(int irq, int cpu)
-{
- struct irq_cfg *cfg = &irq_cfg[irq];
- int vector;
- cpumask_t domain;
-
- if (cfg->move_in_progress || cfg->move_cleanup_count)
- return -EBUSY;
- if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu))
- return -EINVAL;
- if (cpumask_test_cpu(cpu, &cfg->domain))
- return 0;
- domain = vector_allocation_domain(cpu);
- vector = find_unassigned_vector(domain);
- if (vector < 0)
- return -ENOSPC;
- cfg->move_in_progress = 1;
- cfg->old_domain = cfg->domain;
- cfg->vector = IRQ_VECTOR_UNASSIGNED;
- cfg->domain = CPU_MASK_NONE;
- BUG_ON(__bind_irq_vector(irq, vector, domain));
- return 0;
-}
-
-int irq_prepare_move(int irq, int cpu)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&vector_lock, flags);
- ret = __irq_prepare_move(irq, cpu);
- spin_unlock_irqrestore(&vector_lock, flags);
- return ret;
-}
-
-void irq_complete_move(unsigned irq)
-{
- struct irq_cfg *cfg = &irq_cfg[irq];
- cpumask_t cleanup_mask;
- int i;
-
- if (likely(!cfg->move_in_progress))
- return;
-
- if (unlikely(cpumask_test_cpu(smp_processor_id(), &cfg->old_domain)))
- return;
-
- cpumask_and(&cleanup_mask, &cfg->old_domain, cpu_online_mask);
- cfg->move_cleanup_count = cpumask_weight(&cleanup_mask);
- for_each_cpu(i, &cleanup_mask)
- ia64_send_ipi(i, IA64_IRQ_MOVE_VECTOR, IA64_IPI_DM_INT, 0);
- cfg->move_in_progress = 0;
-}
-
-static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id)
-{
- int me = smp_processor_id();
- ia64_vector vector;
- unsigned long flags;
-
- for (vector = IA64_FIRST_DEVICE_VECTOR;
- vector < IA64_LAST_DEVICE_VECTOR; vector++) {
- int irq;
- struct irq_desc *desc;
- struct irq_cfg *cfg;
- irq = __this_cpu_read(vector_irq[vector]);
- if (irq < 0)
- continue;
-
- desc = irq_to_desc(irq);
- cfg = irq_cfg + irq;
- raw_spin_lock(&desc->lock);
- if (!cfg->move_cleanup_count)
- goto unlock;
-
- if (!cpumask_test_cpu(me, &cfg->old_domain))
- goto unlock;
-
- spin_lock_irqsave(&vector_lock, flags);
- __this_cpu_write(vector_irq[vector], -1);
- cpumask_clear_cpu(me, &vector_table[vector]);
- spin_unlock_irqrestore(&vector_lock, flags);
- cfg->move_cleanup_count--;
- unlock:
- raw_spin_unlock(&desc->lock);
- }
- return IRQ_HANDLED;
-}
-
-static int __init parse_vector_domain(char *arg)
-{
- if (!arg)
- return -EINVAL;
- if (!strcmp(arg, "percpu")) {
- vector_domain_type = VECTOR_DOMAIN_PERCPU;
- no_int_routing = 1;
- }
- return 0;
-}
-early_param("vector", parse_vector_domain);
-#else
-static cpumask_t vector_allocation_domain(int cpu)
-{
- return CPU_MASK_ALL;
-}
-#endif
-
-
-void destroy_and_reserve_irq(unsigned int irq)
-{
- unsigned long flags;
-
- irq_init_desc(irq);
- spin_lock_irqsave(&vector_lock, flags);
- __clear_irq_vector(irq);
- irq_status[irq] = IRQ_RSVD;
- spin_unlock_irqrestore(&vector_lock, flags);
-}
-
-/*
- * Dynamic irq allocate and deallocation for MSI
- */
-int create_irq(void)
-{
- unsigned long flags;
- int irq, vector, cpu;
- cpumask_t domain = CPU_MASK_NONE;
-
- irq = vector = -ENOSPC;
- spin_lock_irqsave(&vector_lock, flags);
- for_each_online_cpu(cpu) {
- domain = vector_allocation_domain(cpu);
- vector = find_unassigned_vector(domain);
- if (vector >= 0)
- break;
- }
- if (vector < 0)
- goto out;
- irq = find_unassigned_irq();
- if (irq < 0)
- goto out;
- BUG_ON(__bind_irq_vector(irq, vector, domain));
- out:
- spin_unlock_irqrestore(&vector_lock, flags);
- if (irq >= 0)
- irq_init_desc(irq);
- return irq;
-}
-
-void destroy_irq(unsigned int irq)
-{
- irq_init_desc(irq);
- clear_irq_vector(irq);
-}
-
-#ifdef CONFIG_SMP
-# define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE)
-# define IS_LOCAL_TLB_FLUSH(vec) (vec == IA64_IPI_LOCAL_TLB_FLUSH)
-#else
-# define IS_RESCHEDULE(vec) (0)
-# define IS_LOCAL_TLB_FLUSH(vec) (0)
-#endif
-/*
- * That's where the IVT branches when we get an external
- * interrupt. This branches to the correct hardware IRQ handler via
- * function ptr.
- */
-void
-ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
-{
- struct pt_regs *old_regs = set_irq_regs(regs);
- unsigned long saved_tpr;
-
-#if IRQ_DEBUG
- {
- unsigned long bsp, sp;
-
- /*
- * Note: if the interrupt happened while executing in
- * the context switch routine (ia64_switch_to), we may
- * get a spurious stack overflow here. This is
- * because the register and the memory stack are not
- * switched atomically.
- */
- bsp = ia64_getreg(_IA64_REG_AR_BSP);
- sp = ia64_getreg(_IA64_REG_SP);
-
- if ((sp - bsp) < 1024) {
- static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
-
- if (__ratelimit(&ratelimit)) {
- printk("ia64_handle_irq: DANGER: less than "
- "1KB of free stack space!!\n"
- "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
- }
- }
- }
-#endif /* IRQ_DEBUG */
-
- /*
- * Always set TPR to limit maximum interrupt nesting depth to
- * 16 (without this, it would be ~240, which could easily lead
- * to kernel stack overflows).
- */
- irq_enter();
- saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
- ia64_srlz_d();
- while (vector != IA64_SPURIOUS_INT_VECTOR) {
- int irq = local_vector_to_irq(vector);
-
- if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
- smp_local_flush_tlb();
- kstat_incr_irq_this_cpu(irq);
- } else if (unlikely(IS_RESCHEDULE(vector))) {
- scheduler_ipi();
- kstat_incr_irq_this_cpu(irq);
- } else {
- ia64_setreg(_IA64_REG_CR_TPR, vector);
- ia64_srlz_d();
-
- if (unlikely(irq < 0)) {
- printk(KERN_ERR "%s: Unexpected interrupt "
- "vector %d on CPU %d is not mapped "
- "to any IRQ!\n", __func__, vector,
- smp_processor_id());
- } else
- generic_handle_irq(irq);
-
- /*
- * Disable interrupts and send EOI:
- */
- local_irq_disable();
- ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
- }
- ia64_eoi();
- vector = ia64_get_ivr();
- }
- /*
- * This must be done *after* the ia64_eoi(). For example, the keyboard softirq
- * handler needs to be able to wait for further keyboard interrupts, which can't
- * come through until ia64_eoi() has been done.
- */
- irq_exit();
- set_irq_regs(old_regs);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-/*
- * This function emulates a interrupt processing when a cpu is about to be
- * brought down.
- */
-void ia64_process_pending_intr(void)
-{
- ia64_vector vector;
- unsigned long saved_tpr;
- extern unsigned int vectors_in_migration[NR_IRQS];
-
- vector = ia64_get_ivr();
-
- irq_enter();
- saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
- ia64_srlz_d();
-
- /*
- * Perform normal interrupt style processing
- */
- while (vector != IA64_SPURIOUS_INT_VECTOR) {
- int irq = local_vector_to_irq(vector);
-
- if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
- smp_local_flush_tlb();
- kstat_incr_irq_this_cpu(irq);
- } else if (unlikely(IS_RESCHEDULE(vector))) {
- kstat_incr_irq_this_cpu(irq);
- } else {
- struct pt_regs *old_regs = set_irq_regs(NULL);
-
- ia64_setreg(_IA64_REG_CR_TPR, vector);
- ia64_srlz_d();
-
- /*
- * Now try calling normal ia64_handle_irq as it would have got called
- * from a real intr handler. Try passing null for pt_regs, hopefully
- * it will work. I hope it works!.
- * Probably could shared code.
- */
- if (unlikely(irq < 0)) {
- printk(KERN_ERR "%s: Unexpected interrupt "
- "vector %d on CPU %d not being mapped "
- "to any IRQ!!\n", __func__, vector,
- smp_processor_id());
- } else {
- vectors_in_migration[irq]=0;
- generic_handle_irq(irq);
- }
- set_irq_regs(old_regs);
-
- /*
- * Disable interrupts and send EOI
- */
- local_irq_disable();
- ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
- }
- ia64_eoi();
- vector = ia64_get_ivr();
- }
- irq_exit();
-}
-#endif
-
-
-#ifdef CONFIG_SMP
-
-static irqreturn_t dummy_handler (int irq, void *dev_id)
-{
- BUG();
- return IRQ_NONE;
-}
-
-/*
- * KVM uses this interrupt to force a cpu out of guest mode
- */
-
-#endif
-
-void
-register_percpu_irq(ia64_vector vec, irq_handler_t handler, unsigned long flags,
- const char *name)
-{
- unsigned int irq;
-
- irq = vec;
- BUG_ON(bind_irq_vector(irq, vec, CPU_MASK_ALL));
- irq_set_status_flags(irq, IRQ_PER_CPU);
- irq_set_chip(irq, &irq_type_ia64_lsapic);
- if (handler)
- if (request_irq(irq, handler, flags, name, NULL))
- pr_err("Failed to request irq %u (%s)\n", irq, name);
- irq_set_handler(irq, handle_percpu_irq);
-}
-
-void __init
-ia64_native_register_ipi(void)
-{
-#ifdef CONFIG_SMP
- register_percpu_irq(IA64_IPI_VECTOR, handle_IPI, 0, "IPI");
- register_percpu_irq(IA64_IPI_RESCHEDULE, dummy_handler, 0, "resched");
- register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, dummy_handler, 0,
- "tlb_flush");
-#endif
-}
-
-void __init
-init_IRQ (void)
-{
- acpi_boot_init();
- ia64_register_ipi();
- register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL, 0, NULL);
-#ifdef CONFIG_SMP
- if (vector_domain_type != VECTOR_DOMAIN_NONE) {
- register_percpu_irq(IA64_IRQ_MOVE_VECTOR,
- smp_irq_move_cleanup_interrupt, 0,
- "irq_move");
- }
-#endif
-}
-
-void
-ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect)
-{
- void __iomem *ipi_addr;
- unsigned long ipi_data;
- unsigned long phys_cpu_id;
-
- phys_cpu_id = cpu_physical_id(cpu);
-
- /*
- * cpu number is in 8bit ID and 8bit EID
- */
-
- ipi_data = (delivery_mode << 8) | (vector & 0xff);
- ipi_addr = ipi_base_addr + ((phys_cpu_id << 4) | ((redirect & 1) << 3));
-
- writeq(ipi_data, ipi_addr);
-}
diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c
deleted file mode 100644
index 23bf4499a75d..000000000000
--- a/arch/ia64/kernel/irq_lsapic.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * LSAPIC Interrupt Controller
- *
- * This takes care of interrupts that are generated by the CPU's
- * internal Streamlined Advanced Programmable Interrupt Controller
- * (LSAPIC), such as the ITC and IPI interrupts.
- *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 2000 Hewlett-Packard Co
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/sched.h>
-#include <linux/irq.h>
-
-static unsigned int
-lsapic_noop_startup (struct irq_data *data)
-{
- return 0;
-}
-
-static void
-lsapic_noop (struct irq_data *data)
-{
- /* nothing to do... */
-}
-
-static int lsapic_retrigger(struct irq_data *data)
-{
- ia64_resend_irq(data->irq);
-
- return 1;
-}
-
-struct irq_chip irq_type_ia64_lsapic = {
- .name = "LSAPIC",
- .irq_startup = lsapic_noop_startup,
- .irq_shutdown = lsapic_noop,
- .irq_enable = lsapic_noop,
- .irq_disable = lsapic_noop,
- .irq_ack = lsapic_noop,
- .irq_retrigger = lsapic_retrigger,
-};
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
deleted file mode 100644
index da90c49df628..000000000000
--- a/arch/ia64/kernel/ivt.S
+++ /dev/null
@@ -1,1688 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/ia64/kernel/ivt.S
- *
- * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- * David Mosberger <davidm@hpl.hp.com>
- * Copyright (C) 2000, 2002-2003 Intel Co
- * Asit Mallick <asit.k.mallick@intel.com>
- * Suresh Siddha <suresh.b.siddha@intel.com>
- * Kenneth Chen <kenneth.w.chen@intel.com>
- * Fenghua Yu <fenghua.yu@intel.com>
- *
- * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP
- * 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT.
- *
- * Copyright (C) 2005 Hewlett-Packard Co
- * Dan Magenheimer <dan.magenheimer@hp.com>
- * Xen paravirtualization
- * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
- * VA Linux Systems Japan K.K.
- * pv_ops.
- * Yaozu (Eddie) Dong <eddie.dong@intel.com>
- */
-/*
- * This file defines the interruption vector table used by the CPU.
- * It does not include one entry per possible cause of interruption.
- *
- * The first 20 entries of the table contain 64 bundles each while the
- * remaining 48 entries contain only 16 bundles each.
- *
- * The 64 bundles are used to allow inlining the whole handler for critical
- * interruptions like TLB misses.
- *
- * For each entry, the comment is as follows:
- *
- * // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
- * entry offset ----/ / / / /
- * entry number ---------/ / / /
- * size of the entry -------------/ / /
- * vector name -------------------------------------/ /
- * interruptions triggering this vector ----------------------/
- *
- * The table is 32KB in size and must be aligned on 32KB boundary.
- * (The CPU ignores the 15 lower bits of the address)
- *
- * Table is based upon EAS2.6 (Oct 1999)
- */
-
-#include <linux/export.h>
-#include <linux/pgtable.h>
-#include <asm/asmmacro.h>
-#include <asm/break.h>
-#include <asm/kregs.h>
-#include <asm/asm-offsets.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/thread_info.h>
-#include <asm/unistd.h>
-#include <asm/errno.h>
-
-#if 0
-# define PSR_DEFAULT_BITS psr.ac
-#else
-# define PSR_DEFAULT_BITS 0
-#endif
-
-#if 0
- /*
- * This lets you track the last eight faults that occurred on the CPU. Make sure ar.k2 isn't
- * needed for something else before enabling this...
- */
-# define DBG_FAULT(i) mov r16=ar.k2;; shl r16=r16,8;; add r16=(i),r16;;mov ar.k2=r16
-#else
-# define DBG_FAULT(i)
-#endif
-
-#include "minstate.h"
-
-#define FAULT(n) \
- mov r31=pr; \
- mov r19=n;; /* prepare to save predicates */ \
- br.sptk.many dispatch_to_fault_handler
-
- .section .text..ivt,"ax"
-
- .align 32768 // align on 32KB boundary
- .global ia64_ivt
- EXPORT_SYMBOL(ia64_ivt)
-ia64_ivt:
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47)
-ENTRY(vhpt_miss)
- DBG_FAULT(0)
- /*
- * The VHPT vector is invoked when the TLB entry for the virtual page table
- * is missing. This happens only as a result of a previous
- * (the "original") TLB miss, which may either be caused by an instruction
- * fetch or a data access (or non-access).
- *
- * What we do here is normal TLB miss handing for the _original_ miss,
- * followed by inserting the TLB entry for the virtual page table page
- * that the VHPT walker was attempting to access. The latter gets
- * inserted as long as page table entry above pte level have valid
- * mappings for the faulting address. The TLB entry for the original
- * miss gets inserted only if the pte entry indicates that the page is
- * present.
- *
- * do_page_fault gets invoked in the following cases:
- * - the faulting virtual address uses unimplemented address bits
- * - the faulting virtual address has no valid page table mapping
- */
- MOV_FROM_IFA(r16) // get address that caused the TLB miss
-#ifdef CONFIG_HUGETLB_PAGE
- movl r18=PAGE_SHIFT
- MOV_FROM_ITIR(r25)
-#endif
- ;;
- RSM_PSR_DT // use physical addressing for data
- mov r31=pr // save the predicate registers
- mov r19=IA64_KR(PT_BASE) // get page table base address
- shl r21=r16,3 // shift bit 60 into sign bit
- shr.u r17=r16,61 // get the region number into r17
- ;;
- shr.u r22=r21,3
-#ifdef CONFIG_HUGETLB_PAGE
- extr.u r26=r25,2,6
- ;;
- cmp.ne p8,p0=r18,r26
- sub r27=r26,r18
- ;;
-(p8) dep r25=r18,r25,2,6
-(p8) shr r22=r22,r27
-#endif
- ;;
- cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5?
- shr.u r18=r22,PGDIR_SHIFT // get bottom portion of pgd index bit
- ;;
-(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place
-
- srlz.d
- LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir
-
- .pred.rel "mutex", p6, p7
-(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
-(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
- ;;
-(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=pgd_offset for region 5
-(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=pgd_offset for region[0-4]
- cmp.eq p7,p6=0,r21 // unused address bits all zeroes?
-#if CONFIG_PGTABLE_LEVELS == 4
- shr.u r28=r22,PUD_SHIFT // shift pud index into position
-#else
- shr.u r18=r22,PMD_SHIFT // shift pmd index into position
-#endif
- ;;
- ld8 r17=[r17] // get *pgd (may be 0)
- ;;
-(p7) cmp.eq p6,p7=r17,r0 // was pgd_present(*pgd) == NULL?
-#if CONFIG_PGTABLE_LEVELS == 4
- dep r28=r28,r17,3,(PAGE_SHIFT-3) // r28=pud_offset(pgd,addr)
- ;;
- shr.u r18=r22,PMD_SHIFT // shift pmd index into position
-(p7) ld8 r29=[r28] // get *pud (may be 0)
- ;;
-(p7) cmp.eq.or.andcm p6,p7=r29,r0 // was pud_present(*pud) == NULL?
- dep r17=r18,r29,3,(PAGE_SHIFT-3) // r17=pmd_offset(pud,addr)
-#else
- dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=pmd_offset(pgd,addr)
-#endif
- ;;
-(p7) ld8 r20=[r17] // get *pmd (may be 0)
- shr.u r19=r22,PAGE_SHIFT // shift pte index into position
- ;;
-(p7) cmp.eq.or.andcm p6,p7=r20,r0 // was pmd_present(*pmd) == NULL?
- dep r21=r19,r20,3,(PAGE_SHIFT-3) // r21=pte_offset(pmd,addr)
- ;;
-(p7) ld8 r18=[r21] // read *pte
- MOV_FROM_ISR(r19) // cr.isr bit 32 tells us if this is an insn miss
- ;;
-(p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared?
- MOV_FROM_IHA(r22) // get the VHPT address that caused the TLB miss
- ;; // avoid RAW on p7
-(p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss?
- dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address
- ;;
- ITC_I_AND_D(p10, p11, r18, r24) // insert the instruction TLB entry and
- // insert the data TLB entry
-(p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault)
- MOV_TO_IFA(r22, r24)
-
-#ifdef CONFIG_HUGETLB_PAGE
- MOV_TO_ITIR(p8, r25, r24) // change to default page-size for VHPT
-#endif
-
- /*
- * Now compute and insert the TLB entry for the virtual page table. We never
- * execute in a page table page so there is no need to set the exception deferral
- * bit.
- */
- adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
- ;;
- ITC_D(p7, r24, r25)
- ;;
-#ifdef CONFIG_SMP
- /*
- * Tell the assemblers dependency-violation checker that the above "itc" instructions
- * cannot possibly affect the following loads:
- */
- dv_serialize_data
-
- /*
- * Re-check pagetable entry. If they changed, we may have received a ptc.g
- * between reading the pagetable and the "itc". If so, flush the entry we
- * inserted and retry. At this point, we have:
- *
- * r28 = equivalent of pud_offset(pgd, ifa)
- * r17 = equivalent of pmd_offset(pud, ifa)
- * r21 = equivalent of pte_offset(pmd, ifa)
- *
- * r29 = *pud
- * r20 = *pmd
- * r18 = *pte
- */
- ld8 r25=[r21] // read *pte again
- ld8 r26=[r17] // read *pmd again
-#if CONFIG_PGTABLE_LEVELS == 4
- ld8 r19=[r28] // read *pud again
-#endif
- cmp.ne p6,p7=r0,r0
- ;;
- cmp.ne.or.andcm p6,p7=r26,r20 // did *pmd change
-#if CONFIG_PGTABLE_LEVELS == 4
- cmp.ne.or.andcm p6,p7=r19,r29 // did *pud change
-#endif
- mov r27=PAGE_SHIFT<<2
- ;;
-(p6) ptc.l r22,r27 // purge PTE page translation
-(p7) cmp.ne.or.andcm p6,p7=r25,r18 // did *pte change
- ;;
-(p6) ptc.l r16,r27 // purge translation
-#endif
-
- mov pr=r31,-1 // restore predicate registers
- RFI
-END(vhpt_miss)
-
- .org ia64_ivt+0x400
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x0400 Entry 1 (size 64 bundles) ITLB (21)
-ENTRY(itlb_miss)
- DBG_FAULT(1)
- /*
- * The ITLB handler accesses the PTE via the virtually mapped linear
- * page table. If a nested TLB miss occurs, we switch into physical
- * mode, walk the page table, and then re-execute the PTE read and
- * go on normally after that.
- */
- MOV_FROM_IFA(r16) // get virtual address
- mov r29=b0 // save b0
- mov r31=pr // save predicates
-.itlb_fault:
- MOV_FROM_IHA(r17) // get virtual address of PTE
- movl r30=1f // load nested fault continuation point
- ;;
-1: ld8 r18=[r17] // read *pte
- ;;
- mov b0=r29
- tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
-(p6) br.cond.spnt page_fault
- ;;
- ITC_I(p0, r18, r19)
- ;;
-#ifdef CONFIG_SMP
- /*
- * Tell the assemblers dependency-violation checker that the above "itc" instructions
- * cannot possibly affect the following loads:
- */
- dv_serialize_data
-
- ld8 r19=[r17] // read *pte again and see if same
- mov r20=PAGE_SHIFT<<2 // setup page size for purge
- ;;
- cmp.ne p7,p0=r18,r19
- ;;
-(p7) ptc.l r16,r20
-#endif
- mov pr=r31,-1
- RFI
-END(itlb_miss)
-
- .org ia64_ivt+0x0800
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
-ENTRY(dtlb_miss)
- DBG_FAULT(2)
- /*
- * The DTLB handler accesses the PTE via the virtually mapped linear
- * page table. If a nested TLB miss occurs, we switch into physical
- * mode, walk the page table, and then re-execute the PTE read and
- * go on normally after that.
- */
- MOV_FROM_IFA(r16) // get virtual address
- mov r29=b0 // save b0
- mov r31=pr // save predicates
-dtlb_fault:
- MOV_FROM_IHA(r17) // get virtual address of PTE
- movl r30=1f // load nested fault continuation point
- ;;
-1: ld8 r18=[r17] // read *pte
- ;;
- mov b0=r29
- tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
-(p6) br.cond.spnt page_fault
- ;;
- ITC_D(p0, r18, r19)
- ;;
-#ifdef CONFIG_SMP
- /*
- * Tell the assemblers dependency-violation checker that the above "itc" instructions
- * cannot possibly affect the following loads:
- */
- dv_serialize_data
-
- ld8 r19=[r17] // read *pte again and see if same
- mov r20=PAGE_SHIFT<<2 // setup page size for purge
- ;;
- cmp.ne p7,p0=r18,r19
- ;;
-(p7) ptc.l r16,r20
-#endif
- mov pr=r31,-1
- RFI
-END(dtlb_miss)
-
- .org ia64_ivt+0x0c00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
-ENTRY(alt_itlb_miss)
- DBG_FAULT(3)
- MOV_FROM_IFA(r16) // get address that caused the TLB miss
- movl r17=PAGE_KERNEL
- MOV_FROM_IPSR(p0, r21)
- movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
- mov r31=pr
- ;;
-#ifdef CONFIG_DISABLE_VHPT
- shr.u r22=r16,61 // get the region number into r21
- ;;
- cmp.gt p8,p0=6,r22 // user mode
- ;;
- THASH(p8, r17, r16, r23)
- ;;
- MOV_TO_IHA(p8, r17, r23)
-(p8) mov r29=b0 // save b0
-(p8) br.cond.dptk .itlb_fault
-#endif
- extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl
- and r19=r19,r16 // clear ed, reserved bits, and PTE control bits
- shr.u r18=r16,57 // move address bit 61 to bit 4
- ;;
- andcm r18=0x10,r18 // bit 4=~address-bit(61)
- cmp.ne p8,p0=r0,r23 // psr.cpl != 0?
- or r19=r17,r19 // insert PTE control bits into r19
- ;;
- or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6
-(p8) br.cond.spnt page_fault
- ;;
- ITC_I(p0, r19, r18) // insert the TLB entry
- mov pr=r31,-1
- RFI
-END(alt_itlb_miss)
-
- .org ia64_ivt+0x1000
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
-ENTRY(alt_dtlb_miss)
- DBG_FAULT(4)
- MOV_FROM_IFA(r16) // get address that caused the TLB miss
- movl r17=PAGE_KERNEL
- MOV_FROM_ISR(r20)
- movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
- MOV_FROM_IPSR(p0, r21)
- mov r31=pr
- mov r24=PERCPU_ADDR
- ;;
-#ifdef CONFIG_DISABLE_VHPT
- shr.u r22=r16,61 // get the region number into r21
- ;;
- cmp.gt p8,p0=6,r22 // access to region 0-5
- ;;
- THASH(p8, r17, r16, r25)
- ;;
- MOV_TO_IHA(p8, r17, r25)
-(p8) mov r29=b0 // save b0
-(p8) br.cond.dptk dtlb_fault
-#endif
- cmp.ge p10,p11=r16,r24 // access to per_cpu_data?
- tbit.z p12,p0=r16,61 // access to region 6?
- mov r25=PERCPU_PAGE_SHIFT << 2
- mov r26=PERCPU_PAGE_SIZE
- nop.m 0
- nop.b 0
- ;;
-(p10) mov r19=IA64_KR(PER_CPU_DATA)
-(p11) and r19=r19,r16 // clear non-ppn fields
- extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl
- and r22=IA64_ISR_CODE_MASK,r20 // get the isr.code field
- tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on?
- tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on?
- ;;
-(p10) sub r19=r19,r26
- MOV_TO_ITIR(p10, r25, r24)
- cmp.ne p8,p0=r0,r23
-(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field
-(p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr
-(p8) br.cond.spnt page_fault
-
- dep r21=-1,r21,IA64_PSR_ED_BIT,1
- ;;
- or r19=r19,r17 // insert PTE control bits into r19
- MOV_TO_IPSR(p6, r21, r24)
- ;;
- ITC_D(p7, r19, r18) // insert the TLB entry
- mov pr=r31,-1
- RFI
-END(alt_dtlb_miss)
-
- .org ia64_ivt+0x1400
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
-ENTRY(nested_dtlb_miss)
- /*
- * In the absence of kernel bugs, we get here when the virtually mapped linear
- * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction
- * Access-bit, or Data Access-bit faults). If the DTLB entry for the virtual page
- * table is missing, a nested TLB miss fault is triggered and control is
- * transferred to this point. When this happens, we lookup the pte for the
- * faulting address by walking the page table in physical mode and return to the
- * continuation point passed in register r30 (or call page_fault if the address is
- * not mapped).
- *
- * Input: r16: faulting address
- * r29: saved b0
- * r30: continuation address
- * r31: saved pr
- *
- * Output: r17: physical address of PTE of faulting address
- * r29: saved b0
- * r30: continuation address
- * r31: saved pr
- *
- * Clobbered: b0, r18, r19, r21, r22, psr.dt (cleared)
- */
- RSM_PSR_DT // switch to using physical data addressing
- mov r19=IA64_KR(PT_BASE) // get the page table base address
- shl r21=r16,3 // shift bit 60 into sign bit
- MOV_FROM_ITIR(r18)
- ;;
- shr.u r17=r16,61 // get the region number into r17
- extr.u r18=r18,2,6 // get the faulting page size
- ;;
- cmp.eq p6,p7=5,r17 // is faulting address in region 5?
- add r22=-PAGE_SHIFT,r18 // adjustment for hugetlb address
- add r18=PGDIR_SHIFT-PAGE_SHIFT,r18
- ;;
- shr.u r22=r16,r22
- shr.u r18=r16,r18
-(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place
-
- srlz.d
- LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir
-
- .pred.rel "mutex", p6, p7
-(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
-(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
- ;;
-(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=pgd_offset for region 5
-(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=pgd_offset for region[0-4]
- cmp.eq p7,p6=0,r21 // unused address bits all zeroes?
-#if CONFIG_PGTABLE_LEVELS == 4
- shr.u r18=r22,PUD_SHIFT // shift pud index into position
-#else
- shr.u r18=r22,PMD_SHIFT // shift pmd index into position
-#endif
- ;;
- ld8 r17=[r17] // get *pgd (may be 0)
- ;;
-(p7) cmp.eq p6,p7=r17,r0 // was pgd_present(*pgd) == NULL?
- dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=p[u|m]d_offset(pgd,addr)
- ;;
-#if CONFIG_PGTABLE_LEVELS == 4
-(p7) ld8 r17=[r17] // get *pud (may be 0)
- shr.u r18=r22,PMD_SHIFT // shift pmd index into position
- ;;
-(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was pud_present(*pud) == NULL?
- dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=pmd_offset(pud,addr)
- ;;
-#endif
-(p7) ld8 r17=[r17] // get *pmd (may be 0)
- shr.u r19=r22,PAGE_SHIFT // shift pte index into position
- ;;
-(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was pmd_present(*pmd) == NULL?
- dep r17=r19,r17,3,(PAGE_SHIFT-3) // r17=pte_offset(pmd,addr);
-(p6) br.cond.spnt page_fault
- mov b0=r30
- br.sptk.many b0 // return to continuation point
-END(nested_dtlb_miss)
-
- .org ia64_ivt+0x1800
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
-ENTRY(ikey_miss)
- DBG_FAULT(6)
- FAULT(6)
-END(ikey_miss)
-
- .org ia64_ivt+0x1c00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
-ENTRY(dkey_miss)
- DBG_FAULT(7)
- FAULT(7)
-END(dkey_miss)
-
- .org ia64_ivt+0x2000
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
-ENTRY(dirty_bit)
- DBG_FAULT(8)
- /*
- * What we do here is to simply turn on the dirty bit in the PTE. We need to
- * update both the page-table and the TLB entry. To efficiently access the PTE,
- * we address it through the virtual page table. Most likely, the TLB entry for
- * the relevant virtual page table page is still present in the TLB so we can
- * normally do this without additional TLB misses. In case the necessary virtual
- * page table TLB entry isn't present, we take a nested TLB miss hit where we look
- * up the physical address of the L3 PTE and then continue at label 1 below.
- */
- MOV_FROM_IFA(r16) // get the address that caused the fault
- movl r30=1f // load continuation point in case of nested fault
- ;;
- THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
- mov r29=b0 // save b0 in case of nested fault
- mov r31=pr // save pr
-#ifdef CONFIG_SMP
- mov r28=ar.ccv // save ar.ccv
- ;;
-1: ld8 r18=[r17]
- ;; // avoid RAW on r18
- mov ar.ccv=r18 // set compare value for cmpxchg
- or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits
- tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit
- ;;
-(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only update if page is present
- mov r24=PAGE_SHIFT<<2
- ;;
-(p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present
- ;;
- ITC_D(p6, r25, r18) // install updated PTE
- ;;
- /*
- * Tell the assemblers dependency-violation checker that the above "itc" instructions
- * cannot possibly affect the following loads:
- */
- dv_serialize_data
-
- ld8 r18=[r17] // read PTE again
- ;;
- cmp.eq p6,p7=r18,r25 // is it same as the newly installed
- ;;
-(p7) ptc.l r16,r24
- mov b0=r29 // restore b0
- mov ar.ccv=r28
-#else
- ;;
-1: ld8 r18=[r17]
- ;; // avoid RAW on r18
- or r18=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits
- mov b0=r29 // restore b0
- ;;
- st8 [r17]=r18 // store back updated PTE
- ITC_D(p0, r18, r16) // install updated PTE
-#endif
- mov pr=r31,-1 // restore pr
- RFI
-END(dirty_bit)
-
- .org ia64_ivt+0x2400
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
-ENTRY(iaccess_bit)
- DBG_FAULT(9)
- // Like Entry 8, except for instruction access
- MOV_FROM_IFA(r16) // get the address that caused the fault
- movl r30=1f // load continuation point in case of nested fault
- mov r31=pr // save predicates
-#ifdef CONFIG_ITANIUM
- /*
- * Erratum 10 (IFA may contain incorrect address) has "NoFix" status.
- */
- MOV_FROM_IPSR(p0, r17)
- ;;
- MOV_FROM_IIP(r18)
- tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set?
- ;;
-(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa
-#endif /* CONFIG_ITANIUM */
- ;;
- THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
- mov r29=b0 // save b0 in case of nested fault)
-#ifdef CONFIG_SMP
- mov r28=ar.ccv // save ar.ccv
- ;;
-1: ld8 r18=[r17]
- ;;
- mov ar.ccv=r18 // set compare value for cmpxchg
- or r25=_PAGE_A,r18 // set the accessed bit
- tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit
- ;;
-(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page present
- mov r24=PAGE_SHIFT<<2
- ;;
-(p6) cmp.eq p6,p7=r26,r18 // Only if page present
- ;;
- ITC_I(p6, r25, r26) // install updated PTE
- ;;
- /*
- * Tell the assemblers dependency-violation checker that the above "itc" instructions
- * cannot possibly affect the following loads:
- */
- dv_serialize_data
-
- ld8 r18=[r17] // read PTE again
- ;;
- cmp.eq p6,p7=r18,r25 // is it same as the newly installed
- ;;
-(p7) ptc.l r16,r24
- mov b0=r29 // restore b0
- mov ar.ccv=r28
-#else /* !CONFIG_SMP */
- ;;
-1: ld8 r18=[r17]
- ;;
- or r18=_PAGE_A,r18 // set the accessed bit
- mov b0=r29 // restore b0
- ;;
- st8 [r17]=r18 // store back updated PTE
- ITC_I(p0, r18, r16) // install updated PTE
-#endif /* !CONFIG_SMP */
- mov pr=r31,-1
- RFI
-END(iaccess_bit)
-
- .org ia64_ivt+0x2800
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
-ENTRY(daccess_bit)
- DBG_FAULT(10)
- // Like Entry 8, except for data access
- MOV_FROM_IFA(r16) // get the address that caused the fault
- movl r30=1f // load continuation point in case of nested fault
- ;;
- THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
- mov r31=pr
- mov r29=b0 // save b0 in case of nested fault)
-#ifdef CONFIG_SMP
- mov r28=ar.ccv // save ar.ccv
- ;;
-1: ld8 r18=[r17]
- ;; // avoid RAW on r18
- mov ar.ccv=r18 // set compare value for cmpxchg
- or r25=_PAGE_A,r18 // set the dirty bit
- tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit
- ;;
-(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page is present
- mov r24=PAGE_SHIFT<<2
- ;;
-(p6) cmp.eq p6,p7=r26,r18 // Only if page is present
- ;;
- ITC_D(p6, r25, r26) // install updated PTE
- /*
- * Tell the assemblers dependency-violation checker that the above "itc" instructions
- * cannot possibly affect the following loads:
- */
- dv_serialize_data
- ;;
- ld8 r18=[r17] // read PTE again
- ;;
- cmp.eq p6,p7=r18,r25 // is it same as the newly installed
- ;;
-(p7) ptc.l r16,r24
- mov ar.ccv=r28
-#else
- ;;
-1: ld8 r18=[r17]
- ;; // avoid RAW on r18
- or r18=_PAGE_A,r18 // set the accessed bit
- ;;
- st8 [r17]=r18 // store back updated PTE
- ITC_D(p0, r18, r16) // install updated PTE
-#endif
- mov b0=r29 // restore b0
- mov pr=r31,-1
- RFI
-END(daccess_bit)
-
- .org ia64_ivt+0x2c00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
-ENTRY(break_fault)
- /*
- * The streamlined system call entry/exit paths only save/restore the initial part
- * of pt_regs. This implies that the callers of system-calls must adhere to the
- * normal procedure calling conventions.
- *
- * Registers to be saved & restored:
- * CR registers: cr.ipsr, cr.iip, cr.ifs
- * AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
- * others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
- * Registers to be restored only:
- * r8-r11: output value from the system call.
- *
- * During system call exit, scratch registers (including r15) are modified/cleared
- * to prevent leaking bits from kernel to user level.
- */
- DBG_FAULT(11)
- mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc)
- MOV_FROM_IPSR(p0, r29) // M2 (12 cyc)
- mov r31=pr // I0 (2 cyc)
-
- MOV_FROM_IIM(r17) // M2 (2 cyc)
- mov.m r27=ar.rsc // M2 (12 cyc)
- mov r18=__IA64_BREAK_SYSCALL // A
-
- mov.m ar.rsc=0 // M2
- mov.m r21=ar.fpsr // M2 (12 cyc)
- mov r19=b6 // I0 (2 cyc)
- ;;
- mov.m r23=ar.bspstore // M2 (12 cyc)
- mov.m r24=ar.rnat // M2 (5 cyc)
- mov.i r26=ar.pfs // I0 (2 cyc)
-
- invala // M0|1
- nop.m 0 // M
- mov r20=r1 // A save r1
-
- nop.m 0
- movl r30=sys_call_table // X
-
- MOV_FROM_IIP(r28) // M2 (2 cyc)
- cmp.eq p0,p7=r18,r17 // I0 is this a system call?
-(p7) br.cond.spnt non_syscall // B no ->
- //
- // From this point on, we are definitely on the syscall-path
- // and we can use (non-banked) scratch registers.
- //
-///////////////////////////////////////////////////////////////////////
- mov r1=r16 // A move task-pointer to "addl"-addressable reg
- mov r2=r16 // A setup r2 for ia64_syscall_setup
- add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = &current_thread_info()->flags
-
- adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
- adds r15=-1024,r15 // A subtract 1024 from syscall number
- mov r3=NR_syscalls - 1
- ;;
- ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag
- ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags
- extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr
-
- shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024)
- addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS
- cmp.leu p6,p7=r15,r3 // A syscall number in range?
- ;;
-
- lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS
-(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point
- tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT?
-
- mov.m ar.bspstore=r22 // M2 switch to kernel RBS
- cmp.eq p8,p9=2,r8 // A isr.ei==2?
- ;;
-
-(p8) mov r8=0 // A clear ei to 0
-(p7) movl r30=sys_ni_syscall // X
-
-(p8) adds r28=16,r28 // A switch cr.iip to next bundle
-(p9) adds r8=1,r8 // A increment ei to next slot
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- ;;
- mov b6=r30 // I0 setup syscall handler branch reg early
-#else
- nop.i 0
- ;;
-#endif
-
- mov.m r25=ar.unat // M2 (5 cyc)
- dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr
- adds r15=1024,r15 // A restore original syscall number
- //
- // If any of the above loads miss in L1D, we'll stall here until
- // the data arrives.
- //
-///////////////////////////////////////////////////////////////////////
- st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- MOV_FROM_ITC(p0, p14, r30, r18) // M get cycle for accounting
-#else
- mov b6=r30 // I0 setup syscall handler branch reg early
-#endif
- cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already?
-
- and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit
- mov r18=ar.bsp // M2 (12 cyc)
-(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS
- ;;
-.back_from_break_fixup:
-(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack
- cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited?
- br.call.sptk.many b7=ia64_syscall_setup // B
-1:
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
- // mov.m r30=ar.itc is called in advance, and r13 is current
- add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13 // A
- add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13 // A
-(pKStk) br.cond.spnt .skip_accounting // B unlikely skip
- ;;
- ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP // M get last stamp
- ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE // M time at leave
- ;;
- ld8 r20=[r16],TI_AC_STAMP-TI_AC_STIME // M cumulated stime
- ld8 r21=[r17] // M cumulated utime
- sub r22=r19,r18 // A stime before leave
- ;;
- st8 [r16]=r30,TI_AC_STIME-TI_AC_STAMP // M update stamp
- sub r18=r30,r19 // A elapsed time in user
- ;;
- add r20=r20,r22 // A sum stime
- add r21=r21,r18 // A sum utime
- ;;
- st8 [r16]=r20 // M update stime
- st8 [r17]=r21 // M update utime
- ;;
-.skip_accounting:
-#endif
- mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
- nop 0
- BSW_1(r2, r14) // B (6 cyc) regs are saved, switch to bank 1
- ;;
-
- SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r16) // M2 now it's safe to re-enable intr.-collection
- // M0 ensure interruption collection is on
- movl r3=ia64_ret_from_syscall // X
- ;;
- mov rp=r3 // I0 set the real return addr
-(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
-
- SSM_PSR_I(p15, p15, r16) // M2 restore psr.i
-(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr)
- br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic
- // NOT REACHED
-///////////////////////////////////////////////////////////////////////
- // On entry, we optimistically assumed that we're coming from user-space.
- // For the rare cases where a system-call is done from within the kernel,
- // we fix things up at this point:
-.break_fixup:
- add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure
- mov ar.rnat=r24 // M2 restore kernel's AR.RNAT
- ;;
- mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE
- br.cond.sptk .back_from_break_fixup
-END(break_fault)
-
- .org ia64_ivt+0x3000
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
-ENTRY(interrupt)
- /* interrupt handler has become too big to fit this area. */
- br.sptk.many __interrupt
-END(interrupt)
-
- .org ia64_ivt+0x3400
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x3400 Entry 13 (size 64 bundles) Reserved
- DBG_FAULT(13)
- FAULT(13)
-
- .org ia64_ivt+0x3800
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x3800 Entry 14 (size 64 bundles) Reserved
- DBG_FAULT(14)
- FAULT(14)
-
- /*
- * There is no particular reason for this code to be here, other than that
- * there happens to be space here that would go unused otherwise. If this
- * fault ever gets "unreserved", simply moved the following code to a more
- * suitable spot...
- *
- * ia64_syscall_setup() is a separate subroutine so that it can
- * allocate stacked registers so it can safely demine any
- * potential NaT values from the input registers.
- *
- * On entry:
- * - executing on bank 0 or bank 1 register set (doesn't matter)
- * - r1: stack pointer
- * - r2: current task pointer
- * - r3: preserved
- * - r11: original contents (saved ar.pfs to be saved)
- * - r12: original contents (sp to be saved)
- * - r13: original contents (tp to be saved)
- * - r15: original contents (syscall # to be saved)
- * - r18: saved bsp (after switching to kernel stack)
- * - r19: saved b6
- * - r20: saved r1 (gp)
- * - r21: saved ar.fpsr
- * - r22: kernel's register backing store base (krbs_base)
- * - r23: saved ar.bspstore
- * - r24: saved ar.rnat
- * - r25: saved ar.unat
- * - r26: saved ar.pfs
- * - r27: saved ar.rsc
- * - r28: saved cr.iip
- * - r29: saved cr.ipsr
- * - r30: ar.itc for accounting (don't touch)
- * - r31: saved pr
- * - b0: original contents (to be saved)
- * On exit:
- * - p10: TRUE if syscall is invoked with more than 8 out
- * registers or r15's Nat is true
- * - r1: kernel's gp
- * - r3: preserved (same as on entry)
- * - r8: -EINVAL if p10 is true
- * - r12: points to kernel stack
- * - r13: points to current task
- * - r14: preserved (same as on entry)
- * - p13: preserved
- * - p15: TRUE if interrupts need to be re-enabled
- * - ar.fpsr: set to kernel settings
- * - b6: preserved (same as on entry)
- */
-GLOBAL_ENTRY(ia64_syscall_setup)
-#if PT(B6) != 0
-# error This code assumes that b6 is the first field in pt_regs.
-#endif
- st8 [r1]=r19 // save b6
- add r16=PT(CR_IPSR),r1 // initialize first base pointer
- add r17=PT(R11),r1 // initialize second base pointer
- ;;
- alloc r19=ar.pfs,8,0,0,0 // ensure in0-in7 are writable
- st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR) // save cr.ipsr
- tnat.nz p8,p0=in0
-
- st8.spill [r17]=r11,PT(CR_IIP)-PT(R11) // save r11
- tnat.nz p9,p0=in1
-(pKStk) mov r18=r0 // make sure r18 isn't NaT
- ;;
-
- st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS) // save ar.pfs
- st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP) // save cr.iip
- mov r28=b0 // save b0 (2 cyc)
- ;;
-
- st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT) // save ar.unat
- dep r19=0,r19,38,26 // clear all bits but 0..37 [I0]
-(p8) mov in0=-1
- ;;
-
- st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS) // store ar.pfs.pfm in cr.ifs
- extr.u r11=r19,7,7 // I0 // get sol of ar.pfs
- and r8=0x7f,r19 // A // get sof of ar.pfs
-
- st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
- tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
-(p9) mov in1=-1
- ;;
-
-(pUStk) sub r18=r18,r22 // r18=RSE.ndirty*8
- tnat.nz p10,p0=in2
- add r11=8,r11
- ;;
-(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16 // skip over ar_rnat field
-(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17 // skip over ar_bspstore field
- tnat.nz p11,p0=in3
- ;;
-(p10) mov in2=-1
- tnat.nz p12,p0=in4 // [I0]
-(p11) mov in3=-1
- ;;
-(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT) // save ar.rnat
-(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE) // save ar.bspstore
- shl r18=r18,16 // compute ar.rsc to be used for "loadrs"
- ;;
- st8 [r16]=r31,PT(LOADRS)-PT(PR) // save predicates
- st8 [r17]=r28,PT(R1)-PT(B0) // save b0
- tnat.nz p13,p0=in5 // [I0]
- ;;
- st8 [r16]=r18,PT(R12)-PT(LOADRS) // save ar.rsc value for "loadrs"
- st8.spill [r17]=r20,PT(R13)-PT(R1) // save original r1
-(p12) mov in4=-1
- ;;
-
-.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12) // save r12
-.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13) // save r13
-(p13) mov in5=-1
- ;;
- st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr
- tnat.nz p13,p0=in6
- cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8
- ;;
- mov r8=1
-(p9) tnat.nz p10,p0=r15
- adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch)
-
- st8.spill [r17]=r15 // save r15
- tnat.nz p8,p0=in7
- nop.i 0
-
- mov r13=r2 // establish `current'
- movl r1=__gp // establish kernel global pointer
- ;;
- st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
-(p13) mov in6=-1
-(p8) mov in7=-1
-
- cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
- movl r17=FPSR_DEFAULT
- ;;
- mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value
-(p10) mov r8=-EINVAL
- br.ret.sptk.many b7
-END(ia64_syscall_setup)
-
- .org ia64_ivt+0x3c00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x3c00 Entry 15 (size 64 bundles) Reserved
- DBG_FAULT(15)
- FAULT(15)
-
- .org ia64_ivt+0x4000
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x4000 Entry 16 (size 64 bundles) Reserved
- DBG_FAULT(16)
- FAULT(16)
-
-#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE)
- /*
- * There is no particular reason for this code to be here, other than
- * that there happens to be space here that would go unused otherwise.
- * If this fault ever gets "unreserved", simply moved the following
- * code to a more suitable spot...
- *
- * account_sys_enter is called from SAVE_MIN* macros if accounting is
- * enabled and if the macro is entered from user mode.
- */
-GLOBAL_ENTRY(account_sys_enter)
- // mov.m r20=ar.itc is called in advance, and r13 is current
- add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13
- add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13
- ;;
- ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP // time at last check in kernel
- ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE // time at left from kernel
- ;;
- ld8 r23=[r16],TI_AC_STAMP-TI_AC_STIME // cumulated stime
- ld8 r21=[r17] // cumulated utime
- sub r22=r19,r18 // stime before leave kernel
- ;;
- st8 [r16]=r20,TI_AC_STIME-TI_AC_STAMP // update stamp
- sub r18=r20,r19 // elapsed time in user mode
- ;;
- add r23=r23,r22 // sum stime
- add r21=r21,r18 // sum utime
- ;;
- st8 [r16]=r23 // update stime
- st8 [r17]=r21 // update utime
- ;;
- br.ret.sptk.many rp
-END(account_sys_enter)
-#endif
-
- .org ia64_ivt+0x4400
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x4400 Entry 17 (size 64 bundles) Reserved
- DBG_FAULT(17)
- FAULT(17)
-
- .org ia64_ivt+0x4800
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x4800 Entry 18 (size 64 bundles) Reserved
- DBG_FAULT(18)
- FAULT(18)
-
- .org ia64_ivt+0x4c00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x4c00 Entry 19 (size 64 bundles) Reserved
- DBG_FAULT(19)
- FAULT(19)
-
-//
-// --- End of long entries, Beginning of short entries
-//
-
- .org ia64_ivt+0x5000
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
-ENTRY(page_not_present)
- DBG_FAULT(20)
- MOV_FROM_IFA(r16)
- RSM_PSR_DT
- /*
- * The Linux page fault handler doesn't expect non-present pages to be in
- * the TLB. Flush the existing entry now, so we meet that expectation.
- */
- mov r17=PAGE_SHIFT<<2
- ;;
- ptc.l r16,r17
- ;;
- mov r31=pr
- srlz.d
- br.sptk.many page_fault
-END(page_not_present)
-
- .org ia64_ivt+0x5100
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
-ENTRY(key_permission)
- DBG_FAULT(21)
- MOV_FROM_IFA(r16)
- RSM_PSR_DT
- mov r31=pr
- ;;
- srlz.d
- br.sptk.many page_fault
-END(key_permission)
-
- .org ia64_ivt+0x5200
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
-ENTRY(iaccess_rights)
- DBG_FAULT(22)
- MOV_FROM_IFA(r16)
- RSM_PSR_DT
- mov r31=pr
- ;;
- srlz.d
- br.sptk.many page_fault
-END(iaccess_rights)
-
- .org ia64_ivt+0x5300
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
-ENTRY(daccess_rights)
- DBG_FAULT(23)
- MOV_FROM_IFA(r16)
- RSM_PSR_DT
- mov r31=pr
- ;;
- srlz.d
- br.sptk.many page_fault
-END(daccess_rights)
-
- .org ia64_ivt+0x5400
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
-ENTRY(general_exception)
- DBG_FAULT(24)
- MOV_FROM_ISR(r16)
- mov r31=pr
- ;;
- cmp4.eq p6,p0=0,r16
-(p6) br.sptk.many dispatch_illegal_op_fault
- ;;
- mov r19=24 // fault number
- br.sptk.many dispatch_to_fault_handler
-END(general_exception)
-
- .org ia64_ivt+0x5500
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
-ENTRY(disabled_fp_reg)
- DBG_FAULT(25)
- rsm psr.dfh // ensure we can access fph
- ;;
- srlz.d
- mov r31=pr
- mov r19=25
- br.sptk.many dispatch_to_fault_handler
-END(disabled_fp_reg)
-
- .org ia64_ivt+0x5600
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
-ENTRY(nat_consumption)
- DBG_FAULT(26)
-
- MOV_FROM_IPSR(p0, r16)
- MOV_FROM_ISR(r17)
- mov r31=pr // save PR
- ;;
- and r18=0xf,r17 // r18 = cr.ipsr.code{3:0}
- tbit.z p6,p0=r17,IA64_ISR_NA_BIT
- ;;
- cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18
- dep r16=-1,r16,IA64_PSR_ED_BIT,1
-(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
- ;;
- MOV_TO_IPSR(p0, r16, r18)
- mov pr=r31,-1
- ;;
- RFI
-
-1: mov pr=r31,-1
- ;;
- FAULT(26)
-END(nat_consumption)
-
- .org ia64_ivt+0x5700
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5700 Entry 27 (size 16 bundles) Speculation (40)
-ENTRY(speculation_vector)
- DBG_FAULT(27)
- /*
- * A [f]chk.[as] instruction needs to take the branch to the recovery code but
- * this part of the architecture is not implemented in hardware on some CPUs, such
- * as Itanium. Thus, in general we need to emulate the behavior. IIM contains
- * the relative target (not yet sign extended). So after sign extending it we
- * simply add it to IIP. We also need to reset the EI field of the IPSR to zero,
- * i.e., the slot to restart into.
- *
- * cr.imm contains zero_ext(imm21)
- */
- MOV_FROM_IIM(r18)
- ;;
- MOV_FROM_IIP(r17)
- shl r18=r18,43 // put sign bit in position (43=64-21)
- ;;
-
- MOV_FROM_IPSR(p0, r16)
- shr r18=r18,39 // sign extend (39=43-4)
- ;;
-
- add r17=r17,r18 // now add the offset
- ;;
- MOV_TO_IIP(r17, r19)
- dep r16=0,r16,41,2 // clear EI
- ;;
-
- MOV_TO_IPSR(p0, r16, r19)
- ;;
-
- RFI
-END(speculation_vector)
-
- .org ia64_ivt+0x5800
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5800 Entry 28 (size 16 bundles) Reserved
- DBG_FAULT(28)
- FAULT(28)
-
- .org ia64_ivt+0x5900
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
-ENTRY(debug_vector)
- DBG_FAULT(29)
- FAULT(29)
-END(debug_vector)
-
- .org ia64_ivt+0x5a00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
-ENTRY(unaligned_access)
- DBG_FAULT(30)
- mov r31=pr // prepare to save predicates
- ;;
- br.sptk.many dispatch_unaligned_handler
-END(unaligned_access)
-
- .org ia64_ivt+0x5b00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
-ENTRY(unsupported_data_reference)
- DBG_FAULT(31)
- FAULT(31)
-END(unsupported_data_reference)
-
- .org ia64_ivt+0x5c00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
-ENTRY(floating_point_fault)
- DBG_FAULT(32)
- FAULT(32)
-END(floating_point_fault)
-
- .org ia64_ivt+0x5d00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
-ENTRY(floating_point_trap)
- DBG_FAULT(33)
- FAULT(33)
-END(floating_point_trap)
-
- .org ia64_ivt+0x5e00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66)
-ENTRY(lower_privilege_trap)
- DBG_FAULT(34)
- FAULT(34)
-END(lower_privilege_trap)
-
- .org ia64_ivt+0x5f00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
-ENTRY(taken_branch_trap)
- DBG_FAULT(35)
- FAULT(35)
-END(taken_branch_trap)
-
- .org ia64_ivt+0x6000
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
-ENTRY(single_step_trap)
- DBG_FAULT(36)
- FAULT(36)
-END(single_step_trap)
-
- .org ia64_ivt+0x6100
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6100 Entry 37 (size 16 bundles) Reserved
- DBG_FAULT(37)
- FAULT(37)
-
- .org ia64_ivt+0x6200
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6200 Entry 38 (size 16 bundles) Reserved
- DBG_FAULT(38)
- FAULT(38)
-
- .org ia64_ivt+0x6300
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6300 Entry 39 (size 16 bundles) Reserved
- DBG_FAULT(39)
- FAULT(39)
-
- .org ia64_ivt+0x6400
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6400 Entry 40 (size 16 bundles) Reserved
- DBG_FAULT(40)
- FAULT(40)
-
- .org ia64_ivt+0x6500
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6500 Entry 41 (size 16 bundles) Reserved
- DBG_FAULT(41)
- FAULT(41)
-
- .org ia64_ivt+0x6600
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6600 Entry 42 (size 16 bundles) Reserved
- DBG_FAULT(42)
- FAULT(42)
-
- .org ia64_ivt+0x6700
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6700 Entry 43 (size 16 bundles) Reserved
- DBG_FAULT(43)
- FAULT(43)
-
- .org ia64_ivt+0x6800
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6800 Entry 44 (size 16 bundles) Reserved
- DBG_FAULT(44)
- FAULT(44)
-
- .org ia64_ivt+0x6900
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77)
-ENTRY(ia32_exception)
- DBG_FAULT(45)
- FAULT(45)
-END(ia32_exception)
-
- .org ia64_ivt+0x6a00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71)
-ENTRY(ia32_intercept)
- DBG_FAULT(46)
- FAULT(46)
-END(ia32_intercept)
-
- .org ia64_ivt+0x6b00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt (74)
-ENTRY(ia32_interrupt)
- DBG_FAULT(47)
- FAULT(47)
-END(ia32_interrupt)
-
- .org ia64_ivt+0x6c00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6c00 Entry 48 (size 16 bundles) Reserved
- DBG_FAULT(48)
- FAULT(48)
-
- .org ia64_ivt+0x6d00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6d00 Entry 49 (size 16 bundles) Reserved
- DBG_FAULT(49)
- FAULT(49)
-
- .org ia64_ivt+0x6e00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6e00 Entry 50 (size 16 bundles) Reserved
- DBG_FAULT(50)
- FAULT(50)
-
- .org ia64_ivt+0x6f00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x6f00 Entry 51 (size 16 bundles) Reserved
- DBG_FAULT(51)
- FAULT(51)
-
- .org ia64_ivt+0x7000
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7000 Entry 52 (size 16 bundles) Reserved
- DBG_FAULT(52)
- FAULT(52)
-
- .org ia64_ivt+0x7100
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7100 Entry 53 (size 16 bundles) Reserved
- DBG_FAULT(53)
- FAULT(53)
-
- .org ia64_ivt+0x7200
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7200 Entry 54 (size 16 bundles) Reserved
- DBG_FAULT(54)
- FAULT(54)
-
- .org ia64_ivt+0x7300
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7300 Entry 55 (size 16 bundles) Reserved
- DBG_FAULT(55)
- FAULT(55)
-
- .org ia64_ivt+0x7400
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7400 Entry 56 (size 16 bundles) Reserved
- DBG_FAULT(56)
- FAULT(56)
-
- .org ia64_ivt+0x7500
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7500 Entry 57 (size 16 bundles) Reserved
- DBG_FAULT(57)
- FAULT(57)
-
- .org ia64_ivt+0x7600
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7600 Entry 58 (size 16 bundles) Reserved
- DBG_FAULT(58)
- FAULT(58)
-
- .org ia64_ivt+0x7700
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7700 Entry 59 (size 16 bundles) Reserved
- DBG_FAULT(59)
- FAULT(59)
-
- .org ia64_ivt+0x7800
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7800 Entry 60 (size 16 bundles) Reserved
- DBG_FAULT(60)
- FAULT(60)
-
- .org ia64_ivt+0x7900
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7900 Entry 61 (size 16 bundles) Reserved
- DBG_FAULT(61)
- FAULT(61)
-
- .org ia64_ivt+0x7a00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7a00 Entry 62 (size 16 bundles) Reserved
- DBG_FAULT(62)
- FAULT(62)
-
- .org ia64_ivt+0x7b00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7b00 Entry 63 (size 16 bundles) Reserved
- DBG_FAULT(63)
- FAULT(63)
-
- .org ia64_ivt+0x7c00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7c00 Entry 64 (size 16 bundles) Reserved
- DBG_FAULT(64)
- FAULT(64)
-
- .org ia64_ivt+0x7d00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7d00 Entry 65 (size 16 bundles) Reserved
- DBG_FAULT(65)
- FAULT(65)
-
- .org ia64_ivt+0x7e00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7e00 Entry 66 (size 16 bundles) Reserved
- DBG_FAULT(66)
- FAULT(66)
-
- .org ia64_ivt+0x7f00
-/////////////////////////////////////////////////////////////////////////////////////////
-// 0x7f00 Entry 67 (size 16 bundles) Reserved
- DBG_FAULT(67)
- FAULT(67)
-
- //-----------------------------------------------------------------------------------
- // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
-ENTRY(page_fault)
- SSM_PSR_DT_AND_SRLZ_I
- ;;
- SAVE_MIN_WITH_COVER
- alloc r15=ar.pfs,0,0,3,0
- MOV_FROM_IFA(out0)
- MOV_FROM_ISR(out1)
- SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r14, r3)
- adds r3=8,r2 // set up second base pointer
- SSM_PSR_I(p15, p15, r14) // restore psr.i
- movl r14=ia64_leave_kernel
- ;;
- SAVE_REST
- mov rp=r14
- ;;
- adds out2=16,r12 // out2 = pointer to pt_regs
- br.call.sptk.many b6=ia64_do_page_fault // ignore return address
-END(page_fault)
-
-ENTRY(non_syscall)
- mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER
- ;;
- SAVE_MIN_WITH_COVER
-
- // There is no particular reason for this code to be here, other than that
- // there happens to be space here that would go unused otherwise. If this
- // fault ever gets "unreserved", simply moved the following code to a more
- // suitable spot...
-
- alloc r14=ar.pfs,0,0,2,0
- MOV_FROM_IIM(out0)
- add out1=16,sp
- adds r3=8,r2 // set up second base pointer for SAVE_REST
-
- SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r15, r24)
- // guarantee that interruption collection is on
- SSM_PSR_I(p15, p15, r15) // restore psr.i
- movl r15=ia64_leave_kernel
- ;;
- SAVE_REST
- mov rp=r15
- ;;
- br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore return addr
-END(non_syscall)
-
-ENTRY(__interrupt)
- DBG_FAULT(12)
- mov r31=pr // prepare to save predicates
- ;;
- SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3
- SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r14)
- // ensure everybody knows psr.ic is back on
- adds r3=8,r2 // set up second base pointer for SAVE_REST
- ;;
- SAVE_REST
- ;;
- MCA_RECOVER_RANGE(interrupt)
- alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
- MOV_FROM_IVR(out0, r8) // pass cr.ivr as first arg
- add out1=16,sp // pass pointer to pt_regs as second arg
- ;;
- srlz.d // make sure we see the effect of cr.ivr
- movl r14=ia64_leave_kernel
- ;;
- mov rp=r14
- br.call.sptk.many b6=ia64_handle_irq
-END(__interrupt)
-
- /*
- * There is no particular reason for this code to be here, other than that
- * there happens to be space here that would go unused otherwise. If this
- * fault ever gets "unreserved", simply moved the following code to a more
- * suitable spot...
- */
-
-ENTRY(dispatch_unaligned_handler)
- SAVE_MIN_WITH_COVER
- ;;
- alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!)
- MOV_FROM_IFA(out0)
- adds out1=16,sp
-
- SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
- // guarantee that interruption collection is on
- SSM_PSR_I(p15, p15, r3) // restore psr.i
- adds r3=8,r2 // set up second base pointer
- ;;
- SAVE_REST
- movl r14=ia64_leave_kernel
- ;;
- mov rp=r14
- br.sptk.many ia64_prepare_handle_unaligned
-END(dispatch_unaligned_handler)
-
- /*
- * There is no particular reason for this code to be here, other than that
- * there happens to be space here that would go unused otherwise. If this
- * fault ever gets "unreserved", simply moved the following code to a more
- * suitable spot...
- */
-
-ENTRY(dispatch_to_fault_handler)
- /*
- * Input:
- * psr.ic: off
- * r19: fault vector number (e.g., 24 for General Exception)
- * r31: contains saved predicates (pr)
- */
- SAVE_MIN_WITH_COVER_R19
- alloc r14=ar.pfs,0,0,5,0
- MOV_FROM_ISR(out1)
- MOV_FROM_IFA(out2)
- MOV_FROM_IIM(out3)
- MOV_FROM_ITIR(out4)
- ;;
- SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, out0)
- // guarantee that interruption collection is on
- mov out0=r15
- ;;
- SSM_PSR_I(p15, p15, r3) // restore psr.i
- adds r3=8,r2 // set up second base pointer for SAVE_REST
- ;;
- SAVE_REST
- movl r14=ia64_leave_kernel
- ;;
- mov rp=r14
- br.call.sptk.many b6=ia64_fault
-END(dispatch_to_fault_handler)
-
- /*
- * Squatting in this space ...
- *
- * This special case dispatcher for illegal operation faults allows preserved
- * registers to be modified through a callback function (asm only) that is handed
- * back from the fault handler in r8. Up to three arguments can be passed to the
- * callback function by returning an aggregate with the callback as its first
- * element, followed by the arguments.
- */
-ENTRY(dispatch_illegal_op_fault)
- .prologue
- .body
- SAVE_MIN_WITH_COVER
- SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
- // guarantee that interruption collection is on
- ;;
- SSM_PSR_I(p15, p15, r3) // restore psr.i
- adds r3=8,r2 // set up second base pointer for SAVE_REST
- ;;
- alloc r14=ar.pfs,0,0,1,0 // must be first in insn group
- mov out0=ar.ec
- ;;
- SAVE_REST
- PT_REGS_UNWIND_INFO(0)
- ;;
- br.call.sptk.many rp=ia64_illegal_op_fault
-.ret0: ;;
- alloc r14=ar.pfs,0,0,3,0 // must be first in insn group
- mov out0=r9
- mov out1=r10
- mov out2=r11
- movl r15=ia64_leave_kernel
- ;;
- mov rp=r15
- mov b6=r8
- ;;
- cmp.ne p6,p0=0,r8
-(p6) br.call.dpnt.many b6=b6 // call returns to ia64_leave_kernel
- br.sptk.many ia64_leave_kernel
-END(dispatch_illegal_op_fault)
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
deleted file mode 100644
index ca34e51e84b4..000000000000
--- a/arch/ia64/kernel/kprobes.c
+++ /dev/null
@@ -1,911 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Kernel Probes (KProbes)
- * arch/ia64/kernel/kprobes.c
- *
- * Copyright (C) IBM Corporation, 2002, 2004
- * Copyright (C) Intel Corporation, 2005
- *
- * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
- * <anil.s.keshavamurthy@intel.com> adapted from i386
- */
-
-#include <linux/kprobes.h>
-#include <linux/ptrace.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/preempt.h>
-#include <linux/extable.h>
-#include <linux/kdebug.h>
-#include <linux/pgtable.h>
-
-#include <asm/sections.h>
-#include <asm/exception.h>
-
-DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
-DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
-
-struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
-
-enum instruction_type {A, I, M, F, B, L, X, u};
-static enum instruction_type bundle_encoding[32][3] = {
- [0x00] = { M, I, I },
- [0x01] = { M, I, I },
- [0x02] = { M, I, I },
- [0x03] = { M, I, I },
- [0x04] = { M, L, X },
- [0x05] = { M, L, X },
- [0x06] = { u, u, u },
- [0x07] = { u, u, u },
- [0x08] = { M, M, I },
- [0x09] = { M, M, I },
- [0x0A] = { M, M, I },
- [0x0B] = { M, M, I },
- [0x0C] = { M, F, I },
- [0x0D] = { M, F, I },
- [0x0E] = { M, M, F },
- [0x0F] = { M, M, F },
- [0x10] = { M, I, B },
- [0x11] = { M, I, B },
- [0x12] = { M, B, B },
- [0x13] = { M, B, B },
- [0x14] = { u, u, u },
- [0x15] = { u, u, u },
- [0x16] = { B, B, B },
- [0x17] = { B, B, B },
- [0x18] = { M, M, B },
- [0x19] = { M, M, B },
- [0x1A] = { u, u, u },
- [0x1B] = { u, u, u },
- [0x1C] = { M, F, B },
- [0x1D] = { M, F, B },
- [0x1E] = { u, u, u },
- [0x1F] = { u, u, u },
-};
-
-/* Insert a long branch code */
-static void __kprobes set_brl_inst(void *from, void *to)
-{
- s64 rel = ((s64) to - (s64) from) >> 4;
- bundle_t *brl;
- brl = (bundle_t *) ((u64) from & ~0xf);
- brl->quad0.template = 0x05; /* [MLX](stop) */
- brl->quad0.slot0 = NOP_M_INST; /* nop.m 0x0 */
- brl->quad0.slot1_p0 = ((rel >> 20) & 0x7fffffffff) << 2;
- brl->quad1.slot1_p1 = (((rel >> 20) & 0x7fffffffff) << 2) >> (64 - 46);
- /* brl.cond.sptk.many.clr rel<<4 (qp=0) */
- brl->quad1.slot2 = BRL_INST(rel >> 59, rel & 0xfffff);
-}
-
-/*
- * In this function we check to see if the instruction
- * is IP relative instruction and update the kprobe
- * inst flag accordingly
- */
-static void __kprobes update_kprobe_inst_flag(uint template, uint slot,
- uint major_opcode,
- unsigned long kprobe_inst,
- struct kprobe *p)
-{
- p->ainsn.inst_flag = 0;
- p->ainsn.target_br_reg = 0;
- p->ainsn.slot = slot;
-
- /* Check for Break instruction
- * Bits 37:40 Major opcode to be zero
- * Bits 27:32 X6 to be zero
- * Bits 32:35 X3 to be zero
- */
- if ((!major_opcode) && (!((kprobe_inst >> 27) & 0x1FF)) ) {
- /* is a break instruction */
- p->ainsn.inst_flag |= INST_FLAG_BREAK_INST;
- return;
- }
-
- if (bundle_encoding[template][slot] == B) {
- switch (major_opcode) {
- case INDIRECT_CALL_OPCODE:
- p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
- p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
- break;
- case IP_RELATIVE_PREDICT_OPCODE:
- case IP_RELATIVE_BRANCH_OPCODE:
- p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
- break;
- case IP_RELATIVE_CALL_OPCODE:
- p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
- p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
- p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
- break;
- }
- } else if (bundle_encoding[template][slot] == X) {
- switch (major_opcode) {
- case LONG_CALL_OPCODE:
- p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
- p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
- break;
- }
- }
- return;
-}
-
-/*
- * In this function we check to see if the instruction
- * (qp) cmpx.crel.ctype p1,p2=r2,r3
- * on which we are inserting kprobe is cmp instruction
- * with ctype as unc.
- */
-static uint __kprobes is_cmp_ctype_unc_inst(uint template, uint slot,
- uint major_opcode,
- unsigned long kprobe_inst)
-{
- cmp_inst_t cmp_inst;
- uint ctype_unc = 0;
-
- if (!((bundle_encoding[template][slot] == I) ||
- (bundle_encoding[template][slot] == M)))
- goto out;
-
- if (!((major_opcode == 0xC) || (major_opcode == 0xD) ||
- (major_opcode == 0xE)))
- goto out;
-
- cmp_inst.l = kprobe_inst;
- if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) {
- /* Integer compare - Register Register (A6 type)*/
- if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0)
- &&(cmp_inst.f.c == 1))
- ctype_unc = 1;
- } else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) {
- /* Integer compare - Immediate Register (A8 type)*/
- if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1))
- ctype_unc = 1;
- }
-out:
- return ctype_unc;
-}
-
-/*
- * In this function we check to see if the instruction
- * on which we are inserting kprobe is supported.
- * Returns qp value if supported
- * Returns -EINVAL if unsupported
- */
-static int __kprobes unsupported_inst(uint template, uint slot,
- uint major_opcode,
- unsigned long kprobe_inst,
- unsigned long addr)
-{
- int qp;
-
- qp = kprobe_inst & 0x3f;
- if (is_cmp_ctype_unc_inst(template, slot, major_opcode, kprobe_inst)) {
- if (slot == 1 && qp) {
- printk(KERN_WARNING "Kprobes on cmp unc "
- "instruction on slot 1 at <0x%lx> "
- "is not supported\n", addr);
- return -EINVAL;
-
- }
- qp = 0;
- }
- else if (bundle_encoding[template][slot] == I) {
- if (major_opcode == 0) {
- /*
- * Check for Integer speculation instruction
- * - Bit 33-35 to be equal to 0x1
- */
- if (((kprobe_inst >> 33) & 0x7) == 1) {
- printk(KERN_WARNING
- "Kprobes on speculation inst at <0x%lx> not supported\n",
- addr);
- return -EINVAL;
- }
- /*
- * IP relative mov instruction
- * - Bit 27-35 to be equal to 0x30
- */
- if (((kprobe_inst >> 27) & 0x1FF) == 0x30) {
- printk(KERN_WARNING
- "Kprobes on \"mov r1=ip\" at <0x%lx> not supported\n",
- addr);
- return -EINVAL;
-
- }
- }
- else if ((major_opcode == 5) && !(kprobe_inst & (0xFUl << 33)) &&
- (kprobe_inst & (0x1UL << 12))) {
- /* test bit instructions, tbit,tnat,tf
- * bit 33-36 to be equal to 0
- * bit 12 to be equal to 1
- */
- if (slot == 1 && qp) {
- printk(KERN_WARNING "Kprobes on test bit "
- "instruction on slot at <0x%lx> "
- "is not supported\n", addr);
- return -EINVAL;
- }
- qp = 0;
- }
- }
- else if (bundle_encoding[template][slot] == B) {
- if (major_opcode == 7) {
- /* IP-Relative Predict major code is 7 */
- printk(KERN_WARNING "Kprobes on IP-Relative"
- "Predict is not supported\n");
- return -EINVAL;
- }
- else if (major_opcode == 2) {
- /* Indirect Predict, major code is 2
- * bit 27-32 to be equal to 10 or 11
- */
- int x6=(kprobe_inst >> 27) & 0x3F;
- if ((x6 == 0x10) || (x6 == 0x11)) {
- printk(KERN_WARNING "Kprobes on "
- "Indirect Predict is not supported\n");
- return -EINVAL;
- }
- }
- }
- /* kernel does not use float instruction, here for safety kprobe
- * will judge whether it is fcmp/flass/float approximation instruction
- */
- else if (unlikely(bundle_encoding[template][slot] == F)) {
- if ((major_opcode == 4 || major_opcode == 5) &&
- (kprobe_inst & (0x1 << 12))) {
- /* fcmp/fclass unc instruction */
- if (slot == 1 && qp) {
- printk(KERN_WARNING "Kprobes on fcmp/fclass "
- "instruction on slot at <0x%lx> "
- "is not supported\n", addr);
- return -EINVAL;
-
- }
- qp = 0;
- }
- if ((major_opcode == 0 || major_opcode == 1) &&
- (kprobe_inst & (0x1UL << 33))) {
- /* float Approximation instruction */
- if (slot == 1 && qp) {
- printk(KERN_WARNING "Kprobes on float Approx "
- "instr at <0x%lx> is not supported\n",
- addr);
- return -EINVAL;
- }
- qp = 0;
- }
- }
- return qp;
-}
-
-/*
- * In this function we override the bundle with
- * the break instruction at the given slot.
- */
-static void __kprobes prepare_break_inst(uint template, uint slot,
- uint major_opcode,
- unsigned long kprobe_inst,
- struct kprobe *p,
- int qp)
-{
- unsigned long break_inst = BREAK_INST;
- bundle_t *bundle = &p->opcode.bundle;
-
- /*
- * Copy the original kprobe_inst qualifying predicate(qp)
- * to the break instruction
- */
- break_inst |= qp;
-
- switch (slot) {
- case 0:
- bundle->quad0.slot0 = break_inst;
- break;
- case 1:
- bundle->quad0.slot1_p0 = break_inst;
- bundle->quad1.slot1_p1 = break_inst >> (64-46);
- break;
- case 2:
- bundle->quad1.slot2 = break_inst;
- break;
- }
-
- /*
- * Update the instruction flag, so that we can
- * emulate the instruction properly after we
- * single step on original instruction
- */
- update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p);
-}
-
-static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot,
- unsigned long *kprobe_inst, uint *major_opcode)
-{
- unsigned long kprobe_inst_p0, kprobe_inst_p1;
- unsigned int template;
-
- template = bundle->quad0.template;
-
- switch (slot) {
- case 0:
- *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
- *kprobe_inst = bundle->quad0.slot0;
- break;
- case 1:
- *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
- kprobe_inst_p0 = bundle->quad0.slot1_p0;
- kprobe_inst_p1 = bundle->quad1.slot1_p1;
- *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
- break;
- case 2:
- *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
- *kprobe_inst = bundle->quad1.slot2;
- break;
- }
-}
-
-/* Returns non-zero if the addr is in the Interrupt Vector Table */
-static int __kprobes in_ivt_functions(unsigned long addr)
-{
- return (addr >= (unsigned long)__start_ivt_text
- && addr < (unsigned long)__end_ivt_text);
-}
-
-static int __kprobes valid_kprobe_addr(int template, int slot,
- unsigned long addr)
-{
- if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) {
- printk(KERN_WARNING "Attempting to insert unaligned kprobe "
- "at 0x%lx\n", addr);
- return -EINVAL;
- }
-
- if (in_ivt_functions(addr)) {
- printk(KERN_WARNING "Kprobes can't be inserted inside "
- "IVT functions at 0x%lx\n", addr);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
-{
- unsigned int i;
- i = atomic_add_return(1, &kcb->prev_kprobe_index);
- kcb->prev_kprobe[i-1].kp = kprobe_running();
- kcb->prev_kprobe[i-1].status = kcb->kprobe_status;
-}
-
-static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
-{
- unsigned int i;
- i = atomic_read(&kcb->prev_kprobe_index);
- __this_cpu_write(current_kprobe, kcb->prev_kprobe[i-1].kp);
- kcb->kprobe_status = kcb->prev_kprobe[i-1].status;
- atomic_sub(1, &kcb->prev_kprobe_index);
-}
-
-static void __kprobes set_current_kprobe(struct kprobe *p,
- struct kprobe_ctlblk *kcb)
-{
- __this_cpu_write(current_kprobe, p);
-}
-
-void __kretprobe_trampoline(void)
-{
-}
-
-int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
-{
- regs->cr_iip = __kretprobe_trampoline_handler(regs, NULL);
- /*
- * By returning a non-zero value, we are telling
- * kprobe_handler() that we don't want the post_handler
- * to run (and have re-enabled preemption)
- */
- return 1;
-}
-
-void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
- struct pt_regs *regs)
-{
- ri->ret_addr = (kprobe_opcode_t *)regs->b0;
- ri->fp = NULL;
-
- /* Replace the return addr with trampoline addr */
- regs->b0 = (unsigned long)dereference_function_descriptor(__kretprobe_trampoline);
-}
-
-/* Check the instruction in the slot is break */
-static int __kprobes __is_ia64_break_inst(bundle_t *bundle, uint slot)
-{
- unsigned int major_opcode;
- unsigned int template = bundle->quad0.template;
- unsigned long kprobe_inst;
-
- /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
- if (slot == 1 && bundle_encoding[template][1] == L)
- slot++;
-
- /* Get Kprobe probe instruction at given slot*/
- get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
-
- /* For break instruction,
- * Bits 37:40 Major opcode to be zero
- * Bits 27:32 X6 to be zero
- * Bits 32:35 X3 to be zero
- */
- if (major_opcode || ((kprobe_inst >> 27) & 0x1FF)) {
- /* Not a break instruction */
- return 0;
- }
-
- /* Is a break instruction */
- return 1;
-}
-
-/*
- * In this function, we check whether the target bundle modifies IP or
- * it triggers an exception. If so, it cannot be boostable.
- */
-static int __kprobes can_boost(bundle_t *bundle, uint slot,
- unsigned long bundle_addr)
-{
- unsigned int template = bundle->quad0.template;
-
- do {
- if (search_exception_tables(bundle_addr + slot) ||
- __is_ia64_break_inst(bundle, slot))
- return 0; /* exception may occur in this bundle*/
- } while ((++slot) < 3);
- template &= 0x1e;
- if (template >= 0x10 /* including B unit */ ||
- template == 0x04 /* including X unit */ ||
- template == 0x06) /* undefined */
- return 0;
-
- return 1;
-}
-
-/* Prepare long jump bundle and disables other boosters if need */
-static void __kprobes prepare_booster(struct kprobe *p)
-{
- unsigned long addr = (unsigned long)p->addr & ~0xFULL;
- unsigned int slot = (unsigned long)p->addr & 0xf;
- struct kprobe *other_kp;
-
- if (can_boost(&p->ainsn.insn[0].bundle, slot, addr)) {
- set_brl_inst(&p->ainsn.insn[1].bundle, (bundle_t *)addr + 1);
- p->ainsn.inst_flag |= INST_FLAG_BOOSTABLE;
- }
-
- /* disables boosters in previous slots */
- for (; addr < (unsigned long)p->addr; addr++) {
- other_kp = get_kprobe((void *)addr);
- if (other_kp)
- other_kp->ainsn.inst_flag &= ~INST_FLAG_BOOSTABLE;
- }
-}
-
-int __kprobes arch_prepare_kprobe(struct kprobe *p)
-{
- unsigned long addr = (unsigned long) p->addr;
- unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
- unsigned long kprobe_inst=0;
- unsigned int slot = addr & 0xf, template, major_opcode = 0;
- bundle_t *bundle;
- int qp;
-
- bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle;
- template = bundle->quad0.template;
-
- if(valid_kprobe_addr(template, slot, addr))
- return -EINVAL;
-
- /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
- if (slot == 1 && bundle_encoding[template][1] == L)
- slot++;
-
- /* Get kprobe_inst and major_opcode from the bundle */
- get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
-
- qp = unsupported_inst(template, slot, major_opcode, kprobe_inst, addr);
- if (qp < 0)
- return -EINVAL;
-
- p->ainsn.insn = get_insn_slot();
- if (!p->ainsn.insn)
- return -ENOMEM;
- memcpy(&p->opcode, kprobe_addr, sizeof(kprobe_opcode_t));
- memcpy(p->ainsn.insn, kprobe_addr, sizeof(kprobe_opcode_t));
-
- prepare_break_inst(template, slot, major_opcode, kprobe_inst, p, qp);
-
- prepare_booster(p);
-
- return 0;
-}
-
-void __kprobes arch_arm_kprobe(struct kprobe *p)
-{
- unsigned long arm_addr;
- bundle_t *src, *dest;
-
- arm_addr = ((unsigned long)p->addr) & ~0xFUL;
- dest = &((kprobe_opcode_t *)arm_addr)->bundle;
- src = &p->opcode.bundle;
-
- flush_icache_range((unsigned long)p->ainsn.insn,
- (unsigned long)p->ainsn.insn +
- sizeof(kprobe_opcode_t) * MAX_INSN_SIZE);
-
- switch (p->ainsn.slot) {
- case 0:
- dest->quad0.slot0 = src->quad0.slot0;
- break;
- case 1:
- dest->quad1.slot1_p1 = src->quad1.slot1_p1;
- break;
- case 2:
- dest->quad1.slot2 = src->quad1.slot2;
- break;
- }
- flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t));
-}
-
-void __kprobes arch_disarm_kprobe(struct kprobe *p)
-{
- unsigned long arm_addr;
- bundle_t *src, *dest;
-
- arm_addr = ((unsigned long)p->addr) & ~0xFUL;
- dest = &((kprobe_opcode_t *)arm_addr)->bundle;
- /* p->ainsn.insn contains the original unaltered kprobe_opcode_t */
- src = &p->ainsn.insn->bundle;
- switch (p->ainsn.slot) {
- case 0:
- dest->quad0.slot0 = src->quad0.slot0;
- break;
- case 1:
- dest->quad1.slot1_p1 = src->quad1.slot1_p1;
- break;
- case 2:
- dest->quad1.slot2 = src->quad1.slot2;
- break;
- }
- flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t));
-}
-
-void __kprobes arch_remove_kprobe(struct kprobe *p)
-{
- if (p->ainsn.insn) {
- free_insn_slot(p->ainsn.insn,
- p->ainsn.inst_flag & INST_FLAG_BOOSTABLE);
- p->ainsn.insn = NULL;
- }
-}
-/*
- * We are resuming execution after a single step fault, so the pt_regs
- * structure reflects the register state after we executed the instruction
- * located in the kprobe (p->ainsn.insn->bundle). We still need to adjust
- * the ip to point back to the original stack address. To set the IP address
- * to original stack address, handle the case where we need to fixup the
- * relative IP address and/or fixup branch register.
- */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
-{
- unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
- unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
- unsigned long template;
- int slot = ((unsigned long)p->addr & 0xf);
-
- template = p->ainsn.insn->bundle.quad0.template;
-
- if (slot == 1 && bundle_encoding[template][1] == L)
- slot = 2;
-
- if (p->ainsn.inst_flag & ~INST_FLAG_BOOSTABLE) {
-
- if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
- /* Fix relative IP address */
- regs->cr_iip = (regs->cr_iip - bundle_addr) +
- resume_addr;
- }
-
- if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
- /*
- * Fix target branch register, software convention is
- * to use either b0 or b6 or b7, so just checking
- * only those registers
- */
- switch (p->ainsn.target_br_reg) {
- case 0:
- if ((regs->b0 == bundle_addr) ||
- (regs->b0 == bundle_addr + 0x10)) {
- regs->b0 = (regs->b0 - bundle_addr) +
- resume_addr;
- }
- break;
- case 6:
- if ((regs->b6 == bundle_addr) ||
- (regs->b6 == bundle_addr + 0x10)) {
- regs->b6 = (regs->b6 - bundle_addr) +
- resume_addr;
- }
- break;
- case 7:
- if ((regs->b7 == bundle_addr) ||
- (regs->b7 == bundle_addr + 0x10)) {
- regs->b7 = (regs->b7 - bundle_addr) +
- resume_addr;
- }
- break;
- } /* end switch */
- }
- goto turn_ss_off;
- }
-
- if (slot == 2) {
- if (regs->cr_iip == bundle_addr + 0x10) {
- regs->cr_iip = resume_addr + 0x10;
- }
- } else {
- if (regs->cr_iip == bundle_addr) {
- regs->cr_iip = resume_addr;
- }
- }
-
-turn_ss_off:
- /* Turn off Single Step bit */
- ia64_psr(regs)->ss = 0;
-}
-
-static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
-{
- unsigned long bundle_addr = (unsigned long) &p->ainsn.insn->bundle;
- unsigned long slot = (unsigned long)p->addr & 0xf;
-
- /* single step inline if break instruction */
- if (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)
- regs->cr_iip = (unsigned long)p->addr & ~0xFULL;
- else
- regs->cr_iip = bundle_addr & ~0xFULL;
-
- if (slot > 2)
- slot = 0;
-
- ia64_psr(regs)->ri = slot;
-
- /* turn on single stepping */
- ia64_psr(regs)->ss = 1;
-}
-
-static int __kprobes is_ia64_break_inst(struct pt_regs *regs)
-{
- unsigned int slot = ia64_psr(regs)->ri;
- unsigned long *kprobe_addr = (unsigned long *)regs->cr_iip;
- bundle_t bundle;
-
- memcpy(&bundle, kprobe_addr, sizeof(bundle_t));
-
- return __is_ia64_break_inst(&bundle, slot);
-}
-
-static int __kprobes pre_kprobes_handler(struct die_args *args)
-{
- struct kprobe *p;
- int ret = 0;
- struct pt_regs *regs = args->regs;
- kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
- struct kprobe_ctlblk *kcb;
-
- /*
- * We don't want to be preempted for the entire
- * duration of kprobe processing
- */
- preempt_disable();
- kcb = get_kprobe_ctlblk();
-
- /* Handle recursion cases */
- if (kprobe_running()) {
- p = get_kprobe(addr);
- if (p) {
- if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
- (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
- ia64_psr(regs)->ss = 0;
- goto no_kprobe;
- }
- /* We have reentered the pre_kprobe_handler(), since
- * another probe was hit while within the handler.
- * We here save the original kprobes variables and
- * just single step on the instruction of the new probe
- * without calling any user handlers.
- */
- save_previous_kprobe(kcb);
- set_current_kprobe(p, kcb);
- kprobes_inc_nmissed_count(p);
- prepare_ss(p, regs);
- kcb->kprobe_status = KPROBE_REENTER;
- return 1;
- } else if (!is_ia64_break_inst(regs)) {
- /* The breakpoint instruction was removed by
- * another cpu right after we hit, no further
- * handling of this interrupt is appropriate
- */
- ret = 1;
- goto no_kprobe;
- } else {
- /* Not our break */
- goto no_kprobe;
- }
- }
-
- p = get_kprobe(addr);
- if (!p) {
- if (!is_ia64_break_inst(regs)) {
- /*
- * The breakpoint instruction was removed right
- * after we hit it. Another cpu has removed
- * either a probepoint or a debugger breakpoint
- * at this address. In either case, no further
- * handling of this interrupt is appropriate.
- */
- ret = 1;
-
- }
-
- /* Not one of our break, let kernel handle it */
- goto no_kprobe;
- }
-
- set_current_kprobe(p, kcb);
- kcb->kprobe_status = KPROBE_HIT_ACTIVE;
-
- if (p->pre_handler && p->pre_handler(p, regs)) {
- reset_current_kprobe();
- preempt_enable_no_resched();
- return 1;
- }
-
-#if !defined(CONFIG_PREEMPTION)
- if (p->ainsn.inst_flag == INST_FLAG_BOOSTABLE && !p->post_handler) {
- /* Boost up -- we can execute copied instructions directly */
- ia64_psr(regs)->ri = p->ainsn.slot;
- regs->cr_iip = (unsigned long)&p->ainsn.insn->bundle & ~0xFULL;
- /* turn single stepping off */
- ia64_psr(regs)->ss = 0;
-
- reset_current_kprobe();
- preempt_enable_no_resched();
- return 1;
- }
-#endif
- prepare_ss(p, regs);
- kcb->kprobe_status = KPROBE_HIT_SS;
- return 1;
-
-no_kprobe:
- preempt_enable_no_resched();
- return ret;
-}
-
-static int __kprobes post_kprobes_handler(struct pt_regs *regs)
-{
- struct kprobe *cur = kprobe_running();
- struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-
- if (!cur)
- return 0;
-
- if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
- kcb->kprobe_status = KPROBE_HIT_SSDONE;
- cur->post_handler(cur, regs, 0);
- }
-
- resume_execution(cur, regs);
-
- /*Restore back the original saved kprobes variables and continue. */
- if (kcb->kprobe_status == KPROBE_REENTER) {
- restore_previous_kprobe(kcb);
- goto out;
- }
- reset_current_kprobe();
-
-out:
- preempt_enable_no_resched();
- return 1;
-}
-
-int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
-{
- struct kprobe *cur = kprobe_running();
- struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-
-
- switch(kcb->kprobe_status) {
- case KPROBE_HIT_SS:
- case KPROBE_REENTER:
- /*
- * We are here because the instruction being single
- * stepped caused a page fault. We reset the current
- * kprobe and the instruction pointer points back to
- * the probe address and allow the page fault handler
- * to continue as a normal page fault.
- */
- regs->cr_iip = ((unsigned long)cur->addr) & ~0xFULL;
- ia64_psr(regs)->ri = ((unsigned long)cur->addr) & 0xf;
- if (kcb->kprobe_status == KPROBE_REENTER)
- restore_previous_kprobe(kcb);
- else
- reset_current_kprobe();
- preempt_enable_no_resched();
- break;
- case KPROBE_HIT_ACTIVE:
- case KPROBE_HIT_SSDONE:
- /*
- * In case the user-specified fault handler returned
- * zero, try to fix up.
- */
- if (ia64_done_with_exception(regs))
- return 1;
-
- /*
- * Let ia64_do_page_fault() fix it.
- */
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
- unsigned long val, void *data)
-{
- struct die_args *args = (struct die_args *)data;
- int ret = NOTIFY_DONE;
-
- if (args->regs && user_mode(args->regs))
- return ret;
-
- switch(val) {
- case DIE_BREAK:
- /* err is break number from ia64_bad_break() */
- if ((args->err >> 12) == (__IA64_BREAK_KPROBE >> 12)
- || args->err == 0)
- if (pre_kprobes_handler(args))
- ret = NOTIFY_STOP;
- break;
- case DIE_FAULT:
- /* err is vector number from ia64_fault() */
- if (args->err == 36)
- if (post_kprobes_handler(args->regs))
- ret = NOTIFY_STOP;
- break;
- default:
- break;
- }
- return ret;
-}
-
-static struct kprobe trampoline_p = {
- .pre_handler = trampoline_probe_handler
-};
-
-int __init arch_init_kprobes(void)
-{
- trampoline_p.addr =
- dereference_function_descriptor(__kretprobe_trampoline);
- return register_kprobe(&trampoline_p);
-}
-
-int __kprobes arch_trampoline_kprobe(struct kprobe *p)
-{
- if (p->addr ==
- dereference_function_descriptor(__kretprobe_trampoline))
- return 1;
-
- return 0;
-}
diff --git a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c
deleted file mode 100644
index 4db9ca144fa5..000000000000
--- a/arch/ia64/kernel/machine_kexec.c
+++ /dev/null
@@ -1,163 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/ia64/kernel/machine_kexec.c
- *
- * Handle transition of Linux booting another kernel
- * Copyright (C) 2005 Hewlett-Packard Development Comapny, L.P.
- * Copyright (C) 2005 Khalid Aziz <khalid.aziz@hp.com>
- * Copyright (C) 2006 Intel Corp, Zou Nan hai <nanhai.zou@intel.com>
- */
-
-#include <linux/mm.h>
-#include <linux/kexec.h>
-#include <linux/cpu.h>
-#include <linux/irq.h>
-#include <linux/efi.h>
-#include <linux/numa.h>
-#include <linux/mmzone.h>
-
-#include <asm/efi.h>
-#include <asm/numa.h>
-#include <asm/mmu_context.h>
-#include <asm/setup.h>
-#include <asm/delay.h>
-#include <asm/meminit.h>
-#include <asm/processor.h>
-#include <asm/sal.h>
-#include <asm/mca.h>
-
-typedef void (*relocate_new_kernel_t)(
- unsigned long indirection_page,
- unsigned long start_address,
- struct ia64_boot_param *boot_param,
- unsigned long pal_addr) __noreturn;
-
-struct kimage *ia64_kimage;
-
-struct resource efi_memmap_res = {
- .name = "EFI Memory Map",
- .start = 0,
- .end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
-};
-
-struct resource boot_param_res = {
- .name = "Boot parameter",
- .start = 0,
- .end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
-};
-
-
-/*
- * Do what every setup is needed on image and the
- * reboot code buffer to allow us to avoid allocations
- * later.
- */
-int machine_kexec_prepare(struct kimage *image)
-{
- void *control_code_buffer;
- const unsigned long *func;
-
- func = (unsigned long *)&relocate_new_kernel;
- /* Pre-load control code buffer to minimize work in kexec path */
- control_code_buffer = page_address(image->control_code_page);
- memcpy((void *)control_code_buffer, (const void *)func[0],
- relocate_new_kernel_size);
- flush_icache_range((unsigned long)control_code_buffer,
- (unsigned long)control_code_buffer + relocate_new_kernel_size);
- ia64_kimage = image;
-
- return 0;
-}
-
-void machine_kexec_cleanup(struct kimage *image)
-{
-}
-
-/*
- * Do not allocate memory (or fail in any way) in machine_kexec().
- * We are past the point of no return, committed to rebooting now.
- */
-static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
-{
- struct kimage *image = arg;
- relocate_new_kernel_t rnk;
- void *pal_addr = efi_get_pal_addr();
- unsigned long code_addr;
- int ii;
- u64 fp, gp;
- ia64_fptr_t *init_handler = (ia64_fptr_t *)ia64_os_init_on_kdump;
-
- BUG_ON(!image);
- code_addr = (unsigned long)page_address(image->control_code_page);
- if (image->type == KEXEC_TYPE_CRASH) {
- crash_save_this_cpu();
- current->thread.ksp = (__u64)info->sw - 16;
-
- /* Register noop init handler */
- fp = ia64_tpa(init_handler->fp);
- gp = ia64_tpa(ia64_getreg(_IA64_REG_GP));
- ia64_sal_set_vectors(SAL_VECTOR_OS_INIT, fp, gp, 0, fp, gp, 0);
- } else {
- /* Unregister init handlers of current kernel */
- ia64_sal_set_vectors(SAL_VECTOR_OS_INIT, 0, 0, 0, 0, 0, 0);
- }
-
- /* Unregister mca handler - No more recovery on current kernel */
- ia64_sal_set_vectors(SAL_VECTOR_OS_MCA, 0, 0, 0, 0, 0, 0);
-
- /* Interrupts aren't acceptable while we reboot */
- local_irq_disable();
-
- /* Mask CMC and Performance Monitor interrupts */
- ia64_setreg(_IA64_REG_CR_PMV, 1 << 16);
- ia64_setreg(_IA64_REG_CR_CMCV, 1 << 16);
-
- /* Mask ITV and Local Redirect Registers */
- ia64_set_itv(1 << 16);
- ia64_set_lrr0(1 << 16);
- ia64_set_lrr1(1 << 16);
-
- /* terminate possible nested in-service interrupts */
- for (ii = 0; ii < 16; ii++)
- ia64_eoi();
-
- /* unmask TPR and clear any pending interrupts */
- ia64_setreg(_IA64_REG_CR_TPR, 0);
- ia64_srlz_d();
- while (ia64_get_ivr() != IA64_SPURIOUS_INT_VECTOR)
- ia64_eoi();
- rnk = (relocate_new_kernel_t)&code_addr;
- (*rnk)(image->head, image->start, ia64_boot_param,
- GRANULEROUNDDOWN((unsigned long) pal_addr));
- BUG();
-}
-
-void machine_kexec(struct kimage *image)
-{
- BUG_ON(!image);
- unw_init_running(ia64_machine_kexec, image);
- for(;;);
-}
-
-void arch_crash_save_vmcoreinfo(void)
-{
-#if defined(CONFIG_SPARSEMEM)
- VMCOREINFO_SYMBOL(pgdat_list);
- VMCOREINFO_LENGTH(pgdat_list, MAX_NUMNODES);
-#endif
-#ifdef CONFIG_NUMA
- VMCOREINFO_SYMBOL(node_memblk);
- VMCOREINFO_LENGTH(node_memblk, NR_NODE_MEMBLKS);
- VMCOREINFO_STRUCT_SIZE(node_memblk_s);
- VMCOREINFO_OFFSET(node_memblk_s, start_paddr);
- VMCOREINFO_OFFSET(node_memblk_s, size);
-#endif
-#if CONFIG_PGTABLE_LEVELS == 3
- VMCOREINFO_CONFIG(PGTABLE_3);
-#elif CONFIG_PGTABLE_LEVELS == 4
- VMCOREINFO_CONFIG(PGTABLE_4);
-#endif
-}
-
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
deleted file mode 100644
index 2671688d349a..000000000000
--- a/arch/ia64/kernel/mca.c
+++ /dev/null
@@ -1,2111 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * File: mca.c
- * Purpose: Generic MCA handling layer
- *
- * Copyright (C) 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Copyright (C) 2002 Dell Inc.
- * Copyright (C) Matt Domsch <Matt_Domsch@dell.com>
- *
- * Copyright (C) 2002 Intel
- * Copyright (C) Jenna Hall <jenna.s.hall@intel.com>
- *
- * Copyright (C) 2001 Intel
- * Copyright (C) Fred Lewis <frederick.v.lewis@intel.com>
- *
- * Copyright (C) 2000 Intel
- * Copyright (C) Chuck Fleckenstein <cfleck@co.intel.com>
- *
- * Copyright (C) 1999, 2004-2008 Silicon Graphics, Inc.
- * Copyright (C) Vijay Chander <vijay@engr.sgi.com>
- *
- * Copyright (C) 2006 FUJITSU LIMITED
- * Copyright (C) Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
- *
- * 2000-03-29 Chuck Fleckenstein <cfleck@co.intel.com>
- * Fixed PAL/SAL update issues, began MCA bug fixes, logging issues,
- * added min save state dump, added INIT handler.
- *
- * 2001-01-03 Fred Lewis <frederick.v.lewis@intel.com>
- * Added setup of CMCI and CPEI IRQs, logging of corrected platform
- * errors, completed code for logging of corrected & uncorrected
- * machine check errors, and updated for conformance with Nov. 2000
- * revision of the SAL 3.0 spec.
- *
- * 2002-01-04 Jenna Hall <jenna.s.hall@intel.com>
- * Aligned MCA stack to 16 bytes, added platform vs. CPU error flag,
- * set SAL default return values, changed error record structure to
- * linked list, added init call to sal_get_state_info_size().
- *
- * 2002-03-25 Matt Domsch <Matt_Domsch@dell.com>
- * GUID cleanups.
- *
- * 2003-04-15 David Mosberger-Tang <davidm@hpl.hp.com>
- * Added INIT backtrace support.
- *
- * 2003-12-08 Keith Owens <kaos@sgi.com>
- * smp_call_function() must not be called from interrupt context
- * (can deadlock on tasklist_lock).
- * Use keventd to call smp_call_function().
- *
- * 2004-02-01 Keith Owens <kaos@sgi.com>
- * Avoid deadlock when using printk() for MCA and INIT records.
- * Delete all record printing code, moved to salinfo_decode in user
- * space. Mark variables and functions static where possible.
- * Delete dead variables and functions. Reorder to remove the need
- * for forward declarations and to consolidate related code.
- *
- * 2005-08-12 Keith Owens <kaos@sgi.com>
- * Convert MCA/INIT handlers to use per event stacks and SAL/OS
- * state.
- *
- * 2005-10-07 Keith Owens <kaos@sgi.com>
- * Add notify_die() hooks.
- *
- * 2006-09-15 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
- * Add printing support for MCA/INIT.
- *
- * 2007-04-27 Russ Anderson <rja@sgi.com>
- * Support multiple cpus going through OS_MCA in the same event.
- */
-#include <linux/jiffies.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/sched/signal.h>
-#include <linux/sched/debug.h>
-#include <linux/sched/task.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/memblock.h>
-#include <linux/acpi.h>
-#include <linux/timer.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/workqueue.h>
-#include <linux/cpumask.h>
-#include <linux/kdebug.h>
-#include <linux/cpu.h>
-#include <linux/gfp.h>
-
-#include <asm/delay.h>
-#include <asm/efi.h>
-#include <asm/meminit.h>
-#include <asm/page.h>
-#include <asm/ptrace.h>
-#include <asm/sal.h>
-#include <asm/mca.h>
-#include <asm/mca_asm.h>
-#include <asm/kexec.h>
-
-#include <asm/irq.h>
-#include <asm/hw_irq.h>
-#include <asm/tlb.h>
-
-#include "mca_drv.h"
-#include "entry.h"
-#include "irq.h"
-
-#if defined(IA64_MCA_DEBUG_INFO)
-# define IA64_MCA_DEBUG(fmt...) printk(fmt)
-#else
-# define IA64_MCA_DEBUG(fmt...) do {} while (0)
-#endif
-
-#define NOTIFY_INIT(event, regs, arg, spin) \
-do { \
- if ((notify_die((event), "INIT", (regs), (arg), 0, 0) \
- == NOTIFY_STOP) && ((spin) == 1)) \
- ia64_mca_spin(__func__); \
-} while (0)
-
-#define NOTIFY_MCA(event, regs, arg, spin) \
-do { \
- if ((notify_die((event), "MCA", (regs), (arg), 0, 0) \
- == NOTIFY_STOP) && ((spin) == 1)) \
- ia64_mca_spin(__func__); \
-} while (0)
-
-/* Used by mca_asm.S */
-DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */
-DEFINE_PER_CPU(u64, ia64_mca_per_cpu_pte); /* PTE to map per-CPU area */
-DEFINE_PER_CPU(u64, ia64_mca_pal_pte); /* PTE to map PAL code */
-DEFINE_PER_CPU(u64, ia64_mca_pal_base); /* vaddr PAL code granule */
-DEFINE_PER_CPU(u64, ia64_mca_tr_reload); /* Flag for TR reload */
-
-unsigned long __per_cpu_mca[NR_CPUS];
-
-/* In mca_asm.S */
-extern void ia64_os_init_dispatch_monarch (void);
-extern void ia64_os_init_dispatch_slave (void);
-
-static int monarch_cpu = -1;
-
-static ia64_mc_info_t ia64_mc_info;
-
-#define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */
-#define MIN_CPE_POLL_INTERVAL (2*60*HZ) /* 2 minutes */
-#define CMC_POLL_INTERVAL (1*60*HZ) /* 1 minute */
-#define CPE_HISTORY_LENGTH 5
-#define CMC_HISTORY_LENGTH 5
-
-static struct timer_list cpe_poll_timer;
-static struct timer_list cmc_poll_timer;
-/*
- * This variable tells whether we are currently in polling mode.
- * Start with this in the wrong state so we won't play w/ timers
- * before the system is ready.
- */
-static int cmc_polling_enabled = 1;
-
-/*
- * Clearing this variable prevents CPE polling from getting activated
- * in mca_late_init. Use it if your system doesn't provide a CPEI,
- * but encounters problems retrieving CPE logs. This should only be
- * necessary for debugging.
- */
-static int cpe_poll_enabled = 1;
-
-extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
-
-static int mca_init __initdata;
-
-/*
- * limited & delayed printing support for MCA/INIT handler
- */
-
-#define mprintk(fmt...) ia64_mca_printk(fmt)
-
-#define MLOGBUF_SIZE (512+256*NR_CPUS)
-#define MLOGBUF_MSGMAX 256
-static char mlogbuf[MLOGBUF_SIZE];
-static DEFINE_SPINLOCK(mlogbuf_wlock); /* mca context only */
-static DEFINE_SPINLOCK(mlogbuf_rlock); /* normal context only */
-static unsigned long mlogbuf_start;
-static unsigned long mlogbuf_end;
-static unsigned int mlogbuf_finished = 0;
-static unsigned long mlogbuf_timestamp = 0;
-
-static int loglevel_save = -1;
-#define BREAK_LOGLEVEL(__console_loglevel) \
- oops_in_progress = 1; \
- if (loglevel_save < 0) \
- loglevel_save = __console_loglevel; \
- __console_loglevel = 15;
-
-#define RESTORE_LOGLEVEL(__console_loglevel) \
- if (loglevel_save >= 0) { \
- __console_loglevel = loglevel_save; \
- loglevel_save = -1; \
- } \
- mlogbuf_finished = 0; \
- oops_in_progress = 0;
-
-/*
- * Push messages into buffer, print them later if not urgent.
- */
-void ia64_mca_printk(const char *fmt, ...)
-{
- va_list args;
- int printed_len;
- char temp_buf[MLOGBUF_MSGMAX];
- char *p;
-
- va_start(args, fmt);
- printed_len = vscnprintf(temp_buf, sizeof(temp_buf), fmt, args);
- va_end(args);
-
- /* Copy the output into mlogbuf */
- if (oops_in_progress) {
- /* mlogbuf was abandoned, use printk directly instead. */
- printk("%s", temp_buf);
- } else {
- spin_lock(&mlogbuf_wlock);
- for (p = temp_buf; *p; p++) {
- unsigned long next = (mlogbuf_end + 1) % MLOGBUF_SIZE;
- if (next != mlogbuf_start) {
- mlogbuf[mlogbuf_end] = *p;
- mlogbuf_end = next;
- } else {
- /* buffer full */
- break;
- }
- }
- mlogbuf[mlogbuf_end] = '\0';
- spin_unlock(&mlogbuf_wlock);
- }
-}
-EXPORT_SYMBOL(ia64_mca_printk);
-
-/*
- * Print buffered messages.
- * NOTE: call this after returning normal context. (ex. from salinfod)
- */
-void ia64_mlogbuf_dump(void)
-{
- char temp_buf[MLOGBUF_MSGMAX];
- char *p;
- unsigned long index;
- unsigned long flags;
- unsigned int printed_len;
-
- /* Get output from mlogbuf */
- while (mlogbuf_start != mlogbuf_end) {
- temp_buf[0] = '\0';
- p = temp_buf;
- printed_len = 0;
-
- spin_lock_irqsave(&mlogbuf_rlock, flags);
-
- index = mlogbuf_start;
- while (index != mlogbuf_end) {
- *p = mlogbuf[index];
- index = (index + 1) % MLOGBUF_SIZE;
- if (!*p)
- break;
- p++;
- if (++printed_len >= MLOGBUF_MSGMAX - 1)
- break;
- }
- *p = '\0';
- if (temp_buf[0])
- printk("%s", temp_buf);
- mlogbuf_start = index;
-
- mlogbuf_timestamp = 0;
- spin_unlock_irqrestore(&mlogbuf_rlock, flags);
- }
-}
-EXPORT_SYMBOL(ia64_mlogbuf_dump);
-
-/*
- * Call this if system is going to down or if immediate flushing messages to
- * console is required. (ex. recovery was failed, crash dump is going to be
- * invoked, long-wait rendezvous etc.)
- * NOTE: this should be called from monarch.
- */
-static void ia64_mlogbuf_finish(int wait)
-{
- BREAK_LOGLEVEL(console_loglevel);
-
- ia64_mlogbuf_dump();
- printk(KERN_EMERG "mlogbuf_finish: printing switched to urgent mode, "
- "MCA/INIT might be dodgy or fail.\n");
-
- if (!wait)
- return;
-
- /* wait for console */
- printk("Delaying for 5 seconds...\n");
- udelay(5*1000000);
-
- mlogbuf_finished = 1;
-}
-
-/*
- * Print buffered messages from INIT context.
- */
-static void ia64_mlogbuf_dump_from_init(void)
-{
- if (mlogbuf_finished)
- return;
-
- if (mlogbuf_timestamp &&
- time_before(jiffies, mlogbuf_timestamp + 30 * HZ)) {
- printk(KERN_ERR "INIT: mlogbuf_dump is interrupted by INIT "
- " and the system seems to be messed up.\n");
- ia64_mlogbuf_finish(0);
- return;
- }
-
- if (!spin_trylock(&mlogbuf_rlock)) {
- printk(KERN_ERR "INIT: mlogbuf_dump is interrupted by INIT. "
- "Generated messages other than stack dump will be "
- "buffered to mlogbuf and will be printed later.\n");
- printk(KERN_ERR "INIT: If messages would not printed after "
- "this INIT, wait 30sec and assert INIT again.\n");
- if (!mlogbuf_timestamp)
- mlogbuf_timestamp = jiffies;
- return;
- }
- spin_unlock(&mlogbuf_rlock);
- ia64_mlogbuf_dump();
-}
-
-static inline void
-ia64_mca_spin(const char *func)
-{
- if (monarch_cpu == smp_processor_id())
- ia64_mlogbuf_finish(0);
- mprintk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func);
- while (1)
- cpu_relax();
-}
-/*
- * IA64_MCA log support
- */
-#define IA64_MAX_LOGS 2 /* Double-buffering for nested MCAs */
-#define IA64_MAX_LOG_TYPES 4 /* MCA, INIT, CMC, CPE */
-
-typedef struct ia64_state_log_s
-{
- spinlock_t isl_lock;
- int isl_index;
- unsigned long isl_count;
- ia64_err_rec_t *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */
-} ia64_state_log_t;
-
-static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES];
-
-#define IA64_LOG_LOCK_INIT(it) spin_lock_init(&ia64_state_log[it].isl_lock)
-#define IA64_LOG_LOCK(it) spin_lock_irqsave(&ia64_state_log[it].isl_lock, s)
-#define IA64_LOG_UNLOCK(it) spin_unlock_irqrestore(&ia64_state_log[it].isl_lock,s)
-#define IA64_LOG_NEXT_INDEX(it) ia64_state_log[it].isl_index
-#define IA64_LOG_CURR_INDEX(it) 1 - ia64_state_log[it].isl_index
-#define IA64_LOG_INDEX_INC(it) \
- {ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index; \
- ia64_state_log[it].isl_count++;}
-#define IA64_LOG_INDEX_DEC(it) \
- ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index
-#define IA64_LOG_NEXT_BUFFER(it) (void *)((ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)]))
-#define IA64_LOG_CURR_BUFFER(it) (void *)((ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)]))
-#define IA64_LOG_COUNT(it) ia64_state_log[it].isl_count
-
-static inline void ia64_log_allocate(int it, u64 size)
-{
- ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)] =
- (ia64_err_rec_t *)memblock_alloc(size, SMP_CACHE_BYTES);
- if (!ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)])
- panic("%s: Failed to allocate %llu bytes\n", __func__, size);
-
- ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)] =
- (ia64_err_rec_t *)memblock_alloc(size, SMP_CACHE_BYTES);
- if (!ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)])
- panic("%s: Failed to allocate %llu bytes\n", __func__, size);
-}
-
-/*
- * ia64_log_init
- * Reset the OS ia64 log buffer
- * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE})
- * Outputs : None
- */
-static void __init
-ia64_log_init(int sal_info_type)
-{
- u64 max_size = 0;
-
- IA64_LOG_NEXT_INDEX(sal_info_type) = 0;
- IA64_LOG_LOCK_INIT(sal_info_type);
-
- // SAL will tell us the maximum size of any error record of this type
- max_size = ia64_sal_get_state_info_size(sal_info_type);
- if (!max_size)
- /* alloc_bootmem() doesn't like zero-sized allocations! */
- return;
-
- // set up OS data structures to hold error info
- ia64_log_allocate(sal_info_type, max_size);
-}
-
-/*
- * ia64_log_get
- *
- * Get the current MCA log from SAL and copy it into the OS log buffer.
- *
- * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE})
- * irq_safe whether you can use printk at this point
- * Outputs : size (total record length)
- * *buffer (ptr to error record)
- *
- */
-static u64
-ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe)
-{
- sal_log_record_header_t *log_buffer;
- u64 total_len = 0;
- unsigned long s;
-
- IA64_LOG_LOCK(sal_info_type);
-
- /* Get the process state information */
- log_buffer = IA64_LOG_NEXT_BUFFER(sal_info_type);
-
- total_len = ia64_sal_get_state_info(sal_info_type, (u64 *)log_buffer);
-
- if (total_len) {
- IA64_LOG_INDEX_INC(sal_info_type);
- IA64_LOG_UNLOCK(sal_info_type);
- if (irq_safe) {
- IA64_MCA_DEBUG("%s: SAL error record type %d retrieved. Record length = %ld\n",
- __func__, sal_info_type, total_len);
- }
- *buffer = (u8 *) log_buffer;
- return total_len;
- } else {
- IA64_LOG_UNLOCK(sal_info_type);
- return 0;
- }
-}
-
-/*
- * ia64_mca_log_sal_error_record
- *
- * This function retrieves a specified error record type from SAL
- * and wakes up any processes waiting for error records.
- *
- * Inputs : sal_info_type (Type of error record MCA/CMC/CPE)
- * FIXME: remove MCA and irq_safe.
- */
-static void
-ia64_mca_log_sal_error_record(int sal_info_type)
-{
- u8 *buffer;
- sal_log_record_header_t *rh;
- u64 size;
- int irq_safe = sal_info_type != SAL_INFO_TYPE_MCA;
-#ifdef IA64_MCA_DEBUG_INFO
- static const char * const rec_name[] = { "MCA", "INIT", "CMC", "CPE" };
-#endif
-
- size = ia64_log_get(sal_info_type, &buffer, irq_safe);
- if (!size)
- return;
-
- salinfo_log_wakeup(sal_info_type, buffer, size, irq_safe);
-
- if (irq_safe)
- IA64_MCA_DEBUG("CPU %d: SAL log contains %s error record\n",
- smp_processor_id(),
- sal_info_type < ARRAY_SIZE(rec_name) ? rec_name[sal_info_type] : "UNKNOWN");
-
- /* Clear logs from corrected errors in case there's no user-level logger */
- rh = (sal_log_record_header_t *)buffer;
- if (rh->severity == sal_log_severity_corrected)
- ia64_sal_clear_state_info(sal_info_type);
-}
-
-/*
- * search_mca_table
- * See if the MCA surfaced in an instruction range
- * that has been tagged as recoverable.
- *
- * Inputs
- * first First address range to check
- * last Last address range to check
- * ip Instruction pointer, address we are looking for
- *
- * Return value:
- * 1 on Success (in the table)/ 0 on Failure (not in the table)
- */
-int
-search_mca_table (const struct mca_table_entry *first,
- const struct mca_table_entry *last,
- unsigned long ip)
-{
- const struct mca_table_entry *curr;
- u64 curr_start, curr_end;
-
- curr = first;
- while (curr <= last) {
- curr_start = (u64) &curr->start_addr + curr->start_addr;
- curr_end = (u64) &curr->end_addr + curr->end_addr;
-
- if ((ip >= curr_start) && (ip <= curr_end)) {
- return 1;
- }
- curr++;
- }
- return 0;
-}
-
-/* Given an address, look for it in the mca tables. */
-int mca_recover_range(unsigned long addr)
-{
- extern struct mca_table_entry __start___mca_table[];
- extern struct mca_table_entry __stop___mca_table[];
-
- return search_mca_table(__start___mca_table, __stop___mca_table-1, addr);
-}
-EXPORT_SYMBOL_GPL(mca_recover_range);
-
-int cpe_vector = -1;
-int ia64_cpe_irq = -1;
-
-static irqreturn_t
-ia64_mca_cpe_int_handler (int cpe_irq, void *arg)
-{
- static unsigned long cpe_history[CPE_HISTORY_LENGTH];
- static int index;
- static DEFINE_SPINLOCK(cpe_history_lock);
-
- IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
- __func__, cpe_irq, smp_processor_id());
-
- /* SAL spec states this should run w/ interrupts enabled */
- local_irq_enable();
-
- spin_lock(&cpe_history_lock);
- if (!cpe_poll_enabled && cpe_vector >= 0) {
-
- int i, count = 1; /* we know 1 happened now */
- unsigned long now = jiffies;
-
- for (i = 0; i < CPE_HISTORY_LENGTH; i++) {
- if (now - cpe_history[i] <= HZ)
- count++;
- }
-
- IA64_MCA_DEBUG(KERN_INFO "CPE threshold %d/%d\n", count, CPE_HISTORY_LENGTH);
- if (count >= CPE_HISTORY_LENGTH) {
-
- cpe_poll_enabled = 1;
- spin_unlock(&cpe_history_lock);
- disable_irq_nosync(local_vector_to_irq(IA64_CPE_VECTOR));
-
- /*
- * Corrected errors will still be corrected, but
- * make sure there's a log somewhere that indicates
- * something is generating more than we can handle.
- */
- printk(KERN_WARNING "WARNING: Switching to polling CPE handler; error records may be lost\n");
-
- mod_timer(&cpe_poll_timer, jiffies + MIN_CPE_POLL_INTERVAL);
-
- /* lock already released, get out now */
- goto out;
- } else {
- cpe_history[index++] = now;
- if (index == CPE_HISTORY_LENGTH)
- index = 0;
- }
- }
- spin_unlock(&cpe_history_lock);
-out:
- /* Get the CPE error record and log it */
- ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE);
-
- local_irq_disable();
-
- return IRQ_HANDLED;
-}
-
-/*
- * ia64_mca_register_cpev
- *
- * Register the corrected platform error vector with SAL.
- *
- * Inputs
- * cpev Corrected Platform Error Vector number
- *
- * Outputs
- * None
- */
-void
-ia64_mca_register_cpev (int cpev)
-{
- /* Register the CPE interrupt vector with SAL */
- struct ia64_sal_retval isrv;
-
- isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0);
- if (isrv.status) {
- printk(KERN_ERR "Failed to register Corrected Platform "
- "Error interrupt vector with SAL (status %ld)\n", isrv.status);
- return;
- }
-
- IA64_MCA_DEBUG("%s: corrected platform error "
- "vector %#x registered\n", __func__, cpev);
-}
-
-/*
- * ia64_mca_cmc_vector_setup
- *
- * Setup the corrected machine check vector register in the processor.
- * (The interrupt is masked on boot. ia64_mca_late_init unmask this.)
- * This function is invoked on a per-processor basis.
- *
- * Inputs
- * None
- *
- * Outputs
- * None
- */
-void
-ia64_mca_cmc_vector_setup (void)
-{
- cmcv_reg_t cmcv;
-
- cmcv.cmcv_regval = 0;
- cmcv.cmcv_mask = 1; /* Mask/disable interrupt at first */
- cmcv.cmcv_vector = IA64_CMC_VECTOR;
- ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
-
- IA64_MCA_DEBUG("%s: CPU %d corrected machine check vector %#x registered.\n",
- __func__, smp_processor_id(), IA64_CMC_VECTOR);
-
- IA64_MCA_DEBUG("%s: CPU %d CMCV = %#016lx\n",
- __func__, smp_processor_id(), ia64_getreg(_IA64_REG_CR_CMCV));
-}
-
-/*
- * ia64_mca_cmc_vector_disable
- *
- * Mask the corrected machine check vector register in the processor.
- * This function is invoked on a per-processor basis.
- *
- * Inputs
- * dummy(unused)
- *
- * Outputs
- * None
- */
-static void
-ia64_mca_cmc_vector_disable (void *dummy)
-{
- cmcv_reg_t cmcv;
-
- cmcv.cmcv_regval = ia64_getreg(_IA64_REG_CR_CMCV);
-
- cmcv.cmcv_mask = 1; /* Mask/disable interrupt */
- ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
-
- IA64_MCA_DEBUG("%s: CPU %d corrected machine check vector %#x disabled.\n",
- __func__, smp_processor_id(), cmcv.cmcv_vector);
-}
-
-/*
- * ia64_mca_cmc_vector_enable
- *
- * Unmask the corrected machine check vector register in the processor.
- * This function is invoked on a per-processor basis.
- *
- * Inputs
- * dummy(unused)
- *
- * Outputs
- * None
- */
-static void
-ia64_mca_cmc_vector_enable (void *dummy)
-{
- cmcv_reg_t cmcv;
-
- cmcv.cmcv_regval = ia64_getreg(_IA64_REG_CR_CMCV);
-
- cmcv.cmcv_mask = 0; /* Unmask/enable interrupt */
- ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
-
- IA64_MCA_DEBUG("%s: CPU %d corrected machine check vector %#x enabled.\n",
- __func__, smp_processor_id(), cmcv.cmcv_vector);
-}
-
-/*
- * ia64_mca_cmc_vector_disable_keventd
- *
- * Called via keventd (smp_call_function() is not safe in interrupt context) to
- * disable the cmc interrupt vector.
- */
-static void
-ia64_mca_cmc_vector_disable_keventd(struct work_struct *unused)
-{
- on_each_cpu(ia64_mca_cmc_vector_disable, NULL, 0);
-}
-
-/*
- * ia64_mca_cmc_vector_enable_keventd
- *
- * Called via keventd (smp_call_function() is not safe in interrupt context) to
- * enable the cmc interrupt vector.
- */
-static void
-ia64_mca_cmc_vector_enable_keventd(struct work_struct *unused)
-{
- on_each_cpu(ia64_mca_cmc_vector_enable, NULL, 0);
-}
-
-/*
- * ia64_mca_wakeup
- *
- * Send an inter-cpu interrupt to wake-up a particular cpu.
- *
- * Inputs : cpuid
- * Outputs : None
- */
-static void
-ia64_mca_wakeup(int cpu)
-{
- ia64_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0);
-}
-
-/*
- * ia64_mca_wakeup_all
- *
- * Wakeup all the slave cpus which have rendez'ed previously.
- *
- * Inputs : None
- * Outputs : None
- */
-static void
-ia64_mca_wakeup_all(void)
-{
- int cpu;
-
- /* Clear the Rendez checkin flag for all cpus */
- for_each_online_cpu(cpu) {
- if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE)
- ia64_mca_wakeup(cpu);
- }
-
-}
-
-/*
- * ia64_mca_rendez_interrupt_handler
- *
- * This is handler used to put slave processors into spinloop
- * while the monarch processor does the mca handling and later
- * wake each slave up once the monarch is done. The state
- * IA64_MCA_RENDEZ_CHECKIN_DONE indicates the cpu is rendez'ed
- * in SAL. The state IA64_MCA_RENDEZ_CHECKIN_NOTDONE indicates
- * the cpu has come out of OS rendezvous.
- *
- * Inputs : None
- * Outputs : None
- */
-static irqreturn_t
-ia64_mca_rendez_int_handler(int rendez_irq, void *arg)
-{
- unsigned long flags;
- int cpu = smp_processor_id();
- struct ia64_mca_notify_die nd =
- { .sos = NULL, .monarch_cpu = &monarch_cpu };
-
- /* Mask all interrupts */
- local_irq_save(flags);
-
- NOTIFY_MCA(DIE_MCA_RENDZVOUS_ENTER, get_irq_regs(), (long)&nd, 1);
-
- ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
- /* Register with the SAL monarch that the slave has
- * reached SAL
- */
- ia64_sal_mc_rendez();
-
- NOTIFY_MCA(DIE_MCA_RENDZVOUS_PROCESS, get_irq_regs(), (long)&nd, 1);
-
- /* Wait for the monarch cpu to exit. */
- while (monarch_cpu != -1)
- cpu_relax(); /* spin until monarch leaves */
-
- NOTIFY_MCA(DIE_MCA_RENDZVOUS_LEAVE, get_irq_regs(), (long)&nd, 1);
-
- ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
- /* Enable all interrupts */
- local_irq_restore(flags);
- return IRQ_HANDLED;
-}
-
-/*
- * ia64_mca_wakeup_int_handler
- *
- * The interrupt handler for processing the inter-cpu interrupt to the
- * slave cpu which was spinning in the rendez loop.
- * Since this spinning is done by turning off the interrupts and
- * polling on the wakeup-interrupt bit in the IRR, there is
- * nothing useful to be done in the handler.
- *
- * Inputs : wakeup_irq (Wakeup-interrupt bit)
- * arg (Interrupt handler specific argument)
- * Outputs : None
- *
- */
-static irqreturn_t
-ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg)
-{
- return IRQ_HANDLED;
-}
-
-/* Function pointer for extra MCA recovery */
-int (*ia64_mca_ucmc_extension)
- (void*,struct ia64_sal_os_state*)
- = NULL;
-
-int
-ia64_reg_MCA_extension(int (*fn)(void *, struct ia64_sal_os_state *))
-{
- if (ia64_mca_ucmc_extension)
- return 1;
-
- ia64_mca_ucmc_extension = fn;
- return 0;
-}
-
-void
-ia64_unreg_MCA_extension(void)
-{
- if (ia64_mca_ucmc_extension)
- ia64_mca_ucmc_extension = NULL;
-}
-
-EXPORT_SYMBOL(ia64_reg_MCA_extension);
-EXPORT_SYMBOL(ia64_unreg_MCA_extension);
-
-
-static inline void
-copy_reg(const u64 *fr, u64 fnat, unsigned long *tr, unsigned long *tnat)
-{
- u64 fslot, tslot, nat;
- *tr = *fr;
- fslot = ((unsigned long)fr >> 3) & 63;
- tslot = ((unsigned long)tr >> 3) & 63;
- *tnat &= ~(1UL << tslot);
- nat = (fnat >> fslot) & 1;
- *tnat |= (nat << tslot);
-}
-
-/* Change the comm field on the MCA/INT task to include the pid that
- * was interrupted, it makes for easier debugging. If that pid was 0
- * (swapper or nested MCA/INIT) then use the start of the previous comm
- * field suffixed with its cpu.
- */
-
-static void
-ia64_mca_modify_comm(const struct task_struct *previous_current)
-{
- char *p, comm[sizeof(current->comm)];
- if (previous_current->pid)
- snprintf(comm, sizeof(comm), "%s %d",
- current->comm, previous_current->pid);
- else {
- int l;
- if ((p = strchr(previous_current->comm, ' ')))
- l = p - previous_current->comm;
- else
- l = strlen(previous_current->comm);
- snprintf(comm, sizeof(comm), "%s %*s %d",
- current->comm, l, previous_current->comm,
- task_thread_info(previous_current)->cpu);
- }
- memcpy(current->comm, comm, sizeof(current->comm));
-}
-
-static void
-finish_pt_regs(struct pt_regs *regs, struct ia64_sal_os_state *sos,
- unsigned long *nat)
-{
- const struct pal_min_state_area *ms = sos->pal_min_state;
- const u64 *bank;
-
- /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use
- * pmsa_{xip,xpsr,xfs}
- */
- if (ia64_psr(regs)->ic) {
- regs->cr_iip = ms->pmsa_iip;
- regs->cr_ipsr = ms->pmsa_ipsr;
- regs->cr_ifs = ms->pmsa_ifs;
- } else {
- regs->cr_iip = ms->pmsa_xip;
- regs->cr_ipsr = ms->pmsa_xpsr;
- regs->cr_ifs = ms->pmsa_xfs;
-
- sos->iip = ms->pmsa_iip;
- sos->ipsr = ms->pmsa_ipsr;
- sos->ifs = ms->pmsa_ifs;
- }
- regs->pr = ms->pmsa_pr;
- regs->b0 = ms->pmsa_br0;
- regs->ar_rsc = ms->pmsa_rsc;
- copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, &regs->r1, nat);
- copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, &regs->r2, nat);
- copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, &regs->r3, nat);
- copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, &regs->r8, nat);
- copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, &regs->r9, nat);
- copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, &regs->r10, nat);
- copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, &regs->r11, nat);
- copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, &regs->r12, nat);
- copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, &regs->r13, nat);
- copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, &regs->r14, nat);
- copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, &regs->r15, nat);
- if (ia64_psr(regs)->bn)
- bank = ms->pmsa_bank1_gr;
- else
- bank = ms->pmsa_bank0_gr;
- copy_reg(&bank[16-16], ms->pmsa_nat_bits, &regs->r16, nat);
- copy_reg(&bank[17-16], ms->pmsa_nat_bits, &regs->r17, nat);
- copy_reg(&bank[18-16], ms->pmsa_nat_bits, &regs->r18, nat);
- copy_reg(&bank[19-16], ms->pmsa_nat_bits, &regs->r19, nat);
- copy_reg(&bank[20-16], ms->pmsa_nat_bits, &regs->r20, nat);
- copy_reg(&bank[21-16], ms->pmsa_nat_bits, &regs->r21, nat);
- copy_reg(&bank[22-16], ms->pmsa_nat_bits, &regs->r22, nat);
- copy_reg(&bank[23-16], ms->pmsa_nat_bits, &regs->r23, nat);
- copy_reg(&bank[24-16], ms->pmsa_nat_bits, &regs->r24, nat);
- copy_reg(&bank[25-16], ms->pmsa_nat_bits, &regs->r25, nat);
- copy_reg(&bank[26-16], ms->pmsa_nat_bits, &regs->r26, nat);
- copy_reg(&bank[27-16], ms->pmsa_nat_bits, &regs->r27, nat);
- copy_reg(&bank[28-16], ms->pmsa_nat_bits, &regs->r28, nat);
- copy_reg(&bank[29-16], ms->pmsa_nat_bits, &regs->r29, nat);
- copy_reg(&bank[30-16], ms->pmsa_nat_bits, &regs->r30, nat);
- copy_reg(&bank[31-16], ms->pmsa_nat_bits, &regs->r31, nat);
-}
-
-/* On entry to this routine, we are running on the per cpu stack, see
- * mca_asm.h. The original stack has not been touched by this event. Some of
- * the original stack's registers will be in the RBS on this stack. This stack
- * also contains a partial pt_regs and switch_stack, the rest of the data is in
- * PAL minstate.
- *
- * The first thing to do is modify the original stack to look like a blocked
- * task so we can run backtrace on the original task. Also mark the per cpu
- * stack as current to ensure that we use the correct task state, it also means
- * that we can do backtrace on the MCA/INIT handler code itself.
- */
-
-static struct task_struct *
-ia64_mca_modify_original_stack(struct pt_regs *regs,
- const struct switch_stack *sw,
- struct ia64_sal_os_state *sos,
- const char *type)
-{
- char *p;
- ia64_va va;
- extern char ia64_leave_kernel[]; /* Need asm address, not function descriptor */
- const struct pal_min_state_area *ms = sos->pal_min_state;
- struct task_struct *previous_current;
- struct pt_regs *old_regs;
- struct switch_stack *old_sw;
- unsigned size = sizeof(struct pt_regs) +
- sizeof(struct switch_stack) + 16;
- unsigned long *old_bspstore, *old_bsp;
- unsigned long *new_bspstore, *new_bsp;
- unsigned long old_unat, old_rnat, new_rnat, nat;
- u64 slots, loadrs = regs->loadrs;
- u64 r12 = ms->pmsa_gr[12-1], r13 = ms->pmsa_gr[13-1];
- u64 ar_bspstore = regs->ar_bspstore;
- u64 ar_bsp = regs->ar_bspstore + (loadrs >> 16);
- const char *msg;
- int cpu = smp_processor_id();
-
- previous_current = curr_task(cpu);
- ia64_set_curr_task(cpu, current);
- if ((p = strchr(current->comm, ' ')))
- *p = '\0';
-
- /* Best effort attempt to cope with MCA/INIT delivered while in
- * physical mode.
- */
- regs->cr_ipsr = ms->pmsa_ipsr;
- if (ia64_psr(regs)->dt == 0) {
- va.l = r12;
- if (va.f.reg == 0) {
- va.f.reg = 7;
- r12 = va.l;
- }
- va.l = r13;
- if (va.f.reg == 0) {
- va.f.reg = 7;
- r13 = va.l;
- }
- }
- if (ia64_psr(regs)->rt == 0) {
- va.l = ar_bspstore;
- if (va.f.reg == 0) {
- va.f.reg = 7;
- ar_bspstore = va.l;
- }
- va.l = ar_bsp;
- if (va.f.reg == 0) {
- va.f.reg = 7;
- ar_bsp = va.l;
- }
- }
-
- /* mca_asm.S ia64_old_stack() cannot assume that the dirty registers
- * have been copied to the old stack, the old stack may fail the
- * validation tests below. So ia64_old_stack() must restore the dirty
- * registers from the new stack. The old and new bspstore probably
- * have different alignments, so loadrs calculated on the old bsp
- * cannot be used to restore from the new bsp. Calculate a suitable
- * loadrs for the new stack and save it in the new pt_regs, where
- * ia64_old_stack() can get it.
- */
- old_bspstore = (unsigned long *)ar_bspstore;
- old_bsp = (unsigned long *)ar_bsp;
- slots = ia64_rse_num_regs(old_bspstore, old_bsp);
- new_bspstore = (unsigned long *)((u64)current + IA64_RBS_OFFSET);
- new_bsp = ia64_rse_skip_regs(new_bspstore, slots);
- regs->loadrs = (new_bsp - new_bspstore) * 8 << 16;
-
- /* Verify the previous stack state before we change it */
- if (user_mode(regs)) {
- msg = "occurred in user space";
- /* previous_current is guaranteed to be valid when the task was
- * in user space, so ...
- */
- ia64_mca_modify_comm(previous_current);
- goto no_mod;
- }
-
- if (r13 != sos->prev_IA64_KR_CURRENT) {
- msg = "inconsistent previous current and r13";
- goto no_mod;
- }
-
- if (!mca_recover_range(ms->pmsa_iip)) {
- if ((r12 - r13) >= KERNEL_STACK_SIZE) {
- msg = "inconsistent r12 and r13";
- goto no_mod;
- }
- if ((ar_bspstore - r13) >= KERNEL_STACK_SIZE) {
- msg = "inconsistent ar.bspstore and r13";
- goto no_mod;
- }
- va.p = old_bspstore;
- if (va.f.reg < 5) {
- msg = "old_bspstore is in the wrong region";
- goto no_mod;
- }
- if ((ar_bsp - r13) >= KERNEL_STACK_SIZE) {
- msg = "inconsistent ar.bsp and r13";
- goto no_mod;
- }
- size += (ia64_rse_skip_regs(old_bspstore, slots) - old_bspstore) * 8;
- if (ar_bspstore + size > r12) {
- msg = "no room for blocked state";
- goto no_mod;
- }
- }
-
- ia64_mca_modify_comm(previous_current);
-
- /* Make the original task look blocked. First stack a struct pt_regs,
- * describing the state at the time of interrupt. mca_asm.S built a
- * partial pt_regs, copy it and fill in the blanks using minstate.
- */
- p = (char *)r12 - sizeof(*regs);
- old_regs = (struct pt_regs *)p;
- memcpy(old_regs, regs, sizeof(*regs));
- old_regs->loadrs = loadrs;
- old_unat = old_regs->ar_unat;
- finish_pt_regs(old_regs, sos, &old_unat);
-
- /* Next stack a struct switch_stack. mca_asm.S built a partial
- * switch_stack, copy it and fill in the blanks using pt_regs and
- * minstate.
- *
- * In the synthesized switch_stack, b0 points to ia64_leave_kernel,
- * ar.pfs is set to 0.
- *
- * unwind.c::unw_unwind() does special processing for interrupt frames.
- * It checks if the PRED_NON_SYSCALL predicate is set, if the predicate
- * is clear then unw_unwind() does _not_ adjust bsp over pt_regs. Not
- * that this is documented, of course. Set PRED_NON_SYSCALL in the
- * switch_stack on the original stack so it will unwind correctly when
- * unwind.c reads pt_regs.
- *
- * thread.ksp is updated to point to the synthesized switch_stack.
- */
- p -= sizeof(struct switch_stack);
- old_sw = (struct switch_stack *)p;
- memcpy(old_sw, sw, sizeof(*sw));
- old_sw->caller_unat = old_unat;
- old_sw->ar_fpsr = old_regs->ar_fpsr;
- copy_reg(&ms->pmsa_gr[4-1], ms->pmsa_nat_bits, &old_sw->r4, &old_unat);
- copy_reg(&ms->pmsa_gr[5-1], ms->pmsa_nat_bits, &old_sw->r5, &old_unat);
- copy_reg(&ms->pmsa_gr[6-1], ms->pmsa_nat_bits, &old_sw->r6, &old_unat);
- copy_reg(&ms->pmsa_gr[7-1], ms->pmsa_nat_bits, &old_sw->r7, &old_unat);
- old_sw->b0 = (u64)ia64_leave_kernel;
- old_sw->b1 = ms->pmsa_br1;
- old_sw->ar_pfs = 0;
- old_sw->ar_unat = old_unat;
- old_sw->pr = old_regs->pr | (1UL << PRED_NON_SYSCALL);
- previous_current->thread.ksp = (u64)p - 16;
-
- /* Finally copy the original stack's registers back to its RBS.
- * Registers from ar.bspstore through ar.bsp at the time of the event
- * are in the current RBS, copy them back to the original stack. The
- * copy must be done register by register because the original bspstore
- * and the current one have different alignments, so the saved RNAT
- * data occurs at different places.
- *
- * mca_asm does cover, so the old_bsp already includes all registers at
- * the time of MCA/INIT. It also does flushrs, so all registers before
- * this function have been written to backing store on the MCA/INIT
- * stack.
- */
- new_rnat = ia64_get_rnat(ia64_rse_rnat_addr(new_bspstore));
- old_rnat = regs->ar_rnat;
- while (slots--) {
- if (ia64_rse_is_rnat_slot(new_bspstore)) {
- new_rnat = ia64_get_rnat(new_bspstore++);
- }
- if (ia64_rse_is_rnat_slot(old_bspstore)) {
- *old_bspstore++ = old_rnat;
- old_rnat = 0;
- }
- nat = (new_rnat >> ia64_rse_slot_num(new_bspstore)) & 1UL;
- old_rnat &= ~(1UL << ia64_rse_slot_num(old_bspstore));
- old_rnat |= (nat << ia64_rse_slot_num(old_bspstore));
- *old_bspstore++ = *new_bspstore++;
- }
- old_sw->ar_bspstore = (unsigned long)old_bspstore;
- old_sw->ar_rnat = old_rnat;
-
- sos->prev_task = previous_current;
- return previous_current;
-
-no_mod:
- mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n",
- smp_processor_id(), type, msg);
- old_unat = regs->ar_unat;
- finish_pt_regs(regs, sos, &old_unat);
- return previous_current;
-}
-
-/* The monarch/slave interaction is based on monarch_cpu and requires that all
- * slaves have entered rendezvous before the monarch leaves. If any cpu has
- * not entered rendezvous yet then wait a bit. The assumption is that any
- * slave that has not rendezvoused after a reasonable time is never going to do
- * so. In this context, slave includes cpus that respond to the MCA rendezvous
- * interrupt, as well as cpus that receive the INIT slave event.
- */
-
-static void
-ia64_wait_for_slaves(int monarch, const char *type)
-{
- int c, i , wait;
-
- /*
- * wait 5 seconds total for slaves (arbitrary)
- */
- for (i = 0; i < 5000; i++) {
- wait = 0;
- for_each_online_cpu(c) {
- if (c == monarch)
- continue;
- if (ia64_mc_info.imi_rendez_checkin[c]
- == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) {
- udelay(1000); /* short wait */
- wait = 1;
- break;
- }
- }
- if (!wait)
- goto all_in;
- }
-
- /*
- * Maybe slave(s) dead. Print buffered messages immediately.
- */
- ia64_mlogbuf_finish(0);
- mprintk(KERN_INFO "OS %s slave did not rendezvous on cpu", type);
- for_each_online_cpu(c) {
- if (c == monarch)
- continue;
- if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE)
- mprintk(" %d", c);
- }
- mprintk("\n");
- return;
-
-all_in:
- mprintk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type);
- return;
-}
-
-/* mca_insert_tr
- *
- * Switch rid when TR reload and needed!
- * iord: 1: itr, 2: itr;
- *
-*/
-static void mca_insert_tr(u64 iord)
-{
-
- int i;
- u64 old_rr;
- struct ia64_tr_entry *p;
- unsigned long psr;
- int cpu = smp_processor_id();
-
- if (!ia64_idtrs[cpu])
- return;
-
- psr = ia64_clear_ic();
- for (i = IA64_TR_ALLOC_BASE; i < IA64_TR_ALLOC_MAX; i++) {
- p = ia64_idtrs[cpu] + (iord - 1) * IA64_TR_ALLOC_MAX;
- if (p->pte & 0x1) {
- old_rr = ia64_get_rr(p->ifa);
- if (old_rr != p->rr) {
- ia64_set_rr(p->ifa, p->rr);
- ia64_srlz_d();
- }
- ia64_ptr(iord, p->ifa, p->itir >> 2);
- ia64_srlz_i();
- if (iord & 0x1) {
- ia64_itr(0x1, i, p->ifa, p->pte, p->itir >> 2);
- ia64_srlz_i();
- }
- if (iord & 0x2) {
- ia64_itr(0x2, i, p->ifa, p->pte, p->itir >> 2);
- ia64_srlz_i();
- }
- if (old_rr != p->rr) {
- ia64_set_rr(p->ifa, old_rr);
- ia64_srlz_d();
- }
- }
- }
- ia64_set_psr(psr);
-}
-
-/*
- * ia64_mca_handler
- *
- * This is uncorrectable machine check handler called from OS_MCA
- * dispatch code which is in turn called from SAL_CHECK().
- * This is the place where the core of OS MCA handling is done.
- * Right now the logs are extracted and displayed in a well-defined
- * format. This handler code is supposed to be run only on the
- * monarch processor. Once the monarch is done with MCA handling
- * further MCA logging is enabled by clearing logs.
- * Monarch also has the duty of sending wakeup-IPIs to pull the
- * slave processors out of rendezvous spinloop.
- *
- * If multiple processors call into OS_MCA, the first will become
- * the monarch. Subsequent cpus will be recorded in the mca_cpu
- * bitmask. After the first monarch has processed its MCA, it
- * will wake up the next cpu in the mca_cpu bitmask and then go
- * into the rendezvous loop. When all processors have serviced
- * their MCA, the last monarch frees up the rest of the processors.
- */
-void
-ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
- struct ia64_sal_os_state *sos)
-{
- int recover, cpu = smp_processor_id();
- struct task_struct *previous_current;
- struct ia64_mca_notify_die nd =
- { .sos = sos, .monarch_cpu = &monarch_cpu, .data = &recover };
- static atomic_t mca_count;
- static cpumask_t mca_cpu;
-
- if (atomic_add_return(1, &mca_count) == 1) {
- monarch_cpu = cpu;
- sos->monarch = 1;
- } else {
- cpumask_set_cpu(cpu, &mca_cpu);
- sos->monarch = 0;
- }
- mprintk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d "
- "monarch=%ld\n", sos->proc_state_param, cpu, sos->monarch);
-
- previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
-
- NOTIFY_MCA(DIE_MCA_MONARCH_ENTER, regs, (long)&nd, 1);
-
- ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA;
- if (sos->monarch) {
- ia64_wait_for_slaves(cpu, "MCA");
-
- /* Wakeup all the processors which are spinning in the
- * rendezvous loop. They will leave SAL, then spin in the OS
- * with interrupts disabled until this monarch cpu leaves the
- * MCA handler. That gets control back to the OS so we can
- * backtrace the other cpus, backtrace when spinning in SAL
- * does not work.
- */
- ia64_mca_wakeup_all();
- } else {
- while (cpumask_test_cpu(cpu, &mca_cpu))
- cpu_relax(); /* spin until monarch wakes us */
- }
-
- NOTIFY_MCA(DIE_MCA_MONARCH_PROCESS, regs, (long)&nd, 1);
-
- /* Get the MCA error record and log it */
- ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
-
- /* MCA error recovery */
- recover = (ia64_mca_ucmc_extension
- && ia64_mca_ucmc_extension(
- IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_MCA),
- sos));
-
- if (recover) {
- sal_log_record_header_t *rh = IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_MCA);
- rh->severity = sal_log_severity_corrected;
- ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
- sos->os_status = IA64_MCA_CORRECTED;
- } else {
- /* Dump buffered message to console */
- ia64_mlogbuf_finish(1);
- }
-
- if (__this_cpu_read(ia64_mca_tr_reload)) {
- mca_insert_tr(0x1); /*Reload dynamic itrs*/
- mca_insert_tr(0x2); /*Reload dynamic itrs*/
- }
-
- NOTIFY_MCA(DIE_MCA_MONARCH_LEAVE, regs, (long)&nd, 1);
-
- if (atomic_dec_return(&mca_count) > 0) {
- int i;
-
- /* wake up the next monarch cpu,
- * and put this cpu in the rendez loop.
- */
- for_each_online_cpu(i) {
- if (cpumask_test_cpu(i, &mca_cpu)) {
- monarch_cpu = i;
- cpumask_clear_cpu(i, &mca_cpu); /* wake next cpu */
- while (monarch_cpu != -1)
- cpu_relax(); /* spin until last cpu leaves */
- ia64_set_curr_task(cpu, previous_current);
- ia64_mc_info.imi_rendez_checkin[cpu]
- = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
- return;
- }
- }
- }
- ia64_set_curr_task(cpu, previous_current);
- ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
- monarch_cpu = -1; /* This frees the slaves and previous monarchs */
-}
-
-static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd);
-static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd);
-
-/*
- * ia64_mca_cmc_int_handler
- *
- * This is corrected machine check interrupt handler.
- * Right now the logs are extracted and displayed in a well-defined
- * format.
- *
- * Inputs
- * interrupt number
- * client data arg ptr
- *
- * Outputs
- * None
- */
-static irqreturn_t
-ia64_mca_cmc_int_handler(int cmc_irq, void *arg)
-{
- static unsigned long cmc_history[CMC_HISTORY_LENGTH];
- static int index;
- static DEFINE_SPINLOCK(cmc_history_lock);
-
- IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
- __func__, cmc_irq, smp_processor_id());
-
- /* SAL spec states this should run w/ interrupts enabled */
- local_irq_enable();
-
- spin_lock(&cmc_history_lock);
- if (!cmc_polling_enabled) {
- int i, count = 1; /* we know 1 happened now */
- unsigned long now = jiffies;
-
- for (i = 0; i < CMC_HISTORY_LENGTH; i++) {
- if (now - cmc_history[i] <= HZ)
- count++;
- }
-
- IA64_MCA_DEBUG(KERN_INFO "CMC threshold %d/%d\n", count, CMC_HISTORY_LENGTH);
- if (count >= CMC_HISTORY_LENGTH) {
-
- cmc_polling_enabled = 1;
- spin_unlock(&cmc_history_lock);
- /* If we're being hit with CMC interrupts, we won't
- * ever execute the schedule_work() below. Need to
- * disable CMC interrupts on this processor now.
- */
- ia64_mca_cmc_vector_disable(NULL);
- schedule_work(&cmc_disable_work);
-
- /*
- * Corrected errors will still be corrected, but
- * make sure there's a log somewhere that indicates
- * something is generating more than we can handle.
- */
- printk(KERN_WARNING "WARNING: Switching to polling CMC handler; error records may be lost\n");
-
- mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
-
- /* lock already released, get out now */
- goto out;
- } else {
- cmc_history[index++] = now;
- if (index == CMC_HISTORY_LENGTH)
- index = 0;
- }
- }
- spin_unlock(&cmc_history_lock);
-out:
- /* Get the CMC error record and log it */
- ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC);
-
- local_irq_disable();
-
- return IRQ_HANDLED;
-}
-
-/*
- * ia64_mca_cmc_int_caller
- *
- * Triggered by sw interrupt from CMC polling routine. Calls
- * real interrupt handler and either triggers a sw interrupt
- * on the next cpu or does cleanup at the end.
- *
- * Inputs
- * interrupt number
- * client data arg ptr
- * Outputs
- * handled
- */
-static irqreturn_t
-ia64_mca_cmc_int_caller(int cmc_irq, void *arg)
-{
- static int start_count = -1;
- unsigned int cpuid;
-
- cpuid = smp_processor_id();
-
- /* If first cpu, update count */
- if (start_count == -1)
- start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC);
-
- ia64_mca_cmc_int_handler(cmc_irq, arg);
-
- cpuid = cpumask_next(cpuid+1, cpu_online_mask);
-
- if (cpuid < nr_cpu_ids) {
- ia64_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
- } else {
- /* If no log record, switch out of polling mode */
- if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) {
-
- printk(KERN_WARNING "Returning to interrupt driven CMC handler\n");
- schedule_work(&cmc_enable_work);
- cmc_polling_enabled = 0;
-
- } else {
-
- mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
- }
-
- start_count = -1;
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * ia64_mca_cmc_poll
- *
- * Poll for Corrected Machine Checks (CMCs)
- *
- * Inputs : dummy(unused)
- * Outputs : None
- *
- */
-static void
-ia64_mca_cmc_poll (struct timer_list *unused)
-{
- /* Trigger a CMC interrupt cascade */
- ia64_send_ipi(cpumask_first(cpu_online_mask), IA64_CMCP_VECTOR,
- IA64_IPI_DM_INT, 0);
-}
-
-/*
- * ia64_mca_cpe_int_caller
- *
- * Triggered by sw interrupt from CPE polling routine. Calls
- * real interrupt handler and either triggers a sw interrupt
- * on the next cpu or does cleanup at the end.
- *
- * Inputs
- * interrupt number
- * client data arg ptr
- * Outputs
- * handled
- */
-static irqreturn_t
-ia64_mca_cpe_int_caller(int cpe_irq, void *arg)
-{
- static int start_count = -1;
- static int poll_time = MIN_CPE_POLL_INTERVAL;
- unsigned int cpuid;
-
- cpuid = smp_processor_id();
-
- /* If first cpu, update count */
- if (start_count == -1)
- start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE);
-
- ia64_mca_cpe_int_handler(cpe_irq, arg);
-
- cpuid = cpumask_next(cpuid+1, cpu_online_mask);
-
- if (cpuid < NR_CPUS) {
- ia64_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
- } else {
- /*
- * If a log was recorded, increase our polling frequency,
- * otherwise, backoff or return to interrupt mode.
- */
- if (start_count != IA64_LOG_COUNT(SAL_INFO_TYPE_CPE)) {
- poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time / 2);
- } else if (cpe_vector < 0) {
- poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2);
- } else {
- poll_time = MIN_CPE_POLL_INTERVAL;
-
- printk(KERN_WARNING "Returning to interrupt driven CPE handler\n");
- enable_irq(local_vector_to_irq(IA64_CPE_VECTOR));
- cpe_poll_enabled = 0;
- }
-
- if (cpe_poll_enabled)
- mod_timer(&cpe_poll_timer, jiffies + poll_time);
- start_count = -1;
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * ia64_mca_cpe_poll
- *
- * Poll for Corrected Platform Errors (CPEs), trigger interrupt
- * on first cpu, from there it will trickle through all the cpus.
- *
- * Inputs : dummy(unused)
- * Outputs : None
- *
- */
-static void
-ia64_mca_cpe_poll (struct timer_list *unused)
-{
- /* Trigger a CPE interrupt cascade */
- ia64_send_ipi(cpumask_first(cpu_online_mask), IA64_CPEP_VECTOR,
- IA64_IPI_DM_INT, 0);
-}
-
-static int
-default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data)
-{
- int c;
- struct task_struct *g, *t;
- if (val != DIE_INIT_MONARCH_PROCESS)
- return NOTIFY_DONE;
-#ifdef CONFIG_KEXEC
- if (atomic_read(&kdump_in_progress))
- return NOTIFY_DONE;
-#endif
-
- /*
- * FIXME: mlogbuf will brim over with INIT stack dumps.
- * To enable show_stack from INIT, we use oops_in_progress which should
- * be used in real oops. This would cause something wrong after INIT.
- */
- BREAK_LOGLEVEL(console_loglevel);
- ia64_mlogbuf_dump_from_init();
-
- printk(KERN_ERR "Processes interrupted by INIT -");
- for_each_online_cpu(c) {
- struct ia64_sal_os_state *s;
- t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
- s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
- g = s->prev_task;
- if (g) {
- if (g->pid)
- printk(" %d", g->pid);
- else
- printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
- }
- }
- printk("\n\n");
- if (read_trylock(&tasklist_lock)) {
- for_each_process_thread(g, t) {
- printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
- show_stack(t, NULL, KERN_DEFAULT);
- }
- read_unlock(&tasklist_lock);
- }
- /* FIXME: This will not restore zapped printk locks. */
- RESTORE_LOGLEVEL(console_loglevel);
- return NOTIFY_DONE;
-}
-
-/*
- * C portion of the OS INIT handler
- *
- * Called from ia64_os_init_dispatch
- *
- * Inputs: pointer to pt_regs where processor info was saved. SAL/OS state for
- * this event. This code is used for both monarch and slave INIT events, see
- * sos->monarch.
- *
- * All INIT events switch to the INIT stack and change the previous process to
- * blocked status. If one of the INIT events is the monarch then we are
- * probably processing the nmi button/command. Use the monarch cpu to dump all
- * the processes. The slave INIT events all spin until the monarch cpu
- * returns. We can also get INIT slave events for MCA, in which case the MCA
- * process is the monarch.
- */
-
-void
-ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
- struct ia64_sal_os_state *sos)
-{
- static atomic_t slaves;
- static atomic_t monarchs;
- struct task_struct *previous_current;
- int cpu = smp_processor_id();
- struct ia64_mca_notify_die nd =
- { .sos = sos, .monarch_cpu = &monarch_cpu };
-
- NOTIFY_INIT(DIE_INIT_ENTER, regs, (long)&nd, 0);
-
- mprintk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n",
- sos->proc_state_param, cpu, sos->monarch);
- salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0);
-
- previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "INIT");
- sos->os_status = IA64_INIT_RESUME;
-
- /* FIXME: Workaround for broken proms that drive all INIT events as
- * slaves. The last slave that enters is promoted to be a monarch.
- * Remove this code in September 2006, that gives platforms a year to
- * fix their proms and get their customers updated.
- */
- if (!sos->monarch && atomic_add_return(1, &slaves) == num_online_cpus()) {
- mprintk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n",
- __func__, cpu);
- atomic_dec(&slaves);
- sos->monarch = 1;
- }
-
- /* FIXME: Workaround for broken proms that drive all INIT events as
- * monarchs. Second and subsequent monarchs are demoted to slaves.
- * Remove this code in September 2006, that gives platforms a year to
- * fix their proms and get their customers updated.
- */
- if (sos->monarch && atomic_add_return(1, &monarchs) > 1) {
- mprintk(KERN_WARNING "%s: Demoting cpu %d to slave.\n",
- __func__, cpu);
- atomic_dec(&monarchs);
- sos->monarch = 0;
- }
-
- if (!sos->monarch) {
- ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
-
-#ifdef CONFIG_KEXEC
- while (monarch_cpu == -1 && !atomic_read(&kdump_in_progress))
- udelay(1000);
-#else
- while (monarch_cpu == -1)
- cpu_relax(); /* spin until monarch enters */
-#endif
-
- NOTIFY_INIT(DIE_INIT_SLAVE_ENTER, regs, (long)&nd, 1);
- NOTIFY_INIT(DIE_INIT_SLAVE_PROCESS, regs, (long)&nd, 1);
-
-#ifdef CONFIG_KEXEC
- while (monarch_cpu != -1 && !atomic_read(&kdump_in_progress))
- udelay(1000);
-#else
- while (monarch_cpu != -1)
- cpu_relax(); /* spin until monarch leaves */
-#endif
-
- NOTIFY_INIT(DIE_INIT_SLAVE_LEAVE, regs, (long)&nd, 1);
-
- mprintk("Slave on cpu %d returning to normal service.\n", cpu);
- ia64_set_curr_task(cpu, previous_current);
- ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
- atomic_dec(&slaves);
- return;
- }
-
- monarch_cpu = cpu;
- NOTIFY_INIT(DIE_INIT_MONARCH_ENTER, regs, (long)&nd, 1);
-
- /*
- * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
- * generated via the BMC's command-line interface, but since the console is on the
- * same serial line, the user will need some time to switch out of the BMC before
- * the dump begins.
- */
- mprintk("Delaying for 5 seconds...\n");
- udelay(5*1000000);
- ia64_wait_for_slaves(cpu, "INIT");
- /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
- * to default_monarch_init_process() above and just print all the
- * tasks.
- */
- NOTIFY_INIT(DIE_INIT_MONARCH_PROCESS, regs, (long)&nd, 1);
- NOTIFY_INIT(DIE_INIT_MONARCH_LEAVE, regs, (long)&nd, 1);
-
- mprintk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
- atomic_dec(&monarchs);
- ia64_set_curr_task(cpu, previous_current);
- monarch_cpu = -1;
- return;
-}
-
-static int __init
-ia64_mca_disable_cpe_polling(char *str)
-{
- cpe_poll_enabled = 0;
- return 1;
-}
-
-__setup("disable_cpe_poll", ia64_mca_disable_cpe_polling);
-
-/* Minimal format of the MCA/INIT stacks. The pseudo processes that run on
- * these stacks can never sleep, they cannot return from the kernel to user
- * space, they do not appear in a normal ps listing. So there is no need to
- * format most of the fields.
- */
-
-static void
-format_mca_init_stack(void *mca_data, unsigned long offset,
- const char *type, int cpu)
-{
- struct task_struct *p = (struct task_struct *)((char *)mca_data + offset);
- struct thread_info *ti;
- memset(p, 0, KERNEL_STACK_SIZE);
- ti = task_thread_info(p);
- ti->flags = _TIF_MCA_INIT;
- ti->preempt_count = 1;
- ti->task = p;
- ti->cpu = cpu;
- p->stack = ti;
- p->__state = TASK_UNINTERRUPTIBLE;
- cpumask_set_cpu(cpu, &p->cpus_mask);
- INIT_LIST_HEAD(&p->tasks);
- p->parent = p->real_parent = p->group_leader = p;
- INIT_LIST_HEAD(&p->children);
- INIT_LIST_HEAD(&p->sibling);
- strscpy(p->comm, type, sizeof(p->comm)-1);
-}
-
-/* Caller prevents this from being called after init */
-static void * __ref mca_bootmem(void)
-{
- return memblock_alloc(sizeof(struct ia64_mca_cpu), KERNEL_STACK_SIZE);
-}
-
-/* Do per-CPU MCA-related initialization. */
-void
-ia64_mca_cpu_init(void *cpu_data)
-{
- void *pal_vaddr;
- void *data;
- long sz = sizeof(struct ia64_mca_cpu);
- int cpu = smp_processor_id();
- static int first_time = 1;
-
- /*
- * Structure will already be allocated if cpu has been online,
- * then offlined.
- */
- if (__per_cpu_mca[cpu]) {
- data = __va(__per_cpu_mca[cpu]);
- } else {
- if (first_time) {
- data = mca_bootmem();
- first_time = 0;
- } else
- data = (void *)__get_free_pages(GFP_ATOMIC,
- get_order(sz));
- if (!data)
- panic("Could not allocate MCA memory for cpu %d\n",
- cpu);
- }
- format_mca_init_stack(data, offsetof(struct ia64_mca_cpu, mca_stack),
- "MCA", cpu);
- format_mca_init_stack(data, offsetof(struct ia64_mca_cpu, init_stack),
- "INIT", cpu);
- __this_cpu_write(ia64_mca_data, (__per_cpu_mca[cpu] = __pa(data)));
-
- /*
- * Stash away a copy of the PTE needed to map the per-CPU page.
- * We may need it during MCA recovery.
- */
- __this_cpu_write(ia64_mca_per_cpu_pte,
- pte_val(mk_pte_phys(__pa(cpu_data), PAGE_KERNEL)));
-
- /*
- * Also, stash away a copy of the PAL address and the PTE
- * needed to map it.
- */
- pal_vaddr = efi_get_pal_addr();
- if (!pal_vaddr)
- return;
- __this_cpu_write(ia64_mca_pal_base,
- GRANULEROUNDDOWN((unsigned long) pal_vaddr));
- __this_cpu_write(ia64_mca_pal_pte, pte_val(mk_pte_phys(__pa(pal_vaddr),
- PAGE_KERNEL)));
-}
-
-static int ia64_mca_cpu_online(unsigned int cpu)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- if (!cmc_polling_enabled)
- ia64_mca_cmc_vector_enable(NULL);
- local_irq_restore(flags);
- return 0;
-}
-
-/*
- * ia64_mca_init
- *
- * Do all the system level mca specific initialization.
- *
- * 1. Register spinloop and wakeup request interrupt vectors
- *
- * 2. Register OS_MCA handler entry point
- *
- * 3. Register OS_INIT handler entry point
- *
- * 4. Initialize MCA/CMC/INIT related log buffers maintained by the OS.
- *
- * Note that this initialization is done very early before some kernel
- * services are available.
- *
- * Inputs : None
- *
- * Outputs : None
- */
-void __init
-ia64_mca_init(void)
-{
- ia64_fptr_t *init_hldlr_ptr_monarch = (ia64_fptr_t *)ia64_os_init_dispatch_monarch;
- ia64_fptr_t *init_hldlr_ptr_slave = (ia64_fptr_t *)ia64_os_init_dispatch_slave;
- ia64_fptr_t *mca_hldlr_ptr = (ia64_fptr_t *)ia64_os_mca_dispatch;
- int i;
- long rc;
- struct ia64_sal_retval isrv;
- unsigned long timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */
- static struct notifier_block default_init_monarch_nb = {
- .notifier_call = default_monarch_init_process,
- .priority = 0/* we need to notified last */
- };
-
- IA64_MCA_DEBUG("%s: begin\n", __func__);
-
- /* Clear the Rendez checkin flag for all cpus */
- for(i = 0 ; i < NR_CPUS; i++)
- ia64_mc_info.imi_rendez_checkin[i] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
-
- /*
- * Register the rendezvous spinloop and wakeup mechanism with SAL
- */
-
- /* Register the rendezvous interrupt vector with SAL */
- while (1) {
- isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_INT,
- SAL_MC_PARAM_MECHANISM_INT,
- IA64_MCA_RENDEZ_VECTOR,
- timeout,
- SAL_MC_PARAM_RZ_ALWAYS);
- rc = isrv.status;
- if (rc == 0)
- break;
- if (rc == -2) {
- printk(KERN_INFO "Increasing MCA rendezvous timeout from "
- "%ld to %ld milliseconds\n", timeout, isrv.v0);
- timeout = isrv.v0;
- NOTIFY_MCA(DIE_MCA_NEW_TIMEOUT, NULL, timeout, 0);
- continue;
- }
- printk(KERN_ERR "Failed to register rendezvous interrupt "
- "with SAL (status %ld)\n", rc);
- return;
- }
-
- /* Register the wakeup interrupt vector with SAL */
- isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_WAKEUP,
- SAL_MC_PARAM_MECHANISM_INT,
- IA64_MCA_WAKEUP_VECTOR,
- 0, 0);
- rc = isrv.status;
- if (rc) {
- printk(KERN_ERR "Failed to register wakeup interrupt with SAL "
- "(status %ld)\n", rc);
- return;
- }
-
- IA64_MCA_DEBUG("%s: registered MCA rendezvous spinloop and wakeup mech.\n", __func__);
-
- ia64_mc_info.imi_mca_handler = ia64_tpa(mca_hldlr_ptr->fp);
- /*
- * XXX - disable SAL checksum by setting size to 0; should be
- * ia64_tpa(ia64_os_mca_dispatch_end) - ia64_tpa(ia64_os_mca_dispatch);
- */
- ia64_mc_info.imi_mca_handler_size = 0;
-
- /* Register the os mca handler with SAL */
- if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_MCA,
- ia64_mc_info.imi_mca_handler,
- ia64_tpa(mca_hldlr_ptr->gp),
- ia64_mc_info.imi_mca_handler_size,
- 0, 0, 0)))
- {
- printk(KERN_ERR "Failed to register OS MCA handler with SAL "
- "(status %ld)\n", rc);
- return;
- }
-
- IA64_MCA_DEBUG("%s: registered OS MCA handler with SAL at 0x%lx, gp = 0x%lx\n", __func__,
- ia64_mc_info.imi_mca_handler, ia64_tpa(mca_hldlr_ptr->gp));
-
- /*
- * XXX - disable SAL checksum by setting size to 0, should be
- * size of the actual init handler in mca_asm.S.
- */
- ia64_mc_info.imi_monarch_init_handler = ia64_tpa(init_hldlr_ptr_monarch->fp);
- ia64_mc_info.imi_monarch_init_handler_size = 0;
- ia64_mc_info.imi_slave_init_handler = ia64_tpa(init_hldlr_ptr_slave->fp);
- ia64_mc_info.imi_slave_init_handler_size = 0;
-
- IA64_MCA_DEBUG("%s: OS INIT handler at %lx\n", __func__,
- ia64_mc_info.imi_monarch_init_handler);
-
- /* Register the os init handler with SAL */
- if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_INIT,
- ia64_mc_info.imi_monarch_init_handler,
- ia64_tpa(ia64_getreg(_IA64_REG_GP)),
- ia64_mc_info.imi_monarch_init_handler_size,
- ia64_mc_info.imi_slave_init_handler,
- ia64_tpa(ia64_getreg(_IA64_REG_GP)),
- ia64_mc_info.imi_slave_init_handler_size)))
- {
- printk(KERN_ERR "Failed to register m/s INIT handlers with SAL "
- "(status %ld)\n", rc);
- return;
- }
- if (register_die_notifier(&default_init_monarch_nb)) {
- printk(KERN_ERR "Failed to register default monarch INIT process\n");
- return;
- }
-
- IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __func__);
-
- /* Initialize the areas set aside by the OS to buffer the
- * platform/processor error states for MCA/INIT/CMC
- * handling.
- */
- ia64_log_init(SAL_INFO_TYPE_MCA);
- ia64_log_init(SAL_INFO_TYPE_INIT);
- ia64_log_init(SAL_INFO_TYPE_CMC);
- ia64_log_init(SAL_INFO_TYPE_CPE);
-
- mca_init = 1;
- printk(KERN_INFO "MCA related initialization done\n");
-}
-
-
-/*
- * These pieces cannot be done in ia64_mca_init() because it is called before
- * early_irq_init() which would wipe out our percpu irq registrations. But we
- * cannot leave them until ia64_mca_late_init() because by then all the other
- * processors have been brought online and have set their own CMC vectors to
- * point at a non-existant action. Called from arch_early_irq_init().
- */
-void __init ia64_mca_irq_init(void)
-{
- /*
- * Configure the CMCI/P vector and handler. Interrupts for CMC are
- * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c).
- */
- register_percpu_irq(IA64_CMC_VECTOR, ia64_mca_cmc_int_handler, 0,
- "cmc_hndlr");
- register_percpu_irq(IA64_CMCP_VECTOR, ia64_mca_cmc_int_caller, 0,
- "cmc_poll");
- ia64_mca_cmc_vector_setup(); /* Setup vector on BSP */
-
- /* Setup the MCA rendezvous interrupt vector */
- register_percpu_irq(IA64_MCA_RENDEZ_VECTOR, ia64_mca_rendez_int_handler,
- 0, "mca_rdzv");
-
- /* Setup the MCA wakeup interrupt vector */
- register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, ia64_mca_wakeup_int_handler,
- 0, "mca_wkup");
-
- /* Setup the CPEI/P handler */
- register_percpu_irq(IA64_CPEP_VECTOR, ia64_mca_cpe_int_caller, 0,
- "cpe_poll");
-}
-
-/*
- * ia64_mca_late_init
- *
- * Opportunity to setup things that require initialization later
- * than ia64_mca_init. Setup a timer to poll for CPEs if the
- * platform doesn't support an interrupt driven mechanism.
- *
- * Inputs : None
- * Outputs : Status
- */
-static int __init
-ia64_mca_late_init(void)
-{
- if (!mca_init)
- return 0;
-
- /* Setup the CMCI/P vector and handler */
- timer_setup(&cmc_poll_timer, ia64_mca_cmc_poll, 0);
-
- /* Unmask/enable the vector */
- cmc_polling_enabled = 0;
- cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "ia64/mca:online",
- ia64_mca_cpu_online, NULL);
- IA64_MCA_DEBUG("%s: CMCI/P setup and enabled.\n", __func__);
-
- /* Setup the CPEI/P vector and handler */
- cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
- timer_setup(&cpe_poll_timer, ia64_mca_cpe_poll, 0);
-
- {
- unsigned int irq;
-
- if (cpe_vector >= 0) {
- /* If platform supports CPEI, enable the irq. */
- irq = local_vector_to_irq(cpe_vector);
- if (irq > 0) {
- cpe_poll_enabled = 0;
- irq_set_status_flags(irq, IRQ_PER_CPU);
- if (request_irq(irq, ia64_mca_cpe_int_handler,
- 0, "cpe_hndlr", NULL))
- pr_err("Failed to register cpe_hndlr interrupt\n");
- ia64_cpe_irq = irq;
- ia64_mca_register_cpev(cpe_vector);
- IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n",
- __func__);
- return 0;
- }
- printk(KERN_ERR "%s: Failed to find irq for CPE "
- "interrupt handler, vector %d\n",
- __func__, cpe_vector);
- }
- /* If platform doesn't support CPEI, get the timer going. */
- if (cpe_poll_enabled) {
- ia64_mca_cpe_poll(0UL);
- IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __func__);
- }
- }
-
- return 0;
-}
-
-device_initcall(ia64_mca_late_init);
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
deleted file mode 100644
index 0d6b8cf9d1d0..000000000000
--- a/arch/ia64/kernel/mca_asm.S
+++ /dev/null
@@ -1,1123 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * File: mca_asm.S
- * Purpose: assembly portion of the IA64 MCA handling
- *
- * Mods by cfleck to integrate into kernel build
- *
- * 2000-03-15 David Mosberger-Tang <davidm@hpl.hp.com>
- * Added various stop bits to get a clean compile
- *
- * 2000-03-29 Chuck Fleckenstein <cfleck@co.intel.com>
- * Added code to save INIT handoff state in pt_regs format,
- * switch to temp kstack, switch modes, jump to C INIT handler
- *
- * 2002-01-04 J.Hall <jenna.s.hall@intel.com>
- * Before entering virtual mode code:
- * 1. Check for TLB CPU error
- * 2. Restore current thread pointer to kr6
- * 3. Move stack ptr 16 bytes to conform to C calling convention
- *
- * 2004-11-12 Russ Anderson <rja@sgi.com>
- * Added per cpu MCA/INIT stack save areas.
- *
- * 2005-12-08 Keith Owens <kaos@sgi.com>
- * Use per cpu MCA/INIT stacks for all data.
- */
-#include <linux/threads.h>
-#include <linux/pgtable.h>
-
-#include <asm/asmmacro.h>
-#include <asm/processor.h>
-#include <asm/mca_asm.h>
-#include <asm/mca.h>
-
-#include "entry.h"
-
-#define GET_IA64_MCA_DATA(reg) \
- GET_THIS_PADDR(reg, ia64_mca_data) \
- ;; \
- ld8 reg=[reg]
-
- .global ia64_do_tlb_purge
- .global ia64_os_mca_dispatch
- .global ia64_os_init_on_kdump
- .global ia64_os_init_dispatch_monarch
- .global ia64_os_init_dispatch_slave
-
- .text
- .align 16
-
-//StartMain////////////////////////////////////////////////////////////////////
-
-/*
- * Just the TLB purge part is moved to a separate function
- * so we can re-use the code for cpu hotplug code as well
- * Caller should now setup b1, so we can branch once the
- * tlb flush is complete.
- */
-
-ia64_do_tlb_purge:
-#define O(member) IA64_CPUINFO_##member##_OFFSET
-
- GET_THIS_PADDR(r2, ia64_cpu_info) // load phys addr of cpu_info into r2
- ;;
- addl r17=O(PTCE_STRIDE),r2
- addl r2=O(PTCE_BASE),r2
- ;;
- ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));; // r18=ptce_base
- ld4 r19=[r2],4 // r19=ptce_count[0]
- ld4 r21=[r17],4 // r21=ptce_stride[0]
- ;;
- ld4 r20=[r2] // r20=ptce_count[1]
- ld4 r22=[r17] // r22=ptce_stride[1]
- mov r24=0
- ;;
- adds r20=-1,r20
- ;;
-#undef O
-
-2:
- cmp.ltu p6,p7=r24,r19
-(p7) br.cond.dpnt.few 4f
- mov ar.lc=r20
-3:
- ptc.e r18
- ;;
- add r18=r22,r18
- br.cloop.sptk.few 3b
- ;;
- add r18=r21,r18
- add r24=1,r24
- ;;
- br.sptk.few 2b
-4:
- srlz.i // srlz.i implies srlz.d
- ;;
-
- // Now purge addresses formerly mapped by TR registers
- // 1. Purge ITR&DTR for kernel.
- movl r16=KERNEL_START
- mov r18=KERNEL_TR_PAGE_SHIFT<<2
- ;;
- ptr.i r16, r18
- ptr.d r16, r18
- ;;
- srlz.i
- ;;
- srlz.d
- ;;
- // 3. Purge ITR for PAL code.
- GET_THIS_PADDR(r2, ia64_mca_pal_base)
- ;;
- ld8 r16=[r2]
- mov r18=IA64_GRANULE_SHIFT<<2
- ;;
- ptr.i r16,r18
- ;;
- srlz.i
- ;;
- // 4. Purge DTR for stack.
- mov r16=IA64_KR(CURRENT_STACK)
- ;;
- shl r16=r16,IA64_GRANULE_SHIFT
- movl r19=PAGE_OFFSET
- ;;
- add r16=r19,r16
- mov r18=IA64_GRANULE_SHIFT<<2
- ;;
- ptr.d r16,r18
- ;;
- srlz.i
- ;;
- // Now branch away to caller.
- br.sptk.many b1
- ;;
-
-//EndMain//////////////////////////////////////////////////////////////////////
-
-//StartMain////////////////////////////////////////////////////////////////////
-
-ia64_os_mca_dispatch:
- mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- mov r19=1 // All MCA events are treated as monarch (for now)
- br.sptk ia64_state_save // save the state that is not in minstate
-1:
-
- GET_IA64_MCA_DATA(r2)
- // Using MCA stack, struct ia64_sal_os_state, variable proc_state_param
- ;;
- add r3=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_SOS_OFFSET+SOS(PROC_STATE_PARAM), r2
- ;;
- ld8 r18=[r3] // Get processor state parameter on existing PALE_CHECK.
- ;;
- tbit.nz p6,p7=r18,60
-(p7) br.spnt done_tlb_purge_and_reload
-
- // The following code purges TC and TR entries. Then reload all TC entries.
- // Purge percpu data TC entries.
-begin_tlb_purge_and_reload:
- movl r18=ia64_reload_tr;;
- LOAD_PHYSICAL(p0,r18,ia64_reload_tr);;
- mov b1=r18;;
- br.sptk.many ia64_do_tlb_purge;;
-
-ia64_reload_tr:
- // Finally reload the TR registers.
- // 1. Reload DTR/ITR registers for kernel.
- mov r18=KERNEL_TR_PAGE_SHIFT<<2
- movl r17=KERNEL_START
- ;;
- mov cr.itir=r18
- mov cr.ifa=r17
- mov r16=IA64_TR_KERNEL
- mov r19=ip
- movl r18=PAGE_KERNEL
- ;;
- dep r17=0,r19,0, KERNEL_TR_PAGE_SHIFT
- ;;
- or r18=r17,r18
- ;;
- itr.i itr[r16]=r18
- ;;
- itr.d dtr[r16]=r18
- ;;
- srlz.i
- srlz.d
- ;;
- // 3. Reload ITR for PAL code.
- GET_THIS_PADDR(r2, ia64_mca_pal_pte)
- ;;
- ld8 r18=[r2] // load PAL PTE
- ;;
- GET_THIS_PADDR(r2, ia64_mca_pal_base)
- ;;
- ld8 r16=[r2] // load PAL vaddr
- mov r19=IA64_GRANULE_SHIFT<<2
- ;;
- mov cr.itir=r19
- mov cr.ifa=r16
- mov r20=IA64_TR_PALCODE
- ;;
- itr.i itr[r20]=r18
- ;;
- srlz.i
- ;;
- // 4. Reload DTR for stack.
- mov r16=IA64_KR(CURRENT_STACK)
- ;;
- shl r16=r16,IA64_GRANULE_SHIFT
- movl r19=PAGE_OFFSET
- ;;
- add r18=r19,r16
- movl r20=PAGE_KERNEL
- ;;
- add r16=r20,r16
- mov r19=IA64_GRANULE_SHIFT<<2
- ;;
- mov cr.itir=r19
- mov cr.ifa=r18
- mov r20=IA64_TR_CURRENT_STACK
- ;;
- itr.d dtr[r20]=r16
- GET_THIS_PADDR(r2, ia64_mca_tr_reload)
- mov r18 = 1
- ;;
- srlz.d
- ;;
- st8 [r2] =r18
- ;;
-
-done_tlb_purge_and_reload:
-
- // switch to per cpu MCA stack
- mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- br.sptk ia64_new_stack
-1:
-
- // everything saved, now we can set the kernel registers
- mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- br.sptk ia64_set_kernel_registers
-1:
-
- // This must be done in physical mode
- GET_IA64_MCA_DATA(r2)
- ;;
- mov r7=r2
-
- // Enter virtual mode from physical mode
- VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4)
-
- // This code returns to SAL via SOS r2, in general SAL has no unwind
- // data. To get a clean termination when backtracing the C MCA/INIT
- // handler, set a dummy return address of 0 in this routine. That
- // requires that ia64_os_mca_virtual_begin be a global function.
-ENTRY(ia64_os_mca_virtual_begin)
- .prologue
- .save rp,r0
- .body
-
- mov ar.rsc=3 // set eager mode for C handler
- mov r2=r7 // see GET_IA64_MCA_DATA above
- ;;
-
- // Call virtual mode handler
- alloc r14=ar.pfs,0,0,3,0
- ;;
- DATA_PA_TO_VA(r2,r7)
- ;;
- add out0=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_PT_REGS_OFFSET, r2
- add out1=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_SWITCH_STACK_OFFSET, r2
- add out2=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_SOS_OFFSET, r2
- br.call.sptk.many b0=ia64_mca_handler
-
- // Revert back to physical mode before going back to SAL
- PHYSICAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_end, r4)
-ia64_os_mca_virtual_end:
-
-END(ia64_os_mca_virtual_begin)
-
- // switch back to previous stack
- alloc r14=ar.pfs,0,0,0,0 // remove the MCA handler frame
- mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- br.sptk ia64_old_stack
-1:
-
- mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- br.sptk ia64_state_restore // restore the SAL state
-1:
-
- mov b0=r12 // SAL_CHECK return address
-
- br b0
-
-//EndMain//////////////////////////////////////////////////////////////////////
-
-//StartMain////////////////////////////////////////////////////////////////////
-
-//
-// NOP init handler for kdump. In panic situation, we may receive INIT
-// while kernel transition. Since we initialize registers on leave from
-// current kernel, no longer monarch/slave handlers of current kernel in
-// virtual mode are called safely.
-// We can unregister these init handlers from SAL, however then the INIT
-// will result in warmboot by SAL and we cannot retrieve the crashdump.
-// Therefore register this NOP function to SAL, to prevent entering virtual
-// mode and resulting warmboot by SAL.
-//
-ia64_os_init_on_kdump:
- mov r8=r0 // IA64_INIT_RESUME
- mov r9=r10 // SAL_GP
- mov r22=r17 // *minstate
- ;;
- mov r10=r0 // return to same context
- mov b0=r12 // SAL_CHECK return address
- br b0
-
-//
-// SAL to OS entry point for INIT on all processors. This has been defined for
-// registration purposes with SAL as a part of ia64_mca_init. Monarch and
-// slave INIT have identical processing, except for the value of the
-// sos->monarch flag in r19.
-//
-
-ia64_os_init_dispatch_monarch:
- mov r19=1 // Bow, bow, ye lower middle classes!
- br.sptk ia64_os_init_dispatch
-
-ia64_os_init_dispatch_slave:
- mov r19=0 // <igor>yeth, mathter</igor>
-
-ia64_os_init_dispatch:
-
- mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- br.sptk ia64_state_save // save the state that is not in minstate
-1:
-
- // switch to per cpu INIT stack
- mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- br.sptk ia64_new_stack
-1:
-
- // everything saved, now we can set the kernel registers
- mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- br.sptk ia64_set_kernel_registers
-1:
-
- // This must be done in physical mode
- GET_IA64_MCA_DATA(r2)
- ;;
- mov r7=r2
-
- // Enter virtual mode from physical mode
- VIRTUAL_MODE_ENTER(r2, r3, ia64_os_init_virtual_begin, r4)
-
- // This code returns to SAL via SOS r2, in general SAL has no unwind
- // data. To get a clean termination when backtracing the C MCA/INIT
- // handler, set a dummy return address of 0 in this routine. That
- // requires that ia64_os_init_virtual_begin be a global function.
-ENTRY(ia64_os_init_virtual_begin)
- .prologue
- .save rp,r0
- .body
-
- mov ar.rsc=3 // set eager mode for C handler
- mov r2=r7 // see GET_IA64_MCA_DATA above
- ;;
-
- // Call virtual mode handler
- alloc r14=ar.pfs,0,0,3,0
- ;;
- DATA_PA_TO_VA(r2,r7)
- ;;
- add out0=IA64_MCA_CPU_INIT_STACK_OFFSET+MCA_PT_REGS_OFFSET, r2
- add out1=IA64_MCA_CPU_INIT_STACK_OFFSET+MCA_SWITCH_STACK_OFFSET, r2
- add out2=IA64_MCA_CPU_INIT_STACK_OFFSET+MCA_SOS_OFFSET, r2
- br.call.sptk.many b0=ia64_init_handler
-
- // Revert back to physical mode before going back to SAL
- PHYSICAL_MODE_ENTER(r2, r3, ia64_os_init_virtual_end, r4)
-ia64_os_init_virtual_end:
-
-END(ia64_os_init_virtual_begin)
-
- mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- br.sptk ia64_state_restore // restore the SAL state
-1:
-
- // switch back to previous stack
- alloc r14=ar.pfs,0,0,0,0 // remove the INIT handler frame
- mov r3=IA64_MCA_CPU_INIT_STACK_OFFSET // use the INIT stack
- LOAD_PHYSICAL(p0,r2,1f) // return address
- br.sptk ia64_old_stack
-1:
-
- mov b0=r12 // SAL_CHECK return address
- br b0
-
-//EndMain//////////////////////////////////////////////////////////////////////
-
-// common defines for the stubs
-#define ms r4
-#define regs r5
-#define temp1 r2 /* careful, it overlaps with input registers */
-#define temp2 r3 /* careful, it overlaps with input registers */
-#define temp3 r7
-#define temp4 r14
-
-
-//++
-// Name:
-// ia64_state_save()
-//
-// Stub Description:
-//
-// Save the state that is not in minstate. This is sensitive to the layout of
-// struct ia64_sal_os_state in mca.h.
-//
-// r2 contains the return address, r3 contains either
-// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
-//
-// The OS to SAL section of struct ia64_sal_os_state is set to a default
-// value of cold boot (MCA) or warm boot (INIT) and return to the same
-// context. ia64_sal_os_state is also used to hold some registers that
-// need to be saved and restored across the stack switches.
-//
-// Most input registers to this stub come from PAL/SAL
-// r1 os gp, physical
-// r8 pal_proc entry point
-// r9 sal_proc entry point
-// r10 sal gp
-// r11 MCA - rendevzous state, INIT - reason code
-// r12 sal return address
-// r17 pal min_state
-// r18 processor state parameter
-// r19 monarch flag, set by the caller of this routine
-//
-// In addition to the SAL to OS state, this routine saves all the
-// registers that appear in struct pt_regs and struct switch_stack,
-// excluding those that are already in the PAL minstate area. This
-// results in a partial pt_regs and switch_stack, the C code copies the
-// remaining registers from PAL minstate to pt_regs and switch_stack. The
-// resulting structures contain all the state of the original process when
-// MCA/INIT occurred.
-//
-//--
-
-ia64_state_save:
- add regs=MCA_SOS_OFFSET, r3
- add ms=MCA_SOS_OFFSET+8, r3
- mov b0=r2 // save return address
- cmp.eq p1,p2=IA64_MCA_CPU_MCA_STACK_OFFSET, r3
- ;;
- GET_IA64_MCA_DATA(temp2)
- ;;
- add temp1=temp2, regs // struct ia64_sal_os_state on MCA or INIT stack
- add temp2=temp2, ms // struct ia64_sal_os_state+8 on MCA or INIT stack
- ;;
- mov regs=temp1 // save the start of sos
- st8 [temp1]=r1,16 // os_gp
- st8 [temp2]=r8,16 // pal_proc
- ;;
- st8 [temp1]=r9,16 // sal_proc
- st8 [temp2]=r11,16 // rv_rc
- mov r11=cr.iipa
- ;;
- st8 [temp1]=r18 // proc_state_param
- st8 [temp2]=r19 // monarch
- mov r6=IA64_KR(CURRENT)
- add temp1=SOS(SAL_RA), regs
- add temp2=SOS(SAL_GP), regs
- ;;
- st8 [temp1]=r12,16 // sal_ra
- st8 [temp2]=r10,16 // sal_gp
- mov r12=cr.isr
- ;;
- st8 [temp1]=r17,16 // pal_min_state
- st8 [temp2]=r6,16 // prev_IA64_KR_CURRENT
- mov r6=IA64_KR(CURRENT_STACK)
- ;;
- st8 [temp1]=r6,16 // prev_IA64_KR_CURRENT_STACK
- st8 [temp2]=r0,16 // prev_task, starts off as NULL
- mov r6=cr.ifa
- ;;
- st8 [temp1]=r12,16 // cr.isr
- st8 [temp2]=r6,16 // cr.ifa
- mov r12=cr.itir
- ;;
- st8 [temp1]=r12,16 // cr.itir
- st8 [temp2]=r11,16 // cr.iipa
- mov r12=cr.iim
- ;;
- st8 [temp1]=r12 // cr.iim
-(p1) mov r12=IA64_MCA_COLD_BOOT
-(p2) mov r12=IA64_INIT_WARM_BOOT
- mov r6=cr.iha
- add temp1=SOS(OS_STATUS), regs
- ;;
- st8 [temp2]=r6 // cr.iha
- add temp2=SOS(CONTEXT), regs
- st8 [temp1]=r12 // os_status, default is cold boot
- mov r6=IA64_MCA_SAME_CONTEXT
- ;;
- st8 [temp2]=r6 // context, default is same context
-
- // Save the pt_regs data that is not in minstate. The previous code
- // left regs at sos.
- add regs=MCA_PT_REGS_OFFSET-MCA_SOS_OFFSET, regs
- ;;
- add temp1=PT(B6), regs
- mov temp3=b6
- mov temp4=b7
- add temp2=PT(B7), regs
- ;;
- st8 [temp1]=temp3,PT(AR_CSD)-PT(B6) // save b6
- st8 [temp2]=temp4,PT(AR_SSD)-PT(B7) // save b7
- mov temp3=ar.csd
- mov temp4=ar.ssd
- cover // must be last in group
- ;;
- st8 [temp1]=temp3,PT(AR_UNAT)-PT(AR_CSD) // save ar.csd
- st8 [temp2]=temp4,PT(AR_PFS)-PT(AR_SSD) // save ar.ssd
- mov temp3=ar.unat
- mov temp4=ar.pfs
- ;;
- st8 [temp1]=temp3,PT(AR_RNAT)-PT(AR_UNAT) // save ar.unat
- st8 [temp2]=temp4,PT(AR_BSPSTORE)-PT(AR_PFS) // save ar.pfs
- mov temp3=ar.rnat
- mov temp4=ar.bspstore
- ;;
- st8 [temp1]=temp3,PT(LOADRS)-PT(AR_RNAT) // save ar.rnat
- st8 [temp2]=temp4,PT(AR_FPSR)-PT(AR_BSPSTORE) // save ar.bspstore
- mov temp3=ar.bsp
- ;;
- sub temp3=temp3, temp4 // ar.bsp - ar.bspstore
- mov temp4=ar.fpsr
- ;;
- shl temp3=temp3,16 // compute ar.rsc to be used for "loadrs"
- ;;
- st8 [temp1]=temp3,PT(AR_CCV)-PT(LOADRS) // save loadrs
- st8 [temp2]=temp4,PT(F6)-PT(AR_FPSR) // save ar.fpsr
- mov temp3=ar.ccv
- ;;
- st8 [temp1]=temp3,PT(F7)-PT(AR_CCV) // save ar.ccv
- stf.spill [temp2]=f6,PT(F8)-PT(F6)
- ;;
- stf.spill [temp1]=f7,PT(F9)-PT(F7)
- stf.spill [temp2]=f8,PT(F10)-PT(F8)
- ;;
- stf.spill [temp1]=f9,PT(F11)-PT(F9)
- stf.spill [temp2]=f10
- ;;
- stf.spill [temp1]=f11
-
- // Save the switch_stack data that is not in minstate nor pt_regs. The
- // previous code left regs at pt_regs.
- add regs=MCA_SWITCH_STACK_OFFSET-MCA_PT_REGS_OFFSET, regs
- ;;
- add temp1=SW(F2), regs
- add temp2=SW(F3), regs
- ;;
- stf.spill [temp1]=f2,32
- stf.spill [temp2]=f3,32
- ;;
- stf.spill [temp1]=f4,32
- stf.spill [temp2]=f5,32
- ;;
- stf.spill [temp1]=f12,32
- stf.spill [temp2]=f13,32
- ;;
- stf.spill [temp1]=f14,32
- stf.spill [temp2]=f15,32
- ;;
- stf.spill [temp1]=f16,32
- stf.spill [temp2]=f17,32
- ;;
- stf.spill [temp1]=f18,32
- stf.spill [temp2]=f19,32
- ;;
- stf.spill [temp1]=f20,32
- stf.spill [temp2]=f21,32
- ;;
- stf.spill [temp1]=f22,32
- stf.spill [temp2]=f23,32
- ;;
- stf.spill [temp1]=f24,32
- stf.spill [temp2]=f25,32
- ;;
- stf.spill [temp1]=f26,32
- stf.spill [temp2]=f27,32
- ;;
- stf.spill [temp1]=f28,32
- stf.spill [temp2]=f29,32
- ;;
- stf.spill [temp1]=f30,SW(B2)-SW(F30)
- stf.spill [temp2]=f31,SW(B3)-SW(F31)
- mov temp3=b2
- mov temp4=b3
- ;;
- st8 [temp1]=temp3,16 // save b2
- st8 [temp2]=temp4,16 // save b3
- mov temp3=b4
- mov temp4=b5
- ;;
- st8 [temp1]=temp3,SW(AR_LC)-SW(B4) // save b4
- st8 [temp2]=temp4 // save b5
- mov temp3=ar.lc
- ;;
- st8 [temp1]=temp3 // save ar.lc
-
- // FIXME: Some proms are incorrectly accessing the minstate area as
- // cached data. The C code uses region 6, uncached virtual. Ensure
- // that there is no cache data lying around for the first 1K of the
- // minstate area.
- // Remove this code in September 2006, that gives platforms a year to
- // fix their proms and get their customers updated.
-
- add r1=32*1,r17
- add r2=32*2,r17
- add r3=32*3,r17
- add r4=32*4,r17
- add r5=32*5,r17
- add r6=32*6,r17
- add r7=32*7,r17
- ;;
- fc r17
- fc r1
- fc r2
- fc r3
- fc r4
- fc r5
- fc r6
- fc r7
- add r17=32*8,r17
- add r1=32*8,r1
- add r2=32*8,r2
- add r3=32*8,r3
- add r4=32*8,r4
- add r5=32*8,r5
- add r6=32*8,r6
- add r7=32*8,r7
- ;;
- fc r17
- fc r1
- fc r2
- fc r3
- fc r4
- fc r5
- fc r6
- fc r7
- add r17=32*8,r17
- add r1=32*8,r1
- add r2=32*8,r2
- add r3=32*8,r3
- add r4=32*8,r4
- add r5=32*8,r5
- add r6=32*8,r6
- add r7=32*8,r7
- ;;
- fc r17
- fc r1
- fc r2
- fc r3
- fc r4
- fc r5
- fc r6
- fc r7
- add r17=32*8,r17
- add r1=32*8,r1
- add r2=32*8,r2
- add r3=32*8,r3
- add r4=32*8,r4
- add r5=32*8,r5
- add r6=32*8,r6
- add r7=32*8,r7
- ;;
- fc r17
- fc r1
- fc r2
- fc r3
- fc r4
- fc r5
- fc r6
- fc r7
-
- br.sptk b0
-
-//EndStub//////////////////////////////////////////////////////////////////////
-
-
-//++
-// Name:
-// ia64_state_restore()
-//
-// Stub Description:
-//
-// Restore the SAL/OS state. This is sensitive to the layout of struct
-// ia64_sal_os_state in mca.h.
-//
-// r2 contains the return address, r3 contains either
-// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
-//
-// In addition to the SAL to OS state, this routine restores all the
-// registers that appear in struct pt_regs and struct switch_stack,
-// excluding those in the PAL minstate area.
-//
-//--
-
-ia64_state_restore:
- // Restore the switch_stack data that is not in minstate nor pt_regs.
- add regs=MCA_SWITCH_STACK_OFFSET, r3
- mov b0=r2 // save return address
- ;;
- GET_IA64_MCA_DATA(temp2)
- ;;
- add regs=temp2, regs
- ;;
- add temp1=SW(F2), regs
- add temp2=SW(F3), regs
- ;;
- ldf.fill f2=[temp1],32
- ldf.fill f3=[temp2],32
- ;;
- ldf.fill f4=[temp1],32
- ldf.fill f5=[temp2],32
- ;;
- ldf.fill f12=[temp1],32
- ldf.fill f13=[temp2],32
- ;;
- ldf.fill f14=[temp1],32
- ldf.fill f15=[temp2],32
- ;;
- ldf.fill f16=[temp1],32
- ldf.fill f17=[temp2],32
- ;;
- ldf.fill f18=[temp1],32
- ldf.fill f19=[temp2],32
- ;;
- ldf.fill f20=[temp1],32
- ldf.fill f21=[temp2],32
- ;;
- ldf.fill f22=[temp1],32
- ldf.fill f23=[temp2],32
- ;;
- ldf.fill f24=[temp1],32
- ldf.fill f25=[temp2],32
- ;;
- ldf.fill f26=[temp1],32
- ldf.fill f27=[temp2],32
- ;;
- ldf.fill f28=[temp1],32
- ldf.fill f29=[temp2],32
- ;;
- ldf.fill f30=[temp1],SW(B2)-SW(F30)
- ldf.fill f31=[temp2],SW(B3)-SW(F31)
- ;;
- ld8 temp3=[temp1],16 // restore b2
- ld8 temp4=[temp2],16 // restore b3
- ;;
- mov b2=temp3
- mov b3=temp4
- ld8 temp3=[temp1],SW(AR_LC)-SW(B4) // restore b4
- ld8 temp4=[temp2] // restore b5
- ;;
- mov b4=temp3
- mov b5=temp4
- ld8 temp3=[temp1] // restore ar.lc
- ;;
- mov ar.lc=temp3
-
- // Restore the pt_regs data that is not in minstate. The previous code
- // left regs at switch_stack.
- add regs=MCA_PT_REGS_OFFSET-MCA_SWITCH_STACK_OFFSET, regs
- ;;
- add temp1=PT(B6), regs
- add temp2=PT(B7), regs
- ;;
- ld8 temp3=[temp1],PT(AR_CSD)-PT(B6) // restore b6
- ld8 temp4=[temp2],PT(AR_SSD)-PT(B7) // restore b7
- ;;
- mov b6=temp3
- mov b7=temp4
- ld8 temp3=[temp1],PT(AR_UNAT)-PT(AR_CSD) // restore ar.csd
- ld8 temp4=[temp2],PT(AR_PFS)-PT(AR_SSD) // restore ar.ssd
- ;;
- mov ar.csd=temp3
- mov ar.ssd=temp4
- ld8 temp3=[temp1] // restore ar.unat
- add temp1=PT(AR_CCV)-PT(AR_UNAT), temp1
- ld8 temp4=[temp2],PT(AR_FPSR)-PT(AR_PFS) // restore ar.pfs
- ;;
- mov ar.unat=temp3
- mov ar.pfs=temp4
- // ar.rnat, ar.bspstore, loadrs are restore in ia64_old_stack.
- ld8 temp3=[temp1],PT(F6)-PT(AR_CCV) // restore ar.ccv
- ld8 temp4=[temp2],PT(F7)-PT(AR_FPSR) // restore ar.fpsr
- ;;
- mov ar.ccv=temp3
- mov ar.fpsr=temp4
- ldf.fill f6=[temp1],PT(F8)-PT(F6)
- ldf.fill f7=[temp2],PT(F9)-PT(F7)
- ;;
- ldf.fill f8=[temp1],PT(F10)-PT(F8)
- ldf.fill f9=[temp2],PT(F11)-PT(F9)
- ;;
- ldf.fill f10=[temp1]
- ldf.fill f11=[temp2]
-
- // Restore the SAL to OS state. The previous code left regs at pt_regs.
- add regs=MCA_SOS_OFFSET-MCA_PT_REGS_OFFSET, regs
- ;;
- add temp1=SOS(SAL_RA), regs
- add temp2=SOS(SAL_GP), regs
- ;;
- ld8 r12=[temp1],16 // sal_ra
- ld8 r9=[temp2],16 // sal_gp
- ;;
- ld8 r22=[temp1],16 // pal_min_state, virtual
- ld8 r13=[temp2],16 // prev_IA64_KR_CURRENT
- ;;
- ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK
- ld8 r20=[temp2],16 // prev_task
- ;;
- ld8 temp3=[temp1],16 // cr.isr
- ld8 temp4=[temp2],16 // cr.ifa
- ;;
- mov cr.isr=temp3
- mov cr.ifa=temp4
- ld8 temp3=[temp1],16 // cr.itir
- ld8 temp4=[temp2],16 // cr.iipa
- ;;
- mov cr.itir=temp3
- mov cr.iipa=temp4
- ld8 temp3=[temp1] // cr.iim
- ld8 temp4=[temp2] // cr.iha
- add temp1=SOS(OS_STATUS), regs
- add temp2=SOS(CONTEXT), regs
- ;;
- mov cr.iim=temp3
- mov cr.iha=temp4
- dep r22=0,r22,62,1 // pal_min_state, physical, uncached
- mov IA64_KR(CURRENT)=r13
- ld8 r8=[temp1] // os_status
- ld8 r10=[temp2] // context
-
- /* Wire IA64_TR_CURRENT_STACK to the stack that we are resuming to. To
- * avoid any dependencies on the algorithm in ia64_switch_to(), just
- * purge any existing CURRENT_STACK mapping and insert the new one.
- *
- * r16 contains prev_IA64_KR_CURRENT_STACK, r13 contains
- * prev_IA64_KR_CURRENT, these values may have been changed by the C
- * code. Do not use r8, r9, r10, r22, they contain values ready for
- * the return to SAL.
- */
-
- mov r15=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
- ;;
- shl r15=r15,IA64_GRANULE_SHIFT
- ;;
- dep r15=-1,r15,61,3 // virtual granule
- mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
- ;;
- ptr.d r15,r18
- ;;
- srlz.d
-
- extr.u r19=r13,61,3 // r13 = prev_IA64_KR_CURRENT
- shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK
- movl r21=PAGE_KERNEL // page properties
- ;;
- mov IA64_KR(CURRENT_STACK)=r16
- cmp.ne p6,p0=RGN_KERNEL,r19 // new stack is in the kernel region?
- or r21=r20,r21 // construct PA | page properties
-(p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:(
- ;;
- mov cr.itir=r18
- mov cr.ifa=r13
- mov r20=IA64_TR_CURRENT_STACK
- ;;
- itr.d dtr[r20]=r21
- ;;
- srlz.d
-1:
-
- br.sptk b0
-
-//EndStub//////////////////////////////////////////////////////////////////////
-
-
-//++
-// Name:
-// ia64_new_stack()
-//
-// Stub Description:
-//
-// Switch to the MCA/INIT stack.
-//
-// r2 contains the return address, r3 contains either
-// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
-//
-// On entry RBS is still on the original stack, this routine switches RBS
-// to use the MCA/INIT stack.
-//
-// On entry, sos->pal_min_state is physical, on exit it is virtual.
-//
-//--
-
-ia64_new_stack:
- add regs=MCA_PT_REGS_OFFSET, r3
- add temp2=MCA_SOS_OFFSET+SOS(PAL_MIN_STATE), r3
- mov b0=r2 // save return address
- GET_IA64_MCA_DATA(temp1)
- invala
- ;;
- add temp2=temp2, temp1 // struct ia64_sal_os_state.pal_min_state on MCA or INIT stack
- add regs=regs, temp1 // struct pt_regs on MCA or INIT stack
- ;;
- // Address of minstate area provided by PAL is physical, uncacheable.
- // Convert to Linux virtual address in region 6 for C code.
- ld8 ms=[temp2] // pal_min_state, physical
- ;;
- dep temp1=-1,ms,62,2 // set region 6
- mov temp3=IA64_RBS_OFFSET-MCA_PT_REGS_OFFSET
- ;;
- st8 [temp2]=temp1 // pal_min_state, virtual
-
- add temp4=temp3, regs // start of bspstore on new stack
- ;;
- mov ar.bspstore=temp4 // switch RBS to MCA/INIT stack
- ;;
- flushrs // must be first in group
- br.sptk b0
-
-//EndStub//////////////////////////////////////////////////////////////////////
-
-
-//++
-// Name:
-// ia64_old_stack()
-//
-// Stub Description:
-//
-// Switch to the old stack.
-//
-// r2 contains the return address, r3 contains either
-// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
-//
-// On entry, pal_min_state is virtual, on exit it is physical.
-//
-// On entry RBS is on the MCA/INIT stack, this routine switches RBS
-// back to the previous stack.
-//
-// The psr is set to all zeroes. SAL return requires either all zeroes or
-// just psr.mc set. Leaving psr.mc off allows INIT to be issued if this
-// code does not perform correctly.
-//
-// The dirty registers at the time of the event were flushed to the
-// MCA/INIT stack in ia64_pt_regs_save(). Restore the dirty registers
-// before reverting to the previous bspstore.
-//--
-
-ia64_old_stack:
- add regs=MCA_PT_REGS_OFFSET, r3
- mov b0=r2 // save return address
- GET_IA64_MCA_DATA(temp2)
- LOAD_PHYSICAL(p0,temp1,1f)
- ;;
- mov cr.ipsr=r0
- mov cr.ifs=r0
- mov cr.iip=temp1
- ;;
- invala
- rfi
-1:
-
- add regs=regs, temp2 // struct pt_regs on MCA or INIT stack
- ;;
- add temp1=PT(LOADRS), regs
- ;;
- ld8 temp2=[temp1],PT(AR_BSPSTORE)-PT(LOADRS) // restore loadrs
- ;;
- ld8 temp3=[temp1],PT(AR_RNAT)-PT(AR_BSPSTORE) // restore ar.bspstore
- mov ar.rsc=temp2
- ;;
- loadrs
- ld8 temp4=[temp1] // restore ar.rnat
- ;;
- mov ar.bspstore=temp3 // back to old stack
- ;;
- mov ar.rnat=temp4
- ;;
-
- br.sptk b0
-
-//EndStub//////////////////////////////////////////////////////////////////////
-
-
-//++
-// Name:
-// ia64_set_kernel_registers()
-//
-// Stub Description:
-//
-// Set the registers that are required by the C code in order to run on an
-// MCA/INIT stack.
-//
-// r2 contains the return address, r3 contains either
-// IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.
-//
-//--
-
-ia64_set_kernel_registers:
- add temp3=MCA_SP_OFFSET, r3
- mov b0=r2 // save return address
- GET_IA64_MCA_DATA(temp1)
- ;;
- add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack
- add r13=temp1, r3 // set current to start of MCA/INIT stack
- add r20=temp1, r3 // physical start of MCA/INIT stack
- ;;
- DATA_PA_TO_VA(r12,temp2)
- DATA_PA_TO_VA(r13,temp3)
- ;;
- mov IA64_KR(CURRENT)=r13
-
- /* Wire IA64_TR_CURRENT_STACK to the MCA/INIT handler stack. To avoid
- * any dependencies on the algorithm in ia64_switch_to(), just purge
- * any existing CURRENT_STACK mapping and insert the new one.
- */
-
- mov r16=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
- ;;
- shl r16=r16,IA64_GRANULE_SHIFT
- ;;
- dep r16=-1,r16,61,3 // virtual granule
- mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
- ;;
- ptr.d r16,r18
- ;;
- srlz.d
-
- shr.u r16=r20,IA64_GRANULE_SHIFT // r20 = physical start of MCA/INIT stack
- movl r21=PAGE_KERNEL // page properties
- ;;
- mov IA64_KR(CURRENT_STACK)=r16
- or r21=r20,r21 // construct PA | page properties
- ;;
- mov cr.itir=r18
- mov cr.ifa=r13
- mov r20=IA64_TR_CURRENT_STACK
-
- movl r17=FPSR_DEFAULT
- ;;
- mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value
- ;;
- itr.d dtr[r20]=r21
- ;;
- srlz.d
-
- br.sptk b0
-
-//EndStub//////////////////////////////////////////////////////////////////////
-
-#undef ms
-#undef regs
-#undef temp1
-#undef temp2
-#undef temp3
-#undef temp4
-
-
-// Support function for mca.c, it is here to avoid using inline asm. Given the
-// address of an rnat slot, if that address is below the current ar.bspstore
-// then return the contents of that slot, otherwise return the contents of
-// ar.rnat.
-GLOBAL_ENTRY(ia64_get_rnat)
- alloc r14=ar.pfs,1,0,0,0
- mov ar.rsc=0
- ;;
- mov r14=ar.bspstore
- ;;
- cmp.lt p6,p7=in0,r14
- ;;
-(p6) ld8 r8=[in0]
-(p7) mov r8=ar.rnat
- mov ar.rsc=3
- br.ret.sptk.many rp
-END(ia64_get_rnat)
-
-
-// void ia64_set_psr_mc(void)
-//
-// Set psr.mc bit to mask MCA/INIT.
-GLOBAL_ENTRY(ia64_set_psr_mc)
- rsm psr.i | psr.ic // disable interrupts
- ;;
- srlz.d
- ;;
- mov r14 = psr // get psr{36:35,31:0}
- movl r15 = 1f
- ;;
- dep r14 = -1, r14, PSR_MC, 1 // set psr.mc
- ;;
- dep r14 = -1, r14, PSR_IC, 1 // set psr.ic
- ;;
- dep r14 = -1, r14, PSR_BN, 1 // keep bank1 in use
- ;;
- mov cr.ipsr = r14
- mov cr.ifs = r0
- mov cr.iip = r15
- ;;
- rfi
-1:
- br.ret.sptk.many rp
-END(ia64_set_psr_mc)
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
deleted file mode 100644
index 23c203639a96..000000000000
--- a/arch/ia64/kernel/mca_drv.c
+++ /dev/null
@@ -1,796 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * File: mca_drv.c
- * Purpose: Generic MCA handling layer
- *
- * Copyright (C) 2004 FUJITSU LIMITED
- * Copyright (C) 2004 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
- * Copyright (C) 2005 Silicon Graphics, Inc
- * Copyright (C) 2005 Keith Owens <kaos@sgi.com>
- * Copyright (C) 2006 Russ Anderson <rja@sgi.com>
- */
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kallsyms.h>
-#include <linux/memblock.h>
-#include <linux/acpi.h>
-#include <linux/timer.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/workqueue.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-
-#include <asm/delay.h>
-#include <asm/page.h>
-#include <asm/ptrace.h>
-#include <asm/sal.h>
-#include <asm/mca.h>
-
-#include <asm/irq.h>
-#include <asm/hw_irq.h>
-
-#include "mca_drv.h"
-
-/* max size of SAL error record (default) */
-static int sal_rec_max = 10000;
-
-/* from mca_drv_asm.S */
-extern void *mca_handler_bhhook(void);
-
-static DEFINE_SPINLOCK(mca_bh_lock);
-
-typedef enum {
- MCA_IS_LOCAL = 0,
- MCA_IS_GLOBAL = 1
-} mca_type_t;
-
-#define MAX_PAGE_ISOLATE 1024
-
-static struct page *page_isolate[MAX_PAGE_ISOLATE];
-static int num_page_isolate = 0;
-
-typedef enum {
- ISOLATE_NG,
- ISOLATE_OK,
- ISOLATE_NONE
-} isolate_status_t;
-
-typedef enum {
- MCA_NOT_RECOVERED = 0,
- MCA_RECOVERED = 1
-} recovery_status_t;
-
-/*
- * This pool keeps pointers to the section part of SAL error record
- */
-static struct {
- slidx_list_t *buffer; /* section pointer list pool */
- int cur_idx; /* Current index of section pointer list pool */
- int max_idx; /* Maximum index of section pointer list pool */
-} slidx_pool;
-
-static int
-fatal_mca(const char *fmt, ...)
-{
- va_list args;
- char buf[256];
-
- va_start(args, fmt);
- vsnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
- ia64_mca_printk(KERN_ALERT "MCA: %s\n", buf);
-
- return MCA_NOT_RECOVERED;
-}
-
-static int
-mca_recovered(const char *fmt, ...)
-{
- va_list args;
- char buf[256];
-
- va_start(args, fmt);
- vsnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
- ia64_mca_printk(KERN_INFO "MCA: %s\n", buf);
-
- return MCA_RECOVERED;
-}
-
-/**
- * mca_page_isolate - isolate a poisoned page in order not to use it later
- * @paddr: poisoned memory location
- *
- * Return value:
- * one of isolate_status_t, ISOLATE_OK/NG/NONE.
- */
-
-static isolate_status_t
-mca_page_isolate(unsigned long paddr)
-{
- int i;
- struct page *p;
-
- /* whether physical address is valid or not */
- if (!ia64_phys_addr_valid(paddr))
- return ISOLATE_NONE;
-
- if (!pfn_valid(paddr >> PAGE_SHIFT))
- return ISOLATE_NONE;
-
- /* convert physical address to physical page number */
- p = pfn_to_page(paddr>>PAGE_SHIFT);
-
- /* check whether a page number have been already registered or not */
- for (i = 0; i < num_page_isolate; i++)
- if (page_isolate[i] == p)
- return ISOLATE_OK; /* already listed */
-
- /* limitation check */
- if (num_page_isolate == MAX_PAGE_ISOLATE)
- return ISOLATE_NG;
-
- /* kick pages having attribute 'SLAB' or 'Reserved' */
- if (PageSlab(p) || PageReserved(p))
- return ISOLATE_NG;
-
- /* add attribute 'Reserved' and register the page */
- get_page(p);
- SetPageReserved(p);
- page_isolate[num_page_isolate++] = p;
-
- return ISOLATE_OK;
-}
-
-/**
- * mca_hanlder_bh - Kill the process which occurred memory read error
- * @paddr: poisoned address received from MCA Handler
- */
-
-void
-mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr)
-{
- ia64_mlogbuf_dump();
- printk(KERN_ERR "OS_MCA: process [cpu %d, pid: %d, uid: %d, "
- "iip: %p, psr: 0x%lx,paddr: 0x%lx](%s) encounters MCA.\n",
- raw_smp_processor_id(), current->pid,
- from_kuid(&init_user_ns, current_uid()),
- iip, ipsr, paddr, current->comm);
-
- spin_lock(&mca_bh_lock);
- switch (mca_page_isolate(paddr)) {
- case ISOLATE_OK:
- printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr);
- break;
- case ISOLATE_NG:
- printk(KERN_CRIT "Page isolation: ( %lx ) failure.\n", paddr);
- break;
- default:
- break;
- }
- spin_unlock(&mca_bh_lock);
-
- /* This process is about to be killed itself */
- make_task_dead(SIGKILL);
-}
-
-/**
- * mca_make_peidx - Make index of processor error section
- * @slpi: pointer to record of processor error section
- * @peidx: pointer to index of processor error section
- */
-
-static void
-mca_make_peidx(sal_log_processor_info_t *slpi, peidx_table_t *peidx)
-{
- /*
- * calculate the start address of
- * "struct cpuid_info" and "sal_processor_static_info_t".
- */
- u64 total_check_num = slpi->valid.num_cache_check
- + slpi->valid.num_tlb_check
- + slpi->valid.num_bus_check
- + slpi->valid.num_reg_file_check
- + slpi->valid.num_ms_check;
- u64 head_size = sizeof(sal_log_mod_error_info_t) * total_check_num
- + sizeof(sal_log_processor_info_t);
- u64 mid_size = slpi->valid.cpuid_info * sizeof(struct sal_cpuid_info);
-
- peidx_head(peidx) = slpi;
- peidx_mid(peidx) = (struct sal_cpuid_info *)
- (slpi->valid.cpuid_info ? ((char*)slpi + head_size) : NULL);
- peidx_bottom(peidx) = (sal_processor_static_info_t *)
- (slpi->valid.psi_static_struct ?
- ((char*)slpi + head_size + mid_size) : NULL);
-}
-
-/**
- * mca_make_slidx - Make index of SAL error record
- * @buffer: pointer to SAL error record
- * @slidx: pointer to index of SAL error record
- *
- * Return value:
- * 1 if record has platform error / 0 if not
- */
-#define LOG_INDEX_ADD_SECT_PTR(sect, ptr) \
- {slidx_list_t *hl = &slidx_pool.buffer[slidx_pool.cur_idx]; \
- hl->hdr = ptr; \
- list_add(&hl->list, &(sect)); \
- slidx_pool.cur_idx = (slidx_pool.cur_idx + 1)%slidx_pool.max_idx; }
-
-static int
-mca_make_slidx(void *buffer, slidx_table_t *slidx)
-{
- int platform_err = 0;
- int record_len = ((sal_log_record_header_t*)buffer)->len;
- u32 ercd_pos;
- int sects;
- sal_log_section_hdr_t *sp;
-
- /*
- * Initialize index referring current record
- */
- INIT_LIST_HEAD(&(slidx->proc_err));
- INIT_LIST_HEAD(&(slidx->mem_dev_err));
- INIT_LIST_HEAD(&(slidx->sel_dev_err));
- INIT_LIST_HEAD(&(slidx->pci_bus_err));
- INIT_LIST_HEAD(&(slidx->smbios_dev_err));
- INIT_LIST_HEAD(&(slidx->pci_comp_err));
- INIT_LIST_HEAD(&(slidx->plat_specific_err));
- INIT_LIST_HEAD(&(slidx->host_ctlr_err));
- INIT_LIST_HEAD(&(slidx->plat_bus_err));
- INIT_LIST_HEAD(&(slidx->unsupported));
-
- /*
- * Extract a Record Header
- */
- slidx->header = buffer;
-
- /*
- * Extract each section records
- * (arranged from "int ia64_log_platform_info_print()")
- */
- for (ercd_pos = sizeof(sal_log_record_header_t), sects = 0;
- ercd_pos < record_len; ercd_pos += sp->len, sects++) {
- sp = (sal_log_section_hdr_t *)((char*)buffer + ercd_pos);
- if (!efi_guidcmp(sp->guid, SAL_PROC_DEV_ERR_SECT_GUID)) {
- LOG_INDEX_ADD_SECT_PTR(slidx->proc_err, sp);
- } else if (!efi_guidcmp(sp->guid,
- SAL_PLAT_MEM_DEV_ERR_SECT_GUID)) {
- platform_err = 1;
- LOG_INDEX_ADD_SECT_PTR(slidx->mem_dev_err, sp);
- } else if (!efi_guidcmp(sp->guid,
- SAL_PLAT_SEL_DEV_ERR_SECT_GUID)) {
- platform_err = 1;
- LOG_INDEX_ADD_SECT_PTR(slidx->sel_dev_err, sp);
- } else if (!efi_guidcmp(sp->guid,
- SAL_PLAT_PCI_BUS_ERR_SECT_GUID)) {
- platform_err = 1;
- LOG_INDEX_ADD_SECT_PTR(slidx->pci_bus_err, sp);
- } else if (!efi_guidcmp(sp->guid,
- SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID)) {
- platform_err = 1;
- LOG_INDEX_ADD_SECT_PTR(slidx->smbios_dev_err, sp);
- } else if (!efi_guidcmp(sp->guid,
- SAL_PLAT_PCI_COMP_ERR_SECT_GUID)) {
- platform_err = 1;
- LOG_INDEX_ADD_SECT_PTR(slidx->pci_comp_err, sp);
- } else if (!efi_guidcmp(sp->guid,
- SAL_PLAT_SPECIFIC_ERR_SECT_GUID)) {
- platform_err = 1;
- LOG_INDEX_ADD_SECT_PTR(slidx->plat_specific_err, sp);
- } else if (!efi_guidcmp(sp->guid,
- SAL_PLAT_HOST_CTLR_ERR_SECT_GUID)) {
- platform_err = 1;
- LOG_INDEX_ADD_SECT_PTR(slidx->host_ctlr_err, sp);
- } else if (!efi_guidcmp(sp->guid,
- SAL_PLAT_BUS_ERR_SECT_GUID)) {
- platform_err = 1;
- LOG_INDEX_ADD_SECT_PTR(slidx->plat_bus_err, sp);
- } else {
- LOG_INDEX_ADD_SECT_PTR(slidx->unsupported, sp);
- }
- }
- slidx->n_sections = sects;
-
- return platform_err;
-}
-
-/**
- * init_record_index_pools - Initialize pool of lists for SAL record index
- *
- * Return value:
- * 0 on Success / -ENOMEM on Failure
- */
-static int
-init_record_index_pools(void)
-{
- int i;
- int rec_max_size; /* Maximum size of SAL error records */
- int sect_min_size; /* Minimum size of SAL error sections */
- /* minimum size table of each section */
- static int sal_log_sect_min_sizes[] = {
- sizeof(sal_log_processor_info_t)
- + sizeof(sal_processor_static_info_t),
- sizeof(sal_log_mem_dev_err_info_t),
- sizeof(sal_log_sel_dev_err_info_t),
- sizeof(sal_log_pci_bus_err_info_t),
- sizeof(sal_log_smbios_dev_err_info_t),
- sizeof(sal_log_pci_comp_err_info_t),
- sizeof(sal_log_plat_specific_err_info_t),
- sizeof(sal_log_host_ctlr_err_info_t),
- sizeof(sal_log_plat_bus_err_info_t),
- };
-
- /*
- * MCA handler cannot allocate new memory on flight,
- * so we preallocate enough memory to handle a SAL record.
- *
- * Initialize a handling set of slidx_pool:
- * 1. Pick up the max size of SAL error records
- * 2. Pick up the min size of SAL error sections
- * 3. Allocate the pool as enough to 2 SAL records
- * (now we can estimate the maxinum of section in a record.)
- */
-
- /* - 1 - */
- rec_max_size = sal_rec_max;
-
- /* - 2 - */
- sect_min_size = sal_log_sect_min_sizes[0];
- for (i = 1; i < ARRAY_SIZE(sal_log_sect_min_sizes); i++)
- if (sect_min_size > sal_log_sect_min_sizes[i])
- sect_min_size = sal_log_sect_min_sizes[i];
-
- /* - 3 - */
- slidx_pool.max_idx = (rec_max_size/sect_min_size) * 2 + 1;
- slidx_pool.buffer =
- kmalloc_array(slidx_pool.max_idx, sizeof(slidx_list_t),
- GFP_KERNEL);
-
- return slidx_pool.buffer ? 0 : -ENOMEM;
-}
-
-
-/*****************************************************************************
- * Recovery functions *
- *****************************************************************************/
-
-/**
- * is_mca_global - Check whether this MCA is global or not
- * @peidx: pointer of index of processor error section
- * @pbci: pointer to pal_bus_check_info_t
- * @sos: pointer to hand off struct between SAL and OS
- *
- * Return value:
- * MCA_IS_LOCAL / MCA_IS_GLOBAL
- */
-
-static mca_type_t
-is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci,
- struct ia64_sal_os_state *sos)
-{
- pal_processor_state_info_t *psp =
- (pal_processor_state_info_t*)peidx_psp(peidx);
-
- /*
- * PAL can request a rendezvous, if the MCA has a global scope.
- * If "rz_always" flag is set, SAL requests MCA rendezvous
- * in spite of global MCA.
- * Therefore it is local MCA when rendezvous has not been requested.
- * Failed to rendezvous, the system must be down.
- */
- switch (sos->rv_rc) {
- case -1: /* SAL rendezvous unsuccessful */
- return MCA_IS_GLOBAL;
- case 0: /* SAL rendezvous not required */
- return MCA_IS_LOCAL;
- case 1: /* SAL rendezvous successful int */
- case 2: /* SAL rendezvous successful int with init */
- default:
- break;
- }
-
- /*
- * If One or more Cache/TLB/Reg_File/Uarch_Check is here,
- * it would be a local MCA. (i.e. processor internal error)
- */
- if (psp->tc || psp->cc || psp->rc || psp->uc)
- return MCA_IS_LOCAL;
-
- /*
- * Bus_Check structure with Bus_Check.ib (internal bus error) flag set
- * would be a global MCA. (e.g. a system bus address parity error)
- */
- if (!pbci || pbci->ib)
- return MCA_IS_GLOBAL;
-
- /*
- * Bus_Check structure with Bus_Check.eb (external bus error) flag set
- * could be either a local MCA or a global MCA.
- *
- * Referring Bus_Check.bsi:
- * 0: Unknown/unclassified
- * 1: BERR#
- * 2: BINIT#
- * 3: Hard Fail
- * (FIXME: Are these SGI specific or generic bsi values?)
- */
- if (pbci->eb)
- switch (pbci->bsi) {
- case 0:
- /* e.g. a load from poisoned memory */
- return MCA_IS_LOCAL;
- case 1:
- case 2:
- case 3:
- return MCA_IS_GLOBAL;
- }
-
- return MCA_IS_GLOBAL;
-}
-
-/**
- * get_target_identifier - Get the valid Cache or Bus check target identifier.
- * @peidx: pointer of index of processor error section
- *
- * Return value:
- * target address on Success / 0 on Failure
- */
-static u64
-get_target_identifier(peidx_table_t *peidx)
-{
- u64 target_address = 0;
- sal_log_mod_error_info_t *smei;
- pal_cache_check_info_t *pcci;
- int i, level = 9;
-
- /*
- * Look through the cache checks for a valid target identifier
- * If more than one valid target identifier, return the one
- * with the lowest cache level.
- */
- for (i = 0; i < peidx_cache_check_num(peidx); i++) {
- smei = (sal_log_mod_error_info_t *)peidx_cache_check(peidx, i);
- if (smei->valid.target_identifier && smei->target_identifier) {
- pcci = (pal_cache_check_info_t *)&(smei->check_info);
- if (!target_address || (pcci->level < level)) {
- target_address = smei->target_identifier;
- level = pcci->level;
- continue;
- }
- }
- }
- if (target_address)
- return target_address;
-
- /*
- * Look at the bus check for a valid target identifier
- */
- smei = peidx_bus_check(peidx, 0);
- if (smei && smei->valid.target_identifier)
- return smei->target_identifier;
-
- return 0;
-}
-
-/**
- * recover_from_read_error - Try to recover the errors which type are "read"s.
- * @slidx: pointer of index of SAL error record
- * @peidx: pointer of index of processor error section
- * @pbci: pointer of pal_bus_check_info
- * @sos: pointer to hand off struct between SAL and OS
- *
- * Return value:
- * 1 on Success / 0 on Failure
- */
-
-static int
-recover_from_read_error(slidx_table_t *slidx,
- peidx_table_t *peidx, pal_bus_check_info_t *pbci,
- struct ia64_sal_os_state *sos)
-{
- u64 target_identifier;
- struct pal_min_state_area *pmsa;
- struct ia64_psr *psr1, *psr2;
- ia64_fptr_t *mca_hdlr_bh = (ia64_fptr_t*)mca_handler_bhhook;
-
- /* Is target address valid? */
- target_identifier = get_target_identifier(peidx);
- if (!target_identifier)
- return fatal_mca("target address not valid");
-
- /*
- * cpu read or memory-mapped io read
- *
- * offending process affected process OS MCA do
- * kernel mode kernel mode down system
- * kernel mode user mode kill the process
- * user mode kernel mode down system (*)
- * user mode user mode kill the process
- *
- * (*) You could terminate offending user-mode process
- * if (pbci->pv && pbci->pl != 0) *and* if you sure
- * the process not have any locks of kernel.
- */
-
- /* Is minstate valid? */
- if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate))
- return fatal_mca("minstate not valid");
- psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr);
- psr2 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_xpsr);
-
- /*
- * Check the privilege level of interrupted context.
- * If it is user-mode, then terminate affected process.
- */
-
- pmsa = sos->pal_min_state;
- if (psr1->cpl != 0 ||
- ((psr2->cpl != 0) && mca_recover_range(pmsa->pmsa_iip))) {
- /*
- * setup for resume to bottom half of MCA,
- * "mca_handler_bhhook"
- */
- /* pass to bhhook as argument (gr8, ...) */
- pmsa->pmsa_gr[8-1] = target_identifier;
- pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip;
- pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr;
- /* set interrupted return address (but no use) */
- pmsa->pmsa_br0 = pmsa->pmsa_iip;
- /* change resume address to bottom half */
- pmsa->pmsa_iip = mca_hdlr_bh->fp;
- pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp;
- /* set cpl with kernel mode */
- psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
- psr2->cpl = 0;
- psr2->ri = 0;
- psr2->bn = 1;
- psr2->i = 0;
-
- return mca_recovered("user memory corruption. "
- "kill affected process - recovered.");
- }
-
- return fatal_mca("kernel context not recovered, iip 0x%lx\n",
- pmsa->pmsa_iip);
-}
-
-/**
- * recover_from_platform_error - Recover from platform error.
- * @slidx: pointer of index of SAL error record
- * @peidx: pointer of index of processor error section
- * @pbci: pointer of pal_bus_check_info
- * @sos: pointer to hand off struct between SAL and OS
- *
- * Return value:
- * 1 on Success / 0 on Failure
- */
-
-static int
-recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx,
- pal_bus_check_info_t *pbci,
- struct ia64_sal_os_state *sos)
-{
- int status = 0;
- pal_processor_state_info_t *psp =
- (pal_processor_state_info_t*)peidx_psp(peidx);
-
- if (psp->bc && pbci->eb && pbci->bsi == 0) {
- switch(pbci->type) {
- case 1: /* partial read */
- case 3: /* full line(cpu) read */
- case 9: /* I/O space read */
- status = recover_from_read_error(slidx, peidx, pbci,
- sos);
- break;
- case 0: /* unknown */
- case 2: /* partial write */
- case 4: /* full line write */
- case 5: /* implicit or explicit write-back operation */
- case 6: /* snoop probe */
- case 7: /* incoming or outgoing ptc.g */
- case 8: /* write coalescing transactions */
- case 10: /* I/O space write */
- case 11: /* inter-processor interrupt message(IPI) */
- case 12: /* interrupt acknowledge or
- external task priority cycle */
- default:
- break;
- }
- } else if (psp->cc && !psp->bc) { /* Cache error */
- status = recover_from_read_error(slidx, peidx, pbci, sos);
- }
-
- return status;
-}
-
-/*
- * recover_from_tlb_check
- * @peidx: pointer of index of processor error section
- *
- * Return value:
- * 1 on Success / 0 on Failure
- */
-static int
-recover_from_tlb_check(peidx_table_t *peidx)
-{
- sal_log_mod_error_info_t *smei;
- pal_tlb_check_info_t *ptci;
-
- smei = (sal_log_mod_error_info_t *)peidx_tlb_check(peidx, 0);
- ptci = (pal_tlb_check_info_t *)&(smei->check_info);
-
- /*
- * Look for signature of a duplicate TLB DTC entry, which is
- * a SW bug and always fatal.
- */
- if (ptci->op == PAL_TLB_CHECK_OP_PURGE
- && !(ptci->itr || ptci->dtc || ptci->itc))
- return fatal_mca("Duplicate TLB entry");
-
- return mca_recovered("TLB check recovered");
-}
-
-/**
- * recover_from_processor_error
- * @platform: whether there are some platform error section or not
- * @slidx: pointer of index of SAL error record
- * @peidx: pointer of index of processor error section
- * @pbci: pointer of pal_bus_check_info
- * @sos: pointer to hand off struct between SAL and OS
- *
- * Return value:
- * 1 on Success / 0 on Failure
- */
-
-static int
-recover_from_processor_error(int platform, slidx_table_t *slidx,
- peidx_table_t *peidx, pal_bus_check_info_t *pbci,
- struct ia64_sal_os_state *sos)
-{
- pal_processor_state_info_t *psp =
- (pal_processor_state_info_t*)peidx_psp(peidx);
-
- /*
- * Processor recovery status must key off of the PAL recovery
- * status in the Processor State Parameter.
- */
-
- /*
- * The machine check is corrected.
- */
- if (psp->cm == 1)
- return mca_recovered("machine check is already corrected.");
-
- /*
- * The error was not contained. Software must be reset.
- */
- if (psp->us || psp->ci == 0)
- return fatal_mca("error not contained");
-
- /*
- * Look for recoverable TLB check
- */
- if (psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc))
- return recover_from_tlb_check(peidx);
-
- /*
- * The cache check and bus check bits have four possible states
- * cc bc
- * 1 1 Memory error, attempt recovery
- * 1 0 Cache error, attempt recovery
- * 0 1 I/O error, attempt recovery
- * 0 0 Other error type, not recovered
- */
- if (psp->cc == 0 && (psp->bc == 0 || pbci == NULL))
- return fatal_mca("No cache or bus check");
-
- /*
- * Cannot handle more than one bus check.
- */
- if (peidx_bus_check_num(peidx) > 1)
- return fatal_mca("Too many bus checks");
-
- if (pbci->ib)
- return fatal_mca("Internal Bus error");
- if (pbci->eb && pbci->bsi > 0)
- return fatal_mca("External bus check fatal status");
-
- /*
- * This is a local MCA and estimated as a recoverable error.
- */
- if (platform)
- return recover_from_platform_error(slidx, peidx, pbci, sos);
-
- /*
- * On account of strange SAL error record, we cannot recover.
- */
- return fatal_mca("Strange SAL record");
-}
-
-/**
- * mca_try_to_recover - Try to recover from MCA
- * @rec: pointer to a SAL error record
- * @sos: pointer to hand off struct between SAL and OS
- *
- * Return value:
- * 1 on Success / 0 on Failure
- */
-
-static int
-mca_try_to_recover(void *rec, struct ia64_sal_os_state *sos)
-{
- int platform_err;
- int n_proc_err;
- slidx_table_t slidx;
- peidx_table_t peidx;
- pal_bus_check_info_t pbci;
-
- /* Make index of SAL error record */
- platform_err = mca_make_slidx(rec, &slidx);
-
- /* Count processor error sections */
- n_proc_err = slidx_count(&slidx, proc_err);
-
- /* Now, OS can recover when there is one processor error section */
- if (n_proc_err > 1)
- return fatal_mca("Too Many Errors");
- else if (n_proc_err == 0)
- /* Weird SAL record ... We can't do anything */
- return fatal_mca("Weird SAL record");
-
- /* Make index of processor error section */
- mca_make_peidx((sal_log_processor_info_t*)
- slidx_first_entry(&slidx.proc_err)->hdr, &peidx);
-
- /* Extract Processor BUS_CHECK[0] */
- *((u64*)&pbci) = peidx_check_info(&peidx, bus_check, 0);
-
- /* Check whether MCA is global or not */
- if (is_mca_global(&peidx, &pbci, sos))
- return fatal_mca("global MCA");
-
- /* Try to recover a processor error */
- return recover_from_processor_error(platform_err, &slidx, &peidx,
- &pbci, sos);
-}
-
-/*
- * =============================================================================
- */
-
-int __init mca_external_handler_init(void)
-{
- if (init_record_index_pools())
- return -ENOMEM;
-
- /* register external mca handlers */
- if (ia64_reg_MCA_extension(mca_try_to_recover)) {
- printk(KERN_ERR "ia64_reg_MCA_extension failed.\n");
- kfree(slidx_pool.buffer);
- return -EFAULT;
- }
- return 0;
-}
-
-void __exit mca_external_handler_exit(void)
-{
- /* unregister external mca handlers */
- ia64_unreg_MCA_extension();
- kfree(slidx_pool.buffer);
-}
-
-module_init(mca_external_handler_init);
-module_exit(mca_external_handler_exit);
-
-module_param(sal_rec_max, int, 0644);
-MODULE_PARM_DESC(sal_rec_max, "Max size of SAL error record");
-
-MODULE_DESCRIPTION("ia64 platform dependent mca handler driver");
-MODULE_LICENSE("GPL");
diff --git a/arch/ia64/kernel/mca_drv.h b/arch/ia64/kernel/mca_drv.h
deleted file mode 100644
index 45bc4e3ae14f..000000000000
--- a/arch/ia64/kernel/mca_drv.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * File: mca_drv.h
- * Purpose: Define helpers for Generic MCA handling
- *
- * Copyright (C) 2004 FUJITSU LIMITED
- * Copyright (C) 2004 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
- */
-/*
- * Processor error section:
- *
- * +-sal_log_processor_info_t *info-------------+
- * | sal_log_section_hdr_t header; |
- * | ... |
- * | sal_log_mod_error_info_t info[0]; |
- * +-+----------------+-------------------------+
- * | CACHE_CHECK | ^ num_cache_check v
- * +----------------+
- * | TLB_CHECK | ^ num_tlb_check v
- * +----------------+
- * | BUS_CHECK | ^ num_bus_check v
- * +----------------+
- * | REG_FILE_CHECK | ^ num_reg_file_check v
- * +----------------+
- * | MS_CHECK | ^ num_ms_check v
- * +-struct cpuid_info *id----------------------+
- * | regs[5]; |
- * | reserved; |
- * +-sal_processor_static_info_t *regs----------+
- * | valid; |
- * | ... |
- * | fr[128]; |
- * +--------------------------------------------+
- */
-
-/* peidx: index of processor error section */
-typedef struct peidx_table {
- sal_log_processor_info_t *info;
- struct sal_cpuid_info *id;
- sal_processor_static_info_t *regs;
-} peidx_table_t;
-
-#define peidx_head(p) (((p)->info))
-#define peidx_mid(p) (((p)->id))
-#define peidx_bottom(p) (((p)->regs))
-
-#define peidx_psp(p) (&(peidx_head(p)->proc_state_parameter))
-#define peidx_field_valid(p) (&(peidx_head(p)->valid))
-#define peidx_minstate_area(p) (&(peidx_bottom(p)->min_state_area))
-
-#define peidx_cache_check_num(p) (peidx_head(p)->valid.num_cache_check)
-#define peidx_tlb_check_num(p) (peidx_head(p)->valid.num_tlb_check)
-#define peidx_bus_check_num(p) (peidx_head(p)->valid.num_bus_check)
-#define peidx_reg_file_check_num(p) (peidx_head(p)->valid.num_reg_file_check)
-#define peidx_ms_check_num(p) (peidx_head(p)->valid.num_ms_check)
-
-#define peidx_cache_check_idx(p, n) (n)
-#define peidx_tlb_check_idx(p, n) (peidx_cache_check_idx(p, peidx_cache_check_num(p)) + n)
-#define peidx_bus_check_idx(p, n) (peidx_tlb_check_idx(p, peidx_tlb_check_num(p)) + n)
-#define peidx_reg_file_check_idx(p, n) (peidx_bus_check_idx(p, peidx_bus_check_num(p)) + n)
-#define peidx_ms_check_idx(p, n) (peidx_reg_file_check_idx(p, peidx_reg_file_check_num(p)) + n)
-
-#define peidx_mod_error_info(p, name, n) \
-({ int __idx = peidx_##name##_idx(p, n); \
- sal_log_mod_error_info_t *__ret = NULL; \
- if (peidx_##name##_num(p) > n) /*BUG*/ \
- __ret = &(peidx_head(p)->info[__idx]); \
- __ret; })
-
-#define peidx_cache_check(p, n) peidx_mod_error_info(p, cache_check, n)
-#define peidx_tlb_check(p, n) peidx_mod_error_info(p, tlb_check, n)
-#define peidx_bus_check(p, n) peidx_mod_error_info(p, bus_check, n)
-#define peidx_reg_file_check(p, n) peidx_mod_error_info(p, reg_file_check, n)
-#define peidx_ms_check(p, n) peidx_mod_error_info(p, ms_check, n)
-
-#define peidx_check_info(proc, name, n) \
-({ \
- sal_log_mod_error_info_t *__info = peidx_mod_error_info(proc, name, n);\
- u64 __temp = __info && __info->valid.check_info \
- ? __info->check_info : 0; \
- __temp; })
-
-/* slidx: index of SAL log error record */
-
-typedef struct slidx_list {
- struct list_head list;
- sal_log_section_hdr_t *hdr;
-} slidx_list_t;
-
-typedef struct slidx_table {
- sal_log_record_header_t *header;
- int n_sections; /* # of section headers */
- struct list_head proc_err;
- struct list_head mem_dev_err;
- struct list_head sel_dev_err;
- struct list_head pci_bus_err;
- struct list_head smbios_dev_err;
- struct list_head pci_comp_err;
- struct list_head plat_specific_err;
- struct list_head host_ctlr_err;
- struct list_head plat_bus_err;
- struct list_head unsupported; /* list of unsupported sections */
-} slidx_table_t;
-
-#define slidx_foreach_entry(pos, head) \
- list_for_each_entry(pos, head, list)
-#define slidx_first_entry(head) \
- (((head)->next != (head)) ? list_entry((head)->next, typeof(slidx_list_t), list) : NULL)
-#define slidx_count(slidx, sec) \
-({ int __count = 0; \
- slidx_list_t *__pos; \
- slidx_foreach_entry(__pos, &((slidx)->sec)) { __count++; }\
- __count; })
-
-struct mca_table_entry {
- int start_addr; /* location-relative starting address of MCA recoverable range */
- int end_addr; /* location-relative ending address of MCA recoverable range */
-};
-
-extern const struct mca_table_entry *search_mca_tables (unsigned long addr);
-extern int mca_recover_range(unsigned long);
-extern void ia64_mlogbuf_dump(void);
-
diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S
deleted file mode 100644
index 4428f57bee73..000000000000
--- a/arch/ia64/kernel/mca_drv_asm.S
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * File: mca_drv_asm.S
- * Purpose: Assembly portion of Generic MCA handling
- *
- * Copyright (C) 2004 FUJITSU LIMITED
- * Copyright (C) 2004 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
- */
-#include <linux/threads.h>
-
-#include <asm/asmmacro.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-
-GLOBAL_ENTRY(mca_handler_bhhook)
- invala // clear RSE ?
- cover
- ;;
- clrrrb
- ;;
- alloc r16=ar.pfs,0,2,3,0 // make a new frame
- mov ar.rsc=0
- mov r13=IA64_KR(CURRENT) // current task pointer
- ;;
- mov r2=r13
- ;;
- addl r22=IA64_RBS_OFFSET,r2
- ;;
- mov ar.bspstore=r22
- addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2
- ;;
- adds r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
- ;;
- st1 [r2]=r0 // clear current->thread.on_ustack flag
- mov loc0=r16
- movl loc1=mca_handler_bh // recovery C function
- ;;
- mov out0=r8 // poisoned address
- mov out1=r9 // iip
- mov out2=r10 // psr
- mov b6=loc1
- ;;
- mov loc1=rp
- ssm psr.ic
- ;;
- srlz.i
- ;;
- ssm psr.i
- br.call.sptk.many rp=b6 // does not return ...
- ;;
- mov ar.pfs=loc0
- mov rp=loc1
- ;;
- mov r8=r0
- br.ret.sptk.many rp
-END(mca_handler_bhhook)
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
deleted file mode 100644
index d6eab2a1084d..000000000000
--- a/arch/ia64/kernel/minstate.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#include <asm/cache.h>
-
-#include "entry.h"
-#include <asm/native/inst.h>
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-/* read ar.itc in advance, and use it before leaving bank 0 */
-#define ACCOUNT_GET_STAMP \
-(pUStk) mov.m r20=ar.itc;
-#define ACCOUNT_SYS_ENTER \
-(pUStk) br.call.spnt rp=account_sys_enter \
- ;;
-#else
-#define ACCOUNT_GET_STAMP
-#define ACCOUNT_SYS_ENTER
-#endif
-
-.section ".data..patch.rse", "a"
-.previous
-
-/*
- * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
- * the minimum state necessary that allows us to turn psr.ic back
- * on.
- *
- * Assumed state upon entry:
- * psr.ic: off
- * r31: contains saved predicates (pr)
- *
- * Upon exit, the state is as follows:
- * psr.ic: off
- * r2 = points to &pt_regs.r16
- * r8 = contents of ar.ccv
- * r9 = contents of ar.csd
- * r10 = contents of ar.ssd
- * r11 = FPSR_DEFAULT
- * r12 = kernel sp (kernel virtual address)
- * r13 = points to current task_struct (kernel virtual address)
- * p15 = TRUE if psr.i is set in cr.ipsr
- * predicate registers (other than p2, p3, and p15), b6, r3, r14, r15:
- * preserved
- *
- * Note that psr.ic is NOT turned on by this macro. This is so that
- * we can pass interruption state as arguments to a handler.
- */
-#define IA64_NATIVE_DO_SAVE_MIN(__COVER,SAVE_IFS,EXTRA,WORKAROUND) \
- mov r16=IA64_KR(CURRENT); /* M */ \
- mov r27=ar.rsc; /* M */ \
- mov r20=r1; /* A */ \
- mov r25=ar.unat; /* M */ \
- MOV_FROM_IPSR(p0,r29); /* M */ \
- mov r26=ar.pfs; /* I */ \
- MOV_FROM_IIP(r28); /* M */ \
- mov r21=ar.fpsr; /* M */ \
- __COVER; /* B;; (or nothing) */ \
- ;; \
- adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16; \
- ;; \
- ld1 r17=[r16]; /* load current->thread.on_ustack flag */ \
- st1 [r16]=r0; /* clear current->thread.on_ustack flag */ \
- adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 \
- /* switch from user to kernel RBS: */ \
- ;; \
- invala; /* M */ \
- SAVE_IFS; \
- cmp.eq pKStk,pUStk=r0,r17; /* are we in kernel mode already? */ \
- ;; \
-(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \
- ;; \
-(pUStk) mov.m r24=ar.rnat; \
-(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \
-(pKStk) mov r1=sp; /* get sp */ \
- ;; \
-(pUStk) lfetch.fault.excl.nt1 [r22]; \
-(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \
-(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \
- ;; \
-(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \
-(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \
- ;; \
-(pUStk) mov r18=ar.bsp; \
-(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \
- adds r17=2*L1_CACHE_BYTES,r1; /* really: biggest cache-line size */ \
- adds r16=PT(CR_IPSR),r1; \
- ;; \
- lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES; \
- st8 [r16]=r29; /* save cr.ipsr */ \
- ;; \
- lfetch.fault.excl.nt1 [r17]; \
- tbit.nz p15,p0=r29,IA64_PSR_I_BIT; \
- mov r29=b0 \
- ;; \
- WORKAROUND; \
- adds r16=PT(R8),r1; /* initialize first base pointer */ \
- adds r17=PT(R9),r1; /* initialize second base pointer */ \
-(pKStk) mov r18=r0; /* make sure r18 isn't NaT */ \
- ;; \
-.mem.offset 0,0; st8.spill [r16]=r8,16; \
-.mem.offset 8,0; st8.spill [r17]=r9,16; \
- ;; \
-.mem.offset 0,0; st8.spill [r16]=r10,24; \
-.mem.offset 8,0; st8.spill [r17]=r11,24; \
- ;; \
- st8 [r16]=r28,16; /* save cr.iip */ \
- st8 [r17]=r30,16; /* save cr.ifs */ \
-(pUStk) sub r18=r18,r22; /* r18=RSE.ndirty*8 */ \
- mov r8=ar.ccv; \
- mov r9=ar.csd; \
- mov r10=ar.ssd; \
- movl r11=FPSR_DEFAULT; /* L-unit */ \
- ;; \
- st8 [r16]=r25,16; /* save ar.unat */ \
- st8 [r17]=r26,16; /* save ar.pfs */ \
- shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ \
- ;; \
- st8 [r16]=r27,16; /* save ar.rsc */ \
-(pUStk) st8 [r17]=r24,16; /* save ar.rnat */ \
-(pKStk) adds r17=16,r17; /* skip over ar_rnat field */ \
- ;; /* avoid RAW on r16 & r17 */ \
-(pUStk) st8 [r16]=r23,16; /* save ar.bspstore */ \
- st8 [r17]=r31,16; /* save predicates */ \
-(pKStk) adds r16=16,r16; /* skip over ar_bspstore field */ \
- ;; \
- st8 [r16]=r29,16; /* save b0 */ \
- st8 [r17]=r18,16; /* save ar.rsc value for "loadrs" */ \
- cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ \
- ;; \
-.mem.offset 0,0; st8.spill [r16]=r20,16; /* save original r1 */ \
-.mem.offset 8,0; st8.spill [r17]=r12,16; \
- adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */ \
- ;; \
-.mem.offset 0,0; st8.spill [r16]=r13,16; \
-.mem.offset 8,0; st8.spill [r17]=r21,16; /* save ar.fpsr */ \
- mov r13=IA64_KR(CURRENT); /* establish `current' */ \
- ;; \
-.mem.offset 0,0; st8.spill [r16]=r15,16; \
-.mem.offset 8,0; st8.spill [r17]=r14,16; \
- ;; \
-.mem.offset 0,0; st8.spill [r16]=r2,16; \
-.mem.offset 8,0; st8.spill [r17]=r3,16; \
- ACCOUNT_GET_STAMP \
- adds r2=IA64_PT_REGS_R16_OFFSET,r1; \
- ;; \
- EXTRA; \
- movl r1=__gp; /* establish kernel global pointer */ \
- ;; \
- ACCOUNT_SYS_ENTER \
- bsw.1; /* switch back to bank 1 (must be last in insn group) */ \
- ;;
-
-/*
- * SAVE_REST saves the remainder of pt_regs (with psr.ic on).
- *
- * Assumed state upon entry:
- * psr.ic: on
- * r2: points to &pt_regs.r16
- * r3: points to &pt_regs.r17
- * r8: contents of ar.ccv
- * r9: contents of ar.csd
- * r10: contents of ar.ssd
- * r11: FPSR_DEFAULT
- *
- * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST.
- */
-#define SAVE_REST \
-.mem.offset 0,0; st8.spill [r2]=r16,16; \
-.mem.offset 8,0; st8.spill [r3]=r17,16; \
- ;; \
-.mem.offset 0,0; st8.spill [r2]=r18,16; \
-.mem.offset 8,0; st8.spill [r3]=r19,16; \
- ;; \
-.mem.offset 0,0; st8.spill [r2]=r20,16; \
-.mem.offset 8,0; st8.spill [r3]=r21,16; \
- mov r18=b6; \
- ;; \
-.mem.offset 0,0; st8.spill [r2]=r22,16; \
-.mem.offset 8,0; st8.spill [r3]=r23,16; \
- mov r19=b7; \
- ;; \
-.mem.offset 0,0; st8.spill [r2]=r24,16; \
-.mem.offset 8,0; st8.spill [r3]=r25,16; \
- ;; \
-.mem.offset 0,0; st8.spill [r2]=r26,16; \
-.mem.offset 8,0; st8.spill [r3]=r27,16; \
- ;; \
-.mem.offset 0,0; st8.spill [r2]=r28,16; \
-.mem.offset 8,0; st8.spill [r3]=r29,16; \
- ;; \
-.mem.offset 0,0; st8.spill [r2]=r30,16; \
-.mem.offset 8,0; st8.spill [r3]=r31,32; \
- ;; \
- mov ar.fpsr=r11; /* M-unit */ \
- st8 [r2]=r8,8; /* ar.ccv */ \
- adds r24=PT(B6)-PT(F7),r3; \
- ;; \
- stf.spill [r2]=f6,32; \
- stf.spill [r3]=f7,32; \
- ;; \
- stf.spill [r2]=f8,32; \
- stf.spill [r3]=f9,32; \
- ;; \
- stf.spill [r2]=f10; \
- stf.spill [r3]=f11; \
- adds r25=PT(B7)-PT(F11),r3; \
- ;; \
- st8 [r24]=r18,16; /* b6 */ \
- st8 [r25]=r19,16; /* b7 */ \
- ;; \
- st8 [r24]=r9; /* ar.csd */ \
- st8 [r25]=r10; /* ar.ssd */ \
- ;;
-
-#define RSE_WORKAROUND \
-(pUStk) extr.u r17=r18,3,6; \
-(pUStk) sub r16=r18,r22; \
-[1:](pKStk) br.cond.sptk.many 1f; \
- .xdata4 ".data..patch.rse",1b-. \
- ;; \
- cmp.ge p6,p7 = 33,r17; \
- ;; \
-(p6) mov r17=0x310; \
-(p7) mov r17=0x308; \
- ;; \
- cmp.leu p1,p0=r16,r17; \
-(p1) br.cond.sptk.many 1f; \
- dep.z r17=r26,0,62; \
- movl r16=2f; \
- ;; \
- mov ar.pfs=r17; \
- dep r27=r0,r27,16,14; \
- mov b0=r16; \
- ;; \
- br.ret.sptk b0; \
- ;; \
-2: \
- mov ar.rsc=r0 \
- ;; \
- flushrs; \
- ;; \
- mov ar.bspstore=r22 \
- ;; \
- mov r18=ar.bsp; \
- ;; \
-1: \
- .pred.rel "mutex", pKStk, pUStk
-
-#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(COVER, mov r30=cr.ifs, , RSE_WORKAROUND)
-#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(COVER, mov r30=cr.ifs, mov r15=r19, RSE_WORKAROUND)
-#define SAVE_MIN DO_SAVE_MIN( , mov r30=r0, , )
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
deleted file mode 100644
index 3661135da9d9..000000000000
--- a/arch/ia64/kernel/module.c
+++ /dev/null
@@ -1,959 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * IA-64-specific support for kernel module loader.
- *
- * Copyright (C) 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Loosely based on patch by Rusty Russell.
- */
-
-/* relocs tested so far:
-
- DIR64LSB
- FPTR64LSB
- GPREL22
- LDXMOV
- LDXMOV
- LTOFF22
- LTOFF22X
- LTOFF22X
- LTOFF_FPTR22
- PCREL21B (for br.call only; br.cond is not supported out of modules!)
- PCREL60B (for brl.cond only; brl.call is not supported for modules!)
- PCREL64LSB
- SECREL32LSB
- SEGREL64LSB
- */
-
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/elf.h>
-#include <linux/moduleloader.h>
-#include <linux/string.h>
-#include <linux/vmalloc.h>
-
-#include <asm/patch.h>
-#include <asm/unaligned.h>
-#include <asm/sections.h>
-
-#define ARCH_MODULE_DEBUG 0
-
-#if ARCH_MODULE_DEBUG
-# define DEBUGP printk
-# define inline
-#else
-# define DEBUGP(fmt , a...)
-#endif
-
-#ifdef CONFIG_ITANIUM
-# define USE_BRL 0
-#else
-# define USE_BRL 1
-#endif
-
-#define MAX_LTOFF ((uint64_t) (1 << 22)) /* max. allowable linkage-table offset */
-
-/* Define some relocation helper macros/types: */
-
-#define FORMAT_SHIFT 0
-#define FORMAT_BITS 3
-#define FORMAT_MASK ((1 << FORMAT_BITS) - 1)
-#define VALUE_SHIFT 3
-#define VALUE_BITS 5
-#define VALUE_MASK ((1 << VALUE_BITS) - 1)
-
-enum reloc_target_format {
- /* direct encoded formats: */
- RF_NONE = 0,
- RF_INSN14 = 1,
- RF_INSN22 = 2,
- RF_INSN64 = 3,
- RF_32MSB = 4,
- RF_32LSB = 5,
- RF_64MSB = 6,
- RF_64LSB = 7,
-
- /* formats that cannot be directly decoded: */
- RF_INSN60,
- RF_INSN21B, /* imm21 form 1 */
- RF_INSN21M, /* imm21 form 2 */
- RF_INSN21F /* imm21 form 3 */
-};
-
-enum reloc_value_formula {
- RV_DIRECT = 4, /* S + A */
- RV_GPREL = 5, /* @gprel(S + A) */
- RV_LTREL = 6, /* @ltoff(S + A) */
- RV_PLTREL = 7, /* @pltoff(S + A) */
- RV_FPTR = 8, /* @fptr(S + A) */
- RV_PCREL = 9, /* S + A - P */
- RV_LTREL_FPTR = 10, /* @ltoff(@fptr(S + A)) */
- RV_SEGREL = 11, /* @segrel(S + A) */
- RV_SECREL = 12, /* @secrel(S + A) */
- RV_BDREL = 13, /* BD + A */
- RV_LTV = 14, /* S + A (like RV_DIRECT, except frozen at static link-time) */
- RV_PCREL2 = 15, /* S + A - P */
- RV_SPECIAL = 16, /* various (see below) */
- RV_RSVD17 = 17,
- RV_TPREL = 18, /* @tprel(S + A) */
- RV_LTREL_TPREL = 19, /* @ltoff(@tprel(S + A)) */
- RV_DTPMOD = 20, /* @dtpmod(S + A) */
- RV_LTREL_DTPMOD = 21, /* @ltoff(@dtpmod(S + A)) */
- RV_DTPREL = 22, /* @dtprel(S + A) */
- RV_LTREL_DTPREL = 23, /* @ltoff(@dtprel(S + A)) */
- RV_RSVD24 = 24,
- RV_RSVD25 = 25,
- RV_RSVD26 = 26,
- RV_RSVD27 = 27
- /* 28-31 reserved for implementation-specific purposes. */
-};
-
-#define N(reloc) [R_IA64_##reloc] = #reloc
-
-static const char *reloc_name[256] = {
- N(NONE), N(IMM14), N(IMM22), N(IMM64),
- N(DIR32MSB), N(DIR32LSB), N(DIR64MSB), N(DIR64LSB),
- N(GPREL22), N(GPREL64I), N(GPREL32MSB), N(GPREL32LSB),
- N(GPREL64MSB), N(GPREL64LSB), N(LTOFF22), N(LTOFF64I),
- N(PLTOFF22), N(PLTOFF64I), N(PLTOFF64MSB), N(PLTOFF64LSB),
- N(FPTR64I), N(FPTR32MSB), N(FPTR32LSB), N(FPTR64MSB),
- N(FPTR64LSB), N(PCREL60B), N(PCREL21B), N(PCREL21M),
- N(PCREL21F), N(PCREL32MSB), N(PCREL32LSB), N(PCREL64MSB),
- N(PCREL64LSB), N(LTOFF_FPTR22), N(LTOFF_FPTR64I), N(LTOFF_FPTR32MSB),
- N(LTOFF_FPTR32LSB), N(LTOFF_FPTR64MSB), N(LTOFF_FPTR64LSB), N(SEGREL32MSB),
- N(SEGREL32LSB), N(SEGREL64MSB), N(SEGREL64LSB), N(SECREL32MSB),
- N(SECREL32LSB), N(SECREL64MSB), N(SECREL64LSB), N(REL32MSB),
- N(REL32LSB), N(REL64MSB), N(REL64LSB), N(LTV32MSB),
- N(LTV32LSB), N(LTV64MSB), N(LTV64LSB), N(PCREL21BI),
- N(PCREL22), N(PCREL64I), N(IPLTMSB), N(IPLTLSB),
- N(COPY), N(LTOFF22X), N(LDXMOV), N(TPREL14),
- N(TPREL22), N(TPREL64I), N(TPREL64MSB), N(TPREL64LSB),
- N(LTOFF_TPREL22), N(DTPMOD64MSB), N(DTPMOD64LSB), N(LTOFF_DTPMOD22),
- N(DTPREL14), N(DTPREL22), N(DTPREL64I), N(DTPREL32MSB),
- N(DTPREL32LSB), N(DTPREL64MSB), N(DTPREL64LSB), N(LTOFF_DTPREL22)
-};
-
-#undef N
-
-/* Opaque struct for insns, to protect against derefs. */
-struct insn;
-
-static inline uint64_t
-bundle (const struct insn *insn)
-{
- return (uint64_t) insn & ~0xfUL;
-}
-
-static inline int
-slot (const struct insn *insn)
-{
- return (uint64_t) insn & 0x3;
-}
-
-static int
-apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
-{
- if (slot(insn) != 1 && slot(insn) != 2) {
- printk(KERN_ERR "%s: invalid slot number %d for IMM64\n",
- mod->name, slot(insn));
- return 0;
- }
- ia64_patch_imm64((u64) insn, val);
- return 1;
-}
-
-static int
-apply_imm60 (struct module *mod, struct insn *insn, uint64_t val)
-{
- if (slot(insn) != 1 && slot(insn) != 2) {
- printk(KERN_ERR "%s: invalid slot number %d for IMM60\n",
- mod->name, slot(insn));
- return 0;
- }
- if (val + ((uint64_t) 1 << 59) >= (1UL << 60)) {
- printk(KERN_ERR "%s: value %ld out of IMM60 range\n",
- mod->name, (long) val);
- return 0;
- }
- ia64_patch_imm60((u64) insn, val);
- return 1;
-}
-
-static int
-apply_imm22 (struct module *mod, struct insn *insn, uint64_t val)
-{
- if (val + (1 << 21) >= (1 << 22)) {
- printk(KERN_ERR "%s: value %li out of IMM22 range\n",
- mod->name, (long)val);
- return 0;
- }
- ia64_patch((u64) insn, 0x01fffcfe000UL, ( ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
- | ((val & 0x1f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x00ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x00007fUL) << 13) /* bit 0 -> 13 */));
- return 1;
-}
-
-static int
-apply_imm21b (struct module *mod, struct insn *insn, uint64_t val)
-{
- if (val + (1 << 20) >= (1 << 21)) {
- printk(KERN_ERR "%s: value %li out of IMM21b range\n",
- mod->name, (long)val);
- return 0;
- }
- ia64_patch((u64) insn, 0x11ffffe000UL, ( ((val & 0x100000UL) << 16) /* bit 20 -> 36 */
- | ((val & 0x0fffffUL) << 13) /* bit 0 -> 13 */));
- return 1;
-}
-
-#if USE_BRL
-
-struct plt_entry {
- /* Three instruction bundles in PLT. */
- unsigned char bundle[2][16];
-};
-
-static const struct plt_entry ia64_plt_template = {
- {
- {
- 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* movl gp=TARGET_GP */
- 0x00, 0x00, 0x00, 0x60
- },
- {
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.many gp=TARGET_GP */
- 0x08, 0x00, 0x00, 0xc0
- }
- }
-};
-
-static int
-patch_plt (struct module *mod, struct plt_entry *plt, long target_ip, unsigned long target_gp)
-{
- if (apply_imm64(mod, (struct insn *) (plt->bundle[0] + 2), target_gp)
- && apply_imm60(mod, (struct insn *) (plt->bundle[1] + 2),
- (target_ip - (int64_t) plt->bundle[1]) / 16))
- return 1;
- return 0;
-}
-
-unsigned long
-plt_target (struct plt_entry *plt)
-{
- uint64_t b0, b1, *b = (uint64_t *) plt->bundle[1];
- long off;
-
- b0 = b[0]; b1 = b[1];
- off = ( ((b1 & 0x00fffff000000000UL) >> 36) /* imm20b -> bit 0 */
- | ((b0 >> 48) << 20) | ((b1 & 0x7fffffUL) << 36) /* imm39 -> bit 20 */
- | ((b1 & 0x0800000000000000UL) << 0)); /* i -> bit 59 */
- return (long) plt->bundle[1] + 16*off;
-}
-
-#else /* !USE_BRL */
-
-struct plt_entry {
- /* Three instruction bundles in PLT. */
- unsigned char bundle[3][16];
-};
-
-static const struct plt_entry ia64_plt_template = {
- {
- {
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* movl r16=TARGET_IP */
- 0x02, 0x00, 0x00, 0x60
- },
- {
- 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* movl gp=TARGET_GP */
- 0x00, 0x00, 0x00, 0x60
- },
- {
- 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
- 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
- 0x60, 0x00, 0x80, 0x00 /* br.few b6 */
- }
- }
-};
-
-static int
-patch_plt (struct module *mod, struct plt_entry *plt, long target_ip, unsigned long target_gp)
-{
- if (apply_imm64(mod, (struct insn *) (plt->bundle[0] + 2), target_ip)
- && apply_imm64(mod, (struct insn *) (plt->bundle[1] + 2), target_gp))
- return 1;
- return 0;
-}
-
-unsigned long
-plt_target (struct plt_entry *plt)
-{
- uint64_t b0, b1, *b = (uint64_t *) plt->bundle[0];
-
- b0 = b[0]; b1 = b[1];
- return ( ((b1 & 0x000007f000000000) >> 36) /* imm7b -> bit 0 */
- | ((b1 & 0x07fc000000000000) >> 43) /* imm9d -> bit 7 */
- | ((b1 & 0x0003e00000000000) >> 29) /* imm5c -> bit 16 */
- | ((b1 & 0x0000100000000000) >> 23) /* ic -> bit 21 */
- | ((b0 >> 46) << 22) | ((b1 & 0x7fffff) << 40) /* imm41 -> bit 22 */
- | ((b1 & 0x0800000000000000) << 4)); /* i -> bit 63 */
-}
-
-#endif /* !USE_BRL */
-
-void
-module_arch_freeing_init (struct module *mod)
-{
- if (mod->arch.init_unw_table) {
- unw_remove_unwind_table(mod->arch.init_unw_table);
- mod->arch.init_unw_table = NULL;
- }
-}
-
-/* Have we already seen one of these relocations? */
-/* FIXME: we could look in other sections, too --RR */
-static int
-duplicate_reloc (const Elf64_Rela *rela, unsigned int num)
-{
- unsigned int i;
-
- for (i = 0; i < num; i++) {
- if (rela[i].r_info == rela[num].r_info && rela[i].r_addend == rela[num].r_addend)
- return 1;
- }
- return 0;
-}
-
-/* Count how many GOT entries we may need */
-static unsigned int
-count_gots (const Elf64_Rela *rela, unsigned int num)
-{
- unsigned int i, ret = 0;
-
- /* Sure, this is order(n^2), but it's usually short, and not
- time critical */
- for (i = 0; i < num; i++) {
- switch (ELF64_R_TYPE(rela[i].r_info)) {
- case R_IA64_LTOFF22:
- case R_IA64_LTOFF22X:
- case R_IA64_LTOFF64I:
- case R_IA64_LTOFF_FPTR22:
- case R_IA64_LTOFF_FPTR64I:
- case R_IA64_LTOFF_FPTR32MSB:
- case R_IA64_LTOFF_FPTR32LSB:
- case R_IA64_LTOFF_FPTR64MSB:
- case R_IA64_LTOFF_FPTR64LSB:
- if (!duplicate_reloc(rela, i))
- ret++;
- break;
- }
- }
- return ret;
-}
-
-/* Count how many PLT entries we may need */
-static unsigned int
-count_plts (const Elf64_Rela *rela, unsigned int num)
-{
- unsigned int i, ret = 0;
-
- /* Sure, this is order(n^2), but it's usually short, and not
- time critical */
- for (i = 0; i < num; i++) {
- switch (ELF64_R_TYPE(rela[i].r_info)) {
- case R_IA64_PCREL21B:
- case R_IA64_PLTOFF22:
- case R_IA64_PLTOFF64I:
- case R_IA64_PLTOFF64MSB:
- case R_IA64_PLTOFF64LSB:
- case R_IA64_IPLTMSB:
- case R_IA64_IPLTLSB:
- if (!duplicate_reloc(rela, i))
- ret++;
- break;
- }
- }
- return ret;
-}
-
-/* We need to create an function-descriptors for any internal function
- which is referenced. */
-static unsigned int
-count_fdescs (const Elf64_Rela *rela, unsigned int num)
-{
- unsigned int i, ret = 0;
-
- /* Sure, this is order(n^2), but it's usually short, and not time critical. */
- for (i = 0; i < num; i++) {
- switch (ELF64_R_TYPE(rela[i].r_info)) {
- case R_IA64_FPTR64I:
- case R_IA64_FPTR32LSB:
- case R_IA64_FPTR32MSB:
- case R_IA64_FPTR64LSB:
- case R_IA64_FPTR64MSB:
- case R_IA64_LTOFF_FPTR22:
- case R_IA64_LTOFF_FPTR32LSB:
- case R_IA64_LTOFF_FPTR32MSB:
- case R_IA64_LTOFF_FPTR64I:
- case R_IA64_LTOFF_FPTR64LSB:
- case R_IA64_LTOFF_FPTR64MSB:
- case R_IA64_IPLTMSB:
- case R_IA64_IPLTLSB:
- /*
- * Jumps to static functions sometimes go straight to their
- * offset. Of course, that may not be possible if the jump is
- * from init -> core or vice. versa, so we need to generate an
- * FDESC (and PLT etc) for that.
- */
- case R_IA64_PCREL21B:
- if (!duplicate_reloc(rela, i))
- ret++;
- break;
- }
- }
- return ret;
-}
-
-int
-module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
- struct module *mod)
-{
- unsigned long core_plts = 0, init_plts = 0, gots = 0, fdescs = 0;
- Elf64_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;
-
- /*
- * To store the PLTs and function-descriptors, we expand the .text section for
- * core module-code and the .init.text section for initialization code.
- */
- for (s = sechdrs; s < sechdrs_end; ++s)
- if (strcmp(".core.plt", secstrings + s->sh_name) == 0)
- mod->arch.core_plt = s;
- else if (strcmp(".init.plt", secstrings + s->sh_name) == 0)
- mod->arch.init_plt = s;
- else if (strcmp(".got", secstrings + s->sh_name) == 0)
- mod->arch.got = s;
- else if (strcmp(".opd", secstrings + s->sh_name) == 0)
- mod->arch.opd = s;
- else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0)
- mod->arch.unwind = s;
-
- if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) {
- printk(KERN_ERR "%s: sections missing\n", mod->name);
- return -ENOEXEC;
- }
-
- /* GOT and PLTs can occur in any relocated section... */
- for (s = sechdrs + 1; s < sechdrs_end; ++s) {
- const Elf64_Rela *rels = (void *)ehdr + s->sh_offset;
- unsigned long numrels = s->sh_size/sizeof(Elf64_Rela);
-
- if (s->sh_type != SHT_RELA)
- continue;
-
- gots += count_gots(rels, numrels);
- fdescs += count_fdescs(rels, numrels);
- if (strstr(secstrings + s->sh_name, ".init"))
- init_plts += count_plts(rels, numrels);
- else
- core_plts += count_plts(rels, numrels);
- }
-
- mod->arch.core_plt->sh_type = SHT_NOBITS;
- mod->arch.core_plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
- mod->arch.core_plt->sh_addralign = 16;
- mod->arch.core_plt->sh_size = core_plts * sizeof(struct plt_entry);
- mod->arch.init_plt->sh_type = SHT_NOBITS;
- mod->arch.init_plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
- mod->arch.init_plt->sh_addralign = 16;
- mod->arch.init_plt->sh_size = init_plts * sizeof(struct plt_entry);
- mod->arch.got->sh_type = SHT_NOBITS;
- mod->arch.got->sh_flags = ARCH_SHF_SMALL | SHF_ALLOC;
- mod->arch.got->sh_addralign = 8;
- mod->arch.got->sh_size = gots * sizeof(struct got_entry);
- mod->arch.opd->sh_type = SHT_NOBITS;
- mod->arch.opd->sh_flags = SHF_ALLOC;
- mod->arch.opd->sh_addralign = 8;
- mod->arch.opd->sh_size = fdescs * sizeof(struct fdesc);
- DEBUGP("%s: core.plt=%lx, init.plt=%lx, got=%lx, fdesc=%lx\n",
- __func__, mod->arch.core_plt->sh_size, mod->arch.init_plt->sh_size,
- mod->arch.got->sh_size, mod->arch.opd->sh_size);
- return 0;
-}
-
-static inline bool
-in_init (const struct module *mod, uint64_t addr)
-{
- return within_module_init(addr, mod);
-}
-
-static inline bool
-in_core (const struct module *mod, uint64_t addr)
-{
- return within_module_core(addr, mod);
-}
-
-static inline bool
-is_internal (const struct module *mod, uint64_t value)
-{
- return in_init(mod, value) || in_core(mod, value);
-}
-
-/*
- * Get gp-relative offset for the linkage-table entry of VALUE.
- */
-static uint64_t
-get_ltoff (struct module *mod, uint64_t value, int *okp)
-{
- struct got_entry *got, *e;
-
- if (!*okp)
- return 0;
-
- got = (void *) mod->arch.got->sh_addr;
- for (e = got; e < got + mod->arch.next_got_entry; ++e)
- if (e->val == value)
- goto found;
-
- /* Not enough GOT entries? */
- BUG_ON(e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size));
-
- e->val = value;
- ++mod->arch.next_got_entry;
- found:
- return (uint64_t) e - mod->arch.gp;
-}
-
-static inline int
-gp_addressable (struct module *mod, uint64_t value)
-{
- return value - mod->arch.gp + MAX_LTOFF/2 < MAX_LTOFF;
-}
-
-/* Get PC-relative PLT entry for this value. Returns 0 on failure. */
-static uint64_t
-get_plt (struct module *mod, const struct insn *insn, uint64_t value, int *okp)
-{
- struct plt_entry *plt, *plt_end;
- uint64_t target_ip, target_gp;
-
- if (!*okp)
- return 0;
-
- if (in_init(mod, (uint64_t) insn)) {
- plt = (void *) mod->arch.init_plt->sh_addr;
- plt_end = (void *) plt + mod->arch.init_plt->sh_size;
- } else {
- plt = (void *) mod->arch.core_plt->sh_addr;
- plt_end = (void *) plt + mod->arch.core_plt->sh_size;
- }
-
- /* "value" is a pointer to a function-descriptor; fetch the target ip/gp from it: */
- target_ip = ((uint64_t *) value)[0];
- target_gp = ((uint64_t *) value)[1];
-
- /* Look for existing PLT entry. */
- while (plt->bundle[0][0]) {
- if (plt_target(plt) == target_ip)
- goto found;
- if (++plt >= plt_end)
- BUG();
- }
- *plt = ia64_plt_template;
- if (!patch_plt(mod, plt, target_ip, target_gp)) {
- *okp = 0;
- return 0;
- }
-#if ARCH_MODULE_DEBUG
- if (plt_target(plt) != target_ip) {
- printk("%s: mistargeted PLT: wanted %lx, got %lx\n",
- __func__, target_ip, plt_target(plt));
- *okp = 0;
- return 0;
- }
-#endif
- found:
- return (uint64_t) plt;
-}
-
-/* Get function descriptor for VALUE. */
-static uint64_t
-get_fdesc (struct module *mod, uint64_t value, int *okp)
-{
- struct fdesc *fdesc = (void *) mod->arch.opd->sh_addr;
-
- if (!*okp)
- return 0;
-
- if (!value) {
- printk(KERN_ERR "%s: fdesc for zero requested!\n", mod->name);
- return 0;
- }
-
- if (!is_internal(mod, value))
- /*
- * If it's not a module-local entry-point, "value" already points to a
- * function-descriptor.
- */
- return value;
-
- /* Look for existing function descriptor. */
- while (fdesc->addr) {
- if (fdesc->addr == value)
- return (uint64_t)fdesc;
- if ((uint64_t) ++fdesc >= mod->arch.opd->sh_addr + mod->arch.opd->sh_size)
- BUG();
- }
-
- /* Create new one */
- fdesc->addr = value;
- fdesc->gp = mod->arch.gp;
- return (uint64_t) fdesc;
-}
-
-static inline int
-do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
- Elf64_Shdr *sec, void *location)
-{
- enum reloc_target_format format = (r_type >> FORMAT_SHIFT) & FORMAT_MASK;
- enum reloc_value_formula formula = (r_type >> VALUE_SHIFT) & VALUE_MASK;
- uint64_t val;
- int ok = 1;
-
- val = sym->st_value + addend;
-
- switch (formula) {
- case RV_SEGREL: /* segment base is arbitrarily chosen to be 0 for kernel modules */
- case RV_DIRECT:
- break;
-
- case RV_GPREL: val -= mod->arch.gp; break;
- case RV_LTREL: val = get_ltoff(mod, val, &ok); break;
- case RV_PLTREL: val = get_plt(mod, location, val, &ok); break;
- case RV_FPTR: val = get_fdesc(mod, val, &ok); break;
- case RV_SECREL: val -= sec->sh_addr; break;
- case RV_LTREL_FPTR: val = get_ltoff(mod, get_fdesc(mod, val, &ok), &ok); break;
-
- case RV_PCREL:
- switch (r_type) {
- case R_IA64_PCREL21B:
- if ((in_init(mod, val) && in_core(mod, (uint64_t)location)) ||
- (in_core(mod, val) && in_init(mod, (uint64_t)location))) {
- /*
- * Init section may have been allocated far away from core,
- * if the branch won't reach, then allocate a plt for it.
- */
- uint64_t delta = ((int64_t)val - (int64_t)location) / 16;
- if (delta + (1 << 20) >= (1 << 21)) {
- val = get_fdesc(mod, val, &ok);
- val = get_plt(mod, location, val, &ok);
- }
- } else if (!is_internal(mod, val))
- val = get_plt(mod, location, val, &ok);
- fallthrough;
- default:
- val -= bundle(location);
- break;
-
- case R_IA64_PCREL32MSB:
- case R_IA64_PCREL32LSB:
- case R_IA64_PCREL64MSB:
- case R_IA64_PCREL64LSB:
- val -= (uint64_t) location;
- break;
-
- }
- switch (r_type) {
- case R_IA64_PCREL60B: format = RF_INSN60; break;
- case R_IA64_PCREL21B: format = RF_INSN21B; break;
- case R_IA64_PCREL21M: format = RF_INSN21M; break;
- case R_IA64_PCREL21F: format = RF_INSN21F; break;
- default: break;
- }
- break;
-
- case RV_BDREL:
- val -= (uint64_t) (in_init(mod, val) ? mod->mem[MOD_INIT_TEXT].base :
- mod->mem[MOD_TEXT].base);
- break;
-
- case RV_LTV:
- /* can link-time value relocs happen here? */
- BUG();
- break;
-
- case RV_PCREL2:
- if (r_type == R_IA64_PCREL21BI) {
- if (!is_internal(mod, val)) {
- printk(KERN_ERR "%s: %s reloc against "
- "non-local symbol (%lx)\n", __func__,
- reloc_name[r_type], (unsigned long)val);
- return -ENOEXEC;
- }
- format = RF_INSN21B;
- }
- val -= bundle(location);
- break;
-
- case RV_SPECIAL:
- switch (r_type) {
- case R_IA64_IPLTMSB:
- case R_IA64_IPLTLSB:
- val = get_fdesc(mod, get_plt(mod, location, val, &ok), &ok);
- format = RF_64LSB;
- if (r_type == R_IA64_IPLTMSB)
- format = RF_64MSB;
- break;
-
- case R_IA64_SUB:
- val = addend - sym->st_value;
- format = RF_INSN64;
- break;
-
- case R_IA64_LTOFF22X:
- if (gp_addressable(mod, val))
- val -= mod->arch.gp;
- else
- val = get_ltoff(mod, val, &ok);
- format = RF_INSN22;
- break;
-
- case R_IA64_LDXMOV:
- if (gp_addressable(mod, val)) {
- /* turn "ld8" into "mov": */
- DEBUGP("%s: patching ld8 at %p to mov\n", __func__, location);
- ia64_patch((u64) location, 0x1fff80fe000UL, 0x10000000000UL);
- }
- return 0;
-
- default:
- if (reloc_name[r_type])
- printk(KERN_ERR "%s: special reloc %s not supported",
- mod->name, reloc_name[r_type]);
- else
- printk(KERN_ERR "%s: unknown special reloc %x\n",
- mod->name, r_type);
- return -ENOEXEC;
- }
- break;
-
- case RV_TPREL:
- case RV_LTREL_TPREL:
- case RV_DTPMOD:
- case RV_LTREL_DTPMOD:
- case RV_DTPREL:
- case RV_LTREL_DTPREL:
- printk(KERN_ERR "%s: %s reloc not supported\n",
- mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?");
- return -ENOEXEC;
-
- default:
- printk(KERN_ERR "%s: unknown reloc %x\n", mod->name, r_type);
- return -ENOEXEC;
- }
-
- if (!ok)
- return -ENOEXEC;
-
- DEBUGP("%s: [%p]<-%016lx = %s(%lx)\n", __func__, location, val,
- reloc_name[r_type] ? reloc_name[r_type] : "?", sym->st_value + addend);
-
- switch (format) {
- case RF_INSN21B: ok = apply_imm21b(mod, location, (int64_t) val / 16); break;
- case RF_INSN22: ok = apply_imm22(mod, location, val); break;
- case RF_INSN64: ok = apply_imm64(mod, location, val); break;
- case RF_INSN60: ok = apply_imm60(mod, location, (int64_t) val / 16); break;
- case RF_32LSB: put_unaligned(val, (uint32_t *) location); break;
- case RF_64LSB: put_unaligned(val, (uint64_t *) location); break;
- case RF_32MSB: /* ia64 Linux is little-endian... */
- case RF_64MSB: /* ia64 Linux is little-endian... */
- case RF_INSN14: /* must be within-module, i.e., resolved by "ld -r" */
- case RF_INSN21M: /* must be within-module, i.e., resolved by "ld -r" */
- case RF_INSN21F: /* must be within-module, i.e., resolved by "ld -r" */
- printk(KERN_ERR "%s: format %u needed by %s reloc is not supported\n",
- mod->name, format, reloc_name[r_type] ? reloc_name[r_type] : "?");
- return -ENOEXEC;
-
- default:
- printk(KERN_ERR "%s: relocation %s resulted in unknown format %u\n",
- mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?", format);
- return -ENOEXEC;
- }
- return ok ? 0 : -ENOEXEC;
-}
-
-int
-apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
- unsigned int relsec, struct module *mod)
-{
- unsigned int i, n = sechdrs[relsec].sh_size / sizeof(Elf64_Rela);
- Elf64_Rela *rela = (void *) sechdrs[relsec].sh_addr;
- Elf64_Shdr *target_sec;
- int ret;
-
- DEBUGP("%s: applying section %u (%u relocs) to %u\n", __func__,
- relsec, n, sechdrs[relsec].sh_info);
-
- target_sec = sechdrs + sechdrs[relsec].sh_info;
-
- if (target_sec->sh_entsize == ~0UL)
- /*
- * If target section wasn't allocated, we don't need to relocate it.
- * Happens, e.g., for debug sections.
- */
- return 0;
-
- if (!mod->arch.gp) {
- /*
- * XXX Should have an arch-hook for running this after final section
- * addresses have been selected...
- */
- uint64_t gp;
- struct module_memory *mod_mem;
-
- mod_mem = &mod->mem[MOD_DATA];
- if (mod_mem->size > MAX_LTOFF)
- /*
- * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
- * at the end of the module.
- */
- gp = mod_mem->size - MAX_LTOFF / 2;
- else
- gp = mod_mem->size / 2;
- gp = (uint64_t) mod_mem->base + ((gp + 7) & -8);
- mod->arch.gp = gp;
- DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
- }
-
- for (i = 0; i < n; i++) {
- ret = do_reloc(mod, ELF64_R_TYPE(rela[i].r_info),
- ((Elf64_Sym *) sechdrs[symindex].sh_addr
- + ELF64_R_SYM(rela[i].r_info)),
- rela[i].r_addend, target_sec,
- (void *) target_sec->sh_addr + rela[i].r_offset);
- if (ret < 0)
- return ret;
- }
- return 0;
-}
-
-/*
- * Modules contain a single unwind table which covers both the core and the init text
- * sections but since the two are not contiguous, we need to split this table up such that
- * we can register (and unregister) each "segment" separately. Fortunately, this sounds
- * more complicated than it really is.
- */
-static void
-register_unwind_table (struct module *mod)
-{
- struct unw_table_entry *start = (void *) mod->arch.unwind->sh_addr;
- struct unw_table_entry *end = start + mod->arch.unwind->sh_size / sizeof (*start);
- struct unw_table_entry *e1, *e2, *core, *init;
- unsigned long num_init = 0, num_core = 0;
-
- /* First, count how many init and core unwind-table entries there are. */
- for (e1 = start; e1 < end; ++e1)
- if (in_init(mod, e1->start_offset))
- ++num_init;
- else
- ++num_core;
- /*
- * Second, sort the table such that all unwind-table entries for the init and core
- * text sections are nicely separated. We do this with a stupid bubble sort
- * (unwind tables don't get ridiculously huge).
- */
- for (e1 = start; e1 < end; ++e1) {
- for (e2 = e1 + 1; e2 < end; ++e2) {
- if (e2->start_offset < e1->start_offset) {
- swap(*e1, *e2);
- }
- }
- }
- /*
- * Third, locate the init and core segments in the unwind table:
- */
- if (in_init(mod, start->start_offset)) {
- init = start;
- core = start + num_init;
- } else {
- core = start;
- init = start + num_core;
- }
-
- DEBUGP("%s: name=%s, gp=%lx, num_init=%lu, num_core=%lu\n", __func__,
- mod->name, mod->arch.gp, num_init, num_core);
-
- /*
- * Fourth, register both tables (if not empty).
- */
- if (num_core > 0) {
- mod->arch.core_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
- core, core + num_core);
- DEBUGP("%s: core: handle=%p [%p-%p)\n", __func__,
- mod->arch.core_unw_table, core, core + num_core);
- }
- if (num_init > 0) {
- mod->arch.init_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
- init, init + num_init);
- DEBUGP("%s: init: handle=%p [%p-%p)\n", __func__,
- mod->arch.init_unw_table, init, init + num_init);
- }
-}
-
-int
-module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod)
-{
- struct mod_arch_specific *mas = &mod->arch;
-
- DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
- if (mas->unwind)
- register_unwind_table(mod);
-
- /*
- * ".opd" was already relocated to the final destination. Store
- * it's address for use in symbolizer.
- */
- mas->opd_addr = (void *)mas->opd->sh_addr;
- mas->opd_size = mas->opd->sh_size;
-
- /*
- * Module relocation was already done at this point. Section
- * headers are about to be deleted. Wipe out load-time context.
- */
- mas->core_plt = NULL;
- mas->init_plt = NULL;
- mas->got = NULL;
- mas->opd = NULL;
- mas->unwind = NULL;
- mas->gp = 0;
- mas->next_got_entry = 0;
-
- return 0;
-}
-
-void
-module_arch_cleanup (struct module *mod)
-{
- if (mod->arch.init_unw_table) {
- unw_remove_unwind_table(mod->arch.init_unw_table);
- mod->arch.init_unw_table = NULL;
- }
- if (mod->arch.core_unw_table) {
- unw_remove_unwind_table(mod->arch.core_unw_table);
- mod->arch.core_unw_table = NULL;
- }
-}
-
-void *dereference_module_function_descriptor(struct module *mod, void *ptr)
-{
- struct mod_arch_specific *mas = &mod->arch;
-
- if (ptr < mas->opd_addr || ptr >= mas->opd_addr + mas->opd_size)
- return ptr;
-
- return dereference_function_descriptor(ptr);
-}
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
deleted file mode 100644
index 025e5133c860..000000000000
--- a/arch/ia64/kernel/msi_ia64.c
+++ /dev/null
@@ -1,198 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * MSI hooks for standard x86 apic
- */
-
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <linux/msi.h>
-#include <linux/dmar.h>
-#include <asm/smp.h>
-#include <asm/msidef.h>
-
-static struct irq_chip ia64_msi_chip;
-
-#ifdef CONFIG_SMP
-static int ia64_set_msi_irq_affinity(struct irq_data *idata,
- const cpumask_t *cpu_mask, bool force)
-{
- struct msi_msg msg;
- u32 addr, data;
- int cpu = cpumask_first_and(cpu_mask, cpu_online_mask);
- unsigned int irq = idata->irq;
-
- if (irq_prepare_move(irq, cpu))
- return -1;
-
- __get_cached_msi_msg(irq_data_get_msi_desc(idata), &msg);
-
- addr = msg.address_lo;
- addr &= MSI_ADDR_DEST_ID_MASK;
- addr |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));
- msg.address_lo = addr;
-
- data = msg.data;
- data &= MSI_DATA_VECTOR_MASK;
- data |= MSI_DATA_VECTOR(irq_to_vector(irq));
- msg.data = data;
-
- pci_write_msi_msg(irq, &msg);
- irq_data_update_affinity(idata, cpumask_of(cpu));
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
-{
- struct msi_msg msg;
- unsigned long dest_phys_id;
- int irq, vector;
-
- irq = create_irq();
- if (irq < 0)
- return irq;
-
- irq_set_msi_desc(irq, desc);
- dest_phys_id = cpu_physical_id(cpumask_any_and(&(irq_to_domain(irq)),
- cpu_online_mask));
- vector = irq_to_vector(irq);
-
- msg.address_hi = 0;
- msg.address_lo =
- MSI_ADDR_HEADER |
- MSI_ADDR_DEST_MODE_PHYS |
- MSI_ADDR_REDIRECTION_CPU |
- MSI_ADDR_DEST_ID_CPU(dest_phys_id);
-
- msg.data =
- MSI_DATA_TRIGGER_EDGE |
- MSI_DATA_LEVEL_ASSERT |
- MSI_DATA_DELIVERY_FIXED |
- MSI_DATA_VECTOR(vector);
-
- pci_write_msi_msg(irq, &msg);
- irq_set_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
-
- return 0;
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
- destroy_irq(irq);
-}
-
-static void ia64_ack_msi_irq(struct irq_data *data)
-{
- irq_complete_move(data->irq);
- irq_move_irq(data);
- ia64_eoi();
-}
-
-static int ia64_msi_retrigger_irq(struct irq_data *data)
-{
- unsigned int vector = irq_to_vector(data->irq);
- ia64_resend_irq(vector);
-
- return 1;
-}
-
-/*
- * Generic ops used on most IA64 platforms.
- */
-static struct irq_chip ia64_msi_chip = {
- .name = "PCI-MSI",
- .irq_mask = pci_msi_mask_irq,
- .irq_unmask = pci_msi_unmask_irq,
- .irq_ack = ia64_ack_msi_irq,
-#ifdef CONFIG_SMP
- .irq_set_affinity = ia64_set_msi_irq_affinity,
-#endif
- .irq_retrigger = ia64_msi_retrigger_irq,
-};
-
-#ifdef CONFIG_INTEL_IOMMU
-#ifdef CONFIG_SMP
-static int dmar_msi_set_affinity(struct irq_data *data,
- const struct cpumask *mask, bool force)
-{
- unsigned int irq = data->irq;
- struct irq_cfg *cfg = irq_cfg + irq;
- struct msi_msg msg;
- int cpu = cpumask_first_and(mask, cpu_online_mask);
-
- if (irq_prepare_move(irq, cpu))
- return -1;
-
- dmar_msi_read(irq, &msg);
-
- msg.data &= ~MSI_DATA_VECTOR_MASK;
- msg.data |= MSI_DATA_VECTOR(cfg->vector);
- msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
- msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));
-
- dmar_msi_write(irq, &msg);
- irq_data_update_affinity(data, mask);
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-static struct irq_chip dmar_msi_type = {
- .name = "DMAR_MSI",
- .irq_unmask = dmar_msi_unmask,
- .irq_mask = dmar_msi_mask,
- .irq_ack = ia64_ack_msi_irq,
-#ifdef CONFIG_SMP
- .irq_set_affinity = dmar_msi_set_affinity,
-#endif
- .irq_retrigger = ia64_msi_retrigger_irq,
-};
-
-static void
-msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
-{
- struct irq_cfg *cfg = irq_cfg + irq;
- unsigned dest;
-
- dest = cpu_physical_id(cpumask_first_and(&(irq_to_domain(irq)),
- cpu_online_mask));
-
- msg->address_hi = 0;
- msg->address_lo =
- MSI_ADDR_HEADER |
- MSI_ADDR_DEST_MODE_PHYS |
- MSI_ADDR_REDIRECTION_CPU |
- MSI_ADDR_DEST_ID_CPU(dest);
-
- msg->data =
- MSI_DATA_TRIGGER_EDGE |
- MSI_DATA_LEVEL_ASSERT |
- MSI_DATA_DELIVERY_FIXED |
- MSI_DATA_VECTOR(cfg->vector);
-}
-
-int dmar_alloc_hwirq(int id, int node, void *arg)
-{
- int irq;
- struct msi_msg msg;
-
- irq = create_irq();
- if (irq > 0) {
- irq_set_handler_data(irq, arg);
- irq_set_chip_and_handler_name(irq, &dmar_msi_type,
- handle_edge_irq, "edge");
- msi_compose_msg(NULL, irq, &msg);
- dmar_msi_write(irq, &msg);
- }
-
- return irq;
-}
-
-void dmar_free_hwirq(int irq)
-{
- irq_set_handler_data(irq, NULL);
- destroy_irq(irq);
-}
-#endif /* CONFIG_INTEL_IOMMU */
-
diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c
deleted file mode 100644
index 8a959f20662d..000000000000
--- a/arch/ia64/kernel/numa.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * ia64 kernel NUMA specific stuff
- *
- * Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
- * Copyright (C) 2004 Silicon Graphics, Inc.
- * Jesse Barnes <jbarnes@sgi.com>
- */
-#include <linux/topology.h>
-#include <linux/module.h>
-#include <asm/processor.h>
-#include <asm/smp.h>
-
-u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_to_node_map);
-
-cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
-EXPORT_SYMBOL(node_to_cpu_mask);
-
-void map_cpu_to_node(int cpu, int nid)
-{
- int oldnid;
- if (nid < 0) { /* just initialize by zero */
- cpu_to_node_map[cpu] = 0;
- return;
- }
- /* sanity check first */
- oldnid = cpu_to_node_map[cpu];
- if (cpumask_test_cpu(cpu, &node_to_cpu_mask[oldnid])) {
- return; /* nothing to do */
- }
- /* we don't have cpu-driven node hot add yet...
- In usual case, node is created from SRAT at boot time. */
- if (!node_online(nid))
- nid = first_online_node;
- cpu_to_node_map[cpu] = nid;
- cpumask_set_cpu(cpu, &node_to_cpu_mask[nid]);
- return;
-}
-
-void unmap_cpu_from_node(int cpu, int nid)
-{
- WARN_ON(!cpumask_test_cpu(cpu, &node_to_cpu_mask[nid]));
- WARN_ON(cpu_to_node_map[cpu] != nid);
- cpu_to_node_map[cpu] = 0;
- cpumask_clear_cpu(cpu, &node_to_cpu_mask[nid]);
-}
-
-
-/**
- * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
- *
- * Build cpu to node mapping and initialize the per node cpu masks using
- * info from the node_cpuid array handed to us by ACPI.
- */
-void __init build_cpu_to_node_map(void)
-{
- int cpu, i, node;
-
- for(node=0; node < MAX_NUMNODES; node++)
- cpumask_clear(&node_to_cpu_mask[node]);
-
- for_each_possible_early_cpu(cpu) {
- node = NUMA_NO_NODE;
- for (i = 0; i < NR_CPUS; ++i)
- if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) {
- node = node_cpuid[i].nid;
- break;
- }
- map_cpu_to_node(cpu, node);
- }
-}
diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S
deleted file mode 100644
index fb6db6966f70..000000000000
--- a/arch/ia64/kernel/pal.S
+++ /dev/null
@@ -1,306 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * PAL Firmware support
- * IA-64 Processor Programmers Reference Vol 2
- *
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
- * David Mosberger <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- *
- * 05/22/2000 eranian Added support for stacked register calls
- * 05/24/2000 eranian Added support for physical mode static calls
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-#include <asm/processor.h>
-
- .data
-pal_entry_point:
- data8 ia64_pal_default_handler
- .text
-
-/*
- * Set the PAL entry point address. This could be written in C code, but we
- * do it here to keep it all in one module (besides, it's so trivial that it's
- * not a big deal).
- *
- * in0 Address of the PAL entry point (text address, NOT a function
- * descriptor).
- */
-GLOBAL_ENTRY(ia64_pal_handler_init)
- alloc r3=ar.pfs,1,0,0,0
- movl r2=pal_entry_point
- ;;
- st8 [r2]=in0
- br.ret.sptk.many rp
-END(ia64_pal_handler_init)
-
-/*
- * Default PAL call handler. This needs to be coded in assembly because it
- * uses the static calling convention, i.e., the RSE may not be used and
- * calls are done via "br.cond" (not "br.call").
- */
-GLOBAL_ENTRY(ia64_pal_default_handler)
- mov r8=-1
- br.cond.sptk.many rp
-END(ia64_pal_default_handler)
-
-/*
- * Make a PAL call using the static calling convention.
- *
- * in0 Index of PAL service
- * in1 - in3 Remaining PAL arguments
- */
-GLOBAL_ENTRY(ia64_pal_call_static)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
- alloc loc1 = ar.pfs,4,5,0,0
- movl loc2 = pal_entry_point
-1: {
- mov r28 = in0
- mov r29 = in1
- mov r8 = ip
- }
- ;;
- ld8 loc2 = [loc2] // loc2 <- entry point
- adds r8 = 1f-1b,r8
- mov loc4=ar.rsc // save RSE configuration
- ;;
- mov ar.rsc=0 // put RSE in enforced lazy, LE mode
- mov loc3 = psr
- mov loc0 = rp
- .body
- mov r30 = in2
-
- mov r31 = in3
- mov b7 = loc2
-
- rsm psr.i
- ;;
- mov rp = r8
- br.cond.sptk.many b7
-1: mov psr.l = loc3
- mov ar.rsc = loc4 // restore RSE configuration
- mov ar.pfs = loc1
- mov rp = loc0
- ;;
- srlz.d // serialize restoration of psr.l
- br.ret.sptk.many b0
-END(ia64_pal_call_static)
-EXPORT_SYMBOL(ia64_pal_call_static)
-
-/*
- * Make a PAL call using the stacked registers calling convention.
- *
- * Inputs:
- * in0 Index of PAL service
- * in2 - in3 Remaining PAL arguments
- */
-GLOBAL_ENTRY(ia64_pal_call_stacked)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
- alloc loc1 = ar.pfs,4,4,4,0
- movl loc2 = pal_entry_point
-
- mov r28 = in0 // Index MUST be copied to r28
- mov out0 = in0 // AND in0 of PAL function
- mov loc0 = rp
- .body
- ;;
- ld8 loc2 = [loc2] // loc2 <- entry point
- mov out1 = in1
- mov out2 = in2
- mov out3 = in3
- mov loc3 = psr
- ;;
- rsm psr.i
- mov b7 = loc2
- ;;
- br.call.sptk.many rp=b7 // now make the call
-.ret0: mov psr.l = loc3
- mov ar.pfs = loc1
- mov rp = loc0
- ;;
- srlz.d // serialize restoration of psr.l
- br.ret.sptk.many b0
-END(ia64_pal_call_stacked)
-EXPORT_SYMBOL(ia64_pal_call_stacked)
-
-/*
- * Make a physical mode PAL call using the static registers calling convention.
- *
- * Inputs:
- * in0 Index of PAL service
- * in2 - in3 Remaining PAL arguments
- *
- * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
- * So we don't need to clear them.
- */
-#define PAL_PSR_BITS_TO_CLEAR \
- (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT |\
- IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \
- IA64_PSR_DFL | IA64_PSR_DFH)
-
-#define PAL_PSR_BITS_TO_SET \
- (IA64_PSR_BN)
-
-
-GLOBAL_ENTRY(ia64_pal_call_phys_static)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
- alloc loc1 = ar.pfs,4,7,0,0
- movl loc2 = pal_entry_point
-1: {
- mov r28 = in0 // copy procedure index
- mov r8 = ip // save ip to compute branch
- mov loc0 = rp // save rp
- }
- .body
- ;;
- ld8 loc2 = [loc2] // loc2 <- entry point
- mov r29 = in1 // first argument
- mov r30 = in2 // copy arg2
- mov r31 = in3 // copy arg3
- ;;
- mov loc3 = psr // save psr
- adds r8 = 1f-1b,r8 // calculate return address for call
- ;;
- mov loc4=ar.rsc // save RSE configuration
- dep.z loc2=loc2,0,61 // convert pal entry point to physical
- tpa r8=r8 // convert rp to physical
- ;;
- mov b7 = loc2 // install target to branch reg
- mov ar.rsc=0 // put RSE in enforced lazy, LE mode
- movl r16=PAL_PSR_BITS_TO_CLEAR
- movl r17=PAL_PSR_BITS_TO_SET
- ;;
- or loc3=loc3,r17 // add in psr the bits to set
- ;;
- andcm r16=loc3,r16 // removes bits to clear from psr
- br.call.sptk.many rp=ia64_switch_mode_phys
- mov rp = r8 // install return address (physical)
- mov loc5 = r19
- mov loc6 = r20
- br.cond.sptk.many b7
-1:
- mov ar.rsc=0 // put RSE in enforced lazy, LE mode
- mov r16=loc3 // r16= original psr
- mov r19=loc5
- mov r20=loc6
- br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
- mov psr.l = loc3 // restore init PSR
-
- mov ar.pfs = loc1
- mov rp = loc0
- ;;
- mov ar.rsc=loc4 // restore RSE configuration
- srlz.d // serialize restoration of psr.l
- br.ret.sptk.many b0
-END(ia64_pal_call_phys_static)
-EXPORT_SYMBOL(ia64_pal_call_phys_static)
-
-/*
- * Make a PAL call using the stacked registers in physical mode.
- *
- * Inputs:
- * in0 Index of PAL service
- * in2 - in3 Remaining PAL arguments
- */
-GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
- alloc loc1 = ar.pfs,5,7,4,0
- movl loc2 = pal_entry_point
-1: {
- mov r28 = in0 // copy procedure index
- mov loc0 = rp // save rp
- }
- .body
- ;;
- ld8 loc2 = [loc2] // loc2 <- entry point
- mov loc3 = psr // save psr
- ;;
- mov loc4=ar.rsc // save RSE configuration
- dep.z loc2=loc2,0,61 // convert pal entry point to physical
- ;;
- mov ar.rsc=0 // put RSE in enforced lazy, LE mode
- movl r16=PAL_PSR_BITS_TO_CLEAR
- movl r17=PAL_PSR_BITS_TO_SET
- ;;
- or loc3=loc3,r17 // add in psr the bits to set
- mov b7 = loc2 // install target to branch reg
- ;;
- andcm r16=loc3,r16 // removes bits to clear from psr
- br.call.sptk.many rp=ia64_switch_mode_phys
-
- mov out0 = in0 // first argument
- mov out1 = in1 // copy arg2
- mov out2 = in2 // copy arg3
- mov out3 = in3 // copy arg3
- mov loc5 = r19
- mov loc6 = r20
-
- br.call.sptk.many rp=b7 // now make the call
-
- mov ar.rsc=0 // put RSE in enforced lazy, LE mode
- mov r16=loc3 // r16= original psr
- mov r19=loc5
- mov r20=loc6
- br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
-
- mov psr.l = loc3 // restore init PSR
- mov ar.pfs = loc1
- mov rp = loc0
- ;;
- mov ar.rsc=loc4 // restore RSE configuration
- srlz.d // serialize restoration of psr.l
- br.ret.sptk.many b0
-END(ia64_pal_call_phys_stacked)
-EXPORT_SYMBOL(ia64_pal_call_phys_stacked)
-
-/*
- * Save scratch fp scratch regs which aren't saved in pt_regs already
- * (fp10-fp15).
- *
- * NOTE: We need to do this since firmware (SAL and PAL) may use any of the
- * scratch regs fp-low partition.
- *
- * Inputs:
- * in0 Address of stack storage for fp regs
- */
-GLOBAL_ENTRY(ia64_save_scratch_fpregs)
- alloc r3=ar.pfs,1,0,0,0
- add r2=16,in0
- ;;
- stf.spill [in0] = f10,32
- stf.spill [r2] = f11,32
- ;;
- stf.spill [in0] = f12,32
- stf.spill [r2] = f13,32
- ;;
- stf.spill [in0] = f14,32
- stf.spill [r2] = f15,32
- br.ret.sptk.many rp
-END(ia64_save_scratch_fpregs)
-EXPORT_SYMBOL(ia64_save_scratch_fpregs)
-
-/*
- * Load scratch fp scratch regs (fp10-fp15)
- *
- * Inputs:
- * in0 Address of stack storage for fp regs
- */
-GLOBAL_ENTRY(ia64_load_scratch_fpregs)
- alloc r3=ar.pfs,1,0,0,0
- add r2=16,in0
- ;;
- ldf.fill f10 = [in0],32
- ldf.fill f11 = [r2],32
- ;;
- ldf.fill f12 = [in0],32
- ldf.fill f13 = [r2],32
- ;;
- ldf.fill f14 = [in0],32
- ldf.fill f15 = [r2],32
- br.ret.sptk.many rp
-END(ia64_load_scratch_fpregs)
-EXPORT_SYMBOL(ia64_load_scratch_fpregs)
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
deleted file mode 100644
index b9ae093bfe37..000000000000
--- a/arch/ia64/kernel/palinfo.c
+++ /dev/null
@@ -1,942 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * palinfo.c
- *
- * Prints processor specific information reported by PAL.
- * This code is based on specification of PAL as of the
- * Intel IA-64 Architecture Software Developer's Manual v1.0.
- *
- *
- * Copyright (C) 2000-2001, 2003 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 2004 Intel Corporation
- * Ashok Raj <ashok.raj@intel.com>
- *
- * 05/26/2000 S.Eranian initial release
- * 08/21/2000 S.Eranian updated to July 2000 PAL specs
- * 02/05/2001 S.Eranian fixed module support
- * 10/23/2001 S.Eranian updated pal_perf_mon_info bug fixes
- * 03/24/2004 Ashok Raj updated to work with CPU Hotplug
- * 10/26/2006 Russ Anderson updated processor features to rev 2.2 spec
- */
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/efi.h>
-#include <linux/notifier.h>
-#include <linux/cpu.h>
-#include <linux/cpumask.h>
-
-#include <asm/pal.h>
-#include <asm/sal.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <linux/smp.h>
-
-MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
-MODULE_DESCRIPTION("/proc interface to IA-64 PAL");
-MODULE_LICENSE("GPL");
-
-#define PALINFO_VERSION "0.5"
-
-typedef int (*palinfo_func_t)(struct seq_file *);
-
-typedef struct {
- const char *name; /* name of the proc entry */
- palinfo_func_t proc_read; /* function to call for reading */
- struct proc_dir_entry *entry; /* registered entry (removal) */
-} palinfo_entry_t;
-
-
-/*
- * A bunch of string array to get pretty printing
- */
-
-static const char *cache_types[] = {
- "", /* not used */
- "Instruction",
- "Data",
- "Data/Instruction" /* unified */
-};
-
-static const char *cache_mattrib[]={
- "WriteThrough",
- "WriteBack",
- "", /* reserved */
- "" /* reserved */
-};
-
-static const char *cache_st_hints[]={
- "Temporal, level 1",
- "Reserved",
- "Reserved",
- "Non-temporal, all levels",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved"
-};
-
-static const char *cache_ld_hints[]={
- "Temporal, level 1",
- "Non-temporal, level 1",
- "Reserved",
- "Non-temporal, all levels",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved"
-};
-
-static const char *rse_hints[]={
- "enforced lazy",
- "eager stores",
- "eager loads",
- "eager loads and stores"
-};
-
-#define RSE_HINTS_COUNT ARRAY_SIZE(rse_hints)
-
-static const char *mem_attrib[]={
- "WB", /* 000 */
- "SW", /* 001 */
- "010", /* 010 */
- "011", /* 011 */
- "UC", /* 100 */
- "UCE", /* 101 */
- "WC", /* 110 */
- "NaTPage" /* 111 */
-};
-
-/*
- * Take a 64bit vector and produces a string such that
- * if bit n is set then 2^n in clear text is generated. The adjustment
- * to the right unit is also done.
- *
- * Input:
- * - a pointer to a buffer to hold the string
- * - a 64-bit vector
- * Output:
- * - a pointer to the end of the buffer
- *
- */
-static void bitvector_process(struct seq_file *m, u64 vector)
-{
- int i,j;
- static const char *units[]={ "", "K", "M", "G", "T" };
-
- for (i=0, j=0; i < 64; i++ , j=i/10) {
- if (vector & 0x1)
- seq_printf(m, "%d%s ", 1 << (i-j*10), units[j]);
- vector >>= 1;
- }
-}
-
-/*
- * Take a 64bit vector and produces a string such that
- * if bit n is set then register n is present. The function
- * takes into account consecutive registers and prints out ranges.
- *
- * Input:
- * - a pointer to a buffer to hold the string
- * - a 64-bit vector
- * Ouput:
- * - a pointer to the end of the buffer
- *
- */
-static void bitregister_process(struct seq_file *m, u64 *reg_info, int max)
-{
- int i, begin, skip = 0;
- u64 value = reg_info[0];
-
- value >>= i = begin = ffs(value) - 1;
-
- for(; i < max; i++ ) {
-
- if (i != 0 && (i%64) == 0) value = *++reg_info;
-
- if ((value & 0x1) == 0 && skip == 0) {
- if (begin <= i - 2)
- seq_printf(m, "%d-%d ", begin, i-1);
- else
- seq_printf(m, "%d ", i-1);
- skip = 1;
- begin = -1;
- } else if ((value & 0x1) && skip == 1) {
- skip = 0;
- begin = i;
- }
- value >>=1;
- }
- if (begin > -1) {
- if (begin < 127)
- seq_printf(m, "%d-127", begin);
- else
- seq_puts(m, "127");
- }
-}
-
-static int power_info(struct seq_file *m)
-{
- s64 status;
- u64 halt_info_buffer[8];
- pal_power_mgmt_info_u_t *halt_info =(pal_power_mgmt_info_u_t *)halt_info_buffer;
- int i;
-
- status = ia64_pal_halt_info(halt_info);
- if (status != 0) return 0;
-
- for (i=0; i < 8 ; i++ ) {
- if (halt_info[i].pal_power_mgmt_info_s.im == 1) {
- seq_printf(m,
- "Power level %d:\n"
- "\tentry_latency : %d cycles\n"
- "\texit_latency : %d cycles\n"
- "\tpower consumption : %d mW\n"
- "\tCache+TLB coherency : %s\n", i,
- halt_info[i].pal_power_mgmt_info_s.entry_latency,
- halt_info[i].pal_power_mgmt_info_s.exit_latency,
- halt_info[i].pal_power_mgmt_info_s.power_consumption,
- halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No");
- } else {
- seq_printf(m,"Power level %d: not implemented\n", i);
- }
- }
- return 0;
-}
-
-static int cache_info(struct seq_file *m)
-{
- unsigned long i, levels, unique_caches;
- pal_cache_config_info_t cci;
- int j, k;
- long status;
-
- if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
- printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status);
- return 0;
- }
-
- seq_printf(m, "Cache levels : %ld\nUnique caches : %ld\n\n",
- levels, unique_caches);
-
- for (i=0; i < levels; i++) {
- for (j=2; j >0 ; j--) {
- /* even without unification some level may not be present */
- if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0)
- continue;
-
- seq_printf(m,
- "%s Cache level %lu:\n"
- "\tSize : %u bytes\n"
- "\tAttributes : ",
- cache_types[j+cci.pcci_unified], i+1,
- cci.pcci_cache_size);
-
- if (cci.pcci_unified)
- seq_puts(m, "Unified ");
-
- seq_printf(m, "%s\n", cache_mattrib[cci.pcci_cache_attr]);
-
- seq_printf(m,
- "\tAssociativity : %d\n"
- "\tLine size : %d bytes\n"
- "\tStride : %d bytes\n",
- cci.pcci_assoc,
- 1<<cci.pcci_line_size,
- 1<<cci.pcci_stride);
- if (j == 1)
- seq_puts(m, "\tStore latency : N/A\n");
- else
- seq_printf(m, "\tStore latency : %d cycle(s)\n",
- cci.pcci_st_latency);
-
- seq_printf(m,
- "\tLoad latency : %d cycle(s)\n"
- "\tStore hints : ", cci.pcci_ld_latency);
-
- for(k=0; k < 8; k++ ) {
- if ( cci.pcci_st_hints & 0x1)
- seq_printf(m, "[%s]", cache_st_hints[k]);
- cci.pcci_st_hints >>=1;
- }
- seq_puts(m, "\n\tLoad hints : ");
-
- for(k=0; k < 8; k++ ) {
- if (cci.pcci_ld_hints & 0x1)
- seq_printf(m, "[%s]", cache_ld_hints[k]);
- cci.pcci_ld_hints >>=1;
- }
- seq_printf(m,
- "\n\tAlias boundary : %d byte(s)\n"
- "\tTag LSB : %d\n"
- "\tTag MSB : %d\n",
- 1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb,
- cci.pcci_tag_msb);
-
- /* when unified, data(j=2) is enough */
- if (cci.pcci_unified)
- break;
- }
- }
- return 0;
-}
-
-
-static int vm_info(struct seq_file *m)
-{
- u64 tr_pages =0, vw_pages=0, tc_pages;
- u64 attrib;
- pal_vm_info_1_u_t vm_info_1;
- pal_vm_info_2_u_t vm_info_2;
- pal_tc_info_u_t tc_info;
- ia64_ptce_info_t ptce;
- const char *sep;
- int i, j;
- long status;
-
- if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
- printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
- } else {
-
- seq_printf(m,
- "Physical Address Space : %d bits\n"
- "Virtual Address Space : %d bits\n"
- "Protection Key Registers(PKR) : %d\n"
- "Implemented bits in PKR.key : %d\n"
- "Hash Tag ID : 0x%x\n"
- "Size of RR.rid : %d\n"
- "Max Purges : ",
- vm_info_1.pal_vm_info_1_s.phys_add_size,
- vm_info_2.pal_vm_info_2_s.impl_va_msb+1,
- vm_info_1.pal_vm_info_1_s.max_pkr+1,
- vm_info_1.pal_vm_info_1_s.key_size,
- vm_info_1.pal_vm_info_1_s.hash_tag_id,
- vm_info_2.pal_vm_info_2_s.rid_size);
- if (vm_info_2.pal_vm_info_2_s.max_purges == PAL_MAX_PURGES)
- seq_puts(m, "unlimited\n");
- else
- seq_printf(m, "%d\n",
- vm_info_2.pal_vm_info_2_s.max_purges ?
- vm_info_2.pal_vm_info_2_s.max_purges : 1);
- }
-
- if (ia64_pal_mem_attrib(&attrib) == 0) {
- seq_puts(m, "Supported memory attributes : ");
- sep = "";
- for (i = 0; i < 8; i++) {
- if (attrib & (1 << i)) {
- seq_printf(m, "%s%s", sep, mem_attrib[i]);
- sep = ", ";
- }
- }
- seq_putc(m, '\n');
- }
-
- if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
- printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status);
- } else {
-
- seq_printf(m,
- "\nTLB walker : %simplemented\n"
- "Number of DTR : %d\n"
- "Number of ITR : %d\n"
- "TLB insertable page sizes : ",
- vm_info_1.pal_vm_info_1_s.vw ? "" : "not ",
- vm_info_1.pal_vm_info_1_s.max_dtr_entry+1,
- vm_info_1.pal_vm_info_1_s.max_itr_entry+1);
-
- bitvector_process(m, tr_pages);
-
- seq_puts(m, "\nTLB purgeable page sizes : ");
-
- bitvector_process(m, vw_pages);
- }
-
- if ((status = ia64_get_ptce(&ptce)) != 0) {
- printk(KERN_ERR "ia64_get_ptce=%ld\n", status);
- } else {
- seq_printf(m,
- "\nPurge base address : 0x%016lx\n"
- "Purge outer loop count : %d\n"
- "Purge inner loop count : %d\n"
- "Purge outer loop stride : %d\n"
- "Purge inner loop stride : %d\n",
- ptce.base, ptce.count[0], ptce.count[1],
- ptce.stride[0], ptce.stride[1]);
-
- seq_printf(m,
- "TC Levels : %d\n"
- "Unique TC(s) : %d\n",
- vm_info_1.pal_vm_info_1_s.num_tc_levels,
- vm_info_1.pal_vm_info_1_s.max_unique_tcs);
-
- for(i=0; i < vm_info_1.pal_vm_info_1_s.num_tc_levels; i++) {
- for (j=2; j>0 ; j--) {
- tc_pages = 0; /* just in case */
-
- /* even without unification, some levels may not be present */
- if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0)
- continue;
-
- seq_printf(m,
- "\n%s Translation Cache Level %d:\n"
- "\tHash sets : %d\n"
- "\tAssociativity : %d\n"
- "\tNumber of entries : %d\n"
- "\tFlags : ",
- cache_types[j+tc_info.tc_unified], i+1,
- tc_info.tc_num_sets,
- tc_info.tc_associativity,
- tc_info.tc_num_entries);
-
- if (tc_info.tc_pf)
- seq_puts(m, "PreferredPageSizeOptimized ");
- if (tc_info.tc_unified)
- seq_puts(m, "Unified ");
- if (tc_info.tc_reduce_tr)
- seq_puts(m, "TCReduction");
-
- seq_puts(m, "\n\tSupported page sizes: ");
-
- bitvector_process(m, tc_pages);
-
- /* when unified date (j=2) is enough */
- if (tc_info.tc_unified)
- break;
- }
- }
- }
-
- seq_putc(m, '\n');
- return 0;
-}
-
-
-static int register_info(struct seq_file *m)
-{
- u64 reg_info[2];
- u64 info;
- unsigned long phys_stacked;
- pal_hints_u_t hints;
- unsigned long iregs, dregs;
- static const char * const info_type[] = {
- "Implemented AR(s)",
- "AR(s) with read side-effects",
- "Implemented CR(s)",
- "CR(s) with read side-effects",
- };
-
- for(info=0; info < 4; info++) {
- if (ia64_pal_register_info(info, &reg_info[0], &reg_info[1]) != 0)
- return 0;
- seq_printf(m, "%-32s : ", info_type[info]);
- bitregister_process(m, reg_info, 128);
- seq_putc(m, '\n');
- }
-
- if (ia64_pal_rse_info(&phys_stacked, &hints) == 0)
- seq_printf(m,
- "RSE stacked physical registers : %ld\n"
- "RSE load/store hints : %ld (%s)\n",
- phys_stacked, hints.ph_data,
- hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)");
-
- if (ia64_pal_debug_info(&iregs, &dregs))
- return 0;
-
- seq_printf(m,
- "Instruction debug register pairs : %ld\n"
- "Data debug register pairs : %ld\n", iregs, dregs);
-
- return 0;
-}
-
-static const char *const proc_features_0[]={ /* Feature set 0 */
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,
- "Unimplemented instruction address fault",
- "INIT, PMI, and LINT pins",
- "Simple unimplemented instr addresses",
- "Variable P-state performance",
- "Virtual machine features implemented",
- "XIP,XPSR,XFS implemented",
- "XR1-XR3 implemented",
- "Disable dynamic predicate prediction",
- "Disable processor physical number",
- "Disable dynamic data cache prefetch",
- "Disable dynamic inst cache prefetch",
- "Disable dynamic branch prediction",
- NULL, NULL, NULL, NULL,
- "Disable P-states",
- "Enable MCA on Data Poisoning",
- "Enable vmsw instruction",
- "Enable extern environmental notification",
- "Disable BINIT on processor time-out",
- "Disable dynamic power management (DPM)",
- "Disable coherency",
- "Disable cache",
- "Enable CMCI promotion",
- "Enable MCA to BINIT promotion",
- "Enable MCA promotion",
- "Enable BERR promotion"
-};
-
-static const char *const proc_features_16[]={ /* Feature set 16 */
- "Disable ETM",
- "Enable ETM",
- "Enable MCA on half-way timer",
- "Enable snoop WC",
- NULL,
- "Enable Fast Deferral",
- "Disable MCA on memory aliasing",
- "Enable RSB",
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- "DP system processor",
- "Low Voltage",
- "HT supported",
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL
-};
-
-static const char *const *const proc_features[]={
- proc_features_0,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- proc_features_16,
- NULL, NULL, NULL, NULL,
-};
-
-static void feature_set_info(struct seq_file *m, u64 avail, u64 status, u64 control,
- unsigned long set)
-{
- const char *const *vf, *const *v;
- int i;
-
- vf = v = proc_features[set];
- for(i=0; i < 64; i++, avail >>=1, status >>=1, control >>=1) {
-
- if (!(control)) /* No remaining bits set */
- break;
- if (!(avail & 0x1)) /* Print only bits that are available */
- continue;
- if (vf)
- v = vf + i;
- if ( v && *v ) {
- seq_printf(m, "%-40s : %s %s\n", *v,
- avail & 0x1 ? (status & 0x1 ?
- "On " : "Off"): "",
- avail & 0x1 ? (control & 0x1 ?
- "Ctrl" : "NoCtrl"): "");
- } else {
- seq_printf(m, "Feature set %2ld bit %2d\t\t\t"
- " : %s %s\n",
- set, i,
- avail & 0x1 ? (status & 0x1 ?
- "On " : "Off"): "",
- avail & 0x1 ? (control & 0x1 ?
- "Ctrl" : "NoCtrl"): "");
- }
- }
-}
-
-static int processor_info(struct seq_file *m)
-{
- u64 avail=1, status=1, control=1, feature_set=0;
- s64 ret;
-
- do {
- ret = ia64_pal_proc_get_features(&avail, &status, &control,
- feature_set);
- if (ret < 0)
- return 0;
-
- if (ret == 1) {
- feature_set++;
- continue;
- }
-
- feature_set_info(m, avail, status, control, feature_set);
- feature_set++;
- } while(1);
-
- return 0;
-}
-
-static const char *const bus_features[]={
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,
- "Request Bus Parking",
- "Bus Lock Mask",
- "Enable Half Transfer",
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- "Enable Cache Line Repl. Shared",
- "Enable Cache Line Repl. Exclusive",
- "Disable Transaction Queuing",
- "Disable Response Error Checking",
- "Disable Bus Error Checking",
- "Disable Bus Requester Internal Error Signalling",
- "Disable Bus Requester Error Signalling",
- "Disable Bus Initialization Event Checking",
- "Disable Bus Initialization Event Signalling",
- "Disable Bus Address Error Checking",
- "Disable Bus Address Error Signalling",
- "Disable Bus Data Error Checking"
-};
-
-
-static int bus_info(struct seq_file *m)
-{
- const char *const *v = bus_features;
- pal_bus_features_u_t av, st, ct;
- u64 avail, status, control;
- int i;
- s64 ret;
-
- if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0)
- return 0;
-
- avail = av.pal_bus_features_val;
- status = st.pal_bus_features_val;
- control = ct.pal_bus_features_val;
-
- for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) {
- if ( ! *v )
- continue;
- seq_printf(m, "%-48s : %s%s %s\n", *v,
- avail & 0x1 ? "" : "NotImpl",
- avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "",
- avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): "");
- }
- return 0;
-}
-
-static int version_info(struct seq_file *m)
-{
- pal_version_u_t min_ver, cur_ver;
-
- if (ia64_pal_version(&min_ver, &cur_ver) != 0)
- return 0;
-
- seq_printf(m,
- "PAL_vendor : 0x%02x (min=0x%02x)\n"
- "PAL_A : %02x.%02x (min=%02x.%02x)\n"
- "PAL_B : %02x.%02x (min=%02x.%02x)\n",
- cur_ver.pal_version_s.pv_pal_vendor,
- min_ver.pal_version_s.pv_pal_vendor,
- cur_ver.pal_version_s.pv_pal_a_model,
- cur_ver.pal_version_s.pv_pal_a_rev,
- min_ver.pal_version_s.pv_pal_a_model,
- min_ver.pal_version_s.pv_pal_a_rev,
- cur_ver.pal_version_s.pv_pal_b_model,
- cur_ver.pal_version_s.pv_pal_b_rev,
- min_ver.pal_version_s.pv_pal_b_model,
- min_ver.pal_version_s.pv_pal_b_rev);
- return 0;
-}
-
-static int frequency_info(struct seq_file *m)
-{
- struct pal_freq_ratio proc, itc, bus;
- unsigned long base;
-
- if (ia64_pal_freq_base(&base) == -1)
- seq_puts(m, "Output clock : not implemented\n");
- else
- seq_printf(m, "Output clock : %ld ticks/s\n", base);
-
- if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0;
-
- seq_printf(m,
- "Processor/Clock ratio : %d/%d\n"
- "Bus/Clock ratio : %d/%d\n"
- "ITC/Clock ratio : %d/%d\n",
- proc.num, proc.den, bus.num, bus.den, itc.num, itc.den);
- return 0;
-}
-
-static int tr_info(struct seq_file *m)
-{
- long status;
- pal_tr_valid_u_t tr_valid;
- u64 tr_buffer[4];
- pal_vm_info_1_u_t vm_info_1;
- pal_vm_info_2_u_t vm_info_2;
- unsigned long i, j;
- unsigned long max[3], pgm;
- struct ifa_reg {
- unsigned long valid:1;
- unsigned long ig:11;
- unsigned long vpn:52;
- } *ifa_reg;
- struct itir_reg {
- unsigned long rv1:2;
- unsigned long ps:6;
- unsigned long key:24;
- unsigned long rv2:32;
- } *itir_reg;
- struct gr_reg {
- unsigned long p:1;
- unsigned long rv1:1;
- unsigned long ma:3;
- unsigned long a:1;
- unsigned long d:1;
- unsigned long pl:2;
- unsigned long ar:3;
- unsigned long ppn:38;
- unsigned long rv2:2;
- unsigned long ed:1;
- unsigned long ig:11;
- } *gr_reg;
- struct rid_reg {
- unsigned long ig1:1;
- unsigned long rv1:1;
- unsigned long ig2:6;
- unsigned long rid:24;
- unsigned long rv2:32;
- } *rid_reg;
-
- if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
- printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
- return 0;
- }
- max[0] = vm_info_1.pal_vm_info_1_s.max_itr_entry+1;
- max[1] = vm_info_1.pal_vm_info_1_s.max_dtr_entry+1;
-
- for (i=0; i < 2; i++ ) {
- for (j=0; j < max[i]; j++) {
-
- status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid);
- if (status != 0) {
- printk(KERN_ERR "palinfo: pal call failed on tr[%lu:%lu]=%ld\n",
- i, j, status);
- continue;
- }
-
- ifa_reg = (struct ifa_reg *)&tr_buffer[2];
-
- if (ifa_reg->valid == 0)
- continue;
-
- gr_reg = (struct gr_reg *)tr_buffer;
- itir_reg = (struct itir_reg *)&tr_buffer[1];
- rid_reg = (struct rid_reg *)&tr_buffer[3];
-
- pgm = -1 << (itir_reg->ps - 12);
- seq_printf(m,
- "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n"
- "\tppn : 0x%lx\n"
- "\tvpn : 0x%lx\n"
- "\tps : ",
- "ID"[i], j,
- tr_valid.pal_tr_valid_s.access_rights_valid,
- tr_valid.pal_tr_valid_s.priv_level_valid,
- tr_valid.pal_tr_valid_s.dirty_bit_valid,
- tr_valid.pal_tr_valid_s.mem_attr_valid,
- (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12);
-
- bitvector_process(m, 1<< itir_reg->ps);
-
- seq_printf(m,
- "\n\tpl : %d\n"
- "\tar : %d\n"
- "\trid : %x\n"
- "\tp : %d\n"
- "\tma : %d\n"
- "\td : %d\n",
- gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma,
- gr_reg->d);
- }
- }
- return 0;
-}
-
-
-
-/*
- * List {name,function} pairs for every entry in /proc/palinfo/cpu*
- */
-static const palinfo_entry_t palinfo_entries[]={
- { "version_info", version_info, },
- { "vm_info", vm_info, },
- { "cache_info", cache_info, },
- { "power_info", power_info, },
- { "register_info", register_info, },
- { "processor_info", processor_info, },
- { "frequency_info", frequency_info, },
- { "bus_info", bus_info },
- { "tr_info", tr_info, }
-};
-
-#define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries)
-
-static struct proc_dir_entry *palinfo_dir;
-
-/*
- * This data structure is used to pass which cpu,function is being requested
- * It must fit in a 64bit quantity to be passed to the proc callback routine
- *
- * In SMP mode, when we get a request for another CPU, we must call that
- * other CPU using IPI and wait for the result before returning.
- */
-typedef union {
- u64 value;
- struct {
- unsigned req_cpu: 32; /* for which CPU this info is */
- unsigned func_id: 32; /* which function is requested */
- } pal_func_cpu;
-} pal_func_cpu_u_t;
-
-#define req_cpu pal_func_cpu.req_cpu
-#define func_id pal_func_cpu.func_id
-
-#ifdef CONFIG_SMP
-
-/*
- * used to hold information about final function to call
- */
-typedef struct {
- palinfo_func_t func; /* pointer to function to call */
- struct seq_file *m; /* buffer to store results */
- int ret; /* return value from call */
-} palinfo_smp_data_t;
-
-
-/*
- * this function does the actual final call and he called
- * from the smp code, i.e., this is the palinfo callback routine
- */
-static void
-palinfo_smp_call(void *info)
-{
- palinfo_smp_data_t *data = (palinfo_smp_data_t *)info;
- data->ret = (*data->func)(data->m);
-}
-
-/*
- * function called to trigger the IPI, we need to access a remote CPU
- * Return:
- * 0 : error or nothing to output
- * otherwise how many bytes in the "page" buffer were written
- */
-static
-int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f)
-{
- palinfo_smp_data_t ptr;
- int ret;
-
- ptr.func = palinfo_entries[f->func_id].proc_read;
- ptr.m = m;
- ptr.ret = 0; /* just in case */
-
-
- /* will send IPI to other CPU and wait for completion of remote call */
- if ((ret=smp_call_function_single(f->req_cpu, palinfo_smp_call, &ptr, 1))) {
- printk(KERN_ERR "palinfo: remote CPU call from %d to %d on function %d: "
- "error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret);
- return 0;
- }
- return ptr.ret;
-}
-#else /* ! CONFIG_SMP */
-static
-int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f)
-{
- printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n");
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-/*
- * Entry point routine: all calls go through this function
- */
-static int proc_palinfo_show(struct seq_file *m, void *v)
-{
- pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&m->private;
-
- /*
- * in SMP mode, we may need to call another CPU to get correct
- * information. PAL, by definition, is processor specific
- */
- if (f->req_cpu == get_cpu())
- (*palinfo_entries[f->func_id].proc_read)(m);
- else
- palinfo_handle_smp(m, f);
-
- put_cpu();
- return 0;
-}
-
-static int palinfo_add_proc(unsigned int cpu)
-{
- pal_func_cpu_u_t f;
- struct proc_dir_entry *cpu_dir;
- int j;
- char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */
- sprintf(cpustr, "cpu%d", cpu);
-
- cpu_dir = proc_mkdir(cpustr, palinfo_dir);
- if (!cpu_dir)
- return -EINVAL;
-
- f.req_cpu = cpu;
-
- for (j=0; j < NR_PALINFO_ENTRIES; j++) {
- f.func_id = j;
- proc_create_single_data(palinfo_entries[j].name, 0, cpu_dir,
- proc_palinfo_show, (void *)f.value);
- }
- return 0;
-}
-
-static int palinfo_del_proc(unsigned int hcpu)
-{
- char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */
-
- sprintf(cpustr, "cpu%d", hcpu);
- remove_proc_subtree(cpustr, palinfo_dir);
- return 0;
-}
-
-static enum cpuhp_state hp_online;
-
-static int __init palinfo_init(void)
-{
- int i = 0;
-
- printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION);
- palinfo_dir = proc_mkdir("pal", NULL);
- if (!palinfo_dir)
- return -ENOMEM;
-
- i = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "ia64/palinfo:online",
- palinfo_add_proc, palinfo_del_proc);
- if (i < 0) {
- remove_proc_subtree("pal", NULL);
- return i;
- }
- hp_online = i;
- return 0;
-}
-
-static void __exit palinfo_exit(void)
-{
- cpuhp_remove_state(hp_online);
- remove_proc_subtree("pal", NULL);
-}
-
-module_init(palinfo_init);
-module_exit(palinfo_exit);
diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c
deleted file mode 100644
index 7f21a8c57ed7..000000000000
--- a/arch/ia64/kernel/patch.c
+++ /dev/null
@@ -1,237 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Instruction-patching support.
- *
- * Copyright (C) 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#include <linux/init.h>
-#include <linux/string.h>
-
-#include <asm/patch.h>
-#include <asm/processor.h>
-#include <asm/sections.h>
-#include <asm/unistd.h>
-
-/*
- * This was adapted from code written by Tony Luck:
- *
- * The 64-bit value in a "movl reg=value" is scattered between the two words of the bundle
- * like this:
- *
- * 6 6 5 4 3 2 1
- * 3210987654321098765432109876543210987654321098765432109876543210
- * ABBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCDEEEEEFFFFFFFFFGGGGGGG
- *
- * CCCCCCCCCCCCCCCCCCxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- * xxxxAFFFFFFFFFEEEEEDxGGGGGGGxxxxxxxxxxxxxBBBBBBBBBBBBBBBBBBBBBBB
- */
-static u64
-get_imm64 (u64 insn_addr)
-{
- u64 *p = (u64 *) (insn_addr & -16); /* mask out slot number */
-
- return ( (p[1] & 0x0800000000000000UL) << 4) | /*A*/
- ((p[1] & 0x00000000007fffffUL) << 40) | /*B*/
- ((p[0] & 0xffffc00000000000UL) >> 24) | /*C*/
- ((p[1] & 0x0000100000000000UL) >> 23) | /*D*/
- ((p[1] & 0x0003e00000000000UL) >> 29) | /*E*/
- ((p[1] & 0x07fc000000000000UL) >> 43) | /*F*/
- ((p[1] & 0x000007f000000000UL) >> 36); /*G*/
-}
-
-/* Patch instruction with "val" where "mask" has 1 bits. */
-void
-ia64_patch (u64 insn_addr, u64 mask, u64 val)
-{
- u64 m0, m1, v0, v1, b0, b1, *b = (u64 *) (insn_addr & -16);
-# define insn_mask ((1UL << 41) - 1)
- unsigned long shift;
-
- b0 = b[0]; b1 = b[1];
- shift = 5 + 41 * (insn_addr % 16); /* 5 bits of template, then 3 x 41-bit instructions */
- if (shift >= 64) {
- m1 = mask << (shift - 64);
- v1 = val << (shift - 64);
- } else {
- m0 = mask << shift; m1 = mask >> (64 - shift);
- v0 = val << shift; v1 = val >> (64 - shift);
- b[0] = (b0 & ~m0) | (v0 & m0);
- }
- b[1] = (b1 & ~m1) | (v1 & m1);
-}
-
-void
-ia64_patch_imm64 (u64 insn_addr, u64 val)
-{
- /* The assembler may generate offset pointing to either slot 1
- or slot 2 for a long (2-slot) instruction, occupying slots 1
- and 2. */
- insn_addr &= -16UL;
- ia64_patch(insn_addr + 2,
- 0x01fffefe000UL, ( ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
- | ((val & 0x0000000000200000UL) << 0) /* bit 21 -> 21 */
- | ((val & 0x00000000001f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x000000000000ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x000000000000007fUL) << 13) /* bit 0 -> 13 */));
- ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22);
-}
-
-void
-ia64_patch_imm60 (u64 insn_addr, u64 val)
-{
- /* The assembler may generate offset pointing to either slot 1
- or slot 2 for a long (2-slot) instruction, occupying slots 1
- and 2. */
- insn_addr &= -16UL;
- ia64_patch(insn_addr + 2,
- 0x011ffffe000UL, ( ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
- | ((val & 0x00000000000fffffUL) << 13) /* bit 0 -> 13 */));
- ia64_patch(insn_addr + 1, 0x1fffffffffcUL, val >> 18);
-}
-
-/*
- * We need sometimes to load the physical address of a kernel
- * object. Often we can convert the virtual address to physical
- * at execution time, but sometimes (either for performance reasons
- * or during error recovery) we cannot to this. Patch the marked
- * bundles to load the physical address.
- */
-void __init
-ia64_patch_vtop (unsigned long start, unsigned long end)
-{
- s32 *offp = (s32 *) start;
- u64 ip;
-
- while (offp < (s32 *) end) {
- ip = (u64) offp + *offp;
-
- /* replace virtual address with corresponding physical address: */
- ia64_patch_imm64(ip, ia64_tpa(get_imm64(ip)));
- ia64_fc((void *) ip);
- ++offp;
- }
- ia64_sync_i();
- ia64_srlz_i();
-}
-
-/*
- * Disable the RSE workaround by turning the conditional branch
- * that we tagged in each place the workaround was used into an
- * unconditional branch.
- */
-void __init
-ia64_patch_rse (unsigned long start, unsigned long end)
-{
- s32 *offp = (s32 *) start;
- u64 ip, *b;
-
- while (offp < (s32 *) end) {
- ip = (u64) offp + *offp;
-
- b = (u64 *)(ip & -16);
- b[1] &= ~0xf800000L;
- ia64_fc((void *) ip);
- ++offp;
- }
- ia64_sync_i();
- ia64_srlz_i();
-}
-
-void __init
-ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
-{
- static int first_time = 1;
- int need_workaround;
- s32 *offp = (s32 *) start;
- u64 *wp;
-
- need_workaround = (local_cpu_data->family == 0x1f && local_cpu_data->model == 0);
-
- if (first_time) {
- first_time = 0;
- if (need_workaround)
- printk(KERN_INFO "Leaving McKinley Errata 9 workaround enabled\n");
- }
- if (need_workaround)
- return;
-
- while (offp < (s32 *) end) {
- wp = (u64 *) ia64_imva((char *) offp + *offp);
- wp[0] = 0x0000000100000011UL; /* nop.m 0; nop.i 0; br.ret.sptk.many b6 */
- wp[1] = 0x0084006880000200UL;
- wp[2] = 0x0000000100000000UL; /* nop.m 0; nop.i 0; nop.i 0 */
- wp[3] = 0x0004000000000200UL;
- ia64_fc(wp); ia64_fc(wp + 2);
- ++offp;
- }
- ia64_sync_i();
- ia64_srlz_i();
-}
-
-static void __init
-patch_fsyscall_table (unsigned long start, unsigned long end)
-{
- extern unsigned long fsyscall_table[NR_syscalls];
- s32 *offp = (s32 *) start;
- u64 ip;
-
- while (offp < (s32 *) end) {
- ip = (u64) ia64_imva((char *) offp + *offp);
- ia64_patch_imm64(ip, (u64) fsyscall_table);
- ia64_fc((void *) ip);
- ++offp;
- }
- ia64_sync_i();
- ia64_srlz_i();
-}
-
-static void __init
-patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
-{
- extern char fsys_bubble_down[];
- s32 *offp = (s32 *) start;
- u64 ip;
-
- while (offp < (s32 *) end) {
- ip = (u64) offp + *offp;
- ia64_patch_imm60((u64) ia64_imva((void *) ip),
- (u64) (fsys_bubble_down - (ip & -16)) / 16);
- ia64_fc((void *) ip);
- ++offp;
- }
- ia64_sync_i();
- ia64_srlz_i();
-}
-
-void __init
-ia64_patch_gate (void)
-{
-# define START(name) ((unsigned long) __start_gate_##name##_patchlist)
-# define END(name) ((unsigned long)__end_gate_##name##_patchlist)
-
- patch_fsyscall_table(START(fsyscall), END(fsyscall));
- patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
- ia64_patch_vtop(START(vtop), END(vtop));
- ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
-}
-
-void ia64_patch_phys_stack_reg(unsigned long val)
-{
- s32 * offp = (s32 *) __start___phys_stack_reg_patchlist;
- s32 * end = (s32 *) __end___phys_stack_reg_patchlist;
- u64 ip, mask, imm;
-
- /* see instruction format A4: adds r1 = imm13, r3 */
- mask = (0x3fUL << 27) | (0x7f << 13);
- imm = (((val >> 7) & 0x3f) << 27) | (val & 0x7f) << 13;
-
- while (offp < end) {
- ip = (u64) offp + *offp;
- ia64_patch(ip, mask, imm);
- ia64_fc((void *)ip);
- ++offp;
- }
- ia64_sync_i();
- ia64_srlz_i();
-}
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
deleted file mode 100644
index c90221733c6b..000000000000
--- a/arch/ia64/kernel/pci-dma.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Dynamic DMA mapping support.
- */
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/dmar.h>
-#include <asm/iommu.h>
-#include <linux/dma-mapping.h>
-#include <linux/kernel.h>
-#include <asm/page.h>
-
-int no_iommu __read_mostly;
-#ifdef CONFIG_IOMMU_DEBUG
-int force_iommu __read_mostly = 1;
-#else
-int force_iommu __read_mostly;
-#endif
-
-static int __init pci_iommu_init(void)
-{
- if (iommu_detected)
- intel_iommu_init();
-
- return 0;
-}
-
-/* Must execute after PCI subsystem */
-fs_initcall(pci_iommu_init);
diff --git a/arch/ia64/kernel/perfmon_itanium.h b/arch/ia64/kernel/perfmon_itanium.h
deleted file mode 100644
index dbd04028aafa..000000000000
--- a/arch/ia64/kernel/perfmon_itanium.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file contains the Itanium PMU register description tables
- * and pmc checker.
- *
- * Copyright (C) 2002-2003 Hewlett Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- */
-static int pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
-
-static pfm_reg_desc_t pfm_ita_pmc_desc[PMU_MAX_PMCS]={
-/* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc4 */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc5 */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc6 */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc7 */ { PFM_REG_COUNTING, 6, 0x0UL, -1UL, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc8 */ { PFM_REG_CONFIG , 0, 0xf00000003ffffff8UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc9 */ { PFM_REG_CONFIG , 0, 0xf00000003ffffff8UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc10 */ { PFM_REG_MONITOR , 6, 0x0UL, -1UL, NULL, NULL, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc11 */ { PFM_REG_MONITOR , 6, 0x0000000010000000UL, -1UL, NULL, pfm_ita_pmc_check, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc12 */ { PFM_REG_MONITOR , 6, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc13 */ { PFM_REG_CONFIG , 0, 0x0003ffff00000001UL, -1UL, NULL, pfm_ita_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
- { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
-};
-
-static pfm_reg_desc_t pfm_ita_pmd_desc[PMU_MAX_PMDS]={
-/* pmd0 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
-/* pmd1 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
-/* pmd2 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
-/* pmd3 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
-/* pmd4 */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
-/* pmd5 */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
-/* pmd6 */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
-/* pmd7 */ { PFM_REG_COUNTING, 0, 0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
-/* pmd8 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
-/* pmd9 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
-/* pmd10 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
-/* pmd11 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
-/* pmd12 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
-/* pmd13 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
-/* pmd14 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
-/* pmd15 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
-/* pmd16 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
-/* pmd17 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
- { PFM_REG_END , 0, 0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
-};
-
-static int
-pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
-{
- int ret;
- int is_loaded;
-
- /* sanitfy check */
- if (ctx == NULL) return -EINVAL;
-
- is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED;
-
- /*
- * we must clear the (instruction) debug registers if pmc13.ta bit is cleared
- * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
- */
- if (cnum == 13 && is_loaded && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) {
-
- DPRINT(("pmc[%d]=0x%lx has active pmc13.ta cleared, clearing ibr\n", cnum, *val));
-
- /* don't mix debug with perfmon */
- if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
-
- /*
- * a count of 0 will mark the debug registers as in use and also
- * ensure that they are properly cleared.
- */
- ret = pfm_write_ibr_dbr(1, ctx, NULL, 0, regs);
- if (ret) return ret;
- }
-
- /*
- * we must clear the (data) debug registers if pmc11.pt bit is cleared
- * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
- */
- if (cnum == 11 && is_loaded && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) {
-
- DPRINT(("pmc[%d]=0x%lx has active pmc11.pt cleared, clearing dbr\n", cnum, *val));
-
- /* don't mix debug with perfmon */
- if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
-
- /*
- * a count of 0 will mark the debug registers as in use and also
- * ensure that they are properly cleared.
- */
- ret = pfm_write_ibr_dbr(0, ctx, NULL, 0, regs);
- if (ret) return ret;
- }
- return 0;
-}
-
-/*
- * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
- */
-static pmu_config_t pmu_conf_ita={
- .pmu_name = "Itanium",
- .pmu_family = 0x7,
- .ovfl_val = (1UL << 32) - 1,
- .pmd_desc = pfm_ita_pmd_desc,
- .pmc_desc = pfm_ita_pmc_desc,
- .num_ibrs = 8,
- .num_dbrs = 8,
- .use_rr_dbregs = 1, /* debug register are use for range retrictions */
-};
-
-
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
deleted file mode 100644
index 9a5cd9fad3a9..000000000000
--- a/arch/ia64/kernel/process.c
+++ /dev/null
@@ -1,611 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Architecture-specific setup.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support
- *
- * 2005-10-07 Keith Owens <kaos@sgi.com>
- * Add notify_die() hooks.
- */
-#include <linux/cpu.h>
-#include <linux/pm.h>
-#include <linux/elf.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/notifier.h>
-#include <linux/personality.h>
-#include <linux/reboot.h>
-#include <linux/sched.h>
-#include <linux/sched/debug.h>
-#include <linux/sched/hotplug.h>
-#include <linux/sched/task.h>
-#include <linux/sched/task_stack.h>
-#include <linux/stddef.h>
-#include <linux/thread_info.h>
-#include <linux/unistd.h>
-#include <linux/efi.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/kdebug.h>
-#include <linux/utsname.h>
-#include <linux/resume_user_mode.h>
-#include <linux/rcupdate.h>
-
-#include <asm/cpu.h>
-#include <asm/delay.h>
-#include <asm/elf.h>
-#include <asm/irq.h>
-#include <asm/kexec.h>
-#include <asm/processor.h>
-#include <asm/sal.h>
-#include <asm/switch_to.h>
-#include <asm/tlbflush.h>
-#include <linux/uaccess.h>
-#include <asm/unwind.h>
-#include <asm/user.h>
-#include <asm/xtp.h>
-
-#include "entry.h"
-
-#include "sigframe.h"
-
-void (*ia64_mark_idle)(int);
-
-unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
-EXPORT_SYMBOL(boot_option_idle_override);
-void (*pm_power_off) (void);
-EXPORT_SYMBOL(pm_power_off);
-
-static void
-ia64_do_show_stack (struct unw_frame_info *info, void *arg)
-{
- unsigned long ip, sp, bsp;
- const char *loglvl = arg;
-
- printk("%s\nCall Trace:\n", loglvl);
- do {
- unw_get_ip(info, &ip);
- if (ip == 0)
- break;
-
- unw_get_sp(info, &sp);
- unw_get_bsp(info, &bsp);
- printk("%s [<%016lx>] %pS\n"
- " sp=%016lx bsp=%016lx\n",
- loglvl, ip, (void *)ip, sp, bsp);
- } while (unw_unwind(info) >= 0);
-}
-
-void
-show_stack (struct task_struct *task, unsigned long *sp, const char *loglvl)
-{
- if (!task)
- unw_init_running(ia64_do_show_stack, (void *)loglvl);
- else {
- struct unw_frame_info info;
-
- unw_init_from_blocked_task(&info, task);
- ia64_do_show_stack(&info, (void *)loglvl);
- }
-}
-
-void
-show_regs (struct pt_regs *regs)
-{
- unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
-
- print_modules();
- printk("\n");
- show_regs_print_info(KERN_DEFAULT);
- printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s)\n",
- regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(),
- init_utsname()->release);
- printk("ip is at %pS\n", (void *)ip);
- printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
- regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
- printk("rnat: %016lx bsps: %016lx pr : %016lx\n",
- regs->ar_rnat, regs->ar_bspstore, regs->pr);
- printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n",
- regs->loadrs, regs->ar_ccv, regs->ar_fpsr);
- printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd);
- printk("b0 : %016lx b6 : %016lx b7 : %016lx\n", regs->b0, regs->b6, regs->b7);
- printk("f6 : %05lx%016lx f7 : %05lx%016lx\n",
- regs->f6.u.bits[1], regs->f6.u.bits[0],
- regs->f7.u.bits[1], regs->f7.u.bits[0]);
- printk("f8 : %05lx%016lx f9 : %05lx%016lx\n",
- regs->f8.u.bits[1], regs->f8.u.bits[0],
- regs->f9.u.bits[1], regs->f9.u.bits[0]);
- printk("f10 : %05lx%016lx f11 : %05lx%016lx\n",
- regs->f10.u.bits[1], regs->f10.u.bits[0],
- regs->f11.u.bits[1], regs->f11.u.bits[0]);
-
- printk("r1 : %016lx r2 : %016lx r3 : %016lx\n", regs->r1, regs->r2, regs->r3);
- printk("r8 : %016lx r9 : %016lx r10 : %016lx\n", regs->r8, regs->r9, regs->r10);
- printk("r11 : %016lx r12 : %016lx r13 : %016lx\n", regs->r11, regs->r12, regs->r13);
- printk("r14 : %016lx r15 : %016lx r16 : %016lx\n", regs->r14, regs->r15, regs->r16);
- printk("r17 : %016lx r18 : %016lx r19 : %016lx\n", regs->r17, regs->r18, regs->r19);
- printk("r20 : %016lx r21 : %016lx r22 : %016lx\n", regs->r20, regs->r21, regs->r22);
- printk("r23 : %016lx r24 : %016lx r25 : %016lx\n", regs->r23, regs->r24, regs->r25);
- printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, regs->r27, regs->r28);
- printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, regs->r30, regs->r31);
-
- if (user_mode(regs)) {
- /* print the stacked registers */
- unsigned long val, *bsp, ndirty;
- int i, sof, is_nat = 0;
-
- sof = regs->cr_ifs & 0x7f; /* size of frame */
- ndirty = (regs->loadrs >> 19);
- bsp = ia64_rse_skip_regs((unsigned long *) regs->ar_bspstore, ndirty);
- for (i = 0; i < sof; ++i) {
- get_user(val, (unsigned long __user *) ia64_rse_skip_regs(bsp, i));
- printk("r%-3u:%c%016lx%s", 32 + i, is_nat ? '*' : ' ', val,
- ((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
- }
- } else
- show_stack(NULL, NULL, KERN_DEFAULT);
-}
-
-/* local support for deprecated console_print */
-void
-console_print(const char *s)
-{
- printk(KERN_EMERG "%s", s);
-}
-
-void
-do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
-{
- if (fsys_mode(current, &scr->pt)) {
- /*
- * defer signal-handling etc. until we return to
- * privilege-level 0.
- */
- if (!ia64_psr(&scr->pt)->lp)
- ia64_psr(&scr->pt)->lp = 1;
- return;
- }
-
- /* deal with pending signal delivery */
- if (test_thread_flag(TIF_SIGPENDING) ||
- test_thread_flag(TIF_NOTIFY_SIGNAL)) {
- local_irq_enable(); /* force interrupt enable */
- ia64_do_signal(scr, in_syscall);
- }
-
- if (test_thread_flag(TIF_NOTIFY_RESUME)) {
- local_irq_enable(); /* force interrupt enable */
- resume_user_mode_work(&scr->pt);
- }
-
- /* copy user rbs to kernel rbs */
- if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) {
- local_irq_enable(); /* force interrupt enable */
- ia64_sync_krbs();
- }
-
- local_irq_disable(); /* force interrupt disable */
-}
-
-static int __init nohalt_setup(char * str)
-{
- cpu_idle_poll_ctrl(true);
- return 1;
-}
-__setup("nohalt", nohalt_setup);
-
-#ifdef CONFIG_HOTPLUG_CPU
-/* We don't actually take CPU down, just spin without interrupts. */
-static inline void __noreturn play_dead(void)
-{
- unsigned int this_cpu = smp_processor_id();
-
- /* Ack it */
- __this_cpu_write(cpu_state, CPU_DEAD);
-
- max_xtp();
- local_irq_disable();
- idle_task_exit();
- ia64_jump_to_sal(&sal_boot_rendez_state[this_cpu]);
- /*
- * The above is a point of no-return, the processor is
- * expected to be in SAL loop now.
- */
- BUG();
-}
-#else
-static inline void __noreturn play_dead(void)
-{
- BUG();
-}
-#endif /* CONFIG_HOTPLUG_CPU */
-
-void __noreturn arch_cpu_idle_dead(void)
-{
- play_dead();
-}
-
-void arch_cpu_idle(void)
-{
- void (*mark_idle)(int) = ia64_mark_idle;
-
-#ifdef CONFIG_SMP
- min_xtp();
-#endif
- rmb();
- if (mark_idle)
- (*mark_idle)(1);
-
- raw_safe_halt();
- raw_local_irq_disable();
-
- if (mark_idle)
- (*mark_idle)(0);
-#ifdef CONFIG_SMP
- normal_xtp();
-#endif
-}
-
-void
-ia64_save_extra (struct task_struct *task)
-{
- if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
- ia64_save_debug_regs(&task->thread.dbr[0]);
-}
-
-void
-ia64_load_extra (struct task_struct *task)
-{
- if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
- ia64_load_debug_regs(&task->thread.dbr[0]);
-}
-
-/*
- * Copy the state of an ia-64 thread.
- *
- * We get here through the following call chain:
- *
- * from user-level: from kernel:
- *
- * <clone syscall> <some kernel call frames>
- * sys_clone :
- * kernel_clone kernel_clone
- * copy_thread copy_thread
- *
- * This means that the stack layout is as follows:
- *
- * +---------------------+ (highest addr)
- * | struct pt_regs |
- * +---------------------+
- * | struct switch_stack |
- * +---------------------+
- * | |
- * | memory stack |
- * | | <-- sp (lowest addr)
- * +---------------------+
- *
- * Observe that we copy the unat values that are in pt_regs and switch_stack. Spilling an
- * integer to address X causes bit N in ar.unat to be set to the NaT bit of the register,
- * with N=(X & 0x1ff)/8. Thus, copying the unat value preserves the NaT bits ONLY if the
- * pt_regs structure in the parent is congruent to that of the child, modulo 512. Since
- * the stack is page aligned and the page size is at least 4KB, this is always the case,
- * so there is nothing to worry about.
- */
-int
-copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
-{
- unsigned long clone_flags = args->flags;
- unsigned long user_stack_base = args->stack;
- unsigned long user_stack_size = args->stack_size;
- unsigned long tls = args->tls;
- extern char ia64_ret_from_clone;
- struct switch_stack *child_stack, *stack;
- unsigned long rbs, child_rbs, rbs_size;
- struct pt_regs *child_ptregs;
- struct pt_regs *regs = current_pt_regs();
- int retval = 0;
-
- child_ptregs = (struct pt_regs *) ((unsigned long) p + IA64_STK_OFFSET) - 1;
- child_stack = (struct switch_stack *) child_ptregs - 1;
-
- rbs = (unsigned long) current + IA64_RBS_OFFSET;
- child_rbs = (unsigned long) p + IA64_RBS_OFFSET;
-
- /* copy parts of thread_struct: */
- p->thread.ksp = (unsigned long) child_stack - 16;
-
- /*
- * NOTE: The calling convention considers all floating point
- * registers in the high partition (fph) to be scratch. Since
- * the only way to get to this point is through a system call,
- * we know that the values in fph are all dead. Hence, there
- * is no need to inherit the fph state from the parent to the
- * child and all we have to do is to make sure that
- * IA64_THREAD_FPH_VALID is cleared in the child.
- *
- * XXX We could push this optimization a bit further by
- * clearing IA64_THREAD_FPH_VALID on ANY system call.
- * However, it's not clear this is worth doing. Also, it
- * would be a slight deviation from the normal Linux system
- * call behavior where scratch registers are preserved across
- * system calls (unless used by the system call itself).
- */
-# define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \
- | IA64_THREAD_PM_VALID)
-# define THREAD_FLAGS_TO_SET 0
- p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
- | THREAD_FLAGS_TO_SET);
-
- ia64_drop_fpu(p); /* don't pick up stale state from a CPU's fph */
-
- if (unlikely(args->fn)) {
- if (unlikely(args->idle)) {
- /* fork_idle() called us */
- return 0;
- }
- memset(child_stack, 0, sizeof(*child_ptregs) + sizeof(*child_stack));
- child_stack->r4 = (unsigned long) args->fn;
- child_stack->r5 = (unsigned long) args->fn_arg;
- /*
- * Preserve PSR bits, except for bits 32-34 and 37-45,
- * which we can't read.
- */
- child_ptregs->cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN;
- /* mark as valid, empty frame */
- child_ptregs->cr_ifs = 1UL << 63;
- child_stack->ar_fpsr = child_ptregs->ar_fpsr
- = ia64_getreg(_IA64_REG_AR_FPSR);
- child_stack->pr = (1 << PRED_KERNEL_STACK);
- child_stack->ar_bspstore = child_rbs;
- child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
-
- /* stop some PSR bits from being inherited.
- * the psr.up/psr.pp bits must be cleared on fork but inherited on execve()
- * therefore we must specify them explicitly here and not include them in
- * IA64_PSR_BITS_TO_CLEAR.
- */
- child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
- & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
-
- return 0;
- }
- stack = ((struct switch_stack *) regs) - 1;
- /* copy parent's switch_stack & pt_regs to child: */
- memcpy(child_stack, stack, sizeof(*child_ptregs) + sizeof(*child_stack));
-
- /* copy the parent's register backing store to the child: */
- rbs_size = stack->ar_bspstore - rbs;
- memcpy((void *) child_rbs, (void *) rbs, rbs_size);
- if (clone_flags & CLONE_SETTLS)
- child_ptregs->r13 = tls;
- if (user_stack_base) {
- child_ptregs->r12 = user_stack_base + user_stack_size - 16;
- child_ptregs->ar_bspstore = user_stack_base;
- child_ptregs->ar_rnat = 0;
- child_ptregs->loadrs = 0;
- }
- child_stack->ar_bspstore = child_rbs + rbs_size;
- child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
-
- /* stop some PSR bits from being inherited.
- * the psr.up/psr.pp bits must be cleared on fork but inherited on execve()
- * therefore we must specify them explicitly here and not include them in
- * IA64_PSR_BITS_TO_CLEAR.
- */
- child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
- & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
- return retval;
-}
-
-asmlinkage long ia64_clone(unsigned long clone_flags, unsigned long stack_start,
- unsigned long stack_size, unsigned long parent_tidptr,
- unsigned long child_tidptr, unsigned long tls)
-{
- struct kernel_clone_args args = {
- .flags = (lower_32_bits(clone_flags) & ~CSIGNAL),
- .pidfd = (int __user *)parent_tidptr,
- .child_tid = (int __user *)child_tidptr,
- .parent_tid = (int __user *)parent_tidptr,
- .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL),
- .stack = stack_start,
- .stack_size = stack_size,
- .tls = tls,
- };
-
- return kernel_clone(&args);
-}
-
-static void
-do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg)
-{
- unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm;
- unsigned long ip;
- elf_greg_t *dst = arg;
- struct pt_regs *pt;
- char nat;
- int i;
-
- memset(dst, 0, sizeof(elf_gregset_t)); /* don't leak any kernel bits to user-level */
-
- if (unw_unwind_to_user(info) < 0)
- return;
-
- unw_get_sp(info, &sp);
- pt = (struct pt_regs *) (sp + 16);
-
- urbs_end = ia64_get_user_rbs_end(task, pt, &cfm);
-
- if (ia64_sync_user_rbs(task, info->sw, pt->ar_bspstore, urbs_end) < 0)
- return;
-
- ia64_peek(task, info->sw, urbs_end, (long) ia64_rse_rnat_addr((long *) urbs_end),
- &ar_rnat);
-
- /*
- * coredump format:
- * r0-r31
- * NaT bits (for r0-r31; bit N == 1 iff rN is a NaT)
- * predicate registers (p0-p63)
- * b0-b7
- * ip cfm user-mask
- * ar.rsc ar.bsp ar.bspstore ar.rnat
- * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec
- */
-
- /* r0 is zero */
- for (i = 1, mask = (1UL << i); i < 32; ++i) {
- unw_get_gr(info, i, &dst[i], &nat);
- if (nat)
- nat_bits |= mask;
- mask <<= 1;
- }
- dst[32] = nat_bits;
- unw_get_pr(info, &dst[33]);
-
- for (i = 0; i < 8; ++i)
- unw_get_br(info, i, &dst[34 + i]);
-
- unw_get_rp(info, &ip);
- dst[42] = ip + ia64_psr(pt)->ri;
- dst[43] = cfm;
- dst[44] = pt->cr_ipsr & IA64_PSR_UM;
-
- unw_get_ar(info, UNW_AR_RSC, &dst[45]);
- /*
- * For bsp and bspstore, unw_get_ar() would return the kernel
- * addresses, but we need the user-level addresses instead:
- */
- dst[46] = urbs_end; /* note: by convention PT_AR_BSP points to the end of the urbs! */
- dst[47] = pt->ar_bspstore;
- dst[48] = ar_rnat;
- unw_get_ar(info, UNW_AR_CCV, &dst[49]);
- unw_get_ar(info, UNW_AR_UNAT, &dst[50]);
- unw_get_ar(info, UNW_AR_FPSR, &dst[51]);
- dst[52] = pt->ar_pfs; /* UNW_AR_PFS is == to pt->cr_ifs for interrupt frames */
- unw_get_ar(info, UNW_AR_LC, &dst[53]);
- unw_get_ar(info, UNW_AR_EC, &dst[54]);
- unw_get_ar(info, UNW_AR_CSD, &dst[55]);
- unw_get_ar(info, UNW_AR_SSD, &dst[56]);
-}
-
-static void
-do_copy_regs (struct unw_frame_info *info, void *arg)
-{
- do_copy_task_regs(current, info, arg);
-}
-
-void
-ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
-{
- unw_init_running(do_copy_regs, dst);
-}
-
-/*
- * Flush thread state. This is called when a thread does an execve().
- */
-void
-flush_thread (void)
-{
- /* drop floating-point and debug-register state if it exists: */
- current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
- ia64_drop_fpu(current);
-}
-
-/*
- * Clean up state associated with a thread. This is called when
- * the thread calls exit().
- */
-void
-exit_thread (struct task_struct *tsk)
-{
-
- ia64_drop_fpu(tsk);
-}
-
-unsigned long
-__get_wchan (struct task_struct *p)
-{
- struct unw_frame_info info;
- unsigned long ip;
- int count = 0;
-
- /*
- * Note: p may not be a blocked task (it could be current or
- * another process running on some other CPU. Rather than
- * trying to determine if p is really blocked, we just assume
- * it's blocked and rely on the unwind routines to fail
- * gracefully if the process wasn't really blocked after all.
- * --davidm 99/12/15
- */
- unw_init_from_blocked_task(&info, p);
- do {
- if (task_is_running(p))
- return 0;
- if (unw_unwind(&info) < 0)
- return 0;
- unw_get_ip(&info, &ip);
- if (!in_sched_functions(ip))
- return ip;
- } while (count++ < 16);
- return 0;
-}
-
-void
-cpu_halt (void)
-{
- pal_power_mgmt_info_u_t power_info[8];
- unsigned long min_power;
- int i, min_power_state;
-
- if (ia64_pal_halt_info(power_info) != 0)
- return;
-
- min_power_state = 0;
- min_power = power_info[0].pal_power_mgmt_info_s.power_consumption;
- for (i = 1; i < 8; ++i)
- if (power_info[i].pal_power_mgmt_info_s.im
- && power_info[i].pal_power_mgmt_info_s.power_consumption < min_power) {
- min_power = power_info[i].pal_power_mgmt_info_s.power_consumption;
- min_power_state = i;
- }
-
- while (1)
- ia64_pal_halt(min_power_state);
-}
-
-void machine_shutdown(void)
-{
- smp_shutdown_nonboot_cpus(reboot_cpu);
-
-#ifdef CONFIG_KEXEC
- kexec_disable_iosapic();
-#endif
-}
-
-void
-machine_restart (char *restart_cmd)
-{
- (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
- efi_reboot(REBOOT_WARM, NULL);
-}
-
-void
-machine_halt (void)
-{
- (void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
- cpu_halt();
-}
-
-void
-machine_power_off (void)
-{
- do_kernel_power_off();
- machine_halt();
-}
-
-EXPORT_SYMBOL(ia64_delay_loop);
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
deleted file mode 100644
index 4c41912c550f..000000000000
--- a/arch/ia64/kernel/ptrace.c
+++ /dev/null
@@ -1,2012 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Kernel support for the ptrace() and syscall tracing interfaces.
- *
- * Copyright (C) 1999-2005 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2006 Intel Co
- * 2006-08-12 - IA64 Native Utrace implementation support added by
- * Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
- *
- * Derived from the x86 and Alpha versions.
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/sched/task.h>
-#include <linux/sched/task_stack.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/security.h>
-#include <linux/audit.h>
-#include <linux/signal.h>
-#include <linux/regset.h>
-#include <linux/elf.h>
-#include <linux/resume_user_mode.h>
-
-#include <asm/processor.h>
-#include <asm/ptrace_offsets.h>
-#include <asm/rse.h>
-#include <linux/uaccess.h>
-#include <asm/unwind.h>
-
-#include "entry.h"
-
-/*
- * Bits in the PSR that we allow ptrace() to change:
- * be, up, ac, mfl, mfh (the user mask; five bits total)
- * db (debug breakpoint fault; one bit)
- * id (instruction debug fault disable; one bit)
- * dd (data debug fault disable; one bit)
- * ri (restart instruction; two bits)
- * is (instruction set; one bit)
- */
-#define IPSR_MASK (IA64_PSR_UM | IA64_PSR_DB | IA64_PSR_IS \
- | IA64_PSR_ID | IA64_PSR_DD | IA64_PSR_RI)
-
-#define MASK(nbits) ((1UL << (nbits)) - 1) /* mask with NBITS bits set */
-#define PFM_MASK MASK(38)
-
-#define PTRACE_DEBUG 0
-
-#if PTRACE_DEBUG
-# define dprintk(format...) printk(format)
-# define inline
-#else
-# define dprintk(format...)
-#endif
-
-/* Return TRUE if PT was created due to kernel-entry via a system-call. */
-
-static inline int
-in_syscall (struct pt_regs *pt)
-{
- return (long) pt->cr_ifs >= 0;
-}
-
-/*
- * Collect the NaT bits for r1-r31 from scratch_unat and return a NaT
- * bitset where bit i is set iff the NaT bit of register i is set.
- */
-unsigned long
-ia64_get_scratch_nat_bits (struct pt_regs *pt, unsigned long scratch_unat)
-{
-# define GET_BITS(first, last, unat) \
- ({ \
- unsigned long bit = ia64_unat_pos(&pt->r##first); \
- unsigned long nbits = (last - first + 1); \
- unsigned long mask = MASK(nbits) << first; \
- unsigned long dist; \
- if (bit < first) \
- dist = 64 + bit - first; \
- else \
- dist = bit - first; \
- ia64_rotr(unat, dist) & mask; \
- })
- unsigned long val;
-
- /*
- * Registers that are stored consecutively in struct pt_regs
- * can be handled in parallel. If the register order in
- * struct_pt_regs changes, this code MUST be updated.
- */
- val = GET_BITS( 1, 1, scratch_unat);
- val |= GET_BITS( 2, 3, scratch_unat);
- val |= GET_BITS(12, 13, scratch_unat);
- val |= GET_BITS(14, 14, scratch_unat);
- val |= GET_BITS(15, 15, scratch_unat);
- val |= GET_BITS( 8, 11, scratch_unat);
- val |= GET_BITS(16, 31, scratch_unat);
- return val;
-
-# undef GET_BITS
-}
-
-/*
- * Set the NaT bits for the scratch registers according to NAT and
- * return the resulting unat (assuming the scratch registers are
- * stored in PT).
- */
-unsigned long
-ia64_put_scratch_nat_bits (struct pt_regs *pt, unsigned long nat)
-{
-# define PUT_BITS(first, last, nat) \
- ({ \
- unsigned long bit = ia64_unat_pos(&pt->r##first); \
- unsigned long nbits = (last - first + 1); \
- unsigned long mask = MASK(nbits) << first; \
- long dist; \
- if (bit < first) \
- dist = 64 + bit - first; \
- else \
- dist = bit - first; \
- ia64_rotl(nat & mask, dist); \
- })
- unsigned long scratch_unat;
-
- /*
- * Registers that are stored consecutively in struct pt_regs
- * can be handled in parallel. If the register order in
- * struct_pt_regs changes, this code MUST be updated.
- */
- scratch_unat = PUT_BITS( 1, 1, nat);
- scratch_unat |= PUT_BITS( 2, 3, nat);
- scratch_unat |= PUT_BITS(12, 13, nat);
- scratch_unat |= PUT_BITS(14, 14, nat);
- scratch_unat |= PUT_BITS(15, 15, nat);
- scratch_unat |= PUT_BITS( 8, 11, nat);
- scratch_unat |= PUT_BITS(16, 31, nat);
-
- return scratch_unat;
-
-# undef PUT_BITS
-}
-
-#define IA64_MLX_TEMPLATE 0x2
-#define IA64_MOVL_OPCODE 6
-
-void
-ia64_increment_ip (struct pt_regs *regs)
-{
- unsigned long w0, ri = ia64_psr(regs)->ri + 1;
-
- if (ri > 2) {
- ri = 0;
- regs->cr_iip += 16;
- } else if (ri == 2) {
- get_user(w0, (char __user *) regs->cr_iip + 0);
- if (((w0 >> 1) & 0xf) == IA64_MLX_TEMPLATE) {
- /*
- * rfi'ing to slot 2 of an MLX bundle causes
- * an illegal operation fault. We don't want
- * that to happen...
- */
- ri = 0;
- regs->cr_iip += 16;
- }
- }
- ia64_psr(regs)->ri = ri;
-}
-
-void
-ia64_decrement_ip (struct pt_regs *regs)
-{
- unsigned long w0, ri = ia64_psr(regs)->ri - 1;
-
- if (ia64_psr(regs)->ri == 0) {
- regs->cr_iip -= 16;
- ri = 2;
- get_user(w0, (char __user *) regs->cr_iip + 0);
- if (((w0 >> 1) & 0xf) == IA64_MLX_TEMPLATE) {
- /*
- * rfi'ing to slot 2 of an MLX bundle causes
- * an illegal operation fault. We don't want
- * that to happen...
- */
- ri = 1;
- }
- }
- ia64_psr(regs)->ri = ri;
-}
-
-/*
- * This routine is used to read an rnat bits that are stored on the
- * kernel backing store. Since, in general, the alignment of the user
- * and kernel are different, this is not completely trivial. In
- * essence, we need to construct the user RNAT based on up to two
- * kernel RNAT values and/or the RNAT value saved in the child's
- * pt_regs.
- *
- * user rbs
- *
- * +--------+ <-- lowest address
- * | slot62 |
- * +--------+
- * | rnat | 0x....1f8
- * +--------+
- * | slot00 | \
- * +--------+ |
- * | slot01 | > child_regs->ar_rnat
- * +--------+ |
- * | slot02 | / kernel rbs
- * +--------+ +--------+
- * <- child_regs->ar_bspstore | slot61 | <-- krbs
- * +- - - - + +--------+
- * | slot62 |
- * +- - - - + +--------+
- * | rnat |
- * +- - - - + +--------+
- * vrnat | slot00 |
- * +- - - - + +--------+
- * = =
- * +--------+
- * | slot00 | \
- * +--------+ |
- * | slot01 | > child_stack->ar_rnat
- * +--------+ |
- * | slot02 | /
- * +--------+
- * <--- child_stack->ar_bspstore
- *
- * The way to think of this code is as follows: bit 0 in the user rnat
- * corresponds to some bit N (0 <= N <= 62) in one of the kernel rnat
- * value. The kernel rnat value holding this bit is stored in
- * variable rnat0. rnat1 is loaded with the kernel rnat value that
- * form the upper bits of the user rnat value.
- *
- * Boundary cases:
- *
- * o when reading the rnat "below" the first rnat slot on the kernel
- * backing store, rnat0/rnat1 are set to 0 and the low order bits are
- * merged in from pt->ar_rnat.
- *
- * o when reading the rnat "above" the last rnat slot on the kernel
- * backing store, rnat0/rnat1 gets its value from sw->ar_rnat.
- */
-static unsigned long
-get_rnat (struct task_struct *task, struct switch_stack *sw,
- unsigned long *krbs, unsigned long *urnat_addr,
- unsigned long *urbs_end)
-{
- unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr;
- unsigned long umask = 0, mask, m;
- unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift;
- long num_regs, nbits;
- struct pt_regs *pt;
-
- pt = task_pt_regs(task);
- kbsp = (unsigned long *) sw->ar_bspstore;
- ubspstore = (unsigned long *) pt->ar_bspstore;
-
- if (urbs_end < urnat_addr)
- nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_end);
- else
- nbits = 63;
- mask = MASK(nbits);
- /*
- * First, figure out which bit number slot 0 in user-land maps
- * to in the kernel rnat. Do this by figuring out how many
- * register slots we're beyond the user's backingstore and
- * then computing the equivalent address in kernel space.
- */
- num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1);
- slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs);
- shift = ia64_rse_slot_num(slot0_kaddr);
- rnat1_kaddr = ia64_rse_rnat_addr(slot0_kaddr);
- rnat0_kaddr = rnat1_kaddr - 64;
-
- if (ubspstore + 63 > urnat_addr) {
- /* some bits need to be merged in from pt->ar_rnat */
- umask = MASK(ia64_rse_slot_num(ubspstore)) & mask;
- urnat = (pt->ar_rnat & umask);
- mask &= ~umask;
- if (!mask)
- return urnat;
- }
-
- m = mask << shift;
- if (rnat0_kaddr >= kbsp)
- rnat0 = sw->ar_rnat;
- else if (rnat0_kaddr > krbs)
- rnat0 = *rnat0_kaddr;
- urnat |= (rnat0 & m) >> shift;
-
- m = mask >> (63 - shift);
- if (rnat1_kaddr >= kbsp)
- rnat1 = sw->ar_rnat;
- else if (rnat1_kaddr > krbs)
- rnat1 = *rnat1_kaddr;
- urnat |= (rnat1 & m) << (63 - shift);
- return urnat;
-}
-
-/*
- * The reverse of get_rnat.
- */
-static void
-put_rnat (struct task_struct *task, struct switch_stack *sw,
- unsigned long *krbs, unsigned long *urnat_addr, unsigned long urnat,
- unsigned long *urbs_end)
-{
- unsigned long rnat0 = 0, rnat1 = 0, *slot0_kaddr, umask = 0, mask, m;
- unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift;
- long num_regs, nbits;
- struct pt_regs *pt;
- unsigned long cfm, *urbs_kargs;
-
- pt = task_pt_regs(task);
- kbsp = (unsigned long *) sw->ar_bspstore;
- ubspstore = (unsigned long *) pt->ar_bspstore;
-
- urbs_kargs = urbs_end;
- if (in_syscall(pt)) {
- /*
- * If entered via syscall, don't allow user to set rnat bits
- * for syscall args.
- */
- cfm = pt->cr_ifs;
- urbs_kargs = ia64_rse_skip_regs(urbs_end, -(cfm & 0x7f));
- }
-
- if (urbs_kargs >= urnat_addr)
- nbits = 63;
- else {
- if ((urnat_addr - 63) >= urbs_kargs)
- return;
- nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_kargs);
- }
- mask = MASK(nbits);
-
- /*
- * First, figure out which bit number slot 0 in user-land maps
- * to in the kernel rnat. Do this by figuring out how many
- * register slots we're beyond the user's backingstore and
- * then computing the equivalent address in kernel space.
- */
- num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1);
- slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs);
- shift = ia64_rse_slot_num(slot0_kaddr);
- rnat1_kaddr = ia64_rse_rnat_addr(slot0_kaddr);
- rnat0_kaddr = rnat1_kaddr - 64;
-
- if (ubspstore + 63 > urnat_addr) {
- /* some bits need to be place in pt->ar_rnat: */
- umask = MASK(ia64_rse_slot_num(ubspstore)) & mask;
- pt->ar_rnat = (pt->ar_rnat & ~umask) | (urnat & umask);
- mask &= ~umask;
- if (!mask)
- return;
- }
- /*
- * Note: Section 11.1 of the EAS guarantees that bit 63 of an
- * rnat slot is ignored. so we don't have to clear it here.
- */
- rnat0 = (urnat << shift);
- m = mask << shift;
- if (rnat0_kaddr >= kbsp)
- sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat0 & m);
- else if (rnat0_kaddr > krbs)
- *rnat0_kaddr = ((*rnat0_kaddr & ~m) | (rnat0 & m));
-
- rnat1 = (urnat >> (63 - shift));
- m = mask >> (63 - shift);
- if (rnat1_kaddr >= kbsp)
- sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat1 & m);
- else if (rnat1_kaddr > krbs)
- *rnat1_kaddr = ((*rnat1_kaddr & ~m) | (rnat1 & m));
-}
-
-static inline int
-on_kernel_rbs (unsigned long addr, unsigned long bspstore,
- unsigned long urbs_end)
-{
- unsigned long *rnat_addr = ia64_rse_rnat_addr((unsigned long *)
- urbs_end);
- return (addr >= bspstore && addr <= (unsigned long) rnat_addr);
-}
-
-/*
- * Read a word from the user-level backing store of task CHILD. ADDR
- * is the user-level address to read the word from, VAL a pointer to
- * the return value, and USER_BSP gives the end of the user-level
- * backing store (i.e., it's the address that would be in ar.bsp after
- * the user executed a "cover" instruction).
- *
- * This routine takes care of accessing the kernel register backing
- * store for those registers that got spilled there. It also takes
- * care of calculating the appropriate RNaT collection words.
- */
-long
-ia64_peek (struct task_struct *child, struct switch_stack *child_stack,
- unsigned long user_rbs_end, unsigned long addr, long *val)
-{
- unsigned long *bspstore, *krbs, regnum, *laddr, *urbs_end, *rnat_addr;
- struct pt_regs *child_regs;
- size_t copied;
- long ret;
-
- urbs_end = (long *) user_rbs_end;
- laddr = (unsigned long *) addr;
- child_regs = task_pt_regs(child);
- bspstore = (unsigned long *) child_regs->ar_bspstore;
- krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
- if (on_kernel_rbs(addr, (unsigned long) bspstore,
- (unsigned long) urbs_end))
- {
- /*
- * Attempt to read the RBS in an area that's actually
- * on the kernel RBS => read the corresponding bits in
- * the kernel RBS.
- */
- rnat_addr = ia64_rse_rnat_addr(laddr);
- ret = get_rnat(child, child_stack, krbs, rnat_addr, urbs_end);
-
- if (laddr == rnat_addr) {
- /* return NaT collection word itself */
- *val = ret;
- return 0;
- }
-
- if (((1UL << ia64_rse_slot_num(laddr)) & ret) != 0) {
- /*
- * It is implementation dependent whether the
- * data portion of a NaT value gets saved on a
- * st8.spill or RSE spill (e.g., see EAS 2.6,
- * 4.4.4.6 Register Spill and Fill). To get
- * consistent behavior across all possible
- * IA-64 implementations, we return zero in
- * this case.
- */
- *val = 0;
- return 0;
- }
-
- if (laddr < urbs_end) {
- /*
- * The desired word is on the kernel RBS and
- * is not a NaT.
- */
- regnum = ia64_rse_num_regs(bspstore, laddr);
- *val = *ia64_rse_skip_regs(krbs, regnum);
- return 0;
- }
- }
- copied = access_process_vm(child, addr, &ret, sizeof(ret), FOLL_FORCE);
- if (copied != sizeof(ret))
- return -EIO;
- *val = ret;
- return 0;
-}
-
-long
-ia64_poke (struct task_struct *child, struct switch_stack *child_stack,
- unsigned long user_rbs_end, unsigned long addr, long val)
-{
- unsigned long *bspstore, *krbs, regnum, *laddr;
- unsigned long *urbs_end = (long *) user_rbs_end;
- struct pt_regs *child_regs;
-
- laddr = (unsigned long *) addr;
- child_regs = task_pt_regs(child);
- bspstore = (unsigned long *) child_regs->ar_bspstore;
- krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
- if (on_kernel_rbs(addr, (unsigned long) bspstore,
- (unsigned long) urbs_end))
- {
- /*
- * Attempt to write the RBS in an area that's actually
- * on the kernel RBS => write the corresponding bits
- * in the kernel RBS.
- */
- if (ia64_rse_is_rnat_slot(laddr))
- put_rnat(child, child_stack, krbs, laddr, val,
- urbs_end);
- else {
- if (laddr < urbs_end) {
- regnum = ia64_rse_num_regs(bspstore, laddr);
- *ia64_rse_skip_regs(krbs, regnum) = val;
- }
- }
- } else if (access_process_vm(child, addr, &val, sizeof(val),
- FOLL_FORCE | FOLL_WRITE)
- != sizeof(val))
- return -EIO;
- return 0;
-}
-
-/*
- * Calculate the address of the end of the user-level register backing
- * store. This is the address that would have been stored in ar.bsp
- * if the user had executed a "cover" instruction right before
- * entering the kernel. If CFMP is not NULL, it is used to return the
- * "current frame mask" that was active at the time the kernel was
- * entered.
- */
-unsigned long
-ia64_get_user_rbs_end (struct task_struct *child, struct pt_regs *pt,
- unsigned long *cfmp)
-{
- unsigned long *krbs, *bspstore, cfm = pt->cr_ifs;
- long ndirty;
-
- krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
- bspstore = (unsigned long *) pt->ar_bspstore;
- ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19));
-
- if (in_syscall(pt))
- ndirty += (cfm & 0x7f);
- else
- cfm &= ~(1UL << 63); /* clear valid bit */
-
- if (cfmp)
- *cfmp = cfm;
- return (unsigned long) ia64_rse_skip_regs(bspstore, ndirty);
-}
-
-/*
- * Synchronize (i.e, write) the RSE backing store living in kernel
- * space to the VM of the CHILD task. SW and PT are the pointers to
- * the switch_stack and pt_regs structures, respectively.
- * USER_RBS_END is the user-level address at which the backing store
- * ends.
- */
-long
-ia64_sync_user_rbs (struct task_struct *child, struct switch_stack *sw,
- unsigned long user_rbs_start, unsigned long user_rbs_end)
-{
- unsigned long addr, val;
- long ret;
-
- /* now copy word for word from kernel rbs to user rbs: */
- for (addr = user_rbs_start; addr < user_rbs_end; addr += 8) {
- ret = ia64_peek(child, sw, user_rbs_end, addr, &val);
- if (ret < 0)
- return ret;
- if (access_process_vm(child, addr, &val, sizeof(val),
- FOLL_FORCE | FOLL_WRITE)
- != sizeof(val))
- return -EIO;
- }
- return 0;
-}
-
-static long
-ia64_sync_kernel_rbs (struct task_struct *child, struct switch_stack *sw,
- unsigned long user_rbs_start, unsigned long user_rbs_end)
-{
- unsigned long addr, val;
- long ret;
-
- /* now copy word for word from user rbs to kernel rbs: */
- for (addr = user_rbs_start; addr < user_rbs_end; addr += 8) {
- if (access_process_vm(child, addr, &val, sizeof(val),
- FOLL_FORCE)
- != sizeof(val))
- return -EIO;
-
- ret = ia64_poke(child, sw, user_rbs_end, addr, val);
- if (ret < 0)
- return ret;
- }
- return 0;
-}
-
-typedef long (*syncfunc_t)(struct task_struct *, struct switch_stack *,
- unsigned long, unsigned long);
-
-static void do_sync_rbs(struct unw_frame_info *info, void *arg)
-{
- struct pt_regs *pt;
- unsigned long urbs_end;
- syncfunc_t fn = arg;
-
- if (unw_unwind_to_user(info) < 0)
- return;
- pt = task_pt_regs(info->task);
- urbs_end = ia64_get_user_rbs_end(info->task, pt, NULL);
-
- fn(info->task, info->sw, pt->ar_bspstore, urbs_end);
-}
-
-/*
- * when a thread is stopped (ptraced), debugger might change thread's user
- * stack (change memory directly), and we must avoid the RSE stored in kernel
- * to override user stack (user space's RSE is newer than kernel's in the
- * case). To workaround the issue, we copy kernel RSE to user RSE before the
- * task is stopped, so user RSE has updated data. we then copy user RSE to
- * kernel after the task is resummed from traced stop and kernel will use the
- * newer RSE to return to user. TIF_RESTORE_RSE is the flag to indicate we need
- * synchronize user RSE to kernel.
- */
-void ia64_ptrace_stop(void)
-{
- if (test_and_set_tsk_thread_flag(current, TIF_RESTORE_RSE))
- return;
- set_notify_resume(current);
- unw_init_running(do_sync_rbs, ia64_sync_user_rbs);
-}
-
-/*
- * This is called to read back the register backing store.
- */
-void ia64_sync_krbs(void)
-{
- clear_tsk_thread_flag(current, TIF_RESTORE_RSE);
-
- unw_init_running(do_sync_rbs, ia64_sync_kernel_rbs);
-}
-
-/*
- * Write f32-f127 back to task->thread.fph if it has been modified.
- */
-inline void
-ia64_flush_fph (struct task_struct *task)
-{
- struct ia64_psr *psr = ia64_psr(task_pt_regs(task));
-
- /*
- * Prevent migrating this task while
- * we're fiddling with the FPU state
- */
- preempt_disable();
- if (ia64_is_local_fpu_owner(task) && psr->mfh) {
- psr->mfh = 0;
- task->thread.flags |= IA64_THREAD_FPH_VALID;
- ia64_save_fpu(&task->thread.fph[0]);
- }
- preempt_enable();
-}
-
-/*
- * Sync the fph state of the task so that it can be manipulated
- * through thread.fph. If necessary, f32-f127 are written back to
- * thread.fph or, if the fph state hasn't been used before, thread.fph
- * is cleared to zeroes. Also, access to f32-f127 is disabled to
- * ensure that the task picks up the state from thread.fph when it
- * executes again.
- */
-void
-ia64_sync_fph (struct task_struct *task)
-{
- struct ia64_psr *psr = ia64_psr(task_pt_regs(task));
-
- ia64_flush_fph(task);
- if (!(task->thread.flags & IA64_THREAD_FPH_VALID)) {
- task->thread.flags |= IA64_THREAD_FPH_VALID;
- memset(&task->thread.fph, 0, sizeof(task->thread.fph));
- }
- ia64_drop_fpu(task);
- psr->dfh = 1;
-}
-
-/*
- * Change the machine-state of CHILD such that it will return via the normal
- * kernel exit-path, rather than the syscall-exit path.
- */
-static void
-convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt,
- unsigned long cfm)
-{
- struct unw_frame_info info, prev_info;
- unsigned long ip, sp, pr;
-
- unw_init_from_blocked_task(&info, child);
- while (1) {
- prev_info = info;
- if (unw_unwind(&info) < 0)
- return;
-
- unw_get_sp(&info, &sp);
- if ((long)((unsigned long)child + IA64_STK_OFFSET - sp)
- < IA64_PT_REGS_SIZE) {
- dprintk("ptrace.%s: ran off the top of the kernel "
- "stack\n", __func__);
- return;
- }
- if (unw_get_pr (&prev_info, &pr) < 0) {
- unw_get_rp(&prev_info, &ip);
- dprintk("ptrace.%s: failed to read "
- "predicate register (ip=0x%lx)\n",
- __func__, ip);
- return;
- }
- if (unw_is_intr_frame(&info)
- && (pr & (1UL << PRED_USER_STACK)))
- break;
- }
-
- /*
- * Note: at the time of this call, the target task is blocked
- * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL
- * (aka, "pLvSys") we redirect execution from
- * .work_pending_syscall_end to .work_processed_kernel.
- */
- unw_get_pr(&prev_info, &pr);
- pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL));
- pr |= (1UL << PRED_NON_SYSCALL);
- unw_set_pr(&prev_info, pr);
-
- pt->cr_ifs = (1UL << 63) | cfm;
- /*
- * Clear the memory that is NOT written on syscall-entry to
- * ensure we do not leak kernel-state to user when execution
- * resumes.
- */
- pt->r2 = 0;
- pt->r3 = 0;
- pt->r14 = 0;
- memset(&pt->r16, 0, 16*8); /* clear r16-r31 */
- memset(&pt->f6, 0, 6*16); /* clear f6-f11 */
- pt->b7 = 0;
- pt->ar_ccv = 0;
- pt->ar_csd = 0;
- pt->ar_ssd = 0;
-}
-
-static int
-access_nat_bits (struct task_struct *child, struct pt_regs *pt,
- struct unw_frame_info *info,
- unsigned long *data, int write_access)
-{
- unsigned long regnum, nat_bits, scratch_unat, dummy = 0;
- char nat = 0;
-
- if (write_access) {
- nat_bits = *data;
- scratch_unat = ia64_put_scratch_nat_bits(pt, nat_bits);
- if (unw_set_ar(info, UNW_AR_UNAT, scratch_unat) < 0) {
- dprintk("ptrace: failed to set ar.unat\n");
- return -1;
- }
- for (regnum = 4; regnum <= 7; ++regnum) {
- unw_get_gr(info, regnum, &dummy, &nat);
- unw_set_gr(info, regnum, dummy,
- (nat_bits >> regnum) & 1);
- }
- } else {
- if (unw_get_ar(info, UNW_AR_UNAT, &scratch_unat) < 0) {
- dprintk("ptrace: failed to read ar.unat\n");
- return -1;
- }
- nat_bits = ia64_get_scratch_nat_bits(pt, scratch_unat);
- for (regnum = 4; regnum <= 7; ++regnum) {
- unw_get_gr(info, regnum, &dummy, &nat);
- nat_bits |= (nat != 0) << regnum;
- }
- *data = nat_bits;
- }
- return 0;
-}
-
-static int
-access_elf_reg(struct task_struct *target, struct unw_frame_info *info,
- unsigned long addr, unsigned long *data, int write_access);
-
-static long
-ptrace_getregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
-{
- unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val;
- struct unw_frame_info info;
- struct ia64_fpreg fpval;
- struct switch_stack *sw;
- struct pt_regs *pt;
- long ret, retval = 0;
- char nat = 0;
- int i;
-
- if (!access_ok(ppr, sizeof(struct pt_all_user_regs)))
- return -EIO;
-
- pt = task_pt_regs(child);
- sw = (struct switch_stack *) (child->thread.ksp + 16);
- unw_init_from_blocked_task(&info, child);
- if (unw_unwind_to_user(&info) < 0) {
- return -EIO;
- }
-
- if (((unsigned long) ppr & 0x7) != 0) {
- dprintk("ptrace:unaligned register address %p\n", ppr);
- return -EIO;
- }
-
- if (access_elf_reg(child, &info, ELF_CR_IPSR_OFFSET, &psr, 0) < 0 ||
- access_elf_reg(child, &info, ELF_AR_EC_OFFSET, &ec, 0) < 0 ||
- access_elf_reg(child, &info, ELF_AR_LC_OFFSET, &lc, 0) < 0 ||
- access_elf_reg(child, &info, ELF_AR_RNAT_OFFSET, &rnat, 0) < 0 ||
- access_elf_reg(child, &info, ELF_AR_BSP_OFFSET, &bsp, 0) < 0 ||
- access_elf_reg(child, &info, ELF_CFM_OFFSET, &cfm, 0) < 0 ||
- access_elf_reg(child, &info, ELF_NAT_OFFSET, &nat_bits, 0) < 0)
- return -EIO;
-
- /* control regs */
-
- retval |= __put_user(pt->cr_iip, &ppr->cr_iip);
- retval |= __put_user(psr, &ppr->cr_ipsr);
-
- /* app regs */
-
- retval |= __put_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
- retval |= __put_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]);
- retval |= __put_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
- retval |= __put_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
- retval |= __put_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
- retval |= __put_user(pt->ar_fpsr, &ppr->ar[PT_AUR_FPSR]);
-
- retval |= __put_user(ec, &ppr->ar[PT_AUR_EC]);
- retval |= __put_user(lc, &ppr->ar[PT_AUR_LC]);
- retval |= __put_user(rnat, &ppr->ar[PT_AUR_RNAT]);
- retval |= __put_user(bsp, &ppr->ar[PT_AUR_BSP]);
- retval |= __put_user(cfm, &ppr->cfm);
-
- /* gr1-gr3 */
-
- retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long));
- retval |= __copy_to_user(&ppr->gr[2], &pt->r2, sizeof(long) *2);
-
- /* gr4-gr7 */
-
- for (i = 4; i < 8; i++) {
- if (unw_access_gr(&info, i, &val, &nat, 0) < 0)
- return -EIO;
- retval |= __put_user(val, &ppr->gr[i]);
- }
-
- /* gr8-gr11 */
-
- retval |= __copy_to_user(&ppr->gr[8], &pt->r8, sizeof(long) * 4);
-
- /* gr12-gr15 */
-
- retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 2);
- retval |= __copy_to_user(&ppr->gr[14], &pt->r14, sizeof(long));
- retval |= __copy_to_user(&ppr->gr[15], &pt->r15, sizeof(long));
-
- /* gr16-gr31 */
-
- retval |= __copy_to_user(&ppr->gr[16], &pt->r16, sizeof(long) * 16);
-
- /* b0 */
-
- retval |= __put_user(pt->b0, &ppr->br[0]);
-
- /* b1-b5 */
-
- for (i = 1; i < 6; i++) {
- if (unw_access_br(&info, i, &val, 0) < 0)
- return -EIO;
- __put_user(val, &ppr->br[i]);
- }
-
- /* b6-b7 */
-
- retval |= __put_user(pt->b6, &ppr->br[6]);
- retval |= __put_user(pt->b7, &ppr->br[7]);
-
- /* fr2-fr5 */
-
- for (i = 2; i < 6; i++) {
- if (unw_get_fr(&info, i, &fpval) < 0)
- return -EIO;
- retval |= __copy_to_user(&ppr->fr[i], &fpval, sizeof (fpval));
- }
-
- /* fr6-fr11 */
-
- retval |= __copy_to_user(&ppr->fr[6], &pt->f6,
- sizeof(struct ia64_fpreg) * 6);
-
- /* fp scratch regs(12-15) */
-
- retval |= __copy_to_user(&ppr->fr[12], &sw->f12,
- sizeof(struct ia64_fpreg) * 4);
-
- /* fr16-fr31 */
-
- for (i = 16; i < 32; i++) {
- if (unw_get_fr(&info, i, &fpval) < 0)
- return -EIO;
- retval |= __copy_to_user(&ppr->fr[i], &fpval, sizeof (fpval));
- }
-
- /* fph */
-
- ia64_flush_fph(child);
- retval |= __copy_to_user(&ppr->fr[32], &child->thread.fph,
- sizeof(ppr->fr[32]) * 96);
-
- /* preds */
-
- retval |= __put_user(pt->pr, &ppr->pr);
-
- /* nat bits */
-
- retval |= __put_user(nat_bits, &ppr->nat);
-
- ret = retval ? -EIO : 0;
- return ret;
-}
-
-static long
-ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
-{
- unsigned long psr, rsc, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
- struct unw_frame_info info;
- struct switch_stack *sw;
- struct ia64_fpreg fpval;
- struct pt_regs *pt;
- long retval = 0;
- int i;
-
- memset(&fpval, 0, sizeof(fpval));
-
- if (!access_ok(ppr, sizeof(struct pt_all_user_regs)))
- return -EIO;
-
- pt = task_pt_regs(child);
- sw = (struct switch_stack *) (child->thread.ksp + 16);
- unw_init_from_blocked_task(&info, child);
- if (unw_unwind_to_user(&info) < 0) {
- return -EIO;
- }
-
- if (((unsigned long) ppr & 0x7) != 0) {
- dprintk("ptrace:unaligned register address %p\n", ppr);
- return -EIO;
- }
-
- /* control regs */
-
- retval |= __get_user(pt->cr_iip, &ppr->cr_iip);
- retval |= __get_user(psr, &ppr->cr_ipsr);
-
- /* app regs */
-
- retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
- retval |= __get_user(rsc, &ppr->ar[PT_AUR_RSC]);
- retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
- retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
- retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
- retval |= __get_user(pt->ar_fpsr, &ppr->ar[PT_AUR_FPSR]);
-
- retval |= __get_user(ec, &ppr->ar[PT_AUR_EC]);
- retval |= __get_user(lc, &ppr->ar[PT_AUR_LC]);
- retval |= __get_user(rnat, &ppr->ar[PT_AUR_RNAT]);
- retval |= __get_user(bsp, &ppr->ar[PT_AUR_BSP]);
- retval |= __get_user(cfm, &ppr->cfm);
-
- /* gr1-gr3 */
-
- retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long));
- retval |= __copy_from_user(&pt->r2, &ppr->gr[2], sizeof(long) * 2);
-
- /* gr4-gr7 */
-
- for (i = 4; i < 8; i++) {
- retval |= __get_user(val, &ppr->gr[i]);
- /* NaT bit will be set via PT_NAT_BITS: */
- if (unw_set_gr(&info, i, val, 0) < 0)
- return -EIO;
- }
-
- /* gr8-gr11 */
-
- retval |= __copy_from_user(&pt->r8, &ppr->gr[8], sizeof(long) * 4);
-
- /* gr12-gr15 */
-
- retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 2);
- retval |= __copy_from_user(&pt->r14, &ppr->gr[14], sizeof(long));
- retval |= __copy_from_user(&pt->r15, &ppr->gr[15], sizeof(long));
-
- /* gr16-gr31 */
-
- retval |= __copy_from_user(&pt->r16, &ppr->gr[16], sizeof(long) * 16);
-
- /* b0 */
-
- retval |= __get_user(pt->b0, &ppr->br[0]);
-
- /* b1-b5 */
-
- for (i = 1; i < 6; i++) {
- retval |= __get_user(val, &ppr->br[i]);
- unw_set_br(&info, i, val);
- }
-
- /* b6-b7 */
-
- retval |= __get_user(pt->b6, &ppr->br[6]);
- retval |= __get_user(pt->b7, &ppr->br[7]);
-
- /* fr2-fr5 */
-
- for (i = 2; i < 6; i++) {
- retval |= __copy_from_user(&fpval, &ppr->fr[i], sizeof(fpval));
- if (unw_set_fr(&info, i, fpval) < 0)
- return -EIO;
- }
-
- /* fr6-fr11 */
-
- retval |= __copy_from_user(&pt->f6, &ppr->fr[6],
- sizeof(ppr->fr[6]) * 6);
-
- /* fp scratch regs(12-15) */
-
- retval |= __copy_from_user(&sw->f12, &ppr->fr[12],
- sizeof(ppr->fr[12]) * 4);
-
- /* fr16-fr31 */
-
- for (i = 16; i < 32; i++) {
- retval |= __copy_from_user(&fpval, &ppr->fr[i],
- sizeof(fpval));
- if (unw_set_fr(&info, i, fpval) < 0)
- return -EIO;
- }
-
- /* fph */
-
- ia64_sync_fph(child);
- retval |= __copy_from_user(&child->thread.fph, &ppr->fr[32],
- sizeof(ppr->fr[32]) * 96);
-
- /* preds */
-
- retval |= __get_user(pt->pr, &ppr->pr);
-
- /* nat bits */
-
- retval |= __get_user(nat_bits, &ppr->nat);
-
- retval |= access_elf_reg(child, &info, ELF_CR_IPSR_OFFSET, &psr, 1);
- retval |= access_elf_reg(child, &info, ELF_AR_RSC_OFFSET, &rsc, 1);
- retval |= access_elf_reg(child, &info, ELF_AR_EC_OFFSET, &ec, 1);
- retval |= access_elf_reg(child, &info, ELF_AR_LC_OFFSET, &lc, 1);
- retval |= access_elf_reg(child, &info, ELF_AR_RNAT_OFFSET, &rnat, 1);
- retval |= access_elf_reg(child, &info, ELF_AR_BSP_OFFSET, &bsp, 1);
- retval |= access_elf_reg(child, &info, ELF_CFM_OFFSET, &cfm, 1);
- retval |= access_elf_reg(child, &info, ELF_NAT_OFFSET, &nat_bits, 1);
-
- return retval ? -EIO : 0;
-}
-
-void
-user_enable_single_step (struct task_struct *child)
-{
- struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
-
- set_tsk_thread_flag(child, TIF_SINGLESTEP);
- child_psr->ss = 1;
-}
-
-void
-user_enable_block_step (struct task_struct *child)
-{
- struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
-
- set_tsk_thread_flag(child, TIF_SINGLESTEP);
- child_psr->tb = 1;
-}
-
-void
-user_disable_single_step (struct task_struct *child)
-{
- struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
-
- /* make sure the single step/taken-branch trap bits are not set: */
- clear_tsk_thread_flag(child, TIF_SINGLESTEP);
- child_psr->ss = 0;
- child_psr->tb = 0;
-}
-
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure the single step bit is not set.
- */
-void
-ptrace_disable (struct task_struct *child)
-{
- user_disable_single_step(child);
-}
-
-static int
-access_uarea (struct task_struct *child, unsigned long addr,
- unsigned long *data, int write_access);
-
-long
-arch_ptrace (struct task_struct *child, long request,
- unsigned long addr, unsigned long data)
-{
- switch (request) {
- case PTRACE_PEEKTEXT:
- case PTRACE_PEEKDATA:
- /* read word at location addr */
- if (ptrace_access_vm(child, addr, &data, sizeof(data),
- FOLL_FORCE)
- != sizeof(data))
- return -EIO;
- /* ensure return value is not mistaken for error code */
- force_successful_syscall_return();
- return data;
-
- /* PTRACE_POKETEXT and PTRACE_POKEDATA is handled
- * by the generic ptrace_request().
- */
-
- case PTRACE_PEEKUSR:
- /* read the word at addr in the USER area */
- if (access_uarea(child, addr, &data, 0) < 0)
- return -EIO;
- /* ensure return value is not mistaken for error code */
- force_successful_syscall_return();
- return data;
-
- case PTRACE_POKEUSR:
- /* write the word at addr in the USER area */
- if (access_uarea(child, addr, &data, 1) < 0)
- return -EIO;
- return 0;
-
- case PTRACE_OLD_GETSIGINFO:
- /* for backwards-compatibility */
- return ptrace_request(child, PTRACE_GETSIGINFO, addr, data);
-
- case PTRACE_OLD_SETSIGINFO:
- /* for backwards-compatibility */
- return ptrace_request(child, PTRACE_SETSIGINFO, addr, data);
-
- case PTRACE_GETREGS:
- return ptrace_getregs(child,
- (struct pt_all_user_regs __user *) data);
-
- case PTRACE_SETREGS:
- return ptrace_setregs(child,
- (struct pt_all_user_regs __user *) data);
-
- default:
- return ptrace_request(child, request, addr, data);
- }
-}
-
-
-/* "asmlinkage" so the input arguments are preserved... */
-
-asmlinkage long
-syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
- long arg4, long arg5, long arg6, long arg7,
- struct pt_regs regs)
-{
- if (test_thread_flag(TIF_SYSCALL_TRACE))
- if (ptrace_report_syscall_entry(&regs))
- return -ENOSYS;
-
- /* copy user rbs to kernel rbs */
- if (test_thread_flag(TIF_RESTORE_RSE))
- ia64_sync_krbs();
-
-
- audit_syscall_entry(regs.r15, arg0, arg1, arg2, arg3);
-
- return 0;
-}
-
-/* "asmlinkage" so the input arguments are preserved... */
-
-asmlinkage void
-syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
- long arg4, long arg5, long arg6, long arg7,
- struct pt_regs regs)
-{
- int step;
-
- audit_syscall_exit(&regs);
-
- step = test_thread_flag(TIF_SINGLESTEP);
- if (step || test_thread_flag(TIF_SYSCALL_TRACE))
- ptrace_report_syscall_exit(&regs, step);
-
- /* copy user rbs to kernel rbs */
- if (test_thread_flag(TIF_RESTORE_RSE))
- ia64_sync_krbs();
-}
-
-/* Utrace implementation starts here */
-struct regset_get {
- void *kbuf;
- void __user *ubuf;
-};
-
-struct regset_set {
- const void *kbuf;
- const void __user *ubuf;
-};
-
-struct regset_getset {
- struct task_struct *target;
- const struct user_regset *regset;
- union {
- struct regset_get get;
- struct regset_set set;
- } u;
- unsigned int pos;
- unsigned int count;
- int ret;
-};
-
-static const ptrdiff_t pt_offsets[32] =
-{
-#define R(n) offsetof(struct pt_regs, r##n)
- [0] = -1, R(1), R(2), R(3),
- [4] = -1, [5] = -1, [6] = -1, [7] = -1,
- R(8), R(9), R(10), R(11), R(12), R(13), R(14), R(15),
- R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
- R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),
-#undef R
-};
-
-static int
-access_elf_gpreg(struct task_struct *target, struct unw_frame_info *info,
- unsigned long addr, unsigned long *data, int write_access)
-{
- struct pt_regs *pt = task_pt_regs(target);
- unsigned reg = addr / sizeof(unsigned long);
- ptrdiff_t d = pt_offsets[reg];
-
- if (d >= 0) {
- unsigned long *ptr = (void *)pt + d;
- if (write_access)
- *ptr = *data;
- else
- *data = *ptr;
- return 0;
- } else {
- char nat = 0;
- if (write_access) {
- /* read NaT bit first: */
- unsigned long dummy;
- int ret = unw_get_gr(info, reg, &dummy, &nat);
- if (ret < 0)
- return ret;
- }
- return unw_access_gr(info, reg, data, &nat, write_access);
- }
-}
-
-static int
-access_elf_breg(struct task_struct *target, struct unw_frame_info *info,
- unsigned long addr, unsigned long *data, int write_access)
-{
- struct pt_regs *pt;
- unsigned long *ptr = NULL;
-
- pt = task_pt_regs(target);
- switch (addr) {
- case ELF_BR_OFFSET(0):
- ptr = &pt->b0;
- break;
- case ELF_BR_OFFSET(1) ... ELF_BR_OFFSET(5):
- return unw_access_br(info, (addr - ELF_BR_OFFSET(0))/8,
- data, write_access);
- case ELF_BR_OFFSET(6):
- ptr = &pt->b6;
- break;
- case ELF_BR_OFFSET(7):
- ptr = &pt->b7;
- }
- if (write_access)
- *ptr = *data;
- else
- *data = *ptr;
- return 0;
-}
-
-static int
-access_elf_areg(struct task_struct *target, struct unw_frame_info *info,
- unsigned long addr, unsigned long *data, int write_access)
-{
- struct pt_regs *pt;
- unsigned long cfm, urbs_end;
- unsigned long *ptr = NULL;
-
- pt = task_pt_regs(target);
- if (addr >= ELF_AR_RSC_OFFSET && addr <= ELF_AR_SSD_OFFSET) {
- switch (addr) {
- case ELF_AR_RSC_OFFSET:
- /* force PL3 */
- if (write_access)
- pt->ar_rsc = *data | (3 << 2);
- else
- *data = pt->ar_rsc;
- return 0;
- case ELF_AR_BSP_OFFSET:
- /*
- * By convention, we use PT_AR_BSP to refer to
- * the end of the user-level backing store.
- * Use ia64_rse_skip_regs(PT_AR_BSP, -CFM.sof)
- * to get the real value of ar.bsp at the time
- * the kernel was entered.
- *
- * Furthermore, when changing the contents of
- * PT_AR_BSP (or PT_CFM) while the task is
- * blocked in a system call, convert the state
- * so that the non-system-call exit
- * path is used. This ensures that the proper
- * state will be picked up when resuming
- * execution. However, it *also* means that
- * once we write PT_AR_BSP/PT_CFM, it won't be
- * possible to modify the syscall arguments of
- * the pending system call any longer. This
- * shouldn't be an issue because modifying
- * PT_AR_BSP/PT_CFM generally implies that
- * we're either abandoning the pending system
- * call or that we defer it's re-execution
- * (e.g., due to GDB doing an inferior
- * function call).
- */
- urbs_end = ia64_get_user_rbs_end(target, pt, &cfm);
- if (write_access) {
- if (*data != urbs_end) {
- if (in_syscall(pt))
- convert_to_non_syscall(target,
- pt,
- cfm);
- /*
- * Simulate user-level write
- * of ar.bsp:
- */
- pt->loadrs = 0;
- pt->ar_bspstore = *data;
- }
- } else
- *data = urbs_end;
- return 0;
- case ELF_AR_BSPSTORE_OFFSET:
- ptr = &pt->ar_bspstore;
- break;
- case ELF_AR_RNAT_OFFSET:
- ptr = &pt->ar_rnat;
- break;
- case ELF_AR_CCV_OFFSET:
- ptr = &pt->ar_ccv;
- break;
- case ELF_AR_UNAT_OFFSET:
- ptr = &pt->ar_unat;
- break;
- case ELF_AR_FPSR_OFFSET:
- ptr = &pt->ar_fpsr;
- break;
- case ELF_AR_PFS_OFFSET:
- ptr = &pt->ar_pfs;
- break;
- case ELF_AR_LC_OFFSET:
- return unw_access_ar(info, UNW_AR_LC, data,
- write_access);
- case ELF_AR_EC_OFFSET:
- return unw_access_ar(info, UNW_AR_EC, data,
- write_access);
- case ELF_AR_CSD_OFFSET:
- ptr = &pt->ar_csd;
- break;
- case ELF_AR_SSD_OFFSET:
- ptr = &pt->ar_ssd;
- }
- } else if (addr >= ELF_CR_IIP_OFFSET && addr <= ELF_CR_IPSR_OFFSET) {
- switch (addr) {
- case ELF_CR_IIP_OFFSET:
- ptr = &pt->cr_iip;
- break;
- case ELF_CFM_OFFSET:
- urbs_end = ia64_get_user_rbs_end(target, pt, &cfm);
- if (write_access) {
- if (((cfm ^ *data) & PFM_MASK) != 0) {
- if (in_syscall(pt))
- convert_to_non_syscall(target,
- pt,
- cfm);
- pt->cr_ifs = ((pt->cr_ifs & ~PFM_MASK)
- | (*data & PFM_MASK));
- }
- } else
- *data = cfm;
- return 0;
- case ELF_CR_IPSR_OFFSET:
- if (write_access) {
- unsigned long tmp = *data;
- /* psr.ri==3 is a reserved value: SDM 2:25 */
- if ((tmp & IA64_PSR_RI) == IA64_PSR_RI)
- tmp &= ~IA64_PSR_RI;
- pt->cr_ipsr = ((tmp & IPSR_MASK)
- | (pt->cr_ipsr & ~IPSR_MASK));
- } else
- *data = (pt->cr_ipsr & IPSR_MASK);
- return 0;
- }
- } else if (addr == ELF_NAT_OFFSET)
- return access_nat_bits(target, pt, info,
- data, write_access);
- else if (addr == ELF_PR_OFFSET)
- ptr = &pt->pr;
- else
- return -1;
-
- if (write_access)
- *ptr = *data;
- else
- *data = *ptr;
-
- return 0;
-}
-
-static int
-access_elf_reg(struct task_struct *target, struct unw_frame_info *info,
- unsigned long addr, unsigned long *data, int write_access)
-{
- if (addr >= ELF_GR_OFFSET(1) && addr <= ELF_GR_OFFSET(31))
- return access_elf_gpreg(target, info, addr, data, write_access);
- else if (addr >= ELF_BR_OFFSET(0) && addr <= ELF_BR_OFFSET(7))
- return access_elf_breg(target, info, addr, data, write_access);
- else
- return access_elf_areg(target, info, addr, data, write_access);
-}
-
-struct regset_membuf {
- struct membuf to;
- int ret;
-};
-
-static void do_gpregs_get(struct unw_frame_info *info, void *arg)
-{
- struct regset_membuf *dst = arg;
- struct membuf to = dst->to;
- unsigned int n;
- elf_greg_t reg;
-
- if (unw_unwind_to_user(info) < 0)
- return;
-
- /*
- * coredump format:
- * r0-r31
- * NaT bits (for r0-r31; bit N == 1 iff rN is a NaT)
- * predicate registers (p0-p63)
- * b0-b7
- * ip cfm user-mask
- * ar.rsc ar.bsp ar.bspstore ar.rnat
- * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec
- */
-
-
- /* Skip r0 */
- membuf_zero(&to, 8);
- for (n = 8; to.left && n < ELF_AR_END_OFFSET; n += 8) {
- if (access_elf_reg(info->task, info, n, &reg, 0) < 0) {
- dst->ret = -EIO;
- return;
- }
- membuf_store(&to, reg);
- }
-}
-
-static void do_gpregs_set(struct unw_frame_info *info, void *arg)
-{
- struct regset_getset *dst = arg;
-
- if (unw_unwind_to_user(info) < 0)
- return;
-
- if (!dst->count)
- return;
- /* Skip r0 */
- if (dst->pos < ELF_GR_OFFSET(1)) {
- user_regset_copyin_ignore(&dst->pos, &dst->count,
- &dst->u.set.kbuf, &dst->u.set.ubuf,
- 0, ELF_GR_OFFSET(1));
- dst->ret = 0;
- }
-
- while (dst->count && dst->pos < ELF_AR_END_OFFSET) {
- unsigned int n, from, to;
- elf_greg_t tmp[16];
-
- from = dst->pos;
- to = from + sizeof(tmp);
- if (to > ELF_AR_END_OFFSET)
- to = ELF_AR_END_OFFSET;
- /* get up to 16 values */
- dst->ret = user_regset_copyin(&dst->pos, &dst->count,
- &dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
- from, to);
- if (dst->ret)
- return;
- /* now copy them into registers */
- for (n = 0; from < dst->pos; from += sizeof(elf_greg_t), n++)
- if (access_elf_reg(dst->target, info, from,
- &tmp[n], 1) < 0) {
- dst->ret = -EIO;
- return;
- }
- }
-}
-
-#define ELF_FP_OFFSET(i) (i * sizeof(elf_fpreg_t))
-
-static void do_fpregs_get(struct unw_frame_info *info, void *arg)
-{
- struct task_struct *task = info->task;
- struct regset_membuf *dst = arg;
- struct membuf to = dst->to;
- elf_fpreg_t reg;
- unsigned int n;
-
- if (unw_unwind_to_user(info) < 0)
- return;
-
- /* Skip pos 0 and 1 */
- membuf_zero(&to, 2 * sizeof(elf_fpreg_t));
-
- /* fr2-fr31 */
- for (n = 2; to.left && n < 32; n++) {
- if (unw_get_fr(info, n, &reg)) {
- dst->ret = -EIO;
- return;
- }
- membuf_write(&to, &reg, sizeof(reg));
- }
-
- /* fph */
- if (!to.left)
- return;
-
- ia64_flush_fph(task);
- if (task->thread.flags & IA64_THREAD_FPH_VALID)
- membuf_write(&to, &task->thread.fph, 96 * sizeof(reg));
- else
- membuf_zero(&to, 96 * sizeof(reg));
-}
-
-static void do_fpregs_set(struct unw_frame_info *info, void *arg)
-{
- struct regset_getset *dst = arg;
- elf_fpreg_t fpreg, tmp[30];
- int index, start, end;
-
- if (unw_unwind_to_user(info) < 0)
- return;
-
- /* Skip pos 0 and 1 */
- if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(2)) {
- user_regset_copyin_ignore(&dst->pos, &dst->count,
- &dst->u.set.kbuf, &dst->u.set.ubuf,
- 0, ELF_FP_OFFSET(2));
- dst->ret = 0;
- if (dst->count == 0)
- return;
- }
-
- /* fr2-fr31 */
- if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(32)) {
- start = dst->pos;
- end = min(((unsigned int)ELF_FP_OFFSET(32)),
- dst->pos + dst->count);
- dst->ret = user_regset_copyin(&dst->pos, &dst->count,
- &dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
- ELF_FP_OFFSET(2), ELF_FP_OFFSET(32));
- if (dst->ret)
- return;
-
- if (start & 0xF) { /* only write high part */
- if (unw_get_fr(info, start / sizeof(elf_fpreg_t),
- &fpreg)) {
- dst->ret = -EIO;
- return;
- }
- tmp[start / sizeof(elf_fpreg_t) - 2].u.bits[0]
- = fpreg.u.bits[0];
- start &= ~0xFUL;
- }
- if (end & 0xF) { /* only write low part */
- if (unw_get_fr(info, end / sizeof(elf_fpreg_t),
- &fpreg)) {
- dst->ret = -EIO;
- return;
- }
- tmp[end / sizeof(elf_fpreg_t) - 2].u.bits[1]
- = fpreg.u.bits[1];
- end = (end + 0xF) & ~0xFUL;
- }
-
- for ( ; start < end ; start += sizeof(elf_fpreg_t)) {
- index = start / sizeof(elf_fpreg_t);
- if (unw_set_fr(info, index, tmp[index - 2])) {
- dst->ret = -EIO;
- return;
- }
- }
- if (dst->ret || dst->count == 0)
- return;
- }
-
- /* fph */
- if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(128)) {
- ia64_sync_fph(dst->target);
- dst->ret = user_regset_copyin(&dst->pos, &dst->count,
- &dst->u.set.kbuf,
- &dst->u.set.ubuf,
- &dst->target->thread.fph,
- ELF_FP_OFFSET(32), -1);
- }
-}
-
-static void
-unwind_and_call(void (*call)(struct unw_frame_info *, void *),
- struct task_struct *target, void *data)
-{
- if (target == current)
- unw_init_running(call, data);
- else {
- struct unw_frame_info info;
- memset(&info, 0, sizeof(info));
- unw_init_from_blocked_task(&info, target);
- (*call)(&info, data);
- }
-}
-
-static int
-do_regset_call(void (*call)(struct unw_frame_info *, void *),
- struct task_struct *target,
- const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- const void *kbuf, const void __user *ubuf)
-{
- struct regset_getset info = { .target = target, .regset = regset,
- .pos = pos, .count = count,
- .u.set = { .kbuf = kbuf, .ubuf = ubuf },
- .ret = 0 };
- unwind_and_call(call, target, &info);
- return info.ret;
-}
-
-static int
-gpregs_get(struct task_struct *target,
- const struct user_regset *regset,
- struct membuf to)
-{
- struct regset_membuf info = {.to = to};
- unwind_and_call(do_gpregs_get, target, &info);
- return info.ret;
-}
-
-static int gpregs_set(struct task_struct *target,
- const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- const void *kbuf, const void __user *ubuf)
-{
- return do_regset_call(do_gpregs_set, target, regset, pos, count,
- kbuf, ubuf);
-}
-
-static void do_gpregs_writeback(struct unw_frame_info *info, void *arg)
-{
- do_sync_rbs(info, ia64_sync_user_rbs);
-}
-
-/*
- * This is called to write back the register backing store.
- * ptrace does this before it stops, so that a tracer reading the user
- * memory after the thread stops will get the current register data.
- */
-static int
-gpregs_writeback(struct task_struct *target,
- const struct user_regset *regset,
- int now)
-{
- if (test_and_set_tsk_thread_flag(target, TIF_RESTORE_RSE))
- return 0;
- set_notify_resume(target);
- return do_regset_call(do_gpregs_writeback, target, regset, 0, 0,
- NULL, NULL);
-}
-
-static int
-fpregs_active(struct task_struct *target, const struct user_regset *regset)
-{
- return (target->thread.flags & IA64_THREAD_FPH_VALID) ? 128 : 32;
-}
-
-static int fpregs_get(struct task_struct *target,
- const struct user_regset *regset,
- struct membuf to)
-{
- struct regset_membuf info = {.to = to};
- unwind_and_call(do_fpregs_get, target, &info);
- return info.ret;
-}
-
-static int fpregs_set(struct task_struct *target,
- const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- const void *kbuf, const void __user *ubuf)
-{
- return do_regset_call(do_fpregs_set, target, regset, pos, count,
- kbuf, ubuf);
-}
-
-static int
-access_uarea(struct task_struct *child, unsigned long addr,
- unsigned long *data, int write_access)
-{
- unsigned int pos = -1; /* an invalid value */
- unsigned long *ptr, regnum;
-
- if ((addr & 0x7) != 0) {
- dprintk("ptrace: unaligned register address 0x%lx\n", addr);
- return -1;
- }
- if ((addr >= PT_NAT_BITS + 8 && addr < PT_F2) ||
- (addr >= PT_R7 + 8 && addr < PT_B1) ||
- (addr >= PT_AR_LC + 8 && addr < PT_CR_IPSR) ||
- (addr >= PT_AR_SSD + 8 && addr < PT_DBR)) {
- dprintk("ptrace: rejecting access to register "
- "address 0x%lx\n", addr);
- return -1;
- }
-
- switch (addr) {
- case PT_F32 ... (PT_F127 + 15):
- pos = addr - PT_F32 + ELF_FP_OFFSET(32);
- break;
- case PT_F2 ... (PT_F5 + 15):
- pos = addr - PT_F2 + ELF_FP_OFFSET(2);
- break;
- case PT_F10 ... (PT_F31 + 15):
- pos = addr - PT_F10 + ELF_FP_OFFSET(10);
- break;
- case PT_F6 ... (PT_F9 + 15):
- pos = addr - PT_F6 + ELF_FP_OFFSET(6);
- break;
- }
-
- if (pos != -1) {
- unsigned reg = pos / sizeof(elf_fpreg_t);
- int which_half = (pos / sizeof(unsigned long)) & 1;
-
- if (reg < 32) { /* fr2-fr31 */
- struct unw_frame_info info;
- elf_fpreg_t fpreg;
-
- memset(&info, 0, sizeof(info));
- unw_init_from_blocked_task(&info, child);
- if (unw_unwind_to_user(&info) < 0)
- return 0;
-
- if (unw_get_fr(&info, reg, &fpreg))
- return -1;
- if (write_access) {
- fpreg.u.bits[which_half] = *data;
- if (unw_set_fr(&info, reg, fpreg))
- return -1;
- } else {
- *data = fpreg.u.bits[which_half];
- }
- } else { /* fph */
- elf_fpreg_t *p = &child->thread.fph[reg - 32];
- unsigned long *bits = &p->u.bits[which_half];
-
- ia64_sync_fph(child);
- if (write_access)
- *bits = *data;
- else if (child->thread.flags & IA64_THREAD_FPH_VALID)
- *data = *bits;
- else
- *data = 0;
- }
- return 0;
- }
-
- switch (addr) {
- case PT_NAT_BITS:
- pos = ELF_NAT_OFFSET;
- break;
- case PT_R4 ... PT_R7:
- pos = addr - PT_R4 + ELF_GR_OFFSET(4);
- break;
- case PT_B1 ... PT_B5:
- pos = addr - PT_B1 + ELF_BR_OFFSET(1);
- break;
- case PT_AR_EC:
- pos = ELF_AR_EC_OFFSET;
- break;
- case PT_AR_LC:
- pos = ELF_AR_LC_OFFSET;
- break;
- case PT_CR_IPSR:
- pos = ELF_CR_IPSR_OFFSET;
- break;
- case PT_CR_IIP:
- pos = ELF_CR_IIP_OFFSET;
- break;
- case PT_CFM:
- pos = ELF_CFM_OFFSET;
- break;
- case PT_AR_UNAT:
- pos = ELF_AR_UNAT_OFFSET;
- break;
- case PT_AR_PFS:
- pos = ELF_AR_PFS_OFFSET;
- break;
- case PT_AR_RSC:
- pos = ELF_AR_RSC_OFFSET;
- break;
- case PT_AR_RNAT:
- pos = ELF_AR_RNAT_OFFSET;
- break;
- case PT_AR_BSPSTORE:
- pos = ELF_AR_BSPSTORE_OFFSET;
- break;
- case PT_PR:
- pos = ELF_PR_OFFSET;
- break;
- case PT_B6:
- pos = ELF_BR_OFFSET(6);
- break;
- case PT_AR_BSP:
- pos = ELF_AR_BSP_OFFSET;
- break;
- case PT_R1 ... PT_R3:
- pos = addr - PT_R1 + ELF_GR_OFFSET(1);
- break;
- case PT_R12 ... PT_R15:
- pos = addr - PT_R12 + ELF_GR_OFFSET(12);
- break;
- case PT_R8 ... PT_R11:
- pos = addr - PT_R8 + ELF_GR_OFFSET(8);
- break;
- case PT_R16 ... PT_R31:
- pos = addr - PT_R16 + ELF_GR_OFFSET(16);
- break;
- case PT_AR_CCV:
- pos = ELF_AR_CCV_OFFSET;
- break;
- case PT_AR_FPSR:
- pos = ELF_AR_FPSR_OFFSET;
- break;
- case PT_B0:
- pos = ELF_BR_OFFSET(0);
- break;
- case PT_B7:
- pos = ELF_BR_OFFSET(7);
- break;
- case PT_AR_CSD:
- pos = ELF_AR_CSD_OFFSET;
- break;
- case PT_AR_SSD:
- pos = ELF_AR_SSD_OFFSET;
- break;
- }
-
- if (pos != -1) {
- struct unw_frame_info info;
-
- memset(&info, 0, sizeof(info));
- unw_init_from_blocked_task(&info, child);
- if (unw_unwind_to_user(&info) < 0)
- return 0;
-
- return access_elf_reg(child, &info, pos, data, write_access);
- }
-
- /* access debug registers */
- if (addr >= PT_IBR) {
- regnum = (addr - PT_IBR) >> 3;
- ptr = &child->thread.ibr[0];
- } else {
- regnum = (addr - PT_DBR) >> 3;
- ptr = &child->thread.dbr[0];
- }
-
- if (regnum >= 8) {
- dprintk("ptrace: rejecting access to register "
- "address 0x%lx\n", addr);
- return -1;
- }
-
- if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
- child->thread.flags |= IA64_THREAD_DBG_VALID;
- memset(child->thread.dbr, 0,
- sizeof(child->thread.dbr));
- memset(child->thread.ibr, 0,
- sizeof(child->thread.ibr));
- }
-
- ptr += regnum;
-
- if ((regnum & 1) && write_access) {
- /* don't let the user set kernel-level breakpoints: */
- *ptr = *data & ~(7UL << 56);
- return 0;
- }
- if (write_access)
- *ptr = *data;
- else
- *data = *ptr;
- return 0;
-}
-
-static const struct user_regset native_regsets[] = {
- {
- .core_note_type = NT_PRSTATUS,
- .n = ELF_NGREG,
- .size = sizeof(elf_greg_t), .align = sizeof(elf_greg_t),
- .regset_get = gpregs_get, .set = gpregs_set,
- .writeback = gpregs_writeback
- },
- {
- .core_note_type = NT_PRFPREG,
- .n = ELF_NFPREG,
- .size = sizeof(elf_fpreg_t), .align = sizeof(elf_fpreg_t),
- .regset_get = fpregs_get, .set = fpregs_set, .active = fpregs_active
- },
-};
-
-static const struct user_regset_view user_ia64_view = {
- .name = "ia64",
- .e_machine = EM_IA_64,
- .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
-};
-
-const struct user_regset_view *task_user_regset_view(struct task_struct *tsk)
-{
- return &user_ia64_view;
-}
-
-struct syscall_get_args {
- unsigned int i;
- unsigned int n;
- unsigned long *args;
- struct pt_regs *regs;
-};
-
-static void syscall_get_args_cb(struct unw_frame_info *info, void *data)
-{
- struct syscall_get_args *args = data;
- struct pt_regs *pt = args->regs;
- unsigned long *krbs, cfm, ndirty, nlocals, nouts;
- int i, count;
-
- if (unw_unwind_to_user(info) < 0)
- return;
-
- /*
- * We get here via a few paths:
- * - break instruction: cfm is shared with caller.
- * syscall args are in out= regs, locals are non-empty.
- * - epsinstruction: cfm is set by br.call
- * locals don't exist.
- *
- * For both cases arguments are reachable in cfm.sof - cfm.sol.
- * CFM: [ ... | sor: 17..14 | sol : 13..7 | sof : 6..0 ]
- */
- cfm = pt->cr_ifs;
- nlocals = (cfm >> 7) & 0x7f; /* aka sol */
- nouts = (cfm & 0x7f) - nlocals; /* aka sof - sol */
- krbs = (unsigned long *)info->task + IA64_RBS_OFFSET/8;
- ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19));
-
- count = 0;
- if (in_syscall(pt))
- count = min_t(int, args->n, nouts);
-
- /* Iterate over outs. */
- for (i = 0; i < count; i++) {
- int j = ndirty + nlocals + i + args->i;
- args->args[i] = *ia64_rse_skip_regs(krbs, j);
- }
-
- while (i < args->n) {
- args->args[i] = 0;
- i++;
- }
-}
-
-void syscall_get_arguments(struct task_struct *task,
- struct pt_regs *regs, unsigned long *args)
-{
- struct syscall_get_args data = {
- .i = 0,
- .n = 6,
- .args = args,
- .regs = regs,
- };
-
- if (task == current)
- unw_init_running(syscall_get_args_cb, &data);
- else {
- struct unw_frame_info ufi;
- memset(&ufi, 0, sizeof(ufi));
- unw_init_from_blocked_task(&ufi, task);
- syscall_get_args_cb(&ufi, &data);
- }
-}
diff --git a/arch/ia64/kernel/relocate_kernel.S b/arch/ia64/kernel/relocate_kernel.S
deleted file mode 100644
index 527a7b896a6e..000000000000
--- a/arch/ia64/kernel/relocate_kernel.S
+++ /dev/null
@@ -1,321 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/ia64/kernel/relocate_kernel.S
- *
- * Relocate kexec'able kernel and start it
- *
- * Copyright (C) 2005 Hewlett-Packard Development Company, L.P.
- * Copyright (C) 2005 Khalid Aziz <khalid.aziz@hp.com>
- * Copyright (C) 2005 Intel Corp, Zou Nan hai <nanhai.zou@intel.com>
- */
-#include <linux/pgtable.h>
-#include <asm/asmmacro.h>
-#include <asm/kregs.h>
-#include <asm/page.h>
-#include <asm/mca_asm.h>
-
- /* Must be relocatable PIC code callable as a C function
- */
-GLOBAL_ENTRY(relocate_new_kernel)
- .prologue
- alloc r31=ar.pfs,4,0,0,0
- .body
-.reloc_entry:
-{
- rsm psr.i| psr.ic
- mov r2=ip
-}
- ;;
-{
- flushrs // must be first insn in group
- srlz.i
-}
- ;;
- dep r2=0,r2,61,3 //to physical address
- ;;
- //first switch to physical mode
- add r3=1f-.reloc_entry, r2
- movl r16 = IA64_PSR_AC|IA64_PSR_BN|IA64_PSR_IC
- mov ar.rsc=0 // put RSE in enforced lazy mode
- ;;
- add sp=(memory_stack_end - 16 - .reloc_entry),r2
- add r8=(register_stack - .reloc_entry),r2
- ;;
- mov r18=ar.rnat
- mov ar.bspstore=r8
- ;;
- mov cr.ipsr=r16
- mov cr.iip=r3
- mov cr.ifs=r0
- srlz.i
- ;;
- mov ar.rnat=r18
- rfi // note: this unmask MCA/INIT (psr.mc)
- ;;
-1:
- //physical mode code begin
- mov b6=in1
- dep r28=0,in2,61,3 //to physical address
-
- // purge all TC entries
-#define O(member) IA64_CPUINFO_##member##_OFFSET
- GET_THIS_PADDR(r2, ia64_cpu_info) // load phys addr of cpu_info into r2
- ;;
- addl r17=O(PTCE_STRIDE),r2
- addl r2=O(PTCE_BASE),r2
- ;;
- ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));; // r18=ptce_base
- ld4 r19=[r2],4 // r19=ptce_count[0]
- ld4 r21=[r17],4 // r21=ptce_stride[0]
- ;;
- ld4 r20=[r2] // r20=ptce_count[1]
- ld4 r22=[r17] // r22=ptce_stride[1]
- mov r24=r0
- ;;
- adds r20=-1,r20
- ;;
-#undef O
-2:
- cmp.ltu p6,p7=r24,r19
-(p7) br.cond.dpnt.few 4f
- mov ar.lc=r20
-3:
- ptc.e r18
- ;;
- add r18=r22,r18
- br.cloop.sptk.few 3b
- ;;
- add r18=r21,r18
- add r24=1,r24
- ;;
- br.sptk.few 2b
-4:
- srlz.i
- ;;
- // purge TR entry for kernel text and data
- movl r16=KERNEL_START
- mov r18=KERNEL_TR_PAGE_SHIFT<<2
- ;;
- ptr.i r16, r18
- ptr.d r16, r18
- ;;
- srlz.i
- ;;
-
- // purge TR entry for pal code
- mov r16=in3
- mov r18=IA64_GRANULE_SHIFT<<2
- ;;
- ptr.i r16,r18
- ;;
- srlz.i
- ;;
-
- // purge TR entry for stack
- mov r16=IA64_KR(CURRENT_STACK)
- ;;
- shl r16=r16,IA64_GRANULE_SHIFT
- movl r19=PAGE_OFFSET
- ;;
- add r16=r19,r16
- mov r18=IA64_GRANULE_SHIFT<<2
- ;;
- ptr.d r16,r18
- ;;
- srlz.i
- ;;
-
- //copy segments
- movl r16=PAGE_MASK
- mov r30=in0 // in0 is page_list
- br.sptk.few .dest_page
- ;;
-.loop:
- ld8 r30=[in0], 8;;
-.dest_page:
- tbit.z p0, p6=r30, 0;; // 0x1 dest page
-(p6) and r17=r30, r16
-(p6) br.cond.sptk.few .loop;;
-
- tbit.z p0, p6=r30, 1;; // 0x2 indirect page
-(p6) and in0=r30, r16
-(p6) br.cond.sptk.few .loop;;
-
- tbit.z p0, p6=r30, 2;; // 0x4 end flag
-(p6) br.cond.sptk.few .end_loop;;
-
- tbit.z p6, p0=r30, 3;; // 0x8 source page
-(p6) br.cond.sptk.few .loop
-
- and r18=r30, r16
-
- // simple copy page, may optimize later
- movl r14=PAGE_SIZE/8 - 1;;
- mov ar.lc=r14;;
-1:
- ld8 r14=[r18], 8;;
- st8 [r17]=r14;;
- fc.i r17
- add r17=8, r17
- br.ctop.sptk.few 1b
- br.sptk.few .loop
- ;;
-
-.end_loop:
- sync.i // for fc.i
- ;;
- srlz.i
- ;;
- srlz.d
- ;;
- br.call.sptk.many b0=b6;;
-
-.align 32
-memory_stack:
- .fill 8192, 1, 0
-memory_stack_end:
-register_stack:
- .fill 8192, 1, 0
-register_stack_end:
-relocate_new_kernel_end:
-END(relocate_new_kernel)
-
-.global relocate_new_kernel_size
-relocate_new_kernel_size:
- data8 relocate_new_kernel_end - relocate_new_kernel
-
-GLOBAL_ENTRY(ia64_dump_cpu_regs)
- .prologue
- alloc loc0=ar.pfs,1,2,0,0
- .body
- mov ar.rsc=0 // put RSE in enforced lazy mode
- add loc1=4*8, in0 // save r4 and r5 first
- ;;
-{
- flushrs // flush dirty regs to backing store
- srlz.i
-}
- st8 [loc1]=r4, 8
- ;;
- st8 [loc1]=r5, 8
- ;;
- add loc1=32*8, in0
- mov r4=ar.rnat
- ;;
- st8 [in0]=r0, 8 // r0
- st8 [loc1]=r4, 8 // rnat
- mov r5=pr
- ;;
- st8 [in0]=r1, 8 // r1
- st8 [loc1]=r5, 8 // pr
- mov r4=b0
- ;;
- st8 [in0]=r2, 8 // r2
- st8 [loc1]=r4, 8 // b0
- mov r5=b1;
- ;;
- st8 [in0]=r3, 24 // r3
- st8 [loc1]=r5, 8 // b1
- mov r4=b2
- ;;
- st8 [in0]=r6, 8 // r6
- st8 [loc1]=r4, 8 // b2
- mov r5=b3
- ;;
- st8 [in0]=r7, 8 // r7
- st8 [loc1]=r5, 8 // b3
- mov r4=b4
- ;;
- st8 [in0]=r8, 8 // r8
- st8 [loc1]=r4, 8 // b4
- mov r5=b5
- ;;
- st8 [in0]=r9, 8 // r9
- st8 [loc1]=r5, 8 // b5
- mov r4=b6
- ;;
- st8 [in0]=r10, 8 // r10
- st8 [loc1]=r5, 8 // b6
- mov r5=b7
- ;;
- st8 [in0]=r11, 8 // r11
- st8 [loc1]=r5, 8 // b7
- mov r4=b0
- ;;
- st8 [in0]=r12, 8 // r12
- st8 [loc1]=r4, 8 // ip
- mov r5=loc0
- ;;
- st8 [in0]=r13, 8 // r13
- extr.u r5=r5, 0, 38 // ar.pfs.pfm
- mov r4=r0 // user mask
- ;;
- st8 [in0]=r14, 8 // r14
- st8 [loc1]=r5, 8 // cfm
- ;;
- st8 [in0]=r15, 8 // r15
- st8 [loc1]=r4, 8 // user mask
- mov r5=ar.rsc
- ;;
- st8 [in0]=r16, 8 // r16
- st8 [loc1]=r5, 8 // ar.rsc
- mov r4=ar.bsp
- ;;
- st8 [in0]=r17, 8 // r17
- st8 [loc1]=r4, 8 // ar.bsp
- mov r5=ar.bspstore
- ;;
- st8 [in0]=r18, 8 // r18
- st8 [loc1]=r5, 8 // ar.bspstore
- mov r4=ar.rnat
- ;;
- st8 [in0]=r19, 8 // r19
- st8 [loc1]=r4, 8 // ar.rnat
- mov r5=ar.ccv
- ;;
- st8 [in0]=r20, 8 // r20
- st8 [loc1]=r5, 8 // ar.ccv
- mov r4=ar.unat
- ;;
- st8 [in0]=r21, 8 // r21
- st8 [loc1]=r4, 8 // ar.unat
- mov r5 = ar.fpsr
- ;;
- st8 [in0]=r22, 8 // r22
- st8 [loc1]=r5, 8 // ar.fpsr
- mov r4 = ar.unat
- ;;
- st8 [in0]=r23, 8 // r23
- st8 [loc1]=r4, 8 // unat
- mov r5 = ar.fpsr
- ;;
- st8 [in0]=r24, 8 // r24
- st8 [loc1]=r5, 8 // fpsr
- mov r4 = ar.pfs
- ;;
- st8 [in0]=r25, 8 // r25
- st8 [loc1]=r4, 8 // ar.pfs
- mov r5 = ar.lc
- ;;
- st8 [in0]=r26, 8 // r26
- st8 [loc1]=r5, 8 // ar.lc
- mov r4 = ar.ec
- ;;
- st8 [in0]=r27, 8 // r27
- st8 [loc1]=r4, 8 // ar.ec
- mov r5 = ar.csd
- ;;
- st8 [in0]=r28, 8 // r28
- st8 [loc1]=r5, 8 // ar.csd
- mov r4 = ar.ssd
- ;;
- st8 [in0]=r29, 8 // r29
- st8 [loc1]=r4, 8 // ar.ssd
- ;;
- st8 [in0]=r30, 8 // r30
- ;;
- st8 [in0]=r31, 8 // r31
- mov ar.pfs=loc0
- ;;
- br.ret.sptk.many rp
-END(ia64_dump_cpu_regs)
diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c
deleted file mode 100644
index e4f0705c0282..000000000000
--- a/arch/ia64/kernel/sal.c
+++ /dev/null
@@ -1,400 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * System Abstraction Layer (SAL) interface routines.
- *
- * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-
-#include <asm/delay.h>
-#include <asm/page.h>
-#include <asm/sal.h>
-#include <asm/pal.h>
-#include <asm/xtp.h>
-
- __cacheline_aligned DEFINE_SPINLOCK(sal_lock);
-unsigned long sal_platform_features;
-
-unsigned short sal_revision;
-unsigned short sal_version;
-
-#define SAL_MAJOR(x) ((x) >> 8)
-#define SAL_MINOR(x) ((x) & 0xff)
-
-static struct {
- void *addr; /* function entry point */
- void *gpval; /* gp value to use */
-} pdesc;
-
-static long
-default_handler (void)
-{
- return -1;
-}
-
-ia64_sal_handler ia64_sal = (ia64_sal_handler) default_handler;
-ia64_sal_desc_ptc_t *ia64_ptc_domain_info;
-
-const char *
-ia64_sal_strerror (long status)
-{
- const char *str;
- switch (status) {
- case 0: str = "Call completed without error"; break;
- case 1: str = "Effect a warm boot of the system to complete "
- "the update"; break;
- case -1: str = "Not implemented"; break;
- case -2: str = "Invalid argument"; break;
- case -3: str = "Call completed with error"; break;
- case -4: str = "Virtual address not registered"; break;
- case -5: str = "No information available"; break;
- case -6: str = "Insufficient space to add the entry"; break;
- case -7: str = "Invalid entry_addr value"; break;
- case -8: str = "Invalid interrupt vector"; break;
- case -9: str = "Requested memory not available"; break;
- case -10: str = "Unable to write to the NVM device"; break;
- case -11: str = "Invalid partition type specified"; break;
- case -12: str = "Invalid NVM_Object id specified"; break;
- case -13: str = "NVM_Object already has the maximum number "
- "of partitions"; break;
- case -14: str = "Insufficient space in partition for the "
- "requested write sub-function"; break;
- case -15: str = "Insufficient data buffer space for the "
- "requested read record sub-function"; break;
- case -16: str = "Scratch buffer required for the write/delete "
- "sub-function"; break;
- case -17: str = "Insufficient space in the NVM_Object for the "
- "requested create sub-function"; break;
- case -18: str = "Invalid value specified in the partition_rec "
- "argument"; break;
- case -19: str = "Record oriented I/O not supported for this "
- "partition"; break;
- case -20: str = "Bad format of record to be written or "
- "required keyword variable not "
- "specified"; break;
- default: str = "Unknown SAL status code"; break;
- }
- return str;
-}
-
-void __init
-ia64_sal_handler_init (void *entry_point, void *gpval)
-{
- /* fill in the SAL procedure descriptor and point ia64_sal to it: */
- pdesc.addr = entry_point;
- pdesc.gpval = gpval;
- ia64_sal = (ia64_sal_handler) &pdesc;
-}
-
-static void __init
-check_versions (struct ia64_sal_systab *systab)
-{
- sal_revision = (systab->sal_rev_major << 8) | systab->sal_rev_minor;
- sal_version = (systab->sal_b_rev_major << 8) | systab->sal_b_rev_minor;
-
- /* Check for broken firmware */
- if ((sal_revision == SAL_VERSION_CODE(49, 29))
- && (sal_version == SAL_VERSION_CODE(49, 29)))
- {
- /*
- * Old firmware for zx2000 prototypes have this weird version number,
- * reset it to something sane.
- */
- sal_revision = SAL_VERSION_CODE(2, 8);
- sal_version = SAL_VERSION_CODE(0, 0);
- }
-}
-
-static void __init
-sal_desc_entry_point (void *p)
-{
- struct ia64_sal_desc_entry_point *ep = p;
- ia64_pal_handler_init(__va(ep->pal_proc));
- ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp));
-}
-
-#ifdef CONFIG_SMP
-static void __init
-set_smp_redirect (int flag)
-{
-#ifndef CONFIG_HOTPLUG_CPU
- if (no_int_routing)
- smp_int_redirect &= ~flag;
- else
- smp_int_redirect |= flag;
-#else
- /*
- * For CPU Hotplug we dont want to do any chipset supported
- * interrupt redirection. The reason is this would require that
- * All interrupts be stopped and hard bind the irq to a cpu.
- * Later when the interrupt is fired we need to set the redir hint
- * on again in the vector. This is cumbersome for something that the
- * user mode irq balancer will solve anyways.
- */
- no_int_routing=1;
- smp_int_redirect &= ~flag;
-#endif
-}
-#else
-#define set_smp_redirect(flag) do { } while (0)
-#endif
-
-static void __init
-sal_desc_platform_feature (void *p)
-{
- struct ia64_sal_desc_platform_feature *pf = p;
- sal_platform_features = pf->feature_mask;
-
- printk(KERN_INFO "SAL Platform features:");
- if (!sal_platform_features) {
- printk(" None\n");
- return;
- }
-
- if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK)
- printk(" BusLock");
- if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT) {
- printk(" IRQ_Redirection");
- set_smp_redirect(SMP_IRQ_REDIRECTION);
- }
- if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT) {
- printk(" IPI_Redirection");
- set_smp_redirect(SMP_IPI_REDIRECTION);
- }
- if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)
- printk(" ITC_Drift");
- printk("\n");
-}
-
-#ifdef CONFIG_SMP
-static void __init
-sal_desc_ap_wakeup (void *p)
-{
- struct ia64_sal_desc_ap_wakeup *ap = p;
-
- switch (ap->mechanism) {
- case IA64_SAL_AP_EXTERNAL_INT:
- ap_wakeup_vector = ap->vector;
- printk(KERN_INFO "SAL: AP wakeup using external interrupt "
- "vector 0x%lx\n", ap_wakeup_vector);
- break;
- default:
- printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n");
- break;
- }
-}
-
-static void __init
-chk_nointroute_opt(void)
-{
- char *cp;
-
- for (cp = boot_command_line; *cp; ) {
- if (memcmp(cp, "nointroute", 10) == 0) {
- no_int_routing = 1;
- printk ("no_int_routing on\n");
- break;
- } else {
- while (*cp != ' ' && *cp)
- ++cp;
- while (*cp == ' ')
- ++cp;
- }
- }
-}
-
-#else
-static void __init sal_desc_ap_wakeup(void *p) { }
-#endif
-
-/*
- * HP rx5670 firmware polls for interrupts during SAL_CACHE_FLUSH by reading
- * cr.ivr, but it never writes cr.eoi. This leaves any interrupt marked as
- * "in-service" and masks other interrupts of equal or lower priority.
- *
- * HP internal defect reports: F1859, F2775, F3031.
- */
-static int sal_cache_flush_drops_interrupts;
-
-static int __init
-force_pal_cache_flush(char *str)
-{
- sal_cache_flush_drops_interrupts = 1;
- return 0;
-}
-early_param("force_pal_cache_flush", force_pal_cache_flush);
-
-void __init
-check_sal_cache_flush (void)
-{
- unsigned long flags;
- int cpu;
- u64 vector, cache_type = 3;
- struct ia64_sal_retval isrv;
-
- if (sal_cache_flush_drops_interrupts)
- return;
-
- cpu = get_cpu();
- local_irq_save(flags);
-
- /*
- * Send ourselves a timer interrupt, wait until it's reported, and see
- * if SAL_CACHE_FLUSH drops it.
- */
- ia64_send_ipi(cpu, IA64_TIMER_VECTOR, IA64_IPI_DM_INT, 0);
-
- while (!ia64_get_irr(IA64_TIMER_VECTOR))
- cpu_relax();
-
- SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
-
- if (isrv.status)
- printk(KERN_ERR "SAL_CAL_FLUSH failed with %ld\n", isrv.status);
-
- if (ia64_get_irr(IA64_TIMER_VECTOR)) {
- vector = ia64_get_ivr();
- ia64_eoi();
- WARN_ON(vector != IA64_TIMER_VECTOR);
- } else {
- sal_cache_flush_drops_interrupts = 1;
- printk(KERN_ERR "SAL: SAL_CACHE_FLUSH drops interrupts; "
- "PAL_CACHE_FLUSH will be used instead\n");
- ia64_eoi();
- }
-
- local_irq_restore(flags);
- put_cpu();
-}
-
-s64
-ia64_sal_cache_flush (u64 cache_type)
-{
- struct ia64_sal_retval isrv;
-
- if (sal_cache_flush_drops_interrupts) {
- unsigned long flags;
- u64 progress;
- s64 rc;
-
- progress = 0;
- local_irq_save(flags);
- rc = ia64_pal_cache_flush(cache_type,
- PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL);
- local_irq_restore(flags);
- return rc;
- }
-
- SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
- return isrv.status;
-}
-EXPORT_SYMBOL_GPL(ia64_sal_cache_flush);
-
-void __init
-ia64_sal_init (struct ia64_sal_systab *systab)
-{
- char *p;
- int i;
-
- if (!systab) {
- printk(KERN_WARNING "Hmm, no SAL System Table.\n");
- return;
- }
-
- if (strncmp(systab->signature, "SST_", 4) != 0)
- printk(KERN_ERR "bad signature in system table!");
-
- check_versions(systab);
-#ifdef CONFIG_SMP
- chk_nointroute_opt();
-#endif
-
- /* revisions are coded in BCD, so %x does the job for us */
- printk(KERN_INFO "SAL %x.%x: %.32s %.32s%sversion %x.%x\n",
- SAL_MAJOR(sal_revision), SAL_MINOR(sal_revision),
- systab->oem_id, systab->product_id,
- systab->product_id[0] ? " " : "",
- SAL_MAJOR(sal_version), SAL_MINOR(sal_version));
-
- p = (char *) (systab + 1);
- for (i = 0; i < systab->entry_count; i++) {
- /*
- * The first byte of each entry type contains the type
- * descriptor.
- */
- switch (*p) {
- case SAL_DESC_ENTRY_POINT:
- sal_desc_entry_point(p);
- break;
- case SAL_DESC_PLATFORM_FEATURE:
- sal_desc_platform_feature(p);
- break;
- case SAL_DESC_PTC:
- ia64_ptc_domain_info = (ia64_sal_desc_ptc_t *)p;
- break;
- case SAL_DESC_AP_WAKEUP:
- sal_desc_ap_wakeup(p);
- break;
- }
- p += SAL_DESC_SIZE(*p);
- }
-
-}
-
-int
-ia64_sal_oemcall(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1,
- u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7)
-{
- if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX)
- return -1;
- SAL_CALL(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
- return 0;
-}
-EXPORT_SYMBOL(ia64_sal_oemcall);
-
-int
-ia64_sal_oemcall_nolock(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1,
- u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6,
- u64 arg7)
-{
- if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX)
- return -1;
- SAL_CALL_NOLOCK(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6,
- arg7);
- return 0;
-}
-EXPORT_SYMBOL(ia64_sal_oemcall_nolock);
-
-int
-ia64_sal_oemcall_reentrant(struct ia64_sal_retval *isrvp, u64 oemfunc,
- u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5,
- u64 arg6, u64 arg7)
-{
- if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX)
- return -1;
- SAL_CALL_REENTRANT(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6,
- arg7);
- return 0;
-}
-EXPORT_SYMBOL(ia64_sal_oemcall_reentrant);
-
-long
-ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second,
- unsigned long *drift_info)
-{
- struct ia64_sal_retval isrv;
-
- SAL_CALL(isrv, SAL_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
- *ticks_per_second = isrv.v0;
- *drift_info = isrv.v1;
- return isrv.status;
-}
-EXPORT_SYMBOL_GPL(ia64_sal_freq_base);
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
deleted file mode 100644
index 03b632c56899..000000000000
--- a/arch/ia64/kernel/salinfo.c
+++ /dev/null
@@ -1,646 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * salinfo.c
- *
- * Creates entries in /proc/sal for various system features.
- *
- * Copyright (c) 2003, 2006 Silicon Graphics, Inc. All rights reserved.
- * Copyright (c) 2003 Hewlett-Packard Co
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- *
- * 10/30/2001 jbarnes@sgi.com copied much of Stephane's palinfo
- * code to create this file
- * Oct 23 2003 kaos@sgi.com
- * Replace IPI with set_cpus_allowed() to read a record from the required cpu.
- * Redesign salinfo log processing to separate interrupt and user space
- * contexts.
- * Cache the record across multi-block reads from user space.
- * Support > 64 cpus.
- * Delete module_exit and MOD_INC/DEC_COUNT, salinfo cannot be a module.
- *
- * Jan 28 2004 kaos@sgi.com
- * Periodically check for outstanding MCA or INIT records.
- *
- * Dec 5 2004 kaos@sgi.com
- * Standardize which records are cleared automatically.
- *
- * Aug 18 2005 kaos@sgi.com
- * mca.c may not pass a buffer, a NULL buffer just indicates that a new
- * record is available in SAL.
- * Replace some NR_CPUS by cpus_online, for hotplug cpu.
- *
- * Jan 5 2006 kaos@sgi.com
- * Handle hotplug cpus coming online.
- * Handle hotplug cpus going offline while they still have outstanding records.
- * Use the cpu_* macros consistently.
- * Replace the counting semaphore with a mutex and a test if the cpumask is non-empty.
- * Modify the locking to make the test for "work to do" an atomic operation.
- */
-
-#include <linux/capability.h>
-#include <linux/cpu.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/smp.h>
-#include <linux/timer.h>
-#include <linux/vmalloc.h>
-#include <linux/semaphore.h>
-
-#include <asm/sal.h>
-#include <linux/uaccess.h>
-
-MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>");
-MODULE_DESCRIPTION("/proc interface to IA-64 SAL features");
-MODULE_LICENSE("GPL");
-
-typedef struct {
- const char *name; /* name of the proc entry */
- unsigned long feature; /* feature bit */
- struct proc_dir_entry *entry; /* registered entry (removal) */
-} salinfo_entry_t;
-
-/*
- * List {name,feature} pairs for every entry in /proc/sal/<feature>
- * that this module exports
- */
-static const salinfo_entry_t salinfo_entries[]={
- { "bus_lock", IA64_SAL_PLATFORM_FEATURE_BUS_LOCK, },
- { "irq_redirection", IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT, },
- { "ipi_redirection", IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT, },
- { "itc_drift", IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT, },
-};
-
-#define NR_SALINFO_ENTRIES ARRAY_SIZE(salinfo_entries)
-
-static char *salinfo_log_name[] = {
- "mca",
- "init",
- "cmc",
- "cpe",
-};
-
-static struct proc_dir_entry *salinfo_proc_entries[
- ARRAY_SIZE(salinfo_entries) + /* /proc/sal/bus_lock */
- ARRAY_SIZE(salinfo_log_name) + /* /proc/sal/{mca,...} */
- (2 * ARRAY_SIZE(salinfo_log_name)) + /* /proc/sal/mca/{event,data} */
- 1]; /* /proc/sal */
-
-/* Some records we get ourselves, some are accessed as saved data in buffers
- * that are owned by mca.c.
- */
-struct salinfo_data_saved {
- u8* buffer;
- u64 size;
- u64 id;
- int cpu;
-};
-
-/* State transitions. Actions are :-
- * Write "read <cpunum>" to the data file.
- * Write "clear <cpunum>" to the data file.
- * Write "oemdata <cpunum> <offset> to the data file.
- * Read from the data file.
- * Close the data file.
- *
- * Start state is NO_DATA.
- *
- * NO_DATA
- * write "read <cpunum>" -> NO_DATA or LOG_RECORD.
- * write "clear <cpunum>" -> NO_DATA or LOG_RECORD.
- * write "oemdata <cpunum> <offset> -> return -EINVAL.
- * read data -> return EOF.
- * close -> unchanged. Free record areas.
- *
- * LOG_RECORD
- * write "read <cpunum>" -> NO_DATA or LOG_RECORD.
- * write "clear <cpunum>" -> NO_DATA or LOG_RECORD.
- * write "oemdata <cpunum> <offset> -> format the oem data, goto OEMDATA.
- * read data -> return the INIT/MCA/CMC/CPE record.
- * close -> unchanged. Keep record areas.
- *
- * OEMDATA
- * write "read <cpunum>" -> NO_DATA or LOG_RECORD.
- * write "clear <cpunum>" -> NO_DATA or LOG_RECORD.
- * write "oemdata <cpunum> <offset> -> format the oem data, goto OEMDATA.
- * read data -> return the formatted oemdata.
- * close -> unchanged. Keep record areas.
- *
- * Closing the data file does not change the state. This allows shell scripts
- * to manipulate salinfo data, each shell redirection opens the file, does one
- * action then closes it again. The record areas are only freed at close when
- * the state is NO_DATA.
- */
-enum salinfo_state {
- STATE_NO_DATA,
- STATE_LOG_RECORD,
- STATE_OEMDATA,
-};
-
-struct salinfo_data {
- cpumask_t cpu_event; /* which cpus have outstanding events */
- wait_queue_head_t read_wait;
- u8 *log_buffer;
- u64 log_size;
- u8 *oemdata; /* decoded oem data */
- u64 oemdata_size;
- int open; /* single-open to prevent races */
- u8 type;
- u8 saved_num; /* using a saved record? */
- enum salinfo_state state :8; /* processing state */
- u8 padding;
- int cpu_check; /* next CPU to check */
- struct salinfo_data_saved data_saved[5];/* save last 5 records from mca.c, must be < 255 */
-};
-
-static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)];
-
-static DEFINE_SPINLOCK(data_lock);
-static DEFINE_SPINLOCK(data_saved_lock);
-
-/** salinfo_platform_oemdata - optional callback to decode oemdata from an error
- * record.
- * @sect_header: pointer to the start of the section to decode.
- * @oemdata: returns vmalloc area containing the decoded output.
- * @oemdata_size: returns length of decoded output (strlen).
- *
- * Description: If user space asks for oem data to be decoded by the kernel
- * and/or prom and the platform has set salinfo_platform_oemdata to the address
- * of a platform specific routine then call that routine. salinfo_platform_oemdata
- * vmalloc's and formats its output area, returning the address of the text
- * and its strlen. Returns 0 for success, -ve for error. The callback is
- * invoked on the cpu that generated the error record.
- */
-int (*salinfo_platform_oemdata)(const u8 *sect_header, u8 **oemdata, u64 *oemdata_size);
-
-struct salinfo_platform_oemdata_parms {
- const u8 *efi_guid;
- u8 **oemdata;
- u64 *oemdata_size;
-};
-
-static long
-salinfo_platform_oemdata_cpu(void *context)
-{
- struct salinfo_platform_oemdata_parms *parms = context;
-
- return salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size);
-}
-
-static void
-shift1_data_saved (struct salinfo_data *data, int shift)
-{
- memcpy(data->data_saved+shift, data->data_saved+shift+1,
- (ARRAY_SIZE(data->data_saved) - (shift+1)) * sizeof(data->data_saved[0]));
- memset(data->data_saved + ARRAY_SIZE(data->data_saved) - 1, 0,
- sizeof(data->data_saved[0]));
-}
-
-/* This routine is invoked in interrupt context. Note: mca.c enables
- * interrupts before calling this code for CMC/CPE. MCA and INIT events are
- * not irq safe, do not call any routines that use spinlocks, they may deadlock.
- * MCA and INIT records are recorded, a timer event will look for any
- * outstanding events and wake up the user space code.
- *
- * The buffer passed from mca.c points to the output from ia64_log_get. This is
- * a persistent buffer but its contents can change between the interrupt and
- * when user space processes the record. Save the record id to identify
- * changes. If the buffer is NULL then just update the bitmap.
- */
-void
-salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe)
-{
- struct salinfo_data *data = salinfo_data + type;
- struct salinfo_data_saved *data_saved;
- unsigned long flags = 0;
- int i;
- int saved_size = ARRAY_SIZE(data->data_saved);
-
- BUG_ON(type >= ARRAY_SIZE(salinfo_log_name));
-
- if (irqsafe)
- spin_lock_irqsave(&data_saved_lock, flags);
- if (buffer) {
- for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) {
- if (!data_saved->buffer)
- break;
- }
- if (i == saved_size) {
- if (!data->saved_num) {
- shift1_data_saved(data, 0);
- data_saved = data->data_saved + saved_size - 1;
- } else
- data_saved = NULL;
- }
- if (data_saved) {
- data_saved->cpu = smp_processor_id();
- data_saved->id = ((sal_log_record_header_t *)buffer)->id;
- data_saved->size = size;
- data_saved->buffer = buffer;
- }
- }
- cpumask_set_cpu(smp_processor_id(), &data->cpu_event);
- if (irqsafe) {
- wake_up_interruptible(&data->read_wait);
- spin_unlock_irqrestore(&data_saved_lock, flags);
- }
-}
-
-/* Check for outstanding MCA/INIT records every minute (arbitrary) */
-#define SALINFO_TIMER_DELAY (60*HZ)
-static struct timer_list salinfo_timer;
-extern void ia64_mlogbuf_dump(void);
-
-static void
-salinfo_timeout_check(struct salinfo_data *data)
-{
- if (!data->open)
- return;
- if (!cpumask_empty(&data->cpu_event))
- wake_up_interruptible(&data->read_wait);
-}
-
-static void
-salinfo_timeout(struct timer_list *unused)
-{
- ia64_mlogbuf_dump();
- salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA);
- salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_INIT);
- salinfo_timer.expires = jiffies + SALINFO_TIMER_DELAY;
- add_timer(&salinfo_timer);
-}
-
-static int
-salinfo_event_open(struct inode *inode, struct file *file)
-{
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- return 0;
-}
-
-static ssize_t
-salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
- struct salinfo_data *data = pde_data(file_inode(file));
- char cmd[32];
- size_t size;
- int i, n, cpu = -1;
-
-retry:
- if (cpumask_empty(&data->cpu_event)) {
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
- if (wait_event_interruptible(data->read_wait,
- !cpumask_empty(&data->cpu_event)))
- return -EINTR;
- }
-
- n = data->cpu_check;
- for (i = 0; i < nr_cpu_ids; i++) {
- if (cpumask_test_cpu(n, &data->cpu_event)) {
- if (!cpu_online(n)) {
- cpumask_clear_cpu(n, &data->cpu_event);
- continue;
- }
- cpu = n;
- break;
- }
- if (++n == nr_cpu_ids)
- n = 0;
- }
-
- if (cpu == -1)
- goto retry;
-
- ia64_mlogbuf_dump();
-
- /* for next read, start checking at next CPU */
- data->cpu_check = cpu;
- if (++data->cpu_check == nr_cpu_ids)
- data->cpu_check = 0;
-
- snprintf(cmd, sizeof(cmd), "read %d\n", cpu);
-
- size = strlen(cmd);
- if (size > count)
- size = count;
- if (copy_to_user(buffer, cmd, size))
- return -EFAULT;
-
- return size;
-}
-
-static const struct proc_ops salinfo_event_proc_ops = {
- .proc_open = salinfo_event_open,
- .proc_read = salinfo_event_read,
- .proc_lseek = noop_llseek,
-};
-
-static int
-salinfo_log_open(struct inode *inode, struct file *file)
-{
- struct salinfo_data *data = pde_data(inode);
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- spin_lock(&data_lock);
- if (data->open) {
- spin_unlock(&data_lock);
- return -EBUSY;
- }
- data->open = 1;
- spin_unlock(&data_lock);
-
- if (data->state == STATE_NO_DATA &&
- !(data->log_buffer = vmalloc(ia64_sal_get_state_info_size(data->type)))) {
- data->open = 0;
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static int
-salinfo_log_release(struct inode *inode, struct file *file)
-{
- struct salinfo_data *data = pde_data(inode);
-
- if (data->state == STATE_NO_DATA) {
- vfree(data->log_buffer);
- vfree(data->oemdata);
- data->log_buffer = NULL;
- data->oemdata = NULL;
- }
- spin_lock(&data_lock);
- data->open = 0;
- spin_unlock(&data_lock);
- return 0;
-}
-
-static long
-salinfo_log_read_cpu(void *context)
-{
- struct salinfo_data *data = context;
- sal_log_record_header_t *rh;
- data->log_size = ia64_sal_get_state_info(data->type, (u64 *) data->log_buffer);
- rh = (sal_log_record_header_t *)(data->log_buffer);
- /* Clear corrected errors as they are read from SAL */
- if (rh->severity == sal_log_severity_corrected)
- ia64_sal_clear_state_info(data->type);
- return 0;
-}
-
-static void
-salinfo_log_new_read(int cpu, struct salinfo_data *data)
-{
- struct salinfo_data_saved *data_saved;
- unsigned long flags;
- int i;
- int saved_size = ARRAY_SIZE(data->data_saved);
-
- data->saved_num = 0;
- spin_lock_irqsave(&data_saved_lock, flags);
-retry:
- for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) {
- if (data_saved->buffer && data_saved->cpu == cpu) {
- sal_log_record_header_t *rh = (sal_log_record_header_t *)(data_saved->buffer);
- data->log_size = data_saved->size;
- memcpy(data->log_buffer, rh, data->log_size);
- barrier(); /* id check must not be moved */
- if (rh->id == data_saved->id) {
- data->saved_num = i+1;
- break;
- }
- /* saved record changed by mca.c since interrupt, discard it */
- shift1_data_saved(data, i);
- goto retry;
- }
- }
- spin_unlock_irqrestore(&data_saved_lock, flags);
-
- if (!data->saved_num)
- work_on_cpu_safe(cpu, salinfo_log_read_cpu, data);
- if (!data->log_size) {
- data->state = STATE_NO_DATA;
- cpumask_clear_cpu(cpu, &data->cpu_event);
- } else {
- data->state = STATE_LOG_RECORD;
- }
-}
-
-static ssize_t
-salinfo_log_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
- struct salinfo_data *data = pde_data(file_inode(file));
- u8 *buf;
- u64 bufsize;
-
- if (data->state == STATE_LOG_RECORD) {
- buf = data->log_buffer;
- bufsize = data->log_size;
- } else if (data->state == STATE_OEMDATA) {
- buf = data->oemdata;
- bufsize = data->oemdata_size;
- } else {
- buf = NULL;
- bufsize = 0;
- }
- return simple_read_from_buffer(buffer, count, ppos, buf, bufsize);
-}
-
-static long
-salinfo_log_clear_cpu(void *context)
-{
- struct salinfo_data *data = context;
-
- ia64_sal_clear_state_info(data->type);
- return 0;
-}
-
-static int
-salinfo_log_clear(struct salinfo_data *data, int cpu)
-{
- sal_log_record_header_t *rh;
- unsigned long flags;
- spin_lock_irqsave(&data_saved_lock, flags);
- data->state = STATE_NO_DATA;
- if (!cpumask_test_cpu(cpu, &data->cpu_event)) {
- spin_unlock_irqrestore(&data_saved_lock, flags);
- return 0;
- }
- cpumask_clear_cpu(cpu, &data->cpu_event);
- if (data->saved_num) {
- shift1_data_saved(data, data->saved_num - 1);
- data->saved_num = 0;
- }
- spin_unlock_irqrestore(&data_saved_lock, flags);
- rh = (sal_log_record_header_t *)(data->log_buffer);
- /* Corrected errors have already been cleared from SAL */
- if (rh->severity != sal_log_severity_corrected)
- work_on_cpu_safe(cpu, salinfo_log_clear_cpu, data);
- /* clearing a record may make a new record visible */
- salinfo_log_new_read(cpu, data);
- if (data->state == STATE_LOG_RECORD) {
- spin_lock_irqsave(&data_saved_lock, flags);
- cpumask_set_cpu(cpu, &data->cpu_event);
- wake_up_interruptible(&data->read_wait);
- spin_unlock_irqrestore(&data_saved_lock, flags);
- }
- return 0;
-}
-
-static ssize_t
-salinfo_log_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
- struct salinfo_data *data = pde_data(file_inode(file));
- char cmd[32];
- size_t size;
- u32 offset;
- int cpu;
-
- size = sizeof(cmd);
- if (count < size)
- size = count;
- if (copy_from_user(cmd, buffer, size))
- return -EFAULT;
-
- if (sscanf(cmd, "read %d", &cpu) == 1) {
- salinfo_log_new_read(cpu, data);
- } else if (sscanf(cmd, "clear %d", &cpu) == 1) {
- int ret;
- if ((ret = salinfo_log_clear(data, cpu)))
- count = ret;
- } else if (sscanf(cmd, "oemdata %d %d", &cpu, &offset) == 2) {
- if (data->state != STATE_LOG_RECORD && data->state != STATE_OEMDATA)
- return -EINVAL;
- if (offset > data->log_size - sizeof(efi_guid_t))
- return -EINVAL;
- data->state = STATE_OEMDATA;
- if (salinfo_platform_oemdata) {
- struct salinfo_platform_oemdata_parms parms = {
- .efi_guid = data->log_buffer + offset,
- .oemdata = &data->oemdata,
- .oemdata_size = &data->oemdata_size
- };
- count = work_on_cpu_safe(cpu, salinfo_platform_oemdata_cpu,
- &parms);
- } else
- data->oemdata_size = 0;
- } else
- return -EINVAL;
-
- return count;
-}
-
-static const struct proc_ops salinfo_data_proc_ops = {
- .proc_open = salinfo_log_open,
- .proc_release = salinfo_log_release,
- .proc_read = salinfo_log_read,
- .proc_write = salinfo_log_write,
- .proc_lseek = default_llseek,
-};
-
-static int salinfo_cpu_online(unsigned int cpu)
-{
- unsigned int i, end = ARRAY_SIZE(salinfo_data);
- struct salinfo_data *data;
-
- spin_lock_irq(&data_saved_lock);
- for (i = 0, data = salinfo_data; i < end; ++i, ++data) {
- cpumask_set_cpu(cpu, &data->cpu_event);
- wake_up_interruptible(&data->read_wait);
- }
- spin_unlock_irq(&data_saved_lock);
- return 0;
-}
-
-static int salinfo_cpu_pre_down(unsigned int cpu)
-{
- unsigned int i, end = ARRAY_SIZE(salinfo_data);
- struct salinfo_data *data;
-
- spin_lock_irq(&data_saved_lock);
- for (i = 0, data = salinfo_data; i < end; ++i, ++data) {
- struct salinfo_data_saved *data_saved;
- int j = ARRAY_SIZE(data->data_saved) - 1;
-
- for (data_saved = data->data_saved + j; j >= 0;
- --j, --data_saved) {
- if (data_saved->buffer && data_saved->cpu == cpu)
- shift1_data_saved(data, j);
- }
- cpumask_clear_cpu(cpu, &data->cpu_event);
- }
- spin_unlock_irq(&data_saved_lock);
- return 0;
-}
-
-/*
- * 'data' contains an integer that corresponds to the feature we're
- * testing
- */
-static int __maybe_unused proc_salinfo_show(struct seq_file *m, void *v)
-{
- unsigned long data = (unsigned long)v;
- seq_puts(m, (sal_platform_features & data) ? "1\n" : "0\n");
- return 0;
-}
-
-static int __init
-salinfo_init(void)
-{
- struct proc_dir_entry *salinfo_dir; /* /proc/sal dir entry */
- struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */
- struct proc_dir_entry *dir, *entry;
- struct salinfo_data *data;
- int i;
-
- salinfo_dir = proc_mkdir("sal", NULL);
- if (!salinfo_dir)
- return 0;
-
- for (i=0; i < NR_SALINFO_ENTRIES; i++) {
- /* pass the feature bit in question as misc data */
- *sdir++ = proc_create_single_data(salinfo_entries[i].name, 0,
- salinfo_dir, proc_salinfo_show,
- (void *)salinfo_entries[i].feature);
- }
-
- for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) {
- data = salinfo_data + i;
- data->type = i;
- init_waitqueue_head(&data->read_wait);
- dir = proc_mkdir(salinfo_log_name[i], salinfo_dir);
- if (!dir)
- continue;
-
- entry = proc_create_data("event", S_IRUSR, dir,
- &salinfo_event_proc_ops, data);
- if (!entry)
- continue;
- *sdir++ = entry;
-
- entry = proc_create_data("data", S_IRUSR | S_IWUSR, dir,
- &salinfo_data_proc_ops, data);
- if (!entry)
- continue;
- *sdir++ = entry;
-
- *sdir++ = dir;
- }
-
- *sdir++ = salinfo_dir;
-
- timer_setup(&salinfo_timer, salinfo_timeout, 0);
- salinfo_timer.expires = jiffies + SALINFO_TIMER_DELAY;
- add_timer(&salinfo_timer);
-
- i = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "ia64/salinfo:online",
- salinfo_cpu_online, salinfo_cpu_pre_down);
- WARN_ON(i < 0);
- return 0;
-}
-
-module_init(salinfo_init);
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
deleted file mode 100644
index 5a55ac82c13a..000000000000
--- a/arch/ia64/kernel/setup.c
+++ /dev/null
@@ -1,1081 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Architecture-specific setup.
- *
- * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 2000, 2004 Intel Corp
- * Rohit Seth <rohit.seth@intel.com>
- * Suresh Siddha <suresh.b.siddha@intel.com>
- * Gordon Jin <gordon.jin@intel.com>
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- *
- * 12/26/04 S.Siddha, G.Jin, R.Seth
- * Add multi-threading and multi-core detection
- * 11/12/01 D.Mosberger Convert get_cpuinfo() to seq_file based show_cpuinfo().
- * 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map
- * 03/31/00 R.Seth cpu_initialized and current->processor fixes
- * 02/04/00 D.Mosberger some more get_cpuinfo fixes...
- * 02/01/00 R.Seth fixed get_cpuinfo for SMP
- * 01/07/99 S.Eranian added the support for command line argument
- * 06/24/99 W.Drummond added boot_cpu_data.
- * 05/28/05 Z. Menyhart Dynamic stride size for "flush_icache_range()"
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pgtable.h>
-
-#include <linux/acpi.h>
-#include <linux/console.h>
-#include <linux/delay.h>
-#include <linux/cpu.h>
-#include <linux/kdev_t.h>
-#include <linux/kernel.h>
-#include <linux/memblock.h>
-#include <linux/reboot.h>
-#include <linux/sched/mm.h>
-#include <linux/sched/clock.h>
-#include <linux/sched/task_stack.h>
-#include <linux/seq_file.h>
-#include <linux/string.h>
-#include <linux/threads.h>
-#include <linux/screen_info.h>
-#include <linux/dmi.h>
-#include <linux/root_dev.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/efi.h>
-#include <linux/initrd.h>
-#include <linux/pm.h>
-#include <linux/cpufreq.h>
-#include <linux/kexec.h>
-#include <linux/crash_dump.h>
-
-#include <asm/mca.h>
-#include <asm/meminit.h>
-#include <asm/page.h>
-#include <asm/patch.h>
-#include <asm/processor.h>
-#include <asm/sal.h>
-#include <asm/sections.h>
-#include <asm/setup.h>
-#include <asm/smp.h>
-#include <asm/tlbflush.h>
-#include <asm/unistd.h>
-#include <asm/uv/uv.h>
-#include <asm/xtp.h>
-
-#if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
-# error "struct cpuinfo_ia64 too big!"
-#endif
-
-char ia64_platform_name[64];
-
-#ifdef CONFIG_SMP
-unsigned long __per_cpu_offset[NR_CPUS];
-EXPORT_SYMBOL(__per_cpu_offset);
-#endif
-
-DEFINE_PER_CPU(struct cpuinfo_ia64, ia64_cpu_info);
-EXPORT_SYMBOL(ia64_cpu_info);
-DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
-#ifdef CONFIG_SMP
-EXPORT_SYMBOL(local_per_cpu_offset);
-#endif
-unsigned long ia64_cycles_per_usec;
-struct ia64_boot_param *ia64_boot_param;
-struct screen_info screen_info;
-unsigned long vga_console_iobase;
-unsigned long vga_console_membase;
-
-static struct resource data_resource = {
- .name = "Kernel data",
- .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
-};
-
-static struct resource code_resource = {
- .name = "Kernel code",
- .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
-};
-
-static struct resource bss_resource = {
- .name = "Kernel bss",
- .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
-};
-
-unsigned long ia64_max_cacheline_size;
-
-unsigned long ia64_iobase; /* virtual address for I/O accesses */
-EXPORT_SYMBOL(ia64_iobase);
-struct io_space io_space[MAX_IO_SPACES];
-EXPORT_SYMBOL(io_space);
-unsigned int num_io_spaces;
-
-/*
- * "flush_icache_range()" needs to know what processor dependent stride size to use
- * when it makes i-cache(s) coherent with d-caches.
- */
-#define I_CACHE_STRIDE_SHIFT 5 /* Safest way to go: 32 bytes by 32 bytes */
-unsigned long ia64_i_cache_stride_shift = ~0;
-/*
- * "clflush_cache_range()" needs to know what processor dependent stride size to
- * use when it flushes cache lines including both d-cache and i-cache.
- */
-/* Safest way to go: 32 bytes by 32 bytes */
-#define CACHE_STRIDE_SHIFT 5
-unsigned long ia64_cache_stride_shift = ~0;
-
-/*
- * We use a special marker for the end of memory and it uses the extra (+1) slot
- */
-struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1] __initdata;
-static int num_rsvd_regions __initdata;
-
-
-/*
- * Filter incoming memory segments based on the primitive map created from the boot
- * parameters. Segments contained in the map are removed from the memory ranges. A
- * caller-specified function is called with the memory ranges that remain after filtering.
- * This routine does not assume the incoming segments are sorted.
- */
-int __init
-filter_rsvd_memory (u64 start, u64 end, void *arg)
-{
- u64 range_start, range_end, prev_start;
- void (*func)(unsigned long, unsigned long, int);
- int i;
-
-#if IGNORE_PFN0
- if (start == PAGE_OFFSET) {
- printk(KERN_WARNING "warning: skipping physical page 0\n");
- start += PAGE_SIZE;
- if (start >= end) return 0;
- }
-#endif
- /*
- * lowest possible address(walker uses virtual)
- */
- prev_start = PAGE_OFFSET;
- func = arg;
-
- for (i = 0; i < num_rsvd_regions; ++i) {
- range_start = max(start, prev_start);
- range_end = min(end, rsvd_region[i].start);
-
- if (range_start < range_end)
- call_pernode_memory(__pa(range_start), range_end - range_start, func);
-
- /* nothing more available in this segment */
- if (range_end == end) return 0;
-
- prev_start = rsvd_region[i].end;
- }
- /* end of memory marker allows full processing inside loop body */
- return 0;
-}
-
-/*
- * Similar to "filter_rsvd_memory()", but the reserved memory ranges
- * are not filtered out.
- */
-int __init
-filter_memory(u64 start, u64 end, void *arg)
-{
- void (*func)(unsigned long, unsigned long, int);
-
-#if IGNORE_PFN0
- if (start == PAGE_OFFSET) {
- printk(KERN_WARNING "warning: skipping physical page 0\n");
- start += PAGE_SIZE;
- if (start >= end)
- return 0;
- }
-#endif
- func = arg;
- if (start < end)
- call_pernode_memory(__pa(start), end - start, func);
- return 0;
-}
-
-static void __init
-sort_regions (struct rsvd_region *rsvd_region, int max)
-{
- int j;
-
- /* simple bubble sorting */
- while (max--) {
- for (j = 0; j < max; ++j) {
- if (rsvd_region[j].start > rsvd_region[j+1].start) {
- swap(rsvd_region[j], rsvd_region[j + 1]);
- }
- }
- }
-}
-
-/* merge overlaps */
-static int __init
-merge_regions (struct rsvd_region *rsvd_region, int max)
-{
- int i;
- for (i = 1; i < max; ++i) {
- if (rsvd_region[i].start >= rsvd_region[i-1].end)
- continue;
- if (rsvd_region[i].end > rsvd_region[i-1].end)
- rsvd_region[i-1].end = rsvd_region[i].end;
- --max;
- memmove(&rsvd_region[i], &rsvd_region[i+1],
- (max - i) * sizeof(struct rsvd_region));
- }
- return max;
-}
-
-/*
- * Request address space for all standard resources
- */
-static int __init register_memory(void)
-{
- code_resource.start = ia64_tpa(_text);
- code_resource.end = ia64_tpa(_etext) - 1;
- data_resource.start = ia64_tpa(_etext);
- data_resource.end = ia64_tpa(_edata) - 1;
- bss_resource.start = ia64_tpa(__bss_start);
- bss_resource.end = ia64_tpa(_end) - 1;
- efi_initialize_iomem_resources(&code_resource, &data_resource,
- &bss_resource);
-
- return 0;
-}
-
-__initcall(register_memory);
-
-
-#ifdef CONFIG_KEXEC
-
-/*
- * This function checks if the reserved crashkernel is allowed on the specific
- * IA64 machine flavour. Machines without an IO TLB use swiotlb and require
- * some memory below 4 GB (i.e. in 32 bit area), see the implementation of
- * kernel/dma/swiotlb.c. The hpzx1 architecture has an IO TLB but cannot use that
- * in kdump case. See the comment in sba_init() in sba_iommu.c.
- *
- * So, the only machvec that really supports loading the kdump kernel
- * over 4 GB is "uv".
- */
-static int __init check_crashkernel_memory(unsigned long pbase, size_t size)
-{
- if (is_uv_system())
- return 1;
- else
- return pbase < (1UL << 32);
-}
-
-static void __init setup_crashkernel(unsigned long total, int *n)
-{
- unsigned long long base = 0, size = 0;
- int ret;
-
- ret = parse_crashkernel(boot_command_line, total,
- &size, &base);
- if (ret == 0 && size > 0) {
- if (!base) {
- sort_regions(rsvd_region, *n);
- *n = merge_regions(rsvd_region, *n);
- base = kdump_find_rsvd_region(size,
- rsvd_region, *n);
- }
-
- if (!check_crashkernel_memory(base, size)) {
- pr_warn("crashkernel: There would be kdump memory "
- "at %ld GB but this is unusable because it "
- "must\nbe below 4 GB. Change the memory "
- "configuration of the machine.\n",
- (unsigned long)(base >> 30));
- return;
- }
-
- if (base != ~0UL) {
- printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
- "for crashkernel (System RAM: %ldMB)\n",
- (unsigned long)(size >> 20),
- (unsigned long)(base >> 20),
- (unsigned long)(total >> 20));
- rsvd_region[*n].start =
- (unsigned long)__va(base);
- rsvd_region[*n].end =
- (unsigned long)__va(base + size);
- (*n)++;
- crashk_res.start = base;
- crashk_res.end = base + size - 1;
- }
- }
- efi_memmap_res.start = ia64_boot_param->efi_memmap;
- efi_memmap_res.end = efi_memmap_res.start +
- ia64_boot_param->efi_memmap_size;
- boot_param_res.start = __pa(ia64_boot_param);
- boot_param_res.end = boot_param_res.start +
- sizeof(*ia64_boot_param);
-}
-#else
-static inline void __init setup_crashkernel(unsigned long total, int *n)
-{}
-#endif
-
-#ifdef CONFIG_CRASH_DUMP
-static int __init reserve_elfcorehdr(u64 *start, u64 *end)
-{
- u64 length;
-
- /* We get the address using the kernel command line,
- * but the size is extracted from the EFI tables.
- * Both address and size are required for reservation
- * to work properly.
- */
-
- if (!is_vmcore_usable())
- return -EINVAL;
-
- if ((length = vmcore_find_descriptor_size(elfcorehdr_addr)) == 0) {
- vmcore_unusable();
- return -EINVAL;
- }
-
- *start = (unsigned long)__va(elfcorehdr_addr);
- *end = *start + length;
- return 0;
-}
-#endif /* CONFIG_CRASH_DUMP */
-
-/**
- * reserve_memory - setup reserved memory areas
- *
- * Setup the reserved memory areas set aside for the boot parameters,
- * initrd, etc. There are currently %IA64_MAX_RSVD_REGIONS defined,
- * see arch/ia64/include/asm/meminit.h if you need to define more.
- */
-void __init
-reserve_memory (void)
-{
- int n = 0;
- unsigned long total_memory;
-
- /*
- * none of the entries in this table overlap
- */
- rsvd_region[n].start = (unsigned long) ia64_boot_param;
- rsvd_region[n].end = rsvd_region[n].start + sizeof(*ia64_boot_param);
- n++;
-
- rsvd_region[n].start = (unsigned long) __va(ia64_boot_param->efi_memmap);
- rsvd_region[n].end = rsvd_region[n].start + ia64_boot_param->efi_memmap_size;
- n++;
-
- rsvd_region[n].start = (unsigned long) __va(ia64_boot_param->command_line);
- rsvd_region[n].end = (rsvd_region[n].start
- + strlen(__va(ia64_boot_param->command_line)) + 1);
- n++;
-
- rsvd_region[n].start = (unsigned long) ia64_imva((void *)KERNEL_START);
- rsvd_region[n].end = (unsigned long) ia64_imva(_end);
- n++;
-
-#ifdef CONFIG_BLK_DEV_INITRD
- if (ia64_boot_param->initrd_start) {
- rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start);
- rsvd_region[n].end = rsvd_region[n].start + ia64_boot_param->initrd_size;
- n++;
- }
-#endif
-
-#ifdef CONFIG_CRASH_DUMP
- if (reserve_elfcorehdr(&rsvd_region[n].start,
- &rsvd_region[n].end) == 0)
- n++;
-#endif
-
- total_memory = efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
- n++;
-
- setup_crashkernel(total_memory, &n);
-
- /* end of memory marker */
- rsvd_region[n].start = ~0UL;
- rsvd_region[n].end = ~0UL;
- n++;
-
- num_rsvd_regions = n;
- BUG_ON(IA64_MAX_RSVD_REGIONS + 1 < n);
-
- sort_regions(rsvd_region, num_rsvd_regions);
- num_rsvd_regions = merge_regions(rsvd_region, num_rsvd_regions);
-
- /* reserve all regions except the end of memory marker with memblock */
- for (n = 0; n < num_rsvd_regions - 1; n++) {
- struct rsvd_region *region = &rsvd_region[n];
- phys_addr_t addr = __pa(region->start);
- phys_addr_t size = region->end - region->start;
-
- memblock_reserve(addr, size);
- }
-}
-
-/**
- * find_initrd - get initrd parameters from the boot parameter structure
- *
- * Grab the initrd start and end from the boot parameter struct given us by
- * the boot loader.
- */
-void __init
-find_initrd (void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
- if (ia64_boot_param->initrd_start) {
- initrd_start = (unsigned long)__va(ia64_boot_param->initrd_start);
- initrd_end = initrd_start+ia64_boot_param->initrd_size;
-
- printk(KERN_INFO "Initial ramdisk at: 0x%lx (%llu bytes)\n",
- initrd_start, ia64_boot_param->initrd_size);
- }
-#endif
-}
-
-static void __init
-io_port_init (void)
-{
- unsigned long phys_iobase;
-
- /*
- * Set `iobase' based on the EFI memory map or, failing that, the
- * value firmware left in ar.k0.
- *
- * Note that in ia32 mode, IN/OUT instructions use ar.k0 to compute
- * the port's virtual address, so ia32_load_state() loads it with a
- * user virtual address. But in ia64 mode, glibc uses the
- * *physical* address in ar.k0 to mmap the appropriate area from
- * /dev/mem, and the inX()/outX() interfaces use MMIO. In both
- * cases, user-mode can only use the legacy 0-64K I/O port space.
- *
- * ar.k0 is not involved in kernel I/O port accesses, which can use
- * any of the I/O port spaces and are done via MMIO using the
- * virtual mmio_base from the appropriate io_space[].
- */
- phys_iobase = efi_get_iobase();
- if (!phys_iobase) {
- phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
- printk(KERN_INFO "No I/O port range found in EFI memory map, "
- "falling back to AR.KR0 (0x%lx)\n", phys_iobase);
- }
- ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
- ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
-
- /* setup legacy IO port space */
- io_space[0].mmio_base = ia64_iobase;
- io_space[0].sparse = 1;
- num_io_spaces = 1;
-}
-
-/**
- * early_console_setup - setup debugging console
- *
- * Consoles started here require little enough setup that we can start using
- * them very early in the boot process, either right after the machine
- * vector initialization, or even before if the drivers can detect their hw.
- *
- * Returns non-zero if a console couldn't be setup.
- */
-static inline int __init
-early_console_setup (char *cmdline)
-{
-#ifdef CONFIG_EFI_PCDP
- if (!efi_setup_pcdp_console(cmdline))
- return 0;
-#endif
- return -1;
-}
-
-static void __init
-screen_info_setup(void)
-{
- unsigned int orig_x, orig_y, num_cols, num_rows, font_height;
-
- memset(&screen_info, 0, sizeof(screen_info));
-
- if (!ia64_boot_param->console_info.num_rows ||
- !ia64_boot_param->console_info.num_cols) {
- printk(KERN_WARNING "invalid screen-info, guessing 80x25\n");
- orig_x = 0;
- orig_y = 0;
- num_cols = 80;
- num_rows = 25;
- font_height = 16;
- } else {
- orig_x = ia64_boot_param->console_info.orig_x;
- orig_y = ia64_boot_param->console_info.orig_y;
- num_cols = ia64_boot_param->console_info.num_cols;
- num_rows = ia64_boot_param->console_info.num_rows;
- font_height = 400 / num_rows;
- }
-
- screen_info.orig_x = orig_x;
- screen_info.orig_y = orig_y;
- screen_info.orig_video_cols = num_cols;
- screen_info.orig_video_lines = num_rows;
- screen_info.orig_video_points = font_height;
- screen_info.orig_video_mode = 3; /* XXX fake */
- screen_info.orig_video_isVGA = 1; /* XXX fake */
- screen_info.orig_video_ega_bx = 3; /* XXX fake */
-}
-
-static inline void
-mark_bsp_online (void)
-{
-#ifdef CONFIG_SMP
- /* If we register an early console, allow CPU 0 to printk */
- set_cpu_online(smp_processor_id(), true);
-#endif
-}
-
-static __initdata int nomca;
-static __init int setup_nomca(char *s)
-{
- nomca = 1;
- return 0;
-}
-early_param("nomca", setup_nomca);
-
-void __init
-setup_arch (char **cmdline_p)
-{
- unw_init();
-
- ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
-
- *cmdline_p = __va(ia64_boot_param->command_line);
- strscpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
-
- efi_init();
- io_port_init();
-
- uv_probe_system_type();
- parse_early_param();
-
- if (early_console_setup(*cmdline_p) == 0)
- mark_bsp_online();
-
- /* Initialize the ACPI boot-time table parser */
- acpi_table_init();
- early_acpi_boot_init();
-#ifdef CONFIG_ACPI_NUMA
- acpi_numa_init();
- acpi_numa_fixup();
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
- prefill_possible_map();
-#endif
- per_cpu_scan_finalize((cpumask_empty(&early_cpu_possible_map) ?
- 32 : cpumask_weight(&early_cpu_possible_map)),
- additional_cpus > 0 ? additional_cpus : 0);
-#endif /* CONFIG_ACPI_NUMA */
-
-#ifdef CONFIG_SMP
- smp_build_cpu_map();
-#endif
- find_memory();
-
- /* process SAL system table: */
- ia64_sal_init(__va(sal_systab_phys));
-
-#ifdef CONFIG_ITANIUM
- ia64_patch_rse((u64) __start___rse_patchlist, (u64) __end___rse_patchlist);
-#else
- {
- unsigned long num_phys_stacked;
-
- if (ia64_pal_rse_info(&num_phys_stacked, 0) == 0 && num_phys_stacked > 96)
- ia64_patch_rse((u64) __start___rse_patchlist, (u64) __end___rse_patchlist);
- }
-#endif
-
-#ifdef CONFIG_SMP
- cpu_physical_id(0) = hard_smp_processor_id();
-#endif
-
- cpu_init(); /* initialize the bootstrap CPU */
- mmu_context_init(); /* initialize context_id bitmap */
-
-#ifdef CONFIG_VT
- if (!conswitchp) {
-# if defined(CONFIG_VGA_CONSOLE)
- /*
- * Non-legacy systems may route legacy VGA MMIO range to system
- * memory. vga_con probes the MMIO hole, so memory looks like
- * a VGA device to it. The EFI memory map can tell us if it's
- * memory so we can avoid this problem.
- */
- if (efi_mem_type(0xA0000) != EFI_CONVENTIONAL_MEMORY)
- conswitchp = &vga_con;
-# endif
- }
-#endif
-
- /* enable IA-64 Machine Check Abort Handling unless disabled */
- if (!nomca)
- ia64_mca_init();
-
- /*
- * Default to /dev/sda2. This assumes that the EFI partition
- * is physical disk 1 partition 1 and the Linux root disk is
- * physical disk 1 partition 2.
- */
- ROOT_DEV = MKDEV(SCSI_DISK0_MAJOR, 2);
-
- if (is_uv_system())
- uv_setup(cmdline_p);
-#ifdef CONFIG_SMP
- else
- init_smp_config();
-#endif
-
- screen_info_setup();
- paging_init();
-
- clear_sched_clock_stable();
-}
-
-/*
- * Display cpu info for all CPUs.
- */
-static int
-show_cpuinfo (struct seq_file *m, void *v)
-{
-#ifdef CONFIG_SMP
-# define lpj c->loops_per_jiffy
-# define cpunum c->cpu
-#else
-# define lpj loops_per_jiffy
-# define cpunum 0
-#endif
- static struct {
- unsigned long mask;
- const char *feature_name;
- } feature_bits[] = {
- { 1UL << 0, "branchlong" },
- { 1UL << 1, "spontaneous deferral"},
- { 1UL << 2, "16-byte atomic ops" }
- };
- char features[128], *cp, *sep;
- struct cpuinfo_ia64 *c = v;
- unsigned long mask;
- unsigned long proc_freq;
- int i, size;
-
- mask = c->features;
-
- /* build the feature string: */
- memcpy(features, "standard", 9);
- cp = features;
- size = sizeof(features);
- sep = "";
- for (i = 0; i < ARRAY_SIZE(feature_bits) && size > 1; ++i) {
- if (mask & feature_bits[i].mask) {
- cp += snprintf(cp, size, "%s%s", sep,
- feature_bits[i].feature_name),
- sep = ", ";
- mask &= ~feature_bits[i].mask;
- size = sizeof(features) - (cp - features);
- }
- }
- if (mask && size > 1) {
- /* print unknown features as a hex value */
- snprintf(cp, size, "%s0x%lx", sep, mask);
- }
-
- proc_freq = cpufreq_quick_get(cpunum);
- if (!proc_freq)
- proc_freq = c->proc_freq / 1000;
-
- seq_printf(m,
- "processor : %d\n"
- "vendor : %s\n"
- "arch : IA-64\n"
- "family : %u\n"
- "model : %u\n"
- "model name : %s\n"
- "revision : %u\n"
- "archrev : %u\n"
- "features : %s\n"
- "cpu number : %lu\n"
- "cpu regs : %u\n"
- "cpu MHz : %lu.%03lu\n"
- "itc MHz : %lu.%06lu\n"
- "BogoMIPS : %lu.%02lu\n",
- cpunum, c->vendor, c->family, c->model,
- c->model_name, c->revision, c->archrev,
- features, c->ppn, c->number,
- proc_freq / 1000, proc_freq % 1000,
- c->itc_freq / 1000000, c->itc_freq % 1000000,
- lpj*HZ/500000, (lpj*HZ/5000) % 100);
-#ifdef CONFIG_SMP
- seq_printf(m, "siblings : %u\n",
- cpumask_weight(&cpu_core_map[cpunum]));
- if (c->socket_id != -1)
- seq_printf(m, "physical id: %u\n", c->socket_id);
- if (c->threads_per_core > 1 || c->cores_per_socket > 1)
- seq_printf(m,
- "core id : %u\n"
- "thread id : %u\n",
- c->core_id, c->thread_id);
-#endif
- seq_printf(m,"\n");
-
- return 0;
-}
-
-static void *
-c_start (struct seq_file *m, loff_t *pos)
-{
-#ifdef CONFIG_SMP
- while (*pos < nr_cpu_ids && !cpu_online(*pos))
- ++*pos;
-#endif
- return *pos < nr_cpu_ids ? cpu_data(*pos) : NULL;
-}
-
-static void *
-c_next (struct seq_file *m, void *v, loff_t *pos)
-{
- ++*pos;
- return c_start(m, pos);
-}
-
-static void
-c_stop (struct seq_file *m, void *v)
-{
-}
-
-const struct seq_operations cpuinfo_op = {
- .start = c_start,
- .next = c_next,
- .stop = c_stop,
- .show = show_cpuinfo
-};
-
-#define MAX_BRANDS 8
-static char brandname[MAX_BRANDS][128];
-
-static char *
-get_model_name(__u8 family, __u8 model)
-{
- static int overflow;
- char brand[128];
- int i;
-
- memcpy(brand, "Unknown", 8);
- if (ia64_pal_get_brand_info(brand)) {
- if (family == 0x7)
- memcpy(brand, "Merced", 7);
- else if (family == 0x1f) switch (model) {
- case 0: memcpy(brand, "McKinley", 9); break;
- case 1: memcpy(brand, "Madison", 8); break;
- case 2: memcpy(brand, "Madison up to 9M cache", 23); break;
- }
- }
- for (i = 0; i < MAX_BRANDS; i++)
- if (strcmp(brandname[i], brand) == 0)
- return brandname[i];
- for (i = 0; i < MAX_BRANDS; i++)
- if (brandname[i][0] == '\0')
- return strcpy(brandname[i], brand);
- if (overflow++ == 0)
- printk(KERN_ERR
- "%s: Table overflow. Some processor model information will be missing\n",
- __func__);
- return "Unknown";
-}
-
-static void
-identify_cpu (struct cpuinfo_ia64 *c)
-{
- union {
- unsigned long bits[5];
- struct {
- /* id 0 & 1: */
- char vendor[16];
-
- /* id 2 */
- u64 ppn; /* processor serial number */
-
- /* id 3: */
- unsigned number : 8;
- unsigned revision : 8;
- unsigned model : 8;
- unsigned family : 8;
- unsigned archrev : 8;
- unsigned reserved : 24;
-
- /* id 4: */
- u64 features;
- } field;
- } cpuid;
- pal_vm_info_1_u_t vm1;
- pal_vm_info_2_u_t vm2;
- pal_status_t status;
- unsigned long impl_va_msb = 50, phys_addr_size = 44; /* Itanium defaults */
- int i;
- for (i = 0; i < 5; ++i)
- cpuid.bits[i] = ia64_get_cpuid(i);
-
- memcpy(c->vendor, cpuid.field.vendor, 16);
-#ifdef CONFIG_SMP
- c->cpu = smp_processor_id();
-
- /* below default values will be overwritten by identify_siblings()
- * for Multi-Threading/Multi-Core capable CPUs
- */
- c->threads_per_core = c->cores_per_socket = c->num_log = 1;
- c->socket_id = -1;
-
- identify_siblings(c);
-
- if (c->threads_per_core > smp_num_siblings)
- smp_num_siblings = c->threads_per_core;
-#endif
- c->ppn = cpuid.field.ppn;
- c->number = cpuid.field.number;
- c->revision = cpuid.field.revision;
- c->model = cpuid.field.model;
- c->family = cpuid.field.family;
- c->archrev = cpuid.field.archrev;
- c->features = cpuid.field.features;
- c->model_name = get_model_name(c->family, c->model);
-
- status = ia64_pal_vm_summary(&vm1, &vm2);
- if (status == PAL_STATUS_SUCCESS) {
- impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb;
- phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size;
- }
- c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1));
- c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1));
-}
-
-/*
- * Do the following calculations:
- *
- * 1. the max. cache line size.
- * 2. the minimum of the i-cache stride sizes for "flush_icache_range()".
- * 3. the minimum of the cache stride sizes for "clflush_cache_range()".
- */
-static void
-get_cache_info(void)
-{
- unsigned long line_size, max = 1;
- unsigned long l, levels, unique_caches;
- pal_cache_config_info_t cci;
- long status;
-
- status = ia64_pal_cache_summary(&levels, &unique_caches);
- if (status != 0) {
- printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
- __func__, status);
- max = SMP_CACHE_BYTES;
- /* Safest setup for "flush_icache_range()" */
- ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;
- /* Safest setup for "clflush_cache_range()" */
- ia64_cache_stride_shift = CACHE_STRIDE_SHIFT;
- goto out;
- }
-
- for (l = 0; l < levels; ++l) {
- /* cache_type (data_or_unified)=2 */
- status = ia64_pal_cache_config_info(l, 2, &cci);
- if (status != 0) {
- printk(KERN_ERR "%s: ia64_pal_cache_config_info"
- "(l=%lu, 2) failed (status=%ld)\n",
- __func__, l, status);
- max = SMP_CACHE_BYTES;
- /* The safest setup for "flush_icache_range()" */
- cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
- /* The safest setup for "clflush_cache_range()" */
- ia64_cache_stride_shift = CACHE_STRIDE_SHIFT;
- cci.pcci_unified = 1;
- } else {
- if (cci.pcci_stride < ia64_cache_stride_shift)
- ia64_cache_stride_shift = cci.pcci_stride;
-
- line_size = 1 << cci.pcci_line_size;
- if (line_size > max)
- max = line_size;
- }
-
- if (!cci.pcci_unified) {
- /* cache_type (instruction)=1*/
- status = ia64_pal_cache_config_info(l, 1, &cci);
- if (status != 0) {
- printk(KERN_ERR "%s: ia64_pal_cache_config_info"
- "(l=%lu, 1) failed (status=%ld)\n",
- __func__, l, status);
- /* The safest setup for flush_icache_range() */
- cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
- }
- }
- if (cci.pcci_stride < ia64_i_cache_stride_shift)
- ia64_i_cache_stride_shift = cci.pcci_stride;
- }
- out:
- if (max > ia64_max_cacheline_size)
- ia64_max_cacheline_size = max;
-}
-
-/*
- * cpu_init() initializes state that is per-CPU. This function acts
- * as a 'CPU state barrier', nothing should get across.
- */
-void
-cpu_init (void)
-{
- extern void ia64_mmu_init(void *);
- static unsigned long max_num_phys_stacked = IA64_NUM_PHYS_STACK_REG;
- unsigned long num_phys_stacked;
- pal_vm_info_2_u_t vmi;
- unsigned int max_ctx;
- struct cpuinfo_ia64 *cpu_info;
- void *cpu_data;
-
- cpu_data = per_cpu_init();
-#ifdef CONFIG_SMP
- /*
- * insert boot cpu into sibling and core mapes
- * (must be done after per_cpu area is setup)
- */
- if (smp_processor_id() == 0) {
- cpumask_set_cpu(0, &per_cpu(cpu_sibling_map, 0));
- cpumask_set_cpu(0, &cpu_core_map[0]);
- } else {
- /*
- * Set ar.k3 so that assembly code in MCA handler can compute
- * physical addresses of per cpu variables with a simple:
- * phys = ar.k3 + &per_cpu_var
- * and the alt-dtlb-miss handler can set per-cpu mapping into
- * the TLB when needed. head.S already did this for cpu0.
- */
- ia64_set_kr(IA64_KR_PER_CPU_DATA,
- ia64_tpa(cpu_data) - (long) __per_cpu_start);
- }
-#endif
-
- get_cache_info();
-
- /*
- * We can't pass "local_cpu_data" to identify_cpu() because we haven't called
- * ia64_mmu_init() yet. And we can't call ia64_mmu_init() first because it
- * depends on the data returned by identify_cpu(). We break the dependency by
- * accessing cpu_data() through the canonical per-CPU address.
- */
- cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(ia64_cpu_info) - __per_cpu_start);
- identify_cpu(cpu_info);
-
-#ifdef CONFIG_MCKINLEY
- {
-# define FEATURE_SET 16
- struct ia64_pal_retval iprv;
-
- if (cpu_info->family == 0x1f) {
- PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, FEATURE_SET, 0);
- if ((iprv.status == 0) && (iprv.v0 & 0x80) && (iprv.v2 & 0x80))
- PAL_CALL_PHYS(iprv, PAL_PROC_SET_FEATURES,
- (iprv.v1 | 0x80), FEATURE_SET, 0);
- }
- }
-#endif
-
- /* Clear the stack memory reserved for pt_regs: */
- memset(task_pt_regs(current), 0, sizeof(struct pt_regs));
-
- ia64_set_kr(IA64_KR_FPU_OWNER, 0);
-
- /*
- * Initialize the page-table base register to a global
- * directory with all zeroes. This ensure that we can handle
- * TLB-misses to user address-space even before we created the
- * first user address-space. This may happen, e.g., due to
- * aggressive use of lfetch.fault.
- */
- ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page)));
-
- /*
- * Initialize default control register to defer speculative faults except
- * for those arising from TLB misses, which are not deferred. The
- * kernel MUST NOT depend on a particular setting of these bits (in other words,
- * the kernel must have recovery code for all speculative accesses). Turn on
- * dcr.lc as per recommendation by the architecture team. Most IA-32 apps
- * shouldn't be affected by this (moral: keep your ia32 locks aligned and you'll
- * be fine).
- */
- ia64_setreg(_IA64_REG_CR_DCR, ( IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
- | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
- mmgrab(&init_mm);
- current->active_mm = &init_mm;
- BUG_ON(current->mm);
-
- ia64_mmu_init(ia64_imva(cpu_data));
- ia64_mca_cpu_init(ia64_imva(cpu_data));
-
- /* Clear ITC to eliminate sched_clock() overflows in human time. */
- ia64_set_itc(0);
-
- /* disable all local interrupt sources: */
- ia64_set_itv(1 << 16);
- ia64_set_lrr0(1 << 16);
- ia64_set_lrr1(1 << 16);
- ia64_setreg(_IA64_REG_CR_PMV, 1 << 16);
- ia64_setreg(_IA64_REG_CR_CMCV, 1 << 16);
-
- /* clear TPR & XTP to enable all interrupt classes: */
- ia64_setreg(_IA64_REG_CR_TPR, 0);
-
- /* Clear any pending interrupts left by SAL/EFI */
- while (ia64_get_ivr() != IA64_SPURIOUS_INT_VECTOR)
- ia64_eoi();
-
-#ifdef CONFIG_SMP
- normal_xtp();
-#endif
-
- /* set ia64_ctx.max_rid to the maximum RID that is supported by all CPUs: */
- if (ia64_pal_vm_summary(NULL, &vmi) == 0) {
- max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1;
- setup_ptcg_sem(vmi.pal_vm_info_2_s.max_purges, NPTCG_FROM_PAL);
- } else {
- printk(KERN_WARNING "cpu_init: PAL VM summary failed, assuming 18 RID bits\n");
- max_ctx = (1U << 15) - 1; /* use architected minimum */
- }
- while (max_ctx < ia64_ctx.max_ctx) {
- unsigned int old = ia64_ctx.max_ctx;
- if (cmpxchg(&ia64_ctx.max_ctx, old, max_ctx) == old)
- break;
- }
-
- if (ia64_pal_rse_info(&num_phys_stacked, NULL) != 0) {
- printk(KERN_WARNING "cpu_init: PAL RSE info failed; assuming 96 physical "
- "stacked regs\n");
- num_phys_stacked = 96;
- }
- /* size of physical stacked register partition plus 8 bytes: */
- if (num_phys_stacked > max_num_phys_stacked) {
- ia64_patch_phys_stack_reg(num_phys_stacked*8 + 8);
- max_num_phys_stacked = num_phys_stacked;
- }
-}
-
-void __init arch_cpu_finalize_init(void)
-{
- ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
- (unsigned long) __end___mckinley_e9_bundles);
-}
-
-static int __init run_dmi_scan(void)
-{
- dmi_setup();
- return 0;
-}
-core_initcall(run_dmi_scan);
diff --git a/arch/ia64/kernel/sigframe.h b/arch/ia64/kernel/sigframe.h
deleted file mode 100644
index 58a36ce6c26e..000000000000
--- a/arch/ia64/kernel/sigframe.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-struct sigscratch {
- unsigned long scratch_unat; /* ar.unat for the general registers saved in pt */
- unsigned long ar_pfs; /* for syscalls, the user-level function-state */
- struct pt_regs pt;
-};
-
-struct sigframe {
- /*
- * Place signal handler args where user-level unwinder can find them easily.
- * DO NOT MOVE THESE. They are part of the IA-64 Linux ABI and there is
- * user-level code that depends on their presence!
- */
- unsigned long arg0; /* signum */
- unsigned long arg1; /* siginfo pointer */
- unsigned long arg2; /* sigcontext pointer */
- /*
- * End of architected state.
- */
-
- void __user *handler; /* pointer to the plabel of the signal handler */
- struct siginfo info;
- struct sigcontext sc;
-};
-
-extern void ia64_do_signal (struct sigscratch *, long);
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
deleted file mode 100644
index 51cf6a7ec158..000000000000
--- a/arch/ia64/kernel/signal.c
+++ /dev/null
@@ -1,412 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Architecture-specific signal handling support.
- *
- * Copyright (C) 1999-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Derived from i386 and Alpha versions.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/ptrace.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/smp.h>
-#include <linux/stddef.h>
-#include <linux/tty.h>
-#include <linux/binfmts.h>
-#include <linux/unistd.h>
-#include <linux/wait.h>
-
-#include <asm/intrinsics.h>
-#include <linux/uaccess.h>
-#include <asm/rse.h>
-#include <asm/sigcontext.h>
-
-#include "sigframe.h"
-
-#define DEBUG_SIG 0
-#define STACK_ALIGN 16 /* minimal alignment for stack pointer */
-
-#if _NSIG_WORDS > 1
-# define PUT_SIGSET(k,u) __copy_to_user((u)->sig, (k)->sig, sizeof(sigset_t))
-# define GET_SIGSET(k,u) __copy_from_user((k)->sig, (u)->sig, sizeof(sigset_t))
-#else
-# define PUT_SIGSET(k,u) __put_user((k)->sig[0], &(u)->sig[0])
-# define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0])
-#endif
-
-static long
-restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
-{
- unsigned long ip, flags, nat, um, cfm, rsc;
- long err;
-
- /* Always make any pending restarted system calls return -EINTR */
- current->restart_block.fn = do_no_restart_syscall;
-
- /* restore scratch that always needs gets updated during signal delivery: */
- err = __get_user(flags, &sc->sc_flags);
- err |= __get_user(nat, &sc->sc_nat);
- err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */
- err |= __get_user(cfm, &sc->sc_cfm);
- err |= __get_user(um, &sc->sc_um); /* user mask */
- err |= __get_user(rsc, &sc->sc_ar_rsc);
- err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat);
- err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);
- err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
- err |= __get_user(scr->pt.pr, &sc->sc_pr); /* predicates */
- err |= __get_user(scr->pt.b0, &sc->sc_br[0]); /* b0 (rp) */
- err |= __get_user(scr->pt.b6, &sc->sc_br[6]); /* b6 */
- err |= __copy_from_user(&scr->pt.r1, &sc->sc_gr[1], 8); /* r1 */
- err |= __copy_from_user(&scr->pt.r8, &sc->sc_gr[8], 4*8); /* r8-r11 */
- err |= __copy_from_user(&scr->pt.r12, &sc->sc_gr[12], 2*8); /* r12-r13 */
- err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */
-
- scr->pt.cr_ifs = cfm | (1UL << 63);
- scr->pt.ar_rsc = rsc | (3 << 2); /* force PL3 */
-
- /* establish new instruction pointer: */
- scr->pt.cr_iip = ip & ~0x3UL;
- ia64_psr(&scr->pt)->ri = ip & 0x3;
- scr->pt.cr_ipsr = (scr->pt.cr_ipsr & ~IA64_PSR_UM) | (um & IA64_PSR_UM);
-
- scr->scratch_unat = ia64_put_scratch_nat_bits(&scr->pt, nat);
-
- if (!(flags & IA64_SC_FLAG_IN_SYSCALL)) {
- /* Restore most scratch-state only when not in syscall. */
- err |= __get_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); /* ar.ccv */
- err |= __get_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */
- err |= __get_user(scr->pt.r14, &sc->sc_gr[14]); /* r14 */
- err |= __copy_from_user(&scr->pt.ar_csd, &sc->sc_ar25, 2*8); /* ar.csd & ar.ssd */
- err |= __copy_from_user(&scr->pt.r2, &sc->sc_gr[2], 2*8); /* r2-r3 */
- err |= __copy_from_user(&scr->pt.r16, &sc->sc_gr[16], 16*8); /* r16-r31 */
- }
-
- if ((flags & IA64_SC_FLAG_FPH_VALID) != 0) {
- struct ia64_psr *psr = ia64_psr(&scr->pt);
-
- err |= __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
- psr->mfh = 0; /* drop signal handler's fph contents... */
- preempt_disable();
- if (psr->dfh)
- ia64_drop_fpu(current);
- else {
- /* We already own the local fph, otherwise psr->dfh wouldn't be 0. */
- __ia64_load_fpu(current->thread.fph);
- ia64_set_local_fpu_owner(current);
- }
- preempt_enable();
- }
- return err;
-}
-
-long
-ia64_rt_sigreturn (struct sigscratch *scr)
-{
- extern char ia64_strace_leave_kernel, ia64_leave_kernel;
- struct sigcontext __user *sc;
- sigset_t set;
- long retval;
-
- sc = &((struct sigframe __user *) (scr->pt.r12 + 16))->sc;
-
- /*
- * When we return to the previously executing context, r8 and r10 have already
- * been setup the way we want them. Indeed, if the signal wasn't delivered while
- * in a system call, we must not touch r8 or r10 as otherwise user-level state
- * could be corrupted.
- */
- retval = (long) &ia64_leave_kernel;
- if (test_thread_flag(TIF_SYSCALL_TRACE)
- || test_thread_flag(TIF_SYSCALL_AUDIT))
- /*
- * strace expects to be notified after sigreturn returns even though the
- * context to which we return may not be in the middle of a syscall.
- * Thus, the return-value that strace displays for sigreturn is
- * meaningless.
- */
- retval = (long) &ia64_strace_leave_kernel;
-
- if (!access_ok(sc, sizeof(*sc)))
- goto give_sigsegv;
-
- if (GET_SIGSET(&set, &sc->sc_mask))
- goto give_sigsegv;
-
- set_current_blocked(&set);
-
- if (restore_sigcontext(sc, scr))
- goto give_sigsegv;
-
-#if DEBUG_SIG
- printk("SIG return (%s:%d): sp=%lx ip=%lx\n",
- current->comm, current->pid, scr->pt.r12, scr->pt.cr_iip);
-#endif
- if (restore_altstack(&sc->sc_stack))
- goto give_sigsegv;
- return retval;
-
- give_sigsegv:
- force_sig(SIGSEGV);
- return retval;
-}
-
-/*
- * This does just the minimum required setup of sigcontext.
- * Specifically, it only installs data that is either not knowable at
- * the user-level or that gets modified before execution in the
- * trampoline starts. Everything else is done at the user-level.
- */
-static long
-setup_sigcontext (struct sigcontext __user *sc, sigset_t *mask, struct sigscratch *scr)
-{
- unsigned long flags = 0, ifs, cfm, nat;
- long err = 0;
-
- ifs = scr->pt.cr_ifs;
-
- if (on_sig_stack((unsigned long) sc))
- flags |= IA64_SC_FLAG_ONSTACK;
- if ((ifs & (1UL << 63)) == 0)
- /* if cr_ifs doesn't have the valid bit set, we got here through a syscall */
- flags |= IA64_SC_FLAG_IN_SYSCALL;
- cfm = ifs & ((1UL << 38) - 1);
- ia64_flush_fph(current);
- if ((current->thread.flags & IA64_THREAD_FPH_VALID)) {
- flags |= IA64_SC_FLAG_FPH_VALID;
- err = __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16);
- }
-
- nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat);
-
- err |= __put_user(flags, &sc->sc_flags);
- err |= __put_user(nat, &sc->sc_nat);
- err |= PUT_SIGSET(mask, &sc->sc_mask);
- err |= __put_user(cfm, &sc->sc_cfm);
- err |= __put_user(scr->pt.cr_ipsr & IA64_PSR_UM, &sc->sc_um);
- err |= __put_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
- err |= __put_user(scr->pt.ar_unat, &sc->sc_ar_unat); /* ar.unat */
- err |= __put_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr); /* ar.fpsr */
- err |= __put_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
- err |= __put_user(scr->pt.pr, &sc->sc_pr); /* predicates */
- err |= __put_user(scr->pt.b0, &sc->sc_br[0]); /* b0 (rp) */
- err |= __put_user(scr->pt.b6, &sc->sc_br[6]); /* b6 */
- err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 8); /* r1 */
- err |= __copy_to_user(&sc->sc_gr[8], &scr->pt.r8, 4*8); /* r8-r11 */
- err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 2*8); /* r12-r13 */
- err |= __copy_to_user(&sc->sc_gr[15], &scr->pt.r15, 8); /* r15 */
- err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip);
-
- if (!(flags & IA64_SC_FLAG_IN_SYSCALL)) {
- /* Copy scratch regs to sigcontext if the signal didn't interrupt a syscall. */
- err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); /* ar.ccv */
- err |= __put_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */
- err |= __put_user(scr->pt.r14, &sc->sc_gr[14]); /* r14 */
- err |= __copy_to_user(&sc->sc_ar25, &scr->pt.ar_csd, 2*8); /* ar.csd & ar.ssd */
- err |= __copy_to_user(&sc->sc_gr[2], &scr->pt.r2, 2*8); /* r2-r3 */
- err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8); /* r16-r31 */
- }
- return err;
-}
-
-/*
- * Check whether the register-backing store is already on the signal stack.
- */
-static inline int
-rbs_on_sig_stack (unsigned long bsp)
-{
- return (bsp - current->sas_ss_sp < current->sas_ss_size);
-}
-
-static long
-setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr)
-{
- extern char __kernel_sigtramp[];
- unsigned long tramp_addr, new_rbs = 0, new_sp;
- struct sigframe __user *frame;
- long err;
-
- new_sp = scr->pt.r12;
- tramp_addr = (unsigned long) __kernel_sigtramp;
- if (ksig->ka.sa.sa_flags & SA_ONSTACK) {
- int onstack = sas_ss_flags(new_sp);
-
- if (onstack == 0) {
- new_sp = current->sas_ss_sp + current->sas_ss_size;
- /*
- * We need to check for the register stack being on the
- * signal stack separately, because it's switched
- * separately (memory stack is switched in the kernel,
- * register stack is switched in the signal trampoline).
- */
- if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
- new_rbs = ALIGN(current->sas_ss_sp,
- sizeof(long));
- } else if (onstack == SS_ONSTACK) {
- unsigned long check_sp;
-
- /*
- * If we are on the alternate signal stack and would
- * overflow it, don't. Return an always-bogus address
- * instead so we will die with SIGSEGV.
- */
- check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN;
- if (!likely(on_sig_stack(check_sp))) {
- force_sigsegv(ksig->sig);
- return 1;
- }
- }
- }
- frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
-
- if (!access_ok(frame, sizeof(*frame))) {
- force_sigsegv(ksig->sig);
- return 1;
- }
-
- err = __put_user(ksig->sig, &frame->arg0);
- err |= __put_user(&frame->info, &frame->arg1);
- err |= __put_user(&frame->sc, &frame->arg2);
- err |= __put_user(new_rbs, &frame->sc.sc_rbs_base);
- err |= __put_user(0, &frame->sc.sc_loadrs); /* initialize to zero */
- err |= __put_user(ksig->ka.sa.sa_handler, &frame->handler);
-
- err |= copy_siginfo_to_user(&frame->info, &ksig->info);
-
- err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12);
- err |= setup_sigcontext(&frame->sc, set, scr);
-
- if (unlikely(err)) {
- force_sigsegv(ksig->sig);
- return 1;
- }
-
- scr->pt.r12 = (unsigned long) frame - 16; /* new stack pointer */
- scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */
- scr->pt.cr_iip = tramp_addr;
- ia64_psr(&scr->pt)->ri = 0; /* start executing in first slot */
- ia64_psr(&scr->pt)->be = 0; /* force little-endian byte-order */
- /*
- * Force the interruption function mask to zero. This has no effect when a
- * system-call got interrupted by a signal (since, in that case, scr->pt_cr_ifs is
- * ignored), but it has the desirable effect of making it possible to deliver a
- * signal with an incomplete register frame (which happens when a mandatory RSE
- * load faults). Furthermore, it has no negative effect on the getting the user's
- * dirty partition preserved, because that's governed by scr->pt.loadrs.
- */
- scr->pt.cr_ifs = (1UL << 63);
-
- /*
- * Note: this affects only the NaT bits of the scratch regs (the ones saved in
- * pt_regs), which is exactly what we want.
- */
- scr->scratch_unat = 0; /* ensure NaT bits of r12 is clear */
-
-#if DEBUG_SIG
- printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%p\n",
- current->comm, current->pid, ksig->sig, scr->pt.r12, frame->sc.sc_ip, frame->handler);
-#endif
- return 0;
-}
-
-static long
-handle_signal (struct ksignal *ksig, struct sigscratch *scr)
-{
- int ret = setup_frame(ksig, sigmask_to_save(), scr);
-
- if (!ret)
- signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
-
- return ret;
-}
-
-/*
- * Note that `init' is a special process: it doesn't get signals it doesn't want to
- * handle. Thus you cannot kill init even with a SIGKILL even by mistake.
- */
-void
-ia64_do_signal (struct sigscratch *scr, long in_syscall)
-{
- long restart = in_syscall;
- long errno = scr->pt.r8;
- struct ksignal ksig;
-
- /*
- * This only loops in the rare cases of handle_signal() failing, in which case we
- * need to push through a forced SIGSEGV.
- */
- while (1) {
- if (!get_signal(&ksig))
- break;
-
- /*
- * get_signal() may have run a debugger (via notify_parent())
- * and the debugger may have modified the state (e.g., to arrange for an
- * inferior call), thus it's important to check for restarting _after_
- * get_signal().
- */
- if ((long) scr->pt.r10 != -1)
- /*
- * A system calls has to be restarted only if one of the error codes
- * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned. If r10
- * isn't -1 then r8 doesn't hold an error code and we don't need to
- * restart the syscall, so we can clear the "restart" flag here.
- */
- restart = 0;
-
- if (ksig.sig <= 0)
- break;
-
- if (unlikely(restart)) {
- switch (errno) {
- case ERESTART_RESTARTBLOCK:
- case ERESTARTNOHAND:
- scr->pt.r8 = EINTR;
- /* note: scr->pt.r10 is already -1 */
- break;
- case ERESTARTSYS:
- if ((ksig.ka.sa.sa_flags & SA_RESTART) == 0) {
- scr->pt.r8 = EINTR;
- /* note: scr->pt.r10 is already -1 */
- break;
- }
- fallthrough;
- case ERESTARTNOINTR:
- ia64_decrement_ip(&scr->pt);
- restart = 0; /* don't restart twice if handle_signal() fails... */
- }
- }
-
- /*
- * Whee! Actually deliver the signal. If the delivery failed, we need to
- * continue to iterate in this loop so we can deliver the SIGSEGV...
- */
- if (handle_signal(&ksig, scr))
- return;
- }
-
- /* Did we come from a system call? */
- if (restart) {
- /* Restart the system call - no handlers present */
- if (errno == ERESTARTNOHAND || errno == ERESTARTSYS || errno == ERESTARTNOINTR
- || errno == ERESTART_RESTARTBLOCK)
- {
- /*
- * Note: the syscall number is in r15 which is saved in
- * pt_regs so all we need to do here is adjust ip so that
- * the "break" instruction gets re-executed.
- */
- ia64_decrement_ip(&scr->pt);
- if (errno == ERESTART_RESTARTBLOCK)
- scr->pt.r15 = __NR_restart_syscall;
- }
- }
-
- /* if there's no signal to deliver, we just put the saved sigmask
- * back */
- restore_saved_sigmask();
-}
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
deleted file mode 100644
index ea4f009a232b..000000000000
--- a/arch/ia64/kernel/smp.c
+++ /dev/null
@@ -1,335 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * SMP Support
- *
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999, 2001, 2003 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Lots of stuff stolen from arch/alpha/kernel/smp.c
- *
- * 01/05/16 Rohit Seth <rohit.seth@intel.com> IA64-SMP functions. Reorganized
- * the existing code (on the lines of x86 port).
- * 00/09/11 David Mosberger <davidm@hpl.hp.com> Do loops_per_jiffy
- * calibration on each CPU.
- * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> fixed logical processor id
- * 00/03/31 Rohit Seth <rohit.seth@intel.com> Fixes for Bootstrap Processor
- * & cpu_online_map now gets done here (instead of setup.c)
- * 99/10/05 davidm Update to bring it in sync with new command-line processing
- * scheme.
- * 10/13/00 Goutham Rao <goutham.rao@intel.com> Updated smp_call_function and
- * smp_call_function_single to resend IPI on timeouts
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-#include <linux/kernel_stat.h>
-#include <linux/mm.h>
-#include <linux/cache.h>
-#include <linux/delay.h>
-#include <linux/efi.h>
-#include <linux/bitops.h>
-#include <linux/kexec.h>
-
-#include <linux/atomic.h>
-#include <asm/current.h>
-#include <asm/delay.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/sal.h>
-#include <asm/tlbflush.h>
-#include <asm/unistd.h>
-#include <asm/mca.h>
-#include <asm/xtp.h>
-
-/*
- * Note: alignment of 4 entries/cacheline was empirically determined
- * to be a good tradeoff between hot cachelines & spreading the array
- * across too many cacheline.
- */
-static struct local_tlb_flush_counts {
- unsigned int count;
-} __attribute__((__aligned__(32))) local_tlb_flush_counts[NR_CPUS];
-
-static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned short [NR_CPUS],
- shadow_flush_counts);
-
-#define IPI_CALL_FUNC 0
-#define IPI_CPU_STOP 1
-#define IPI_CALL_FUNC_SINGLE 2
-#define IPI_KDUMP_CPU_STOP 3
-
-/* This needs to be cacheline aligned because it is written to by *other* CPUs. */
-static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, ipi_operation);
-
-extern void cpu_halt (void);
-
-static void
-stop_this_cpu(void)
-{
- /*
- * Remove this CPU:
- */
- set_cpu_online(smp_processor_id(), false);
- max_xtp();
- local_irq_disable();
- cpu_halt();
-}
-
-void
-cpu_die(void)
-{
- max_xtp();
- local_irq_disable();
- cpu_halt();
- /* Should never be here */
- BUG();
- for (;;);
-}
-
-irqreturn_t
-handle_IPI (int irq, void *dev_id)
-{
- int this_cpu = get_cpu();
- unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation);
- unsigned long ops;
-
- mb(); /* Order interrupt and bit testing. */
- while ((ops = xchg(pending_ipis, 0)) != 0) {
- mb(); /* Order bit clearing and data access. */
- do {
- unsigned long which;
-
- which = ffz(~ops);
- ops &= ~(1 << which);
-
- switch (which) {
- case IPI_CPU_STOP:
- stop_this_cpu();
- break;
- case IPI_CALL_FUNC:
- generic_smp_call_function_interrupt();
- break;
- case IPI_CALL_FUNC_SINGLE:
- generic_smp_call_function_single_interrupt();
- break;
-#ifdef CONFIG_KEXEC
- case IPI_KDUMP_CPU_STOP:
- unw_init_running(kdump_cpu_freeze, NULL);
- break;
-#endif
- default:
- printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n",
- this_cpu, which);
- break;
- }
- } while (ops);
- mb(); /* Order data access and bit testing. */
- }
- put_cpu();
- return IRQ_HANDLED;
-}
-
-
-
-/*
- * Called with preemption disabled.
- */
-static inline void
-send_IPI_single (int dest_cpu, int op)
-{
- set_bit(op, &per_cpu(ipi_operation, dest_cpu));
- ia64_send_ipi(dest_cpu, IA64_IPI_VECTOR, IA64_IPI_DM_INT, 0);
-}
-
-/*
- * Called with preemption disabled.
- */
-static inline void
-send_IPI_allbutself (int op)
-{
- unsigned int i;
-
- for_each_online_cpu(i) {
- if (i != smp_processor_id())
- send_IPI_single(i, op);
- }
-}
-
-/*
- * Called with preemption disabled.
- */
-static inline void
-send_IPI_mask(const struct cpumask *mask, int op)
-{
- unsigned int cpu;
-
- for_each_cpu(cpu, mask) {
- send_IPI_single(cpu, op);
- }
-}
-
-/*
- * Called with preemption disabled.
- */
-static inline void
-send_IPI_all (int op)
-{
- int i;
-
- for_each_online_cpu(i) {
- send_IPI_single(i, op);
- }
-}
-
-/*
- * Called with preemption disabled.
- */
-static inline void
-send_IPI_self (int op)
-{
- send_IPI_single(smp_processor_id(), op);
-}
-
-#ifdef CONFIG_KEXEC
-void
-kdump_smp_send_stop(void)
-{
- send_IPI_allbutself(IPI_KDUMP_CPU_STOP);
-}
-
-void
-kdump_smp_send_init(void)
-{
- unsigned int cpu, self_cpu;
- self_cpu = smp_processor_id();
- for_each_online_cpu(cpu) {
- if (cpu != self_cpu) {
- if(kdump_status[cpu] == 0)
- ia64_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
- }
- }
-}
-#endif
-/*
- * Called with preemption disabled.
- */
-void
-arch_smp_send_reschedule (int cpu)
-{
- ia64_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
-}
-EXPORT_SYMBOL_GPL(arch_smp_send_reschedule);
-
-/*
- * Called with preemption disabled.
- */
-static void
-smp_send_local_flush_tlb (int cpu)
-{
- ia64_send_ipi(cpu, IA64_IPI_LOCAL_TLB_FLUSH, IA64_IPI_DM_INT, 0);
-}
-
-void
-smp_local_flush_tlb(void)
-{
- /*
- * Use atomic ops. Otherwise, the load/increment/store sequence from
- * a "++" operation can have the line stolen between the load & store.
- * The overhead of the atomic op in negligible in this case & offers
- * significant benefit for the brief periods where lots of cpus
- * are simultaneously flushing TLBs.
- */
- ia64_fetchadd(1, &local_tlb_flush_counts[smp_processor_id()].count, acq);
- local_flush_tlb_all();
-}
-
-#define FLUSH_DELAY 5 /* Usec backoff to eliminate excessive cacheline bouncing */
-
-void
-smp_flush_tlb_cpumask(cpumask_t xcpumask)
-{
- unsigned short *counts = __ia64_per_cpu_var(shadow_flush_counts);
- cpumask_t cpumask = xcpumask;
- int mycpu, cpu, flush_mycpu = 0;
-
- preempt_disable();
- mycpu = smp_processor_id();
-
- for_each_cpu(cpu, &cpumask)
- counts[cpu] = local_tlb_flush_counts[cpu].count & 0xffff;
-
- mb();
- for_each_cpu(cpu, &cpumask) {
- if (cpu == mycpu)
- flush_mycpu = 1;
- else
- smp_send_local_flush_tlb(cpu);
- }
-
- if (flush_mycpu)
- smp_local_flush_tlb();
-
- for_each_cpu(cpu, &cpumask)
- while(counts[cpu] == (local_tlb_flush_counts[cpu].count & 0xffff))
- udelay(FLUSH_DELAY);
-
- preempt_enable();
-}
-
-void
-smp_flush_tlb_all (void)
-{
- on_each_cpu((void (*)(void *))local_flush_tlb_all, NULL, 1);
-}
-
-void
-smp_flush_tlb_mm (struct mm_struct *mm)
-{
- cpumask_var_t cpus;
- preempt_disable();
- /* this happens for the common case of a single-threaded fork(): */
- if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1))
- {
- local_finish_flush_tlb_mm(mm);
- preempt_enable();
- return;
- }
- if (!alloc_cpumask_var(&cpus, GFP_ATOMIC)) {
- smp_call_function((void (*)(void *))local_finish_flush_tlb_mm,
- mm, 1);
- } else {
- cpumask_copy(cpus, mm_cpumask(mm));
- smp_call_function_many(cpus,
- (void (*)(void *))local_finish_flush_tlb_mm, mm, 1);
- free_cpumask_var(cpus);
- }
- local_irq_disable();
- local_finish_flush_tlb_mm(mm);
- local_irq_enable();
- preempt_enable();
-}
-
-void arch_send_call_function_single_ipi(int cpu)
-{
- send_IPI_single(cpu, IPI_CALL_FUNC_SINGLE);
-}
-
-void arch_send_call_function_ipi_mask(const struct cpumask *mask)
-{
- send_IPI_mask(mask, IPI_CALL_FUNC);
-}
-
-/*
- * this function calls the 'stop' function on all other CPUs in the system.
- */
-void
-smp_send_stop (void)
-{
- send_IPI_allbutself(IPI_CPU_STOP);
-}
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
deleted file mode 100644
index d0e935cf2093..000000000000
--- a/arch/ia64/kernel/smpboot.c
+++ /dev/null
@@ -1,839 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * SMP boot-related support
- *
- * Copyright (C) 1998-2003, 2005 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2001, 2004-2005 Intel Corp
- * Rohit Seth <rohit.seth@intel.com>
- * Suresh Siddha <suresh.b.siddha@intel.com>
- * Gordon Jin <gordon.jin@intel.com>
- * Ashok Raj <ashok.raj@intel.com>
- *
- * 01/05/16 Rohit Seth <rohit.seth@intel.com> Moved SMP booting functions from smp.c to here.
- * 01/04/27 David Mosberger <davidm@hpl.hp.com> Added ITC synching code.
- * 02/07/31 David Mosberger <davidm@hpl.hp.com> Switch over to hotplug-CPU boot-sequence.
- * smp_boot_cpus()/smp_commence() is replaced by
- * smp_prepare_cpus()/__cpu_up()/smp_cpus_done().
- * 04/06/21 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support
- * 04/12/26 Jin Gordon <gordon.jin@intel.com>
- * 04/12/26 Rohit Seth <rohit.seth@intel.com>
- * Add multi-threading and multi-core detection
- * 05/01/30 Suresh Siddha <suresh.b.siddha@intel.com>
- * Setup cpu_sibling_map and cpu_core_map
- */
-
-#include <linux/module.h>
-#include <linux/acpi.h>
-#include <linux/memblock.h>
-#include <linux/cpu.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/mm.h>
-#include <linux/notifier.h>
-#include <linux/smp.h>
-#include <linux/spinlock.h>
-#include <linux/efi.h>
-#include <linux/percpu.h>
-#include <linux/bitops.h>
-
-#include <linux/atomic.h>
-#include <asm/cache.h>
-#include <asm/current.h>
-#include <asm/delay.h>
-#include <asm/efi.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mca.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/sal.h>
-#include <asm/tlbflush.h>
-#include <asm/unistd.h>
-
-#define SMP_DEBUG 0
-
-#if SMP_DEBUG
-#define Dprintk(x...) printk(x)
-#else
-#define Dprintk(x...)
-#endif
-
-#ifdef CONFIG_HOTPLUG_CPU
-#ifdef CONFIG_PERMIT_BSP_REMOVE
-#define bsp_remove_ok 1
-#else
-#define bsp_remove_ok 0
-#endif
-
-/*
- * Global array allocated for NR_CPUS at boot time
- */
-struct sal_to_os_boot sal_boot_rendez_state[NR_CPUS];
-
-/*
- * start_ap in head.S uses this to store current booting cpu
- * info.
- */
-struct sal_to_os_boot *sal_state_for_booting_cpu = &sal_boot_rendez_state[0];
-
-#define set_brendez_area(x) (sal_state_for_booting_cpu = &sal_boot_rendez_state[(x)]);
-
-#else
-#define set_brendez_area(x)
-#endif
-
-
-/*
- * ITC synchronization related stuff:
- */
-#define MASTER (0)
-#define SLAVE (SMP_CACHE_BYTES/8)
-
-#define NUM_ROUNDS 64 /* magic value */
-#define NUM_ITERS 5 /* likewise */
-
-static DEFINE_SPINLOCK(itc_sync_lock);
-static volatile unsigned long go[SLAVE + 1];
-
-#define DEBUG_ITC_SYNC 0
-
-extern void start_ap (void);
-extern unsigned long ia64_iobase;
-
-struct task_struct *task_for_booting_cpu;
-
-/*
- * State for each CPU
- */
-DEFINE_PER_CPU(int, cpu_state);
-
-cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_core_map);
-DEFINE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
-EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
-
-int smp_num_siblings = 1;
-
-/* which logical CPU number maps to which CPU (physical APIC ID) */
-volatile int ia64_cpu_to_sapicid[NR_CPUS];
-EXPORT_SYMBOL(ia64_cpu_to_sapicid);
-
-static cpumask_t cpu_callin_map;
-
-struct smp_boot_data smp_boot_data __initdata;
-
-unsigned long ap_wakeup_vector = -1; /* External Int use to wakeup APs */
-
-char __initdata no_int_routing;
-
-unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */
-
-#ifdef CONFIG_FORCE_CPEI_RETARGET
-#define CPEI_OVERRIDE_DEFAULT (1)
-#else
-#define CPEI_OVERRIDE_DEFAULT (0)
-#endif
-
-unsigned int force_cpei_retarget = CPEI_OVERRIDE_DEFAULT;
-
-static int __init
-cmdl_force_cpei(char *str)
-{
- int value=0;
-
- get_option (&str, &value);
- force_cpei_retarget = value;
-
- return 1;
-}
-
-__setup("force_cpei=", cmdl_force_cpei);
-
-static int __init
-nointroute (char *str)
-{
- no_int_routing = 1;
- printk ("no_int_routing on\n");
- return 1;
-}
-
-__setup("nointroute", nointroute);
-
-static void fix_b0_for_bsp(void)
-{
-#ifdef CONFIG_HOTPLUG_CPU
- int cpuid;
- static int fix_bsp_b0 = 1;
-
- cpuid = smp_processor_id();
-
- /*
- * Cache the b0 value on the first AP that comes up
- */
- if (!(fix_bsp_b0 && cpuid))
- return;
-
- sal_boot_rendez_state[0].br[0] = sal_boot_rendez_state[cpuid].br[0];
- printk ("Fixed BSP b0 value from CPU %d\n", cpuid);
-
- fix_bsp_b0 = 0;
-#endif
-}
-
-void
-sync_master (void *arg)
-{
- unsigned long flags, i;
-
- go[MASTER] = 0;
-
- local_irq_save(flags);
- {
- for (i = 0; i < NUM_ROUNDS*NUM_ITERS; ++i) {
- while (!go[MASTER])
- cpu_relax();
- go[MASTER] = 0;
- go[SLAVE] = ia64_get_itc();
- }
- }
- local_irq_restore(flags);
-}
-
-/*
- * Return the number of cycles by which our itc differs from the itc on the master
- * (time-keeper) CPU. A positive number indicates our itc is ahead of the master,
- * negative that it is behind.
- */
-static inline long
-get_delta (long *rt, long *master)
-{
- unsigned long best_t0 = 0, best_t1 = ~0UL, best_tm = 0;
- unsigned long tcenter, t0, t1, tm;
- long i;
-
- for (i = 0; i < NUM_ITERS; ++i) {
- t0 = ia64_get_itc();
- go[MASTER] = 1;
- while (!(tm = go[SLAVE]))
- cpu_relax();
- go[SLAVE] = 0;
- t1 = ia64_get_itc();
-
- if (t1 - t0 < best_t1 - best_t0)
- best_t0 = t0, best_t1 = t1, best_tm = tm;
- }
-
- *rt = best_t1 - best_t0;
- *master = best_tm - best_t0;
-
- /* average best_t0 and best_t1 without overflow: */
- tcenter = (best_t0/2 + best_t1/2);
- if (best_t0 % 2 + best_t1 % 2 == 2)
- ++tcenter;
- return tcenter - best_tm;
-}
-
-/*
- * Synchronize ar.itc of the current (slave) CPU with the ar.itc of the MASTER CPU
- * (normally the time-keeper CPU). We use a closed loop to eliminate the possibility of
- * unaccounted-for errors (such as getting a machine check in the middle of a calibration
- * step). The basic idea is for the slave to ask the master what itc value it has and to
- * read its own itc before and after the master responds. Each iteration gives us three
- * timestamps:
- *
- * slave master
- *
- * t0 ---\
- * ---\
- * --->
- * tm
- * /---
- * /---
- * t1 <---
- *
- *
- * The goal is to adjust the slave's ar.itc such that tm falls exactly half-way between t0
- * and t1. If we achieve this, the clocks are synchronized provided the interconnect
- * between the slave and the master is symmetric. Even if the interconnect were
- * asymmetric, we would still know that the synchronization error is smaller than the
- * roundtrip latency (t0 - t1).
- *
- * When the interconnect is quiet and symmetric, this lets us synchronize the itc to
- * within one or two cycles. However, we can only *guarantee* that the synchronization is
- * accurate to within a round-trip time, which is typically in the range of several
- * hundred cycles (e.g., ~500 cycles). In practice, this means that the itc's are usually
- * almost perfectly synchronized, but we shouldn't assume that the accuracy is much better
- * than half a micro second or so.
- */
-void
-ia64_sync_itc (unsigned int master)
-{
- long i, delta, adj, adjust_latency = 0, done = 0;
- unsigned long flags, rt, master_time_stamp, bound;
-#if DEBUG_ITC_SYNC
- struct {
- long rt; /* roundtrip time */
- long master; /* master's timestamp */
- long diff; /* difference between midpoint and master's timestamp */
- long lat; /* estimate of itc adjustment latency */
- } t[NUM_ROUNDS];
-#endif
-
- /*
- * Make sure local timer ticks are disabled while we sync. If
- * they were enabled, we'd have to worry about nasty issues
- * like setting the ITC ahead of (or a long time before) the
- * next scheduled tick.
- */
- BUG_ON((ia64_get_itv() & (1 << 16)) == 0);
-
- go[MASTER] = 1;
-
- if (smp_call_function_single(master, sync_master, NULL, 0) < 0) {
- printk(KERN_ERR "sync_itc: failed to get attention of CPU %u!\n", master);
- return;
- }
-
- while (go[MASTER])
- cpu_relax(); /* wait for master to be ready */
-
- spin_lock_irqsave(&itc_sync_lock, flags);
- {
- for (i = 0; i < NUM_ROUNDS; ++i) {
- delta = get_delta(&rt, &master_time_stamp);
- if (delta == 0) {
- done = 1; /* let's lock on to this... */
- bound = rt;
- }
-
- if (!done) {
- if (i > 0) {
- adjust_latency += -delta;
- adj = -delta + adjust_latency/4;
- } else
- adj = -delta;
-
- ia64_set_itc(ia64_get_itc() + adj);
- }
-#if DEBUG_ITC_SYNC
- t[i].rt = rt;
- t[i].master = master_time_stamp;
- t[i].diff = delta;
- t[i].lat = adjust_latency/4;
-#endif
- }
- }
- spin_unlock_irqrestore(&itc_sync_lock, flags);
-
-#if DEBUG_ITC_SYNC
- for (i = 0; i < NUM_ROUNDS; ++i)
- printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ld\n",
- t[i].rt, t[i].master, t[i].diff, t[i].lat);
-#endif
-
- printk(KERN_INFO "CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, "
- "maxerr %lu cycles)\n", smp_processor_id(), master, delta, rt);
-}
-
-/*
- * Ideally sets up per-cpu profiling hooks. Doesn't do much now...
- */
-static inline void smp_setup_percpu_timer(void)
-{
-}
-
-static void
-smp_callin (void)
-{
- int cpuid, phys_id, itc_master;
- struct cpuinfo_ia64 *last_cpuinfo, *this_cpuinfo;
- extern void ia64_init_itm(void);
- extern volatile int time_keeper_id;
-
- cpuid = smp_processor_id();
- phys_id = hard_smp_processor_id();
- itc_master = time_keeper_id;
-
- if (cpu_online(cpuid)) {
- printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
- phys_id, cpuid);
- BUG();
- }
-
- fix_b0_for_bsp();
-
- /*
- * numa_node_id() works after this.
- */
- set_numa_node(cpu_to_node_map[cpuid]);
- set_numa_mem(local_memory_node(cpu_to_node_map[cpuid]));
-
- spin_lock(&vector_lock);
- /* Setup the per cpu irq handling data structures */
- __setup_vector_irq(cpuid);
- notify_cpu_starting(cpuid);
- set_cpu_online(cpuid, true);
- per_cpu(cpu_state, cpuid) = CPU_ONLINE;
- spin_unlock(&vector_lock);
-
- smp_setup_percpu_timer();
-
- ia64_mca_cmc_vector_setup(); /* Setup vector on AP */
-
- local_irq_enable();
-
- if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
- /*
- * Synchronize the ITC with the BP. Need to do this after irqs are
- * enabled because ia64_sync_itc() calls smp_call_function_single(), which
- * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
- * local_bh_enable(), which bugs out if irqs are not enabled...
- */
- Dprintk("Going to syncup ITC with ITC Master.\n");
- ia64_sync_itc(itc_master);
- }
-
- /*
- * Get our bogomips.
- */
- ia64_init_itm();
-
- /*
- * Delay calibration can be skipped if new processor is identical to the
- * previous processor.
- */
- last_cpuinfo = cpu_data(cpuid - 1);
- this_cpuinfo = local_cpu_data;
- if (last_cpuinfo->itc_freq != this_cpuinfo->itc_freq ||
- last_cpuinfo->proc_freq != this_cpuinfo->proc_freq ||
- last_cpuinfo->features != this_cpuinfo->features ||
- last_cpuinfo->revision != this_cpuinfo->revision ||
- last_cpuinfo->family != this_cpuinfo->family ||
- last_cpuinfo->archrev != this_cpuinfo->archrev ||
- last_cpuinfo->model != this_cpuinfo->model)
- calibrate_delay();
- local_cpu_data->loops_per_jiffy = loops_per_jiffy;
-
- /*
- * Allow the master to continue.
- */
- cpumask_set_cpu(cpuid, &cpu_callin_map);
- Dprintk("Stack on CPU %d at about %p\n",cpuid, &cpuid);
-}
-
-
-/*
- * Activate a secondary processor. head.S calls this.
- */
-int
-start_secondary (void *unused)
-{
- /* Early console may use I/O ports */
- ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
-#ifndef CONFIG_PRINTK_TIME
- Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id());
-#endif
- efi_map_pal_code();
- cpu_init();
- smp_callin();
-
- cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
- return 0;
-}
-
-static int
-do_boot_cpu (int sapicid, int cpu, struct task_struct *idle)
-{
- int timeout;
-
- task_for_booting_cpu = idle;
- Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
-
- set_brendez_area(cpu);
- ia64_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0);
-
- /*
- * Wait 10s total for the AP to start
- */
- Dprintk("Waiting on callin_map ...");
- for (timeout = 0; timeout < 100000; timeout++) {
- if (cpumask_test_cpu(cpu, &cpu_callin_map))
- break; /* It has booted */
- barrier(); /* Make sure we re-read cpu_callin_map */
- udelay(100);
- }
- Dprintk("\n");
-
- if (!cpumask_test_cpu(cpu, &cpu_callin_map)) {
- printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid);
- ia64_cpu_to_sapicid[cpu] = -1;
- set_cpu_online(cpu, false); /* was set in smp_callin() */
- return -EINVAL;
- }
- return 0;
-}
-
-static int __init
-decay (char *str)
-{
- int ticks;
- get_option (&str, &ticks);
- return 1;
-}
-
-__setup("decay=", decay);
-
-/*
- * Initialize the logical CPU number to SAPICID mapping
- */
-void __init
-smp_build_cpu_map (void)
-{
- int sapicid, cpu, i;
- int boot_cpu_id = hard_smp_processor_id();
-
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- ia64_cpu_to_sapicid[cpu] = -1;
- }
-
- ia64_cpu_to_sapicid[0] = boot_cpu_id;
- init_cpu_present(cpumask_of(0));
- set_cpu_possible(0, true);
- for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) {
- sapicid = smp_boot_data.cpu_phys_id[i];
- if (sapicid == boot_cpu_id)
- continue;
- set_cpu_present(cpu, true);
- set_cpu_possible(cpu, true);
- ia64_cpu_to_sapicid[cpu] = sapicid;
- cpu++;
- }
-}
-
-/*
- * Cycle through the APs sending Wakeup IPIs to boot each.
- */
-void __init
-smp_prepare_cpus (unsigned int max_cpus)
-{
- int boot_cpu_id = hard_smp_processor_id();
-
- /*
- * Initialize the per-CPU profiling counter/multiplier
- */
-
- smp_setup_percpu_timer();
-
- cpumask_set_cpu(0, &cpu_callin_map);
-
- local_cpu_data->loops_per_jiffy = loops_per_jiffy;
- ia64_cpu_to_sapicid[0] = boot_cpu_id;
-
- printk(KERN_INFO "Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);
-
- current_thread_info()->cpu = 0;
-
- /*
- * If SMP should be disabled, then really disable it!
- */
- if (!max_cpus) {
- printk(KERN_INFO "SMP mode deactivated.\n");
- init_cpu_online(cpumask_of(0));
- init_cpu_present(cpumask_of(0));
- init_cpu_possible(cpumask_of(0));
- return;
- }
-}
-
-void smp_prepare_boot_cpu(void)
-{
- set_cpu_online(smp_processor_id(), true);
- cpumask_set_cpu(smp_processor_id(), &cpu_callin_map);
- set_numa_node(cpu_to_node_map[smp_processor_id()]);
- per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-static inline void
-clear_cpu_sibling_map(int cpu)
-{
- int i;
-
- for_each_cpu(i, &per_cpu(cpu_sibling_map, cpu))
- cpumask_clear_cpu(cpu, &per_cpu(cpu_sibling_map, i));
- for_each_cpu(i, &cpu_core_map[cpu])
- cpumask_clear_cpu(cpu, &cpu_core_map[i]);
-
- per_cpu(cpu_sibling_map, cpu) = cpu_core_map[cpu] = CPU_MASK_NONE;
-}
-
-static void
-remove_siblinginfo(int cpu)
-{
- if (cpu_data(cpu)->threads_per_core == 1 &&
- cpu_data(cpu)->cores_per_socket == 1) {
- cpumask_clear_cpu(cpu, &cpu_core_map[cpu]);
- cpumask_clear_cpu(cpu, &per_cpu(cpu_sibling_map, cpu));
- return;
- }
-
- /* remove it from all sibling map's */
- clear_cpu_sibling_map(cpu);
-}
-
-extern void fixup_irqs(void);
-
-int migrate_platform_irqs(unsigned int cpu)
-{
- int new_cpei_cpu;
- struct irq_data *data = NULL;
- const struct cpumask *mask;
- int retval = 0;
-
- /*
- * dont permit CPEI target to removed.
- */
- if (cpe_vector > 0 && is_cpu_cpei_target(cpu)) {
- printk ("CPU (%d) is CPEI Target\n", cpu);
- if (can_cpei_retarget()) {
- /*
- * Now re-target the CPEI to a different processor
- */
- new_cpei_cpu = cpumask_any(cpu_online_mask);
- mask = cpumask_of(new_cpei_cpu);
- set_cpei_target_cpu(new_cpei_cpu);
- data = irq_get_irq_data(ia64_cpe_irq);
- /*
- * Switch for now, immediately, we need to do fake intr
- * as other interrupts, but need to study CPEI behaviour with
- * polling before making changes.
- */
- if (data && data->chip) {
- data->chip->irq_disable(data);
- data->chip->irq_set_affinity(data, mask, false);
- data->chip->irq_enable(data);
- printk ("Re-targeting CPEI to cpu %d\n", new_cpei_cpu);
- }
- }
- if (!data) {
- printk ("Unable to retarget CPEI, offline cpu [%d] failed\n", cpu);
- retval = -EBUSY;
- }
- }
- return retval;
-}
-
-/* must be called with cpucontrol mutex held */
-int __cpu_disable(void)
-{
- int cpu = smp_processor_id();
-
- /*
- * dont permit boot processor for now
- */
- if (cpu == 0 && !bsp_remove_ok) {
- printk ("Your platform does not support removal of BSP\n");
- return (-EBUSY);
- }
-
- set_cpu_online(cpu, false);
-
- if (migrate_platform_irqs(cpu)) {
- set_cpu_online(cpu, true);
- return -EBUSY;
- }
-
- remove_siblinginfo(cpu);
- fixup_irqs();
- local_flush_tlb_all();
- cpumask_clear_cpu(cpu, &cpu_callin_map);
- return 0;
-}
-
-void __cpu_die(unsigned int cpu)
-{
- unsigned int i;
-
- for (i = 0; i < 100; i++) {
- /* They ack this in play_dead by setting CPU_DEAD */
- if (per_cpu(cpu_state, cpu) == CPU_DEAD)
- {
- printk ("CPU %d is now offline\n", cpu);
- return;
- }
- msleep(100);
- }
- printk(KERN_ERR "CPU %u didn't die...\n", cpu);
-}
-#endif /* CONFIG_HOTPLUG_CPU */
-
-void
-smp_cpus_done (unsigned int dummy)
-{
- int cpu;
- unsigned long bogosum = 0;
-
- /*
- * Allow the user to impress friends.
- */
-
- for_each_online_cpu(cpu) {
- bogosum += cpu_data(cpu)->loops_per_jiffy;
- }
-
- printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
- (int)num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
-}
-
-static inline void set_cpu_sibling_map(int cpu)
-{
- int i;
-
- for_each_online_cpu(i) {
- if ((cpu_data(cpu)->socket_id == cpu_data(i)->socket_id)) {
- cpumask_set_cpu(i, &cpu_core_map[cpu]);
- cpumask_set_cpu(cpu, &cpu_core_map[i]);
- if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) {
- cpumask_set_cpu(i,
- &per_cpu(cpu_sibling_map, cpu));
- cpumask_set_cpu(cpu,
- &per_cpu(cpu_sibling_map, i));
- }
- }
- }
-}
-
-int
-__cpu_up(unsigned int cpu, struct task_struct *tidle)
-{
- int ret;
- int sapicid;
-
- sapicid = ia64_cpu_to_sapicid[cpu];
- if (sapicid == -1)
- return -EINVAL;
-
- /*
- * Already booted cpu? not valid anymore since we dont
- * do idle loop tightspin anymore.
- */
- if (cpumask_test_cpu(cpu, &cpu_callin_map))
- return -EINVAL;
-
- per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
- /* Processor goes to start_secondary(), sets online flag */
- ret = do_boot_cpu(sapicid, cpu, tidle);
- if (ret < 0)
- return ret;
-
- if (cpu_data(cpu)->threads_per_core == 1 &&
- cpu_data(cpu)->cores_per_socket == 1) {
- cpumask_set_cpu(cpu, &per_cpu(cpu_sibling_map, cpu));
- cpumask_set_cpu(cpu, &cpu_core_map[cpu]);
- return 0;
- }
-
- set_cpu_sibling_map(cpu);
-
- return 0;
-}
-
-/*
- * Assume that CPUs have been discovered by some platform-dependent interface. For
- * SoftSDV/Lion, that would be ACPI.
- *
- * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP().
- */
-void __init
-init_smp_config(void)
-{
- struct fptr {
- unsigned long fp;
- unsigned long gp;
- } *ap_startup;
- long sal_ret;
-
- /* Tell SAL where to drop the APs. */
- ap_startup = (struct fptr *) start_ap;
- sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
- ia64_tpa(ap_startup->fp), ia64_tpa(ap_startup->gp), 0, 0, 0, 0);
- if (sal_ret < 0)
- printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n",
- ia64_sal_strerror(sal_ret));
-}
-
-/*
- * identify_siblings(cpu) gets called from identify_cpu. This populates the
- * information related to logical execution units in per_cpu_data structure.
- */
-void identify_siblings(struct cpuinfo_ia64 *c)
-{
- long status;
- u16 pltid;
- pal_logical_to_physical_t info;
-
- status = ia64_pal_logical_to_phys(-1, &info);
- if (status != PAL_STATUS_SUCCESS) {
- if (status != PAL_STATUS_UNIMPLEMENTED) {
- printk(KERN_ERR
- "ia64_pal_logical_to_phys failed with %ld\n",
- status);
- return;
- }
-
- info.overview_ppid = 0;
- info.overview_cpp = 1;
- info.overview_tpc = 1;
- }
-
- status = ia64_sal_physical_id_info(&pltid);
- if (status != PAL_STATUS_SUCCESS) {
- if (status != PAL_STATUS_UNIMPLEMENTED)
- printk(KERN_ERR
- "ia64_sal_pltid failed with %ld\n",
- status);
- return;
- }
-
- c->socket_id = (pltid << 8) | info.overview_ppid;
-
- if (info.overview_cpp == 1 && info.overview_tpc == 1)
- return;
-
- c->cores_per_socket = info.overview_cpp;
- c->threads_per_core = info.overview_tpc;
- c->num_log = info.overview_num_log;
-
- c->core_id = info.log1_cid;
- c->thread_id = info.log1_tid;
-}
-
-/*
- * returns non zero, if multi-threading is enabled
- * on at least one physical package. Due to hotplug cpu
- * and (maxcpus=), all threads may not necessarily be enabled
- * even though the processor supports multi-threading.
- */
-int is_multithreading_enabled(void)
-{
- int i, j;
-
- for_each_present_cpu(i) {
- for_each_present_cpu(j) {
- if (j == i)
- continue;
- if ((cpu_data(j)->socket_id == cpu_data(i)->socket_id)) {
- if (cpu_data(j)->core_id == cpu_data(i)->core_id)
- return 1;
- }
- }
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(is_multithreading_enabled);
diff --git a/arch/ia64/kernel/stacktrace.c b/arch/ia64/kernel/stacktrace.c
deleted file mode 100644
index 6e583a6bd2f6..000000000000
--- a/arch/ia64/kernel/stacktrace.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * arch/ia64/kernel/stacktrace.c
- *
- * Stack trace management functions
- *
- */
-#include <linux/sched.h>
-#include <linux/stacktrace.h>
-#include <linux/module.h>
-
-static void
-ia64_do_save_stack(struct unw_frame_info *info, void *arg)
-{
- struct stack_trace *trace = arg;
- unsigned long ip;
- int skip = trace->skip;
-
- trace->nr_entries = 0;
- do {
- unw_get_ip(info, &ip);
- if (ip == 0)
- break;
- if (skip == 0) {
- trace->entries[trace->nr_entries++] = ip;
- if (trace->nr_entries == trace->max_entries)
- break;
- } else
- skip--;
- } while (unw_unwind(info) >= 0);
-}
-
-/*
- * Save stack-backtrace addresses into a stack_trace buffer.
- */
-void save_stack_trace(struct stack_trace *trace)
-{
- unw_init_running(ia64_do_save_stack, trace);
-}
-EXPORT_SYMBOL(save_stack_trace);
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
deleted file mode 100644
index eb561cc93632..000000000000
--- a/arch/ia64/kernel/sys_ia64.c
+++ /dev/null
@@ -1,197 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file contains various system calls that have different calling
- * conventions on different platforms.
- *
- * Copyright (C) 1999-2000, 2002-2003, 2005 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/sched.h>
-#include <linux/sched/mm.h>
-#include <linux/sched/task_stack.h>
-#include <linux/shm.h>
-#include <linux/file.h> /* doh, must come after sched.h... */
-#include <linux/smp.h>
-#include <linux/syscalls.h>
-#include <linux/highuid.h>
-#include <linux/hugetlb.h>
-
-#include <asm/shmparam.h>
-#include <linux/uaccess.h>
-
-unsigned long
-arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len,
- unsigned long pgoff, unsigned long flags)
-{
- long map_shared = (flags & MAP_SHARED);
- unsigned long align_mask = 0;
- struct mm_struct *mm = current->mm;
- struct vm_unmapped_area_info info;
-
- if (len > RGN_MAP_LIMIT)
- return -ENOMEM;
-
- /* handle fixed mapping: prevent overlap with huge pages */
- if (flags & MAP_FIXED) {
- if (is_hugepage_only_range(mm, addr, len))
- return -EINVAL;
- return addr;
- }
-
-#ifdef CONFIG_HUGETLB_PAGE
- if (REGION_NUMBER(addr) == RGN_HPAGE)
- addr = 0;
-#endif
- if (!addr)
- addr = TASK_UNMAPPED_BASE;
-
- if (map_shared && (TASK_SIZE > 0xfffffffful))
- /*
- * For 64-bit tasks, align shared segments to 1MB to avoid potential
- * performance penalty due to virtual aliasing (see ASDM). For 32-bit
- * tasks, we prefer to avoid exhausting the address space too quickly by
- * limiting alignment to a single page.
- */
- align_mask = PAGE_MASK & (SHMLBA - 1);
-
- info.flags = 0;
- info.length = len;
- info.low_limit = addr;
- info.high_limit = TASK_SIZE;
- info.align_mask = align_mask;
- info.align_offset = pgoff << PAGE_SHIFT;
- return vm_unmapped_area(&info);
-}
-
-asmlinkage long
-ia64_getpriority (int which, int who)
-{
- long prio;
-
- prio = sys_getpriority(which, who);
- if (prio >= 0) {
- force_successful_syscall_return();
- prio = 20 - prio;
- }
- return prio;
-}
-
-/* XXX obsolete, but leave it here until the old libc is gone... */
-asmlinkage unsigned long
-sys_getpagesize (void)
-{
- return PAGE_SIZE;
-}
-
-asmlinkage unsigned long
-ia64_brk (unsigned long brk)
-{
- unsigned long retval = sys_brk(brk);
- force_successful_syscall_return();
- return retval;
-}
-
-/*
- * On IA-64, we return the two file descriptors in ret0 and ret1 (r8
- * and r9) as this is faster than doing a copy_to_user().
- */
-asmlinkage long
-sys_ia64_pipe (void)
-{
- struct pt_regs *regs = task_pt_regs(current);
- int fd[2];
- int retval;
-
- retval = do_pipe_flags(fd, 0);
- if (retval)
- goto out;
- retval = fd[0];
- regs->r9 = fd[1];
- out:
- return retval;
-}
-
-int ia64_mmap_check(unsigned long addr, unsigned long len,
- unsigned long flags)
-{
- unsigned long roff;
-
- /*
- * Don't permit mappings into unmapped space, the virtual page table
- * of a region, or across a region boundary. Note: RGN_MAP_LIMIT is
- * equal to 2^n-PAGE_SIZE (for some integer n <= 61) and len > 0.
- */
- roff = REGION_OFFSET(addr);
- if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len)))
- return -EINVAL;
- return 0;
-}
-
-/*
- * mmap2() is like mmap() except that the offset is expressed in units
- * of PAGE_SIZE (instead of bytes). This allows to mmap2() (pieces
- * of) files that are larger than the address space of the CPU.
- */
-asmlinkage unsigned long
-sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
-{
- addr = ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
- if (!IS_ERR_VALUE(addr))
- force_successful_syscall_return();
- return addr;
-}
-
-asmlinkage unsigned long
-sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, long off)
-{
- if (offset_in_page(off) != 0)
- return -EINVAL;
-
- addr = ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
- if (!IS_ERR_VALUE(addr))
- force_successful_syscall_return();
- return addr;
-}
-
-asmlinkage unsigned long
-ia64_mremap (unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags,
- unsigned long new_addr)
-{
- addr = sys_mremap(addr, old_len, new_len, flags, new_addr);
- if (!IS_ERR_VALUE(addr))
- force_successful_syscall_return();
- return addr;
-}
-
-asmlinkage long
-ia64_clock_getres(const clockid_t which_clock, struct __kernel_timespec __user *tp)
-{
- struct timespec64 rtn_tp;
- s64 tick_ns;
-
- /*
- * ia64's clock_gettime() syscall is implemented as a vdso call
- * fsys_clock_gettime(). Currently it handles only
- * CLOCK_REALTIME and CLOCK_MONOTONIC. Both are based on
- * 'ar.itc' counter which gets incremented at a constant
- * frequency. It's usually 400MHz, ~2.5x times slower than CPU
- * clock frequency. Which is almost a 1ns hrtimer, but not quite.
- *
- * Let's special-case these timers to report correct precision
- * based on ITC frequency and not HZ frequency for supported
- * clocks.
- */
- switch (which_clock) {
- case CLOCK_REALTIME:
- case CLOCK_MONOTONIC:
- tick_ns = DIV_ROUND_UP(NSEC_PER_SEC, local_cpu_data->itc_freq);
- rtn_tp = ns_to_timespec64(tick_ns);
- return put_timespec64(&rtn_tp, tp);
- }
-
- return sys_clock_getres(which_clock, tp);
-}
diff --git a/arch/ia64/kernel/syscalls/Makefile b/arch/ia64/kernel/syscalls/Makefile
deleted file mode 100644
index d009f927a048..000000000000
--- a/arch/ia64/kernel/syscalls/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-kapi := arch/$(SRCARCH)/include/generated/asm
-uapi := arch/$(SRCARCH)/include/generated/uapi/asm
-
-$(shell mkdir -p $(uapi) $(kapi))
-
-syscall := $(src)/syscall.tbl
-syshdr := $(srctree)/scripts/syscallhdr.sh
-systbl := $(srctree)/scripts/syscalltbl.sh
-
-quiet_cmd_syshdr = SYSHDR $@
- cmd_syshdr = $(CONFIG_SHELL) $(syshdr) --emit-nr --offset __NR_Linux $< $@
-
-quiet_cmd_systbl = SYSTBL $@
- cmd_systbl = $(CONFIG_SHELL) $(systbl) $< $@
-
-$(uapi)/unistd_64.h: $(syscall) $(syshdr) FORCE
- $(call if_changed,syshdr)
-
-$(kapi)/syscall_table.h: $(syscall) $(systbl) FORCE
- $(call if_changed,systbl)
-
-uapisyshdr-y += unistd_64.h
-kapisyshdr-y += syscall_table.h
-
-uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y))
-kapisyshdr-y := $(addprefix $(kapi)/, $(kapisyshdr-y))
-targets += $(addprefix ../../../../, $(uapisyshdr-y) $(kapisyshdr-y))
-
-PHONY += all
-all: $(uapisyshdr-y) $(kapisyshdr-y)
- @:
diff --git a/arch/ia64/kernel/syscalls/syscall.tbl b/arch/ia64/kernel/syscalls/syscall.tbl
deleted file mode 100644
index 81375ea78288..000000000000
--- a/arch/ia64/kernel/syscalls/syscall.tbl
+++ /dev/null
@@ -1,378 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
-#
-# Linux system call numbers and entry vectors for ia64
-#
-# The format is:
-# <number> <abi> <name> <entry point>
-#
-# Add 1024 to <number> will get the actual system call number
-#
-# The <abi> is always "common" for this file
-#
-0 common ni_syscall sys_ni_syscall
-1 common exit sys_exit
-2 common read sys_read
-3 common write sys_write
-4 common open sys_open
-5 common close sys_close
-6 common creat sys_creat
-7 common link sys_link
-8 common unlink sys_unlink
-9 common execve ia64_execve
-10 common chdir sys_chdir
-11 common fchdir sys_fchdir
-12 common utimes sys_utimes
-13 common mknod sys_mknod
-14 common chmod sys_chmod
-15 common chown sys_chown
-16 common lseek sys_lseek
-17 common getpid sys_getpid
-18 common getppid sys_getppid
-19 common mount sys_mount
-20 common umount2 sys_umount
-21 common setuid sys_setuid
-22 common getuid sys_getuid
-23 common geteuid sys_geteuid
-24 common ptrace sys_ptrace
-25 common access sys_access
-26 common sync sys_sync
-27 common fsync sys_fsync
-28 common fdatasync sys_fdatasync
-29 common kill sys_kill
-30 common rename sys_rename
-31 common mkdir sys_mkdir
-32 common rmdir sys_rmdir
-33 common dup sys_dup
-34 common pipe sys_ia64_pipe
-35 common times sys_times
-36 common brk ia64_brk
-37 common setgid sys_setgid
-38 common getgid sys_getgid
-39 common getegid sys_getegid
-40 common acct sys_acct
-41 common ioctl sys_ioctl
-42 common fcntl sys_fcntl
-43 common umask sys_umask
-44 common chroot sys_chroot
-45 common ustat sys_ustat
-46 common dup2 sys_dup2
-47 common setreuid sys_setreuid
-48 common setregid sys_setregid
-49 common getresuid sys_getresuid
-50 common setresuid sys_setresuid
-51 common getresgid sys_getresgid
-52 common setresgid sys_setresgid
-53 common getgroups sys_getgroups
-54 common setgroups sys_setgroups
-55 common getpgid sys_getpgid
-56 common setpgid sys_setpgid
-57 common setsid sys_setsid
-58 common getsid sys_getsid
-59 common sethostname sys_sethostname
-60 common setrlimit sys_setrlimit
-61 common getrlimit sys_getrlimit
-62 common getrusage sys_getrusage
-63 common gettimeofday sys_gettimeofday
-64 common settimeofday sys_settimeofday
-65 common select sys_select
-66 common poll sys_poll
-67 common symlink sys_symlink
-68 common readlink sys_readlink
-69 common uselib sys_uselib
-70 common swapon sys_swapon
-71 common swapoff sys_swapoff
-72 common reboot sys_reboot
-73 common truncate sys_truncate
-74 common ftruncate sys_ftruncate
-75 common fchmod sys_fchmod
-76 common fchown sys_fchown
-77 common getpriority ia64_getpriority
-78 common setpriority sys_setpriority
-79 common statfs sys_statfs
-80 common fstatfs sys_fstatfs
-81 common gettid sys_gettid
-82 common semget sys_semget
-83 common semop sys_semop
-84 common semctl sys_semctl
-85 common msgget sys_msgget
-86 common msgsnd sys_msgsnd
-87 common msgrcv sys_msgrcv
-88 common msgctl sys_msgctl
-89 common shmget sys_shmget
-90 common shmat sys_shmat
-91 common shmdt sys_shmdt
-92 common shmctl sys_shmctl
-93 common syslog sys_syslog
-94 common setitimer sys_setitimer
-95 common getitimer sys_getitimer
-# 1120 was old_stat
-# 1121 was old_lstat
-# 1122 was old_fstat
-99 common vhangup sys_vhangup
-100 common lchown sys_lchown
-101 common remap_file_pages sys_remap_file_pages
-102 common wait4 sys_wait4
-103 common sysinfo sys_sysinfo
-104 common clone sys_clone
-105 common setdomainname sys_setdomainname
-106 common uname sys_newuname
-107 common adjtimex sys_adjtimex
-# 1132 was create_module
-109 common init_module sys_init_module
-110 common delete_module sys_delete_module
-# 1135 was get_kernel_syms
-# 1136 was query_module
-113 common quotactl sys_quotactl
-114 common bdflush sys_ni_syscall
-115 common sysfs sys_sysfs
-116 common personality sys_personality
-117 common afs_syscall sys_ni_syscall
-118 common setfsuid sys_setfsuid
-119 common setfsgid sys_setfsgid
-120 common getdents sys_getdents
-121 common flock sys_flock
-122 common readv sys_readv
-123 common writev sys_writev
-124 common pread64 sys_pread64
-125 common pwrite64 sys_pwrite64
-126 common _sysctl sys_ni_syscall
-127 common mmap sys_mmap
-128 common munmap sys_munmap
-129 common mlock sys_mlock
-130 common mlockall sys_mlockall
-131 common mprotect sys_mprotect
-132 common mremap ia64_mremap
-133 common msync sys_msync
-134 common munlock sys_munlock
-135 common munlockall sys_munlockall
-136 common sched_getparam sys_sched_getparam
-137 common sched_setparam sys_sched_setparam
-138 common sched_getscheduler sys_sched_getscheduler
-139 common sched_setscheduler sys_sched_setscheduler
-140 common sched_yield sys_sched_yield
-141 common sched_get_priority_max sys_sched_get_priority_max
-142 common sched_get_priority_min sys_sched_get_priority_min
-143 common sched_rr_get_interval sys_sched_rr_get_interval
-144 common nanosleep sys_nanosleep
-145 common nfsservctl sys_ni_syscall
-146 common prctl sys_prctl
-147 common old_getpagesize sys_getpagesize
-148 common mmap2 sys_mmap2
-149 common pciconfig_read sys_pciconfig_read
-150 common pciconfig_write sys_pciconfig_write
-151 common perfmonctl sys_ni_syscall
-152 common sigaltstack sys_sigaltstack
-153 common rt_sigaction sys_rt_sigaction
-154 common rt_sigpending sys_rt_sigpending
-155 common rt_sigprocmask sys_rt_sigprocmask
-156 common rt_sigqueueinfo sys_rt_sigqueueinfo
-157 common rt_sigreturn sys_rt_sigreturn
-158 common rt_sigsuspend sys_rt_sigsuspend
-159 common rt_sigtimedwait sys_rt_sigtimedwait
-160 common getcwd sys_getcwd
-161 common capget sys_capget
-162 common capset sys_capset
-163 common sendfile sys_sendfile64
-164 common getpmsg sys_ni_syscall
-165 common putpmsg sys_ni_syscall
-166 common socket sys_socket
-167 common bind sys_bind
-168 common connect sys_connect
-169 common listen sys_listen
-170 common accept sys_accept
-171 common getsockname sys_getsockname
-172 common getpeername sys_getpeername
-173 common socketpair sys_socketpair
-174 common send sys_send
-175 common sendto sys_sendto
-176 common recv sys_recv
-177 common recvfrom sys_recvfrom
-178 common shutdown sys_shutdown
-179 common setsockopt sys_setsockopt
-180 common getsockopt sys_getsockopt
-181 common sendmsg sys_sendmsg
-182 common recvmsg sys_recvmsg
-183 common pivot_root sys_pivot_root
-184 common mincore sys_mincore
-185 common madvise sys_madvise
-186 common stat sys_newstat
-187 common lstat sys_newlstat
-188 common fstat sys_newfstat
-189 common clone2 sys_clone2
-190 common getdents64 sys_getdents64
-191 common getunwind sys_getunwind
-192 common readahead sys_readahead
-193 common setxattr sys_setxattr
-194 common lsetxattr sys_lsetxattr
-195 common fsetxattr sys_fsetxattr
-196 common getxattr sys_getxattr
-197 common lgetxattr sys_lgetxattr
-198 common fgetxattr sys_fgetxattr
-199 common listxattr sys_listxattr
-200 common llistxattr sys_llistxattr
-201 common flistxattr sys_flistxattr
-202 common removexattr sys_removexattr
-203 common lremovexattr sys_lremovexattr
-204 common fremovexattr sys_fremovexattr
-205 common tkill sys_tkill
-206 common futex sys_futex
-207 common sched_setaffinity sys_sched_setaffinity
-208 common sched_getaffinity sys_sched_getaffinity
-209 common set_tid_address sys_set_tid_address
-210 common fadvise64 sys_fadvise64_64
-211 common tgkill sys_tgkill
-212 common exit_group sys_exit_group
-213 common lookup_dcookie sys_lookup_dcookie
-214 common io_setup sys_io_setup
-215 common io_destroy sys_io_destroy
-216 common io_getevents sys_io_getevents
-217 common io_submit sys_io_submit
-218 common io_cancel sys_io_cancel
-219 common epoll_create sys_epoll_create
-220 common epoll_ctl sys_epoll_ctl
-221 common epoll_wait sys_epoll_wait
-222 common restart_syscall sys_restart_syscall
-223 common semtimedop sys_semtimedop
-224 common timer_create sys_timer_create
-225 common timer_settime sys_timer_settime
-226 common timer_gettime sys_timer_gettime
-227 common timer_getoverrun sys_timer_getoverrun
-228 common timer_delete sys_timer_delete
-229 common clock_settime sys_clock_settime
-230 common clock_gettime sys_clock_gettime
-231 common clock_getres ia64_clock_getres
-232 common clock_nanosleep sys_clock_nanosleep
-233 common fstatfs64 sys_fstatfs64
-234 common statfs64 sys_statfs64
-235 common mbind sys_mbind
-236 common get_mempolicy sys_get_mempolicy
-237 common set_mempolicy sys_set_mempolicy
-238 common mq_open sys_mq_open
-239 common mq_unlink sys_mq_unlink
-240 common mq_timedsend sys_mq_timedsend
-241 common mq_timedreceive sys_mq_timedreceive
-242 common mq_notify sys_mq_notify
-243 common mq_getsetattr sys_mq_getsetattr
-244 common kexec_load sys_kexec_load
-245 common vserver sys_ni_syscall
-246 common waitid sys_waitid
-247 common add_key sys_add_key
-248 common request_key sys_request_key
-249 common keyctl sys_keyctl
-250 common ioprio_set sys_ioprio_set
-251 common ioprio_get sys_ioprio_get
-252 common move_pages sys_move_pages
-253 common inotify_init sys_inotify_init
-254 common inotify_add_watch sys_inotify_add_watch
-255 common inotify_rm_watch sys_inotify_rm_watch
-256 common migrate_pages sys_migrate_pages
-257 common openat sys_openat
-258 common mkdirat sys_mkdirat
-259 common mknodat sys_mknodat
-260 common fchownat sys_fchownat
-261 common futimesat sys_futimesat
-262 common newfstatat sys_newfstatat
-263 common unlinkat sys_unlinkat
-264 common renameat sys_renameat
-265 common linkat sys_linkat
-266 common symlinkat sys_symlinkat
-267 common readlinkat sys_readlinkat
-268 common fchmodat sys_fchmodat
-269 common faccessat sys_faccessat
-270 common pselect6 sys_pselect6
-271 common ppoll sys_ppoll
-272 common unshare sys_unshare
-273 common splice sys_splice
-274 common set_robust_list sys_set_robust_list
-275 common get_robust_list sys_get_robust_list
-276 common sync_file_range sys_sync_file_range
-277 common tee sys_tee
-278 common vmsplice sys_vmsplice
-279 common fallocate sys_fallocate
-280 common getcpu sys_getcpu
-281 common epoll_pwait sys_epoll_pwait
-282 common utimensat sys_utimensat
-283 common signalfd sys_signalfd
-284 common timerfd sys_ni_syscall
-285 common eventfd sys_eventfd
-286 common timerfd_create sys_timerfd_create
-287 common timerfd_settime sys_timerfd_settime
-288 common timerfd_gettime sys_timerfd_gettime
-289 common signalfd4 sys_signalfd4
-290 common eventfd2 sys_eventfd2
-291 common epoll_create1 sys_epoll_create1
-292 common dup3 sys_dup3
-293 common pipe2 sys_pipe2
-294 common inotify_init1 sys_inotify_init1
-295 common preadv sys_preadv
-296 common pwritev sys_pwritev
-297 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
-298 common recvmmsg sys_recvmmsg
-299 common fanotify_init sys_fanotify_init
-300 common fanotify_mark sys_fanotify_mark
-301 common prlimit64 sys_prlimit64
-302 common name_to_handle_at sys_name_to_handle_at
-303 common open_by_handle_at sys_open_by_handle_at
-304 common clock_adjtime sys_clock_adjtime
-305 common syncfs sys_syncfs
-306 common setns sys_setns
-307 common sendmmsg sys_sendmmsg
-308 common process_vm_readv sys_process_vm_readv
-309 common process_vm_writev sys_process_vm_writev
-310 common accept4 sys_accept4
-311 common finit_module sys_finit_module
-312 common sched_setattr sys_sched_setattr
-313 common sched_getattr sys_sched_getattr
-314 common renameat2 sys_renameat2
-315 common getrandom sys_getrandom
-316 common memfd_create sys_memfd_create
-317 common bpf sys_bpf
-318 common execveat sys_execveat
-319 common userfaultfd sys_userfaultfd
-320 common membarrier sys_membarrier
-321 common kcmp sys_kcmp
-322 common mlock2 sys_mlock2
-323 common copy_file_range sys_copy_file_range
-324 common preadv2 sys_preadv2
-325 common pwritev2 sys_pwritev2
-326 common statx sys_statx
-327 common io_pgetevents sys_io_pgetevents
-328 common perf_event_open sys_perf_event_open
-329 common seccomp sys_seccomp
-330 common pkey_mprotect sys_pkey_mprotect
-331 common pkey_alloc sys_pkey_alloc
-332 common pkey_free sys_pkey_free
-333 common rseq sys_rseq
-# 334 through 423 are reserved to sync up with other architectures
-424 common pidfd_send_signal sys_pidfd_send_signal
-425 common io_uring_setup sys_io_uring_setup
-426 common io_uring_enter sys_io_uring_enter
-427 common io_uring_register sys_io_uring_register
-428 common open_tree sys_open_tree
-429 common move_mount sys_move_mount
-430 common fsopen sys_fsopen
-431 common fsconfig sys_fsconfig
-432 common fsmount sys_fsmount
-433 common fspick sys_fspick
-434 common pidfd_open sys_pidfd_open
-# 435 reserved for clone3
-436 common close_range sys_close_range
-437 common openat2 sys_openat2
-438 common pidfd_getfd sys_pidfd_getfd
-439 common faccessat2 sys_faccessat2
-440 common process_madvise sys_process_madvise
-441 common epoll_pwait2 sys_epoll_pwait2
-442 common mount_setattr sys_mount_setattr
-443 common quotactl_fd sys_quotactl_fd
-444 common landlock_create_ruleset sys_landlock_create_ruleset
-445 common landlock_add_rule sys_landlock_add_rule
-446 common landlock_restrict_self sys_landlock_restrict_self
-# 447 reserved for memfd_secret
-448 common process_mrelease sys_process_mrelease
-449 common futex_waitv sys_futex_waitv
-450 common set_mempolicy_home_node sys_set_mempolicy_home_node
-451 common cachestat sys_cachestat
-452 common fchmodat2 sys_fchmodat2
-454 common futex_wake sys_futex_wake
-455 common futex_wait sys_futex_wait
-456 common futex_requeue sys_futex_requeue
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
deleted file mode 100644
index 83ef044b63ef..000000000000
--- a/arch/ia64/kernel/time.c
+++ /dev/null
@@ -1,463 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/ia64/kernel/time.c
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- * David Mosberger <davidm@hpl.hp.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- * Copyright (C) 1999-2000 VA Linux Systems
- * Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com>
- */
-
-#include <linux/cpu.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/profile.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/nmi.h>
-#include <linux/interrupt.h>
-#include <linux/efi.h>
-#include <linux/timex.h>
-#include <linux/timekeeper_internal.h>
-#include <linux/platform_device.h>
-#include <linux/sched/cputime.h>
-
-#include <asm/cputime.h>
-#include <asm/delay.h>
-#include <asm/efi.h>
-#include <asm/hw_irq.h>
-#include <asm/ptrace.h>
-#include <asm/sal.h>
-#include <asm/sections.h>
-
-#include "fsyscall_gtod_data.h"
-#include "irq.h"
-
-static u64 itc_get_cycles(struct clocksource *cs);
-
-struct fsyscall_gtod_data_t fsyscall_gtod_data;
-
-struct itc_jitter_data_t itc_jitter_data;
-
-volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */
-
-#ifdef CONFIG_IA64_DEBUG_IRQ
-
-unsigned long last_cli_ip;
-EXPORT_SYMBOL(last_cli_ip);
-
-#endif
-
-static struct clocksource clocksource_itc = {
- .name = "itc",
- .rating = 350,
- .read = itc_get_cycles,
- .mask = CLOCKSOURCE_MASK(64),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-static struct clocksource *itc_clocksource;
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-
-#include <linux/kernel_stat.h>
-
-extern u64 cycle_to_nsec(u64 cyc);
-
-void vtime_flush(struct task_struct *tsk)
-{
- struct thread_info *ti = task_thread_info(tsk);
- u64 delta;
-
- if (ti->utime)
- account_user_time(tsk, cycle_to_nsec(ti->utime));
-
- if (ti->gtime)
- account_guest_time(tsk, cycle_to_nsec(ti->gtime));
-
- if (ti->idle_time)
- account_idle_time(cycle_to_nsec(ti->idle_time));
-
- if (ti->stime) {
- delta = cycle_to_nsec(ti->stime);
- account_system_index_time(tsk, delta, CPUTIME_SYSTEM);
- }
-
- if (ti->hardirq_time) {
- delta = cycle_to_nsec(ti->hardirq_time);
- account_system_index_time(tsk, delta, CPUTIME_IRQ);
- }
-
- if (ti->softirq_time) {
- delta = cycle_to_nsec(ti->softirq_time);
- account_system_index_time(tsk, delta, CPUTIME_SOFTIRQ);
- }
-
- ti->utime = 0;
- ti->gtime = 0;
- ti->idle_time = 0;
- ti->stime = 0;
- ti->hardirq_time = 0;
- ti->softirq_time = 0;
-}
-
-/*
- * Called from the context switch with interrupts disabled, to charge all
- * accumulated times to the current process, and to prepare accounting on
- * the next process.
- */
-void arch_vtime_task_switch(struct task_struct *prev)
-{
- struct thread_info *pi = task_thread_info(prev);
- struct thread_info *ni = task_thread_info(current);
-
- ni->ac_stamp = pi->ac_stamp;
- ni->ac_stime = ni->ac_utime = 0;
-}
-
-/*
- * Account time for a transition between system, hard irq or soft irq state.
- * Note that this function is called with interrupts enabled.
- */
-static __u64 vtime_delta(struct task_struct *tsk)
-{
- struct thread_info *ti = task_thread_info(tsk);
- __u64 now, delta_stime;
-
- WARN_ON_ONCE(!irqs_disabled());
-
- now = ia64_get_itc();
- delta_stime = now - ti->ac_stamp;
- ti->ac_stamp = now;
-
- return delta_stime;
-}
-
-void vtime_account_kernel(struct task_struct *tsk)
-{
- struct thread_info *ti = task_thread_info(tsk);
- __u64 stime = vtime_delta(tsk);
-
- if (tsk->flags & PF_VCPU)
- ti->gtime += stime;
- else
- ti->stime += stime;
-}
-EXPORT_SYMBOL_GPL(vtime_account_kernel);
-
-void vtime_account_idle(struct task_struct *tsk)
-{
- struct thread_info *ti = task_thread_info(tsk);
-
- ti->idle_time += vtime_delta(tsk);
-}
-
-void vtime_account_softirq(struct task_struct *tsk)
-{
- struct thread_info *ti = task_thread_info(tsk);
-
- ti->softirq_time += vtime_delta(tsk);
-}
-
-void vtime_account_hardirq(struct task_struct *tsk)
-{
- struct thread_info *ti = task_thread_info(tsk);
-
- ti->hardirq_time += vtime_delta(tsk);
-}
-
-#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
-
-static irqreturn_t
-timer_interrupt (int irq, void *dev_id)
-{
- unsigned long new_itm;
-
- if (cpu_is_offline(smp_processor_id())) {
- return IRQ_HANDLED;
- }
-
- new_itm = local_cpu_data->itm_next;
-
- if (!time_after(ia64_get_itc(), new_itm))
- printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
- ia64_get_itc(), new_itm);
-
- while (1) {
- new_itm += local_cpu_data->itm_delta;
-
- legacy_timer_tick(smp_processor_id() == time_keeper_id);
-
- local_cpu_data->itm_next = new_itm;
-
- if (time_after(new_itm, ia64_get_itc()))
- break;
-
- /*
- * Allow IPIs to interrupt the timer loop.
- */
- local_irq_enable();
- local_irq_disable();
- }
-
- do {
- /*
- * If we're too close to the next clock tick for
- * comfort, we increase the safety margin by
- * intentionally dropping the next tick(s). We do NOT
- * update itm.next because that would force us to call
- * xtime_update() which in turn would let our clock run
- * too fast (with the potentially devastating effect
- * of losing monotony of time).
- */
- while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_delta/2))
- new_itm += local_cpu_data->itm_delta;
- ia64_set_itm(new_itm);
- /* double check, in case we got hit by a (slow) PMI: */
- } while (time_after_eq(ia64_get_itc(), new_itm));
- return IRQ_HANDLED;
-}
-
-/*
- * Encapsulate access to the itm structure for SMP.
- */
-void
-ia64_cpu_local_tick (void)
-{
- int cpu = smp_processor_id();
- unsigned long shift = 0, delta;
-
- /* arrange for the cycle counter to generate a timer interrupt: */
- ia64_set_itv(IA64_TIMER_VECTOR);
-
- delta = local_cpu_data->itm_delta;
- /*
- * Stagger the timer tick for each CPU so they don't occur all at (almost) the
- * same time:
- */
- if (cpu) {
- unsigned long hi = 1UL << ia64_fls(cpu);
- shift = (2*(cpu - hi) + 1) * delta/hi/2;
- }
- local_cpu_data->itm_next = ia64_get_itc() + delta + shift;
- ia64_set_itm(local_cpu_data->itm_next);
-}
-
-static int nojitter;
-
-static int __init nojitter_setup(char *str)
-{
- nojitter = 1;
- printk("Jitter checking for ITC timers disabled\n");
- return 1;
-}
-
-__setup("nojitter", nojitter_setup);
-
-
-void ia64_init_itm(void)
-{
- unsigned long platform_base_freq, itc_freq;
- struct pal_freq_ratio itc_ratio, proc_ratio;
- long status, platform_base_drift, itc_drift;
-
- /*
- * According to SAL v2.6, we need to use a SAL call to determine the platform base
- * frequency and then a PAL call to determine the frequency ratio between the ITC
- * and the base frequency.
- */
- status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM,
- &platform_base_freq, &platform_base_drift);
- if (status != 0) {
- printk(KERN_ERR "SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status));
- } else {
- status = ia64_pal_freq_ratios(&proc_ratio, NULL, &itc_ratio);
- if (status != 0)
- printk(KERN_ERR "PAL_FREQ_RATIOS failed with status=%ld\n", status);
- }
- if (status != 0) {
- /* invent "random" values */
- printk(KERN_ERR
- "SAL/PAL failed to obtain frequency info---inventing reasonable values\n");
- platform_base_freq = 100000000;
- platform_base_drift = -1; /* no drift info */
- itc_ratio.num = 3;
- itc_ratio.den = 1;
- }
- if (platform_base_freq < 40000000) {
- printk(KERN_ERR "Platform base frequency %lu bogus---resetting to 75MHz!\n",
- platform_base_freq);
- platform_base_freq = 75000000;
- platform_base_drift = -1;
- }
- if (!proc_ratio.den)
- proc_ratio.den = 1; /* avoid division by zero */
- if (!itc_ratio.den)
- itc_ratio.den = 1; /* avoid division by zero */
-
- itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
-
- local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
- printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%u/%u, "
- "ITC freq=%lu.%03luMHz", smp_processor_id(),
- platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
- itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
-
- if (platform_base_drift != -1) {
- itc_drift = platform_base_drift*itc_ratio.num/itc_ratio.den;
- printk("+/-%ldppm\n", itc_drift);
- } else {
- itc_drift = -1;
- printk("\n");
- }
-
- local_cpu_data->proc_freq = (platform_base_freq*proc_ratio.num)/proc_ratio.den;
- local_cpu_data->itc_freq = itc_freq;
- local_cpu_data->cyc_per_usec = (itc_freq + USEC_PER_SEC/2) / USEC_PER_SEC;
- local_cpu_data->nsec_per_cyc = ((NSEC_PER_SEC<<IA64_NSEC_PER_CYC_SHIFT)
- + itc_freq/2)/itc_freq;
-
- if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
-#ifdef CONFIG_SMP
- /* On IA64 in an SMP configuration ITCs are never accurately synchronized.
- * Jitter compensation requires a cmpxchg which may limit
- * the scalability of the syscalls for retrieving time.
- * The ITC synchronization is usually successful to within a few
- * ITC ticks but this is not a sure thing. If you need to improve
- * timer performance in SMP situations then boot the kernel with the
- * "nojitter" option. However, doing so may result in time fluctuating (maybe
- * even going backward) if the ITC offsets between the individual CPUs
- * are too large.
- */
- if (!nojitter)
- itc_jitter_data.itc_jitter = 1;
-#endif
- } else
- /*
- * ITC is drifty and we have not synchronized the ITCs in smpboot.c.
- * ITC values may fluctuate significantly between processors.
- * Clock should not be used for hrtimers. Mark itc as only
- * useful for boot and testing.
- *
- * Note that jitter compensation is off! There is no point of
- * synchronizing ITCs since they may be large differentials
- * that change over time.
- *
- * The only way to fix this would be to repeatedly sync the
- * ITCs. Until that time we have to avoid ITC.
- */
- clocksource_itc.rating = 50;
-
- /* avoid softlock up message when cpu is unplug and plugged again. */
- touch_softlockup_watchdog();
-
- /* Setup the CPU local timer tick */
- ia64_cpu_local_tick();
-
- if (!itc_clocksource) {
- clocksource_register_hz(&clocksource_itc,
- local_cpu_data->itc_freq);
- itc_clocksource = &clocksource_itc;
- }
-}
-
-static u64 itc_get_cycles(struct clocksource *cs)
-{
- unsigned long lcycle, now, ret;
-
- if (!itc_jitter_data.itc_jitter)
- return get_cycles();
-
- lcycle = itc_jitter_data.itc_lastcycle;
- now = get_cycles();
- if (lcycle && time_after(lcycle, now))
- return lcycle;
-
- /*
- * Keep track of the last timer value returned.
- * In an SMP environment, you could lose out in contention of
- * cmpxchg. If so, your cmpxchg returns new value which the
- * winner of contention updated to. Use the new value instead.
- */
- ret = cmpxchg(&itc_jitter_data.itc_lastcycle, lcycle, now);
- if (unlikely(ret != lcycle))
- return ret;
-
- return now;
-}
-
-void read_persistent_clock64(struct timespec64 *ts)
-{
- efi_gettimeofday(ts);
-}
-
-void __init
-time_init (void)
-{
- register_percpu_irq(IA64_TIMER_VECTOR, timer_interrupt, IRQF_IRQPOLL,
- "timer");
- ia64_init_itm();
-}
-
-/*
- * Generic udelay assumes that if preemption is allowed and the thread
- * migrates to another CPU, that the ITC values are synchronized across
- * all CPUs.
- */
-static void
-ia64_itc_udelay (unsigned long usecs)
-{
- unsigned long start = ia64_get_itc();
- unsigned long end = start + usecs*local_cpu_data->cyc_per_usec;
-
- while (time_before(ia64_get_itc(), end))
- cpu_relax();
-}
-
-void (*ia64_udelay)(unsigned long usecs) = &ia64_itc_udelay;
-
-void
-udelay (unsigned long usecs)
-{
- (*ia64_udelay)(usecs);
-}
-EXPORT_SYMBOL(udelay);
-
-/* IA64 doesn't cache the timezone */
-void update_vsyscall_tz(void)
-{
-}
-
-void update_vsyscall(struct timekeeper *tk)
-{
- write_seqcount_begin(&fsyscall_gtod_data.seq);
-
- /* copy vsyscall data */
- fsyscall_gtod_data.clk_mask = tk->tkr_mono.mask;
- fsyscall_gtod_data.clk_mult = tk->tkr_mono.mult;
- fsyscall_gtod_data.clk_shift = tk->tkr_mono.shift;
- fsyscall_gtod_data.clk_fsys_mmio = tk->tkr_mono.clock->archdata.fsys_mmio;
- fsyscall_gtod_data.clk_cycle_last = tk->tkr_mono.cycle_last;
-
- fsyscall_gtod_data.wall_time.sec = tk->xtime_sec;
- fsyscall_gtod_data.wall_time.snsec = tk->tkr_mono.xtime_nsec;
-
- fsyscall_gtod_data.monotonic_time.sec = tk->xtime_sec
- + tk->wall_to_monotonic.tv_sec;
- fsyscall_gtod_data.monotonic_time.snsec = tk->tkr_mono.xtime_nsec
- + ((u64)tk->wall_to_monotonic.tv_nsec
- << tk->tkr_mono.shift);
-
- /* normalize */
- while (fsyscall_gtod_data.monotonic_time.snsec >=
- (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) {
- fsyscall_gtod_data.monotonic_time.snsec -=
- ((u64)NSEC_PER_SEC) << tk->tkr_mono.shift;
- fsyscall_gtod_data.monotonic_time.sec++;
- }
-
- write_seqcount_end(&fsyscall_gtod_data.seq);
-}
-
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
deleted file mode 100644
index 741863a187a6..000000000000
--- a/arch/ia64/kernel/topology.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * This file contains NUMA specific variables and functions which are used on
- * NUMA machines with contiguous memory.
- * 2002/08/07 Erich Focht <efocht@ess.nec.de>
- * Populate cpu entries in sysfs for non-numa systems as well
- * Intel Corporation - Ashok Raj
- * 02/27/2006 Zhang, Yanmin
- * Populate cpu cache entries in sysfs for cpu cache info
- */
-
-#include <linux/cpu.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/node.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/memblock.h>
-#include <linux/nodemask.h>
-#include <linux/notifier.h>
-#include <linux/export.h>
-#include <asm/mmzone.h>
-#include <asm/numa.h>
-#include <asm/cpu.h>
-
-static struct ia64_cpu *sysfs_cpus;
-
-void arch_fix_phys_package_id(int num, u32 slot)
-{
-#ifdef CONFIG_SMP
- if (cpu_data(num)->socket_id == -1)
- cpu_data(num)->socket_id = slot;
-#endif
-}
-EXPORT_SYMBOL_GPL(arch_fix_phys_package_id);
-
-
-#ifdef CONFIG_HOTPLUG_CPU
-int __ref arch_register_cpu(int num)
-{
- /*
- * If CPEI can be re-targeted or if this is not
- * CPEI target, then it is hotpluggable
- */
- if (can_cpei_retarget() || !is_cpu_cpei_target(num))
- sysfs_cpus[num].cpu.hotpluggable = 1;
- map_cpu_to_node(num, node_cpuid[num].nid);
- return register_cpu(&sysfs_cpus[num].cpu, num);
-}
-EXPORT_SYMBOL(arch_register_cpu);
-
-void __ref arch_unregister_cpu(int num)
-{
- unregister_cpu(&sysfs_cpus[num].cpu);
- unmap_cpu_from_node(num, cpu_to_node(num));
-}
-EXPORT_SYMBOL(arch_unregister_cpu);
-#else
-int __init arch_register_cpu(int num)
-{
- return register_cpu(&sysfs_cpus[num].cpu, num);
-}
-#endif /*CONFIG_HOTPLUG_CPU*/
-
-
-static int __init topology_init(void)
-{
- int i, err = 0;
-
- sysfs_cpus = kcalloc(NR_CPUS, sizeof(struct ia64_cpu), GFP_KERNEL);
- if (!sysfs_cpus)
- panic("kzalloc in topology_init failed - NR_CPUS too big?");
-
- for_each_present_cpu(i) {
- if((err = arch_register_cpu(i)))
- goto out;
- }
-out:
- return err;
-}
-
-subsys_initcall(topology_init);
-
-
-/*
- * Export cpu cache information through sysfs
- */
-
-/*
- * A bunch of string array to get pretty printing
- */
-static const char *cache_types[] = {
- "", /* not used */
- "Instruction",
- "Data",
- "Unified" /* unified */
-};
-
-static const char *cache_mattrib[]={
- "WriteThrough",
- "WriteBack",
- "", /* reserved */
- "" /* reserved */
-};
-
-struct cache_info {
- pal_cache_config_info_t cci;
- cpumask_t shared_cpu_map;
- int level;
- int type;
- struct kobject kobj;
-};
-
-struct cpu_cache_info {
- struct cache_info *cache_leaves;
- int num_cache_leaves;
- struct kobject kobj;
-};
-
-static struct cpu_cache_info all_cpu_cache_info[NR_CPUS];
-#define LEAF_KOBJECT_PTR(x,y) (&all_cpu_cache_info[x].cache_leaves[y])
-
-#ifdef CONFIG_SMP
-static void cache_shared_cpu_map_setup(unsigned int cpu,
- struct cache_info * this_leaf)
-{
- pal_cache_shared_info_t csi;
- int num_shared, i = 0;
- unsigned int j;
-
- if (cpu_data(cpu)->threads_per_core <= 1 &&
- cpu_data(cpu)->cores_per_socket <= 1) {
- cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map);
- return;
- }
-
- if (ia64_pal_cache_shared_info(this_leaf->level,
- this_leaf->type,
- 0,
- &csi) != PAL_STATUS_SUCCESS)
- return;
-
- num_shared = (int) csi.num_shared;
- do {
- for_each_possible_cpu(j)
- if (cpu_data(cpu)->socket_id == cpu_data(j)->socket_id
- && cpu_data(j)->core_id == csi.log1_cid
- && cpu_data(j)->thread_id == csi.log1_tid)
- cpumask_set_cpu(j, &this_leaf->shared_cpu_map);
-
- i++;
- } while (i < num_shared &&
- ia64_pal_cache_shared_info(this_leaf->level,
- this_leaf->type,
- i,
- &csi) == PAL_STATUS_SUCCESS);
-}
-#else
-static void cache_shared_cpu_map_setup(unsigned int cpu,
- struct cache_info * this_leaf)
-{
- cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map);
- return;
-}
-#endif
-
-static ssize_t show_coherency_line_size(struct cache_info *this_leaf,
- char *buf)
-{
- return sprintf(buf, "%u\n", 1 << this_leaf->cci.pcci_line_size);
-}
-
-static ssize_t show_ways_of_associativity(struct cache_info *this_leaf,
- char *buf)
-{
- return sprintf(buf, "%u\n", this_leaf->cci.pcci_assoc);
-}
-
-static ssize_t show_attributes(struct cache_info *this_leaf, char *buf)
-{
- return sprintf(buf,
- "%s\n",
- cache_mattrib[this_leaf->cci.pcci_cache_attr]);
-}
-
-static ssize_t show_size(struct cache_info *this_leaf, char *buf)
-{
- return sprintf(buf, "%uK\n", this_leaf->cci.pcci_cache_size / 1024);
-}
-
-static ssize_t show_number_of_sets(struct cache_info *this_leaf, char *buf)
-{
- unsigned number_of_sets = this_leaf->cci.pcci_cache_size;
- number_of_sets /= this_leaf->cci.pcci_assoc;
- number_of_sets /= 1 << this_leaf->cci.pcci_line_size;
-
- return sprintf(buf, "%u\n", number_of_sets);
-}
-
-static ssize_t show_shared_cpu_map(struct cache_info *this_leaf, char *buf)
-{
- cpumask_t shared_cpu_map;
-
- cpumask_and(&shared_cpu_map,
- &this_leaf->shared_cpu_map, cpu_online_mask);
- return scnprintf(buf, PAGE_SIZE, "%*pb\n",
- cpumask_pr_args(&shared_cpu_map));
-}
-
-static ssize_t show_type(struct cache_info *this_leaf, char *buf)
-{
- int type = this_leaf->type + this_leaf->cci.pcci_unified;
- return sprintf(buf, "%s\n", cache_types[type]);
-}
-
-static ssize_t show_level(struct cache_info *this_leaf, char *buf)
-{
- return sprintf(buf, "%u\n", this_leaf->level);
-}
-
-struct cache_attr {
- struct attribute attr;
- ssize_t (*show)(struct cache_info *, char *);
- ssize_t (*store)(struct cache_info *, const char *, size_t count);
-};
-
-#ifdef define_one_ro
- #undef define_one_ro
-#endif
-#define define_one_ro(_name) \
- static struct cache_attr _name = \
-__ATTR(_name, 0444, show_##_name, NULL)
-
-define_one_ro(level);
-define_one_ro(type);
-define_one_ro(coherency_line_size);
-define_one_ro(ways_of_associativity);
-define_one_ro(size);
-define_one_ro(number_of_sets);
-define_one_ro(shared_cpu_map);
-define_one_ro(attributes);
-
-static struct attribute * cache_default_attrs[] = {
- &type.attr,
- &level.attr,
- &coherency_line_size.attr,
- &ways_of_associativity.attr,
- &attributes.attr,
- &size.attr,
- &number_of_sets.attr,
- &shared_cpu_map.attr,
- NULL
-};
-ATTRIBUTE_GROUPS(cache_default);
-
-#define to_object(k) container_of(k, struct cache_info, kobj)
-#define to_attr(a) container_of(a, struct cache_attr, attr)
-
-static ssize_t ia64_cache_show(struct kobject * kobj, struct attribute * attr, char * buf)
-{
- struct cache_attr *fattr = to_attr(attr);
- struct cache_info *this_leaf = to_object(kobj);
- ssize_t ret;
-
- ret = fattr->show ? fattr->show(this_leaf, buf) : 0;
- return ret;
-}
-
-static const struct sysfs_ops cache_sysfs_ops = {
- .show = ia64_cache_show
-};
-
-static struct kobj_type cache_ktype = {
- .sysfs_ops = &cache_sysfs_ops,
- .default_groups = cache_default_groups,
-};
-
-static struct kobj_type cache_ktype_percpu_entry = {
- .sysfs_ops = &cache_sysfs_ops,
-};
-
-static void cpu_cache_sysfs_exit(unsigned int cpu)
-{
- kfree(all_cpu_cache_info[cpu].cache_leaves);
- all_cpu_cache_info[cpu].cache_leaves = NULL;
- all_cpu_cache_info[cpu].num_cache_leaves = 0;
- memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject));
- return;
-}
-
-static int cpu_cache_sysfs_init(unsigned int cpu)
-{
- unsigned long i, levels, unique_caches;
- pal_cache_config_info_t cci;
- int j;
- long status;
- struct cache_info *this_cache;
- int num_cache_leaves = 0;
-
- if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
- printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status);
- return -1;
- }
-
- this_cache=kcalloc(unique_caches, sizeof(struct cache_info),
- GFP_KERNEL);
- if (this_cache == NULL)
- return -ENOMEM;
-
- for (i=0; i < levels; i++) {
- for (j=2; j >0 ; j--) {
- if ((status=ia64_pal_cache_config_info(i,j, &cci)) !=
- PAL_STATUS_SUCCESS)
- continue;
-
- this_cache[num_cache_leaves].cci = cci;
- this_cache[num_cache_leaves].level = i + 1;
- this_cache[num_cache_leaves].type = j;
-
- cache_shared_cpu_map_setup(cpu,
- &this_cache[num_cache_leaves]);
- num_cache_leaves ++;
- }
- }
-
- all_cpu_cache_info[cpu].cache_leaves = this_cache;
- all_cpu_cache_info[cpu].num_cache_leaves = num_cache_leaves;
-
- memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject));
-
- return 0;
-}
-
-/* Add cache interface for CPU device */
-static int cache_add_dev(unsigned int cpu)
-{
- struct device *sys_dev = get_cpu_device(cpu);
- unsigned long i, j;
- struct cache_info *this_object;
- int retval = 0;
-
- if (all_cpu_cache_info[cpu].kobj.parent)
- return 0;
-
-
- retval = cpu_cache_sysfs_init(cpu);
- if (unlikely(retval < 0))
- return retval;
-
- retval = kobject_init_and_add(&all_cpu_cache_info[cpu].kobj,
- &cache_ktype_percpu_entry, &sys_dev->kobj,
- "%s", "cache");
- if (unlikely(retval < 0)) {
- cpu_cache_sysfs_exit(cpu);
- return retval;
- }
-
- for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) {
- this_object = LEAF_KOBJECT_PTR(cpu,i);
- retval = kobject_init_and_add(&(this_object->kobj),
- &cache_ktype,
- &all_cpu_cache_info[cpu].kobj,
- "index%1lu", i);
- if (unlikely(retval)) {
- for (j = 0; j < i; j++) {
- kobject_put(&(LEAF_KOBJECT_PTR(cpu,j)->kobj));
- }
- kobject_put(&all_cpu_cache_info[cpu].kobj);
- cpu_cache_sysfs_exit(cpu);
- return retval;
- }
- kobject_uevent(&(this_object->kobj), KOBJ_ADD);
- }
- kobject_uevent(&all_cpu_cache_info[cpu].kobj, KOBJ_ADD);
- return retval;
-}
-
-/* Remove cache interface for CPU device */
-static int cache_remove_dev(unsigned int cpu)
-{
- unsigned long i;
-
- for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++)
- kobject_put(&(LEAF_KOBJECT_PTR(cpu,i)->kobj));
-
- if (all_cpu_cache_info[cpu].kobj.parent) {
- kobject_put(&all_cpu_cache_info[cpu].kobj);
- memset(&all_cpu_cache_info[cpu].kobj,
- 0,
- sizeof(struct kobject));
- }
-
- cpu_cache_sysfs_exit(cpu);
-
- return 0;
-}
-
-static int __init cache_sysfs_init(void)
-{
- int ret;
-
- ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "ia64/topology:online",
- cache_add_dev, cache_remove_dev);
- WARN_ON(ret < 0);
- return 0;
-}
-device_initcall(cache_sysfs_init);
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
deleted file mode 100644
index 53735b1d1be3..000000000000
--- a/arch/ia64/kernel/traps.c
+++ /dev/null
@@ -1,612 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Architecture-specific trap handling.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 05/12/00 grao <goutham.rao@intel.com> : added isr in siginfo for SIGFPE
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched/signal.h>
-#include <linux/sched/debug.h>
-#include <linux/tty.h>
-#include <linux/vt_kern.h> /* For unblank_screen() */
-#include <linux/export.h>
-#include <linux/extable.h>
-#include <linux/hardirq.h>
-#include <linux/kprobes.h>
-#include <linux/delay.h> /* for ssleep() */
-#include <linux/kdebug.h>
-#include <linux/uaccess.h>
-
-#include <asm/fpswa.h>
-#include <asm/intrinsics.h>
-#include <asm/processor.h>
-#include <asm/exception.h>
-#include <asm/setup.h>
-
-fpswa_interface_t *fpswa_interface;
-EXPORT_SYMBOL(fpswa_interface);
-
-void __init
-trap_init (void)
-{
- if (ia64_boot_param->fpswa)
- /* FPSWA fixup: make the interface pointer a kernel virtual address: */
- fpswa_interface = __va(ia64_boot_param->fpswa);
-}
-
-int
-die (const char *str, struct pt_regs *regs, long err)
-{
- static struct {
- spinlock_t lock;
- u32 lock_owner;
- int lock_owner_depth;
- } die = {
- .lock = __SPIN_LOCK_UNLOCKED(die.lock),
- .lock_owner = -1,
- .lock_owner_depth = 0
- };
- static int die_counter;
- int cpu = get_cpu();
-
- if (die.lock_owner != cpu) {
- console_verbose();
- spin_lock_irq(&die.lock);
- die.lock_owner = cpu;
- die.lock_owner_depth = 0;
- bust_spinlocks(1);
- }
- put_cpu();
-
- if (++die.lock_owner_depth < 3) {
- printk("%s[%d]: %s %ld [%d]\n",
- current->comm, task_pid_nr(current), str, err, ++die_counter);
- if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
- != NOTIFY_STOP)
- show_regs(regs);
- else
- regs = NULL;
- } else
- printk(KERN_ERR "Recursive die() failure, output suppressed\n");
-
- bust_spinlocks(0);
- die.lock_owner = -1;
- add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
- spin_unlock_irq(&die.lock);
-
- if (!regs)
- return 1;
-
- if (panic_on_oops)
- panic("Fatal exception");
-
- make_task_dead(SIGSEGV);
- return 0;
-}
-
-int
-die_if_kernel (char *str, struct pt_regs *regs, long err)
-{
- if (!user_mode(regs))
- return die(str, regs, err);
- return 0;
-}
-
-void
-__kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
-{
- int sig, code;
-
- switch (break_num) {
- case 0: /* unknown error (used by GCC for __builtin_abort()) */
- if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
- == NOTIFY_STOP)
- return;
- if (die_if_kernel("bugcheck!", regs, break_num))
- return;
- sig = SIGILL; code = ILL_ILLOPC;
- break;
-
- case 1: /* integer divide by zero */
- sig = SIGFPE; code = FPE_INTDIV;
- break;
-
- case 2: /* integer overflow */
- sig = SIGFPE; code = FPE_INTOVF;
- break;
-
- case 3: /* range check/bounds check */
- sig = SIGFPE; code = FPE_FLTSUB;
- break;
-
- case 4: /* null pointer dereference */
- sig = SIGSEGV; code = SEGV_MAPERR;
- break;
-
- case 5: /* misaligned data */
- sig = SIGSEGV; code = BUS_ADRALN;
- break;
-
- case 6: /* decimal overflow */
- sig = SIGFPE; code = __FPE_DECOVF;
- break;
-
- case 7: /* decimal divide by zero */
- sig = SIGFPE; code = __FPE_DECDIV;
- break;
-
- case 8: /* packed decimal error */
- sig = SIGFPE; code = __FPE_DECERR;
- break;
-
- case 9: /* invalid ASCII digit */
- sig = SIGFPE; code = __FPE_INVASC;
- break;
-
- case 10: /* invalid decimal digit */
- sig = SIGFPE; code = __FPE_INVDEC;
- break;
-
- case 11: /* paragraph stack overflow */
- sig = SIGSEGV; code = __SEGV_PSTKOVF;
- break;
-
- case 0x3f000 ... 0x3ffff: /* bundle-update in progress */
- sig = SIGILL; code = __ILL_BNDMOD;
- break;
-
- default:
- if ((break_num < 0x40000 || break_num > 0x100000)
- && die_if_kernel("Bad break", regs, break_num))
- return;
-
- if (break_num < 0x80000) {
- sig = SIGILL; code = __ILL_BREAK;
- } else {
- if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP)
- == NOTIFY_STOP)
- return;
- sig = SIGTRAP; code = TRAP_BRKPT;
- }
- }
- force_sig_fault(sig, code,
- (void __user *) (regs->cr_iip + ia64_psr(regs)->ri),
- break_num, 0 /* clear __ISR_VALID */, 0);
-}
-
-/*
- * disabled_fph_fault() is called when a user-level process attempts to access f32..f127
- * and it doesn't own the fp-high register partition. When this happens, we save the
- * current fph partition in the task_struct of the fpu-owner (if necessary) and then load
- * the fp-high partition of the current task (if necessary). Note that the kernel has
- * access to fph by the time we get here, as the IVT's "Disabled FP-Register" handler takes
- * care of clearing psr.dfh.
- */
-static inline void
-disabled_fph_fault (struct pt_regs *regs)
-{
- struct ia64_psr *psr = ia64_psr(regs);
-
- /* first, grant user-level access to fph partition: */
- psr->dfh = 0;
-
- /*
- * Make sure that no other task gets in on this processor
- * while we're claiming the FPU
- */
- preempt_disable();
-#ifndef CONFIG_SMP
- {
- struct task_struct *fpu_owner
- = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
-
- if (ia64_is_local_fpu_owner(current)) {
- preempt_enable_no_resched();
- return;
- }
-
- if (fpu_owner)
- ia64_flush_fph(fpu_owner);
- }
-#endif /* !CONFIG_SMP */
- ia64_set_local_fpu_owner(current);
- if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
- __ia64_load_fpu(current->thread.fph);
- psr->mfh = 0;
- } else {
- __ia64_init_fpu();
- /*
- * Set mfh because the state in thread.fph does not match the state in
- * the fph partition.
- */
- psr->mfh = 1;
- }
- preempt_enable_no_resched();
-}
-
-static inline int
-fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs,
- struct pt_regs *regs)
-{
- fp_state_t fp_state;
- fpswa_ret_t ret;
-
- if (!fpswa_interface)
- return -1;
-
- memset(&fp_state, 0, sizeof(fp_state_t));
-
- /*
- * compute fp_state. only FP registers f6 - f11 are used by the
- * kernel, so set those bits in the mask and set the low volatile
- * pointer to point to these registers.
- */
- fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */
-
- fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) &regs->f6;
- /*
- * unsigned long (*EFI_FPSWA) (
- * unsigned long trap_type,
- * void *Bundle,
- * unsigned long *pipsr,
- * unsigned long *pfsr,
- * unsigned long *pisr,
- * unsigned long *ppreds,
- * unsigned long *pifs,
- * void *fp_state);
- */
- ret = (*fpswa_interface->fpswa)((unsigned long) fp_fault, bundle,
- (unsigned long *) ipsr, (unsigned long *) fpsr,
- (unsigned long *) isr, (unsigned long *) pr,
- (unsigned long *) ifs, &fp_state);
-
- return ret.status;
-}
-
-struct fpu_swa_msg {
- unsigned long count;
- unsigned long time;
-};
-static DEFINE_PER_CPU(struct fpu_swa_msg, cpulast);
-DECLARE_PER_CPU(struct fpu_swa_msg, cpulast);
-static struct fpu_swa_msg last __cacheline_aligned;
-
-
-/*
- * Handle floating-point assist faults and traps.
- */
-static int
-handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
-{
- long exception, bundle[2];
- unsigned long fault_ip;
-
- fault_ip = regs->cr_iip;
- if (!fp_fault && (ia64_psr(regs)->ri == 0))
- fault_ip -= 16;
- if (copy_from_user(bundle, (void __user *) fault_ip, sizeof(bundle)))
- return -1;
-
- if (!(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
- unsigned long count, current_jiffies = jiffies;
- struct fpu_swa_msg *cp = this_cpu_ptr(&cpulast);
-
- if (unlikely(current_jiffies > cp->time))
- cp->count = 0;
- if (unlikely(cp->count < 5)) {
- cp->count++;
- cp->time = current_jiffies + 5 * HZ;
-
- /* minimize races by grabbing a copy of count BEFORE checking last.time. */
- count = last.count;
- barrier();
-
- /*
- * Lower 4 bits are used as a count. Upper bits are a sequence
- * number that is updated when count is reset. The cmpxchg will
- * fail is seqno has changed. This minimizes multiple cpus
- * resetting the count.
- */
- if (current_jiffies > last.time)
- (void) cmpxchg_acq(&last.count, count, 16 + (count & ~15));
-
- /* used fetchadd to atomically update the count */
- if ((last.count & 15) < 5 && (ia64_fetchadd(1, &last.count, acq) & 15) < 5) {
- last.time = current_jiffies + 5 * HZ;
- printk(KERN_WARNING
- "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
- current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
- }
- }
- }
-
- exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
- &regs->cr_ifs, regs);
- if (fp_fault) {
- if (exception == 0) {
- /* emulation was successful */
- ia64_increment_ip(regs);
- } else if (exception == -1) {
- printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
- return -1;
- } else {
- /* is next instruction a trap? */
- int si_code;
-
- if (exception & 2) {
- ia64_increment_ip(regs);
- }
- si_code = FPE_FLTUNK; /* default code */
- if (isr & 0x11) {
- si_code = FPE_FLTINV;
- } else if (isr & 0x22) {
- /* denormal operand gets the same si_code as underflow
- * see arch/i386/kernel/traps.c:math_error() */
- si_code = FPE_FLTUND;
- } else if (isr & 0x44) {
- si_code = FPE_FLTDIV;
- }
- force_sig_fault(SIGFPE, si_code,
- (void __user *) (regs->cr_iip + ia64_psr(regs)->ri),
- 0, __ISR_VALID, isr);
- }
- } else {
- if (exception == -1) {
- printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
- return -1;
- } else if (exception != 0) {
- /* raise exception */
- int si_code;
-
- si_code = FPE_FLTUNK; /* default code */
- if (isr & 0x880) {
- si_code = FPE_FLTOVF;
- } else if (isr & 0x1100) {
- si_code = FPE_FLTUND;
- } else if (isr & 0x2200) {
- si_code = FPE_FLTRES;
- }
- force_sig_fault(SIGFPE, si_code,
- (void __user *) (regs->cr_iip + ia64_psr(regs)->ri),
- 0, __ISR_VALID, isr);
- }
- }
- return 0;
-}
-
-struct illegal_op_return {
- unsigned long fkt, arg1, arg2, arg3;
-};
-
-struct illegal_op_return
-ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
- long arg4, long arg5, long arg6, long arg7,
- struct pt_regs regs)
-{
- struct illegal_op_return rv;
- char buf[128];
-
-#ifdef CONFIG_IA64_BRL_EMU
- {
- extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);
-
- rv = ia64_emulate_brl(&regs, ec);
- if (rv.fkt != (unsigned long) -1)
- return rv;
- }
-#endif
-
- sprintf(buf, "IA-64 Illegal operation fault");
- rv.fkt = 0;
- if (die_if_kernel(buf, &regs, 0))
- return rv;
-
- force_sig_fault(SIGILL, ILL_ILLOPC,
- (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri),
- 0, 0, 0);
- return rv;
-}
-
-void __kprobes
-ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
- unsigned long iim, unsigned long itir, long arg5, long arg6,
- long arg7, struct pt_regs regs)
-{
- unsigned long code, error = isr, iip;
- char buf[128];
- int result, sig, si_code;
- static const char *reason[] = {
- "IA-64 Illegal Operation fault",
- "IA-64 Privileged Operation fault",
- "IA-64 Privileged Register fault",
- "IA-64 Reserved Register/Field fault",
- "Disabled Instruction Set Transition fault",
- "Unknown fault 5", "Unknown fault 6", "Unknown fault 7", "Illegal Hazard fault",
- "Unknown fault 9", "Unknown fault 10", "Unknown fault 11", "Unknown fault 12",
- "Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
- };
-
- if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
- /*
- * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
- * the lfetch.
- */
- ia64_psr(&regs)->ed = 1;
- return;
- }
-
- iip = regs.cr_iip + ia64_psr(&regs)->ri;
-
- switch (vector) {
- case 24: /* General Exception */
- code = (isr >> 4) & 0xf;
- sprintf(buf, "General Exception: %s%s", reason[code],
- (code == 3) ? ((isr & (1UL << 37))
- ? " (RSE access)" : " (data access)") : "");
- if (code == 8) {
-# ifdef CONFIG_IA64_PRINT_HAZARDS
- printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
- current->comm, task_pid_nr(current),
- regs.cr_iip + ia64_psr(&regs)->ri, regs.pr);
-# endif
- return;
- }
- break;
-
- case 25: /* Disabled FP-Register */
- if (isr & 2) {
- disabled_fph_fault(&regs);
- return;
- }
- sprintf(buf, "Disabled FPL fault---not supposed to happen!");
- break;
-
- case 26: /* NaT Consumption */
- if (user_mode(&regs)) {
- void __user *addr;
-
- if (((isr >> 4) & 0xf) == 2) {
- /* NaT page consumption */
- sig = SIGSEGV;
- code = SEGV_ACCERR;
- addr = (void __user *) ifa;
- } else {
- /* register NaT consumption */
- sig = SIGILL;
- code = ILL_ILLOPN;
- addr = (void __user *) (regs.cr_iip
- + ia64_psr(&regs)->ri);
- }
- force_sig_fault(sig, code, addr,
- vector, __ISR_VALID, isr);
- return;
- } else if (ia64_done_with_exception(&regs))
- return;
- sprintf(buf, "NaT consumption");
- break;
-
- case 31: /* Unsupported Data Reference */
- if (user_mode(&regs)) {
- force_sig_fault(SIGILL, ILL_ILLOPN, (void __user *) iip,
- vector, __ISR_VALID, isr);
- return;
- }
- sprintf(buf, "Unsupported data reference");
- break;
-
- case 29: /* Debug */
- case 35: /* Taken Branch Trap */
- case 36: /* Single Step Trap */
- if (fsys_mode(current, &regs)) {
- extern char __kernel_syscall_via_break[];
- /*
- * Got a trap in fsys-mode: Taken Branch Trap
- * and Single Step trap need special handling;
- * Debug trap is ignored (we disable it here
- * and re-enable it in the lower-privilege trap).
- */
- if (unlikely(vector == 29)) {
- set_thread_flag(TIF_DB_DISABLED);
- ia64_psr(&regs)->db = 0;
- ia64_psr(&regs)->lp = 1;
- return;
- }
- /* re-do the system call via break 0x100000: */
- regs.cr_iip = (unsigned long) __kernel_syscall_via_break;
- ia64_psr(&regs)->ri = 0;
- ia64_psr(&regs)->cpl = 3;
- return;
- }
- switch (vector) {
- default:
- case 29:
- si_code = TRAP_HWBKPT;
-#ifdef CONFIG_ITANIUM
- /*
- * Erratum 10 (IFA may contain incorrect address) now has
- * "NoFix" status. There are no plans for fixing this.
- */
- if (ia64_psr(&regs)->is == 0)
- ifa = regs.cr_iip;
-#endif
- break;
- case 35: si_code = TRAP_BRANCH; ifa = 0; break;
- case 36: si_code = TRAP_TRACE; ifa = 0; break;
- }
- if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, si_code, SIGTRAP)
- == NOTIFY_STOP)
- return;
- force_sig_fault(SIGTRAP, si_code, (void __user *) ifa,
- 0, __ISR_VALID, isr);
- return;
-
- case 32: /* fp fault */
- case 33: /* fp trap */
- result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, isr);
- if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
- force_sig_fault(SIGFPE, FPE_FLTINV, (void __user *) iip,
- 0, __ISR_VALID, isr);
- }
- return;
-
- case 34:
- if (isr & 0x2) {
- /* Lower-Privilege Transfer Trap */
-
- /* If we disabled debug traps during an fsyscall,
- * re-enable them here.
- */
- if (test_thread_flag(TIF_DB_DISABLED)) {
- clear_thread_flag(TIF_DB_DISABLED);
- ia64_psr(&regs)->db = 1;
- }
-
- /*
- * Just clear PSR.lp and then return immediately:
- * all the interesting work (e.g., signal delivery)
- * is done in the kernel exit path.
- */
- ia64_psr(&regs)->lp = 0;
- return;
- } else {
- /* Unimplemented Instr. Address Trap */
- if (user_mode(&regs)) {
- force_sig_fault(SIGILL, ILL_BADIADDR,
- (void __user *) iip,
- 0, 0, 0);
- return;
- }
- sprintf(buf, "Unimplemented Instruction Address fault");
- }
- break;
-
- case 45:
- printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
- printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
- iip, ifa, isr);
- force_sig(SIGSEGV);
- return;
-
- case 46:
- printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
- printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
- iip, ifa, isr, iim);
- force_sig(SIGSEGV);
- return;
-
- case 47:
- sprintf(buf, "IA-32 Interruption Fault (int 0x%lx)", isr >> 16);
- break;
-
- default:
- sprintf(buf, "Fault %lu", vector);
- break;
- }
- if (!die_if_kernel(buf, &regs, error))
- force_sig(SIGILL);
-}
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
deleted file mode 100644
index 0acb5a0cd7ab..000000000000
--- a/arch/ia64/kernel/unaligned.c
+++ /dev/null
@@ -1,1560 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Architecture-specific unaligned trap handling.
- *
- * Copyright (C) 1999-2002, 2004 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 2002/12/09 Fix rotating register handling (off-by-1 error, missing fr-rotation). Fix
- * get_rse_reg() to not leak kernel bits to user-level (reading an out-of-frame
- * stacked register returns an undefined value; it does NOT trigger a
- * "rsvd register fault").
- * 2001/10/11 Fix unaligned access to rotating registers in s/w pipelined loops.
- * 2001/08/13 Correct size of extended floats (float_fsz) from 16 to 10 bytes.
- * 2001/01/17 Add support emulation of unaligned kernel accesses.
- */
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/tty.h>
-#include <linux/extable.h>
-#include <linux/ratelimit.h>
-#include <linux/uaccess.h>
-
-#include <asm/intrinsics.h>
-#include <asm/processor.h>
-#include <asm/rse.h>
-#include <asm/exception.h>
-#include <asm/unaligned.h>
-
-extern int die_if_kernel(char *str, struct pt_regs *regs, long err);
-
-#undef DEBUG_UNALIGNED_TRAP
-
-#ifdef DEBUG_UNALIGNED_TRAP
-# define DPRINT(a...) do { printk("%s %u: ", __func__, __LINE__); printk (a); } while (0)
-# define DDUMP(str,vp,len) dump(str, vp, len)
-
-static void
-dump (const char *str, void *vp, size_t len)
-{
- unsigned char *cp = vp;
- int i;
-
- printk("%s", str);
- for (i = 0; i < len; ++i)
- printk (" %02x", *cp++);
- printk("\n");
-}
-#else
-# define DPRINT(a...)
-# define DDUMP(str,vp,len)
-#endif
-
-#define IA64_FIRST_STACKED_GR 32
-#define IA64_FIRST_ROTATING_FR 32
-#define SIGN_EXT9 0xffffffffffffff00ul
-
-/*
- * sysctl settable hook which tells the kernel whether to honor the
- * IA64_THREAD_UAC_NOPRINT prctl. Because this is user settable, we want
- * to allow the super user to enable/disable this for security reasons
- * (i.e. don't allow attacker to fill up logs with unaligned accesses).
- */
-int no_unaligned_warning;
-int unaligned_dump_stack;
-
-/*
- * For M-unit:
- *
- * opcode | m | x6 |
- * --------|------|---------|
- * [40-37] | [36] | [35:30] |
- * --------|------|---------|
- * 4 | 1 | 6 | = 11 bits
- * --------------------------
- * However bits [31:30] are not directly useful to distinguish between
- * load/store so we can use [35:32] instead, which gives the following
- * mask ([40:32]) using 9 bits. The 'e' comes from the fact that we defer
- * checking the m-bit until later in the load/store emulation.
- */
-#define IA64_OPCODE_MASK 0x1ef
-#define IA64_OPCODE_SHIFT 32
-
-/*
- * Table C-28 Integer Load/Store
- *
- * We ignore [35:32]= 0x6, 0x7, 0xE, 0xF
- *
- * ld8.fill, st8.fill MUST be aligned because the RNATs are based on
- * the address (bits [8:3]), so we must failed.
- */
-#define LD_OP 0x080
-#define LDS_OP 0x081
-#define LDA_OP 0x082
-#define LDSA_OP 0x083
-#define LDBIAS_OP 0x084
-#define LDACQ_OP 0x085
-/* 0x086, 0x087 are not relevant */
-#define LDCCLR_OP 0x088
-#define LDCNC_OP 0x089
-#define LDCCLRACQ_OP 0x08a
-#define ST_OP 0x08c
-#define STREL_OP 0x08d
-/* 0x08e,0x8f are not relevant */
-
-/*
- * Table C-29 Integer Load +Reg
- *
- * we use the ld->m (bit [36:36]) field to determine whether or not we have
- * a load/store of this form.
- */
-
-/*
- * Table C-30 Integer Load/Store +Imm
- *
- * We ignore [35:32]= 0x6, 0x7, 0xE, 0xF
- *
- * ld8.fill, st8.fill must be aligned because the Nat register are based on
- * the address, so we must fail and the program must be fixed.
- */
-#define LD_IMM_OP 0x0a0
-#define LDS_IMM_OP 0x0a1
-#define LDA_IMM_OP 0x0a2
-#define LDSA_IMM_OP 0x0a3
-#define LDBIAS_IMM_OP 0x0a4
-#define LDACQ_IMM_OP 0x0a5
-/* 0x0a6, 0xa7 are not relevant */
-#define LDCCLR_IMM_OP 0x0a8
-#define LDCNC_IMM_OP 0x0a9
-#define LDCCLRACQ_IMM_OP 0x0aa
-#define ST_IMM_OP 0x0ac
-#define STREL_IMM_OP 0x0ad
-/* 0x0ae,0xaf are not relevant */
-
-/*
- * Table C-32 Floating-point Load/Store
- */
-#define LDF_OP 0x0c0
-#define LDFS_OP 0x0c1
-#define LDFA_OP 0x0c2
-#define LDFSA_OP 0x0c3
-/* 0x0c6 is irrelevant */
-#define LDFCCLR_OP 0x0c8
-#define LDFCNC_OP 0x0c9
-/* 0x0cb is irrelevant */
-#define STF_OP 0x0cc
-
-/*
- * Table C-33 Floating-point Load +Reg
- *
- * we use the ld->m (bit [36:36]) field to determine whether or not we have
- * a load/store of this form.
- */
-
-/*
- * Table C-34 Floating-point Load/Store +Imm
- */
-#define LDF_IMM_OP 0x0e0
-#define LDFS_IMM_OP 0x0e1
-#define LDFA_IMM_OP 0x0e2
-#define LDFSA_IMM_OP 0x0e3
-/* 0x0e6 is irrelevant */
-#define LDFCCLR_IMM_OP 0x0e8
-#define LDFCNC_IMM_OP 0x0e9
-#define STF_IMM_OP 0x0ec
-
-typedef struct {
- unsigned long qp:6; /* [0:5] */
- unsigned long r1:7; /* [6:12] */
- unsigned long imm:7; /* [13:19] */
- unsigned long r3:7; /* [20:26] */
- unsigned long x:1; /* [27:27] */
- unsigned long hint:2; /* [28:29] */
- unsigned long x6_sz:2; /* [30:31] */
- unsigned long x6_op:4; /* [32:35], x6 = x6_sz|x6_op */
- unsigned long m:1; /* [36:36] */
- unsigned long op:4; /* [37:40] */
- unsigned long pad:23; /* [41:63] */
-} load_store_t;
-
-
-typedef enum {
- UPD_IMMEDIATE, /* ldXZ r1=[r3],imm(9) */
- UPD_REG /* ldXZ r1=[r3],r2 */
-} update_t;
-
-/*
- * We use tables to keep track of the offsets of registers in the saved state.
- * This way we save having big switch/case statements.
- *
- * We use bit 0 to indicate switch_stack or pt_regs.
- * The offset is simply shifted by 1 bit.
- * A 2-byte value should be enough to hold any kind of offset
- *
- * In case the calling convention changes (and thus pt_regs/switch_stack)
- * simply use RSW instead of RPT or vice-versa.
- */
-
-#define RPO(x) ((size_t) &((struct pt_regs *)0)->x)
-#define RSO(x) ((size_t) &((struct switch_stack *)0)->x)
-
-#define RPT(x) (RPO(x) << 1)
-#define RSW(x) (1| RSO(x)<<1)
-
-#define GR_OFFS(x) (gr_info[x]>>1)
-#define GR_IN_SW(x) (gr_info[x] & 0x1)
-
-#define FR_OFFS(x) (fr_info[x]>>1)
-#define FR_IN_SW(x) (fr_info[x] & 0x1)
-
-static u16 gr_info[32]={
- 0, /* r0 is read-only : WE SHOULD NEVER GET THIS */
-
- RPT(r1), RPT(r2), RPT(r3),
-
- RSW(r4), RSW(r5), RSW(r6), RSW(r7),
-
- RPT(r8), RPT(r9), RPT(r10), RPT(r11),
- RPT(r12), RPT(r13), RPT(r14), RPT(r15),
-
- RPT(r16), RPT(r17), RPT(r18), RPT(r19),
- RPT(r20), RPT(r21), RPT(r22), RPT(r23),
- RPT(r24), RPT(r25), RPT(r26), RPT(r27),
- RPT(r28), RPT(r29), RPT(r30), RPT(r31)
-};
-
-static u16 fr_info[32]={
- 0, /* constant : WE SHOULD NEVER GET THIS */
- 0, /* constant : WE SHOULD NEVER GET THIS */
-
- RSW(f2), RSW(f3), RSW(f4), RSW(f5),
-
- RPT(f6), RPT(f7), RPT(f8), RPT(f9),
- RPT(f10), RPT(f11),
-
- RSW(f12), RSW(f13), RSW(f14),
- RSW(f15), RSW(f16), RSW(f17), RSW(f18), RSW(f19),
- RSW(f20), RSW(f21), RSW(f22), RSW(f23), RSW(f24),
- RSW(f25), RSW(f26), RSW(f27), RSW(f28), RSW(f29),
- RSW(f30), RSW(f31)
-};
-
-/* Invalidate ALAT entry for integer register REGNO. */
-static void
-invala_gr (int regno)
-{
-# define F(reg) case reg: ia64_invala_gr(reg); break
-
- switch (regno) {
- F( 0); F( 1); F( 2); F( 3); F( 4); F( 5); F( 6); F( 7);
- F( 8); F( 9); F( 10); F( 11); F( 12); F( 13); F( 14); F( 15);
- F( 16); F( 17); F( 18); F( 19); F( 20); F( 21); F( 22); F( 23);
- F( 24); F( 25); F( 26); F( 27); F( 28); F( 29); F( 30); F( 31);
- F( 32); F( 33); F( 34); F( 35); F( 36); F( 37); F( 38); F( 39);
- F( 40); F( 41); F( 42); F( 43); F( 44); F( 45); F( 46); F( 47);
- F( 48); F( 49); F( 50); F( 51); F( 52); F( 53); F( 54); F( 55);
- F( 56); F( 57); F( 58); F( 59); F( 60); F( 61); F( 62); F( 63);
- F( 64); F( 65); F( 66); F( 67); F( 68); F( 69); F( 70); F( 71);
- F( 72); F( 73); F( 74); F( 75); F( 76); F( 77); F( 78); F( 79);
- F( 80); F( 81); F( 82); F( 83); F( 84); F( 85); F( 86); F( 87);
- F( 88); F( 89); F( 90); F( 91); F( 92); F( 93); F( 94); F( 95);
- F( 96); F( 97); F( 98); F( 99); F(100); F(101); F(102); F(103);
- F(104); F(105); F(106); F(107); F(108); F(109); F(110); F(111);
- F(112); F(113); F(114); F(115); F(116); F(117); F(118); F(119);
- F(120); F(121); F(122); F(123); F(124); F(125); F(126); F(127);
- }
-# undef F
-}
-
-/* Invalidate ALAT entry for floating-point register REGNO. */
-static void
-invala_fr (int regno)
-{
-# define F(reg) case reg: ia64_invala_fr(reg); break
-
- switch (regno) {
- F( 0); F( 1); F( 2); F( 3); F( 4); F( 5); F( 6); F( 7);
- F( 8); F( 9); F( 10); F( 11); F( 12); F( 13); F( 14); F( 15);
- F( 16); F( 17); F( 18); F( 19); F( 20); F( 21); F( 22); F( 23);
- F( 24); F( 25); F( 26); F( 27); F( 28); F( 29); F( 30); F( 31);
- F( 32); F( 33); F( 34); F( 35); F( 36); F( 37); F( 38); F( 39);
- F( 40); F( 41); F( 42); F( 43); F( 44); F( 45); F( 46); F( 47);
- F( 48); F( 49); F( 50); F( 51); F( 52); F( 53); F( 54); F( 55);
- F( 56); F( 57); F( 58); F( 59); F( 60); F( 61); F( 62); F( 63);
- F( 64); F( 65); F( 66); F( 67); F( 68); F( 69); F( 70); F( 71);
- F( 72); F( 73); F( 74); F( 75); F( 76); F( 77); F( 78); F( 79);
- F( 80); F( 81); F( 82); F( 83); F( 84); F( 85); F( 86); F( 87);
- F( 88); F( 89); F( 90); F( 91); F( 92); F( 93); F( 94); F( 95);
- F( 96); F( 97); F( 98); F( 99); F(100); F(101); F(102); F(103);
- F(104); F(105); F(106); F(107); F(108); F(109); F(110); F(111);
- F(112); F(113); F(114); F(115); F(116); F(117); F(118); F(119);
- F(120); F(121); F(122); F(123); F(124); F(125); F(126); F(127);
- }
-# undef F
-}
-
-static inline unsigned long
-rotate_reg (unsigned long sor, unsigned long rrb, unsigned long reg)
-{
- reg += rrb;
- if (reg >= sor)
- reg -= sor;
- return reg;
-}
-
-static void
-set_rse_reg (struct pt_regs *regs, unsigned long r1, unsigned long val, int nat)
-{
- struct switch_stack *sw = (struct switch_stack *) regs - 1;
- unsigned long *bsp, *bspstore, *addr, *rnat_addr, *ubs_end;
- unsigned long *kbs = (void *) current + IA64_RBS_OFFSET;
- unsigned long rnats, nat_mask;
- unsigned long on_kbs;
- long sof = (regs->cr_ifs) & 0x7f;
- long sor = 8 * ((regs->cr_ifs >> 14) & 0xf);
- long rrb_gr = (regs->cr_ifs >> 18) & 0x7f;
- long ridx = r1 - 32;
-
- if (ridx >= sof) {
- /* this should never happen, as the "rsvd register fault" has higher priority */
- DPRINT("ignoring write to r%lu; only %lu registers are allocated!\n", r1, sof);
- return;
- }
-
- if (ridx < sor)
- ridx = rotate_reg(sor, rrb_gr, ridx);
-
- DPRINT("r%lu, sw.bspstore=%lx pt.bspstore=%lx sof=%ld sol=%ld ridx=%ld\n",
- r1, sw->ar_bspstore, regs->ar_bspstore, sof, (regs->cr_ifs >> 7) & 0x7f, ridx);
-
- on_kbs = ia64_rse_num_regs(kbs, (unsigned long *) sw->ar_bspstore);
- addr = ia64_rse_skip_regs((unsigned long *) sw->ar_bspstore, -sof + ridx);
- if (addr >= kbs) {
- /* the register is on the kernel backing store: easy... */
- rnat_addr = ia64_rse_rnat_addr(addr);
- if ((unsigned long) rnat_addr >= sw->ar_bspstore)
- rnat_addr = &sw->ar_rnat;
- nat_mask = 1UL << ia64_rse_slot_num(addr);
-
- *addr = val;
- if (nat)
- *rnat_addr |= nat_mask;
- else
- *rnat_addr &= ~nat_mask;
- return;
- }
-
- if (!user_stack(current, regs)) {
- DPRINT("ignoring kernel write to r%lu; register isn't on the kernel RBS!", r1);
- return;
- }
-
- bspstore = (unsigned long *)regs->ar_bspstore;
- ubs_end = ia64_rse_skip_regs(bspstore, on_kbs);
- bsp = ia64_rse_skip_regs(ubs_end, -sof);
- addr = ia64_rse_skip_regs(bsp, ridx);
-
- DPRINT("ubs_end=%p bsp=%p addr=%p\n", (void *) ubs_end, (void *) bsp, (void *) addr);
-
- ia64_poke(current, sw, (unsigned long) ubs_end, (unsigned long) addr, val);
-
- rnat_addr = ia64_rse_rnat_addr(addr);
-
- ia64_peek(current, sw, (unsigned long) ubs_end, (unsigned long) rnat_addr, &rnats);
- DPRINT("rnat @%p = 0x%lx nat=%d old nat=%ld\n",
- (void *) rnat_addr, rnats, nat, (rnats >> ia64_rse_slot_num(addr)) & 1);
-
- nat_mask = 1UL << ia64_rse_slot_num(addr);
- if (nat)
- rnats |= nat_mask;
- else
- rnats &= ~nat_mask;
- ia64_poke(current, sw, (unsigned long) ubs_end, (unsigned long) rnat_addr, rnats);
-
- DPRINT("rnat changed to @%p = 0x%lx\n", (void *) rnat_addr, rnats);
-}
-
-
-static void
-get_rse_reg (struct pt_regs *regs, unsigned long r1, unsigned long *val, int *nat)
-{
- struct switch_stack *sw = (struct switch_stack *) regs - 1;
- unsigned long *bsp, *addr, *rnat_addr, *ubs_end, *bspstore;
- unsigned long *kbs = (void *) current + IA64_RBS_OFFSET;
- unsigned long rnats, nat_mask;
- unsigned long on_kbs;
- long sof = (regs->cr_ifs) & 0x7f;
- long sor = 8 * ((regs->cr_ifs >> 14) & 0xf);
- long rrb_gr = (regs->cr_ifs >> 18) & 0x7f;
- long ridx = r1 - 32;
-
- if (ridx >= sof) {
- /* read of out-of-frame register returns an undefined value; 0 in our case. */
- DPRINT("ignoring read from r%lu; only %lu registers are allocated!\n", r1, sof);
- goto fail;
- }
-
- if (ridx < sor)
- ridx = rotate_reg(sor, rrb_gr, ridx);
-
- DPRINT("r%lu, sw.bspstore=%lx pt.bspstore=%lx sof=%ld sol=%ld ridx=%ld\n",
- r1, sw->ar_bspstore, regs->ar_bspstore, sof, (regs->cr_ifs >> 7) & 0x7f, ridx);
-
- on_kbs = ia64_rse_num_regs(kbs, (unsigned long *) sw->ar_bspstore);
- addr = ia64_rse_skip_regs((unsigned long *) sw->ar_bspstore, -sof + ridx);
- if (addr >= kbs) {
- /* the register is on the kernel backing store: easy... */
- *val = *addr;
- if (nat) {
- rnat_addr = ia64_rse_rnat_addr(addr);
- if ((unsigned long) rnat_addr >= sw->ar_bspstore)
- rnat_addr = &sw->ar_rnat;
- nat_mask = 1UL << ia64_rse_slot_num(addr);
- *nat = (*rnat_addr & nat_mask) != 0;
- }
- return;
- }
-
- if (!user_stack(current, regs)) {
- DPRINT("ignoring kernel read of r%lu; register isn't on the RBS!", r1);
- goto fail;
- }
-
- bspstore = (unsigned long *)regs->ar_bspstore;
- ubs_end = ia64_rse_skip_regs(bspstore, on_kbs);
- bsp = ia64_rse_skip_regs(ubs_end, -sof);
- addr = ia64_rse_skip_regs(bsp, ridx);
-
- DPRINT("ubs_end=%p bsp=%p addr=%p\n", (void *) ubs_end, (void *) bsp, (void *) addr);
-
- ia64_peek(current, sw, (unsigned long) ubs_end, (unsigned long) addr, val);
-
- if (nat) {
- rnat_addr = ia64_rse_rnat_addr(addr);
- nat_mask = 1UL << ia64_rse_slot_num(addr);
-
- DPRINT("rnat @%p = 0x%lx\n", (void *) rnat_addr, rnats);
-
- ia64_peek(current, sw, (unsigned long) ubs_end, (unsigned long) rnat_addr, &rnats);
- *nat = (rnats & nat_mask) != 0;
- }
- return;
-
- fail:
- *val = 0;
- if (nat)
- *nat = 0;
- return;
-}
-
-
-static void
-setreg (unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs)
-{
- struct switch_stack *sw = (struct switch_stack *) regs - 1;
- unsigned long addr;
- unsigned long bitmask;
- unsigned long *unat;
-
- /*
- * First takes care of stacked registers
- */
- if (regnum >= IA64_FIRST_STACKED_GR) {
- set_rse_reg(regs, regnum, val, nat);
- return;
- }
-
- /*
- * Using r0 as a target raises a General Exception fault which has higher priority
- * than the Unaligned Reference fault.
- */
-
- /*
- * Now look at registers in [0-31] range and init correct UNAT
- */
- if (GR_IN_SW(regnum)) {
- addr = (unsigned long)sw;
- unat = &sw->ar_unat;
- } else {
- addr = (unsigned long)regs;
- unat = &sw->caller_unat;
- }
- DPRINT("tmp_base=%lx switch_stack=%s offset=%d\n",
- addr, unat==&sw->ar_unat ? "yes":"no", GR_OFFS(regnum));
- /*
- * add offset from base of struct
- * and do it !
- */
- addr += GR_OFFS(regnum);
-
- *(unsigned long *)addr = val;
-
- /*
- * We need to clear the corresponding UNAT bit to fully emulate the load
- * UNAT bit_pos = GR[r3]{8:3} form EAS-2.4
- */
- bitmask = 1UL << (addr >> 3 & 0x3f);
- DPRINT("*0x%lx=0x%lx NaT=%d prev_unat @%p=%lx\n", addr, val, nat, (void *) unat, *unat);
- if (nat) {
- *unat |= bitmask;
- } else {
- *unat &= ~bitmask;
- }
- DPRINT("*0x%lx=0x%lx NaT=%d new unat: %p=%lx\n", addr, val, nat, (void *) unat,*unat);
-}
-
-/*
- * Return the (rotated) index for floating point register REGNUM (REGNUM must be in the
- * range from 32-127, result is in the range from 0-95.
- */
-static inline unsigned long
-fph_index (struct pt_regs *regs, long regnum)
-{
- unsigned long rrb_fr = (regs->cr_ifs >> 25) & 0x7f;
- return rotate_reg(96, rrb_fr, (regnum - IA64_FIRST_ROTATING_FR));
-}
-
-static void
-setfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
-{
- struct switch_stack *sw = (struct switch_stack *)regs - 1;
- unsigned long addr;
-
- /*
- * From EAS-2.5: FPDisableFault has higher priority than Unaligned
- * Fault. Thus, when we get here, we know the partition is enabled.
- * To update f32-f127, there are three choices:
- *
- * (1) save f32-f127 to thread.fph and update the values there
- * (2) use a gigantic switch statement to directly access the registers
- * (3) generate code on the fly to update the desired register
- *
- * For now, we are using approach (1).
- */
- if (regnum >= IA64_FIRST_ROTATING_FR) {
- ia64_sync_fph(current);
- current->thread.fph[fph_index(regs, regnum)] = *fpval;
- } else {
- /*
- * pt_regs or switch_stack ?
- */
- if (FR_IN_SW(regnum)) {
- addr = (unsigned long)sw;
- } else {
- addr = (unsigned long)regs;
- }
-
- DPRINT("tmp_base=%lx offset=%d\n", addr, FR_OFFS(regnum));
-
- addr += FR_OFFS(regnum);
- *(struct ia64_fpreg *)addr = *fpval;
-
- /*
- * mark the low partition as being used now
- *
- * It is highly unlikely that this bit is not already set, but
- * let's do it for safety.
- */
- regs->cr_ipsr |= IA64_PSR_MFL;
- }
-}
-
-/*
- * Those 2 inline functions generate the spilled versions of the constant floating point
- * registers which can be used with stfX
- */
-static inline void
-float_spill_f0 (struct ia64_fpreg *final)
-{
- ia64_stf_spill(final, 0);
-}
-
-static inline void
-float_spill_f1 (struct ia64_fpreg *final)
-{
- ia64_stf_spill(final, 1);
-}
-
-static void
-getfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
-{
- struct switch_stack *sw = (struct switch_stack *) regs - 1;
- unsigned long addr;
-
- /*
- * From EAS-2.5: FPDisableFault has higher priority than
- * Unaligned Fault. Thus, when we get here, we know the partition is
- * enabled.
- *
- * When regnum > 31, the register is still live and we need to force a save
- * to current->thread.fph to get access to it. See discussion in setfpreg()
- * for reasons and other ways of doing this.
- */
- if (regnum >= IA64_FIRST_ROTATING_FR) {
- ia64_flush_fph(current);
- *fpval = current->thread.fph[fph_index(regs, regnum)];
- } else {
- /*
- * f0 = 0.0, f1= 1.0. Those registers are constant and are thus
- * not saved, we must generate their spilled form on the fly
- */
- switch(regnum) {
- case 0:
- float_spill_f0(fpval);
- break;
- case 1:
- float_spill_f1(fpval);
- break;
- default:
- /*
- * pt_regs or switch_stack ?
- */
- addr = FR_IN_SW(regnum) ? (unsigned long)sw
- : (unsigned long)regs;
-
- DPRINT("is_sw=%d tmp_base=%lx offset=0x%x\n",
- FR_IN_SW(regnum), addr, FR_OFFS(regnum));
-
- addr += FR_OFFS(regnum);
- *fpval = *(struct ia64_fpreg *)addr;
- }
- }
-}
-
-
-static void
-getreg (unsigned long regnum, unsigned long *val, int *nat, struct pt_regs *regs)
-{
- struct switch_stack *sw = (struct switch_stack *) regs - 1;
- unsigned long addr, *unat;
-
- if (regnum >= IA64_FIRST_STACKED_GR) {
- get_rse_reg(regs, regnum, val, nat);
- return;
- }
-
- /*
- * take care of r0 (read-only always evaluate to 0)
- */
- if (regnum == 0) {
- *val = 0;
- if (nat)
- *nat = 0;
- return;
- }
-
- /*
- * Now look at registers in [0-31] range and init correct UNAT
- */
- if (GR_IN_SW(regnum)) {
- addr = (unsigned long)sw;
- unat = &sw->ar_unat;
- } else {
- addr = (unsigned long)regs;
- unat = &sw->caller_unat;
- }
-
- DPRINT("addr_base=%lx offset=0x%x\n", addr, GR_OFFS(regnum));
-
- addr += GR_OFFS(regnum);
-
- *val = *(unsigned long *)addr;
-
- /*
- * do it only when requested
- */
- if (nat)
- *nat = (*unat >> (addr >> 3 & 0x3f)) & 0x1UL;
-}
-
-static void
-emulate_load_updates (update_t type, load_store_t ld, struct pt_regs *regs, unsigned long ifa)
-{
- /*
- * IMPORTANT:
- * Given the way we handle unaligned speculative loads, we should
- * not get to this point in the code but we keep this sanity check,
- * just in case.
- */
- if (ld.x6_op == 1 || ld.x6_op == 3) {
- printk(KERN_ERR "%s: register update on speculative load, error\n", __func__);
- if (die_if_kernel("unaligned reference on speculative load with register update\n",
- regs, 30))
- return;
- }
-
-
- /*
- * at this point, we know that the base register to update is valid i.e.,
- * it's not r0
- */
- if (type == UPD_IMMEDIATE) {
- unsigned long imm;
-
- /*
- * Load +Imm: ldXZ r1=[r3],imm(9)
- *
- *
- * form imm9: [13:19] contain the first 7 bits
- */
- imm = ld.x << 7 | ld.imm;
-
- /*
- * sign extend (1+8bits) if m set
- */
- if (ld.m) imm |= SIGN_EXT9;
-
- /*
- * ifa == r3 and we know that the NaT bit on r3 was clear so
- * we can directly use ifa.
- */
- ifa += imm;
-
- setreg(ld.r3, ifa, 0, regs);
-
- DPRINT("ld.x=%d ld.m=%d imm=%ld r3=0x%lx\n", ld.x, ld.m, imm, ifa);
-
- } else if (ld.m) {
- unsigned long r2;
- int nat_r2;
-
- /*
- * Load +Reg Opcode: ldXZ r1=[r3],r2
- *
- * Note: that we update r3 even in the case of ldfX.a
- * (where the load does not happen)
- *
- * The way the load algorithm works, we know that r3 does not
- * have its NaT bit set (would have gotten NaT consumption
- * before getting the unaligned fault). So we can use ifa
- * which equals r3 at this point.
- *
- * IMPORTANT:
- * The above statement holds ONLY because we know that we
- * never reach this code when trying to do a ldX.s.
- * If we ever make it to here on an ldfX.s then
- */
- getreg(ld.imm, &r2, &nat_r2, regs);
-
- ifa += r2;
-
- /*
- * propagate Nat r2 -> r3
- */
- setreg(ld.r3, ifa, nat_r2, regs);
-
- DPRINT("imm=%d r2=%ld r3=0x%lx nat_r2=%d\n",ld.imm, r2, ifa, nat_r2);
- }
-}
-
-static int emulate_store(unsigned long ifa, void *val, int len, bool kernel_mode)
-{
- if (kernel_mode)
- return copy_to_kernel_nofault((void *)ifa, val, len);
-
- return copy_to_user((void __user *)ifa, val, len);
-}
-
-static int emulate_load(void *val, unsigned long ifa, int len, bool kernel_mode)
-{
- if (kernel_mode)
- return copy_from_kernel_nofault(val, (void *)ifa, len);
-
- return copy_from_user(val, (void __user *)ifa, len);
-}
-
-static int
-emulate_load_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs,
- bool kernel_mode)
-{
- unsigned int len = 1 << ld.x6_sz;
- unsigned long val = 0;
-
- /*
- * r0, as target, doesn't need to be checked because Illegal Instruction
- * faults have higher priority than unaligned faults.
- *
- * r0 cannot be found as the base as it would never generate an
- * unaligned reference.
- */
-
- /*
- * ldX.a we will emulate load and also invalidate the ALAT entry.
- * See comment below for explanation on how we handle ldX.a
- */
-
- if (len != 2 && len != 4 && len != 8) {
- DPRINT("unknown size: x6=%d\n", ld.x6_sz);
- return -1;
- }
- /* this assumes little-endian byte-order: */
- if (emulate_load(&val, ifa, len, kernel_mode))
- return -1;
- setreg(ld.r1, val, 0, regs);
-
- /*
- * check for updates on any kind of loads
- */
- if (ld.op == 0x5 || ld.m)
- emulate_load_updates(ld.op == 0x5 ? UPD_IMMEDIATE: UPD_REG, ld, regs, ifa);
-
- /*
- * handling of various loads (based on EAS2.4):
- *
- * ldX.acq (ordered load):
- * - acquire semantics would have been used, so force fence instead.
- *
- * ldX.c.clr (check load and clear):
- * - if we get to this handler, it's because the entry was not in the ALAT.
- * Therefore the operation reverts to a normal load
- *
- * ldX.c.nc (check load no clear):
- * - same as previous one
- *
- * ldX.c.clr.acq (ordered check load and clear):
- * - same as above for c.clr part. The load needs to have acquire semantics. So
- * we use the fence semantics which is stronger and thus ensures correctness.
- *
- * ldX.a (advanced load):
- * - suppose ldX.a r1=[r3]. If we get to the unaligned trap it's because the
- * address doesn't match requested size alignment. This means that we would
- * possibly need more than one load to get the result.
- *
- * The load part can be handled just like a normal load, however the difficult
- * part is to get the right thing into the ALAT. The critical piece of information
- * in the base address of the load & size. To do that, a ld.a must be executed,
- * clearly any address can be pushed into the table by using ld1.a r1=[r3]. Now
- * if we use the same target register, we will be okay for the check.a instruction.
- * If we look at the store, basically a stX [r3]=r1 checks the ALAT for any entry
- * which would overlap within [r3,r3+X] (the size of the load was store in the
- * ALAT). If such an entry is found the entry is invalidated. But this is not good
- * enough, take the following example:
- * r3=3
- * ld4.a r1=[r3]
- *
- * Could be emulated by doing:
- * ld1.a r1=[r3],1
- * store to temporary;
- * ld1.a r1=[r3],1
- * store & shift to temporary;
- * ld1.a r1=[r3],1
- * store & shift to temporary;
- * ld1.a r1=[r3]
- * store & shift to temporary;
- * r1=temporary
- *
- * So in this case, you would get the right value is r1 but the wrong info in
- * the ALAT. Notice that you could do it in reverse to finish with address 3
- * but you would still get the size wrong. To get the size right, one needs to
- * execute exactly the same kind of load. You could do it from a aligned
- * temporary location, but you would get the address wrong.
- *
- * So no matter what, it is not possible to emulate an advanced load
- * correctly. But is that really critical ?
- *
- * We will always convert ld.a into a normal load with ALAT invalidated. This
- * will enable compiler to do optimization where certain code path after ld.a
- * is not required to have ld.c/chk.a, e.g., code path with no intervening stores.
- *
- * If there is a store after the advanced load, one must either do a ld.c.* or
- * chk.a.* to reuse the value stored in the ALAT. Both can "fail" (meaning no
- * entry found in ALAT), and that's perfectly ok because:
- *
- * - ld.c.*, if the entry is not present a normal load is executed
- * - chk.a.*, if the entry is not present, execution jumps to recovery code
- *
- * In either case, the load can be potentially retried in another form.
- *
- * ALAT must be invalidated for the register (so that chk.a or ld.c don't pick
- * up a stale entry later). The register base update MUST also be performed.
- */
-
- /*
- * when the load has the .acq completer then
- * use ordering fence.
- */
- if (ld.x6_op == 0x5 || ld.x6_op == 0xa)
- mb();
-
- /*
- * invalidate ALAT entry in case of advanced load
- */
- if (ld.x6_op == 0x2)
- invala_gr(ld.r1);
-
- return 0;
-}
-
-static int
-emulate_store_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs,
- bool kernel_mode)
-{
- unsigned long r2;
- unsigned int len = 1 << ld.x6_sz;
-
- /*
- * if we get to this handler, Nat bits on both r3 and r2 have already
- * been checked. so we don't need to do it
- *
- * extract the value to be stored
- */
- getreg(ld.imm, &r2, NULL, regs);
-
- /*
- * we rely on the macros in unaligned.h for now i.e.,
- * we let the compiler figure out how to read memory gracefully.
- *
- * We need this switch/case because the way the inline function
- * works. The code is optimized by the compiler and looks like
- * a single switch/case.
- */
- DPRINT("st%d [%lx]=%lx\n", len, ifa, r2);
-
- if (len != 2 && len != 4 && len != 8) {
- DPRINT("unknown size: x6=%d\n", ld.x6_sz);
- return -1;
- }
-
- /* this assumes little-endian byte-order: */
- if (emulate_store(ifa, &r2, len, kernel_mode))
- return -1;
-
- /*
- * stX [r3]=r2,imm(9)
- *
- * NOTE:
- * ld.r3 can never be r0, because r0 would not generate an
- * unaligned access.
- */
- if (ld.op == 0x5) {
- unsigned long imm;
-
- /*
- * form imm9: [12:6] contain first 7bits
- */
- imm = ld.x << 7 | ld.r1;
- /*
- * sign extend (8bits) if m set
- */
- if (ld.m) imm |= SIGN_EXT9;
- /*
- * ifa == r3 (NaT is necessarily cleared)
- */
- ifa += imm;
-
- DPRINT("imm=%lx r3=%lx\n", imm, ifa);
-
- setreg(ld.r3, ifa, 0, regs);
- }
- /*
- * we don't have alat_invalidate_multiple() so we need
- * to do the complete flush :-<<
- */
- ia64_invala();
-
- /*
- * stX.rel: use fence instead of release
- */
- if (ld.x6_op == 0xd)
- mb();
-
- return 0;
-}
-
-/*
- * floating point operations sizes in bytes
- */
-static const unsigned char float_fsz[4]={
- 10, /* extended precision (e) */
- 8, /* integer (8) */
- 4, /* single precision (s) */
- 8 /* double precision (d) */
-};
-
-static inline void
-mem2float_extended (struct ia64_fpreg *init, struct ia64_fpreg *final)
-{
- ia64_ldfe(6, init);
- ia64_stop();
- ia64_stf_spill(final, 6);
-}
-
-static inline void
-mem2float_integer (struct ia64_fpreg *init, struct ia64_fpreg *final)
-{
- ia64_ldf8(6, init);
- ia64_stop();
- ia64_stf_spill(final, 6);
-}
-
-static inline void
-mem2float_single (struct ia64_fpreg *init, struct ia64_fpreg *final)
-{
- ia64_ldfs(6, init);
- ia64_stop();
- ia64_stf_spill(final, 6);
-}
-
-static inline void
-mem2float_double (struct ia64_fpreg *init, struct ia64_fpreg *final)
-{
- ia64_ldfd(6, init);
- ia64_stop();
- ia64_stf_spill(final, 6);
-}
-
-static inline void
-float2mem_extended (struct ia64_fpreg *init, struct ia64_fpreg *final)
-{
- ia64_ldf_fill(6, init);
- ia64_stop();
- ia64_stfe(final, 6);
-}
-
-static inline void
-float2mem_integer (struct ia64_fpreg *init, struct ia64_fpreg *final)
-{
- ia64_ldf_fill(6, init);
- ia64_stop();
- ia64_stf8(final, 6);
-}
-
-static inline void
-float2mem_single (struct ia64_fpreg *init, struct ia64_fpreg *final)
-{
- ia64_ldf_fill(6, init);
- ia64_stop();
- ia64_stfs(final, 6);
-}
-
-static inline void
-float2mem_double (struct ia64_fpreg *init, struct ia64_fpreg *final)
-{
- ia64_ldf_fill(6, init);
- ia64_stop();
- ia64_stfd(final, 6);
-}
-
-static int
-emulate_load_floatpair (unsigned long ifa, load_store_t ld, struct pt_regs *regs, bool kernel_mode)
-{
- struct ia64_fpreg fpr_init[2];
- struct ia64_fpreg fpr_final[2];
- unsigned long len = float_fsz[ld.x6_sz];
-
- /*
- * fr0 & fr1 don't need to be checked because Illegal Instruction faults have
- * higher priority than unaligned faults.
- *
- * r0 cannot be found as the base as it would never generate an unaligned
- * reference.
- */
-
- /*
- * make sure we get clean buffers
- */
- memset(&fpr_init, 0, sizeof(fpr_init));
- memset(&fpr_final, 0, sizeof(fpr_final));
-
- /*
- * ldfpX.a: we don't try to emulate anything but we must
- * invalidate the ALAT entry and execute updates, if any.
- */
- if (ld.x6_op != 0x2) {
- /*
- * This assumes little-endian byte-order. Note that there is no "ldfpe"
- * instruction:
- */
- if (emulate_load(&fpr_init[0], ifa, len, kernel_mode)
- || emulate_load(&fpr_init[1], (ifa + len), len, kernel_mode))
- return -1;
-
- DPRINT("ld.r1=%d ld.imm=%d x6_sz=%d\n", ld.r1, ld.imm, ld.x6_sz);
- DDUMP("frp_init =", &fpr_init, 2*len);
- /*
- * XXX fixme
- * Could optimize inlines by using ldfpX & 2 spills
- */
- switch( ld.x6_sz ) {
- case 0:
- mem2float_extended(&fpr_init[0], &fpr_final[0]);
- mem2float_extended(&fpr_init[1], &fpr_final[1]);
- break;
- case 1:
- mem2float_integer(&fpr_init[0], &fpr_final[0]);
- mem2float_integer(&fpr_init[1], &fpr_final[1]);
- break;
- case 2:
- mem2float_single(&fpr_init[0], &fpr_final[0]);
- mem2float_single(&fpr_init[1], &fpr_final[1]);
- break;
- case 3:
- mem2float_double(&fpr_init[0], &fpr_final[0]);
- mem2float_double(&fpr_init[1], &fpr_final[1]);
- break;
- }
- DDUMP("fpr_final =", &fpr_final, 2*len);
- /*
- * XXX fixme
- *
- * A possible optimization would be to drop fpr_final and directly
- * use the storage from the saved context i.e., the actual final
- * destination (pt_regs, switch_stack or thread structure).
- */
- setfpreg(ld.r1, &fpr_final[0], regs);
- setfpreg(ld.imm, &fpr_final[1], regs);
- }
-
- /*
- * Check for updates: only immediate updates are available for this
- * instruction.
- */
- if (ld.m) {
- /*
- * the immediate is implicit given the ldsz of the operation:
- * single: 8 (2x4) and for all others it's 16 (2x8)
- */
- ifa += len<<1;
-
- /*
- * IMPORTANT:
- * the fact that we force the NaT of r3 to zero is ONLY valid
- * as long as we don't come here with a ldfpX.s.
- * For this reason we keep this sanity check
- */
- if (ld.x6_op == 1 || ld.x6_op == 3)
- printk(KERN_ERR "%s: register update on speculative load pair, error\n",
- __func__);
-
- setreg(ld.r3, ifa, 0, regs);
- }
-
- /*
- * Invalidate ALAT entries, if any, for both registers.
- */
- if (ld.x6_op == 0x2) {
- invala_fr(ld.r1);
- invala_fr(ld.imm);
- }
- return 0;
-}
-
-
-static int
-emulate_load_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs,
- bool kernel_mode)
-{
- struct ia64_fpreg fpr_init;
- struct ia64_fpreg fpr_final;
- unsigned long len = float_fsz[ld.x6_sz];
-
- /*
- * fr0 & fr1 don't need to be checked because Illegal Instruction
- * faults have higher priority than unaligned faults.
- *
- * r0 cannot be found as the base as it would never generate an
- * unaligned reference.
- */
-
- /*
- * make sure we get clean buffers
- */
- memset(&fpr_init,0, sizeof(fpr_init));
- memset(&fpr_final,0, sizeof(fpr_final));
-
- /*
- * ldfX.a we don't try to emulate anything but we must
- * invalidate the ALAT entry.
- * See comments in ldX for descriptions on how the various loads are handled.
- */
- if (ld.x6_op != 0x2) {
- if (emulate_load(&fpr_init, ifa, len, kernel_mode))
- return -1;
-
- DPRINT("ld.r1=%d x6_sz=%d\n", ld.r1, ld.x6_sz);
- DDUMP("fpr_init =", &fpr_init, len);
- /*
- * we only do something for x6_op={0,8,9}
- */
- switch( ld.x6_sz ) {
- case 0:
- mem2float_extended(&fpr_init, &fpr_final);
- break;
- case 1:
- mem2float_integer(&fpr_init, &fpr_final);
- break;
- case 2:
- mem2float_single(&fpr_init, &fpr_final);
- break;
- case 3:
- mem2float_double(&fpr_init, &fpr_final);
- break;
- }
- DDUMP("fpr_final =", &fpr_final, len);
- /*
- * XXX fixme
- *
- * A possible optimization would be to drop fpr_final and directly
- * use the storage from the saved context i.e., the actual final
- * destination (pt_regs, switch_stack or thread structure).
- */
- setfpreg(ld.r1, &fpr_final, regs);
- }
-
- /*
- * check for updates on any loads
- */
- if (ld.op == 0x7 || ld.m)
- emulate_load_updates(ld.op == 0x7 ? UPD_IMMEDIATE: UPD_REG, ld, regs, ifa);
-
- /*
- * invalidate ALAT entry in case of advanced floating point loads
- */
- if (ld.x6_op == 0x2)
- invala_fr(ld.r1);
-
- return 0;
-}
-
-
-static int
-emulate_store_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs,
- bool kernel_mode)
-{
- struct ia64_fpreg fpr_init;
- struct ia64_fpreg fpr_final;
- unsigned long len = float_fsz[ld.x6_sz];
-
- /*
- * make sure we get clean buffers
- */
- memset(&fpr_init,0, sizeof(fpr_init));
- memset(&fpr_final,0, sizeof(fpr_final));
-
- /*
- * if we get to this handler, Nat bits on both r3 and r2 have already
- * been checked. so we don't need to do it
- *
- * extract the value to be stored
- */
- getfpreg(ld.imm, &fpr_init, regs);
- /*
- * during this step, we extract the spilled registers from the saved
- * context i.e., we refill. Then we store (no spill) to temporary
- * aligned location
- */
- switch( ld.x6_sz ) {
- case 0:
- float2mem_extended(&fpr_init, &fpr_final);
- break;
- case 1:
- float2mem_integer(&fpr_init, &fpr_final);
- break;
- case 2:
- float2mem_single(&fpr_init, &fpr_final);
- break;
- case 3:
- float2mem_double(&fpr_init, &fpr_final);
- break;
- }
- DPRINT("ld.r1=%d x6_sz=%d\n", ld.r1, ld.x6_sz);
- DDUMP("fpr_init =", &fpr_init, len);
- DDUMP("fpr_final =", &fpr_final, len);
-
- if (emulate_store(ifa, &fpr_final, len, kernel_mode))
- return -1;
-
- /*
- * stfX [r3]=r2,imm(9)
- *
- * NOTE:
- * ld.r3 can never be r0, because r0 would not generate an
- * unaligned access.
- */
- if (ld.op == 0x7) {
- unsigned long imm;
-
- /*
- * form imm9: [12:6] contain first 7bits
- */
- imm = ld.x << 7 | ld.r1;
- /*
- * sign extend (8bits) if m set
- */
- if (ld.m)
- imm |= SIGN_EXT9;
- /*
- * ifa == r3 (NaT is necessarily cleared)
- */
- ifa += imm;
-
- DPRINT("imm=%lx r3=%lx\n", imm, ifa);
-
- setreg(ld.r3, ifa, 0, regs);
- }
- /*
- * we don't have alat_invalidate_multiple() so we need
- * to do the complete flush :-<<
- */
- ia64_invala();
-
- return 0;
-}
-
-/*
- * Make sure we log the unaligned access, so that user/sysadmin can notice it and
- * eventually fix the program. However, we don't want to do that for every access so we
- * pace it with jiffies.
- */
-static DEFINE_RATELIMIT_STATE(logging_rate_limit, 5 * HZ, 5);
-
-void
-ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
-{
- struct ia64_psr *ipsr = ia64_psr(regs);
- unsigned long bundle[2];
- unsigned long opcode;
- const struct exception_table_entry *eh = NULL;
- union {
- unsigned long l;
- load_store_t insn;
- } u;
- int ret = -1;
- bool kernel_mode = false;
-
- if (ia64_psr(regs)->be) {
- /* we don't support big-endian accesses */
- if (die_if_kernel("big-endian unaligned accesses are not supported", regs, 0))
- return;
- goto force_sigbus;
- }
-
- /*
- * Treat kernel accesses for which there is an exception handler entry the same as
- * user-level unaligned accesses. Otherwise, a clever program could trick this
- * handler into reading an arbitrary kernel addresses...
- */
- if (!user_mode(regs))
- eh = search_exception_tables(regs->cr_iip + ia64_psr(regs)->ri);
- if (user_mode(regs) || eh) {
- if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0)
- goto force_sigbus;
-
- if (!no_unaligned_warning &&
- !(current->thread.flags & IA64_THREAD_UAC_NOPRINT) &&
- __ratelimit(&logging_rate_limit))
- {
- char buf[200]; /* comm[] is at most 16 bytes... */
- size_t len;
-
- len = sprintf(buf, "%s(%d): unaligned access to 0x%016lx, "
- "ip=0x%016lx\n\r", current->comm,
- task_pid_nr(current),
- ifa, regs->cr_iip + ipsr->ri);
- /*
- * Don't call tty_write_message() if we're in the kernel; we might
- * be holding locks...
- */
- if (user_mode(regs)) {
- struct tty_struct *tty = get_current_tty();
- tty_write_message(tty, buf);
- tty_kref_put(tty);
- }
- buf[len-1] = '\0'; /* drop '\r' */
- /* watch for command names containing %s */
- printk(KERN_WARNING "%s", buf);
- } else {
- if (no_unaligned_warning) {
- printk_once(KERN_WARNING "%s(%d) encountered an "
- "unaligned exception which required\n"
- "kernel assistance, which degrades "
- "the performance of the application.\n"
- "Unaligned exception warnings have "
- "been disabled by the system "
- "administrator\n"
- "echo 0 > /proc/sys/kernel/ignore-"
- "unaligned-usertrap to re-enable\n",
- current->comm, task_pid_nr(current));
- }
- }
- } else {
- if (__ratelimit(&logging_rate_limit)) {
- printk(KERN_WARNING "kernel unaligned access to 0x%016lx, ip=0x%016lx\n",
- ifa, regs->cr_iip + ipsr->ri);
- if (unaligned_dump_stack)
- dump_stack();
- }
- kernel_mode = true;
- }
-
- DPRINT("iip=%lx ifa=%lx isr=%lx (ei=%d, sp=%d)\n",
- regs->cr_iip, ifa, regs->cr_ipsr, ipsr->ri, ipsr->it);
-
- if (emulate_load(bundle, regs->cr_iip, 16, kernel_mode))
- goto failure;
-
- /*
- * extract the instruction from the bundle given the slot number
- */
- switch (ipsr->ri) {
- default:
- case 0: u.l = (bundle[0] >> 5); break;
- case 1: u.l = (bundle[0] >> 46) | (bundle[1] << 18); break;
- case 2: u.l = (bundle[1] >> 23); break;
- }
- opcode = (u.l >> IA64_OPCODE_SHIFT) & IA64_OPCODE_MASK;
-
- DPRINT("opcode=%lx ld.qp=%d ld.r1=%d ld.imm=%d ld.r3=%d ld.x=%d ld.hint=%d "
- "ld.x6=0x%x ld.m=%d ld.op=%d\n", opcode, u.insn.qp, u.insn.r1, u.insn.imm,
- u.insn.r3, u.insn.x, u.insn.hint, u.insn.x6_sz, u.insn.m, u.insn.op);
-
- /*
- * IMPORTANT:
- * Notice that the switch statement DOES not cover all possible instructions
- * that DO generate unaligned references. This is made on purpose because for some
- * instructions it DOES NOT make sense to try and emulate the access. Sometimes it
- * is WRONG to try and emulate. Here is a list of instruction we don't emulate i.e.,
- * the program will get a signal and die:
- *
- * load/store:
- * - ldX.spill
- * - stX.spill
- * Reason: RNATs are based on addresses
- * - ld16
- * - st16
- * Reason: ld16 and st16 are supposed to occur in a single
- * memory op
- *
- * synchronization:
- * - cmpxchg
- * - fetchadd
- * - xchg
- * Reason: ATOMIC operations cannot be emulated properly using multiple
- * instructions.
- *
- * speculative loads:
- * - ldX.sZ
- * Reason: side effects, code must be ready to deal with failure so simpler
- * to let the load fail.
- * ---------------------------------------------------------------------------------
- * XXX fixme
- *
- * I would like to get rid of this switch case and do something
- * more elegant.
- */
- switch (opcode) {
- case LDS_OP:
- case LDSA_OP:
- if (u.insn.x)
- /* oops, really a semaphore op (cmpxchg, etc) */
- goto failure;
- fallthrough;
- case LDS_IMM_OP:
- case LDSA_IMM_OP:
- case LDFS_OP:
- case LDFSA_OP:
- case LDFS_IMM_OP:
- /*
- * The instruction will be retried with deferred exceptions turned on, and
- * we should get Nat bit installed
- *
- * IMPORTANT: When PSR_ED is set, the register & immediate update forms
- * are actually executed even though the operation failed. So we don't
- * need to take care of this.
- */
- DPRINT("forcing PSR_ED\n");
- regs->cr_ipsr |= IA64_PSR_ED;
- goto done;
-
- case LD_OP:
- case LDA_OP:
- case LDBIAS_OP:
- case LDACQ_OP:
- case LDCCLR_OP:
- case LDCNC_OP:
- case LDCCLRACQ_OP:
- if (u.insn.x)
- /* oops, really a semaphore op (cmpxchg, etc) */
- goto failure;
- fallthrough;
- case LD_IMM_OP:
- case LDA_IMM_OP:
- case LDBIAS_IMM_OP:
- case LDACQ_IMM_OP:
- case LDCCLR_IMM_OP:
- case LDCNC_IMM_OP:
- case LDCCLRACQ_IMM_OP:
- ret = emulate_load_int(ifa, u.insn, regs, kernel_mode);
- break;
-
- case ST_OP:
- case STREL_OP:
- if (u.insn.x)
- /* oops, really a semaphore op (cmpxchg, etc) */
- goto failure;
- fallthrough;
- case ST_IMM_OP:
- case STREL_IMM_OP:
- ret = emulate_store_int(ifa, u.insn, regs, kernel_mode);
- break;
-
- case LDF_OP:
- case LDFA_OP:
- case LDFCCLR_OP:
- case LDFCNC_OP:
- if (u.insn.x)
- ret = emulate_load_floatpair(ifa, u.insn, regs, kernel_mode);
- else
- ret = emulate_load_float(ifa, u.insn, regs, kernel_mode);
- break;
-
- case LDF_IMM_OP:
- case LDFA_IMM_OP:
- case LDFCCLR_IMM_OP:
- case LDFCNC_IMM_OP:
- ret = emulate_load_float(ifa, u.insn, regs, kernel_mode);
- break;
-
- case STF_OP:
- case STF_IMM_OP:
- ret = emulate_store_float(ifa, u.insn, regs, kernel_mode);
- break;
-
- default:
- goto failure;
- }
- DPRINT("ret=%d\n", ret);
- if (ret)
- goto failure;
-
- if (ipsr->ri == 2)
- /*
- * given today's architecture this case is not likely to happen because a
- * memory access instruction (M) can never be in the last slot of a
- * bundle. But let's keep it for now.
- */
- regs->cr_iip += 16;
- ipsr->ri = (ipsr->ri + 1) & 0x3;
-
- DPRINT("ipsr->ri=%d iip=%lx\n", ipsr->ri, regs->cr_iip);
- done:
- return;
-
- failure:
- /* something went wrong... */
- if (!user_mode(regs)) {
- if (eh) {
- ia64_handle_exception(regs, eh);
- goto done;
- }
- if (die_if_kernel("error during unaligned kernel access\n", regs, ret))
- return;
- /* NOT_REACHED */
- }
- force_sigbus:
- force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) ifa,
- 0, 0, 0);
- goto done;
-}
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
deleted file mode 100644
index a0fec82c56b8..000000000000
--- a/arch/ia64/kernel/uncached.c
+++ /dev/null
@@ -1,273 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2001-2008 Silicon Graphics, Inc. All rights reserved.
- *
- * A simple uncached page allocator using the generic allocator. This
- * allocator first utilizes the spare (spill) pages found in the EFI
- * memmap and will then start converting cached pages to uncached ones
- * at a granule at a time. Node awareness is implemented by having a
- * pool of pages per node.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/efi.h>
-#include <linux/nmi.h>
-#include <linux/genalloc.h>
-#include <linux/gfp.h>
-#include <linux/pgtable.h>
-#include <asm/efi.h>
-#include <asm/page.h>
-#include <asm/pal.h>
-#include <linux/atomic.h>
-#include <asm/tlbflush.h>
-
-struct uncached_pool {
- struct gen_pool *pool;
- struct mutex add_chunk_mutex; /* serialize adding a converted chunk */
- int nchunks_added; /* #of converted chunks added to pool */
- atomic_t status; /* smp called function's return status*/
-};
-
-#define MAX_CONVERTED_CHUNKS_PER_NODE 2
-
-struct uncached_pool uncached_pools[MAX_NUMNODES];
-
-
-static void uncached_ipi_visibility(void *data)
-{
- int status;
- struct uncached_pool *uc_pool = (struct uncached_pool *)data;
-
- status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL);
- if ((status != PAL_VISIBILITY_OK) &&
- (status != PAL_VISIBILITY_OK_REMOTE_NEEDED))
- atomic_inc(&uc_pool->status);
-}
-
-
-static void uncached_ipi_mc_drain(void *data)
-{
- int status;
- struct uncached_pool *uc_pool = (struct uncached_pool *)data;
-
- status = ia64_pal_mc_drain();
- if (status != PAL_STATUS_SUCCESS)
- atomic_inc(&uc_pool->status);
-}
-
-
-/*
- * Add a new chunk of uncached memory pages to the specified pool.
- *
- * @pool: pool to add new chunk of uncached memory to
- * @nid: node id of node to allocate memory from, or -1
- *
- * This is accomplished by first allocating a granule of cached memory pages
- * and then converting them to uncached memory pages.
- */
-static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid)
-{
- struct page *page;
- int status, i, nchunks_added = uc_pool->nchunks_added;
- unsigned long c_addr, uc_addr;
-
- if (mutex_lock_interruptible(&uc_pool->add_chunk_mutex) != 0)
- return -1; /* interrupted by a signal */
-
- if (uc_pool->nchunks_added > nchunks_added) {
- /* someone added a new chunk while we were waiting */
- mutex_unlock(&uc_pool->add_chunk_mutex);
- return 0;
- }
-
- if (uc_pool->nchunks_added >= MAX_CONVERTED_CHUNKS_PER_NODE) {
- mutex_unlock(&uc_pool->add_chunk_mutex);
- return -1;
- }
-
- /* attempt to allocate a granule's worth of cached memory pages */
-
- page = __alloc_pages_node(nid,
- GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
- IA64_GRANULE_SHIFT-PAGE_SHIFT);
- if (!page) {
- mutex_unlock(&uc_pool->add_chunk_mutex);
- return -1;
- }
-
- /* convert the memory pages from cached to uncached */
-
- c_addr = (unsigned long)page_address(page);
- uc_addr = c_addr - PAGE_OFFSET + __IA64_UNCACHED_OFFSET;
-
- /*
- * There's a small race here where it's possible for someone to
- * access the page through /dev/mem halfway through the conversion
- * to uncached - not sure it's really worth bothering about
- */
- for (i = 0; i < (IA64_GRANULE_SIZE / PAGE_SIZE); i++)
- SetPageUncached(&page[i]);
-
- flush_tlb_kernel_range(uc_addr, uc_addr + IA64_GRANULE_SIZE);
-
- status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL);
- if (status == PAL_VISIBILITY_OK_REMOTE_NEEDED) {
- atomic_set(&uc_pool->status, 0);
- smp_call_function(uncached_ipi_visibility, uc_pool, 1);
- if (atomic_read(&uc_pool->status))
- goto failed;
- } else if (status != PAL_VISIBILITY_OK)
- goto failed;
-
- preempt_disable();
-
- flush_icache_range(uc_addr, uc_addr + IA64_GRANULE_SIZE);
-
- /* flush the just introduced uncached translation from the TLB */
- local_flush_tlb_all();
-
- preempt_enable();
-
- status = ia64_pal_mc_drain();
- if (status != PAL_STATUS_SUCCESS)
- goto failed;
- atomic_set(&uc_pool->status, 0);
- smp_call_function(uncached_ipi_mc_drain, uc_pool, 1);
- if (atomic_read(&uc_pool->status))
- goto failed;
-
- /*
- * The chunk of memory pages has been converted to uncached so now we
- * can add it to the pool.
- */
- status = gen_pool_add(uc_pool->pool, uc_addr, IA64_GRANULE_SIZE, nid);
- if (status)
- goto failed;
-
- uc_pool->nchunks_added++;
- mutex_unlock(&uc_pool->add_chunk_mutex);
- return 0;
-
- /* failed to convert or add the chunk so give it back to the kernel */
-failed:
- for (i = 0; i < (IA64_GRANULE_SIZE / PAGE_SIZE); i++)
- ClearPageUncached(&page[i]);
-
- free_pages(c_addr, IA64_GRANULE_SHIFT-PAGE_SHIFT);
- mutex_unlock(&uc_pool->add_chunk_mutex);
- return -1;
-}
-
-
-/*
- * uncached_alloc_page
- *
- * @starting_nid: node id of node to start with, or -1
- * @n_pages: number of contiguous pages to allocate
- *
- * Allocate the specified number of contiguous uncached pages on the
- * requested node. If not enough contiguous uncached pages are available
- * on the requested node, roundrobin starting with the next higher node.
- */
-unsigned long uncached_alloc_page(int starting_nid, int n_pages)
-{
- unsigned long uc_addr;
- struct uncached_pool *uc_pool;
- int nid;
-
- if (unlikely(starting_nid >= MAX_NUMNODES))
- return 0;
-
- if (starting_nid < 0)
- starting_nid = numa_node_id();
- nid = starting_nid;
-
- do {
- if (!node_state(nid, N_HIGH_MEMORY))
- continue;
- uc_pool = &uncached_pools[nid];
- if (uc_pool->pool == NULL)
- continue;
- do {
- uc_addr = gen_pool_alloc(uc_pool->pool,
- n_pages * PAGE_SIZE);
- if (uc_addr != 0)
- return uc_addr;
- } while (uncached_add_chunk(uc_pool, nid) == 0);
-
- } while ((nid = (nid + 1) % MAX_NUMNODES) != starting_nid);
-
- return 0;
-}
-EXPORT_SYMBOL(uncached_alloc_page);
-
-
-/*
- * uncached_free_page
- *
- * @uc_addr: uncached address of first page to free
- * @n_pages: number of contiguous pages to free
- *
- * Free the specified number of uncached pages.
- */
-void uncached_free_page(unsigned long uc_addr, int n_pages)
-{
- int nid = paddr_to_nid(uc_addr - __IA64_UNCACHED_OFFSET);
- struct gen_pool *pool = uncached_pools[nid].pool;
-
- if (unlikely(pool == NULL))
- return;
-
- if ((uc_addr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET)
- panic("uncached_free_page invalid address %lx\n", uc_addr);
-
- gen_pool_free(pool, uc_addr, n_pages * PAGE_SIZE);
-}
-EXPORT_SYMBOL(uncached_free_page);
-
-
-/*
- * uncached_build_memmap,
- *
- * @uc_start: uncached starting address of a chunk of uncached memory
- * @uc_end: uncached ending address of a chunk of uncached memory
- * @arg: ignored, (NULL argument passed in on call to efi_memmap_walk_uc())
- *
- * Called at boot time to build a map of pages that can be used for
- * memory special operations.
- */
-static int __init uncached_build_memmap(u64 uc_start, u64 uc_end, void *arg)
-{
- int nid = paddr_to_nid(uc_start - __IA64_UNCACHED_OFFSET);
- struct gen_pool *pool = uncached_pools[nid].pool;
- size_t size = uc_end - uc_start;
-
- touch_softlockup_watchdog();
-
- if (pool != NULL) {
- memset((char *)uc_start, 0, size);
- (void) gen_pool_add(pool, uc_start, size, nid);
- }
- return 0;
-}
-
-
-static int __init uncached_init(void)
-{
- int nid;
-
- for_each_online_node(nid) {
- uncached_pools[nid].pool = gen_pool_create(PAGE_SHIFT, nid);
- mutex_init(&uncached_pools[nid].add_chunk_mutex);
- }
-
- efi_memmap_walk_uc(uncached_build_memmap, NULL);
- return 0;
-}
-
-__initcall(uncached_init);
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
deleted file mode 100644
index 6bd64c35e691..000000000000
--- a/arch/ia64/kernel/unwind.c
+++ /dev/null
@@ -1,2320 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 1999-2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2003 Fenghua Yu <fenghua.yu@intel.com>
- * - Change pt_regs_off() to make it less dependent on pt_regs structure.
- */
-/*
- * This file implements call frame unwind support for the Linux
- * kernel. Parsing and processing the unwind information is
- * time-consuming, so this implementation translates the unwind
- * descriptors into unwind scripts. These scripts are very simple
- * (basically a sequence of assignments) and efficient to execute.
- * They are cached for later re-use. Each script is specific for a
- * given instruction pointer address and the set of predicate values
- * that the script depends on (most unwind descriptors are
- * unconditional and scripts often do not depend on predicates at
- * all). This code is based on the unwind conventions described in
- * the "IA-64 Software Conventions and Runtime Architecture" manual.
- *
- * SMP conventions:
- * o updates to the global unwind data (in structure "unw") are serialized
- * by the unw.lock spinlock
- * o each unwind script has its own read-write lock; a thread must acquire
- * a read lock before executing a script and must acquire a write lock
- * before modifying a script
- * o if both the unw.lock spinlock and a script's read-write lock must be
- * acquired, then the read-write lock must be acquired first.
- */
-#include <linux/module.h>
-#include <linux/memblock.h>
-#include <linux/elf.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <asm/unwind.h>
-
-#include <asm/delay.h>
-#include <asm/page.h>
-#include <asm/ptrace.h>
-#include <asm/ptrace_offsets.h>
-#include <asm/rse.h>
-#include <asm/sections.h>
-#include <linux/uaccess.h>
-
-#include "entry.h"
-#include "unwind_i.h"
-
-#define UNW_LOG_CACHE_SIZE 7 /* each unw_script is ~256 bytes in size */
-#define UNW_CACHE_SIZE (1 << UNW_LOG_CACHE_SIZE)
-
-#define UNW_LOG_HASH_SIZE (UNW_LOG_CACHE_SIZE + 1)
-#define UNW_HASH_SIZE (1 << UNW_LOG_HASH_SIZE)
-
-#define UNW_STATS 0 /* WARNING: this disabled interrupts for long time-spans!! */
-
-#ifdef UNW_DEBUG
- static unsigned int unw_debug_level = UNW_DEBUG;
-# define UNW_DEBUG_ON(n) unw_debug_level >= n
- /* Do not code a printk level, not all debug lines end in newline */
-# define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__)
-# undef inline
-# define inline
-#else /* !UNW_DEBUG */
-# define UNW_DEBUG_ON(n) 0
-# define UNW_DPRINT(n, ...)
-#endif /* UNW_DEBUG */
-
-#if UNW_STATS
-# define STAT(x...) x
-#else
-# define STAT(x...)
-#endif
-
-#define alloc_reg_state() kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC)
-#define free_reg_state(usr) kfree(usr)
-#define alloc_labeled_state() kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC)
-#define free_labeled_state(usr) kfree(usr)
-
-typedef unsigned long unw_word;
-typedef unsigned char unw_hash_index_t;
-
-static struct {
- spinlock_t lock; /* spinlock for unwind data */
-
- /* list of unwind tables (one per load-module) */
- struct unw_table *tables;
-
- unsigned long r0; /* constant 0 for r0 */
-
- /* table of registers that prologues can save (and order in which they're saved): */
- const unsigned char save_order[8];
-
- /* maps a preserved register index (preg_index) to corresponding switch_stack offset: */
- unsigned short sw_off[sizeof(struct unw_frame_info) / 8];
-
- unsigned short lru_head; /* index of lead-recently used script */
- unsigned short lru_tail; /* index of most-recently used script */
-
- /* index into unw_frame_info for preserved register i */
- unsigned short preg_index[UNW_NUM_REGS];
-
- short pt_regs_offsets[32];
-
- /* unwind table for the kernel: */
- struct unw_table kernel_table;
-
- /* unwind table describing the gate page (kernel code that is mapped into user space): */
- size_t gate_table_size;
- unsigned long *gate_table;
-
- /* hash table that maps instruction pointer to script index: */
- unsigned short hash[UNW_HASH_SIZE];
-
- /* script cache: */
- struct unw_script cache[UNW_CACHE_SIZE];
-
-# ifdef UNW_DEBUG
- const char *preg_name[UNW_NUM_REGS];
-# endif
-# if UNW_STATS
- struct {
- struct {
- int lookups;
- int hinted_hits;
- int normal_hits;
- int collision_chain_traversals;
- } cache;
- struct {
- unsigned long build_time;
- unsigned long run_time;
- unsigned long parse_time;
- int builds;
- int news;
- int collisions;
- int runs;
- } script;
- struct {
- unsigned long init_time;
- unsigned long unwind_time;
- int inits;
- int unwinds;
- } api;
- } stat;
-# endif
-} unw = {
- .tables = &unw.kernel_table,
- .lock = __SPIN_LOCK_UNLOCKED(unw.lock),
- .save_order = {
- UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
- UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
- },
- .preg_index = {
- offsetof(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_GR */
- offsetof(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_MEM */
- offsetof(struct unw_frame_info, bsp_loc)/8,
- offsetof(struct unw_frame_info, bspstore_loc)/8,
- offsetof(struct unw_frame_info, pfs_loc)/8,
- offsetof(struct unw_frame_info, rnat_loc)/8,
- offsetof(struct unw_frame_info, psp)/8,
- offsetof(struct unw_frame_info, rp_loc)/8,
- offsetof(struct unw_frame_info, r4)/8,
- offsetof(struct unw_frame_info, r5)/8,
- offsetof(struct unw_frame_info, r6)/8,
- offsetof(struct unw_frame_info, r7)/8,
- offsetof(struct unw_frame_info, unat_loc)/8,
- offsetof(struct unw_frame_info, pr_loc)/8,
- offsetof(struct unw_frame_info, lc_loc)/8,
- offsetof(struct unw_frame_info, fpsr_loc)/8,
- offsetof(struct unw_frame_info, b1_loc)/8,
- offsetof(struct unw_frame_info, b2_loc)/8,
- offsetof(struct unw_frame_info, b3_loc)/8,
- offsetof(struct unw_frame_info, b4_loc)/8,
- offsetof(struct unw_frame_info, b5_loc)/8,
- offsetof(struct unw_frame_info, f2_loc)/8,
- offsetof(struct unw_frame_info, f3_loc)/8,
- offsetof(struct unw_frame_info, f4_loc)/8,
- offsetof(struct unw_frame_info, f5_loc)/8,
- offsetof(struct unw_frame_info, fr_loc[16 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[17 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[18 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[19 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[20 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[21 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[22 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[23 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[24 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[25 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[26 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[27 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[28 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[29 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[30 - 16])/8,
- offsetof(struct unw_frame_info, fr_loc[31 - 16])/8,
- },
- .pt_regs_offsets = {
- [0] = -1,
- offsetof(struct pt_regs, r1),
- offsetof(struct pt_regs, r2),
- offsetof(struct pt_regs, r3),
- [4] = -1, [5] = -1, [6] = -1, [7] = -1,
- offsetof(struct pt_regs, r8),
- offsetof(struct pt_regs, r9),
- offsetof(struct pt_regs, r10),
- offsetof(struct pt_regs, r11),
- offsetof(struct pt_regs, r12),
- offsetof(struct pt_regs, r13),
- offsetof(struct pt_regs, r14),
- offsetof(struct pt_regs, r15),
- offsetof(struct pt_regs, r16),
- offsetof(struct pt_regs, r17),
- offsetof(struct pt_regs, r18),
- offsetof(struct pt_regs, r19),
- offsetof(struct pt_regs, r20),
- offsetof(struct pt_regs, r21),
- offsetof(struct pt_regs, r22),
- offsetof(struct pt_regs, r23),
- offsetof(struct pt_regs, r24),
- offsetof(struct pt_regs, r25),
- offsetof(struct pt_regs, r26),
- offsetof(struct pt_regs, r27),
- offsetof(struct pt_regs, r28),
- offsetof(struct pt_regs, r29),
- offsetof(struct pt_regs, r30),
- offsetof(struct pt_regs, r31),
- },
- .hash = { [0 ... UNW_HASH_SIZE - 1] = -1 },
-#ifdef UNW_DEBUG
- .preg_name = {
- "pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat", "psp", "rp",
- "r4", "r5", "r6", "r7",
- "ar.unat", "pr", "ar.lc", "ar.fpsr",
- "b1", "b2", "b3", "b4", "b5",
- "f2", "f3", "f4", "f5",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
- }
-#endif
-};
-
-static inline int
-read_only (void *addr)
-{
- return (unsigned long) ((char *) addr - (char *) &unw.r0) < sizeof(unw.r0);
-}
-
-/*
- * Returns offset of rREG in struct pt_regs.
- */
-static inline unsigned long
-pt_regs_off (unsigned long reg)
-{
- short off = -1;
-
- if (reg < ARRAY_SIZE(unw.pt_regs_offsets))
- off = unw.pt_regs_offsets[reg];
-
- if (off < 0) {
- UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __func__, reg);
- off = 0;
- }
- return (unsigned long) off;
-}
-
-static inline struct pt_regs *
-get_scratch_regs (struct unw_frame_info *info)
-{
- if (!info->pt) {
- /* This should not happen with valid unwind info. */
- UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __func__);
- if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
- info->pt = (unsigned long) ((struct pt_regs *) info->psp - 1);
- else
- info->pt = info->sp - 16;
- }
- UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __func__, info->sp, info->pt);
- return (struct pt_regs *) info->pt;
-}
-
-/* Unwind accessors. */
-
-int
-unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char *nat, int write)
-{
- unsigned long *addr, *nat_addr, nat_mask = 0, dummy_nat;
- struct unw_ireg *ireg;
- struct pt_regs *pt;
-
- if ((unsigned) regnum - 1 >= 127) {
- if (regnum == 0 && !write) {
- *val = 0; /* read r0 always returns 0 */
- *nat = 0;
- return 0;
- }
- UNW_DPRINT(0, "unwind.%s: trying to access non-existent r%u\n",
- __func__, regnum);
- return -1;
- }
-
- if (regnum < 32) {
- if (regnum >= 4 && regnum <= 7) {
- /* access a preserved register */
- ireg = &info->r4 + (regnum - 4);
- addr = ireg->loc;
- if (addr) {
- nat_addr = addr + ireg->nat.off;
- switch (ireg->nat.type) {
- case UNW_NAT_VAL:
- /* simulate getf.sig/setf.sig */
- if (write) {
- if (*nat) {
- /* write NaTVal and be done with it */
- addr[0] = 0;
- addr[1] = 0x1fffe;
- return 0;
- }
- addr[1] = 0x1003e;
- } else {
- if (addr[0] == 0 && addr[1] == 0x1ffe) {
- /* return NaT and be done with it */
- *val = 0;
- *nat = 1;
- return 0;
- }
- }
- fallthrough;
- case UNW_NAT_NONE:
- dummy_nat = 0;
- nat_addr = &dummy_nat;
- break;
-
- case UNW_NAT_MEMSTK:
- nat_mask = (1UL << ((long) addr & 0x1f8)/8);
- break;
-
- case UNW_NAT_REGSTK:
- nat_addr = ia64_rse_rnat_addr(addr);
- if ((unsigned long) addr < info->regstk.limit
- || (unsigned long) addr >= info->regstk.top)
- {
- UNW_DPRINT(0, "unwind.%s: %p outside of regstk "
- "[0x%lx-0x%lx)\n",
- __func__, (void *) addr,
- info->regstk.limit,
- info->regstk.top);
- return -1;
- }
- if ((unsigned long) nat_addr >= info->regstk.top)
- nat_addr = &info->sw->ar_rnat;
- nat_mask = (1UL << ia64_rse_slot_num(addr));
- break;
- }
- } else {
- addr = &info->sw->r4 + (regnum - 4);
- nat_addr = &info->sw->ar_unat;
- nat_mask = (1UL << ((long) addr & 0x1f8)/8);
- }
- } else {
- /* access a scratch register */
- pt = get_scratch_regs(info);
- addr = (unsigned long *) ((unsigned long)pt + pt_regs_off(regnum));
- if (info->pri_unat_loc)
- nat_addr = info->pri_unat_loc;
- else
- nat_addr = &info->sw->caller_unat;
- nat_mask = (1UL << ((long) addr & 0x1f8)/8);
- }
- } else {
- /* access a stacked register */
- addr = ia64_rse_skip_regs((unsigned long *) info->bsp, regnum - 32);
- nat_addr = ia64_rse_rnat_addr(addr);
- if ((unsigned long) addr < info->regstk.limit
- || (unsigned long) addr >= info->regstk.top)
- {
- UNW_DPRINT(0, "unwind.%s: ignoring attempt to access register outside "
- "of rbs\n", __func__);
- return -1;
- }
- if ((unsigned long) nat_addr >= info->regstk.top)
- nat_addr = &info->sw->ar_rnat;
- nat_mask = (1UL << ia64_rse_slot_num(addr));
- }
-
- if (write) {
- if (read_only(addr)) {
- UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __func__);
- } else {
- *addr = *val;
- if (*nat)
- *nat_addr |= nat_mask;
- else
- *nat_addr &= ~nat_mask;
- }
- } else {
- if ((*nat_addr & nat_mask) == 0) {
- *val = *addr;
- *nat = 0;
- } else {
- *val = 0; /* if register is a NaT, *addr may contain kernel data! */
- *nat = 1;
- }
- }
- return 0;
-}
-EXPORT_SYMBOL(unw_access_gr);
-
-int
-unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int write)
-{
- unsigned long *addr;
- struct pt_regs *pt;
-
- switch (regnum) {
- /* scratch: */
- case 0: pt = get_scratch_regs(info); addr = &pt->b0; break;
- case 6: pt = get_scratch_regs(info); addr = &pt->b6; break;
- case 7: pt = get_scratch_regs(info); addr = &pt->b7; break;
-
- /* preserved: */
- case 1: case 2: case 3: case 4: case 5:
- addr = *(&info->b1_loc + (regnum - 1));
- if (!addr)
- addr = &info->sw->b1 + (regnum - 1);
- break;
-
- default:
- UNW_DPRINT(0, "unwind.%s: trying to access non-existent b%u\n",
- __func__, regnum);
- return -1;
- }
- if (write)
- if (read_only(addr)) {
- UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __func__);
- } else
- *addr = *val;
- else
- *val = *addr;
- return 0;
-}
-EXPORT_SYMBOL(unw_access_br);
-
-int
-unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, int write)
-{
- struct ia64_fpreg *addr = NULL;
- struct pt_regs *pt;
-
- if ((unsigned) (regnum - 2) >= 126) {
- UNW_DPRINT(0, "unwind.%s: trying to access non-existent f%u\n",
- __func__, regnum);
- return -1;
- }
-
- if (regnum <= 5) {
- addr = *(&info->f2_loc + (regnum - 2));
- if (!addr)
- addr = &info->sw->f2 + (regnum - 2);
- } else if (regnum <= 15) {
- if (regnum <= 11) {
- pt = get_scratch_regs(info);
- addr = &pt->f6 + (regnum - 6);
- }
- else
- addr = &info->sw->f12 + (regnum - 12);
- } else if (regnum <= 31) {
- addr = info->fr_loc[regnum - 16];
- if (!addr)
- addr = &info->sw->f16 + (regnum - 16);
- } else {
- struct task_struct *t = info->task;
-
- if (write)
- ia64_sync_fph(t);
- else
- ia64_flush_fph(t);
- addr = t->thread.fph + (regnum - 32);
- }
-
- if (write)
- if (read_only(addr)) {
- UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __func__);
- } else
- *addr = *val;
- else
- *val = *addr;
- return 0;
-}
-EXPORT_SYMBOL(unw_access_fr);
-
-int
-unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int write)
-{
- unsigned long *addr;
- struct pt_regs *pt;
-
- switch (regnum) {
- case UNW_AR_BSP:
- addr = info->bsp_loc;
- if (!addr)
- addr = &info->sw->ar_bspstore;
- break;
-
- case UNW_AR_BSPSTORE:
- addr = info->bspstore_loc;
- if (!addr)
- addr = &info->sw->ar_bspstore;
- break;
-
- case UNW_AR_PFS:
- addr = info->pfs_loc;
- if (!addr)
- addr = &info->sw->ar_pfs;
- break;
-
- case UNW_AR_RNAT:
- addr = info->rnat_loc;
- if (!addr)
- addr = &info->sw->ar_rnat;
- break;
-
- case UNW_AR_UNAT:
- addr = info->unat_loc;
- if (!addr)
- addr = &info->sw->caller_unat;
- break;
-
- case UNW_AR_LC:
- addr = info->lc_loc;
- if (!addr)
- addr = &info->sw->ar_lc;
- break;
-
- case UNW_AR_EC:
- if (!info->cfm_loc)
- return -1;
- if (write)
- *info->cfm_loc =
- (*info->cfm_loc & ~(0x3fUL << 52)) | ((*val & 0x3f) << 52);
- else
- *val = (*info->cfm_loc >> 52) & 0x3f;
- return 0;
-
- case UNW_AR_FPSR:
- addr = info->fpsr_loc;
- if (!addr)
- addr = &info->sw->ar_fpsr;
- break;
-
- case UNW_AR_RSC:
- pt = get_scratch_regs(info);
- addr = &pt->ar_rsc;
- break;
-
- case UNW_AR_CCV:
- pt = get_scratch_regs(info);
- addr = &pt->ar_ccv;
- break;
-
- case UNW_AR_CSD:
- pt = get_scratch_regs(info);
- addr = &pt->ar_csd;
- break;
-
- case UNW_AR_SSD:
- pt = get_scratch_regs(info);
- addr = &pt->ar_ssd;
- break;
-
- default:
- UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n",
- __func__, regnum);
- return -1;
- }
-
- if (write) {
- if (read_only(addr)) {
- UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __func__);
- } else
- *addr = *val;
- } else
- *val = *addr;
- return 0;
-}
-EXPORT_SYMBOL(unw_access_ar);
-
-int
-unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write)
-{
- unsigned long *addr;
-
- addr = info->pr_loc;
- if (!addr)
- addr = &info->sw->pr;
-
- if (write) {
- if (read_only(addr)) {
- UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
- __func__);
- } else
- *addr = *val;
- } else
- *val = *addr;
- return 0;
-}
-EXPORT_SYMBOL(unw_access_pr);
-
-
-/* Routines to manipulate the state stack. */
-
-static inline void
-push (struct unw_state_record *sr)
-{
- struct unw_reg_state *rs;
-
- rs = alloc_reg_state();
- if (!rs) {
- printk(KERN_ERR "unwind: cannot stack reg state!\n");
- return;
- }
- memcpy(rs, &sr->curr, sizeof(*rs));
- sr->curr.next = rs;
-}
-
-static void
-pop (struct unw_state_record *sr)
-{
- struct unw_reg_state *rs = sr->curr.next;
-
- if (!rs) {
- printk(KERN_ERR "unwind: stack underflow!\n");
- return;
- }
- memcpy(&sr->curr, rs, sizeof(*rs));
- free_reg_state(rs);
-}
-
-/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
-static struct unw_reg_state *
-dup_state_stack (struct unw_reg_state *rs)
-{
- struct unw_reg_state *copy, *prev = NULL, *first = NULL;
-
- while (rs) {
- copy = alloc_reg_state();
- if (!copy) {
- printk(KERN_ERR "unwind.dup_state_stack: out of memory\n");
- return NULL;
- }
- memcpy(copy, rs, sizeof(*copy));
- if (first)
- prev->next = copy;
- else
- first = copy;
- rs = rs->next;
- prev = copy;
- }
- return first;
-}
-
-/* Free all stacked register states (but not RS itself). */
-static void
-free_state_stack (struct unw_reg_state *rs)
-{
- struct unw_reg_state *p, *next;
-
- for (p = rs->next; p != NULL; p = next) {
- next = p->next;
- free_reg_state(p);
- }
- rs->next = NULL;
-}
-
-/* Unwind decoder routines */
-
-static enum unw_register_index __attribute_const__
-decode_abreg (unsigned char abreg, int memory)
-{
- switch (abreg) {
- case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04);
- case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22);
- case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30);
- case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41);
- case 0x60: return UNW_REG_PR;
- case 0x61: return UNW_REG_PSP;
- case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR;
- case 0x63: return UNW_REG_RP;
- case 0x64: return UNW_REG_BSP;
- case 0x65: return UNW_REG_BSPSTORE;
- case 0x66: return UNW_REG_RNAT;
- case 0x67: return UNW_REG_UNAT;
- case 0x68: return UNW_REG_FPSR;
- case 0x69: return UNW_REG_PFS;
- case 0x6a: return UNW_REG_LC;
- default:
- break;
- }
- UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __func__, abreg);
- return UNW_REG_LC;
-}
-
-static void
-set_reg (struct unw_reg_info *reg, enum unw_where where, int when, unsigned long val)
-{
- reg->val = val;
- reg->where = where;
- if (reg->when == UNW_WHEN_NEVER)
- reg->when = when;
-}
-
-static void
-alloc_spill_area (unsigned long *offp, unsigned long regsize,
- struct unw_reg_info *lo, struct unw_reg_info *hi)
-{
- struct unw_reg_info *reg;
-
- for (reg = hi; reg >= lo; --reg) {
- if (reg->where == UNW_WHERE_SPILL_HOME) {
- reg->where = UNW_WHERE_PSPREL;
- *offp -= regsize;
- reg->val = *offp;
- }
- }
-}
-
-static inline void
-spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, unw_word t)
-{
- struct unw_reg_info *reg;
-
- for (reg = *regp; reg <= lim; ++reg) {
- if (reg->where == UNW_WHERE_SPILL_HOME) {
- reg->when = t;
- *regp = reg + 1;
- return;
- }
- }
- UNW_DPRINT(0, "unwind.%s: excess spill!\n", __func__);
-}
-
-static inline void
-finish_prologue (struct unw_state_record *sr)
-{
- struct unw_reg_info *reg;
- unsigned long off;
- int i;
-
- /*
- * First, resolve implicit register save locations (see Section "11.4.2.3 Rules
- * for Using Unwind Descriptors", rule 3):
- */
- for (i = 0; i < (int) ARRAY_SIZE(unw.save_order); ++i) {
- reg = sr->curr.reg + unw.save_order[i];
- if (reg->where == UNW_WHERE_GR_SAVE) {
- reg->where = UNW_WHERE_GR;
- reg->val = sr->gr_save_loc++;
- }
- }
-
- /*
- * Next, compute when the fp, general, and branch registers get
- * saved. This must come before alloc_spill_area() because
- * we need to know which registers are spilled to their home
- * locations.
- */
- if (sr->imask) {
- unsigned char kind, mask = 0, *cp = sr->imask;
- int t;
- static const unsigned char limit[3] = {
- UNW_REG_F31, UNW_REG_R7, UNW_REG_B5
- };
- struct unw_reg_info *(regs[3]);
-
- regs[0] = sr->curr.reg + UNW_REG_F2;
- regs[1] = sr->curr.reg + UNW_REG_R4;
- regs[2] = sr->curr.reg + UNW_REG_B1;
-
- for (t = 0; t < sr->region_len; ++t) {
- if ((t & 3) == 0)
- mask = *cp++;
- kind = (mask >> 2*(3-(t & 3))) & 3;
- if (kind > 0)
- spill_next_when(&regs[kind - 1], sr->curr.reg + limit[kind - 1],
- sr->region_start + t);
- }
- }
- /*
- * Next, lay out the memory stack spill area:
- */
- if (sr->any_spills) {
- off = sr->spill_offset;
- alloc_spill_area(&off, 16, sr->curr.reg + UNW_REG_F2, sr->curr.reg + UNW_REG_F31);
- alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_B1, sr->curr.reg + UNW_REG_B5);
- alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_R4, sr->curr.reg + UNW_REG_R7);
- }
-}
-
-/*
- * Region header descriptors.
- */
-
-static void
-desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave,
- struct unw_state_record *sr)
-{
- int i, region_start;
-
- if (!(sr->in_body || sr->first_region))
- finish_prologue(sr);
- sr->first_region = 0;
-
- /* check if we're done: */
- if (sr->when_target < sr->region_start + sr->region_len) {
- sr->done = 1;
- return;
- }
-
- region_start = sr->region_start + sr->region_len;
-
- for (i = 0; i < sr->epilogue_count; ++i)
- pop(sr);
- sr->epilogue_count = 0;
- sr->epilogue_start = UNW_WHEN_NEVER;
-
- sr->region_start = region_start;
- sr->region_len = rlen;
- sr->in_body = body;
-
- if (!body) {
- push(sr);
-
- for (i = 0; i < 4; ++i) {
- if (mask & 0x8)
- set_reg(sr->curr.reg + unw.save_order[i], UNW_WHERE_GR,
- sr->region_start + sr->region_len - 1, grsave++);
- mask <<= 1;
- }
- sr->gr_save_loc = grsave;
- sr->any_spills = 0;
- sr->imask = NULL;
- sr->spill_offset = 0x10; /* default to psp+16 */
- }
-}
-
-/*
- * Prologue descriptors.
- */
-
-static inline void
-desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr)
-{
- if (abi == 3 && context == 'i') {
- sr->flags |= UNW_FLAG_INTERRUPT_FRAME;
- UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __func__);
- }
- else
- UNW_DPRINT(0, "unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)\n",
- __func__, abi, context);
-}
-
-static inline void
-desc_br_gr (unsigned char brmask, unsigned char gr, struct unw_state_record *sr)
-{
- int i;
-
- for (i = 0; i < 5; ++i) {
- if (brmask & 1)
- set_reg(sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR,
- sr->region_start + sr->region_len - 1, gr++);
- brmask >>= 1;
- }
-}
-
-static inline void
-desc_br_mem (unsigned char brmask, struct unw_state_record *sr)
-{
- int i;
-
- for (i = 0; i < 5; ++i) {
- if (brmask & 1) {
- set_reg(sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME,
- sr->region_start + sr->region_len - 1, 0);
- sr->any_spills = 1;
- }
- brmask >>= 1;
- }
-}
-
-static inline void
-desc_frgr_mem (unsigned char grmask, unw_word frmask, struct unw_state_record *sr)
-{
- int i;
-
- for (i = 0; i < 4; ++i) {
- if ((grmask & 1) != 0) {
- set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
- sr->region_start + sr->region_len - 1, 0);
- sr->any_spills = 1;
- }
- grmask >>= 1;
- }
- for (i = 0; i < 20; ++i) {
- if ((frmask & 1) != 0) {
- int base = (i < 4) ? UNW_REG_F2 : UNW_REG_F16 - 4;
- set_reg(sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
- sr->region_start + sr->region_len - 1, 0);
- sr->any_spills = 1;
- }
- frmask >>= 1;
- }
-}
-
-static inline void
-desc_fr_mem (unsigned char frmask, struct unw_state_record *sr)
-{
- int i;
-
- for (i = 0; i < 4; ++i) {
- if ((frmask & 1) != 0) {
- set_reg(sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
- sr->region_start + sr->region_len - 1, 0);
- sr->any_spills = 1;
- }
- frmask >>= 1;
- }
-}
-
-static inline void
-desc_gr_gr (unsigned char grmask, unsigned char gr, struct unw_state_record *sr)
-{
- int i;
-
- for (i = 0; i < 4; ++i) {
- if ((grmask & 1) != 0)
- set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR,
- sr->region_start + sr->region_len - 1, gr++);
- grmask >>= 1;
- }
-}
-
-static inline void
-desc_gr_mem (unsigned char grmask, struct unw_state_record *sr)
-{
- int i;
-
- for (i = 0; i < 4; ++i) {
- if ((grmask & 1) != 0) {
- set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
- sr->region_start + sr->region_len - 1, 0);
- sr->any_spills = 1;
- }
- grmask >>= 1;
- }
-}
-
-static inline void
-desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr)
-{
- set_reg(sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE,
- sr->region_start + min_t(int, t, sr->region_len - 1), 16*size);
-}
-
-static inline void
-desc_mem_stack_v (unw_word t, struct unw_state_record *sr)
-{
- sr->curr.reg[UNW_REG_PSP].when = sr->region_start + min_t(int, t, sr->region_len - 1);
-}
-
-static inline void
-desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr)
-{
- set_reg(sr->curr.reg + reg, UNW_WHERE_GR, sr->region_start + sr->region_len - 1, dst);
-}
-
-static inline void
-desc_reg_psprel (unsigned char reg, unw_word pspoff, struct unw_state_record *sr)
-{
- set_reg(sr->curr.reg + reg, UNW_WHERE_PSPREL, sr->region_start + sr->region_len - 1,
- 0x10 - 4*pspoff);
-}
-
-static inline void
-desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr)
-{
- set_reg(sr->curr.reg + reg, UNW_WHERE_SPREL, sr->region_start + sr->region_len - 1,
- 4*spoff);
-}
-
-static inline void
-desc_rp_br (unsigned char dst, struct unw_state_record *sr)
-{
- sr->return_link_reg = dst;
-}
-
-static inline void
-desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr)
-{
- struct unw_reg_info *reg = sr->curr.reg + regnum;
-
- if (reg->where == UNW_WHERE_NONE)
- reg->where = UNW_WHERE_GR_SAVE;
- reg->when = sr->region_start + min_t(int, t, sr->region_len - 1);
-}
-
-static inline void
-desc_spill_base (unw_word pspoff, struct unw_state_record *sr)
-{
- sr->spill_offset = 0x10 - 4*pspoff;
-}
-
-static inline unsigned char *
-desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr)
-{
- sr->imask = imaskp;
- return imaskp + (2*sr->region_len + 7)/8;
-}
-
-/*
- * Body descriptors.
- */
-static inline void
-desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
-{
- sr->epilogue_start = sr->region_start + sr->region_len - 1 - t;
- sr->epilogue_count = ecount + 1;
-}
-
-static inline void
-desc_copy_state (unw_word label, struct unw_state_record *sr)
-{
- struct unw_labeled_state *ls;
-
- for (ls = sr->labeled_states; ls; ls = ls->next) {
- if (ls->label == label) {
- free_state_stack(&sr->curr);
- memcpy(&sr->curr, &ls->saved_state, sizeof(sr->curr));
- sr->curr.next = dup_state_stack(ls->saved_state.next);
- return;
- }
- }
- printk(KERN_ERR "unwind: failed to find state labeled 0x%lx\n", label);
-}
-
-static inline void
-desc_label_state (unw_word label, struct unw_state_record *sr)
-{
- struct unw_labeled_state *ls;
-
- ls = alloc_labeled_state();
- if (!ls) {
- printk(KERN_ERR "unwind.desc_label_state(): out of memory\n");
- return;
- }
- ls->label = label;
- memcpy(&ls->saved_state, &sr->curr, sizeof(ls->saved_state));
- ls->saved_state.next = dup_state_stack(sr->curr.next);
-
- /* insert into list of labeled states: */
- ls->next = sr->labeled_states;
- sr->labeled_states = ls;
-}
-
-/*
- * General descriptors.
- */
-
-static inline int
-desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr)
-{
- if (sr->when_target <= sr->region_start + min_t(int, t, sr->region_len - 1))
- return 0;
- if (qp > 0) {
- if ((sr->pr_val & (1UL << qp)) == 0)
- return 0;
- sr->pr_mask |= (1UL << qp);
- }
- return 1;
-}
-
-static inline void
-desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, struct unw_state_record *sr)
-{
- struct unw_reg_info *r;
-
- if (!desc_is_active(qp, t, sr))
- return;
-
- r = sr->curr.reg + decode_abreg(abreg, 0);
- r->where = UNW_WHERE_NONE;
- r->when = UNW_WHEN_NEVER;
- r->val = 0;
-}
-
-static inline void
-desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, unsigned char x,
- unsigned char ytreg, struct unw_state_record *sr)
-{
- enum unw_where where = UNW_WHERE_GR;
- struct unw_reg_info *r;
-
- if (!desc_is_active(qp, t, sr))
- return;
-
- if (x)
- where = UNW_WHERE_BR;
- else if (ytreg & 0x80)
- where = UNW_WHERE_FR;
-
- r = sr->curr.reg + decode_abreg(abreg, 0);
- r->where = where;
- r->when = sr->region_start + min_t(int, t, sr->region_len - 1);
- r->val = (ytreg & 0x7f);
-}
-
-static inline void
-desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word pspoff,
- struct unw_state_record *sr)
-{
- struct unw_reg_info *r;
-
- if (!desc_is_active(qp, t, sr))
- return;
-
- r = sr->curr.reg + decode_abreg(abreg, 1);
- r->where = UNW_WHERE_PSPREL;
- r->when = sr->region_start + min_t(int, t, sr->region_len - 1);
- r->val = 0x10 - 4*pspoff;
-}
-
-static inline void
-desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word spoff,
- struct unw_state_record *sr)
-{
- struct unw_reg_info *r;
-
- if (!desc_is_active(qp, t, sr))
- return;
-
- r = sr->curr.reg + decode_abreg(abreg, 1);
- r->where = UNW_WHERE_SPREL;
- r->when = sr->region_start + min_t(int, t, sr->region_len - 1);
- r->val = 4*spoff;
-}
-
-#define UNW_DEC_BAD_CODE(code) printk(KERN_ERR "unwind: unknown code 0x%02x\n", \
- code);
-
-/*
- * region headers:
- */
-#define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
-#define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
-/*
- * prologue descriptors:
- */
-#define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
-#define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
-#define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
-#define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
-#define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
-#define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
-#define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
-#define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
-#define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
-#define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
-#define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
-#define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
-#define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
-#define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
-#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
-#define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
-#define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
-#define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
-#define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
-#define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
-#define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
-/*
- * body descriptors:
- */
-#define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
-#define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
-#define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
-/*
- * general unwind descriptors:
- */
-#define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
-#define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
-#define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
-#define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
-#define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
-#define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
-#define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
-#define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
-
-#include "unwind_decoder.c"
-
-
-/* Unwind scripts. */
-
-static inline unw_hash_index_t
-hash (unsigned long ip)
-{
- /* magic number = ((sqrt(5)-1)/2)*2^64 */
- static const unsigned long hashmagic = 0x9e3779b97f4a7c16UL;
-
- return (ip >> 4) * hashmagic >> (64 - UNW_LOG_HASH_SIZE);
-}
-
-static inline long
-cache_match (struct unw_script *script, unsigned long ip, unsigned long pr)
-{
- read_lock(&script->lock);
- if (ip == script->ip && ((pr ^ script->pr_val) & script->pr_mask) == 0)
- /* keep the read lock... */
- return 1;
- read_unlock(&script->lock);
- return 0;
-}
-
-static inline struct unw_script *
-script_lookup (struct unw_frame_info *info)
-{
- struct unw_script *script = unw.cache + info->hint;
- unsigned short index;
- unsigned long ip, pr;
-
- if (UNW_DEBUG_ON(0))
- return NULL; /* Always regenerate scripts in debug mode */
-
- STAT(++unw.stat.cache.lookups);
-
- ip = info->ip;
- pr = info->pr;
-
- if (cache_match(script, ip, pr)) {
- STAT(++unw.stat.cache.hinted_hits);
- return script;
- }
-
- index = unw.hash[hash(ip)];
- if (index >= UNW_CACHE_SIZE)
- return NULL;
-
- script = unw.cache + index;
- while (1) {
- if (cache_match(script, ip, pr)) {
- /* update hint; no locking required as single-word writes are atomic */
- STAT(++unw.stat.cache.normal_hits);
- unw.cache[info->prev_script].hint = script - unw.cache;
- return script;
- }
- if (script->coll_chain >= UNW_HASH_SIZE)
- return NULL;
- script = unw.cache + script->coll_chain;
- STAT(++unw.stat.cache.collision_chain_traversals);
- }
-}
-
-/*
- * On returning, a write lock for the SCRIPT is still being held.
- */
-static inline struct unw_script *
-script_new (unsigned long ip)
-{
- struct unw_script *script, *prev, *tmp;
- unw_hash_index_t index;
- unsigned short head;
-
- STAT(++unw.stat.script.news);
-
- /*
- * Can't (easily) use cmpxchg() here because of ABA problem
- * that is intrinsic in cmpxchg()...
- */
- head = unw.lru_head;
- script = unw.cache + head;
- unw.lru_head = script->lru_chain;
-
- /*
- * We'd deadlock here if we interrupted a thread that is holding a read lock on
- * script->lock. Thus, if the write_trylock() fails, we simply bail out. The
- * alternative would be to disable interrupts whenever we hold a read-lock, but
- * that seems silly.
- */
- if (!write_trylock(&script->lock))
- return NULL;
-
- /* re-insert script at the tail of the LRU chain: */
- unw.cache[unw.lru_tail].lru_chain = head;
- unw.lru_tail = head;
-
- /* remove the old script from the hash table (if it's there): */
- if (script->ip) {
- index = hash(script->ip);
- tmp = unw.cache + unw.hash[index];
- prev = NULL;
- while (1) {
- if (tmp == script) {
- if (prev)
- prev->coll_chain = tmp->coll_chain;
- else
- unw.hash[index] = tmp->coll_chain;
- break;
- } else
- prev = tmp;
- if (tmp->coll_chain >= UNW_CACHE_SIZE)
- /* old script wasn't in the hash-table */
- break;
- tmp = unw.cache + tmp->coll_chain;
- }
- }
-
- /* enter new script in the hash table */
- index = hash(ip);
- script->coll_chain = unw.hash[index];
- unw.hash[index] = script - unw.cache;
-
- script->ip = ip; /* set new IP while we're holding the locks */
-
- STAT(if (script->coll_chain < UNW_CACHE_SIZE) ++unw.stat.script.collisions);
-
- script->flags = 0;
- script->hint = 0;
- script->count = 0;
- return script;
-}
-
-static void
-script_finalize (struct unw_script *script, struct unw_state_record *sr)
-{
- script->pr_mask = sr->pr_mask;
- script->pr_val = sr->pr_val;
- /*
- * We could down-grade our write-lock on script->lock here but
- * the rwlock API doesn't offer atomic lock downgrading, so
- * we'll just keep the write-lock and release it later when
- * we're done using the script.
- */
-}
-
-static inline void
-script_emit (struct unw_script *script, struct unw_insn insn)
-{
- if (script->count >= UNW_MAX_SCRIPT_LEN) {
- UNW_DPRINT(0, "unwind.%s: script exceeds maximum size of %u instructions!\n",
- __func__, UNW_MAX_SCRIPT_LEN);
- return;
- }
- script->insn[script->count++] = insn;
-}
-
-static inline void
-emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script)
-{
- struct unw_reg_info *r = sr->curr.reg + i;
- enum unw_insn_opcode opc;
- struct unw_insn insn;
- unsigned long val = 0;
-
- switch (r->where) {
- case UNW_WHERE_GR:
- if (r->val >= 32) {
- /* register got spilled to a stacked register */
- opc = UNW_INSN_SETNAT_TYPE;
- val = UNW_NAT_REGSTK;
- } else
- /* register got spilled to a scratch register */
- opc = UNW_INSN_SETNAT_MEMSTK;
- break;
-
- case UNW_WHERE_FR:
- opc = UNW_INSN_SETNAT_TYPE;
- val = UNW_NAT_VAL;
- break;
-
- case UNW_WHERE_BR:
- opc = UNW_INSN_SETNAT_TYPE;
- val = UNW_NAT_NONE;
- break;
-
- case UNW_WHERE_PSPREL:
- case UNW_WHERE_SPREL:
- opc = UNW_INSN_SETNAT_MEMSTK;
- break;
-
- default:
- UNW_DPRINT(0, "unwind.%s: don't know how to emit nat info for where = %u\n",
- __func__, r->where);
- return;
- }
- insn.opc = opc;
- insn.dst = unw.preg_index[i];
- insn.val = val;
- script_emit(script, insn);
-}
-
-static void
-compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
-{
- struct unw_reg_info *r = sr->curr.reg + i;
- enum unw_insn_opcode opc;
- unsigned long val, rval;
- struct unw_insn insn;
- long need_nat_info;
-
- if (r->where == UNW_WHERE_NONE || r->when >= sr->when_target)
- return;
-
- opc = UNW_INSN_MOVE;
- val = rval = r->val;
- need_nat_info = (i >= UNW_REG_R4 && i <= UNW_REG_R7);
-
- switch (r->where) {
- case UNW_WHERE_GR:
- if (rval >= 32) {
- opc = UNW_INSN_MOVE_STACKED;
- val = rval - 32;
- } else if (rval >= 4 && rval <= 7) {
- if (need_nat_info) {
- opc = UNW_INSN_MOVE2;
- need_nat_info = 0;
- }
- val = unw.preg_index[UNW_REG_R4 + (rval - 4)];
- } else if (rval == 0) {
- opc = UNW_INSN_MOVE_CONST;
- val = 0;
- } else {
- /* register got spilled to a scratch register */
- opc = UNW_INSN_MOVE_SCRATCH;
- val = pt_regs_off(rval);
- }
- break;
-
- case UNW_WHERE_FR:
- if (rval <= 5)
- val = unw.preg_index[UNW_REG_F2 + (rval - 2)];
- else if (rval >= 16 && rval <= 31)
- val = unw.preg_index[UNW_REG_F16 + (rval - 16)];
- else {
- opc = UNW_INSN_MOVE_SCRATCH;
- if (rval <= 11)
- val = offsetof(struct pt_regs, f6) + 16*(rval - 6);
- else
- UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n",
- __func__, rval);
- }
- break;
-
- case UNW_WHERE_BR:
- if (rval >= 1 && rval <= 5)
- val = unw.preg_index[UNW_REG_B1 + (rval - 1)];
- else {
- opc = UNW_INSN_MOVE_SCRATCH;
- if (rval == 0)
- val = offsetof(struct pt_regs, b0);
- else if (rval == 6)
- val = offsetof(struct pt_regs, b6);
- else
- val = offsetof(struct pt_regs, b7);
- }
- break;
-
- case UNW_WHERE_SPREL:
- opc = UNW_INSN_ADD_SP;
- break;
-
- case UNW_WHERE_PSPREL:
- opc = UNW_INSN_ADD_PSP;
- break;
-
- default:
- UNW_DPRINT(0, "unwind%s: register %u has unexpected `where' value of %u\n",
- __func__, i, r->where);
- break;
- }
- insn.opc = opc;
- insn.dst = unw.preg_index[i];
- insn.val = val;
- script_emit(script, insn);
- if (need_nat_info)
- emit_nat_info(sr, i, script);
-
- if (i == UNW_REG_PSP) {
- /*
- * info->psp must contain the _value_ of the previous
- * sp, not it's save location. We get this by
- * dereferencing the value we just stored in
- * info->psp:
- */
- insn.opc = UNW_INSN_LOAD;
- insn.dst = insn.val = unw.preg_index[UNW_REG_PSP];
- script_emit(script, insn);
- }
-}
-
-static inline const struct unw_table_entry *
-lookup (struct unw_table *table, unsigned long rel_ip)
-{
- const struct unw_table_entry *e = NULL;
- unsigned long lo, hi, mid;
-
- /* do a binary search for right entry: */
- for (lo = 0, hi = table->length; lo < hi; ) {
- mid = (lo + hi) / 2;
- e = &table->array[mid];
- if (rel_ip < e->start_offset)
- hi = mid;
- else if (rel_ip >= e->end_offset)
- lo = mid + 1;
- else
- break;
- }
- if (rel_ip < e->start_offset || rel_ip >= e->end_offset)
- return NULL;
- return e;
-}
-
-/*
- * Build an unwind script that unwinds from state OLD_STATE to the
- * entrypoint of the function that called OLD_STATE.
- */
-static inline struct unw_script *
-build_script (struct unw_frame_info *info)
-{
- const struct unw_table_entry *e = NULL;
- struct unw_script *script = NULL;
- struct unw_labeled_state *ls, *next;
- unsigned long ip = info->ip;
- struct unw_state_record sr;
- struct unw_table *table, *prev;
- struct unw_reg_info *r;
- struct unw_insn insn;
- u8 *dp, *desc_end;
- u64 hdr;
- int i;
- STAT(unsigned long start, parse_start;)
-
- STAT(++unw.stat.script.builds; start = ia64_get_itc());
-
- /* build state record */
- memset(&sr, 0, sizeof(sr));
- for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r)
- r->when = UNW_WHEN_NEVER;
- sr.pr_val = info->pr;
-
- UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __func__, ip);
- script = script_new(ip);
- if (!script) {
- UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n", __func__);
- STAT(unw.stat.script.build_time += ia64_get_itc() - start);
- return NULL;
- }
- unw.cache[info->prev_script].hint = script - unw.cache;
-
- /* search the kernels and the modules' unwind tables for IP: */
-
- STAT(parse_start = ia64_get_itc());
-
- prev = NULL;
- for (table = unw.tables; table; table = table->next) {
- if (ip >= table->start && ip < table->end) {
- /*
- * Leave the kernel unwind table at the very front,
- * lest moving it breaks some assumption elsewhere.
- * Otherwise, move the matching table to the second
- * position in the list so that traversals can benefit
- * from commonality in backtrace paths.
- */
- if (prev && prev != unw.tables) {
- /* unw is safe - we're already spinlocked */
- prev->next = table->next;
- table->next = unw.tables->next;
- unw.tables->next = table;
- }
- e = lookup(table, ip - table->segment_base);
- break;
- }
- prev = table;
- }
- if (!e) {
- /* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */
- UNW_DPRINT(1, "unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)\n",
- __func__, ip, unw.cache[info->prev_script].ip);
- sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
- sr.curr.reg[UNW_REG_RP].when = -1;
- sr.curr.reg[UNW_REG_RP].val = 0;
- compile_reg(&sr, UNW_REG_RP, script);
- script_finalize(script, &sr);
- STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
- STAT(unw.stat.script.build_time += ia64_get_itc() - start);
- return script;
- }
-
- sr.when_target = (3*((ip & ~0xfUL) - (table->segment_base + e->start_offset))/16
- + (ip & 0xfUL));
- hdr = *(u64 *) (table->segment_base + e->info_offset);
- dp = (u8 *) (table->segment_base + e->info_offset + 8);
- desc_end = dp + 8*UNW_LENGTH(hdr);
-
- while (!sr.done && dp < desc_end)
- dp = unw_decode(dp, sr.in_body, &sr);
-
- if (sr.when_target > sr.epilogue_start) {
- /*
- * sp has been restored and all values on the memory stack below
- * psp also have been restored.
- */
- sr.curr.reg[UNW_REG_PSP].val = 0;
- sr.curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
- sr.curr.reg[UNW_REG_PSP].when = UNW_WHEN_NEVER;
- for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r)
- if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10)
- || r->where == UNW_WHERE_SPREL)
- {
- r->val = 0;
- r->where = UNW_WHERE_NONE;
- r->when = UNW_WHEN_NEVER;
- }
- }
-
- script->flags = sr.flags;
-
- /*
- * If RP did't get saved, generate entry for the return link
- * register.
- */
- if (sr.curr.reg[UNW_REG_RP].when >= sr.when_target) {
- sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
- sr.curr.reg[UNW_REG_RP].when = -1;
- sr.curr.reg[UNW_REG_RP].val = sr.return_link_reg;
- UNW_DPRINT(1, "unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx\n",
- __func__, ip, sr.curr.reg[UNW_REG_RP].where,
- sr.curr.reg[UNW_REG_RP].val);
- }
-
-#ifdef UNW_DEBUG
- UNW_DPRINT(1, "unwind.%s: state record for func 0x%lx, t=%u:\n",
- __func__, table->segment_base + e->start_offset, sr.when_target);
- for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) {
- if (r->where != UNW_WHERE_NONE || r->when != UNW_WHEN_NEVER) {
- UNW_DPRINT(1, " %s <- ", unw.preg_name[r - sr.curr.reg]);
- switch (r->where) {
- case UNW_WHERE_GR: UNW_DPRINT(1, "r%lu", r->val); break;
- case UNW_WHERE_FR: UNW_DPRINT(1, "f%lu", r->val); break;
- case UNW_WHERE_BR: UNW_DPRINT(1, "b%lu", r->val); break;
- case UNW_WHERE_SPREL: UNW_DPRINT(1, "[sp+0x%lx]", r->val); break;
- case UNW_WHERE_PSPREL: UNW_DPRINT(1, "[psp+0x%lx]", r->val); break;
- case UNW_WHERE_NONE:
- UNW_DPRINT(1, "%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val);
- break;
-
- default:
- UNW_DPRINT(1, "BADWHERE(%d)", r->where);
- break;
- }
- UNW_DPRINT(1, "\t\t%d\n", r->when);
- }
- }
-#endif
-
- STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
-
- /* translate state record into unwinder instructions: */
-
- /*
- * First, set psp if we're dealing with a fixed-size frame;
- * subsequent instructions may depend on this value.
- */
- if (sr.when_target > sr.curr.reg[UNW_REG_PSP].when
- && (sr.curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE)
- && sr.curr.reg[UNW_REG_PSP].val != 0) {
- /* new psp is sp plus frame size */
- insn.opc = UNW_INSN_ADD;
- insn.dst = offsetof(struct unw_frame_info, psp)/8;
- insn.val = sr.curr.reg[UNW_REG_PSP].val; /* frame size */
- script_emit(script, insn);
- }
-
- /* determine where the primary UNaT is: */
- if (sr.when_target < sr.curr.reg[UNW_REG_PRI_UNAT_GR].when)
- i = UNW_REG_PRI_UNAT_MEM;
- else if (sr.when_target < sr.curr.reg[UNW_REG_PRI_UNAT_MEM].when)
- i = UNW_REG_PRI_UNAT_GR;
- else if (sr.curr.reg[UNW_REG_PRI_UNAT_MEM].when > sr.curr.reg[UNW_REG_PRI_UNAT_GR].when)
- i = UNW_REG_PRI_UNAT_MEM;
- else
- i = UNW_REG_PRI_UNAT_GR;
-
- compile_reg(&sr, i, script);
-
- for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i)
- compile_reg(&sr, i, script);
-
- /* free labeled register states & stack: */
-
- STAT(parse_start = ia64_get_itc());
- for (ls = sr.labeled_states; ls; ls = next) {
- next = ls->next;
- free_state_stack(&ls->saved_state);
- free_labeled_state(ls);
- }
- free_state_stack(&sr.curr);
- STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
-
- script_finalize(script, &sr);
- STAT(unw.stat.script.build_time += ia64_get_itc() - start);
- return script;
-}
-
-/*
- * Apply the unwinding actions represented by OPS and update SR to
- * reflect the state that existed upon entry to the function that this
- * unwinder represents.
- */
-static inline void
-run_script (struct unw_script *script, struct unw_frame_info *state)
-{
- struct unw_insn *ip, *limit, next_insn;
- unsigned long opc, dst, val, off;
- unsigned long *s = (unsigned long *) state;
- STAT(unsigned long start;)
-
- STAT(++unw.stat.script.runs; start = ia64_get_itc());
- state->flags = script->flags;
- ip = script->insn;
- limit = script->insn + script->count;
- next_insn = *ip;
-
- while (ip++ < limit) {
- opc = next_insn.opc;
- dst = next_insn.dst;
- val = next_insn.val;
- next_insn = *ip;
-
- redo:
- switch (opc) {
- case UNW_INSN_ADD:
- s[dst] += val;
- break;
-
- case UNW_INSN_MOVE2:
- if (!s[val])
- goto lazy_init;
- s[dst+1] = s[val+1];
- s[dst] = s[val];
- break;
-
- case UNW_INSN_MOVE:
- if (!s[val])
- goto lazy_init;
- s[dst] = s[val];
- break;
-
- case UNW_INSN_MOVE_SCRATCH:
- if (state->pt) {
- s[dst] = (unsigned long) get_scratch_regs(state) + val;
- } else {
- s[dst] = 0;
- UNW_DPRINT(0, "unwind.%s: no state->pt, dst=%ld, val=%ld\n",
- __func__, dst, val);
- }
- break;
-
- case UNW_INSN_MOVE_CONST:
- if (val == 0)
- s[dst] = (unsigned long) &unw.r0;
- else {
- s[dst] = 0;
- UNW_DPRINT(0, "unwind.%s: UNW_INSN_MOVE_CONST bad val=%ld\n",
- __func__, val);
- }
- break;
-
-
- case UNW_INSN_MOVE_STACKED:
- s[dst] = (unsigned long) ia64_rse_skip_regs((unsigned long *)state->bsp,
- val);
- break;
-
- case UNW_INSN_ADD_PSP:
- s[dst] = state->psp + val;
- break;
-
- case UNW_INSN_ADD_SP:
- s[dst] = state->sp + val;
- break;
-
- case UNW_INSN_SETNAT_MEMSTK:
- if (!state->pri_unat_loc)
- state->pri_unat_loc = &state->sw->caller_unat;
- /* register off. is a multiple of 8, so the least 3 bits (type) are 0 */
- s[dst+1] = ((unsigned long) state->pri_unat_loc - s[dst]) | UNW_NAT_MEMSTK;
- break;
-
- case UNW_INSN_SETNAT_TYPE:
- s[dst+1] = val;
- break;
-
- case UNW_INSN_LOAD:
-#ifdef UNW_DEBUG
- if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7)) != 0
- || s[val] < TASK_SIZE)
- {
- UNW_DPRINT(0, "unwind.%s: rejecting bad psp=0x%lx\n",
- __func__, s[val]);
- break;
- }
-#endif
- s[dst] = *(unsigned long *) s[val];
- break;
- }
- }
- STAT(unw.stat.script.run_time += ia64_get_itc() - start);
- return;
-
- lazy_init:
- off = unw.sw_off[val];
- s[val] = (unsigned long) state->sw + off;
- if (off >= offsetof(struct switch_stack, r4) && off <= offsetof(struct switch_stack, r7))
- /*
- * We're initializing a general register: init NaT info, too. Note that
- * the offset is a multiple of 8 which gives us the 3 bits needed for
- * the type field.
- */
- s[val+1] = (offsetof(struct switch_stack, ar_unat) - off) | UNW_NAT_MEMSTK;
- goto redo;
-}
-
-static int
-find_save_locs (struct unw_frame_info *info)
-{
- int have_write_lock = 0;
- struct unw_script *scr;
- unsigned long flags = 0;
-
- if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) {
- /* don't let obviously bad addresses pollute the cache */
- /* FIXME: should really be level 0 but it occurs too often. KAO */
- UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __func__, info->ip);
- info->rp_loc = NULL;
- return -1;
- }
-
- scr = script_lookup(info);
- if (!scr) {
- spin_lock_irqsave(&unw.lock, flags);
- scr = build_script(info);
- if (!scr) {
- spin_unlock_irqrestore(&unw.lock, flags);
- UNW_DPRINT(0,
- "unwind.%s: failed to locate/build unwind script for ip %lx\n",
- __func__, info->ip);
- return -1;
- }
- have_write_lock = 1;
- }
- info->hint = scr->hint;
- info->prev_script = scr - unw.cache;
-
- run_script(scr, info);
-
- if (have_write_lock) {
- write_unlock(&scr->lock);
- spin_unlock_irqrestore(&unw.lock, flags);
- } else
- read_unlock(&scr->lock);
- return 0;
-}
-
-static int
-unw_valid(const struct unw_frame_info *info, unsigned long* p)
-{
- unsigned long loc = (unsigned long)p;
- return (loc >= info->regstk.limit && loc < info->regstk.top) ||
- (loc >= info->memstk.top && loc < info->memstk.limit);
-}
-
-int
-unw_unwind (struct unw_frame_info *info)
-{
- unsigned long prev_ip, prev_sp, prev_bsp;
- unsigned long ip, pr, num_regs;
- STAT(unsigned long start, flags;)
- int retval;
-
- STAT(local_irq_save(flags); ++unw.stat.api.unwinds; start = ia64_get_itc());
-
- prev_ip = info->ip;
- prev_sp = info->sp;
- prev_bsp = info->bsp;
-
- /* validate the return IP pointer */
- if (!unw_valid(info, info->rp_loc)) {
- /* FIXME: should really be level 0 but it occurs too often. KAO */
- UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n",
- __func__, info->ip);
- STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
- return -1;
- }
- /* restore the ip */
- ip = info->ip = *info->rp_loc;
- if (ip < GATE_ADDR) {
- UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __func__, ip);
- STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
- return -1;
- }
-
- /* validate the previous stack frame pointer */
- if (!unw_valid(info, info->pfs_loc)) {
- UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __func__);
- STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
- return -1;
- }
- /* restore the cfm: */
- info->cfm_loc = info->pfs_loc;
-
- /* restore the bsp: */
- pr = info->pr;
- num_regs = 0;
- if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) {
- info->pt = info->sp + 16;
- if ((pr & (1UL << PRED_NON_SYSCALL)) != 0)
- num_regs = *info->cfm_loc & 0x7f; /* size of frame */
- info->pfs_loc =
- (unsigned long *) (info->pt + offsetof(struct pt_regs, ar_pfs));
- UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __func__, info->pt);
- } else
- num_regs = (*info->cfm_loc >> 7) & 0x7f; /* size of locals */
- info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -num_regs);
- if (info->bsp < info->regstk.limit || info->bsp > info->regstk.top) {
- UNW_DPRINT(0, "unwind.%s: bsp (0x%lx) out of range [0x%lx-0x%lx]\n",
- __func__, info->bsp, info->regstk.limit, info->regstk.top);
- STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
- return -1;
- }
-
- /* restore the sp: */
- info->sp = info->psp;
- if (info->sp < info->memstk.top || info->sp > info->memstk.limit) {
- UNW_DPRINT(0, "unwind.%s: sp (0x%lx) out of range [0x%lx-0x%lx]\n",
- __func__, info->sp, info->memstk.top, info->memstk.limit);
- STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
- return -1;
- }
-
- if (info->ip == prev_ip && info->sp == prev_sp && info->bsp == prev_bsp) {
- UNW_DPRINT(0, "unwind.%s: ip, sp, bsp unchanged; stopping here (ip=0x%lx)\n",
- __func__, ip);
- STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
- return -1;
- }
-
- /* as we unwind, the saved ar.unat becomes the primary unat: */
- info->pri_unat_loc = info->unat_loc;
-
- /* finally, restore the predicates: */
- unw_get_pr(info, &info->pr);
-
- retval = find_save_locs(info);
- STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
- return retval;
-}
-EXPORT_SYMBOL(unw_unwind);
-
-int
-unw_unwind_to_user (struct unw_frame_info *info)
-{
- unsigned long ip, sp, pr = info->pr;
-
- do {
- unw_get_sp(info, &sp);
- if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp)
- < IA64_PT_REGS_SIZE) {
- UNW_DPRINT(0, "unwind.%s: ran off the top of the kernel stack\n",
- __func__);
- break;
- }
- if (unw_is_intr_frame(info) &&
- (pr & (1UL << PRED_USER_STACK)))
- return 0;
- if (unw_get_pr (info, &pr) < 0) {
- unw_get_rp(info, &ip);
- UNW_DPRINT(0, "unwind.%s: failed to read "
- "predicate register (ip=0x%lx)\n",
- __func__, ip);
- return -1;
- }
- } while (unw_unwind(info) >= 0);
- unw_get_ip(info, &ip);
- UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n",
- __func__, ip);
- return -1;
-}
-EXPORT_SYMBOL(unw_unwind_to_user);
-
-static void
-init_frame_info (struct unw_frame_info *info, struct task_struct *t,
- struct switch_stack *sw, unsigned long stktop)
-{
- unsigned long rbslimit, rbstop, stklimit;
- STAT(unsigned long start, flags;)
-
- STAT(local_irq_save(flags); ++unw.stat.api.inits; start = ia64_get_itc());
-
- /*
- * Subtle stuff here: we _could_ unwind through the switch_stack frame but we
- * don't want to do that because it would be slow as each preserved register would
- * have to be processed. Instead, what we do here is zero out the frame info and
- * start the unwind process at the function that created the switch_stack frame.
- * When a preserved value in switch_stack needs to be accessed, run_script() will
- * initialize the appropriate pointer on demand.
- */
- memset(info, 0, sizeof(*info));
-
- rbslimit = (unsigned long) t + IA64_RBS_OFFSET;
- stklimit = (unsigned long) t + IA64_STK_OFFSET;
-
- rbstop = sw->ar_bspstore;
- if (rbstop > stklimit || rbstop < rbslimit)
- rbstop = rbslimit;
-
- if (stktop <= rbstop)
- stktop = rbstop;
- if (stktop > stklimit)
- stktop = stklimit;
-
- info->regstk.limit = rbslimit;
- info->regstk.top = rbstop;
- info->memstk.limit = stklimit;
- info->memstk.top = stktop;
- info->task = t;
- info->sw = sw;
- info->sp = info->psp = stktop;
- info->pr = sw->pr;
- UNW_DPRINT(3, "unwind.%s:\n"
- " task 0x%lx\n"
- " rbs = [0x%lx-0x%lx)\n"
- " stk = [0x%lx-0x%lx)\n"
- " pr 0x%lx\n"
- " sw 0x%lx\n"
- " sp 0x%lx\n",
- __func__, (unsigned long) t, rbslimit, rbstop, stktop, stklimit,
- info->pr, (unsigned long) info->sw, info->sp);
- STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
-}
-
-void
-unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw)
-{
- unsigned long sol;
-
- init_frame_info(info, t, sw, (unsigned long) (sw + 1) - 16);
- info->cfm_loc = &sw->ar_pfs;
- sol = (*info->cfm_loc >> 7) & 0x7f;
- info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sol);
- info->ip = sw->b0;
- UNW_DPRINT(3, "unwind.%s:\n"
- " bsp 0x%lx\n"
- " sol 0x%lx\n"
- " ip 0x%lx\n",
- __func__, info->bsp, sol, info->ip);
- find_save_locs(info);
-}
-
-EXPORT_SYMBOL(unw_init_frame_info);
-
-void
-unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
-{
- struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16);
-
- UNW_DPRINT(1, "unwind.%s\n", __func__);
- unw_init_frame_info(info, t, sw);
-}
-EXPORT_SYMBOL(unw_init_from_blocked_task);
-
-static void
-init_unwind_table (struct unw_table *table, const char *name, unsigned long segment_base,
- unsigned long gp, const void *table_start, const void *table_end)
-{
- const struct unw_table_entry *start = table_start, *end = table_end;
-
- table->name = name;
- table->segment_base = segment_base;
- table->gp = gp;
- table->start = segment_base + start[0].start_offset;
- table->end = segment_base + end[-1].end_offset;
- table->array = start;
- table->length = end - start;
-}
-
-void *
-unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned long gp,
- const void *table_start, const void *table_end)
-{
- const struct unw_table_entry *start = table_start, *end = table_end;
- struct unw_table *table;
- unsigned long flags;
-
- if (end - start <= 0) {
- UNW_DPRINT(0, "unwind.%s: ignoring attempt to insert empty unwind table\n",
- __func__);
- return NULL;
- }
-
- table = kmalloc(sizeof(*table), GFP_USER);
- if (!table)
- return NULL;
-
- init_unwind_table(table, name, segment_base, gp, table_start, table_end);
-
- spin_lock_irqsave(&unw.lock, flags);
- {
- /* keep kernel unwind table at the front (it's searched most commonly): */
- table->next = unw.tables->next;
- unw.tables->next = table;
- }
- spin_unlock_irqrestore(&unw.lock, flags);
-
- return table;
-}
-
-void
-unw_remove_unwind_table (void *handle)
-{
- struct unw_table *table, *prev;
- struct unw_script *tmp;
- unsigned long flags;
- long index;
-
- if (!handle) {
- UNW_DPRINT(0, "unwind.%s: ignoring attempt to remove non-existent unwind table\n",
- __func__);
- return;
- }
-
- table = handle;
- if (table == &unw.kernel_table) {
- UNW_DPRINT(0, "unwind.%s: sorry, freeing the kernel's unwind table is a "
- "no-can-do!\n", __func__);
- return;
- }
-
- spin_lock_irqsave(&unw.lock, flags);
- {
- /* first, delete the table: */
-
- for (prev = (struct unw_table *) &unw.tables; prev; prev = prev->next)
- if (prev->next == table)
- break;
- if (!prev) {
- UNW_DPRINT(0, "unwind.%s: failed to find unwind table %p\n",
- __func__, (void *) table);
- spin_unlock_irqrestore(&unw.lock, flags);
- return;
- }
- prev->next = table->next;
- }
- spin_unlock_irqrestore(&unw.lock, flags);
-
- /* next, remove hash table entries for this table */
-
- for (index = 0; index < UNW_HASH_SIZE; ++index) {
- tmp = unw.cache + unw.hash[index];
- if (unw.hash[index] >= UNW_CACHE_SIZE
- || tmp->ip < table->start || tmp->ip >= table->end)
- continue;
-
- write_lock(&tmp->lock);
- {
- if (tmp->ip >= table->start && tmp->ip < table->end) {
- unw.hash[index] = tmp->coll_chain;
- tmp->ip = 0;
- }
- }
- write_unlock(&tmp->lock);
- }
-
- kfree(table);
-}
-
-static int __init
-create_gate_table (void)
-{
- const struct unw_table_entry *entry, *start, *end;
- unsigned long *lp, segbase = GATE_ADDR;
- size_t info_size, size;
- char *info;
- Elf64_Phdr *punw = NULL, *phdr = (Elf64_Phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
- int i;
-
- for (i = 0; i < GATE_EHDR->e_phnum; ++i, ++phdr)
- if (phdr->p_type == PT_IA_64_UNWIND) {
- punw = phdr;
- break;
- }
-
- if (!punw) {
- printk("%s: failed to find gate DSO's unwind table!\n", __func__);
- return 0;
- }
-
- start = (const struct unw_table_entry *) punw->p_vaddr;
- end = (struct unw_table_entry *) ((char *) start + punw->p_memsz);
- size = 0;
-
- unw_add_unwind_table("linux-gate.so", segbase, 0, start, end);
-
- for (entry = start; entry < end; ++entry)
- size += 3*8 + 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
- size += 8; /* reserve space for "end of table" marker */
-
- unw.gate_table = kmalloc(size, GFP_KERNEL);
- if (!unw.gate_table) {
- unw.gate_table_size = 0;
- printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __func__);
- return 0;
- }
- unw.gate_table_size = size;
-
- lp = unw.gate_table;
- info = (char *) unw.gate_table + size;
-
- for (entry = start; entry < end; ++entry, lp += 3) {
- info_size = 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
- info -= info_size;
- memcpy(info, (char *) segbase + entry->info_offset, info_size);
-
- lp[0] = segbase + entry->start_offset; /* start */
- lp[1] = segbase + entry->end_offset; /* end */
- lp[2] = info - (char *) unw.gate_table; /* info */
- }
- *lp = 0; /* end-of-table marker */
- return 0;
-}
-
-__initcall(create_gate_table);
-
-void __init
-unw_init (void)
-{
- extern char __gp[];
- extern void unw_hash_index_t_is_too_narrow (void);
- long i, off;
-
- if (8*sizeof(unw_hash_index_t) < UNW_LOG_HASH_SIZE)
- unw_hash_index_t_is_too_narrow();
-
- unw.sw_off[unw.preg_index[UNW_REG_PRI_UNAT_GR]] = SW(CALLER_UNAT);
- unw.sw_off[unw.preg_index[UNW_REG_BSPSTORE]] = SW(AR_BSPSTORE);
- unw.sw_off[unw.preg_index[UNW_REG_PFS]] = SW(AR_PFS);
- unw.sw_off[unw.preg_index[UNW_REG_RP]] = SW(B0);
- unw.sw_off[unw.preg_index[UNW_REG_UNAT]] = SW(CALLER_UNAT);
- unw.sw_off[unw.preg_index[UNW_REG_PR]] = SW(PR);
- unw.sw_off[unw.preg_index[UNW_REG_LC]] = SW(AR_LC);
- unw.sw_off[unw.preg_index[UNW_REG_FPSR]] = SW(AR_FPSR);
- for (i = UNW_REG_R4, off = SW(R4); i <= UNW_REG_R7; ++i, off += 8)
- unw.sw_off[unw.preg_index[i]] = off;
- for (i = UNW_REG_B1, off = SW(B1); i <= UNW_REG_B5; ++i, off += 8)
- unw.sw_off[unw.preg_index[i]] = off;
- for (i = UNW_REG_F2, off = SW(F2); i <= UNW_REG_F5; ++i, off += 16)
- unw.sw_off[unw.preg_index[i]] = off;
- for (i = UNW_REG_F16, off = SW(F16); i <= UNW_REG_F31; ++i, off += 16)
- unw.sw_off[unw.preg_index[i]] = off;
-
- for (i = 0; i < UNW_CACHE_SIZE; ++i) {
- if (i > 0)
- unw.cache[i].lru_chain = (i - 1);
- unw.cache[i].coll_chain = -1;
- rwlock_init(&unw.cache[i].lock);
- }
- unw.lru_head = UNW_CACHE_SIZE - 1;
- unw.lru_tail = 0;
-
- init_unwind_table(&unw.kernel_table, "kernel", KERNEL_START, (unsigned long) __gp,
- __start_unwind, __end_unwind);
-}
-
-/*
- * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
- *
- * This system call has been deprecated. The new and improved way to get
- * at the kernel's unwind info is via the gate DSO. The address of the
- * ELF header for this DSO is passed to user-level via AT_SYSINFO_EHDR.
- *
- * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
- *
- * This system call copies the unwind data into the buffer pointed to by BUF and returns
- * the size of the unwind data. If BUF_SIZE is smaller than the size of the unwind data
- * or if BUF is NULL, nothing is copied, but the system call still returns the size of the
- * unwind data.
- *
- * The first portion of the unwind data contains an unwind table and rest contains the
- * associated unwind info (in no particular order). The unwind table consists of a table
- * of entries of the form:
- *
- * u64 start; (64-bit address of start of function)
- * u64 end; (64-bit address of start of function)
- * u64 info; (BUF-relative offset to unwind info)
- *
- * The end of the unwind table is indicated by an entry with a START address of zero.
- *
- * Please see the IA-64 Software Conventions and Runtime Architecture manual for details
- * on the format of the unwind info.
- *
- * ERRORS
- * EFAULT BUF points outside your accessible address space.
- */
-asmlinkage long
-sys_getunwind (void __user *buf, size_t buf_size)
-{
- if (buf && buf_size >= unw.gate_table_size)
- if (copy_to_user(buf, unw.gate_table, unw.gate_table_size) != 0)
- return -EFAULT;
- return unw.gate_table_size;
-}
diff --git a/arch/ia64/kernel/unwind_decoder.c b/arch/ia64/kernel/unwind_decoder.c
deleted file mode 100644
index 83f54f7929b5..000000000000
--- a/arch/ia64/kernel/unwind_decoder.c
+++ /dev/null
@@ -1,460 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2000 Hewlett-Packard Co
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Generic IA-64 unwind info decoder.
- *
- * This file is used both by the Linux kernel and objdump. Please keep
- * the two copies of this file in sync.
- *
- * You need to customize the decoder by defining the following
- * macros/constants before including this file:
- *
- * Types:
- * unw_word Unsigned integer type with at least 64 bits
- *
- * Register names:
- * UNW_REG_BSP
- * UNW_REG_BSPSTORE
- * UNW_REG_FPSR
- * UNW_REG_LC
- * UNW_REG_PFS
- * UNW_REG_PR
- * UNW_REG_RNAT
- * UNW_REG_PSP
- * UNW_REG_RP
- * UNW_REG_UNAT
- *
- * Decoder action macros:
- * UNW_DEC_BAD_CODE(code)
- * UNW_DEC_ABI(fmt,abi,context,arg)
- * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
- * UNW_DEC_BR_MEM(fmt,brmask,arg)
- * UNW_DEC_COPY_STATE(fmt,label,arg)
- * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
- * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
- * UNW_DEC_FR_MEM(fmt,frmask,arg)
- * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
- * UNW_DEC_GR_MEM(fmt,grmask,arg)
- * UNW_DEC_LABEL_STATE(fmt,label,arg)
- * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
- * UNW_DEC_MEM_STACK_V(fmt,t,arg)
- * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
- * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
- * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
- * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
- * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
- * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
- * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
- * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
- * UNW_DEC_REG_REG(fmt,src,dst,arg)
- * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
- * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
- * UNW_DEC_RESTORE(fmt,t,abreg,arg)
- * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
- * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
- * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
- * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
- * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
- * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
- * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
- * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
- * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
- */
-
-static unw_word
-unw_decode_uleb128 (unsigned char **dpp)
-{
- unsigned shift = 0;
- unw_word byte, result = 0;
- unsigned char *bp = *dpp;
-
- while (1)
- {
- byte = *bp++;
- result |= (byte & 0x7f) << shift;
- if ((byte & 0x80) == 0)
- break;
- shift += 7;
- }
- *dpp = bp;
- return result;
-}
-
-static unsigned char *
-unw_decode_x1 (unsigned char *dp, unsigned char code, void *arg)
-{
- unsigned char byte1, abreg;
- unw_word t, off;
-
- byte1 = *dp++;
- t = unw_decode_uleb128 (&dp);
- off = unw_decode_uleb128 (&dp);
- abreg = (byte1 & 0x7f);
- if (byte1 & 0x80)
- UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg);
- else
- UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_x2 (unsigned char *dp, unsigned char code, void *arg)
-{
- unsigned char byte1, byte2, abreg, x, ytreg;
- unw_word t;
-
- byte1 = *dp++; byte2 = *dp++;
- t = unw_decode_uleb128 (&dp);
- abreg = (byte1 & 0x7f);
- ytreg = byte2;
- x = (byte1 >> 7) & 1;
- if ((byte1 & 0x80) == 0 && ytreg == 0)
- UNW_DEC_RESTORE(X2, t, abreg, arg);
- else
- UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_x3 (unsigned char *dp, unsigned char code, void *arg)
-{
- unsigned char byte1, byte2, abreg, qp;
- unw_word t, off;
-
- byte1 = *dp++; byte2 = *dp++;
- t = unw_decode_uleb128 (&dp);
- off = unw_decode_uleb128 (&dp);
-
- qp = (byte1 & 0x3f);
- abreg = (byte2 & 0x7f);
-
- if (byte1 & 0x80)
- UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg);
- else
- UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_x4 (unsigned char *dp, unsigned char code, void *arg)
-{
- unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
- unw_word t;
-
- byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
- t = unw_decode_uleb128 (&dp);
-
- qp = (byte1 & 0x3f);
- abreg = (byte2 & 0x7f);
- x = (byte2 >> 7) & 1;
- ytreg = byte3;
-
- if ((byte2 & 0x80) == 0 && byte3 == 0)
- UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg);
- else
- UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg)
-{
- int body = (code & 0x20) != 0;
- unw_word rlen;
-
- rlen = (code & 0x1f);
- UNW_DEC_PROLOGUE(R1, body, rlen, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg)
-{
- unsigned char byte1, mask, grsave;
- unw_word rlen;
-
- byte1 = *dp++;
-
- mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
- grsave = (byte1 & 0x7f);
- rlen = unw_decode_uleb128 (&dp);
- UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg)
-{
- unw_word rlen;
-
- rlen = unw_decode_uleb128 (&dp);
- UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg)
-{
- unsigned char brmask = (code & 0x1f);
-
- UNW_DEC_BR_MEM(P1, brmask, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg)
-{
- if ((code & 0x10) == 0)
- {
- unsigned char byte1 = *dp++;
-
- UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
- (byte1 & 0x7f), arg);
- }
- else if ((code & 0x08) == 0)
- {
- unsigned char byte1 = *dp++, r, dst;
-
- r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
- dst = (byte1 & 0x7f);
- switch (r)
- {
- case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break;
- case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break;
- case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break;
- case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break;
- case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break;
- case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break;
- case 6: UNW_DEC_RP_BR(P3, dst, arg); break;
- case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break;
- case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break;
- case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break;
- case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break;
- case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break;
- default: UNW_DEC_BAD_CODE(r); break;
- }
- }
- else if ((code & 0x7) == 0)
- UNW_DEC_SPILL_MASK(P4, dp, arg);
- else if ((code & 0x7) == 1)
- {
- unw_word grmask, frmask, byte1, byte2, byte3;
-
- byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
- grmask = ((byte1 >> 4) & 0xf);
- frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
- UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg);
- }
- else
- UNW_DEC_BAD_CODE(code);
- return dp;
-}
-
-static unsigned char *
-unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg)
-{
- int gregs = (code & 0x10) != 0;
- unsigned char mask = (code & 0x0f);
-
- if (gregs)
- UNW_DEC_GR_MEM(P6, mask, arg);
- else
- UNW_DEC_FR_MEM(P6, mask, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg)
-{
- unsigned char r, byte1, byte2;
- unw_word t, size;
-
- if ((code & 0x10) == 0)
- {
- r = (code & 0xf);
- t = unw_decode_uleb128 (&dp);
- switch (r)
- {
- case 0:
- size = unw_decode_uleb128 (&dp);
- UNW_DEC_MEM_STACK_F(P7, t, size, arg);
- break;
-
- case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break;
- case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break;
- case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break;
- case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break;
- case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break;
- case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break;
- case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break;
- case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break;
- case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break;
- case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break;
- case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break;
- case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break;
- case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break;
- case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break;
- case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break;
- default: UNW_DEC_BAD_CODE(r); break;
- }
- }
- else
- {
- switch (code & 0xf)
- {
- case 0x0: /* p8 */
- {
- r = *dp++;
- t = unw_decode_uleb128 (&dp);
- switch (r)
- {
- case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break;
- case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break;
- case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break;
- case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break;
- case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break;
- case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break;
- case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break;
- case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break;
- case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break;
- case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break;
- case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
- case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
- case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break;
- case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break;
- case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break;
- case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break;
- case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break;
- case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break;
- case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break;
- default: UNW_DEC_BAD_CODE(r); break;
- }
- }
- break;
-
- case 0x1:
- byte1 = *dp++; byte2 = *dp++;
- UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg);
- break;
-
- case 0xf: /* p10 */
- byte1 = *dp++; byte2 = *dp++;
- UNW_DEC_ABI(P10, byte1, byte2, arg);
- break;
-
- case 0x9:
- return unw_decode_x1 (dp, code, arg);
-
- case 0xa:
- return unw_decode_x2 (dp, code, arg);
-
- case 0xb:
- return unw_decode_x3 (dp, code, arg);
-
- case 0xc:
- return unw_decode_x4 (dp, code, arg);
-
- default:
- UNW_DEC_BAD_CODE(code);
- break;
- }
- }
- return dp;
-}
-
-static unsigned char *
-unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg)
-{
- unw_word label = (code & 0x1f);
-
- if ((code & 0x20) != 0)
- UNW_DEC_COPY_STATE(B1, label, arg);
- else
- UNW_DEC_LABEL_STATE(B1, label, arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg)
-{
- unw_word t;
-
- t = unw_decode_uleb128 (&dp);
- UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg);
- return dp;
-}
-
-static unsigned char *
-unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg)
-{
- unw_word t, ecount, label;
-
- if ((code & 0x10) == 0)
- {
- t = unw_decode_uleb128 (&dp);
- ecount = unw_decode_uleb128 (&dp);
- UNW_DEC_EPILOGUE(B3, t, ecount, arg);
- }
- else if ((code & 0x07) == 0)
- {
- label = unw_decode_uleb128 (&dp);
- if ((code & 0x08) != 0)
- UNW_DEC_COPY_STATE(B4, label, arg);
- else
- UNW_DEC_LABEL_STATE(B4, label, arg);
- }
- else
- switch (code & 0x7)
- {
- case 1: return unw_decode_x1 (dp, code, arg);
- case 2: return unw_decode_x2 (dp, code, arg);
- case 3: return unw_decode_x3 (dp, code, arg);
- case 4: return unw_decode_x4 (dp, code, arg);
- default: UNW_DEC_BAD_CODE(code); break;
- }
- return dp;
-}
-
-typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *);
-
-static unw_decoder unw_decode_table[2][8] =
-{
- /* prologue table: */
- {
- unw_decode_r1, /* 0 */
- unw_decode_r1,
- unw_decode_r2,
- unw_decode_r3,
- unw_decode_p1, /* 4 */
- unw_decode_p2_p5,
- unw_decode_p6,
- unw_decode_p7_p10
- },
- {
- unw_decode_r1, /* 0 */
- unw_decode_r1,
- unw_decode_r2,
- unw_decode_r3,
- unw_decode_b1, /* 4 */
- unw_decode_b1,
- unw_decode_b2,
- unw_decode_b3_x4
- }
-};
-
-/*
- * Decode one descriptor and return address of next descriptor.
- */
-static inline unsigned char *
-unw_decode (unsigned char *dp, int inside_body, void *arg)
-{
- unw_decoder decoder;
- unsigned char code;
-
- code = *dp++;
- decoder = unw_decode_table[inside_body][code >> 5];
- dp = (*decoder) (dp, code, arg);
- return dp;
-}
diff --git a/arch/ia64/kernel/unwind_i.h b/arch/ia64/kernel/unwind_i.h
deleted file mode 100644
index 1dd57ba44327..000000000000
--- a/arch/ia64/kernel/unwind_i.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2000, 2002-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Kernel unwind support.
- */
-
-#define UNW_VER(x) ((x) >> 48)
-#define UNW_FLAG_MASK 0x0000ffff00000000
-#define UNW_FLAG_OSMASK 0x0000f00000000000
-#define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L)
-#define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L)
-#define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL)
-
-enum unw_register_index {
- /* primary unat: */
- UNW_REG_PRI_UNAT_GR,
- UNW_REG_PRI_UNAT_MEM,
-
- /* register stack */
- UNW_REG_BSP, /* register stack pointer */
- UNW_REG_BSPSTORE,
- UNW_REG_PFS, /* previous function state */
- UNW_REG_RNAT,
- /* memory stack */
- UNW_REG_PSP, /* previous memory stack pointer */
- /* return pointer: */
- UNW_REG_RP,
-
- /* preserved registers: */
- UNW_REG_R4, UNW_REG_R5, UNW_REG_R6, UNW_REG_R7,
- UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR,
- UNW_REG_B1, UNW_REG_B2, UNW_REG_B3, UNW_REG_B4, UNW_REG_B5,
- UNW_REG_F2, UNW_REG_F3, UNW_REG_F4, UNW_REG_F5,
- UNW_REG_F16, UNW_REG_F17, UNW_REG_F18, UNW_REG_F19,
- UNW_REG_F20, UNW_REG_F21, UNW_REG_F22, UNW_REG_F23,
- UNW_REG_F24, UNW_REG_F25, UNW_REG_F26, UNW_REG_F27,
- UNW_REG_F28, UNW_REG_F29, UNW_REG_F30, UNW_REG_F31,
- UNW_NUM_REGS
-};
-
-struct unw_info_block {
- u64 header;
- u64 desc[]; /* unwind descriptors */
- /* personality routine and language-specific data follow behind descriptors */
-};
-
-struct unw_table {
- struct unw_table *next; /* must be first member! */
- const char *name;
- unsigned long gp; /* global pointer for this load-module */
- unsigned long segment_base; /* base for offsets in the unwind table entries */
- unsigned long start;
- unsigned long end;
- const struct unw_table_entry *array;
- unsigned long length;
-};
-
-enum unw_where {
- UNW_WHERE_NONE, /* register isn't saved at all */
- UNW_WHERE_GR, /* register is saved in a general register */
- UNW_WHERE_FR, /* register is saved in a floating-point register */
- UNW_WHERE_BR, /* register is saved in a branch register */
- UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */
- UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */
- /*
- * At the end of each prologue these locations get resolved to
- * UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively:
- */
- UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */
- UNW_WHERE_GR_SAVE /* register is saved in next general register */
-};
-
-#define UNW_WHEN_NEVER 0x7fffffff
-
-struct unw_reg_info {
- unsigned long val; /* save location: register number or offset */
- enum unw_where where; /* where the register gets saved */
- int when; /* when the register gets saved */
-};
-
-struct unw_reg_state {
- struct unw_reg_state *next; /* next (outer) element on state stack */
- struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */
-};
-
-struct unw_labeled_state {
- struct unw_labeled_state *next; /* next labeled state (or NULL) */
- unsigned long label; /* label for this state */
- struct unw_reg_state saved_state;
-};
-
-struct unw_state_record {
- unsigned int first_region : 1; /* is this the first region? */
- unsigned int done : 1; /* are we done scanning descriptors? */
- unsigned int any_spills : 1; /* got any register spills? */
- unsigned int in_body : 1; /* are we inside a body (as opposed to a prologue)? */
- unsigned long flags; /* see UNW_FLAG_* in unwind.h */
-
- u8 *imask; /* imask of spill_mask record or NULL */
- unsigned long pr_val; /* predicate values */
- unsigned long pr_mask; /* predicate mask */
- long spill_offset; /* psp-relative offset for spill base */
- int region_start;
- int region_len;
- int epilogue_start;
- int epilogue_count;
- int when_target;
-
- u8 gr_save_loc; /* next general register to use for saving a register */
- u8 return_link_reg; /* branch register in which the return link is passed */
-
- struct unw_labeled_state *labeled_states; /* list of all labeled states */
- struct unw_reg_state curr; /* current state */
-};
-
-enum unw_nat_type {
- UNW_NAT_NONE, /* NaT not represented */
- UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */
- UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */
- UNW_NAT_REGSTK /* NaT is in rnat */
-};
-
-enum unw_insn_opcode {
- UNW_INSN_ADD, /* s[dst] += val */
- UNW_INSN_ADD_PSP, /* s[dst] = (s.psp + val) */
- UNW_INSN_ADD_SP, /* s[dst] = (s.sp + val) */
- UNW_INSN_MOVE, /* s[dst] = s[val] */
- UNW_INSN_MOVE2, /* s[dst] = s[val]; s[dst+1] = s[val+1] */
- UNW_INSN_MOVE_STACKED, /* s[dst] = ia64_rse_skip(*s.bsp, val) */
- UNW_INSN_SETNAT_MEMSTK, /* s[dst+1].nat.type = MEMSTK;
- s[dst+1].nat.off = *s.pri_unat - s[dst] */
- UNW_INSN_SETNAT_TYPE, /* s[dst+1].nat.type = val */
- UNW_INSN_LOAD, /* s[dst] = *s[val] */
- UNW_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */
- UNW_INSN_MOVE_CONST, /* s[dst] = constant reg "val" */
-};
-
-struct unw_insn {
- unsigned int opc : 4;
- unsigned int dst : 9;
- signed int val : 19;
-};
-
-/*
- * Preserved general static registers (r4-r7) give rise to two script
- * instructions; everything else yields at most one instruction; at
- * the end of the script, the psp gets popped, accounting for one more
- * instruction.
- */
-#define UNW_MAX_SCRIPT_LEN (UNW_NUM_REGS + 5)
-
-struct unw_script {
- unsigned long ip; /* ip this script is for */
- unsigned long pr_mask; /* mask of predicates script depends on */
- unsigned long pr_val; /* predicate values this script is for */
- rwlock_t lock;
- unsigned int flags; /* see UNW_FLAG_* in unwind.h */
- unsigned short lru_chain; /* used for least-recently-used chain */
- unsigned short coll_chain; /* used for hash collisions */
- unsigned short hint; /* hint for next script to try (or -1) */
- unsigned short count; /* number of instructions in script */
- struct unw_insn insn[UNW_MAX_SCRIPT_LEN];
-};
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
deleted file mode 100644
index 53dfde161c8a..000000000000
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ /dev/null
@@ -1,224 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#include <linux/pgtable.h>
-#include <asm/cache.h>
-#include <asm/ptrace.h>
-#include <asm/thread_info.h>
-
-#define EMITS_PT_NOTE
-#define RO_EXCEPTION_TABLE_ALIGN 16
-
-#include <asm-generic/vmlinux.lds.h>
-
-OUTPUT_FORMAT("elf64-ia64-little")
-OUTPUT_ARCH(ia64)
-ENTRY(phys_start)
-jiffies = jiffies_64;
-
-PHDRS {
- text PT_LOAD;
- percpu PT_LOAD;
- data PT_LOAD;
- note PT_NOTE;
- unwind 0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */
-}
-
-SECTIONS {
- /*
- * unwind exit sections must be discarded before
- * the rest of the sections get included.
- */
- /DISCARD/ : {
- *(.IA_64.unwind.exit.text)
- *(.IA_64.unwind_info.exit.text)
- *(.comment)
- *(.note)
- }
-
- v = PAGE_OFFSET; /* this symbol is here to make debugging easier... */
- phys_start = _start - LOAD_OFFSET;
-
- code : {
- } :text
- . = KERNEL_START;
-
- _text = .;
- _stext = .;
-
- .text : AT(ADDR(.text) - LOAD_OFFSET) {
- __start_ivt_text = .;
- *(.text..ivt)
- __end_ivt_text = .;
- TEXT_TEXT
- SCHED_TEXT
- LOCK_TEXT
- KPROBES_TEXT
- IRQENTRY_TEXT
- SOFTIRQENTRY_TEXT
- *(.gnu.linkonce.t*)
- }
-
- .text2 : AT(ADDR(.text2) - LOAD_OFFSET) {
- *(.text2)
- }
-
-#ifdef CONFIG_SMP
- .text..lock : AT(ADDR(.text..lock) - LOAD_OFFSET) {
- *(.text..lock)
- }
-#endif
- _etext = .;
-
- /*
- * Read-only data
- */
-
- /* MCA table */
- . = ALIGN(16);
- __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET) {
- __start___mca_table = .;
- *(__mca_table)
- __stop___mca_table = .;
- }
-
- .data..patch.phys_stack_reg : AT(ADDR(.data..patch.phys_stack_reg) - LOAD_OFFSET) {
- __start___phys_stack_reg_patchlist = .;
- *(.data..patch.phys_stack_reg)
- __end___phys_stack_reg_patchlist = .;
- }
-
- /*
- * Global data
- */
- _data = .;
-
- /* Unwind info & table: */
- . = ALIGN(8);
- .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - LOAD_OFFSET) {
- *(.IA_64.unwind_info*)
- }
- .IA_64.unwind : AT(ADDR(.IA_64.unwind) - LOAD_OFFSET) {
- __start_unwind = .;
- *(.IA_64.unwind*)
- __end_unwind = .;
- } :text :unwind
- code_continues2 : {
- } :text
-
- RO_DATA(4096)
-
- .opd : AT(ADDR(.opd) - LOAD_OFFSET) {
- __start_opd = .;
- *(.opd)
- __end_opd = .;
- }
-
- /*
- * Initialization code and data:
- */
- . = ALIGN(PAGE_SIZE);
- __init_begin = .;
-
- INIT_TEXT_SECTION(PAGE_SIZE)
- INIT_DATA_SECTION(16)
-
- .data..patch.vtop : AT(ADDR(.data..patch.vtop) - LOAD_OFFSET) {
- __start___vtop_patchlist = .;
- *(.data..patch.vtop)
- __end___vtop_patchlist = .;
- }
-
- .data..patch.rse : AT(ADDR(.data..patch.rse) - LOAD_OFFSET) {
- __start___rse_patchlist = .;
- *(.data..patch.rse)
- __end___rse_patchlist = .;
- }
-
- .data..patch.mckinley_e9 : AT(ADDR(.data..patch.mckinley_e9) - LOAD_OFFSET) {
- __start___mckinley_e9_bundles = .;
- *(.data..patch.mckinley_e9)
- __end___mckinley_e9_bundles = .;
- }
-
-#ifdef CONFIG_SMP
- . = ALIGN(PERCPU_PAGE_SIZE);
- __cpu0_per_cpu = .;
- . = . + PERCPU_PAGE_SIZE; /* cpu0 per-cpu space */
-#endif
-
- . = ALIGN(PAGE_SIZE);
- __init_end = .;
-
- .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
- PAGE_ALIGNED_DATA(PAGE_SIZE)
- . = ALIGN(PAGE_SIZE);
- __start_gate_section = .;
- *(.data..gate)
- __stop_gate_section = .;
- }
- /*
- * make sure the gate page doesn't expose
- * kernel data
- */
- . = ALIGN(PAGE_SIZE);
-
- /* Per-cpu data: */
- . = ALIGN(PERCPU_PAGE_SIZE);
- PERCPU_VADDR(SMP_CACHE_BYTES, PERCPU_ADDR, :percpu)
- __phys_per_cpu_start = __per_cpu_load;
- /*
- * ensure percpu data fits
- * into percpu page size
- */
- . = __phys_per_cpu_start + PERCPU_PAGE_SIZE;
-
- data : {
- } :data
- .data : AT(ADDR(.data) - LOAD_OFFSET) {
- _sdata = .;
- INIT_TASK_DATA(PAGE_SIZE)
- CACHELINE_ALIGNED_DATA(SMP_CACHE_BYTES)
- READ_MOSTLY_DATA(SMP_CACHE_BYTES)
- DATA_DATA
- *(.data1)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
- }
-
- BUG_TABLE
-
- . = ALIGN(16); /* gp must be 16-byte aligned for exc. table */
- .got : AT(ADDR(.got) - LOAD_OFFSET) {
- *(.got.plt)
- *(.got)
- }
- __gp = ADDR(.got) + 0x200000;
-
- /*
- * We want the small data sections together,
- * so single-instruction offsets can access
- * them all, and initialized data all before
- * uninitialized, so we can shorten the
- * on-disk segment size.
- */
- .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) {
- *(.sdata)
- *(.sdata1)
- *(.srdata)
- }
- _edata = .;
-
- BSS_SECTION(0, 0, 0)
-
- _end = .;
-
- code : {
- } :text
-
- STABS_DEBUG
- DWARF_DEBUG
- ELF_DETAILS
-
- /* Default discards */
- DISCARDS
-}
diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
deleted file mode 100644
index 081fcba01dc0..000000000000
--- a/arch/ia64/lib/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for ia64-specific library routines..
-#
-
-lib-y := io.o __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
- __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \
- checksum.o clear_page.o csum_partial_copy.o \
- clear_user.o strncpy_from_user.o strnlen_user.o \
- flush.o ip_fast_csum.o do_csum.o \
- memset.o strlen.o xor.o
-
-lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
-lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
-
-AFLAGS___divdi3.o =
-AFLAGS___udivdi3.o = -DUNSIGNED
-AFLAGS___moddi3.o = -DMODULO
-AFLAGS___umoddi3.o = -DUNSIGNED -DMODULO
-
-AFLAGS___divsi3.o =
-AFLAGS___udivsi3.o = -DUNSIGNED
-AFLAGS___modsi3.o = -DMODULO
-AFLAGS___umodsi3.o = -DUNSIGNED -DMODULO
-
-$(obj)/__divdi3.o: $(src)/idiv64.S FORCE
- $(call if_changed_rule,as_o_S)
-
-$(obj)/__udivdi3.o: $(src)/idiv64.S FORCE
- $(call if_changed_rule,as_o_S)
-
-$(obj)/__moddi3.o: $(src)/idiv64.S FORCE
- $(call if_changed_rule,as_o_S)
-
-$(obj)/__umoddi3.o: $(src)/idiv64.S FORCE
- $(call if_changed_rule,as_o_S)
-
-$(obj)/__divsi3.o: $(src)/idiv32.S FORCE
- $(call if_changed_rule,as_o_S)
-
-$(obj)/__udivsi3.o: $(src)/idiv32.S FORCE
- $(call if_changed_rule,as_o_S)
-
-$(obj)/__modsi3.o: $(src)/idiv32.S FORCE
- $(call if_changed_rule,as_o_S)
-
-$(obj)/__umodsi3.o: $(src)/idiv32.S FORCE
- $(call if_changed_rule,as_o_S)
diff --git a/arch/ia64/lib/checksum.c b/arch/ia64/lib/checksum.c
deleted file mode 100644
index d26517fe3500..000000000000
--- a/arch/ia64/lib/checksum.c
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Network checksum routines
- *
- * Copyright (C) 1999, 2003 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- *
- * Most of the code coming from arch/alpha/lib/checksum.c
- *
- * This file contains network checksum routines that are better done
- * in an architecture-specific manner due to speed..
- */
-
-#include <linux/module.h>
-#include <linux/string.h>
-
-#include <asm/byteorder.h>
-
-static inline unsigned short
-from64to16 (unsigned long x)
-{
- /* add up 32-bit words for 33 bits */
- x = (x & 0xffffffff) + (x >> 32);
- /* add up 16-bit and 17-bit words for 17+c bits */
- x = (x & 0xffff) + (x >> 16);
- /* add up 16-bit and 2-bit for 16+c bit */
- x = (x & 0xffff) + (x >> 16);
- /* add up carry.. */
- x = (x & 0xffff) + (x >> 16);
- return x;
-}
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented.
- */
-__sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
- __u8 proto, __wsum sum)
-{
- return (__force __sum16)~from64to16(
- (__force u64)saddr + (__force u64)daddr +
- (__force u64)sum + ((len + proto) << 8));
-}
-
-EXPORT_SYMBOL(csum_tcpudp_magic);
-
-__wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
- __u8 proto, __wsum sum)
-{
- unsigned long result;
-
- result = (__force u64)saddr + (__force u64)daddr +
- (__force u64)sum + ((len + proto) << 8);
-
- /* Fold down to 32-bits so we don't lose in the typedef-less network stack. */
- /* 64 to 33 */
- result = (result & 0xffffffff) + (result >> 32);
- /* 33 to 32 */
- result = (result & 0xffffffff) + (result >> 32);
- return (__force __wsum)result;
-}
-EXPORT_SYMBOL(csum_tcpudp_nofold);
-
-extern unsigned long do_csum (const unsigned char *, long);
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum)
-{
- u64 result = do_csum(buff, len);
-
- /* add in old sum, and carry.. */
- result += (__force u32)sum;
- /* 32+c bits -> 32 bits */
- result = (result & 0xffffffff) + (result >> 32);
- return (__force __wsum)result;
-}
-
-EXPORT_SYMBOL(csum_partial);
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-__sum16 ip_compute_csum (const void *buff, int len)
-{
- return (__force __sum16)~do_csum(buff,len);
-}
-
-EXPORT_SYMBOL(ip_compute_csum);
diff --git a/arch/ia64/lib/clear_page.S b/arch/ia64/lib/clear_page.S
deleted file mode 100644
index ba0dd2538fa5..000000000000
--- a/arch/ia64/lib/clear_page.S
+++ /dev/null
@@ -1,79 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 1999-2002 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
- *
- * 1/06/01 davidm Tuned for Itanium.
- * 2/12/02 kchen Tuned for both Itanium and McKinley
- * 3/08/02 davidm Some more tweaking
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-#include <asm/page.h>
-
-#ifdef CONFIG_ITANIUM
-# define L3_LINE_SIZE 64 // Itanium L3 line size
-# define PREFETCH_LINES 9 // magic number
-#else
-# define L3_LINE_SIZE 128 // McKinley L3 line size
-# define PREFETCH_LINES 12 // magic number
-#endif
-
-#define saved_lc r2
-#define dst_fetch r3
-#define dst1 r8
-#define dst2 r9
-#define dst3 r10
-#define dst4 r11
-
-#define dst_last r31
-
-GLOBAL_ENTRY(clear_page)
- .prologue
- .regstk 1,0,0,0
- mov r16 = PAGE_SIZE/L3_LINE_SIZE-1 // main loop count, -1=repeat/until
- .save ar.lc, saved_lc
- mov saved_lc = ar.lc
-
- .body
- mov ar.lc = (PREFETCH_LINES - 1)
- mov dst_fetch = in0
- adds dst1 = 16, in0
- adds dst2 = 32, in0
- ;;
-.fetch: stf.spill.nta [dst_fetch] = f0, L3_LINE_SIZE
- adds dst3 = 48, in0 // executing this multiple times is harmless
- br.cloop.sptk.few .fetch
- ;;
- addl dst_last = (PAGE_SIZE - PREFETCH_LINES*L3_LINE_SIZE), dst_fetch
- mov ar.lc = r16 // one L3 line per iteration
- adds dst4 = 64, in0
- ;;
-#ifdef CONFIG_ITANIUM
- // Optimized for Itanium
-1: stf.spill.nta [dst1] = f0, 64
- stf.spill.nta [dst2] = f0, 64
- cmp.lt p8,p0=dst_fetch, dst_last
- ;;
-#else
- // Optimized for McKinley
-1: stf.spill.nta [dst1] = f0, 64
- stf.spill.nta [dst2] = f0, 64
- stf.spill.nta [dst3] = f0, 64
- stf.spill.nta [dst4] = f0, 128
- cmp.lt p8,p0=dst_fetch, dst_last
- ;;
- stf.spill.nta [dst1] = f0, 64
- stf.spill.nta [dst2] = f0, 64
-#endif
- stf.spill.nta [dst3] = f0, 64
-(p8) stf.spill.nta [dst_fetch] = f0, L3_LINE_SIZE
- br.cloop.sptk.few 1b
- ;;
- mov ar.lc = saved_lc // restore lc
- br.ret.sptk.many rp
-END(clear_page)
-EXPORT_SYMBOL(clear_page)
diff --git a/arch/ia64/lib/clear_user.S b/arch/ia64/lib/clear_user.S
deleted file mode 100644
index 1d9e45ccf8e5..000000000000
--- a/arch/ia64/lib/clear_user.S
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This routine clears to zero a linear memory buffer in user space.
- *
- * Inputs:
- * in0: address of buffer
- * in1: length of buffer in bytes
- * Outputs:
- * r8: number of bytes that didn't get cleared due to a fault
- *
- * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-//
-// arguments
-//
-#define buf r32
-#define len r33
-
-//
-// local registers
-//
-#define cnt r16
-#define buf2 r17
-#define saved_lc r18
-#define saved_pfs r19
-#define tmp r20
-#define len2 r21
-#define len3 r22
-
-//
-// Theory of operations:
-// - we check whether or not the buffer is small, i.e., less than 17
-// in which case we do the byte by byte loop.
-//
-// - Otherwise we go progressively from 1 byte store to 8byte store in
-// the head part, the body is a 16byte store loop and we finish we the
-// tail for the last 15 bytes.
-// The good point about this breakdown is that the long buffer handling
-// contains only 2 branches.
-//
-// The reason for not using shifting & masking for both the head and the
-// tail is to stay semantically correct. This routine is not supposed
-// to write bytes outside of the buffer. While most of the time this would
-// be ok, we can't tolerate a mistake. A classical example is the case
-// of multithreaded code were to the extra bytes touched is actually owned
-// by another thread which runs concurrently to ours. Another, less likely,
-// example is with device drivers where reading an I/O mapped location may
-// have side effects (same thing for writing).
-//
-
-GLOBAL_ENTRY(__do_clear_user)
- .prologue
- .save ar.pfs, saved_pfs
- alloc saved_pfs=ar.pfs,2,0,0,0
- cmp.eq p6,p0=r0,len // check for zero length
- .save ar.lc, saved_lc
- mov saved_lc=ar.lc // preserve ar.lc (slow)
- .body
- ;; // avoid WAW on CFM
- adds tmp=-1,len // br.ctop is repeat/until
- mov ret0=len // return value is length at this point
-(p6) br.ret.spnt.many rp
- ;;
- cmp.lt p6,p0=16,len // if len > 16 then long memset
- mov ar.lc=tmp // initialize lc for small count
-(p6) br.cond.dptk .long_do_clear
- ;; // WAR on ar.lc
- //
- // worst case 16 iterations, avg 8 iterations
- //
- // We could have played with the predicates to use the extra
- // M slot for 2 stores/iteration but the cost the initialization
- // the various counters compared to how long the loop is supposed
- // to last on average does not make this solution viable.
- //
-1:
- EX( .Lexit1, st1 [buf]=r0,1 )
- adds len=-1,len // countdown length using len
- br.cloop.dptk 1b
- ;; // avoid RAW on ar.lc
- //
- // .Lexit4: comes from byte by byte loop
- // len contains bytes left
-.Lexit1:
- mov ret0=len // faster than using ar.lc
- mov ar.lc=saved_lc
- br.ret.sptk.many rp // end of short clear_user
-
-
- //
- // At this point we know we have more than 16 bytes to copy
- // so we focus on alignment (no branches required)
- //
- // The use of len/len2 for countdown of the number of bytes left
- // instead of ret0 is due to the fact that the exception code
- // changes the values of r8.
- //
-.long_do_clear:
- tbit.nz p6,p0=buf,0 // odd alignment (for long_do_clear)
- ;;
- EX( .Lexit3, (p6) st1 [buf]=r0,1 ) // 1-byte aligned
-(p6) adds len=-1,len;; // sync because buf is modified
- tbit.nz p6,p0=buf,1
- ;;
- EX( .Lexit3, (p6) st2 [buf]=r0,2 ) // 2-byte aligned
-(p6) adds len=-2,len;;
- tbit.nz p6,p0=buf,2
- ;;
- EX( .Lexit3, (p6) st4 [buf]=r0,4 ) // 4-byte aligned
-(p6) adds len=-4,len;;
- tbit.nz p6,p0=buf,3
- ;;
- EX( .Lexit3, (p6) st8 [buf]=r0,8 ) // 8-byte aligned
-(p6) adds len=-8,len;;
- shr.u cnt=len,4 // number of 128-bit (2x64bit) words
- ;;
- cmp.eq p6,p0=r0,cnt
- adds tmp=-1,cnt
-(p6) br.cond.dpnt .dotail // we have less than 16 bytes left
- ;;
- adds buf2=8,buf // setup second base pointer
- mov ar.lc=tmp
- ;;
-
- //
- // 16bytes/iteration core loop
- //
- // The second store can never generate a fault because
- // we come into the loop only when we are 16-byte aligned.
- // This means that if we cross a page then it will always be
- // in the first store and never in the second.
- //
- //
- // We need to keep track of the remaining length. A possible (optimistic)
- // way would be to use ar.lc and derive how many byte were left by
- // doing : left= 16*ar.lc + 16. this would avoid the addition at
- // every iteration.
- // However we need to keep the synchronization point. A template
- // M;;MB does not exist and thus we can keep the addition at no
- // extra cycle cost (use a nop slot anyway). It also simplifies the
- // (unlikely) error recovery code
- //
-
-2: EX(.Lexit3, st8 [buf]=r0,16 )
- ;; // needed to get len correct when error
- st8 [buf2]=r0,16
- adds len=-16,len
- br.cloop.dptk 2b
- ;;
- mov ar.lc=saved_lc
- //
- // tail correction based on len only
- //
- // We alternate the use of len3,len2 to allow parallelism and correct
- // error handling. We also reuse p6/p7 to return correct value.
- // The addition of len2/len3 does not cost anything more compared to
- // the regular memset as we had empty slots.
- //
-.dotail:
- mov len2=len // for parallelization of error handling
- mov len3=len
- tbit.nz p6,p0=len,3
- ;;
- EX( .Lexit2, (p6) st8 [buf]=r0,8 ) // at least 8 bytes
-(p6) adds len3=-8,len2
- tbit.nz p7,p6=len,2
- ;;
- EX( .Lexit2, (p7) st4 [buf]=r0,4 ) // at least 4 bytes
-(p7) adds len2=-4,len3
- tbit.nz p6,p7=len,1
- ;;
- EX( .Lexit2, (p6) st2 [buf]=r0,2 ) // at least 2 bytes
-(p6) adds len3=-2,len2
- tbit.nz p7,p6=len,0
- ;;
- EX( .Lexit2, (p7) st1 [buf]=r0 ) // only 1 byte left
- mov ret0=r0 // success
- br.ret.sptk.many rp // end of most likely path
-
- //
- // Outlined error handling code
- //
-
- //
- // .Lexit3: comes from core loop, need restore pr/lc
- // len contains bytes left
- //
- //
- // .Lexit2:
- // if p6 -> coming from st8 or st2 : len2 contains what's left
- // if p7 -> coming from st4 or st1 : len3 contains what's left
- // We must restore lc/pr even though might not have been used.
-.Lexit2:
- .pred.rel "mutex", p6, p7
-(p6) mov len=len2
-(p7) mov len=len3
- ;;
- //
- // .Lexit4: comes from head, need not restore pr/lc
- // len contains bytes left
- //
-.Lexit3:
- mov ret0=len
- mov ar.lc=saved_lc
- br.ret.sptk.many rp
-END(__do_clear_user)
-EXPORT_SYMBOL(__do_clear_user)
diff --git a/arch/ia64/lib/copy_page.S b/arch/ia64/lib/copy_page.S
deleted file mode 100644
index c0a0e6b2af00..000000000000
--- a/arch/ia64/lib/copy_page.S
+++ /dev/null
@@ -1,101 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *
- * Optimized version of the standard copy_page() function
- *
- * Inputs:
- * in0: address of target page
- * in1: address of source page
- * Output:
- * no return value
- *
- * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- * David Mosberger <davidm@hpl.hp.com>
- *
- * 4/06/01 davidm Tuned to make it perform well both for cached and uncached copies.
- */
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-#include <asm/page.h>
-
-#define PIPE_DEPTH 3
-#define EPI p[PIPE_DEPTH-1]
-
-#define lcount r16
-#define saved_pr r17
-#define saved_lc r18
-#define saved_pfs r19
-#define src1 r20
-#define src2 r21
-#define tgt1 r22
-#define tgt2 r23
-#define srcf r24
-#define tgtf r25
-#define tgt_last r26
-
-#define Nrot ((8*PIPE_DEPTH+7)&~7)
-
-GLOBAL_ENTRY(copy_page)
- .prologue
- .save ar.pfs, saved_pfs
- alloc saved_pfs=ar.pfs,3,Nrot-3,0,Nrot
-
- .rotr t1[PIPE_DEPTH], t2[PIPE_DEPTH], t3[PIPE_DEPTH], t4[PIPE_DEPTH], \
- t5[PIPE_DEPTH], t6[PIPE_DEPTH], t7[PIPE_DEPTH], t8[PIPE_DEPTH]
- .rotp p[PIPE_DEPTH]
-
- .save ar.lc, saved_lc
- mov saved_lc=ar.lc
- mov ar.ec=PIPE_DEPTH
-
- mov lcount=PAGE_SIZE/64-1
- .save pr, saved_pr
- mov saved_pr=pr
- mov pr.rot=1<<16
-
- .body
-
- mov src1=in1
- adds src2=8,in1
- mov tgt_last = PAGE_SIZE
- ;;
- adds tgt2=8,in0
- add srcf=512,in1
- mov ar.lc=lcount
- mov tgt1=in0
- add tgtf=512,in0
- add tgt_last = tgt_last, in0
- ;;
-1:
-(p[0]) ld8 t1[0]=[src1],16
-(EPI) st8 [tgt1]=t1[PIPE_DEPTH-1],16
-(p[0]) ld8 t2[0]=[src2],16
-(EPI) st8 [tgt2]=t2[PIPE_DEPTH-1],16
- cmp.ltu p6,p0 = tgtf, tgt_last
- ;;
-(p[0]) ld8 t3[0]=[src1],16
-(EPI) st8 [tgt1]=t3[PIPE_DEPTH-1],16
-(p[0]) ld8 t4[0]=[src2],16
-(EPI) st8 [tgt2]=t4[PIPE_DEPTH-1],16
- ;;
-(p[0]) ld8 t5[0]=[src1],16
-(EPI) st8 [tgt1]=t5[PIPE_DEPTH-1],16
-(p[0]) ld8 t6[0]=[src2],16
-(EPI) st8 [tgt2]=t6[PIPE_DEPTH-1],16
- ;;
-(p[0]) ld8 t7[0]=[src1],16
-(EPI) st8 [tgt1]=t7[PIPE_DEPTH-1],16
-(p[0]) ld8 t8[0]=[src2],16
-(EPI) st8 [tgt2]=t8[PIPE_DEPTH-1],16
-
-(p6) lfetch [srcf], 64
-(p6) lfetch [tgtf], 64
- br.ctop.sptk.few 1b
- ;;
- mov pr=saved_pr,0xffffffffffff0000 // restore predicates
- mov ar.pfs=saved_pfs
- mov ar.lc=saved_lc
- br.ret.sptk.many rp
-END(copy_page)
-EXPORT_SYMBOL(copy_page)
diff --git a/arch/ia64/lib/copy_page_mck.S b/arch/ia64/lib/copy_page_mck.S
deleted file mode 100644
index 5e8bb4b4b535..000000000000
--- a/arch/ia64/lib/copy_page_mck.S
+++ /dev/null
@@ -1,188 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * McKinley-optimized version of copy_page().
- *
- * Copyright (C) 2002 Hewlett-Packard Co
- * David Mosberger <davidm@hpl.hp.com>
- *
- * Inputs:
- * in0: address of target page
- * in1: address of source page
- * Output:
- * no return value
- *
- * General idea:
- * - use regular loads and stores to prefetch data to avoid consuming M-slot just for
- * lfetches => good for in-cache performance
- * - avoid l2 bank-conflicts by not storing into the same 16-byte bank within a single
- * cycle
- *
- * Principle of operation:
- * First, note that L1 has a line-size of 64 bytes and L2 a line-size of 128 bytes.
- * To avoid secondary misses in L2, we prefetch both source and destination with a line-size
- * of 128 bytes. When both of these lines are in the L2 and the first half of the
- * source line is in L1, we start copying the remaining words. The second half of the
- * source line is prefetched in an earlier iteration, so that by the time we start
- * accessing it, it's also present in the L1.
- *
- * We use a software-pipelined loop to control the overall operation. The pipeline
- * has 2*PREFETCH_DIST+K stages. The first PREFETCH_DIST stages are used for prefetching
- * source cache-lines. The second PREFETCH_DIST stages are used for prefetching destination
- * cache-lines, the last K stages are used to copy the cache-line words not copied by
- * the prefetches. The four relevant points in the pipelined are called A, B, C, D:
- * p[A] is TRUE if a source-line should be prefetched, p[B] is TRUE if a destination-line
- * should be prefetched, p[C] is TRUE if the second half of an L2 line should be brought
- * into L1D and p[D] is TRUE if a cacheline needs to be copied.
- *
- * This all sounds very complicated, but thanks to the modulo-scheduled loop support,
- * the resulting code is very regular and quite easy to follow (once you get the idea).
- *
- * As a secondary optimization, the first 2*PREFETCH_DIST iterations are implemented
- * as the separate .prefetch_loop. Logically, this loop performs exactly like the
- * main-loop (.line_copy), but has all known-to-be-predicated-off instructions removed,
- * so that each loop iteration is faster (again, good for cached case).
- *
- * When reading the code, it helps to keep the following picture in mind:
- *
- * word 0 word 1
- * +------+------+---
- * | v[x] | t1 | ^
- * | t2 | t3 | |
- * | t4 | t5 | |
- * | t6 | t7 | | 128 bytes
- * | n[y] | t9 | | (L2 cache line)
- * | t10 | t11 | |
- * | t12 | t13 | |
- * | t14 | t15 | v
- * +------+------+---
- *
- * Here, v[x] is copied by the (memory) prefetch. n[y] is loaded at p[C]
- * to fetch the second-half of the L2 cache line into L1, and the tX words are copied in
- * an order that avoids bank conflicts.
- */
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-#include <asm/page.h>
-
-#define PREFETCH_DIST 8 // McKinley sustains 16 outstanding L2 misses (8 ld, 8 st)
-
-#define src0 r2
-#define src1 r3
-#define dst0 r9
-#define dst1 r10
-#define src_pre_mem r11
-#define dst_pre_mem r14
-#define src_pre_l2 r15
-#define dst_pre_l2 r16
-#define t1 r17
-#define t2 r18
-#define t3 r19
-#define t4 r20
-#define t5 t1 // alias!
-#define t6 t2 // alias!
-#define t7 t3 // alias!
-#define t9 t5 // alias!
-#define t10 t4 // alias!
-#define t11 t7 // alias!
-#define t12 t6 // alias!
-#define t14 t10 // alias!
-#define t13 r21
-#define t15 r22
-
-#define saved_lc r23
-#define saved_pr r24
-
-#define A 0
-#define B (PREFETCH_DIST)
-#define C (B + PREFETCH_DIST)
-#define D (C + 3)
-#define N (D + 1)
-#define Nrot ((N + 7) & ~7)
-
-GLOBAL_ENTRY(copy_page)
- .prologue
- alloc r8 = ar.pfs, 2, Nrot-2, 0, Nrot
-
- .rotr v[2*PREFETCH_DIST], n[D-C+1]
- .rotp p[N]
-
- .save ar.lc, saved_lc
- mov saved_lc = ar.lc
- .save pr, saved_pr
- mov saved_pr = pr
- .body
-
- mov src_pre_mem = in1
- mov pr.rot = 0x10000
- mov ar.ec = 1 // special unrolled loop
-
- mov dst_pre_mem = in0
- mov ar.lc = 2*PREFETCH_DIST - 1
-
- add src_pre_l2 = 8*8, in1
- add dst_pre_l2 = 8*8, in0
- add src0 = 8, in1 // first t1 src
- add src1 = 3*8, in1 // first t3 src
- add dst0 = 8, in0 // first t1 dst
- add dst1 = 3*8, in0 // first t3 dst
- mov t1 = (PAGE_SIZE/128) - (2*PREFETCH_DIST) - 1
- nop.m 0
- nop.i 0
- ;;
- // same as .line_copy loop, but with all predicated-off instructions removed:
-.prefetch_loop:
-(p[A]) ld8 v[A] = [src_pre_mem], 128 // M0
-(p[B]) st8 [dst_pre_mem] = v[B], 128 // M2
- br.ctop.sptk .prefetch_loop
- ;;
- cmp.eq p16, p0 = r0, r0 // reset p16 to 1 (br.ctop cleared it to zero)
- mov ar.lc = t1 // with 64KB pages, t1 is too big to fit in 8 bits!
- mov ar.ec = N // # of stages in pipeline
- ;;
-.line_copy:
-(p[D]) ld8 t2 = [src0], 3*8 // M0
-(p[D]) ld8 t4 = [src1], 3*8 // M1
-(p[B]) st8 [dst_pre_mem] = v[B], 128 // M2 prefetch dst from memory
-(p[D]) st8 [dst_pre_l2] = n[D-C], 128 // M3 prefetch dst from L2
- ;;
-(p[A]) ld8 v[A] = [src_pre_mem], 128 // M0 prefetch src from memory
-(p[C]) ld8 n[0] = [src_pre_l2], 128 // M1 prefetch src from L2
-(p[D]) st8 [dst0] = t1, 8 // M2
-(p[D]) st8 [dst1] = t3, 8 // M3
- ;;
-(p[D]) ld8 t5 = [src0], 8
-(p[D]) ld8 t7 = [src1], 3*8
-(p[D]) st8 [dst0] = t2, 3*8
-(p[D]) st8 [dst1] = t4, 3*8
- ;;
-(p[D]) ld8 t6 = [src0], 3*8
-(p[D]) ld8 t10 = [src1], 8
-(p[D]) st8 [dst0] = t5, 8
-(p[D]) st8 [dst1] = t7, 3*8
- ;;
-(p[D]) ld8 t9 = [src0], 3*8
-(p[D]) ld8 t11 = [src1], 3*8
-(p[D]) st8 [dst0] = t6, 3*8
-(p[D]) st8 [dst1] = t10, 8
- ;;
-(p[D]) ld8 t12 = [src0], 8
-(p[D]) ld8 t14 = [src1], 8
-(p[D]) st8 [dst0] = t9, 3*8
-(p[D]) st8 [dst1] = t11, 3*8
- ;;
-(p[D]) ld8 t13 = [src0], 4*8
-(p[D]) ld8 t15 = [src1], 4*8
-(p[D]) st8 [dst0] = t12, 8
-(p[D]) st8 [dst1] = t14, 8
- ;;
-(p[D-1])ld8 t1 = [src0], 8
-(p[D-1])ld8 t3 = [src1], 8
-(p[D]) st8 [dst0] = t13, 4*8
-(p[D]) st8 [dst1] = t15, 4*8
- br.ctop.sptk .line_copy
- ;;
- mov ar.lc = saved_lc
- mov pr = saved_pr, -1
- br.ret.sptk.many rp
-END(copy_page)
-EXPORT_SYMBOL(copy_page)
diff --git a/arch/ia64/lib/copy_user.S b/arch/ia64/lib/copy_user.S
deleted file mode 100644
index 8daab72cfe77..000000000000
--- a/arch/ia64/lib/copy_user.S
+++ /dev/null
@@ -1,613 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *
- * Optimized version of the copy_user() routine.
- * It is used to copy date across the kernel/user boundary.
- *
- * The source and destination are always on opposite side of
- * the boundary. When reading from user space we must catch
- * faults on loads. When writing to user space we must catch
- * errors on stores. Note that because of the nature of the copy
- * we don't need to worry about overlapping regions.
- *
- *
- * Inputs:
- * in0 address of source buffer
- * in1 address of destination buffer
- * in2 number of bytes to copy
- *
- * Outputs:
- * ret0 0 in case of success. The number of bytes NOT copied in
- * case of error.
- *
- * Copyright (C) 2000-2001 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- *
- * Fixme:
- * - handle the case where we have more than 16 bytes and the alignment
- * are different.
- * - more benchmarking
- * - fix extraneous stop bit introduced by the EX() macro.
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-//
-// Tuneable parameters
-//
-#define COPY_BREAK 16 // we do byte copy below (must be >=16)
-#define PIPE_DEPTH 21 // pipe depth
-
-#define EPI p[PIPE_DEPTH-1]
-
-//
-// arguments
-//
-#define dst in0
-#define src in1
-#define len in2
-
-//
-// local registers
-//
-#define t1 r2 // rshift in bytes
-#define t2 r3 // lshift in bytes
-#define rshift r14 // right shift in bits
-#define lshift r15 // left shift in bits
-#define word1 r16
-#define word2 r17
-#define cnt r18
-#define len2 r19
-#define saved_lc r20
-#define saved_pr r21
-#define tmp r22
-#define val r23
-#define src1 r24
-#define dst1 r25
-#define src2 r26
-#define dst2 r27
-#define len1 r28
-#define enddst r29
-#define endsrc r30
-#define saved_pfs r31
-
-GLOBAL_ENTRY(__copy_user)
- .prologue
- .save ar.pfs, saved_pfs
- alloc saved_pfs=ar.pfs,3,((2*PIPE_DEPTH+7)&~7),0,((2*PIPE_DEPTH+7)&~7)
-
- .rotr val1[PIPE_DEPTH],val2[PIPE_DEPTH]
- .rotp p[PIPE_DEPTH]
-
- adds len2=-1,len // br.ctop is repeat/until
- mov ret0=r0
-
- ;; // RAW of cfm when len=0
- cmp.eq p8,p0=r0,len // check for zero length
- .save ar.lc, saved_lc
- mov saved_lc=ar.lc // preserve ar.lc (slow)
-(p8) br.ret.spnt.many rp // empty mempcy()
- ;;
- add enddst=dst,len // first byte after end of source
- add endsrc=src,len // first byte after end of destination
- .save pr, saved_pr
- mov saved_pr=pr // preserve predicates
-
- .body
-
- mov dst1=dst // copy because of rotation
- mov ar.ec=PIPE_DEPTH
- mov pr.rot=1<<16 // p16=true all others are false
-
- mov src1=src // copy because of rotation
- mov ar.lc=len2 // initialize lc for small count
- cmp.lt p10,p7=COPY_BREAK,len // if len > COPY_BREAK then long copy
-
- xor tmp=src,dst // same alignment test prepare
-(p10) br.cond.dptk .long_copy_user
- ;; // RAW pr.rot/p16 ?
- //
- // Now we do the byte by byte loop with software pipeline
- //
- // p7 is necessarily false by now
-1:
- EX(.failure_in_pipe1,(p16) ld1 val1[0]=[src1],1)
- EX(.failure_out,(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1)
- br.ctop.dptk.few 1b
- ;;
- mov ar.lc=saved_lc
- mov pr=saved_pr,0xffffffffffff0000
- mov ar.pfs=saved_pfs // restore ar.ec
- br.ret.sptk.many rp // end of short memcpy
-
- //
- // Not 8-byte aligned
- //
-.diff_align_copy_user:
- // At this point we know we have more than 16 bytes to copy
- // and also that src and dest do _not_ have the same alignment.
- and src2=0x7,src1 // src offset
- and dst2=0x7,dst1 // dst offset
- ;;
- // The basic idea is that we copy byte-by-byte at the head so
- // that we can reach 8-byte alignment for both src1 and dst1.
- // Then copy the body using software pipelined 8-byte copy,
- // shifting the two back-to-back words right and left, then copy
- // the tail by copying byte-by-byte.
- //
- // Fault handling. If the byte-by-byte at the head fails on the
- // load, then restart and finish the pipleline by copying zeros
- // to the dst1. Then copy zeros for the rest of dst1.
- // If 8-byte software pipeline fails on the load, do the same as
- // failure_in3 does. If the byte-by-byte at the tail fails, it is
- // handled simply by failure_in_pipe1.
- //
- // The case p14 represents the source has more bytes in the
- // the first word (by the shifted part), whereas the p15 needs to
- // copy some bytes from the 2nd word of the source that has the
- // tail of the 1st of the destination.
- //
-
- //
- // Optimization. If dst1 is 8-byte aligned (quite common), we don't need
- // to copy the head to dst1, to start 8-byte copy software pipeline.
- // We know src1 is not 8-byte aligned in this case.
- //
- cmp.eq p14,p15=r0,dst2
-(p15) br.cond.spnt 1f
- ;;
- sub t1=8,src2
- mov t2=src2
- ;;
- shl rshift=t2,3
- sub len1=len,t1 // set len1
- ;;
- sub lshift=64,rshift
- ;;
- br.cond.spnt .word_copy_user
- ;;
-1:
- cmp.leu p14,p15=src2,dst2
- sub t1=dst2,src2
- ;;
- .pred.rel "mutex", p14, p15
-(p14) sub word1=8,src2 // (8 - src offset)
-(p15) sub t1=r0,t1 // absolute value
-(p15) sub word1=8,dst2 // (8 - dst offset)
- ;;
- // For the case p14, we don't need to copy the shifted part to
- // the 1st word of destination.
- sub t2=8,t1
-(p14) sub word1=word1,t1
- ;;
- sub len1=len,word1 // resulting len
-(p15) shl rshift=t1,3 // in bits
-(p14) shl rshift=t2,3
- ;;
-(p14) sub len1=len1,t1
- adds cnt=-1,word1
- ;;
- sub lshift=64,rshift
- mov ar.ec=PIPE_DEPTH
- mov pr.rot=1<<16 // p16=true all others are false
- mov ar.lc=cnt
- ;;
-2:
- EX(.failure_in_pipe2,(p16) ld1 val1[0]=[src1],1)
- EX(.failure_out,(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1)
- br.ctop.dptk.few 2b
- ;;
- clrrrb
- ;;
-.word_copy_user:
- cmp.gtu p9,p0=16,len1
-(p9) br.cond.spnt 4f // if (16 > len1) skip 8-byte copy
- ;;
- shr.u cnt=len1,3 // number of 64-bit words
- ;;
- adds cnt=-1,cnt
- ;;
- .pred.rel "mutex", p14, p15
-(p14) sub src1=src1,t2
-(p15) sub src1=src1,t1
- //
- // Now both src1 and dst1 point to an 8-byte aligned address. And
- // we have more than 8 bytes to copy.
- //
- mov ar.lc=cnt
- mov ar.ec=PIPE_DEPTH
- mov pr.rot=1<<16 // p16=true all others are false
- ;;
-3:
- //
- // The pipleline consists of 3 stages:
- // 1 (p16): Load a word from src1
- // 2 (EPI_1): Shift right pair, saving to tmp
- // 3 (EPI): Store tmp to dst1
- //
- // To make it simple, use at least 2 (p16) loops to set up val1[n]
- // because we need 2 back-to-back val1[] to get tmp.
- // Note that this implies EPI_2 must be p18 or greater.
- //
-
-#define EPI_1 p[PIPE_DEPTH-2]
-#define SWITCH(pred, shift) cmp.eq pred,p0=shift,rshift
-#define CASE(pred, shift) \
- (pred) br.cond.spnt .copy_user_bit##shift
-#define BODY(rshift) \
-.copy_user_bit##rshift: \
-1: \
- EX(.failure_out,(EPI) st8 [dst1]=tmp,8); \
-(EPI_1) shrp tmp=val1[PIPE_DEPTH-2],val1[PIPE_DEPTH-1],rshift; \
- EX(3f,(p16) ld8 val1[1]=[src1],8); \
-(p16) mov val1[0]=r0; \
- br.ctop.dptk 1b; \
- ;; \
- br.cond.sptk.many .diff_align_do_tail; \
-2: \
-(EPI) st8 [dst1]=tmp,8; \
-(EPI_1) shrp tmp=val1[PIPE_DEPTH-2],val1[PIPE_DEPTH-1],rshift; \
-3: \
-(p16) mov val1[1]=r0; \
-(p16) mov val1[0]=r0; \
- br.ctop.dptk 2b; \
- ;; \
- br.cond.sptk.many .failure_in2
-
- //
- // Since the instruction 'shrp' requires a fixed 128-bit value
- // specifying the bits to shift, we need to provide 7 cases
- // below.
- //
- SWITCH(p6, 8)
- SWITCH(p7, 16)
- SWITCH(p8, 24)
- SWITCH(p9, 32)
- SWITCH(p10, 40)
- SWITCH(p11, 48)
- SWITCH(p12, 56)
- ;;
- CASE(p6, 8)
- CASE(p7, 16)
- CASE(p8, 24)
- CASE(p9, 32)
- CASE(p10, 40)
- CASE(p11, 48)
- CASE(p12, 56)
- ;;
- BODY(8)
- BODY(16)
- BODY(24)
- BODY(32)
- BODY(40)
- BODY(48)
- BODY(56)
- ;;
-.diff_align_do_tail:
- .pred.rel "mutex", p14, p15
-(p14) sub src1=src1,t1
-(p14) adds dst1=-8,dst1
-(p15) sub dst1=dst1,t1
- ;;
-4:
- // Tail correction.
- //
- // The problem with this piplelined loop is that the last word is not
- // loaded and thus parf of the last word written is not correct.
- // To fix that, we simply copy the tail byte by byte.
-
- sub len1=endsrc,src1,1
- clrrrb
- ;;
- mov ar.ec=PIPE_DEPTH
- mov pr.rot=1<<16 // p16=true all others are false
- mov ar.lc=len1
- ;;
-5:
- EX(.failure_in_pipe1,(p16) ld1 val1[0]=[src1],1)
- EX(.failure_out,(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1)
- br.ctop.dptk.few 5b
- ;;
- mov ar.lc=saved_lc
- mov pr=saved_pr,0xffffffffffff0000
- mov ar.pfs=saved_pfs
- br.ret.sptk.many rp
-
- //
- // Beginning of long mempcy (i.e. > 16 bytes)
- //
-.long_copy_user:
- tbit.nz p6,p7=src1,0 // odd alignment
- and tmp=7,tmp
- ;;
- cmp.eq p10,p8=r0,tmp
- mov len1=len // copy because of rotation
-(p8) br.cond.dpnt .diff_align_copy_user
- ;;
- // At this point we know we have more than 16 bytes to copy
- // and also that both src and dest have the same alignment
- // which may not be the one we want. So for now we must move
- // forward slowly until we reach 16byte alignment: no need to
- // worry about reaching the end of buffer.
- //
- EX(.failure_in1,(p6) ld1 val1[0]=[src1],1) // 1-byte aligned
-(p6) adds len1=-1,len1;;
- tbit.nz p7,p0=src1,1
- ;;
- EX(.failure_in1,(p7) ld2 val1[1]=[src1],2) // 2-byte aligned
-(p7) adds len1=-2,len1;;
- tbit.nz p8,p0=src1,2
- ;;
- //
- // Stop bit not required after ld4 because if we fail on ld4
- // we have never executed the ld1, therefore st1 is not executed.
- //
- EX(.failure_in1,(p8) ld4 val2[0]=[src1],4) // 4-byte aligned
- ;;
- EX(.failure_out,(p6) st1 [dst1]=val1[0],1)
- tbit.nz p9,p0=src1,3
- ;;
- //
- // Stop bit not required after ld8 because if we fail on ld8
- // we have never executed the ld2, therefore st2 is not executed.
- //
- EX(.failure_in1,(p9) ld8 val2[1]=[src1],8) // 8-byte aligned
- EX(.failure_out,(p7) st2 [dst1]=val1[1],2)
-(p8) adds len1=-4,len1
- ;;
- EX(.failure_out, (p8) st4 [dst1]=val2[0],4)
-(p9) adds len1=-8,len1;;
- shr.u cnt=len1,4 // number of 128-bit (2x64bit) words
- ;;
- EX(.failure_out, (p9) st8 [dst1]=val2[1],8)
- tbit.nz p6,p0=len1,3
- cmp.eq p7,p0=r0,cnt
- adds tmp=-1,cnt // br.ctop is repeat/until
-(p7) br.cond.dpnt .dotail // we have less than 16 bytes left
- ;;
- adds src2=8,src1
- adds dst2=8,dst1
- mov ar.lc=tmp
- ;;
- //
- // 16bytes/iteration
- //
-2:
- EX(.failure_in3,(p16) ld8 val1[0]=[src1],16)
-(p16) ld8 val2[0]=[src2],16
-
- EX(.failure_out, (EPI) st8 [dst1]=val1[PIPE_DEPTH-1],16)
-(EPI) st8 [dst2]=val2[PIPE_DEPTH-1],16
- br.ctop.dptk 2b
- ;; // RAW on src1 when fall through from loop
- //
- // Tail correction based on len only
- //
- // No matter where we come from (loop or test) the src1 pointer
- // is 16 byte aligned AND we have less than 16 bytes to copy.
- //
-.dotail:
- EX(.failure_in1,(p6) ld8 val1[0]=[src1],8) // at least 8 bytes
- tbit.nz p7,p0=len1,2
- ;;
- EX(.failure_in1,(p7) ld4 val1[1]=[src1],4) // at least 4 bytes
- tbit.nz p8,p0=len1,1
- ;;
- EX(.failure_in1,(p8) ld2 val2[0]=[src1],2) // at least 2 bytes
- tbit.nz p9,p0=len1,0
- ;;
- EX(.failure_out, (p6) st8 [dst1]=val1[0],8)
- ;;
- EX(.failure_in1,(p9) ld1 val2[1]=[src1]) // only 1 byte left
- mov ar.lc=saved_lc
- ;;
- EX(.failure_out,(p7) st4 [dst1]=val1[1],4)
- mov pr=saved_pr,0xffffffffffff0000
- ;;
- EX(.failure_out, (p8) st2 [dst1]=val2[0],2)
- mov ar.pfs=saved_pfs
- ;;
- EX(.failure_out, (p9) st1 [dst1]=val2[1])
- br.ret.sptk.many rp
-
-
- //
- // Here we handle the case where the byte by byte copy fails
- // on the load.
- // Several factors make the zeroing of the rest of the buffer kind of
- // tricky:
- // - the pipeline: loads/stores are not in sync (pipeline)
- //
- // In the same loop iteration, the dst1 pointer does not directly
- // reflect where the faulty load was.
- //
- // - pipeline effect
- // When you get a fault on load, you may have valid data from
- // previous loads not yet store in transit. Such data must be
- // store normally before moving onto zeroing the rest.
- //
- // - single/multi dispersal independence.
- //
- // solution:
- // - we don't disrupt the pipeline, i.e. data in transit in
- // the software pipeline will be eventually move to memory.
- // We simply replace the load with a simple mov and keep the
- // pipeline going. We can't really do this inline because
- // p16 is always reset to 1 when lc > 0.
- //
-.failure_in_pipe1:
- sub ret0=endsrc,src1 // number of bytes to zero, i.e. not copied
-1:
-(p16) mov val1[0]=r0
-(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1
- br.ctop.dptk 1b
- ;;
- mov pr=saved_pr,0xffffffffffff0000
- mov ar.lc=saved_lc
- mov ar.pfs=saved_pfs
- br.ret.sptk.many rp
-
- //
- // This is the case where the byte by byte copy fails on the load
- // when we copy the head. We need to finish the pipeline and copy
- // zeros for the rest of the destination. Since this happens
- // at the top we still need to fill the body and tail.
-.failure_in_pipe2:
- sub ret0=endsrc,src1 // number of bytes to zero, i.e. not copied
-2:
-(p16) mov val1[0]=r0
-(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1
- br.ctop.dptk 2b
- ;;
- sub len=enddst,dst1,1 // precompute len
- br.cond.dptk.many .failure_in1bis
- ;;
-
- //
- // Here we handle the head & tail part when we check for alignment.
- // The following code handles only the load failures. The
- // main diffculty comes from the fact that loads/stores are
- // scheduled. So when you fail on a load, the stores corresponding
- // to previous successful loads must be executed.
- //
- // However some simplifications are possible given the way
- // things work.
- //
- // 1) HEAD
- // Theory of operation:
- //
- // Page A | Page B
- // ---------|-----
- // 1|8 x
- // 1 2|8 x
- // 4|8 x
- // 1 4|8 x
- // 2 4|8 x
- // 1 2 4|8 x
- // |1
- // |2 x
- // |4 x
- //
- // page_size >= 4k (2^12). (x means 4, 2, 1)
- // Here we suppose Page A exists and Page B does not.
- //
- // As we move towards eight byte alignment we may encounter faults.
- // The numbers on each page show the size of the load (current alignment).
- //
- // Key point:
- // - if you fail on 1, 2, 4 then you have never executed any smaller
- // size loads, e.g. failing ld4 means no ld1 nor ld2 executed
- // before.
- //
- // This allows us to simplify the cleanup code, because basically you
- // only have to worry about "pending" stores in the case of a failing
- // ld8(). Given the way the code is written today, this means only
- // worry about st2, st4. There we can use the information encapsulated
- // into the predicates.
- //
- // Other key point:
- // - if you fail on the ld8 in the head, it means you went straight
- // to it, i.e. 8byte alignment within an unexisting page.
- // Again this comes from the fact that if you crossed just for the ld8 then
- // you are 8byte aligned but also 16byte align, therefore you would
- // either go for the 16byte copy loop OR the ld8 in the tail part.
- // The combination ld1, ld2, ld4, ld8 where you fail on ld8 is impossible
- // because it would mean you had 15bytes to copy in which case you
- // would have defaulted to the byte by byte copy.
- //
- //
- // 2) TAIL
- // Here we now we have less than 16 bytes AND we are either 8 or 16 byte
- // aligned.
- //
- // Key point:
- // This means that we either:
- // - are right on a page boundary
- // OR
- // - are at more than 16 bytes from a page boundary with
- // at most 15 bytes to copy: no chance of crossing.
- //
- // This allows us to assume that if we fail on a load we haven't possibly
- // executed any of the previous (tail) ones, so we don't need to do
- // any stores. For instance, if we fail on ld2, this means we had
- // 2 or 3 bytes left to copy and we did not execute the ld8 nor ld4.
- //
- // This means that we are in a situation similar the a fault in the
- // head part. That's nice!
- //
-.failure_in1:
- sub ret0=endsrc,src1 // number of bytes to zero, i.e. not copied
- sub len=endsrc,src1,1
- //
- // we know that ret0 can never be zero at this point
- // because we failed why trying to do a load, i.e. there is still
- // some work to do.
- // The failure_in1bis and length problem is taken care of at the
- // calling side.
- //
- ;;
-.failure_in1bis: // from (.failure_in3)
- mov ar.lc=len // Continue with a stupid byte store.
- ;;
-5:
- st1 [dst1]=r0,1
- br.cloop.dptk 5b
- ;;
- mov pr=saved_pr,0xffffffffffff0000
- mov ar.lc=saved_lc
- mov ar.pfs=saved_pfs
- br.ret.sptk.many rp
-
- //
- // Here we simply restart the loop but instead
- // of doing loads we fill the pipeline with zeroes
- // We can't simply store r0 because we may have valid
- // data in transit in the pipeline.
- // ar.lc and ar.ec are setup correctly at this point
- //
- // we MUST use src1/endsrc here and not dst1/enddst because
- // of the pipeline effect.
- //
-.failure_in3:
- sub ret0=endsrc,src1 // number of bytes to zero, i.e. not copied
- ;;
-2:
-(p16) mov val1[0]=r0
-(p16) mov val2[0]=r0
-(EPI) st8 [dst1]=val1[PIPE_DEPTH-1],16
-(EPI) st8 [dst2]=val2[PIPE_DEPTH-1],16
- br.ctop.dptk 2b
- ;;
- cmp.ne p6,p0=dst1,enddst // Do we need to finish the tail ?
- sub len=enddst,dst1,1 // precompute len
-(p6) br.cond.dptk .failure_in1bis
- ;;
- mov pr=saved_pr,0xffffffffffff0000
- mov ar.lc=saved_lc
- mov ar.pfs=saved_pfs
- br.ret.sptk.many rp
-
-.failure_in2:
- sub ret0=endsrc,src1
- cmp.ne p6,p0=dst1,enddst // Do we need to finish the tail ?
- sub len=enddst,dst1,1 // precompute len
-(p6) br.cond.dptk .failure_in1bis
- ;;
- mov pr=saved_pr,0xffffffffffff0000
- mov ar.lc=saved_lc
- mov ar.pfs=saved_pfs
- br.ret.sptk.many rp
-
- //
- // handling of failures on stores: that's the easy part
- //
-.failure_out:
- sub ret0=enddst,dst1
- mov pr=saved_pr,0xffffffffffff0000
- mov ar.lc=saved_lc
-
- mov ar.pfs=saved_pfs
- br.ret.sptk.many rp
-END(__copy_user)
-EXPORT_SYMBOL(__copy_user)
diff --git a/arch/ia64/lib/csum_partial_copy.c b/arch/ia64/lib/csum_partial_copy.c
deleted file mode 100644
index 917e3138b277..000000000000
--- a/arch/ia64/lib/csum_partial_copy.c
+++ /dev/null
@@ -1,98 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Network Checksum & Copy routine
- *
- * Copyright (C) 1999, 2003-2004 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- *
- * Most of the code has been imported from Linux/Alpha
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/string.h>
-
-#include <net/checksum.h>
-
-/*
- * XXX Fixme: those 2 inlines are meant for debugging and will go away
- */
-static inline unsigned
-short from64to16(unsigned long x)
-{
- /* add up 32-bit words for 33 bits */
- x = (x & 0xffffffff) + (x >> 32);
- /* add up 16-bit and 17-bit words for 17+c bits */
- x = (x & 0xffff) + (x >> 16);
- /* add up 16-bit and 2-bit for 16+c bit */
- x = (x & 0xffff) + (x >> 16);
- /* add up carry.. */
- x = (x & 0xffff) + (x >> 16);
- return x;
-}
-
-static inline
-unsigned long do_csum_c(const unsigned char * buff, int len, unsigned int psum)
-{
- int odd, count;
- unsigned long result = (unsigned long)psum;
-
- if (len <= 0)
- goto out;
- odd = 1 & (unsigned long) buff;
- if (odd) {
- result = *buff << 8;
- len--;
- buff++;
- }
- count = len >> 1; /* nr of 16-bit words.. */
- if (count) {
- if (2 & (unsigned long) buff) {
- result += *(unsigned short *) buff;
- count--;
- len -= 2;
- buff += 2;
- }
- count >>= 1; /* nr of 32-bit words.. */
- if (count) {
- if (4 & (unsigned long) buff) {
- result += *(unsigned int *) buff;
- count--;
- len -= 4;
- buff += 4;
- }
- count >>= 1; /* nr of 64-bit words.. */
- if (count) {
- unsigned long carry = 0;
- do {
- unsigned long w = *(unsigned long *) buff;
- count--;
- buff += 8;
- result += carry;
- result += w;
- carry = (w > result);
- } while (count);
- result += carry;
- result = (result & 0xffffffff) + (result >> 32);
- }
- if (len & 4) {
- result += *(unsigned int *) buff;
- buff += 4;
- }
- }
- if (len & 2) {
- result += *(unsigned short *) buff;
- buff += 2;
- }
- }
- if (len & 1)
- result += *buff;
-
- result = from64to16(result);
-
- if (odd)
- result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
-
-out:
- return result;
-}
diff --git a/arch/ia64/lib/do_csum.S b/arch/ia64/lib/do_csum.S
deleted file mode 100644
index 6004dad2597c..000000000000
--- a/arch/ia64/lib/do_csum.S
+++ /dev/null
@@ -1,324 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *
- * Optmized version of the standard do_csum() function
- *
- * Return: a 64bit quantity containing the 16bit Internet checksum
- *
- * Inputs:
- * in0: address of buffer to checksum (char *)
- * in1: length of the buffer (int)
- *
- * Copyright (C) 1999, 2001-2002 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- *
- * 02/04/22 Ken Chen <kenneth.w.chen@intel.com>
- * Data locality study on the checksum buffer.
- * More optimization cleanup - remove excessive stop bits.
- * 02/04/08 David Mosberger <davidm@hpl.hp.com>
- * More cleanup and tuning.
- * 01/04/18 Jun Nakajima <jun.nakajima@intel.com>
- * Clean up and optimize and the software pipeline, loading two
- * back-to-back 8-byte words per loop. Clean up the initialization
- * for the loop. Support the cases where load latency = 1 or 2.
- * Set CONFIG_IA64_LOAD_LATENCY to 1 or 2 (default).
- */
-
-#include <asm/asmmacro.h>
-
-//
-// Theory of operations:
-// The goal is to go as quickly as possible to the point where
-// we can checksum 16 bytes/loop. Before reaching that point we must
-// take care of incorrect alignment of first byte.
-//
-// The code hereafter also takes care of the "tail" part of the buffer
-// before entering the core loop, if any. The checksum is a sum so it
-// allows us to commute operations. So we do the "head" and "tail"
-// first to finish at full speed in the body. Once we get the head and
-// tail values, we feed them into the pipeline, very handy initialization.
-//
-// Of course we deal with the special case where the whole buffer fits
-// into one 8 byte word. In this case we have only one entry in the pipeline.
-//
-// We use a (LOAD_LATENCY+2)-stage pipeline in the loop to account for
-// possible load latency and also to accommodate for head and tail.
-//
-// The end of the function deals with folding the checksum from 64bits
-// down to 16bits taking care of the carry.
-//
-// This version avoids synchronization in the core loop by also using a
-// pipeline for the accumulation of the checksum in resultx[] (x=1,2).
-//
-// wordx[] (x=1,2)
-// |---|
-// | | 0 : new value loaded in pipeline
-// |---|
-// | | - : in transit data
-// |---|
-// | | LOAD_LATENCY : current value to add to checksum
-// |---|
-// | | LOAD_LATENCY+1 : previous value added to checksum
-// |---| (previous iteration)
-//
-// resultx[] (x=1,2)
-// |---|
-// | | 0 : initial value
-// |---|
-// | | LOAD_LATENCY-1 : new checksum
-// |---|
-// | | LOAD_LATENCY : previous value of checksum
-// |---|
-// | | LOAD_LATENCY+1 : final checksum when out of the loop
-// |---|
-//
-//
-// See RFC1071 "Computing the Internet Checksum" for various techniques for
-// calculating the Internet checksum.
-//
-// NOT YET DONE:
-// - Maybe another algorithm which would take care of the folding at the
-// end in a different manner
-// - Work with people more knowledgeable than me on the network stack
-// to figure out if we could not split the function depending on the
-// type of packet or alignment we get. Like the ip_fast_csum() routine
-// where we know we have at least 20bytes worth of data to checksum.
-// - Do a better job of handling small packets.
-// - Note on prefetching: it was found that under various load, i.e. ftp read/write,
-// nfs read/write, the L1 cache hit rate is at 60% and L2 cache hit rate is at 99.8%
-// on the data that buffer points to (partly because the checksum is often preceded by
-// a copy_from_user()). This finding indiate that lfetch will not be beneficial since
-// the data is already in the cache.
-//
-
-#define saved_pfs r11
-#define hmask r16
-#define tmask r17
-#define first1 r18
-#define firstval r19
-#define firstoff r20
-#define last r21
-#define lastval r22
-#define lastoff r23
-#define saved_lc r24
-#define saved_pr r25
-#define tmp1 r26
-#define tmp2 r27
-#define tmp3 r28
-#define carry1 r29
-#define carry2 r30
-#define first2 r31
-
-#define buf in0
-#define len in1
-
-#define LOAD_LATENCY 2 // XXX fix me
-
-#if (LOAD_LATENCY != 1) && (LOAD_LATENCY != 2)
-# error "Only 1 or 2 is supported/tested for LOAD_LATENCY."
-#endif
-
-#define PIPE_DEPTH (LOAD_LATENCY+2)
-#define ELD p[LOAD_LATENCY] // end of load
-#define ELD_1 p[LOAD_LATENCY+1] // and next stage
-
-// unsigned long do_csum(unsigned char *buf,long len)
-
-GLOBAL_ENTRY(do_csum)
- .prologue
- .save ar.pfs, saved_pfs
- alloc saved_pfs=ar.pfs,2,16,0,16
- .rotr word1[4], word2[4],result1[LOAD_LATENCY+2],result2[LOAD_LATENCY+2]
- .rotp p[PIPE_DEPTH], pC1[2], pC2[2]
- mov ret0=r0 // in case we have zero length
- cmp.lt p0,p6=r0,len // check for zero length or negative (32bit len)
- ;;
- add tmp1=buf,len // last byte's address
- .save pr, saved_pr
- mov saved_pr=pr // preserve predicates (rotation)
-(p6) br.ret.spnt.many rp // return if zero or negative length
-
- mov hmask=-1 // initialize head mask
- tbit.nz p15,p0=buf,0 // is buf an odd address?
- and first1=-8,buf // 8-byte align down address of first1 element
-
- and firstoff=7,buf // how many bytes off for first1 element
- mov tmask=-1 // initialize tail mask
-
- ;;
- adds tmp2=-1,tmp1 // last-1
- and lastoff=7,tmp1 // how many bytes off for last element
- ;;
- sub tmp1=8,lastoff // complement to lastoff
- and last=-8,tmp2 // address of word containing last byte
- ;;
- sub tmp3=last,first1 // tmp3=distance from first1 to last
- .save ar.lc, saved_lc
- mov saved_lc=ar.lc // save lc
- cmp.eq p8,p9=last,first1 // everything fits in one word ?
-
- ld8 firstval=[first1],8 // load, ahead of time, "first1" word
- and tmp1=7, tmp1 // make sure that if tmp1==8 -> tmp1=0
- shl tmp2=firstoff,3 // number of bits
- ;;
-(p9) ld8 lastval=[last] // load, ahead of time, "last" word, if needed
- shl tmp1=tmp1,3 // number of bits
-(p9) adds tmp3=-8,tmp3 // effectively loaded
- ;;
-(p8) mov lastval=r0 // we don't need lastval if first1==last
- shl hmask=hmask,tmp2 // build head mask, mask off [0,first1off[
- shr.u tmask=tmask,tmp1 // build tail mask, mask off ]8,lastoff]
- ;;
- .body
-#define count tmp3
-
-(p8) and hmask=hmask,tmask // apply tail mask to head mask if 1 word only
-(p9) and word2[0]=lastval,tmask // mask last it as appropriate
- shr.u count=count,3 // how many 8-byte?
- ;;
- // If count is odd, finish this 8-byte word so that we can
- // load two back-to-back 8-byte words per loop thereafter.
- and word1[0]=firstval,hmask // and mask it as appropriate
- tbit.nz p10,p11=count,0 // if (count is odd)
- ;;
-(p8) mov result1[0]=word1[0]
-(p9) add result1[0]=word1[0],word2[0]
- ;;
- cmp.ltu p6,p0=result1[0],word1[0] // check the carry
- cmp.eq.or.andcm p8,p0=0,count // exit if zero 8-byte
- ;;
-(p6) adds result1[0]=1,result1[0]
-(p8) br.cond.dptk .do_csum_exit // if (within an 8-byte word)
-(p11) br.cond.dptk .do_csum16 // if (count is even)
-
- // Here count is odd.
- ld8 word1[1]=[first1],8 // load an 8-byte word
- cmp.eq p9,p10=1,count // if (count == 1)
- adds count=-1,count // loaded an 8-byte word
- ;;
- add result1[0]=result1[0],word1[1]
- ;;
- cmp.ltu p6,p0=result1[0],word1[1]
- ;;
-(p6) adds result1[0]=1,result1[0]
-(p9) br.cond.sptk .do_csum_exit // if (count == 1) exit
- // Fall through to calculate the checksum, feeding result1[0] as
- // the initial value in result1[0].
- //
- // Calculate the checksum loading two 8-byte words per loop.
- //
-.do_csum16:
- add first2=8,first1
- shr.u count=count,1 // we do 16 bytes per loop
- ;;
- adds count=-1,count
- mov carry1=r0
- mov carry2=r0
- brp.loop.imp 1f,2f
- ;;
- mov ar.ec=PIPE_DEPTH
- mov ar.lc=count // set lc
- mov pr.rot=1<<16
- // result1[0] must be initialized in advance.
- mov result2[0]=r0
- ;;
- .align 32
-1:
-(ELD_1) cmp.ltu pC1[0],p0=result1[LOAD_LATENCY],word1[LOAD_LATENCY+1]
-(pC1[1])adds carry1=1,carry1
-(ELD_1) cmp.ltu pC2[0],p0=result2[LOAD_LATENCY],word2[LOAD_LATENCY+1]
-(pC2[1])adds carry2=1,carry2
-(ELD) add result1[LOAD_LATENCY-1]=result1[LOAD_LATENCY],word1[LOAD_LATENCY]
-(ELD) add result2[LOAD_LATENCY-1]=result2[LOAD_LATENCY],word2[LOAD_LATENCY]
-2:
-(p[0]) ld8 word1[0]=[first1],16
-(p[0]) ld8 word2[0]=[first2],16
- br.ctop.sptk 1b
- ;;
- // Since len is a 32-bit value, carry cannot be larger than a 64-bit value.
-(pC1[1])adds carry1=1,carry1 // since we miss the last one
-(pC2[1])adds carry2=1,carry2
- ;;
- add result1[LOAD_LATENCY+1]=result1[LOAD_LATENCY+1],carry1
- add result2[LOAD_LATENCY+1]=result2[LOAD_LATENCY+1],carry2
- ;;
- cmp.ltu p6,p0=result1[LOAD_LATENCY+1],carry1
- cmp.ltu p7,p0=result2[LOAD_LATENCY+1],carry2
- ;;
-(p6) adds result1[LOAD_LATENCY+1]=1,result1[LOAD_LATENCY+1]
-(p7) adds result2[LOAD_LATENCY+1]=1,result2[LOAD_LATENCY+1]
- ;;
- add result1[0]=result1[LOAD_LATENCY+1],result2[LOAD_LATENCY+1]
- ;;
- cmp.ltu p6,p0=result1[0],result2[LOAD_LATENCY+1]
- ;;
-(p6) adds result1[0]=1,result1[0]
- ;;
-.do_csum_exit:
- //
- // now fold 64 into 16 bits taking care of carry
- // that's not very good because it has lots of sequentiality
- //
- mov tmp3=0xffff
- zxt4 tmp1=result1[0]
- shr.u tmp2=result1[0],32
- ;;
- add result1[0]=tmp1,tmp2
- ;;
- and tmp1=result1[0],tmp3
- shr.u tmp2=result1[0],16
- ;;
- add result1[0]=tmp1,tmp2
- ;;
- and tmp1=result1[0],tmp3
- shr.u tmp2=result1[0],16
- ;;
- add result1[0]=tmp1,tmp2
- ;;
- and tmp1=result1[0],tmp3
- shr.u tmp2=result1[0],16
- ;;
- add ret0=tmp1,tmp2
- mov pr=saved_pr,0xffffffffffff0000
- ;;
- // if buf was odd then swap bytes
- mov ar.pfs=saved_pfs // restore ar.ec
-(p15) mux1 ret0=ret0,@rev // reverse word
- ;;
- mov ar.lc=saved_lc
-(p15) shr.u ret0=ret0,64-16 // + shift back to position = swap bytes
- br.ret.sptk.many rp
-
-// I (Jun Nakajima) wrote an equivalent code (see below), but it was
-// not much better than the original. So keep the original there so that
-// someone else can challenge.
-//
-// shr.u word1[0]=result1[0],32
-// zxt4 result1[0]=result1[0]
-// ;;
-// add result1[0]=result1[0],word1[0]
-// ;;
-// zxt2 result2[0]=result1[0]
-// extr.u word1[0]=result1[0],16,16
-// shr.u carry1=result1[0],32
-// ;;
-// add result2[0]=result2[0],word1[0]
-// ;;
-// add result2[0]=result2[0],carry1
-// ;;
-// extr.u ret0=result2[0],16,16
-// ;;
-// add ret0=ret0,result2[0]
-// ;;
-// zxt2 ret0=ret0
-// mov ar.pfs=saved_pfs // restore ar.ec
-// mov pr=saved_pr,0xffffffffffff0000
-// ;;
-// // if buf was odd then swap bytes
-// mov ar.lc=saved_lc
-//(p15) mux1 ret0=ret0,@rev // reverse word
-// ;;
-//(p15) shr.u ret0=ret0,64-16 // + shift back to position = swap bytes
-// br.ret.sptk.many rp
-
-END(do_csum)
diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S
deleted file mode 100644
index f8e795fe45cb..000000000000
--- a/arch/ia64/lib/flush.S
+++ /dev/null
@@ -1,119 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Cache flushing routines.
- *
- * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 05/28/05 Zoltan Menyhart Dynamic stride size
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
- /*
- * flush_icache_range(start,end)
- *
- * Make i-cache(s) coherent with d-caches.
- *
- * Must deal with range from start to end-1 but nothing else (need to
- * be careful not to touch addresses that may be unmapped).
- *
- * Note: "in0" and "in1" are preserved for debugging purposes.
- */
- .section .kprobes.text,"ax"
-GLOBAL_ENTRY(flush_icache_range)
-
- .prologue
- alloc r2=ar.pfs,2,0,0,0
- movl r3=ia64_i_cache_stride_shift
- mov r21=1
- ;;
- ld8 r20=[r3] // r20: stride shift
- sub r22=in1,r0,1 // last byte address
- ;;
- shr.u r23=in0,r20 // start / (stride size)
- shr.u r22=r22,r20 // (last byte address) / (stride size)
- shl r21=r21,r20 // r21: stride size of the i-cache(s)
- ;;
- sub r8=r22,r23 // number of strides - 1
- shl r24=r23,r20 // r24: addresses for "fc.i" =
- // "start" rounded down to stride boundary
- .save ar.lc,r3
- mov r3=ar.lc // save ar.lc
- ;;
-
- .body
- mov ar.lc=r8
- ;;
- /*
- * 32 byte aligned loop, even number of (actually 2) bundles
- */
-.Loop: fc.i r24 // issuable on M0 only
- add r24=r21,r24 // we flush "stride size" bytes per iteration
- nop.i 0
- br.cloop.sptk.few .Loop
- ;;
- sync.i
- ;;
- srlz.i
- ;;
- mov ar.lc=r3 // restore ar.lc
- br.ret.sptk.many rp
-END(flush_icache_range)
-EXPORT_SYMBOL_GPL(flush_icache_range)
-
- /*
- * clflush_cache_range(start,size)
- *
- * Flush cache lines from start to start+size-1.
- *
- * Must deal with range from start to start+size-1 but nothing else
- * (need to be careful not to touch addresses that may be
- * unmapped).
- *
- * Note: "in0" and "in1" are preserved for debugging purposes.
- */
- .section .kprobes.text,"ax"
-GLOBAL_ENTRY(clflush_cache_range)
-
- .prologue
- alloc r2=ar.pfs,2,0,0,0
- movl r3=ia64_cache_stride_shift
- mov r21=1
- add r22=in1,in0
- ;;
- ld8 r20=[r3] // r20: stride shift
- sub r22=r22,r0,1 // last byte address
- ;;
- shr.u r23=in0,r20 // start / (stride size)
- shr.u r22=r22,r20 // (last byte address) / (stride size)
- shl r21=r21,r20 // r21: stride size of the i-cache(s)
- ;;
- sub r8=r22,r23 // number of strides - 1
- shl r24=r23,r20 // r24: addresses for "fc" =
- // "start" rounded down to stride
- // boundary
- .save ar.lc,r3
- mov r3=ar.lc // save ar.lc
- ;;
-
- .body
- mov ar.lc=r8
- ;;
- /*
- * 32 byte aligned loop, even number of (actually 2) bundles
- */
-.Loop_fc:
- fc r24 // issuable on M0 only
- add r24=r21,r24 // we flush "stride size" bytes per iteration
- nop.i 0
- br.cloop.sptk.few .Loop_fc
- ;;
- sync.i
- ;;
- srlz.i
- ;;
- mov ar.lc=r3 // restore ar.lc
- br.ret.sptk.many rp
-END(clflush_cache_range)
diff --git a/arch/ia64/lib/idiv32.S b/arch/ia64/lib/idiv32.S
deleted file mode 100644
index 83586fbc51ff..000000000000
--- a/arch/ia64/lib/idiv32.S
+++ /dev/null
@@ -1,86 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2000 Hewlett-Packard Co
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 32-bit integer division.
- *
- * This code is based on the application note entitled "Divide, Square Root
- * and Remainder Algorithms for the IA-64 Architecture". This document
- * is available as Intel document number 248725-002 or via the web at
- * http://developer.intel.com/software/opensource/numerics/
- *
- * For more details on the theory behind these algorithms, see "IA-64
- * and Elementary Functions" by Peter Markstein; HP Professional Books
- * (http://www.goodreads.com/book/show/2019887.Ia_64_and_Elementary_Functions)
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-#ifdef MODULO
-# define OP mod
-#else
-# define OP div
-#endif
-
-#ifdef UNSIGNED
-# define SGN u
-# define EXTEND zxt4
-# define INT_TO_FP(a,b) fcvt.xuf.s1 a=b
-# define FP_TO_INT(a,b) fcvt.fxu.trunc.s1 a=b
-#else
-# define SGN
-# define EXTEND sxt4
-# define INT_TO_FP(a,b) fcvt.xf a=b
-# define FP_TO_INT(a,b) fcvt.fx.trunc.s1 a=b
-#endif
-
-#define PASTE1(a,b) a##b
-#define PASTE(a,b) PASTE1(a,b)
-#define NAME PASTE(PASTE(__,SGN),PASTE(OP,si3))
-
-GLOBAL_ENTRY(NAME)
- .regstk 2,0,0,0
- // Transfer inputs to FP registers.
- mov r2 = 0xffdd // r2 = -34 + 65535 (fp reg format bias)
- EXTEND in0 = in0 // in0 = a
- EXTEND in1 = in1 // in1 = b
- ;;
- setf.sig f8 = in0
- setf.sig f9 = in1
-#ifdef MODULO
- sub in1 = r0, in1 // in1 = -b
-#endif
- ;;
- // Convert the inputs to FP, to avoid FP software-assist faults.
- INT_TO_FP(f8, f8)
- INT_TO_FP(f9, f9)
- ;;
- setf.exp f7 = r2 // f7 = 2^-34
- frcpa.s1 f6, p6 = f8, f9 // y0 = frcpa(b)
- ;;
-(p6) fmpy.s1 f8 = f8, f6 // q0 = a*y0
-(p6) fnma.s1 f6 = f9, f6, f1 // e0 = -b*y0 + 1
- ;;
-#ifdef MODULO
- setf.sig f9 = in1 // f9 = -b
-#endif
-(p6) fma.s1 f8 = f6, f8, f8 // q1 = e0*q0 + q0
-(p6) fma.s1 f6 = f6, f6, f7 // e1 = e0*e0 + 2^-34
- ;;
-#ifdef MODULO
- setf.sig f7 = in0
-#endif
-(p6) fma.s1 f6 = f6, f8, f8 // q2 = e1*q1 + q1
- ;;
- FP_TO_INT(f6, f6) // q = trunc(q2)
- ;;
-#ifdef MODULO
- xma.l f6 = f6, f9, f7 // r = q*(-b) + a
- ;;
-#endif
- getf.sig r8 = f6 // transfer result to result register
- br.ret.sptk.many rp
-END(NAME)
-EXPORT_SYMBOL(NAME)
diff --git a/arch/ia64/lib/idiv64.S b/arch/ia64/lib/idiv64.S
deleted file mode 100644
index 5c9113691f72..000000000000
--- a/arch/ia64/lib/idiv64.S
+++ /dev/null
@@ -1,83 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 64-bit integer division.
- *
- * This code is based on the application note entitled "Divide, Square Root
- * and Remainder Algorithms for the IA-64 Architecture". This document
- * is available as Intel document number 248725-002 or via the web at
- * http://developer.intel.com/software/opensource/numerics/
- *
- * For more details on the theory behind these algorithms, see "IA-64
- * and Elementary Functions" by Peter Markstein; HP Professional Books
- * (http://www.goodreads.com/book/show/2019887.Ia_64_and_Elementary_Functions)
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-#ifdef MODULO
-# define OP mod
-#else
-# define OP div
-#endif
-
-#ifdef UNSIGNED
-# define SGN u
-# define INT_TO_FP(a,b) fcvt.xuf.s1 a=b
-# define FP_TO_INT(a,b) fcvt.fxu.trunc.s1 a=b
-#else
-# define SGN
-# define INT_TO_FP(a,b) fcvt.xf a=b
-# define FP_TO_INT(a,b) fcvt.fx.trunc.s1 a=b
-#endif
-
-#define PASTE1(a,b) a##b
-#define PASTE(a,b) PASTE1(a,b)
-#define NAME PASTE(PASTE(__,SGN),PASTE(OP,di3))
-
-GLOBAL_ENTRY(NAME)
- .regstk 2,0,0,0
- // Transfer inputs to FP registers.
- setf.sig f8 = in0
- setf.sig f9 = in1
- ;;
- // Convert the inputs to FP, to avoid FP software-assist faults.
- INT_TO_FP(f8, f8)
- INT_TO_FP(f9, f9)
- ;;
- frcpa.s1 f11, p6 = f8, f9 // y0 = frcpa(b)
- ;;
-(p6) fmpy.s1 f7 = f8, f11 // q0 = a*y0
-(p6) fnma.s1 f6 = f9, f11, f1 // e0 = -b*y0 + 1
- ;;
-(p6) fma.s1 f10 = f7, f6, f7 // q1 = q0*e0 + q0
-(p6) fmpy.s1 f7 = f6, f6 // e1 = e0*e0
- ;;
-#ifdef MODULO
- sub in1 = r0, in1 // in1 = -b
-#endif
-(p6) fma.s1 f10 = f10, f7, f10 // q2 = q1*e1 + q1
-(p6) fma.s1 f6 = f11, f6, f11 // y1 = y0*e0 + y0
- ;;
-(p6) fma.s1 f6 = f6, f7, f6 // y2 = y1*e1 + y1
-(p6) fnma.s1 f7 = f9, f10, f8 // r = -b*q2 + a
- ;;
-#ifdef MODULO
- setf.sig f8 = in0 // f8 = a
- setf.sig f9 = in1 // f9 = -b
-#endif
-(p6) fma.s1 f11 = f7, f6, f10 // q3 = r*y2 + q2
- ;;
- FP_TO_INT(f11, f11) // q = trunc(q3)
- ;;
-#ifdef MODULO
- xma.l f11 = f11, f9, f8 // r = q*(-b) + a
- ;;
-#endif
- getf.sig r8 = f11 // transfer result to result register
- br.ret.sptk.many rp
-END(NAME)
-EXPORT_SYMBOL(NAME)
diff --git a/arch/ia64/lib/io.c b/arch/ia64/lib/io.c
deleted file mode 100644
index c3e02462ed16..000000000000
--- a/arch/ia64/lib/io.c
+++ /dev/null
@@ -1,51 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/module.h>
-#include <linux/types.h>
-
-#include <asm/io.h>
-
-/*
- * Copy data from IO memory space to "real" memory space.
- * This needs to be optimized.
- */
-void memcpy_fromio(void *to, const volatile void __iomem *from, long count)
-{
- char *dst = to;
-
- while (count) {
- count--;
- *dst++ = readb(from++);
- }
-}
-EXPORT_SYMBOL(memcpy_fromio);
-
-/*
- * Copy data from "real" memory space to IO memory space.
- * This needs to be optimized.
- */
-void memcpy_toio(volatile void __iomem *to, const void *from, long count)
-{
- const char *src = from;
-
- while (count) {
- count--;
- writeb(*src++, to++);
- }
-}
-EXPORT_SYMBOL(memcpy_toio);
-
-/*
- * "memset" on IO memory space.
- * This needs to be optimized.
- */
-void memset_io(volatile void __iomem *dst, int c, long count)
-{
- unsigned char ch = (char)(c & 0xff);
-
- while (count) {
- count--;
- writeb(ch, dst);
- dst++;
- }
-}
-EXPORT_SYMBOL(memset_io);
diff --git a/arch/ia64/lib/ip_fast_csum.S b/arch/ia64/lib/ip_fast_csum.S
deleted file mode 100644
index fcc0b812ce2e..000000000000
--- a/arch/ia64/lib/ip_fast_csum.S
+++ /dev/null
@@ -1,148 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Optmized version of the ip_fast_csum() function
- * Used for calculating IP header checksum
- *
- * Return: 16bit checksum, complemented
- *
- * Inputs:
- * in0: address of buffer to checksum (char *)
- * in1: length of the buffer (int)
- *
- * Copyright (C) 2002, 2006 Intel Corp.
- * Copyright (C) 2002, 2006 Ken Chen <kenneth.w.chen@intel.com>
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-/*
- * Since we know that most likely this function is called with buf aligned
- * on 4-byte boundary and 20 bytes in length, we can execution rather quickly
- * versus calling generic version of do_csum, which has lots of overhead in
- * handling various alignments and sizes. However, due to lack of constrains
- * put on the function input argument, cases with alignment not on 4-byte or
- * size not equal to 20 bytes will be handled by the generic do_csum function.
- */
-
-#define in0 r32
-#define in1 r33
-#define in2 r34
-#define in3 r35
-#define in4 r36
-#define ret0 r8
-
-GLOBAL_ENTRY(ip_fast_csum)
- .prologue
- .body
- cmp.ne p6,p7=5,in1 // size other than 20 byte?
- and r14=3,in0 // is it aligned on 4-byte?
- add r15=4,in0 // second source pointer
- ;;
- cmp.ne.or.andcm p6,p7=r14,r0
- ;;
-(p7) ld4 r20=[in0],8
-(p7) ld4 r21=[r15],8
-(p6) br.spnt .generic
- ;;
- ld4 r22=[in0],8
- ld4 r23=[r15],8
- ;;
- ld4 r24=[in0]
- add r20=r20,r21
- add r22=r22,r23
- ;;
- add r20=r20,r22
- ;;
- add r20=r20,r24
- ;;
- shr.u ret0=r20,16 // now need to add the carry
- zxt2 r20=r20
- ;;
- add r20=ret0,r20
- ;;
- shr.u ret0=r20,16 // add carry again
- zxt2 r20=r20
- ;;
- add r20=ret0,r20
- ;;
- shr.u ret0=r20,16
- zxt2 r20=r20
- ;;
- add r20=ret0,r20
- mov r9=0xffff
- ;;
- andcm ret0=r9,r20
- .restore sp // reset frame state
- br.ret.sptk.many b0
- ;;
-
-.generic:
- .prologue
- .save ar.pfs, r35
- alloc r35=ar.pfs,2,2,2,0
- .save rp, r34
- mov r34=b0
- .body
- dep.z out1=in1,2,30
- mov out0=in0
- ;;
- br.call.sptk.many b0=do_csum
- ;;
- andcm ret0=-1,ret0
- mov ar.pfs=r35
- mov b0=r34
- br.ret.sptk.many b0
-END(ip_fast_csum)
-EXPORT_SYMBOL(ip_fast_csum)
-
-GLOBAL_ENTRY(csum_ipv6_magic)
- ld4 r20=[in0],4
- ld4 r21=[in1],4
- zxt4 in2=in2
- ;;
- ld4 r22=[in0],4
- ld4 r23=[in1],4
- dep r15=in3,in2,32,16
- ;;
- ld4 r24=[in0],4
- ld4 r25=[in1],4
- mux1 r15=r15,@rev
- add r16=r20,r21
- add r17=r22,r23
- zxt4 in4=in4
- ;;
- ld4 r26=[in0],4
- ld4 r27=[in1],4
- shr.u r15=r15,16
- add r18=r24,r25
- add r8=r16,r17
- ;;
- add r19=r26,r27
- add r8=r8,r18
- ;;
- add r8=r8,r19
- add r15=r15,in4
- ;;
- add r8=r8,r15
- ;;
- shr.u r10=r8,32 // now fold sum into short
- zxt4 r11=r8
- ;;
- add r8=r10,r11
- ;;
- shr.u r10=r8,16 // yeah, keep it rolling
- zxt2 r11=r8
- ;;
- add r8=r10,r11
- ;;
- shr.u r10=r8,16 // three times lucky
- zxt2 r11=r8
- ;;
- add r8=r10,r11
- mov r9=0xffff
- ;;
- andcm r8=r9,r8
- br.ret.sptk.many b0
-END(csum_ipv6_magic)
-EXPORT_SYMBOL(csum_ipv6_magic)
diff --git a/arch/ia64/lib/memcpy.S b/arch/ia64/lib/memcpy.S
deleted file mode 100644
index 35c9069a8345..000000000000
--- a/arch/ia64/lib/memcpy.S
+++ /dev/null
@@ -1,304 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *
- * Optimized version of the standard memcpy() function
- *
- * Inputs:
- * in0: destination address
- * in1: source address
- * in2: number of bytes to copy
- * Output:
- * no return value
- *
- * Copyright (C) 2000-2001 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-GLOBAL_ENTRY(memcpy)
-
-# define MEM_LAT 21 /* latency to memory */
-
-# define dst r2
-# define src r3
-# define retval r8
-# define saved_pfs r9
-# define saved_lc r10
-# define saved_pr r11
-# define cnt r16
-# define src2 r17
-# define t0 r18
-# define t1 r19
-# define t2 r20
-# define t3 r21
-# define t4 r22
-# define src_end r23
-
-# define N (MEM_LAT + 4)
-# define Nrot ((N + 7) & ~7)
-
- /*
- * First, check if everything (src, dst, len) is a multiple of eight. If
- * so, we handle everything with no taken branches (other than the loop
- * itself) and a small icache footprint. Otherwise, we jump off to
- * the more general copy routine handling arbitrary
- * sizes/alignment etc.
- */
- .prologue
- .save ar.pfs, saved_pfs
- alloc saved_pfs=ar.pfs,3,Nrot,0,Nrot
- .save ar.lc, saved_lc
- mov saved_lc=ar.lc
- or t0=in0,in1
- ;;
-
- or t0=t0,in2
- .save pr, saved_pr
- mov saved_pr=pr
-
- .body
-
- cmp.eq p6,p0=in2,r0 // zero length?
- mov retval=in0 // return dst
-(p6) br.ret.spnt.many rp // zero length, return immediately
- ;;
-
- mov dst=in0 // copy because of rotation
- shr.u cnt=in2,3 // number of 8-byte words to copy
- mov pr.rot=1<<16
- ;;
-
- adds cnt=-1,cnt // br.ctop is repeat/until
- cmp.gtu p7,p0=16,in2 // copying less than 16 bytes?
- mov ar.ec=N
- ;;
-
- and t0=0x7,t0
- mov ar.lc=cnt
- ;;
- cmp.ne p6,p0=t0,r0
-
- mov src=in1 // copy because of rotation
-(p7) br.cond.spnt.few .memcpy_short
-(p6) br.cond.spnt.few .memcpy_long
- ;;
- nop.m 0
- ;;
- nop.m 0
- nop.i 0
- ;;
- nop.m 0
- ;;
- .rotr val[N]
- .rotp p[N]
- .align 32
-1: { .mib
-(p[0]) ld8 val[0]=[src],8
- nop.i 0
- brp.loop.imp 1b, 2f
-}
-2: { .mfb
-(p[N-1])st8 [dst]=val[N-1],8
- nop.f 0
- br.ctop.dptk.few 1b
-}
- ;;
- mov ar.lc=saved_lc
- mov pr=saved_pr,-1
- mov ar.pfs=saved_pfs
- br.ret.sptk.many rp
-
- /*
- * Small (<16 bytes) unaligned copying is done via a simple byte-at-the-time
- * copy loop. This performs relatively poorly on Itanium, but it doesn't
- * get used very often (gcc inlines small copies) and due to atomicity
- * issues, we want to avoid read-modify-write of entire words.
- */
- .align 32
-.memcpy_short:
- adds cnt=-1,in2 // br.ctop is repeat/until
- mov ar.ec=MEM_LAT
- brp.loop.imp 1f, 2f
- ;;
- mov ar.lc=cnt
- ;;
- nop.m 0
- ;;
- nop.m 0
- nop.i 0
- ;;
- nop.m 0
- ;;
- nop.m 0
- ;;
- /*
- * It is faster to put a stop bit in the loop here because it makes
- * the pipeline shorter (and latency is what matters on short copies).
- */
- .align 32
-1: { .mib
-(p[0]) ld1 val[0]=[src],1
- nop.i 0
- brp.loop.imp 1b, 2f
-} ;;
-2: { .mfb
-(p[MEM_LAT-1])st1 [dst]=val[MEM_LAT-1],1
- nop.f 0
- br.ctop.dptk.few 1b
-} ;;
- mov ar.lc=saved_lc
- mov pr=saved_pr,-1
- mov ar.pfs=saved_pfs
- br.ret.sptk.many rp
-
- /*
- * Large (>= 16 bytes) copying is done in a fancy way. Latency isn't
- * an overriding concern here, but throughput is. We first do
- * sub-word copying until the destination is aligned, then we check
- * if the source is also aligned. If so, we do a simple load/store-loop
- * until there are less than 8 bytes left over and then we do the tail,
- * by storing the last few bytes using sub-word copying. If the source
- * is not aligned, we branch off to the non-congruent loop.
- *
- * stage: op:
- * 0 ld
- * :
- * MEM_LAT+3 shrp
- * MEM_LAT+4 st
- *
- * On Itanium, the pipeline itself runs without stalls. However, br.ctop
- * seems to introduce an unavoidable bubble in the pipeline so the overall
- * latency is 2 cycles/iteration. This gives us a _copy_ throughput
- * of 4 byte/cycle. Still not bad.
- */
-# undef N
-# undef Nrot
-# define N (MEM_LAT + 5) /* number of stages */
-# define Nrot ((N+1 + 2 + 7) & ~7) /* number of rotating regs */
-
-#define LOG_LOOP_SIZE 6
-
-.memcpy_long:
- alloc t3=ar.pfs,3,Nrot,0,Nrot // resize register frame
- and t0=-8,src // t0 = src & ~7
- and t2=7,src // t2 = src & 7
- ;;
- ld8 t0=[t0] // t0 = 1st source word
- adds src2=7,src // src2 = (src + 7)
- sub t4=r0,dst // t4 = -dst
- ;;
- and src2=-8,src2 // src2 = (src + 7) & ~7
- shl t2=t2,3 // t2 = 8*(src & 7)
- shl t4=t4,3 // t4 = 8*(dst & 7)
- ;;
- ld8 t1=[src2] // t1 = 1st source word if src is 8-byte aligned, 2nd otherwise
- sub t3=64,t2 // t3 = 64-8*(src & 7)
- shr.u t0=t0,t2
- ;;
- add src_end=src,in2
- shl t1=t1,t3
- mov pr=t4,0x38 // (p5,p4,p3)=(dst & 7)
- ;;
- or t0=t0,t1
- mov cnt=r0
- adds src_end=-1,src_end
- ;;
-(p3) st1 [dst]=t0,1
-(p3) shr.u t0=t0,8
-(p3) adds cnt=1,cnt
- ;;
-(p4) st2 [dst]=t0,2
-(p4) shr.u t0=t0,16
-(p4) adds cnt=2,cnt
- ;;
-(p5) st4 [dst]=t0,4
-(p5) adds cnt=4,cnt
- and src_end=-8,src_end // src_end = last word of source buffer
- ;;
-
- // At this point, dst is aligned to 8 bytes and there at least 16-7=9 bytes left to copy:
-
-1:{ add src=cnt,src // make src point to remainder of source buffer
- sub cnt=in2,cnt // cnt = number of bytes left to copy
- mov t4=ip
- } ;;
- and src2=-8,src // align source pointer
- adds t4=.memcpy_loops-1b,t4
- mov ar.ec=N
-
- and t0=7,src // t0 = src & 7
- shr.u t2=cnt,3 // t2 = number of 8-byte words left to copy
- shl cnt=cnt,3 // move bits 0-2 to 3-5
- ;;
-
- .rotr val[N+1], w[2]
- .rotp p[N]
-
- cmp.ne p6,p0=t0,r0 // is src aligned, too?
- shl t0=t0,LOG_LOOP_SIZE // t0 = 8*(src & 7)
- adds t2=-1,t2 // br.ctop is repeat/until
- ;;
- add t4=t0,t4
- mov pr=cnt,0x38 // set (p5,p4,p3) to # of bytes last-word bytes to copy
- mov ar.lc=t2
- ;;
- nop.m 0
- ;;
- nop.m 0
- nop.i 0
- ;;
- nop.m 0
- ;;
-(p6) ld8 val[1]=[src2],8 // prime the pump...
- mov b6=t4
- br.sptk.few b6
- ;;
-
-.memcpy_tail:
- // At this point, (p5,p4,p3) are set to the number of bytes left to copy (which is
- // less than 8) and t0 contains the last few bytes of the src buffer:
-(p5) st4 [dst]=t0,4
-(p5) shr.u t0=t0,32
- mov ar.lc=saved_lc
- ;;
-(p4) st2 [dst]=t0,2
-(p4) shr.u t0=t0,16
- mov ar.pfs=saved_pfs
- ;;
-(p3) st1 [dst]=t0
- mov pr=saved_pr,-1
- br.ret.sptk.many rp
-
-///////////////////////////////////////////////////////
- .align 64
-
-#define COPY(shift,index) \
- 1: { .mib \
- (p[0]) ld8 val[0]=[src2],8; \
- (p[MEM_LAT+3]) shrp w[0]=val[MEM_LAT+3],val[MEM_LAT+4-index],shift; \
- brp.loop.imp 1b, 2f \
- }; \
- 2: { .mfb \
- (p[MEM_LAT+4]) st8 [dst]=w[1],8; \
- nop.f 0; \
- br.ctop.dptk.few 1b; \
- }; \
- ;; \
- ld8 val[N-1]=[src_end]; /* load last word (may be same as val[N]) */ \
- ;; \
- shrp t0=val[N-1],val[N-index],shift; \
- br .memcpy_tail
-.memcpy_loops:
- COPY(0, 1) /* no point special casing this---it doesn't go any faster without shrp */
- COPY(8, 0)
- COPY(16, 0)
- COPY(24, 0)
- COPY(32, 0)
- COPY(40, 0)
- COPY(48, 0)
- COPY(56, 0)
-
-END(memcpy)
-EXPORT_SYMBOL(memcpy)
diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
deleted file mode 100644
index c0d4362217ae..000000000000
--- a/arch/ia64/lib/memcpy_mck.S
+++ /dev/null
@@ -1,659 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Itanium 2-optimized version of memcpy and copy_user function
- *
- * Inputs:
- * in0: destination address
- * in1: source address
- * in2: number of bytes to copy
- * Output:
- * for memcpy: return dest
- * for copy_user: return 0 if success,
- * or number of byte NOT copied if error occurred.
- *
- * Copyright (C) 2002 Intel Corp.
- * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
- */
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-#include <asm/page.h>
-
-#define EK(y...) EX(y)
-
-/* McKinley specific optimization */
-
-#define retval r8
-#define saved_pfs r31
-#define saved_lc r10
-#define saved_pr r11
-#define saved_in0 r14
-#define saved_in1 r15
-#define saved_in2 r16
-
-#define src0 r2
-#define src1 r3
-#define dst0 r17
-#define dst1 r18
-#define cnt r9
-
-/* r19-r30 are temp for each code section */
-#define PREFETCH_DIST 8
-#define src_pre_mem r19
-#define dst_pre_mem r20
-#define src_pre_l2 r21
-#define dst_pre_l2 r22
-#define t1 r23
-#define t2 r24
-#define t3 r25
-#define t4 r26
-#define t5 t1 // alias!
-#define t6 t2 // alias!
-#define t7 t3 // alias!
-#define n8 r27
-#define t9 t5 // alias!
-#define t10 t4 // alias!
-#define t11 t7 // alias!
-#define t12 t6 // alias!
-#define t14 t10 // alias!
-#define t13 r28
-#define t15 r29
-#define tmp r30
-
-/* defines for long_copy block */
-#define A 0
-#define B (PREFETCH_DIST)
-#define C (B + PREFETCH_DIST)
-#define D (C + 1)
-#define N (D + 1)
-#define Nrot ((N + 7) & ~7)
-
-/* alias */
-#define in0 r32
-#define in1 r33
-#define in2 r34
-
-GLOBAL_ENTRY(memcpy)
- and r28=0x7,in0
- and r29=0x7,in1
- mov f6=f0
- mov retval=in0
- br.cond.sptk .common_code
- ;;
-END(memcpy)
-EXPORT_SYMBOL(memcpy)
-GLOBAL_ENTRY(__copy_user)
- .prologue
-// check dest alignment
- and r28=0x7,in0
- and r29=0x7,in1
- mov f6=f1
- mov saved_in0=in0 // save dest pointer
- mov saved_in1=in1 // save src pointer
- mov retval=r0 // initialize return value
- ;;
-.common_code:
- cmp.gt p15,p0=8,in2 // check for small size
- cmp.ne p13,p0=0,r28 // check dest alignment
- cmp.ne p14,p0=0,r29 // check src alignment
- add src0=0,in1
- sub r30=8,r28 // for .align_dest
- mov saved_in2=in2 // save len
- ;;
- add dst0=0,in0
- add dst1=1,in0 // dest odd index
- cmp.le p6,p0 = 1,r30 // for .align_dest
-(p15) br.cond.dpnt .memcpy_short
-(p13) br.cond.dpnt .align_dest
-(p14) br.cond.dpnt .unaligned_src
- ;;
-
-// both dest and src are aligned on 8-byte boundary
-.aligned_src:
- .save ar.pfs, saved_pfs
- alloc saved_pfs=ar.pfs,3,Nrot-3,0,Nrot
- .save pr, saved_pr
- mov saved_pr=pr
-
- shr.u cnt=in2,7 // this much cache line
- ;;
- cmp.lt p6,p0=2*PREFETCH_DIST,cnt
- cmp.lt p7,p8=1,cnt
- .save ar.lc, saved_lc
- mov saved_lc=ar.lc
- .body
- add cnt=-1,cnt
- add src_pre_mem=0,in1 // prefetch src pointer
- add dst_pre_mem=0,in0 // prefetch dest pointer
- ;;
-(p7) mov ar.lc=cnt // prefetch count
-(p8) mov ar.lc=r0
-(p6) br.cond.dpnt .long_copy
- ;;
-
-.prefetch:
- lfetch.fault [src_pre_mem], 128
- lfetch.fault.excl [dst_pre_mem], 128
- br.cloop.dptk.few .prefetch
- ;;
-
-.medium_copy:
- and tmp=31,in2 // copy length after iteration
- shr.u r29=in2,5 // number of 32-byte iteration
- add dst1=8,dst0 // 2nd dest pointer
- ;;
- add cnt=-1,r29 // ctop iteration adjustment
- cmp.eq p10,p0=r29,r0 // do we really need to loop?
- add src1=8,src0 // 2nd src pointer
- cmp.le p6,p0=8,tmp
- ;;
- cmp.le p7,p0=16,tmp
- mov ar.lc=cnt // loop setup
- cmp.eq p16,p17 = r0,r0
- mov ar.ec=2
-(p10) br.dpnt.few .aligned_src_tail
- ;;
- TEXT_ALIGN(32)
-1:
-EX(.ex_handler, (p16) ld8 r34=[src0],16)
-EK(.ex_handler, (p16) ld8 r38=[src1],16)
-EX(.ex_handler, (p17) st8 [dst0]=r33,16)
-EK(.ex_handler, (p17) st8 [dst1]=r37,16)
- ;;
-EX(.ex_handler, (p16) ld8 r32=[src0],16)
-EK(.ex_handler, (p16) ld8 r36=[src1],16)
-EX(.ex_handler, (p16) st8 [dst0]=r34,16)
-EK(.ex_handler, (p16) st8 [dst1]=r38,16)
- br.ctop.dptk.few 1b
- ;;
-
-.aligned_src_tail:
-EX(.ex_handler, (p6) ld8 t1=[src0])
- mov ar.lc=saved_lc
- mov ar.pfs=saved_pfs
-EX(.ex_hndlr_s, (p7) ld8 t2=[src1],8)
- cmp.le p8,p0=24,tmp
- and r21=-8,tmp
- ;;
-EX(.ex_hndlr_s, (p8) ld8 t3=[src1])
-EX(.ex_handler, (p6) st8 [dst0]=t1) // store byte 1
- and in2=7,tmp // remaining length
-EX(.ex_hndlr_d, (p7) st8 [dst1]=t2,8) // store byte 2
- add src0=src0,r21 // setting up src pointer
- add dst0=dst0,r21 // setting up dest pointer
- ;;
-EX(.ex_handler, (p8) st8 [dst1]=t3) // store byte 3
- mov pr=saved_pr,-1
- br.dptk.many .memcpy_short
- ;;
-
-/* code taken from copy_page_mck */
-.long_copy:
- .rotr v[2*PREFETCH_DIST]
- .rotp p[N]
-
- mov src_pre_mem = src0
- mov pr.rot = 0x10000
- mov ar.ec = 1 // special unrolled loop
-
- mov dst_pre_mem = dst0
-
- add src_pre_l2 = 8*8, src0
- add dst_pre_l2 = 8*8, dst0
- ;;
- add src0 = 8, src_pre_mem // first t1 src
- mov ar.lc = 2*PREFETCH_DIST - 1
- shr.u cnt=in2,7 // number of lines
- add src1 = 3*8, src_pre_mem // first t3 src
- add dst0 = 8, dst_pre_mem // first t1 dst
- add dst1 = 3*8, dst_pre_mem // first t3 dst
- ;;
- and tmp=127,in2 // remaining bytes after this block
- add cnt = -(2*PREFETCH_DIST) - 1, cnt
- // same as .line_copy loop, but with all predicated-off instructions removed:
-.prefetch_loop:
-EX(.ex_hndlr_lcpy_1, (p[A]) ld8 v[A] = [src_pre_mem], 128) // M0
-EK(.ex_hndlr_lcpy_1, (p[B]) st8 [dst_pre_mem] = v[B], 128) // M2
- br.ctop.sptk .prefetch_loop
- ;;
- cmp.eq p16, p0 = r0, r0 // reset p16 to 1
- mov ar.lc = cnt
- mov ar.ec = N // # of stages in pipeline
- ;;
-.line_copy:
-EX(.ex_handler, (p[D]) ld8 t2 = [src0], 3*8) // M0
-EK(.ex_handler, (p[D]) ld8 t4 = [src1], 3*8) // M1
-EX(.ex_handler_lcpy, (p[B]) st8 [dst_pre_mem] = v[B], 128) // M2 prefetch dst from memory
-EK(.ex_handler_lcpy, (p[D]) st8 [dst_pre_l2] = n8, 128) // M3 prefetch dst from L2
- ;;
-EX(.ex_handler_lcpy, (p[A]) ld8 v[A] = [src_pre_mem], 128) // M0 prefetch src from memory
-EK(.ex_handler_lcpy, (p[C]) ld8 n8 = [src_pre_l2], 128) // M1 prefetch src from L2
-EX(.ex_handler, (p[D]) st8 [dst0] = t1, 8) // M2
-EK(.ex_handler, (p[D]) st8 [dst1] = t3, 8) // M3
- ;;
-EX(.ex_handler, (p[D]) ld8 t5 = [src0], 8)
-EK(.ex_handler, (p[D]) ld8 t7 = [src1], 3*8)
-EX(.ex_handler, (p[D]) st8 [dst0] = t2, 3*8)
-EK(.ex_handler, (p[D]) st8 [dst1] = t4, 3*8)
- ;;
-EX(.ex_handler, (p[D]) ld8 t6 = [src0], 3*8)
-EK(.ex_handler, (p[D]) ld8 t10 = [src1], 8)
-EX(.ex_handler, (p[D]) st8 [dst0] = t5, 8)
-EK(.ex_handler, (p[D]) st8 [dst1] = t7, 3*8)
- ;;
-EX(.ex_handler, (p[D]) ld8 t9 = [src0], 3*8)
-EK(.ex_handler, (p[D]) ld8 t11 = [src1], 3*8)
-EX(.ex_handler, (p[D]) st8 [dst0] = t6, 3*8)
-EK(.ex_handler, (p[D]) st8 [dst1] = t10, 8)
- ;;
-EX(.ex_handler, (p[D]) ld8 t12 = [src0], 8)
-EK(.ex_handler, (p[D]) ld8 t14 = [src1], 8)
-EX(.ex_handler, (p[D]) st8 [dst0] = t9, 3*8)
-EK(.ex_handler, (p[D]) st8 [dst1] = t11, 3*8)
- ;;
-EX(.ex_handler, (p[D]) ld8 t13 = [src0], 4*8)
-EK(.ex_handler, (p[D]) ld8 t15 = [src1], 4*8)
-EX(.ex_handler, (p[D]) st8 [dst0] = t12, 8)
-EK(.ex_handler, (p[D]) st8 [dst1] = t14, 8)
- ;;
-EX(.ex_handler, (p[C]) ld8 t1 = [src0], 8)
-EK(.ex_handler, (p[C]) ld8 t3 = [src1], 8)
-EX(.ex_handler, (p[D]) st8 [dst0] = t13, 4*8)
-EK(.ex_handler, (p[D]) st8 [dst1] = t15, 4*8)
- br.ctop.sptk .line_copy
- ;;
-
- add dst0=-8,dst0
- add src0=-8,src0
- mov in2=tmp
- .restore sp
- br.sptk.many .medium_copy
- ;;
-
-#define BLOCK_SIZE 128*32
-#define blocksize r23
-#define curlen r24
-
-// dest is on 8-byte boundary, src is not. We need to do
-// ld8-ld8, shrp, then st8. Max 8 byte copy per cycle.
-.unaligned_src:
- .prologue
- .save ar.pfs, saved_pfs
- alloc saved_pfs=ar.pfs,3,5,0,8
- .save ar.lc, saved_lc
- mov saved_lc=ar.lc
- .save pr, saved_pr
- mov saved_pr=pr
- .body
-.4k_block:
- mov saved_in0=dst0 // need to save all input arguments
- mov saved_in2=in2
- mov blocksize=BLOCK_SIZE
- ;;
- cmp.lt p6,p7=blocksize,in2
- mov saved_in1=src0
- ;;
-(p6) mov in2=blocksize
- ;;
- shr.u r21=in2,7 // this much cache line
- shr.u r22=in2,4 // number of 16-byte iteration
- and curlen=15,in2 // copy length after iteration
- and r30=7,src0 // source alignment
- ;;
- cmp.lt p7,p8=1,r21
- add cnt=-1,r21
- ;;
-
- add src_pre_mem=0,src0 // prefetch src pointer
- add dst_pre_mem=0,dst0 // prefetch dest pointer
- and src0=-8,src0 // 1st src pointer
-(p7) mov ar.lc = cnt
-(p8) mov ar.lc = r0
- ;;
- TEXT_ALIGN(32)
-1: lfetch.fault [src_pre_mem], 128
- lfetch.fault.excl [dst_pre_mem], 128
- br.cloop.dptk.few 1b
- ;;
-
- shladd dst1=r22,3,dst0 // 2nd dest pointer
- shladd src1=r22,3,src0 // 2nd src pointer
- cmp.eq p8,p9=r22,r0 // do we really need to loop?
- cmp.le p6,p7=8,curlen; // have at least 8 byte remaining?
- add cnt=-1,r22 // ctop iteration adjustment
- ;;
-EX(.ex_handler, (p9) ld8 r33=[src0],8) // loop primer
-EK(.ex_handler, (p9) ld8 r37=[src1],8)
-(p8) br.dpnt.few .noloop
- ;;
-
-// The jump address is calculated based on src alignment. The COPYU
-// macro below need to confine its size to power of two, so an entry
-// can be caulated using shl instead of an expensive multiply. The
-// size is then hard coded by the following #define to match the
-// actual size. This make it somewhat tedious when COPYU macro gets
-// changed and this need to be adjusted to match.
-#define LOOP_SIZE 6
-1:
- mov r29=ip // jmp_table thread
- mov ar.lc=cnt
- ;;
- add r29=.jump_table - 1b - (.jmp1-.jump_table), r29
- shl r28=r30, LOOP_SIZE // jmp_table thread
- mov ar.ec=2 // loop setup
- ;;
- add r29=r29,r28 // jmp_table thread
- cmp.eq p16,p17=r0,r0
- ;;
- mov b6=r29 // jmp_table thread
- ;;
- br.cond.sptk.few b6
-
-// for 8-15 byte case
-// We will skip the loop, but need to replicate the side effect
-// that the loop produces.
-.noloop:
-EX(.ex_handler, (p6) ld8 r37=[src1],8)
- add src0=8,src0
-(p6) shl r25=r30,3
- ;;
-EX(.ex_handler, (p6) ld8 r27=[src1])
-(p6) shr.u r28=r37,r25
-(p6) sub r26=64,r25
- ;;
-(p6) shl r27=r27,r26
- ;;
-(p6) or r21=r28,r27
-
-.unaligned_src_tail:
-/* check if we have more than blocksize to copy, if so go back */
- cmp.gt p8,p0=saved_in2,blocksize
- ;;
-(p8) add dst0=saved_in0,blocksize
-(p8) add src0=saved_in1,blocksize
-(p8) sub in2=saved_in2,blocksize
-(p8) br.dpnt .4k_block
- ;;
-
-/* we have up to 15 byte to copy in the tail.
- * part of work is already done in the jump table code
- * we are at the following state.
- * src side:
- *
- * xxxxxx xx <----- r21 has xxxxxxxx already
- * -------- -------- --------
- * 0 8 16
- * ^
- * |
- * src1
- *
- * dst
- * -------- -------- --------
- * ^
- * |
- * dst1
- */
-EX(.ex_handler, (p6) st8 [dst1]=r21,8) // more than 8 byte to copy
-(p6) add curlen=-8,curlen // update length
- mov ar.pfs=saved_pfs
- ;;
- mov ar.lc=saved_lc
- mov pr=saved_pr,-1
- mov in2=curlen // remaining length
- mov dst0=dst1 // dest pointer
- add src0=src1,r30 // forward by src alignment
- ;;
-
-// 7 byte or smaller.
-.memcpy_short:
- cmp.le p8,p9 = 1,in2
- cmp.le p10,p11 = 2,in2
- cmp.le p12,p13 = 3,in2
- cmp.le p14,p15 = 4,in2
- add src1=1,src0 // second src pointer
- add dst1=1,dst0 // second dest pointer
- ;;
-
-EX(.ex_handler_short, (p8) ld1 t1=[src0],2)
-EK(.ex_handler_short, (p10) ld1 t2=[src1],2)
-(p9) br.ret.dpnt rp // 0 byte copy
- ;;
-
-EX(.ex_handler_short, (p8) st1 [dst0]=t1,2)
-EK(.ex_handler_short, (p10) st1 [dst1]=t2,2)
-(p11) br.ret.dpnt rp // 1 byte copy
-
-EX(.ex_handler_short, (p12) ld1 t3=[src0],2)
-EK(.ex_handler_short, (p14) ld1 t4=[src1],2)
-(p13) br.ret.dpnt rp // 2 byte copy
- ;;
-
- cmp.le p6,p7 = 5,in2
- cmp.le p8,p9 = 6,in2
- cmp.le p10,p11 = 7,in2
-
-EX(.ex_handler_short, (p12) st1 [dst0]=t3,2)
-EK(.ex_handler_short, (p14) st1 [dst1]=t4,2)
-(p15) br.ret.dpnt rp // 3 byte copy
- ;;
-
-EX(.ex_handler_short, (p6) ld1 t5=[src0],2)
-EK(.ex_handler_short, (p8) ld1 t6=[src1],2)
-(p7) br.ret.dpnt rp // 4 byte copy
- ;;
-
-EX(.ex_handler_short, (p6) st1 [dst0]=t5,2)
-EK(.ex_handler_short, (p8) st1 [dst1]=t6,2)
-(p9) br.ret.dptk rp // 5 byte copy
-
-EX(.ex_handler_short, (p10) ld1 t7=[src0],2)
-(p11) br.ret.dptk rp // 6 byte copy
- ;;
-
-EX(.ex_handler_short, (p10) st1 [dst0]=t7,2)
- br.ret.dptk rp // done all cases
-
-
-/* Align dest to nearest 8-byte boundary. We know we have at
- * least 7 bytes to copy, enough to crawl to 8-byte boundary.
- * Actual number of byte to crawl depend on the dest alignment.
- * 7 byte or less is taken care at .memcpy_short
-
- * src0 - source even index
- * src1 - source odd index
- * dst0 - dest even index
- * dst1 - dest odd index
- * r30 - distance to 8-byte boundary
- */
-
-.align_dest:
- add src1=1,in1 // source odd index
- cmp.le p7,p0 = 2,r30 // for .align_dest
- cmp.le p8,p0 = 3,r30 // for .align_dest
-EX(.ex_handler_short, (p6) ld1 t1=[src0],2)
- cmp.le p9,p0 = 4,r30 // for .align_dest
- cmp.le p10,p0 = 5,r30
- ;;
-EX(.ex_handler_short, (p7) ld1 t2=[src1],2)
-EK(.ex_handler_short, (p8) ld1 t3=[src0],2)
- cmp.le p11,p0 = 6,r30
-EX(.ex_handler_short, (p6) st1 [dst0] = t1,2)
- cmp.le p12,p0 = 7,r30
- ;;
-EX(.ex_handler_short, (p9) ld1 t4=[src1],2)
-EK(.ex_handler_short, (p10) ld1 t5=[src0],2)
-EX(.ex_handler_short, (p7) st1 [dst1] = t2,2)
-EK(.ex_handler_short, (p8) st1 [dst0] = t3,2)
- ;;
-EX(.ex_handler_short, (p11) ld1 t6=[src1],2)
-EK(.ex_handler_short, (p12) ld1 t7=[src0],2)
- cmp.eq p6,p7=r28,r29
-EX(.ex_handler_short, (p9) st1 [dst1] = t4,2)
-EK(.ex_handler_short, (p10) st1 [dst0] = t5,2)
- sub in2=in2,r30
- ;;
-EX(.ex_handler_short, (p11) st1 [dst1] = t6,2)
-EK(.ex_handler_short, (p12) st1 [dst0] = t7)
- add dst0=in0,r30 // setup arguments
- add src0=in1,r30
-(p6) br.cond.dptk .aligned_src
-(p7) br.cond.dpnt .unaligned_src
- ;;
-
-/* main loop body in jump table format */
-#define COPYU(shift) \
-1: \
-EX(.ex_handler, (p16) ld8 r32=[src0],8); /* 1 */ \
-EK(.ex_handler, (p16) ld8 r36=[src1],8); \
- (p17) shrp r35=r33,r34,shift;; /* 1 */ \
-EX(.ex_handler, (p6) ld8 r22=[src1]); /* common, prime for tail section */ \
- nop.m 0; \
- (p16) shrp r38=r36,r37,shift; \
-EX(.ex_handler, (p17) st8 [dst0]=r35,8); /* 1 */ \
-EK(.ex_handler, (p17) st8 [dst1]=r39,8); \
- br.ctop.dptk.few 1b;; \
- (p7) add src1=-8,src1; /* back out for <8 byte case */ \
- shrp r21=r22,r38,shift; /* speculative work */ \
- br.sptk.few .unaligned_src_tail /* branch out of jump table */ \
- ;;
- TEXT_ALIGN(32)
-.jump_table:
- COPYU(8) // unaligned cases
-.jmp1:
- COPYU(16)
- COPYU(24)
- COPYU(32)
- COPYU(40)
- COPYU(48)
- COPYU(56)
-
-#undef A
-#undef B
-#undef C
-#undef D
-
-/*
- * Due to lack of local tag support in gcc 2.x assembler, it is not clear which
- * instruction failed in the bundle. The exception algorithm is that we
- * first figure out the faulting address, then detect if there is any
- * progress made on the copy, if so, redo the copy from last known copied
- * location up to the faulting address (exclusive). In the copy_from_user
- * case, remaining byte in kernel buffer will be zeroed.
- *
- * Take copy_from_user as an example, in the code there are multiple loads
- * in a bundle and those multiple loads could span over two pages, the
- * faulting address is calculated as page_round_down(max(src0, src1)).
- * This is based on knowledge that if we can access one byte in a page, we
- * can access any byte in that page.
- *
- * predicate used in the exception handler:
- * p6-p7: direction
- * p10-p11: src faulting addr calculation
- * p12-p13: dst faulting addr calculation
- */
-
-#define A r19
-#define B r20
-#define C r21
-#define D r22
-#define F r28
-
-#define saved_retval loc0
-#define saved_rtlink loc1
-#define saved_pfs_stack loc2
-
-.ex_hndlr_s:
- add src0=8,src0
- br.sptk .ex_handler
- ;;
-.ex_hndlr_d:
- add dst0=8,dst0
- br.sptk .ex_handler
- ;;
-.ex_hndlr_lcpy_1:
- mov src1=src_pre_mem
- mov dst1=dst_pre_mem
- cmp.gtu p10,p11=src_pre_mem,saved_in1
- cmp.gtu p12,p13=dst_pre_mem,saved_in0
- ;;
-(p10) add src0=8,saved_in1
-(p11) mov src0=saved_in1
-(p12) add dst0=8,saved_in0
-(p13) mov dst0=saved_in0
- br.sptk .ex_handler
-.ex_handler_lcpy:
- // in line_copy block, the preload addresses should always ahead
- // of the other two src/dst pointers. Furthermore, src1/dst1 should
- // always ahead of src0/dst0.
- mov src1=src_pre_mem
- mov dst1=dst_pre_mem
-.ex_handler:
- mov pr=saved_pr,-1 // first restore pr, lc, and pfs
- mov ar.lc=saved_lc
- mov ar.pfs=saved_pfs
- ;;
-.ex_handler_short: // fault occurred in these sections didn't change pr, lc, pfs
- cmp.ltu p6,p7=saved_in0, saved_in1 // get the copy direction
- cmp.ltu p10,p11=src0,src1
- cmp.ltu p12,p13=dst0,dst1
- fcmp.eq p8,p0=f6,f0 // is it memcpy?
- mov tmp = dst0
- ;;
-(p11) mov src1 = src0 // pick the larger of the two
-(p13) mov dst0 = dst1 // make dst0 the smaller one
-(p13) mov dst1 = tmp // and dst1 the larger one
- ;;
-(p6) dep F = r0,dst1,0,PAGE_SHIFT // usr dst round down to page boundary
-(p7) dep F = r0,src1,0,PAGE_SHIFT // usr src round down to page boundary
- ;;
-(p6) cmp.le p14,p0=dst0,saved_in0 // no progress has been made on store
-(p7) cmp.le p14,p0=src0,saved_in1 // no progress has been made on load
- mov retval=saved_in2
-(p8) ld1 tmp=[src1] // force an oops for memcpy call
-(p8) st1 [dst1]=r0 // force an oops for memcpy call
-(p14) br.ret.sptk.many rp
-
-/*
- * The remaining byte to copy is calculated as:
- *
- * A = (faulting_addr - orig_src) -> len to faulting ld address
- * or
- * (faulting_addr - orig_dst) -> len to faulting st address
- * B = (cur_dst - orig_dst) -> len copied so far
- * C = A - B -> len need to be copied
- * D = orig_len - A -> len need to be left along
- */
-(p6) sub A = F, saved_in0
-(p7) sub A = F, saved_in1
- clrrrb
- ;;
- alloc saved_pfs_stack=ar.pfs,3,3,3,0
- cmp.lt p8,p0=A,r0
- sub B = dst0, saved_in0 // how many byte copied so far
- ;;
-(p8) mov A = 0; // A shouldn't be negative, cap it
- ;;
- sub C = A, B
- sub D = saved_in2, A
- ;;
- cmp.gt p8,p0=C,r0 // more than 1 byte?
- mov r8=0
- mov saved_retval = D
- mov saved_rtlink = b0
-
- add out0=saved_in0, B
- add out1=saved_in1, B
- mov out2=C
-(p8) br.call.sptk.few b0=__copy_user // recursive call
- ;;
-
- add saved_retval=saved_retval,r8 // above might return non-zero value
- ;;
-
- mov retval=saved_retval
- mov ar.pfs=saved_pfs_stack
- mov b0=saved_rtlink
- br.ret.sptk.many rp
-
-/* end of McKinley specific optimization */
-END(__copy_user)
-EXPORT_SYMBOL(__copy_user)
diff --git a/arch/ia64/lib/memset.S b/arch/ia64/lib/memset.S
deleted file mode 100644
index 552c5c7e4d06..000000000000
--- a/arch/ia64/lib/memset.S
+++ /dev/null
@@ -1,365 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Optimized version of the standard memset() function.
-
- Copyright (c) 2002 Hewlett-Packard Co/CERN
- Sverre Jarp <Sverre.Jarp@cern.ch>
-
- Return: dest
-
- Inputs:
- in0: dest
- in1: value
- in2: count
-
- The algorithm is fairly straightforward: set byte by byte until we
- we get to a 16B-aligned address, then loop on 128 B chunks using an
- early store as prefetching, then loop on 32B chucks, then clear remaining
- words, finally clear remaining bytes.
- Since a stf.spill f0 can store 16B in one go, we use this instruction
- to get peak speed when value = 0. */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-#undef ret
-
-#define dest in0
-#define value in1
-#define cnt in2
-
-#define tmp r31
-#define save_lc r30
-#define ptr0 r29
-#define ptr1 r28
-#define ptr2 r27
-#define ptr3 r26
-#define ptr9 r24
-#define loopcnt r23
-#define linecnt r22
-#define bytecnt r21
-
-#define fvalue f6
-
-// This routine uses only scratch predicate registers (p6 - p15)
-#define p_scr p6 // default register for same-cycle branches
-#define p_nz p7
-#define p_zr p8
-#define p_unalgn p9
-#define p_y p11
-#define p_n p12
-#define p_yy p13
-#define p_nn p14
-
-#define MIN1 15
-#define MIN1P1HALF 8
-#define LINE_SIZE 128
-#define LSIZE_SH 7 // shift amount
-#define PREF_AHEAD 8
-
-GLOBAL_ENTRY(memset)
-{ .mmi
- .prologue
- alloc tmp = ar.pfs, 3, 0, 0, 0
- lfetch.nt1 [dest] //
- .save ar.lc, save_lc
- mov.i save_lc = ar.lc
- .body
-} { .mmi
- mov ret0 = dest // return value
- cmp.ne p_nz, p_zr = value, r0 // use stf.spill if value is zero
- cmp.eq p_scr, p0 = cnt, r0
-;; }
-{ .mmi
- and ptr2 = -(MIN1+1), dest // aligned address
- and tmp = MIN1, dest // prepare to check for correct alignment
- tbit.nz p_y, p_n = dest, 0 // Do we have an odd address? (M_B_U)
-} { .mib
- mov ptr1 = dest
- mux1 value = value, @brcst // create 8 identical bytes in word
-(p_scr) br.ret.dpnt.many rp // return immediately if count = 0
-;; }
-{ .mib
- cmp.ne p_unalgn, p0 = tmp, r0 //
-} { .mib
- sub bytecnt = (MIN1+1), tmp // NB: # of bytes to move is 1 higher than loopcnt
- cmp.gt p_scr, p0 = 16, cnt // is it a minimalistic task?
-(p_scr) br.cond.dptk.many .move_bytes_unaligned // go move just a few (M_B_U)
-;; }
-{ .mmi
-(p_unalgn) add ptr1 = (MIN1+1), ptr2 // after alignment
-(p_unalgn) add ptr2 = MIN1P1HALF, ptr2 // after alignment
-(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 3 // should we do a st8 ?
-;; }
-{ .mib
-(p_y) add cnt = -8, cnt //
-(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 2 // should we do a st4 ?
-} { .mib
-(p_y) st8 [ptr2] = value,-4 //
-(p_n) add ptr2 = 4, ptr2 //
-;; }
-{ .mib
-(p_yy) add cnt = -4, cnt //
-(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 1 // should we do a st2 ?
-} { .mib
-(p_yy) st4 [ptr2] = value,-2 //
-(p_nn) add ptr2 = 2, ptr2 //
-;; }
-{ .mmi
- mov tmp = LINE_SIZE+1 // for compare
-(p_y) add cnt = -2, cnt //
-(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 0 // should we do a st1 ?
-} { .mmi
- setf.sig fvalue=value // transfer value to FLP side
-(p_y) st2 [ptr2] = value,-1 //
-(p_n) add ptr2 = 1, ptr2 //
-;; }
-
-{ .mmi
-(p_yy) st1 [ptr2] = value //
- cmp.gt p_scr, p0 = tmp, cnt // is it a minimalistic task?
-} { .mbb
-(p_yy) add cnt = -1, cnt //
-(p_scr) br.cond.dpnt.many .fraction_of_line // go move just a few
-;; }
-
-{ .mib
- nop.m 0
- shr.u linecnt = cnt, LSIZE_SH
-(p_zr) br.cond.dptk.many .l1b // Jump to use stf.spill
-;; }
-
- TEXT_ALIGN(32) // --------------------- // L1A: store ahead into cache lines; fill later
-{ .mmi
- and tmp = -(LINE_SIZE), cnt // compute end of range
- mov ptr9 = ptr1 // used for prefetching
- and cnt = (LINE_SIZE-1), cnt // remainder
-} { .mmi
- mov loopcnt = PREF_AHEAD-1 // default prefetch loop
- cmp.gt p_scr, p0 = PREF_AHEAD, linecnt // check against actual value
-;; }
-{ .mmi
-(p_scr) add loopcnt = -1, linecnt //
- add ptr2 = 8, ptr1 // start of stores (beyond prefetch stores)
- add ptr1 = tmp, ptr1 // first address beyond total range
-;; }
-{ .mmi
- add tmp = -1, linecnt // next loop count
- mov.i ar.lc = loopcnt //
-;; }
-.pref_l1a:
-{ .mib
- stf8 [ptr9] = fvalue, 128 // Do stores one cache line apart
- nop.i 0
- br.cloop.dptk.few .pref_l1a
-;; }
-{ .mmi
- add ptr0 = 16, ptr2 // Two stores in parallel
- mov.i ar.lc = tmp //
-;; }
-.l1ax:
- { .mmi
- stf8 [ptr2] = fvalue, 8
- stf8 [ptr0] = fvalue, 8
- ;; }
- { .mmi
- stf8 [ptr2] = fvalue, 24
- stf8 [ptr0] = fvalue, 24
- ;; }
- { .mmi
- stf8 [ptr2] = fvalue, 8
- stf8 [ptr0] = fvalue, 8
- ;; }
- { .mmi
- stf8 [ptr2] = fvalue, 24
- stf8 [ptr0] = fvalue, 24
- ;; }
- { .mmi
- stf8 [ptr2] = fvalue, 8
- stf8 [ptr0] = fvalue, 8
- ;; }
- { .mmi
- stf8 [ptr2] = fvalue, 24
- stf8 [ptr0] = fvalue, 24
- ;; }
- { .mmi
- stf8 [ptr2] = fvalue, 8
- stf8 [ptr0] = fvalue, 32
- cmp.lt p_scr, p0 = ptr9, ptr1 // do we need more prefetching?
- ;; }
-{ .mmb
- stf8 [ptr2] = fvalue, 24
-(p_scr) stf8 [ptr9] = fvalue, 128
- br.cloop.dptk.few .l1ax
-;; }
-{ .mbb
- cmp.le p_scr, p0 = 8, cnt // just a few bytes left ?
-(p_scr) br.cond.dpnt.many .fraction_of_line // Branch no. 2
- br.cond.dpnt.many .move_bytes_from_alignment // Branch no. 3
-;; }
-
- TEXT_ALIGN(32)
-.l1b: // ------------------------------------ // L1B: store ahead into cache lines; fill later
-{ .mmi
- and tmp = -(LINE_SIZE), cnt // compute end of range
- mov ptr9 = ptr1 // used for prefetching
- and cnt = (LINE_SIZE-1), cnt // remainder
-} { .mmi
- mov loopcnt = PREF_AHEAD-1 // default prefetch loop
- cmp.gt p_scr, p0 = PREF_AHEAD, linecnt // check against actual value
-;; }
-{ .mmi
-(p_scr) add loopcnt = -1, linecnt
- add ptr2 = 16, ptr1 // start of stores (beyond prefetch stores)
- add ptr1 = tmp, ptr1 // first address beyond total range
-;; }
-{ .mmi
- add tmp = -1, linecnt // next loop count
- mov.i ar.lc = loopcnt
-;; }
-.pref_l1b:
-{ .mib
- stf.spill [ptr9] = f0, 128 // Do stores one cache line apart
- nop.i 0
- br.cloop.dptk.few .pref_l1b
-;; }
-{ .mmi
- add ptr0 = 16, ptr2 // Two stores in parallel
- mov.i ar.lc = tmp
-;; }
-.l1bx:
- { .mmi
- stf.spill [ptr2] = f0, 32
- stf.spill [ptr0] = f0, 32
- ;; }
- { .mmi
- stf.spill [ptr2] = f0, 32
- stf.spill [ptr0] = f0, 32
- ;; }
- { .mmi
- stf.spill [ptr2] = f0, 32
- stf.spill [ptr0] = f0, 64
- cmp.lt p_scr, p0 = ptr9, ptr1 // do we need more prefetching?
- ;; }
-{ .mmb
- stf.spill [ptr2] = f0, 32
-(p_scr) stf.spill [ptr9] = f0, 128
- br.cloop.dptk.few .l1bx
-;; }
-{ .mib
- cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ?
-(p_scr) br.cond.dpnt.many .move_bytes_from_alignment //
-;; }
-
-.fraction_of_line:
-{ .mib
- add ptr2 = 16, ptr1
- shr.u loopcnt = cnt, 5 // loopcnt = cnt / 32
-;; }
-{ .mib
- cmp.eq p_scr, p0 = loopcnt, r0
- add loopcnt = -1, loopcnt
-(p_scr) br.cond.dpnt.many .store_words
-;; }
-{ .mib
- and cnt = 0x1f, cnt // compute the remaining cnt
- mov.i ar.lc = loopcnt
-;; }
- TEXT_ALIGN(32)
-.l2: // ------------------------------------ // L2A: store 32B in 2 cycles
-{ .mmb
- stf8 [ptr1] = fvalue, 8
- stf8 [ptr2] = fvalue, 8
-;; } { .mmb
- stf8 [ptr1] = fvalue, 24
- stf8 [ptr2] = fvalue, 24
- br.cloop.dptk.many .l2
-;; }
-.store_words:
-{ .mib
- cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ?
-(p_scr) br.cond.dpnt.many .move_bytes_from_alignment // Branch
-;; }
-
-{ .mmi
- stf8 [ptr1] = fvalue, 8 // store
- cmp.le p_y, p_n = 16, cnt
- add cnt = -8, cnt // subtract
-;; }
-{ .mmi
-(p_y) stf8 [ptr1] = fvalue, 8 // store
-(p_y) cmp.le.unc p_yy, p_nn = 16, cnt
-(p_y) add cnt = -8, cnt // subtract
-;; }
-{ .mmi // store
-(p_yy) stf8 [ptr1] = fvalue, 8
-(p_yy) add cnt = -8, cnt // subtract
-;; }
-
-.move_bytes_from_alignment:
-{ .mib
- cmp.eq p_scr, p0 = cnt, r0
- tbit.nz.unc p_y, p0 = cnt, 2 // should we terminate with a st4 ?
-(p_scr) br.cond.dpnt.few .restore_and_exit
-;; }
-{ .mib
-(p_y) st4 [ptr1] = value,4
- tbit.nz.unc p_yy, p0 = cnt, 1 // should we terminate with a st2 ?
-;; }
-{ .mib
-(p_yy) st2 [ptr1] = value,2
- tbit.nz.unc p_y, p0 = cnt, 0 // should we terminate with a st1 ?
-;; }
-
-{ .mib
-(p_y) st1 [ptr1] = value
-;; }
-.restore_and_exit:
-{ .mib
- nop.m 0
- mov.i ar.lc = save_lc
- br.ret.sptk.many rp
-;; }
-
-.move_bytes_unaligned:
-{ .mmi
- .pred.rel "mutex",p_y, p_n
- .pred.rel "mutex",p_yy, p_nn
-(p_n) cmp.le p_yy, p_nn = 4, cnt
-(p_y) cmp.le p_yy, p_nn = 5, cnt
-(p_n) add ptr2 = 2, ptr1
-} { .mmi
-(p_y) add ptr2 = 3, ptr1
-(p_y) st1 [ptr1] = value, 1 // fill 1 (odd-aligned) byte [15, 14 (or less) left]
-(p_y) add cnt = -1, cnt
-;; }
-{ .mmi
-(p_yy) cmp.le.unc p_y, p0 = 8, cnt
- add ptr3 = ptr1, cnt // prepare last store
- mov.i ar.lc = save_lc
-} { .mmi
-(p_yy) st2 [ptr1] = value, 4 // fill 2 (aligned) bytes
-(p_yy) st2 [ptr2] = value, 4 // fill 2 (aligned) bytes [11, 10 (o less) left]
-(p_yy) add cnt = -4, cnt
-;; }
-{ .mmi
-(p_y) cmp.le.unc p_yy, p0 = 8, cnt
- add ptr3 = -1, ptr3 // last store
- tbit.nz p_scr, p0 = cnt, 1 // will there be a st2 at the end ?
-} { .mmi
-(p_y) st2 [ptr1] = value, 4 // fill 2 (aligned) bytes
-(p_y) st2 [ptr2] = value, 4 // fill 2 (aligned) bytes [7, 6 (or less) left]
-(p_y) add cnt = -4, cnt
-;; }
-{ .mmi
-(p_yy) st2 [ptr1] = value, 4 // fill 2 (aligned) bytes
-(p_yy) st2 [ptr2] = value, 4 // fill 2 (aligned) bytes [3, 2 (or less) left]
- tbit.nz p_y, p0 = cnt, 0 // will there be a st1 at the end ?
-} { .mmi
-(p_yy) add cnt = -4, cnt
-;; }
-{ .mmb
-(p_scr) st2 [ptr1] = value // fill 2 (aligned) bytes
-(p_y) st1 [ptr3] = value // fill last byte (using ptr3)
- br.ret.sptk.many rp
-}
-END(memset)
-EXPORT_SYMBOL(memset)
diff --git a/arch/ia64/lib/strlen.S b/arch/ia64/lib/strlen.S
deleted file mode 100644
index 1f4a46c15127..000000000000
--- a/arch/ia64/lib/strlen.S
+++ /dev/null
@@ -1,195 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *
- * Optimized version of the standard strlen() function
- *
- *
- * Inputs:
- * in0 address of string
- *
- * Outputs:
- * ret0 the number of characters in the string (0 if empty string)
- * does not count the \0
- *
- * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Stephane Eranian <eranian@hpl.hp.com>
- *
- * 09/24/99 S.Eranian add speculation recovery code
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-//
-//
-// This is an enhanced version of the basic strlen. it includes a combination
-// of compute zero index (czx), parallel comparisons, speculative loads and
-// loop unroll using rotating registers.
-//
-// General Ideas about the algorithm:
-// The goal is to look at the string in chunks of 8 bytes.
-// so we need to do a few extra checks at the beginning because the
-// string may not be 8-byte aligned. In this case we load the 8byte
-// quantity which includes the start of the string and mask the unused
-// bytes with 0xff to avoid confusing czx.
-// We use speculative loads and software pipelining to hide memory
-// latency and do read ahead safely. This way we defer any exception.
-//
-// Because we don't want the kernel to be relying on particular
-// settings of the DCR register, we provide recovery code in case
-// speculation fails. The recovery code is going to "redo" the work using
-// only normal loads. If we still get a fault then we generate a
-// kernel panic. Otherwise we return the strlen as usual.
-//
-// The fact that speculation may fail can be caused, for instance, by
-// the DCR.dm bit being set. In this case TLB misses are deferred, i.e.,
-// a NaT bit will be set if the translation is not present. The normal
-// load, on the other hand, will cause the translation to be inserted
-// if the mapping exists.
-//
-// It should be noted that we execute recovery code only when we need
-// to use the data that has been speculatively loaded: we don't execute
-// recovery code on pure read ahead data.
-//
-// Remarks:
-// - the cmp r0,r0 is used as a fast way to initialize a predicate
-// register to 1. This is required to make sure that we get the parallel
-// compare correct.
-//
-// - we don't use the epilogue counter to exit the loop but we need to set
-// it to zero beforehand.
-//
-// - after the loop we must test for Nat values because neither the
-// czx nor cmp instruction raise a NaT consumption fault. We must be
-// careful not to look too far for a Nat for which we don't care.
-// For instance we don't need to look at a NaT in val2 if the zero byte
-// was in val1.
-//
-// - Clearly performance tuning is required.
-//
-//
-//
-#define saved_pfs r11
-#define tmp r10
-#define base r16
-#define orig r17
-#define saved_pr r18
-#define src r19
-#define mask r20
-#define val r21
-#define val1 r22
-#define val2 r23
-
-GLOBAL_ENTRY(strlen)
- .prologue
- .save ar.pfs, saved_pfs
- alloc saved_pfs=ar.pfs,11,0,0,8 // rotating must be multiple of 8
-
- .rotr v[2], w[2] // declares our 4 aliases
-
- extr.u tmp=in0,0,3 // tmp=least significant 3 bits
- mov orig=in0 // keep trackof initial byte address
- dep src=0,in0,0,3 // src=8byte-aligned in0 address
- .save pr, saved_pr
- mov saved_pr=pr // preserve predicates (rotation)
- ;;
-
- .body
-
- ld8 v[1]=[src],8 // must not speculate: can fail here
- shl tmp=tmp,3 // multiply by 8bits/byte
- mov mask=-1 // our mask
- ;;
- ld8.s w[1]=[src],8 // speculatively load next
- cmp.eq p6,p0=r0,r0 // sets p6 to true for cmp.and
- sub tmp=64,tmp // how many bits to shift our mask on the right
- ;;
- shr.u mask=mask,tmp // zero enough bits to hold v[1] valuable part
- mov ar.ec=r0 // clear epilogue counter (saved in ar.pfs)
- ;;
- add base=-16,src // keep track of aligned base
- or v[1]=v[1],mask // now we have a safe initial byte pattern
- ;;
-1:
- ld8.s v[0]=[src],8 // speculatively load next
- czx1.r val1=v[1] // search 0 byte from right
- czx1.r val2=w[1] // search 0 byte from right following 8bytes
- ;;
- ld8.s w[0]=[src],8 // speculatively load next to next
- cmp.eq.and p6,p0=8,val1 // p6 = p6 and val1==8
- cmp.eq.and p6,p0=8,val2 // p6 = p6 and mask==8
-(p6) br.wtop.dptk 1b // loop until p6 == 0
- ;;
- //
- // We must return try the recovery code iff
- // val1_is_nat || (val1==8 && val2_is_nat)
- //
- // XXX Fixme
- // - there must be a better way of doing the test
- //
- cmp.eq p8,p9=8,val1 // p6 = val1 had zero (disambiguate)
- tnat.nz p6,p7=val1 // test NaT on val1
-(p6) br.cond.spnt .recover // jump to recovery if val1 is NaT
- ;;
- //
- // if we come here p7 is true, i.e., initialized for // cmp
- //
- cmp.eq.and p7,p0=8,val1// val1==8?
- tnat.nz.and p7,p0=val2 // test NaT if val2
-(p7) br.cond.spnt .recover // jump to recovery if val2 is NaT
- ;;
-(p8) mov val1=val2 // the other test got us out of the loop
-(p8) adds src=-16,src // correct position when 3 ahead
-(p9) adds src=-24,src // correct position when 4 ahead
- ;;
- sub ret0=src,orig // distance from base
- sub tmp=8,val1 // which byte in word
- mov pr=saved_pr,0xffffffffffff0000
- ;;
- sub ret0=ret0,tmp // adjust
- mov ar.pfs=saved_pfs // because of ar.ec, restore no matter what
- br.ret.sptk.many rp // end of normal execution
-
- //
- // Outlined recovery code when speculation failed
- //
- // This time we don't use speculation and rely on the normal exception
- // mechanism. that's why the loop is not as good as the previous one
- // because read ahead is not possible
- //
- // IMPORTANT:
- // Please note that in the case of strlen() as opposed to strlen_user()
- // we don't use the exception mechanism, as this function is not
- // supposed to fail. If that happens it means we have a bug and the
- // code will cause of kernel fault.
- //
- // XXX Fixme
- // - today we restart from the beginning of the string instead
- // of trying to continue where we left off.
- //
-.recover:
- ld8 val=[base],8 // will fail if unrecoverable fault
- ;;
- or val=val,mask // remask first bytes
- cmp.eq p0,p6=r0,r0 // nullify first ld8 in loop
- ;;
- //
- // ar.ec is still zero here
- //
-2:
-(p6) ld8 val=[base],8 // will fail if unrecoverable fault
- ;;
- czx1.r val1=val // search 0 byte from right
- ;;
- cmp.eq p6,p0=8,val1 // val1==8 ?
-(p6) br.wtop.dptk 2b // loop until p6 == 0
- ;; // (avoid WAW on p63)
- sub ret0=base,orig // distance from base
- sub tmp=8,val1
- mov pr=saved_pr,0xffffffffffff0000
- ;;
- sub ret0=ret0,tmp // length=now - back -1
- mov ar.pfs=saved_pfs // because of ar.ec, restore no matter what
- br.ret.sptk.many rp // end of successful recovery code
-END(strlen)
-EXPORT_SYMBOL(strlen)
diff --git a/arch/ia64/lib/strncpy_from_user.S b/arch/ia64/lib/strncpy_from_user.S
deleted file mode 100644
index a287169bd953..000000000000
--- a/arch/ia64/lib/strncpy_from_user.S
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Just like strncpy() except that if a fault occurs during copying,
- * -EFAULT is returned.
- *
- * Inputs:
- * in0: address of destination buffer
- * in1: address of string to be copied
- * in2: length of buffer in bytes
- * Outputs:
- * r8: -EFAULT in case of fault or number of bytes copied if no fault
- *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 00/03/06 D. Mosberger Fixed to return proper return value (bug found by
- * by Andreas Schwab <schwab@suse.de>).
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-GLOBAL_ENTRY(__strncpy_from_user)
- alloc r2=ar.pfs,3,0,0,0
- mov r8=0
- mov r9=in1
- ;;
- add r10=in1,in2
- cmp.eq p6,p0=r0,in2
-(p6) br.ret.spnt.many rp
-
- // XXX braindead copy loop---this needs to be optimized
-.Loop1:
- EX(.Lexit, ld1 r8=[in1],1)
- ;;
- EX(.Lexit, st1 [in0]=r8,1)
- cmp.ne p6,p7=r8,r0
- ;;
-(p6) cmp.ne.unc p8,p0=in1,r10
-(p8) br.cond.dpnt.few .Loop1
- ;;
-(p6) mov r8=in2 // buffer filled up---return buffer length
-(p7) sub r8=in1,r9,1 // return string length (excluding NUL character)
-[.Lexit:]
- br.ret.sptk.many rp
-END(__strncpy_from_user)
-EXPORT_SYMBOL(__strncpy_from_user)
diff --git a/arch/ia64/lib/strnlen_user.S b/arch/ia64/lib/strnlen_user.S
deleted file mode 100644
index a7eb56e840a9..000000000000
--- a/arch/ia64/lib/strnlen_user.S
+++ /dev/null
@@ -1,48 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Returns 0 if exception before NUL or reaching the supplied limit (N),
- * a value greater than N if the string is longer than the limit, else
- * strlen.
- *
- * Inputs:
- * in0: address of buffer
- * in1: string length limit N
- * Outputs:
- * r8: 0 in case of fault, strlen(buffer)+1 otherwise
- *
- * Copyright (C) 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-GLOBAL_ENTRY(__strnlen_user)
- .prologue
- alloc r2=ar.pfs,2,0,0,0
- .save ar.lc, r16
- mov r16=ar.lc // preserve ar.lc
-
- .body
-
- add r3=-1,in1
- ;;
- mov ar.lc=r3
- mov r9=0
- ;;
- // XXX braindead strlen loop---this needs to be optimized
-.Loop1:
- EXCLR(.Lexit, ld1 r8=[in0],1)
- add r9=1,r9
- ;;
- cmp.eq p6,p0=r8,r0
-(p6) br.cond.dpnt .Lexit
- br.cloop.dptk.few .Loop1
-
- add r9=1,in1 // NUL not found---return N+1
- ;;
-.Lexit:
- mov r8=r9
- mov ar.lc=r16 // restore ar.lc
- br.ret.sptk.many rp
-END(__strnlen_user)
-EXPORT_SYMBOL(__strnlen_user)
diff --git a/arch/ia64/lib/xor.S b/arch/ia64/lib/xor.S
deleted file mode 100644
index 6e2a69662c06..000000000000
--- a/arch/ia64/lib/xor.S
+++ /dev/null
@@ -1,181 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/ia64/lib/xor.S
- *
- * Optimized RAID-5 checksumming functions for IA-64.
- */
-
-#include <linux/export.h>
-#include <asm/asmmacro.h>
-
-GLOBAL_ENTRY(xor_ia64_2)
- .prologue
- .fframe 0
- .save ar.pfs, r31
- alloc r31 = ar.pfs, 3, 0, 13, 16
- .save ar.lc, r30
- mov r30 = ar.lc
- .save pr, r29
- mov r29 = pr
- ;;
- .body
- mov r8 = in1
- mov ar.ec = 6 + 2
- shr in0 = in0, 3
- ;;
- adds in0 = -1, in0
- mov r16 = in1
- mov r17 = in2
- ;;
- mov ar.lc = in0
- mov pr.rot = 1 << 16
- ;;
- .rotr s1[6+1], s2[6+1], d[2]
- .rotp p[6+2]
-0:
-(p[0]) ld8.nta s1[0] = [r16], 8
-(p[0]) ld8.nta s2[0] = [r17], 8
-(p[6]) xor d[0] = s1[6], s2[6]
-(p[6+1])st8.nta [r8] = d[1], 8
- nop.f 0
- br.ctop.dptk.few 0b
- ;;
- mov ar.lc = r30
- mov pr = r29, -1
- br.ret.sptk.few rp
-END(xor_ia64_2)
-EXPORT_SYMBOL(xor_ia64_2)
-
-GLOBAL_ENTRY(xor_ia64_3)
- .prologue
- .fframe 0
- .save ar.pfs, r31
- alloc r31 = ar.pfs, 4, 0, 20, 24
- .save ar.lc, r30
- mov r30 = ar.lc
- .save pr, r29
- mov r29 = pr
- ;;
- .body
- mov r8 = in1
- mov ar.ec = 6 + 2
- shr in0 = in0, 3
- ;;
- adds in0 = -1, in0
- mov r16 = in1
- mov r17 = in2
- ;;
- mov r18 = in3
- mov ar.lc = in0
- mov pr.rot = 1 << 16
- ;;
- .rotr s1[6+1], s2[6+1], s3[6+1], d[2]
- .rotp p[6+2]
-0:
-(p[0]) ld8.nta s1[0] = [r16], 8
-(p[0]) ld8.nta s2[0] = [r17], 8
-(p[6]) xor d[0] = s1[6], s2[6]
- ;;
-(p[0]) ld8.nta s3[0] = [r18], 8
-(p[6+1])st8.nta [r8] = d[1], 8
-(p[6]) xor d[0] = d[0], s3[6]
- br.ctop.dptk.few 0b
- ;;
- mov ar.lc = r30
- mov pr = r29, -1
- br.ret.sptk.few rp
-END(xor_ia64_3)
-EXPORT_SYMBOL(xor_ia64_3)
-
-GLOBAL_ENTRY(xor_ia64_4)
- .prologue
- .fframe 0
- .save ar.pfs, r31
- alloc r31 = ar.pfs, 5, 0, 27, 32
- .save ar.lc, r30
- mov r30 = ar.lc
- .save pr, r29
- mov r29 = pr
- ;;
- .body
- mov r8 = in1
- mov ar.ec = 6 + 2
- shr in0 = in0, 3
- ;;
- adds in0 = -1, in0
- mov r16 = in1
- mov r17 = in2
- ;;
- mov r18 = in3
- mov ar.lc = in0
- mov pr.rot = 1 << 16
- mov r19 = in4
- ;;
- .rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], d[2]
- .rotp p[6+2]
-0:
-(p[0]) ld8.nta s1[0] = [r16], 8
-(p[0]) ld8.nta s2[0] = [r17], 8
-(p[6]) xor d[0] = s1[6], s2[6]
-(p[0]) ld8.nta s3[0] = [r18], 8
-(p[0]) ld8.nta s4[0] = [r19], 8
-(p[6]) xor r20 = s3[6], s4[6]
- ;;
-(p[6+1])st8.nta [r8] = d[1], 8
-(p[6]) xor d[0] = d[0], r20
- br.ctop.dptk.few 0b
- ;;
- mov ar.lc = r30
- mov pr = r29, -1
- br.ret.sptk.few rp
-END(xor_ia64_4)
-EXPORT_SYMBOL(xor_ia64_4)
-
-GLOBAL_ENTRY(xor_ia64_5)
- .prologue
- .fframe 0
- .save ar.pfs, r31
- alloc r31 = ar.pfs, 6, 0, 34, 40
- .save ar.lc, r30
- mov r30 = ar.lc
- .save pr, r29
- mov r29 = pr
- ;;
- .body
- mov r8 = in1
- mov ar.ec = 6 + 2
- shr in0 = in0, 3
- ;;
- adds in0 = -1, in0
- mov r16 = in1
- mov r17 = in2
- ;;
- mov r18 = in3
- mov ar.lc = in0
- mov pr.rot = 1 << 16
- mov r19 = in4
- mov r20 = in5
- ;;
- .rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], s5[6+1], d[2]
- .rotp p[6+2]
-0:
-(p[0]) ld8.nta s1[0] = [r16], 8
-(p[0]) ld8.nta s2[0] = [r17], 8
-(p[6]) xor d[0] = s1[6], s2[6]
-(p[0]) ld8.nta s3[0] = [r18], 8
-(p[0]) ld8.nta s4[0] = [r19], 8
-(p[6]) xor r21 = s3[6], s4[6]
- ;;
-(p[0]) ld8.nta s5[0] = [r20], 8
-(p[6+1])st8.nta [r8] = d[1], 8
-(p[6]) xor d[0] = d[0], r21
- ;;
-(p[6]) xor d[0] = d[0], s5[6]
- nop.f 0
- br.ctop.dptk.few 0b
- ;;
- mov ar.lc = r30
- mov pr = r29, -1
- br.ret.sptk.few rp
-END(xor_ia64_5)
-EXPORT_SYMBOL(xor_ia64_5)
diff --git a/arch/ia64/mm/Makefile b/arch/ia64/mm/Makefile
deleted file mode 100644
index c03f63c62ac4..000000000000
--- a/arch/ia64/mm/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the ia64-specific parts of the memory manager.
-#
-
-obj-y := init.o fault.o tlb.o extable.o ioremap.o
-
-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_NUMA) += numa.o
-obj-$(CONFIG_SPARSEMEM) += discontig.o
-obj-$(CONFIG_FLATMEM) += contig.o
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
deleted file mode 100644
index 1e9eaa107eb7..000000000000
--- a/arch/ia64/mm/contig.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 2003 Silicon Graphics, Inc. All rights reserved.
- *
- * Routines used by ia64 machines with contiguous (or virtually contiguous)
- * memory.
- */
-#include <linux/efi.h>
-#include <linux/memblock.h>
-#include <linux/mm.h>
-#include <linux/nmi.h>
-#include <linux/swap.h>
-#include <linux/sizes.h>
-
-#include <asm/efi.h>
-#include <asm/meminit.h>
-#include <asm/sections.h>
-#include <asm/mca.h>
-
-/* physical address where the bootmem map is located */
-unsigned long bootmap_start;
-
-#ifdef CONFIG_SMP
-static void *cpu_data;
-/**
- * per_cpu_init - setup per-cpu variables
- *
- * Allocate and setup per-cpu data areas.
- */
-void *per_cpu_init(void)
-{
- static bool first_time = true;
- void *cpu0_data = __cpu0_per_cpu;
- unsigned int cpu;
-
- if (!first_time)
- goto skip;
- first_time = false;
-
- /*
- * get_free_pages() cannot be used before cpu_init() done.
- * BSP allocates PERCPU_PAGE_SIZE bytes for all possible CPUs
- * to avoid that AP calls get_zeroed_page().
- */
- for_each_possible_cpu(cpu) {
- void *src = cpu == 0 ? cpu0_data : __phys_per_cpu_start;
-
- memcpy(cpu_data, src, __per_cpu_end - __per_cpu_start);
- __per_cpu_offset[cpu] = (char *)cpu_data - __per_cpu_start;
- per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
-
- /*
- * percpu area for cpu0 is moved from the __init area
- * which is setup by head.S and used till this point.
- * Update ar.k3. This move is ensures that percpu
- * area for cpu0 is on the correct node and its
- * virtual address isn't insanely far from other
- * percpu areas which is important for congruent
- * percpu allocator.
- */
- if (cpu == 0)
- ia64_set_kr(IA64_KR_PER_CPU_DATA, __pa(cpu_data) -
- (unsigned long)__per_cpu_start);
-
- cpu_data += PERCPU_PAGE_SIZE;
- }
-skip:
- return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
-}
-
-static inline __init void
-alloc_per_cpu_data(void)
-{
- size_t size = PERCPU_PAGE_SIZE * num_possible_cpus();
-
- cpu_data = memblock_alloc_from(size, PERCPU_PAGE_SIZE,
- __pa(MAX_DMA_ADDRESS));
- if (!cpu_data)
- panic("%s: Failed to allocate %lu bytes align=%lx from=%lx\n",
- __func__, size, PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
-}
-
-/**
- * setup_per_cpu_areas - setup percpu areas
- *
- * Arch code has already allocated and initialized percpu areas. All
- * this function has to do is to teach the determined layout to the
- * dynamic percpu allocator, which happens to be more complex than
- * creating whole new ones using helpers.
- */
-void __init
-setup_per_cpu_areas(void)
-{
- struct pcpu_alloc_info *ai;
- struct pcpu_group_info *gi;
- unsigned int cpu;
- ssize_t static_size, reserved_size, dyn_size;
-
- ai = pcpu_alloc_alloc_info(1, num_possible_cpus());
- if (!ai)
- panic("failed to allocate pcpu_alloc_info");
- gi = &ai->groups[0];
-
- /* units are assigned consecutively to possible cpus */
- for_each_possible_cpu(cpu)
- gi->cpu_map[gi->nr_units++] = cpu;
-
- /* set parameters */
- static_size = __per_cpu_end - __per_cpu_start;
- reserved_size = PERCPU_MODULE_RESERVE;
- dyn_size = PERCPU_PAGE_SIZE - static_size - reserved_size;
- if (dyn_size < 0)
- panic("percpu area overflow static=%zd reserved=%zd\n",
- static_size, reserved_size);
-
- ai->static_size = static_size;
- ai->reserved_size = reserved_size;
- ai->dyn_size = dyn_size;
- ai->unit_size = PERCPU_PAGE_SIZE;
- ai->atom_size = PAGE_SIZE;
- ai->alloc_size = PERCPU_PAGE_SIZE;
-
- pcpu_setup_first_chunk(ai, __per_cpu_start + __per_cpu_offset[0]);
- pcpu_free_alloc_info(ai);
-}
-#else
-#define alloc_per_cpu_data() do { } while (0)
-#endif /* CONFIG_SMP */
-
-/**
- * find_memory - setup memory map
- *
- * Walk the EFI memory map and find usable memory for the system, taking
- * into account reserved areas.
- */
-void __init
-find_memory (void)
-{
- reserve_memory();
-
- /* first find highest page frame number */
- min_low_pfn = ~0UL;
- max_low_pfn = 0;
- efi_memmap_walk(find_max_min_low_pfn, NULL);
- max_pfn = max_low_pfn;
-
- memblock_add_node(0, PFN_PHYS(max_low_pfn), 0, MEMBLOCK_NONE);
-
- find_initrd();
-
- alloc_per_cpu_data();
-}
-
-static int __init find_largest_hole(u64 start, u64 end, void *arg)
-{
- u64 *max_gap = arg;
-
- static u64 last_end = PAGE_OFFSET;
-
- /* NOTE: this algorithm assumes efi memmap table is ordered */
-
- if (*max_gap < (start - last_end))
- *max_gap = start - last_end;
- last_end = end;
- return 0;
-}
-
-static void __init verify_gap_absence(void)
-{
- unsigned long max_gap;
-
- /* Forbid FLATMEM if hole is > than 1G */
- efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
- if (max_gap >= SZ_1G)
- panic("Cannot use FLATMEM with %ldMB hole\n"
- "Please switch over to SPARSEMEM\n",
- (max_gap >> 20));
-}
-
-/*
- * Set up the page tables.
- */
-
-void __init
-paging_init (void)
-{
- unsigned long max_dma;
- unsigned long max_zone_pfns[MAX_NR_ZONES];
-
- memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
- max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
- max_zone_pfns[ZONE_DMA32] = max_dma;
- max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
-
- verify_gap_absence();
-
- free_area_init(max_zone_pfns);
- zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
-}
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
deleted file mode 100644
index 73d0db36edb6..000000000000
--- a/arch/ia64/mm/discontig.c
+++ /dev/null
@@ -1,635 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2000, 2003 Silicon Graphics, Inc. All rights reserved.
- * Copyright (c) 2001 Intel Corp.
- * Copyright (c) 2001 Tony Luck <tony.luck@intel.com>
- * Copyright (c) 2002 NEC Corp.
- * Copyright (c) 2002 Kimio Suganuma <k-suganuma@da.jp.nec.com>
- * Copyright (c) 2004 Silicon Graphics, Inc
- * Russ Anderson <rja@sgi.com>
- * Jesse Barnes <jbarnes@sgi.com>
- * Jack Steiner <steiner@sgi.com>
- */
-
-/*
- * Platform initialization for Discontig Memory
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/nmi.h>
-#include <linux/swap.h>
-#include <linux/memblock.h>
-#include <linux/acpi.h>
-#include <linux/efi.h>
-#include <linux/nodemask.h>
-#include <linux/slab.h>
-#include <asm/efi.h>
-#include <asm/tlb.h>
-#include <asm/meminit.h>
-#include <asm/numa.h>
-#include <asm/sections.h>
-
-/*
- * Track per-node information needed to setup the boot memory allocator, the
- * per-node areas, and the real VM.
- */
-struct early_node_data {
- struct ia64_node_data *node_data;
- unsigned long pernode_addr;
- unsigned long pernode_size;
- unsigned long min_pfn;
- unsigned long max_pfn;
-};
-
-static struct early_node_data mem_data[MAX_NUMNODES] __initdata;
-static nodemask_t memory_less_mask __initdata;
-
-pg_data_t *pgdat_list[MAX_NUMNODES];
-
-/*
- * To prevent cache aliasing effects, align per-node structures so that they
- * start at addresses that are strided by node number.
- */
-#define MAX_NODE_ALIGN_OFFSET (32 * 1024 * 1024)
-#define NODEDATA_ALIGN(addr, node) \
- ((((addr) + 1024*1024-1) & ~(1024*1024-1)) + \
- (((node)*PERCPU_PAGE_SIZE) & (MAX_NODE_ALIGN_OFFSET - 1)))
-
-/**
- * build_node_maps - callback to setup mem_data structs for each node
- * @start: physical start of range
- * @len: length of range
- * @node: node where this range resides
- *
- * Detect extents of each piece of memory that we wish to
- * treat as a virtually contiguous block (i.e. each node). Each such block
- * must start on an %IA64_GRANULE_SIZE boundary, so we round the address down
- * if necessary. Any non-existent pages will simply be part of the virtual
- * memmap.
- */
-static int __init build_node_maps(unsigned long start, unsigned long len,
- int node)
-{
- unsigned long spfn, epfn, end = start + len;
-
- epfn = GRANULEROUNDUP(end) >> PAGE_SHIFT;
- spfn = GRANULEROUNDDOWN(start) >> PAGE_SHIFT;
-
- if (!mem_data[node].min_pfn) {
- mem_data[node].min_pfn = spfn;
- mem_data[node].max_pfn = epfn;
- } else {
- mem_data[node].min_pfn = min(spfn, mem_data[node].min_pfn);
- mem_data[node].max_pfn = max(epfn, mem_data[node].max_pfn);
- }
-
- return 0;
-}
-
-/**
- * early_nr_cpus_node - return number of cpus on a given node
- * @node: node to check
- *
- * Count the number of cpus on @node. We can't use nr_cpus_node() yet because
- * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been
- * called yet. Note that node 0 will also count all non-existent cpus.
- */
-static int early_nr_cpus_node(int node)
-{
- int cpu, n = 0;
-
- for_each_possible_early_cpu(cpu)
- if (node == node_cpuid[cpu].nid)
- n++;
-
- return n;
-}
-
-/**
- * compute_pernodesize - compute size of pernode data
- * @node: the node id.
- */
-static unsigned long compute_pernodesize(int node)
-{
- unsigned long pernodesize = 0, cpus;
-
- cpus = early_nr_cpus_node(node);
- pernodesize += PERCPU_PAGE_SIZE * cpus;
- pernodesize += node * L1_CACHE_BYTES;
- pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
- pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
- pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
- pernodesize = PAGE_ALIGN(pernodesize);
- return pernodesize;
-}
-
-/**
- * per_cpu_node_setup - setup per-cpu areas on each node
- * @cpu_data: per-cpu area on this node
- * @node: node to setup
- *
- * Copy the static per-cpu data into the region we just set aside and then
- * setup __per_cpu_offset for each CPU on this node. Return a pointer to
- * the end of the area.
- */
-static void *per_cpu_node_setup(void *cpu_data, int node)
-{
-#ifdef CONFIG_SMP
- int cpu;
-
- for_each_possible_early_cpu(cpu) {
- void *src = cpu == 0 ? __cpu0_per_cpu : __phys_per_cpu_start;
-
- if (node != node_cpuid[cpu].nid)
- continue;
-
- memcpy(__va(cpu_data), src, __per_cpu_end - __per_cpu_start);
- __per_cpu_offset[cpu] = (char *)__va(cpu_data) -
- __per_cpu_start;
-
- /*
- * percpu area for cpu0 is moved from the __init area
- * which is setup by head.S and used till this point.
- * Update ar.k3. This move is ensures that percpu
- * area for cpu0 is on the correct node and its
- * virtual address isn't insanely far from other
- * percpu areas which is important for congruent
- * percpu allocator.
- */
- if (cpu == 0)
- ia64_set_kr(IA64_KR_PER_CPU_DATA,
- (unsigned long)cpu_data -
- (unsigned long)__per_cpu_start);
-
- cpu_data += PERCPU_PAGE_SIZE;
- }
-#endif
- return cpu_data;
-}
-
-#ifdef CONFIG_SMP
-/**
- * setup_per_cpu_areas - setup percpu areas
- *
- * Arch code has already allocated and initialized percpu areas. All
- * this function has to do is to teach the determined layout to the
- * dynamic percpu allocator, which happens to be more complex than
- * creating whole new ones using helpers.
- */
-void __init setup_per_cpu_areas(void)
-{
- struct pcpu_alloc_info *ai;
- struct pcpu_group_info *gi;
- unsigned int *cpu_map;
- void *base;
- unsigned long base_offset;
- unsigned int cpu;
- ssize_t static_size, reserved_size, dyn_size;
- int node, prev_node, unit, nr_units;
-
- ai = pcpu_alloc_alloc_info(MAX_NUMNODES, nr_cpu_ids);
- if (!ai)
- panic("failed to allocate pcpu_alloc_info");
- cpu_map = ai->groups[0].cpu_map;
-
- /* determine base */
- base = (void *)ULONG_MAX;
- for_each_possible_cpu(cpu)
- base = min(base,
- (void *)(__per_cpu_offset[cpu] + __per_cpu_start));
- base_offset = (void *)__per_cpu_start - base;
-
- /* build cpu_map, units are grouped by node */
- unit = 0;
- for_each_node(node)
- for_each_possible_cpu(cpu)
- if (node == node_cpuid[cpu].nid)
- cpu_map[unit++] = cpu;
- nr_units = unit;
-
- /* set basic parameters */
- static_size = __per_cpu_end - __per_cpu_start;
- reserved_size = PERCPU_MODULE_RESERVE;
- dyn_size = PERCPU_PAGE_SIZE - static_size - reserved_size;
- if (dyn_size < 0)
- panic("percpu area overflow static=%zd reserved=%zd\n",
- static_size, reserved_size);
-
- ai->static_size = static_size;
- ai->reserved_size = reserved_size;
- ai->dyn_size = dyn_size;
- ai->unit_size = PERCPU_PAGE_SIZE;
- ai->atom_size = PAGE_SIZE;
- ai->alloc_size = PERCPU_PAGE_SIZE;
-
- /*
- * CPUs are put into groups according to node. Walk cpu_map
- * and create new groups at node boundaries.
- */
- prev_node = NUMA_NO_NODE;
- ai->nr_groups = 0;
- for (unit = 0; unit < nr_units; unit++) {
- cpu = cpu_map[unit];
- node = node_cpuid[cpu].nid;
-
- if (node == prev_node) {
- gi->nr_units++;
- continue;
- }
- prev_node = node;
-
- gi = &ai->groups[ai->nr_groups++];
- gi->nr_units = 1;
- gi->base_offset = __per_cpu_offset[cpu] + base_offset;
- gi->cpu_map = &cpu_map[unit];
- }
-
- pcpu_setup_first_chunk(ai, base);
- pcpu_free_alloc_info(ai);
-}
-#endif
-
-/**
- * fill_pernode - initialize pernode data.
- * @node: the node id.
- * @pernode: physical address of pernode data
- * @pernodesize: size of the pernode data
- */
-static void __init fill_pernode(int node, unsigned long pernode,
- unsigned long pernodesize)
-{
- void *cpu_data;
- int cpus = early_nr_cpus_node(node);
-
- mem_data[node].pernode_addr = pernode;
- mem_data[node].pernode_size = pernodesize;
- memset(__va(pernode), 0, pernodesize);
-
- cpu_data = (void *)pernode;
- pernode += PERCPU_PAGE_SIZE * cpus;
- pernode += node * L1_CACHE_BYTES;
-
- pgdat_list[node] = __va(pernode);
- pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
-
- mem_data[node].node_data = __va(pernode);
- pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
- pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
-
- cpu_data = per_cpu_node_setup(cpu_data, node);
-
- return;
-}
-
-/**
- * find_pernode_space - allocate memory for memory map and per-node structures
- * @start: physical start of range
- * @len: length of range
- * @node: node where this range resides
- *
- * This routine reserves space for the per-cpu data struct, the list of
- * pg_data_ts and the per-node data struct. Each node will have something like
- * the following in the first chunk of addr. space large enough to hold it.
- *
- * ________________________
- * | |
- * |~~~~~~~~~~~~~~~~~~~~~~~~| <-- NODEDATA_ALIGN(start, node) for the first
- * | PERCPU_PAGE_SIZE * | start and length big enough
- * | cpus_on_this_node | Node 0 will also have entries for all non-existent cpus.
- * |------------------------|
- * | local pg_data_t * |
- * |------------------------|
- * | local ia64_node_data |
- * |------------------------|
- * | ??? |
- * |________________________|
- *
- * Once this space has been set aside, the bootmem maps are initialized. We
- * could probably move the allocation of the per-cpu and ia64_node_data space
- * outside of this function and use alloc_bootmem_node(), but doing it here
- * is straightforward and we get the alignments we want so...
- */
-static int __init find_pernode_space(unsigned long start, unsigned long len,
- int node)
-{
- unsigned long spfn, epfn;
- unsigned long pernodesize = 0, pernode;
-
- spfn = start >> PAGE_SHIFT;
- epfn = (start + len) >> PAGE_SHIFT;
-
- /*
- * Make sure this memory falls within this node's usable memory
- * since we may have thrown some away in build_maps().
- */
- if (spfn < mem_data[node].min_pfn || epfn > mem_data[node].max_pfn)
- return 0;
-
- /* Don't setup this node's local space twice... */
- if (mem_data[node].pernode_addr)
- return 0;
-
- /*
- * Calculate total size needed, incl. what's necessary
- * for good alignment and alias prevention.
- */
- pernodesize = compute_pernodesize(node);
- pernode = NODEDATA_ALIGN(start, node);
-
- /* Is this range big enough for what we want to store here? */
- if (start + len > (pernode + pernodesize))
- fill_pernode(node, pernode, pernodesize);
-
- return 0;
-}
-
-/**
- * reserve_pernode_space - reserve memory for per-node space
- *
- * Reserve the space used by the bootmem maps & per-node space in the boot
- * allocator so that when we actually create the real mem maps we don't
- * use their memory.
- */
-static void __init reserve_pernode_space(void)
-{
- unsigned long base, size;
- int node;
-
- for_each_online_node(node) {
- if (node_isset(node, memory_less_mask))
- continue;
-
- /* Now the per-node space */
- size = mem_data[node].pernode_size;
- base = __pa(mem_data[node].pernode_addr);
- memblock_reserve(base, size);
- }
-}
-
-static void scatter_node_data(void)
-{
- pg_data_t **dst;
- int node;
-
- /*
- * for_each_online_node() can't be used at here.
- * node_online_map is not set for hot-added nodes at this time,
- * because we are halfway through initialization of the new node's
- * structures. If for_each_online_node() is used, a new node's
- * pg_data_ptrs will be not initialized. Instead of using it,
- * pgdat_list[] is checked.
- */
- for_each_node(node) {
- if (pgdat_list[node]) {
- dst = LOCAL_DATA_ADDR(pgdat_list[node])->pg_data_ptrs;
- memcpy(dst, pgdat_list, sizeof(pgdat_list));
- }
- }
-}
-
-/**
- * initialize_pernode_data - fixup per-cpu & per-node pointers
- *
- * Each node's per-node area has a copy of the global pg_data_t list, so
- * we copy that to each node here, as well as setting the per-cpu pointer
- * to the local node data structure.
- */
-static void __init initialize_pernode_data(void)
-{
- int cpu, node;
-
- scatter_node_data();
-
-#ifdef CONFIG_SMP
- /* Set the node_data pointer for each per-cpu struct */
- for_each_possible_early_cpu(cpu) {
- node = node_cpuid[cpu].nid;
- per_cpu(ia64_cpu_info, cpu).node_data =
- mem_data[node].node_data;
- }
-#else
- {
- struct cpuinfo_ia64 *cpu0_cpu_info;
- cpu = 0;
- node = node_cpuid[cpu].nid;
- cpu0_cpu_info = (struct cpuinfo_ia64 *)(__phys_per_cpu_start +
- ((char *)&ia64_cpu_info - __per_cpu_start));
- cpu0_cpu_info->node_data = mem_data[node].node_data;
- }
-#endif /* CONFIG_SMP */
-}
-
-/**
- * memory_less_node_alloc - * attempt to allocate memory on the best NUMA slit
- * node but fall back to any other node when __alloc_bootmem_node fails
- * for best.
- * @nid: node id
- * @pernodesize: size of this node's pernode data
- */
-static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
-{
- void *ptr = NULL;
- u8 best = 0xff;
- int bestnode = NUMA_NO_NODE, node, anynode = 0;
-
- for_each_online_node(node) {
- if (node_isset(node, memory_less_mask))
- continue;
- else if (node_distance(nid, node) < best) {
- best = node_distance(nid, node);
- bestnode = node;
- }
- anynode = node;
- }
-
- if (bestnode == NUMA_NO_NODE)
- bestnode = anynode;
-
- ptr = memblock_alloc_try_nid(pernodesize, PERCPU_PAGE_SIZE,
- __pa(MAX_DMA_ADDRESS),
- MEMBLOCK_ALLOC_ACCESSIBLE,
- bestnode);
- if (!ptr)
- panic("%s: Failed to allocate %lu bytes align=0x%lx nid=%d from=%lx\n",
- __func__, pernodesize, PERCPU_PAGE_SIZE, bestnode,
- __pa(MAX_DMA_ADDRESS));
-
- return ptr;
-}
-
-/**
- * memory_less_nodes - allocate and initialize CPU only nodes pernode
- * information.
- */
-static void __init memory_less_nodes(void)
-{
- unsigned long pernodesize;
- void *pernode;
- int node;
-
- for_each_node_mask(node, memory_less_mask) {
- pernodesize = compute_pernodesize(node);
- pernode = memory_less_node_alloc(node, pernodesize);
- fill_pernode(node, __pa(pernode), pernodesize);
- }
-
- return;
-}
-
-/**
- * find_memory - walk the EFI memory map and setup the bootmem allocator
- *
- * Called early in boot to setup the bootmem allocator, and to
- * allocate the per-cpu and per-node structures.
- */
-void __init find_memory(void)
-{
- int node;
-
- reserve_memory();
- efi_memmap_walk(filter_memory, register_active_ranges);
-
- if (num_online_nodes() == 0) {
- printk(KERN_ERR "node info missing!\n");
- node_set_online(0);
- }
-
- nodes_or(memory_less_mask, memory_less_mask, node_online_map);
- min_low_pfn = -1;
- max_low_pfn = 0;
-
- /* These actually end up getting called by call_pernode_memory() */
- efi_memmap_walk(filter_rsvd_memory, build_node_maps);
- efi_memmap_walk(filter_rsvd_memory, find_pernode_space);
- efi_memmap_walk(find_max_min_low_pfn, NULL);
-
- for_each_online_node(node)
- if (mem_data[node].min_pfn)
- node_clear(node, memory_less_mask);
-
- reserve_pernode_space();
- memory_less_nodes();
- initialize_pernode_data();
-
- max_pfn = max_low_pfn;
-
- find_initrd();
-}
-
-#ifdef CONFIG_SMP
-/**
- * per_cpu_init - setup per-cpu variables
- *
- * find_pernode_space() does most of this already, we just need to set
- * local_per_cpu_offset
- */
-void *per_cpu_init(void)
-{
- int cpu;
- static int first_time = 1;
-
- if (first_time) {
- first_time = 0;
- for_each_possible_early_cpu(cpu)
- per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
- }
-
- return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
-}
-#endif /* CONFIG_SMP */
-
-/**
- * call_pernode_memory - use SRAT to call callback functions with node info
- * @start: physical start of range
- * @len: length of range
- * @arg: function to call for each range
- *
- * efi_memmap_walk() knows nothing about layout of memory across nodes. Find
- * out to which node a block of memory belongs. Ignore memory that we cannot
- * identify, and split blocks that run across multiple nodes.
- *
- * Take this opportunity to round the start address up and the end address
- * down to page boundaries.
- */
-void call_pernode_memory(unsigned long start, unsigned long len, void *arg)
-{
- unsigned long rs, re, end = start + len;
- void (*func)(unsigned long, unsigned long, int);
- int i;
-
- start = PAGE_ALIGN(start);
- end &= PAGE_MASK;
- if (start >= end)
- return;
-
- func = arg;
-
- if (!num_node_memblks) {
- /* No SRAT table, so assume one node (node 0) */
- if (start < end)
- (*func)(start, end - start, 0);
- return;
- }
-
- for (i = 0; i < num_node_memblks; i++) {
- rs = max(start, node_memblk[i].start_paddr);
- re = min(end, node_memblk[i].start_paddr +
- node_memblk[i].size);
-
- if (rs < re)
- (*func)(rs, re - rs, node_memblk[i].nid);
-
- if (re == end)
- break;
- }
-}
-
-/**
- * paging_init - setup page tables
- *
- * paging_init() sets up the page tables for each node of the system and frees
- * the bootmem allocator memory for general use.
- */
-void __init paging_init(void)
-{
- unsigned long max_dma;
- unsigned long max_zone_pfns[MAX_NR_ZONES];
-
- max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-
- sparse_init();
-
- memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
- max_zone_pfns[ZONE_DMA32] = max_dma;
- max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
- free_area_init(max_zone_pfns);
-
- zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
-}
-
-pg_data_t * __init arch_alloc_nodedata(int nid)
-{
- unsigned long size = compute_pernodesize(nid);
-
- return memblock_alloc(size, SMP_CACHE_BYTES);
-}
-
-void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat)
-{
- pgdat_list[update_node] = update_pgdat;
- scatter_node_data();
-}
-
-#ifdef CONFIG_SPARSEMEM_VMEMMAP
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
- struct vmem_altmap *altmap)
-{
- return vmemmap_populate_basepages(start, end, node, NULL);
-}
-
-void vmemmap_free(unsigned long start, unsigned long end,
- struct vmem_altmap *altmap)
-{
-}
-#endif
diff --git a/arch/ia64/mm/extable.c b/arch/ia64/mm/extable.c
deleted file mode 100644
index da477c11770b..000000000000
--- a/arch/ia64/mm/extable.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Kernel exception handling table support. Derived from arch/alpha/mm/extable.c.
- *
- * Copyright (C) 1998, 1999, 2001-2002, 2004 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <asm/ptrace.h>
-#include <asm/extable.h>
-#include <asm/errno.h>
-#include <asm/processor.h>
-
-void
-ia64_handle_exception (struct pt_regs *regs, const struct exception_table_entry *e)
-{
- long fix = (u64) &e->fixup + e->fixup;
-
- regs->r8 = -EFAULT;
- if (fix & 4)
- regs->r9 = 0;
- regs->cr_iip = fix & ~0xf;
- ia64_psr(regs)->ri = fix & 0x3; /* set continuation slot number */
-}
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
deleted file mode 100644
index 5458b52b4009..000000000000
--- a/arch/ia64/mm/fault.c
+++ /dev/null
@@ -1,251 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * MMU fault handling support.
- *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#include <linux/sched/signal.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/extable.h>
-#include <linux/interrupt.h>
-#include <linux/kprobes.h>
-#include <linux/kdebug.h>
-#include <linux/prefetch.h>
-#include <linux/uaccess.h>
-#include <linux/perf_event.h>
-
-#include <asm/processor.h>
-#include <asm/exception.h>
-
-extern int die(char *, struct pt_regs *, long);
-
-/*
- * Return TRUE if ADDRESS points at a page in the kernel's mapped segment
- * (inside region 5, on ia64) and that page is present.
- */
-static int
-mapped_kernel_page_is_present (unsigned long address)
-{
- pgd_t *pgd;
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *ptep, pte;
-
- pgd = pgd_offset_k(address);
- if (pgd_none(*pgd) || pgd_bad(*pgd))
- return 0;
-
- p4d = p4d_offset(pgd, address);
- if (p4d_none(*p4d) || p4d_bad(*p4d))
- return 0;
-
- pud = pud_offset(p4d, address);
- if (pud_none(*pud) || pud_bad(*pud))
- return 0;
-
- pmd = pmd_offset(pud, address);
- if (pmd_none(*pmd) || pmd_bad(*pmd))
- return 0;
-
- ptep = pte_offset_kernel(pmd, address);
- if (!ptep)
- return 0;
-
- pte = *ptep;
- return pte_present(pte);
-}
-
-# define VM_READ_BIT 0
-# define VM_WRITE_BIT 1
-# define VM_EXEC_BIT 2
-
-void __kprobes
-ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
-{
- int signal = SIGSEGV, code = SEGV_MAPERR;
- struct vm_area_struct *vma, *prev_vma;
- struct mm_struct *mm = current->mm;
- unsigned long mask;
- vm_fault_t fault;
- unsigned int flags = FAULT_FLAG_DEFAULT;
-
- mask = ((((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
- | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
-
- /* mmap_lock is performance critical.... */
- prefetchw(&mm->mmap_lock);
-
- /*
- * If we're in an interrupt or have no user context, we must not take the fault..
- */
- if (faulthandler_disabled() || !mm)
- goto no_context;
-
- /*
- * This is to handle the kprobes on user space access instructions
- */
- if (kprobe_page_fault(regs, TRAP_BRKPT))
- return;
-
- if (user_mode(regs))
- flags |= FAULT_FLAG_USER;
- if (mask & VM_WRITE)
- flags |= FAULT_FLAG_WRITE;
-
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
-retry:
- mmap_read_lock(mm);
-
- vma = find_vma_prev(mm, address, &prev_vma);
- if (!vma && !prev_vma )
- goto bad_area;
-
- /*
- * find_vma_prev() returns vma such that address < vma->vm_end or NULL
- *
- * May find no vma, but could be that the last vm area is the
- * register backing store that needs to expand upwards, in
- * this case vma will be null, but prev_vma will ne non-null
- */
- if (( !vma && prev_vma ) || (address < vma->vm_start) ) {
- vma = expand_stack(mm, address);
- if (!vma)
- goto bad_area_nosemaphore;
- }
-
- code = SEGV_ACCERR;
-
- /* OK, we've got a good vm_area for this memory area. Check the access permissions: */
-
-# if (((1 << VM_READ_BIT) != VM_READ || (1 << VM_WRITE_BIT) != VM_WRITE) \
- || (1 << VM_EXEC_BIT) != VM_EXEC)
-# error File is out of sync with <linux/mm.h>. Please update.
-# endif
-
- if (((isr >> IA64_ISR_R_BIT) & 1UL) && (!(vma->vm_flags & (VM_READ | VM_WRITE))))
- goto bad_area;
-
- if ((vma->vm_flags & mask) != mask)
- goto bad_area;
-
- /*
- * If for any reason at all we couldn't handle the fault, make
- * sure we exit gracefully rather than endlessly redo the
- * fault.
- */
- fault = handle_mm_fault(vma, address, flags, regs);
-
- if (fault_signal_pending(fault, regs)) {
- if (!user_mode(regs))
- goto no_context;
- return;
- }
-
- /* The fault is fully completed (including releasing mmap lock) */
- if (fault & VM_FAULT_COMPLETED)
- return;
-
- if (unlikely(fault & VM_FAULT_ERROR)) {
- /*
- * We ran out of memory, or some other thing happened
- * to us that made us unable to handle the page fault
- * gracefully.
- */
- if (fault & VM_FAULT_OOM) {
- goto out_of_memory;
- } else if (fault & VM_FAULT_SIGSEGV) {
- goto bad_area;
- } else if (fault & VM_FAULT_SIGBUS) {
- signal = SIGBUS;
- goto bad_area;
- }
- BUG();
- }
-
- if (fault & VM_FAULT_RETRY) {
- flags |= FAULT_FLAG_TRIED;
-
- /* No need to mmap_read_unlock(mm) as we would
- * have already released it in __lock_page_or_retry
- * in mm/filemap.c.
- */
-
- goto retry;
- }
-
- mmap_read_unlock(mm);
- return;
-
- bad_area:
- mmap_read_unlock(mm);
- bad_area_nosemaphore:
- if ((isr & IA64_ISR_SP)
- || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
- {
- /*
- * This fault was due to a speculative load or lfetch.fault, set the "ed"
- * bit in the psr to ensure forward progress. (Target register will get a
- * NaT for ld.s, lfetch will be canceled.)
- */
- ia64_psr(regs)->ed = 1;
- return;
- }
- if (user_mode(regs)) {
- force_sig_fault(signal, code, (void __user *) address,
- 0, __ISR_VALID, isr);
- return;
- }
-
- no_context:
- if ((isr & IA64_ISR_SP)
- || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
- {
- /*
- * This fault was due to a speculative load or lfetch.fault, set the "ed"
- * bit in the psr to ensure forward progress. (Target register will get a
- * NaT for ld.s, lfetch will be canceled.)
- */
- ia64_psr(regs)->ed = 1;
- return;
- }
-
- /*
- * Since we have no vma's for region 5, we might get here even if the address is
- * valid, due to the VHPT walker inserting a non present translation that becomes
- * stale. If that happens, the non present fault handler already purged the stale
- * translation, which fixed the problem. So, we check to see if the translation is
- * valid, and return if it is.
- */
- if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address))
- return;
-
- if (ia64_done_with_exception(regs))
- return;
-
- /*
- * Oops. The kernel tried to access some bad page. We'll have to terminate things
- * with extreme prejudice.
- */
- bust_spinlocks(1);
-
- if (address < PAGE_SIZE)
- printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference (address %016lx)\n", address);
- else
- printk(KERN_ALERT "Unable to handle kernel paging request at "
- "virtual address %016lx\n", address);
- if (die("Oops", regs, isr))
- regs = NULL;
- bust_spinlocks(0);
- if (regs)
- make_task_dead(SIGKILL);
- return;
-
- out_of_memory:
- mmap_read_unlock(mm);
- if (!user_mode(regs))
- goto no_context;
- pagefault_out_of_memory();
-}
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
deleted file mode 100644
index adc49f2d22e8..000000000000
--- a/arch/ia64/mm/hugetlbpage.c
+++ /dev/null
@@ -1,186 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * IA-64 Huge TLB Page Support for Kernel.
- *
- * Copyright (C) 2002-2004 Rohit Seth <rohit.seth@intel.com>
- * Copyright (C) 2003-2004 Ken Chen <kenneth.w.chen@intel.com>
- *
- * Sep, 2003: add numa support
- * Feb, 2004: dynamic hugetlb page size via boot parameter
- */
-
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/hugetlb.h>
-#include <linux/pagemap.h>
-#include <linux/module.h>
-#include <linux/sysctl.h>
-#include <linux/log2.h>
-#include <asm/mman.h>
-#include <asm/tlb.h>
-#include <asm/tlbflush.h>
-
-unsigned int hpage_shift = HPAGE_SHIFT_DEFAULT;
-EXPORT_SYMBOL(hpage_shift);
-
-pte_t *
-huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long addr, unsigned long sz)
-{
- unsigned long taddr = htlbpage_to_page(addr);
- pgd_t *pgd;
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte = NULL;
-
- pgd = pgd_offset(mm, taddr);
- p4d = p4d_offset(pgd, taddr);
- pud = pud_alloc(mm, p4d, taddr);
- if (pud) {
- pmd = pmd_alloc(mm, pud, taddr);
- if (pmd)
- pte = pte_alloc_huge(mm, pmd, taddr);
- }
- return pte;
-}
-
-pte_t *
-huge_pte_offset (struct mm_struct *mm, unsigned long addr, unsigned long sz)
-{
- unsigned long taddr = htlbpage_to_page(addr);
- pgd_t *pgd;
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte = NULL;
-
- pgd = pgd_offset(mm, taddr);
- if (pgd_present(*pgd)) {
- p4d = p4d_offset(pgd, taddr);
- if (p4d_present(*p4d)) {
- pud = pud_offset(p4d, taddr);
- if (pud_present(*pud)) {
- pmd = pmd_offset(pud, taddr);
- if (pmd_present(*pmd))
- pte = pte_offset_huge(pmd, taddr);
- }
- }
- }
-
- return pte;
-}
-
-#define mk_pte_huge(entry) { pte_val(entry) |= _PAGE_P; }
-
-/*
- * Don't actually need to do any preparation, but need to make sure
- * the address is in the right region.
- */
-int prepare_hugepage_range(struct file *file,
- unsigned long addr, unsigned long len)
-{
- if (len & ~HPAGE_MASK)
- return -EINVAL;
- if (addr & ~HPAGE_MASK)
- return -EINVAL;
- if (REGION_NUMBER(addr) != RGN_HPAGE)
- return -EINVAL;
-
- return 0;
-}
-
-int pmd_huge(pmd_t pmd)
-{
- return 0;
-}
-
-int pud_huge(pud_t pud)
-{
- return 0;
-}
-
-void hugetlb_free_pgd_range(struct mmu_gather *tlb,
- unsigned long addr, unsigned long end,
- unsigned long floor, unsigned long ceiling)
-{
- /*
- * This is called to free hugetlb page tables.
- *
- * The offset of these addresses from the base of the hugetlb
- * region must be scaled down by HPAGE_SIZE/PAGE_SIZE so that
- * the standard free_pgd_range will free the right page tables.
- *
- * If floor and ceiling are also in the hugetlb region, they
- * must likewise be scaled down; but if outside, left unchanged.
- */
-
- addr = htlbpage_to_page(addr);
- end = htlbpage_to_page(end);
- if (REGION_NUMBER(floor) == RGN_HPAGE)
- floor = htlbpage_to_page(floor);
- if (REGION_NUMBER(ceiling) == RGN_HPAGE)
- ceiling = htlbpage_to_page(ceiling);
-
- free_pgd_range(tlb, addr, end, floor, ceiling);
-}
-
-unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
- unsigned long pgoff, unsigned long flags)
-{
- struct vm_unmapped_area_info info;
-
- if (len > RGN_MAP_LIMIT)
- return -ENOMEM;
- if (len & ~HPAGE_MASK)
- return -EINVAL;
-
- /* Handle MAP_FIXED */
- if (flags & MAP_FIXED) {
- if (prepare_hugepage_range(file, addr, len))
- return -EINVAL;
- return addr;
- }
-
- /* This code assumes that RGN_HPAGE != 0. */
- if ((REGION_NUMBER(addr) != RGN_HPAGE) || (addr & (HPAGE_SIZE - 1)))
- addr = HPAGE_REGION_BASE;
-
- info.flags = 0;
- info.length = len;
- info.low_limit = addr;
- info.high_limit = HPAGE_REGION_BASE + RGN_MAP_LIMIT;
- info.align_mask = PAGE_MASK & (HPAGE_SIZE - 1);
- info.align_offset = 0;
- return vm_unmapped_area(&info);
-}
-
-static int __init hugetlb_setup_sz(char *str)
-{
- u64 tr_pages;
- unsigned long long size;
-
- if (ia64_pal_vm_page_size(&tr_pages, NULL) != 0)
- /*
- * shouldn't happen, but just in case.
- */
- tr_pages = 0x15557000UL;
-
- size = memparse(str, &str);
- if (*str || !is_power_of_2(size) || !(tr_pages & size) ||
- size <= PAGE_SIZE ||
- size > (1UL << PAGE_SHIFT << MAX_ORDER)) {
- printk(KERN_WARNING "Invalid huge page size specified\n");
- return 1;
- }
-
- hpage_shift = __ffs(size);
- /*
- * boot cpu already executed ia64_mmu_init, and has HPAGE_SHIFT_DEFAULT
- * override here with new page shift.
- */
- ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2);
- return 0;
-}
-early_param("hugepagesz", hugetlb_setup_sz);
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
deleted file mode 100644
index 05b0f2f0c073..000000000000
--- a/arch/ia64/mm/init.c
+++ /dev/null
@@ -1,532 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Initialize MMU support.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <linux/dma-map-ops.h>
-#include <linux/dmar.h>
-#include <linux/efi.h>
-#include <linux/elf.h>
-#include <linux/memblock.h>
-#include <linux/mm.h>
-#include <linux/sched/signal.h>
-#include <linux/mmzone.h>
-#include <linux/module.h>
-#include <linux/personality.h>
-#include <linux/reboot.h>
-#include <linux/slab.h>
-#include <linux/swap.h>
-#include <linux/proc_fs.h>
-#include <linux/bitops.h>
-#include <linux/kexec.h>
-#include <linux/swiotlb.h>
-
-#include <asm/dma.h>
-#include <asm/efi.h>
-#include <asm/io.h>
-#include <asm/numa.h>
-#include <asm/patch.h>
-#include <asm/pgalloc.h>
-#include <asm/sal.h>
-#include <asm/sections.h>
-#include <asm/tlb.h>
-#include <linux/uaccess.h>
-#include <asm/unistd.h>
-#include <asm/mca.h>
-
-extern void ia64_tlb_init (void);
-
-unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL;
-
-struct page *zero_page_memmap_ptr; /* map entry for zero page */
-EXPORT_SYMBOL(zero_page_memmap_ptr);
-
-void
-__ia64_sync_icache_dcache (pte_t pte)
-{
- unsigned long addr;
- struct folio *folio;
-
- folio = page_folio(pte_page(pte));
- addr = (unsigned long)folio_address(folio);
-
- if (test_bit(PG_arch_1, &folio->flags))
- return; /* i-cache is already coherent with d-cache */
-
- flush_icache_range(addr, addr + folio_size(folio));
- set_bit(PG_arch_1, &folio->flags); /* mark page as clean */
-}
-
-/*
- * Since DMA is i-cache coherent, any (complete) folios that were written via
- * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to
- * flush them when they get mapped into an executable vm-area.
- */
-void arch_dma_mark_clean(phys_addr_t paddr, size_t size)
-{
- unsigned long pfn = PHYS_PFN(paddr);
- struct folio *folio = page_folio(pfn_to_page(pfn));
- ssize_t left = size;
- size_t offset = offset_in_folio(folio, paddr);
-
- if (offset) {
- left -= folio_size(folio) - offset;
- if (left <= 0)
- return;
- folio = folio_next(folio);
- }
-
- while (left >= (ssize_t)folio_size(folio)) {
- left -= folio_size(folio);
- set_bit(PG_arch_1, &pfn_to_page(pfn)->flags);
- if (!left)
- break;
- folio = folio_next(folio);
- }
-}
-
-inline void
-ia64_set_rbs_bot (void)
-{
- unsigned long stack_size = rlimit_max(RLIMIT_STACK) & -16;
-
- if (stack_size > MAX_USER_STACK_SIZE)
- stack_size = MAX_USER_STACK_SIZE;
- current->thread.rbs_bot = PAGE_ALIGN(current->mm->start_stack - stack_size);
-}
-
-/*
- * This performs some platform-dependent address space initialization.
- * On IA-64, we want to setup the VM area for the register backing
- * store (which grows upwards) and install the gateway page which is
- * used for signal trampolines, etc.
- */
-void
-ia64_init_addr_space (void)
-{
- struct vm_area_struct *vma;
-
- ia64_set_rbs_bot();
-
- /*
- * If we're out of memory and kmem_cache_alloc() returns NULL, we simply ignore
- * the problem. When the process attempts to write to the register backing store
- * for the first time, it will get a SEGFAULT in this case.
- */
- vma = vm_area_alloc(current->mm);
- if (vma) {
- vma_set_anonymous(vma);
- vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
- vma->vm_end = vma->vm_start + PAGE_SIZE;
- vm_flags_init(vma, VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT);
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
- mmap_write_lock(current->mm);
- if (insert_vm_struct(current->mm, vma)) {
- mmap_write_unlock(current->mm);
- vm_area_free(vma);
- return;
- }
- mmap_write_unlock(current->mm);
- }
-
- /* map NaT-page at address zero to speed up speculative dereferencing of NULL: */
- if (!(current->personality & MMAP_PAGE_ZERO)) {
- vma = vm_area_alloc(current->mm);
- if (vma) {
- vma_set_anonymous(vma);
- vma->vm_end = PAGE_SIZE;
- vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
- vm_flags_init(vma, VM_READ | VM_MAYREAD | VM_IO |
- VM_DONTEXPAND | VM_DONTDUMP);
- mmap_write_lock(current->mm);
- if (insert_vm_struct(current->mm, vma)) {
- mmap_write_unlock(current->mm);
- vm_area_free(vma);
- return;
- }
- mmap_write_unlock(current->mm);
- }
- }
-}
-
-void
-free_initmem (void)
-{
- free_reserved_area(ia64_imva(__init_begin), ia64_imva(__init_end),
- -1, "unused kernel");
-}
-
-void __init
-free_initrd_mem (unsigned long start, unsigned long end)
-{
- /*
- * EFI uses 4KB pages while the kernel can use 4KB or bigger.
- * Thus EFI and the kernel may have different page sizes. It is
- * therefore possible to have the initrd share the same page as
- * the end of the kernel (given current setup).
- *
- * To avoid freeing/using the wrong page (kernel sized) we:
- * - align up the beginning of initrd
- * - align down the end of initrd
- *
- * | |
- * |=============| a000
- * | |
- * | |
- * | | 9000
- * |/////////////|
- * |/////////////|
- * |=============| 8000
- * |///INITRD////|
- * |/////////////|
- * |/////////////| 7000
- * | |
- * |KKKKKKKKKKKKK|
- * |=============| 6000
- * |KKKKKKKKKKKKK|
- * |KKKKKKKKKKKKK|
- * K=kernel using 8KB pages
- *
- * In this example, we must free page 8000 ONLY. So we must align up
- * initrd_start and keep initrd_end as is.
- */
- start = PAGE_ALIGN(start);
- end = end & PAGE_MASK;
-
- if (start < end)
- printk(KERN_INFO "Freeing initrd memory: %ldkB freed\n", (end - start) >> 10);
-
- for (; start < end; start += PAGE_SIZE) {
- if (!virt_addr_valid(start))
- continue;
- free_reserved_page(virt_to_page(start));
- }
-}
-
-/*
- * This installs a clean page in the kernel's page table.
- */
-static struct page * __init
-put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
-{
- pgd_t *pgd;
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
-
- pgd = pgd_offset_k(address); /* note: this is NOT pgd_offset()! */
-
- {
- p4d = p4d_alloc(&init_mm, pgd, address);
- if (!p4d)
- goto out;
- pud = pud_alloc(&init_mm, p4d, address);
- if (!pud)
- goto out;
- pmd = pmd_alloc(&init_mm, pud, address);
- if (!pmd)
- goto out;
- pte = pte_alloc_kernel(pmd, address);
- if (!pte)
- goto out;
- if (!pte_none(*pte))
- goto out;
- set_pte(pte, mk_pte(page, pgprot));
- }
- out:
- /* no need for flush_tlb */
- return page;
-}
-
-static void __init
-setup_gate (void)
-{
- struct page *page;
-
- /*
- * Map the gate page twice: once read-only to export the ELF
- * headers etc. and once execute-only page to enable
- * privilege-promotion via "epc":
- */
- page = virt_to_page(ia64_imva(__start_gate_section));
- put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
-#ifdef HAVE_BUGGY_SEGREL
- page = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE));
- put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
-#else
- put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
- /* Fill in the holes (if any) with read-only zero pages: */
- {
- unsigned long addr;
-
- for (addr = GATE_ADDR + PAGE_SIZE;
- addr < GATE_ADDR + PERCPU_PAGE_SIZE;
- addr += PAGE_SIZE)
- {
- put_kernel_page(ZERO_PAGE(0), addr,
- PAGE_READONLY);
- put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE,
- PAGE_READONLY);
- }
- }
-#endif
- ia64_patch_gate();
-}
-
-static struct vm_area_struct gate_vma;
-
-static int __init gate_vma_init(void)
-{
- vma_init(&gate_vma, NULL);
- gate_vma.vm_start = FIXADDR_USER_START;
- gate_vma.vm_end = FIXADDR_USER_END;
- vm_flags_init(&gate_vma, VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC);
- gate_vma.vm_page_prot = __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX);
-
- return 0;
-}
-__initcall(gate_vma_init);
-
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
- return &gate_vma;
-}
-
-int in_gate_area_no_mm(unsigned long addr)
-{
- if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END))
- return 1;
- return 0;
-}
-
-int in_gate_area(struct mm_struct *mm, unsigned long addr)
-{
- return in_gate_area_no_mm(addr);
-}
-
-void ia64_mmu_init(void *my_cpu_data)
-{
- unsigned long pta, impl_va_bits;
- extern void tlb_init(void);
-
-#ifdef CONFIG_DISABLE_VHPT
-# define VHPT_ENABLE_BIT 0
-#else
-# define VHPT_ENABLE_BIT 1
-#endif
-
- /*
- * Check if the virtually mapped linear page table (VMLPT) overlaps with a mapped
- * address space. The IA-64 architecture guarantees that at least 50 bits of
- * virtual address space are implemented but if we pick a large enough page size
- * (e.g., 64KB), the mapped address space is big enough that it will overlap with
- * VMLPT. I assume that once we run on machines big enough to warrant 64KB pages,
- * IMPL_VA_MSB will be significantly bigger, so this is unlikely to become a
- * problem in practice. Alternatively, we could truncate the top of the mapped
- * address space to not permit mappings that would overlap with the VMLPT.
- * --davidm 00/12/06
- */
-# define pte_bits 3
-# define mapped_space_bits (3*(PAGE_SHIFT - pte_bits) + PAGE_SHIFT)
- /*
- * The virtual page table has to cover the entire implemented address space within
- * a region even though not all of this space may be mappable. The reason for
- * this is that the Access bit and Dirty bit fault handlers perform
- * non-speculative accesses to the virtual page table, so the address range of the
- * virtual page table itself needs to be covered by virtual page table.
- */
-# define vmlpt_bits (impl_va_bits - PAGE_SHIFT + pte_bits)
-# define POW2(n) (1ULL << (n))
-
- impl_va_bits = ffz(~(local_cpu_data->unimpl_va_mask | (7UL << 61)));
-
- if (impl_va_bits < 51 || impl_va_bits > 61)
- panic("CPU has bogus IMPL_VA_MSB value of %lu!\n", impl_va_bits - 1);
- /*
- * mapped_space_bits - PAGE_SHIFT is the total number of ptes we need,
- * which must fit into "vmlpt_bits - pte_bits" slots. Second half of
- * the test makes sure that our mapped space doesn't overlap the
- * unimplemented hole in the middle of the region.
- */
- if ((mapped_space_bits - PAGE_SHIFT > vmlpt_bits - pte_bits) ||
- (mapped_space_bits > impl_va_bits - 1))
- panic("Cannot build a big enough virtual-linear page table"
- " to cover mapped address space.\n"
- " Try using a smaller page size.\n");
-
-
- /* place the VMLPT at the end of each page-table mapped region: */
- pta = POW2(61) - POW2(vmlpt_bits);
-
- /*
- * Set the (virtually mapped linear) page table address. Bit
- * 8 selects between the short and long format, bits 2-7 the
- * size of the table, and bit 0 whether the VHPT walker is
- * enabled.
- */
- ia64_set_pta(pta | (0 << 8) | (vmlpt_bits << 2) | VHPT_ENABLE_BIT);
-
- ia64_tlb_init();
-
-#ifdef CONFIG_HUGETLB_PAGE
- ia64_set_rr(HPAGE_REGION_BASE, HPAGE_SHIFT << 2);
- ia64_srlz_d();
-#endif
-}
-
-int __init register_active_ranges(u64 start, u64 len, int nid)
-{
- u64 end = start + len;
-
-#ifdef CONFIG_KEXEC
- if (start > crashk_res.start && start < crashk_res.end)
- start = crashk_res.end;
- if (end > crashk_res.start && end < crashk_res.end)
- end = crashk_res.start;
-#endif
-
- if (start < end)
- memblock_add_node(__pa(start), end - start, nid, MEMBLOCK_NONE);
- return 0;
-}
-
-int
-find_max_min_low_pfn (u64 start, u64 end, void *arg)
-{
- unsigned long pfn_start, pfn_end;
-#ifdef CONFIG_FLATMEM
- pfn_start = (PAGE_ALIGN(__pa(start))) >> PAGE_SHIFT;
- pfn_end = (PAGE_ALIGN(__pa(end - 1))) >> PAGE_SHIFT;
-#else
- pfn_start = GRANULEROUNDDOWN(__pa(start)) >> PAGE_SHIFT;
- pfn_end = GRANULEROUNDUP(__pa(end - 1)) >> PAGE_SHIFT;
-#endif
- min_low_pfn = min(min_low_pfn, pfn_start);
- max_low_pfn = max(max_low_pfn, pfn_end);
- return 0;
-}
-
-/*
- * Boot command-line option "nolwsys" can be used to disable the use of any light-weight
- * system call handler. When this option is in effect, all fsyscalls will end up bubbling
- * down into the kernel and calling the normal (heavy-weight) syscall handler. This is
- * useful for performance testing, but conceivably could also come in handy for debugging
- * purposes.
- */
-
-static int nolwsys __initdata;
-
-static int __init
-nolwsys_setup (char *s)
-{
- nolwsys = 1;
- return 1;
-}
-
-__setup("nolwsys", nolwsys_setup);
-
-void __init
-mem_init (void)
-{
- int i;
-
- BUG_ON(PTRS_PER_PGD * sizeof(pgd_t) != PAGE_SIZE);
- BUG_ON(PTRS_PER_PMD * sizeof(pmd_t) != PAGE_SIZE);
- BUG_ON(PTRS_PER_PTE * sizeof(pte_t) != PAGE_SIZE);
-
- /*
- * This needs to be called _after_ the command line has been parsed but
- * _before_ any drivers that may need the PCI DMA interface are
- * initialized or bootmem has been freed.
- */
- do {
-#ifdef CONFIG_INTEL_IOMMU
- detect_intel_iommu();
- if (iommu_detected)
- break;
-#endif
- swiotlb_init(true, SWIOTLB_VERBOSE);
- } while (0);
-
-#ifdef CONFIG_FLATMEM
- BUG_ON(!mem_map);
-#endif
-
- set_max_mapnr(max_low_pfn);
- high_memory = __va(max_low_pfn * PAGE_SIZE);
- memblock_free_all();
-
- /*
- * For fsyscall entrypoints with no light-weight handler, use the ordinary
- * (heavy-weight) handler, but mark it by setting bit 0, so the fsyscall entry
- * code can tell them apart.
- */
- for (i = 0; i < NR_syscalls; ++i) {
- extern unsigned long fsyscall_table[NR_syscalls];
- extern unsigned long sys_call_table[NR_syscalls];
-
- if (!fsyscall_table[i] || nolwsys)
- fsyscall_table[i] = sys_call_table[i] | 1;
- }
- setup_gate();
-}
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size,
- struct mhp_params *params)
-{
- unsigned long start_pfn = start >> PAGE_SHIFT;
- unsigned long nr_pages = size >> PAGE_SHIFT;
- int ret;
-
- if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot))
- return -EINVAL;
-
- ret = __add_pages(nid, start_pfn, nr_pages, params);
- if (ret)
- printk("%s: Problem encountered in __add_pages() as ret=%d\n",
- __func__, ret);
-
- return ret;
-}
-
-void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
-{
- unsigned long start_pfn = start >> PAGE_SHIFT;
- unsigned long nr_pages = size >> PAGE_SHIFT;
-
- __remove_pages(start_pfn, nr_pages, altmap);
-}
-#endif
-
-static const pgprot_t protection_map[16] = {
- [VM_NONE] = PAGE_NONE,
- [VM_READ] = PAGE_READONLY,
- [VM_WRITE] = PAGE_READONLY,
- [VM_WRITE | VM_READ] = PAGE_READONLY,
- [VM_EXEC] = __pgprot(__ACCESS_BITS | _PAGE_PL_3 |
- _PAGE_AR_X_RX),
- [VM_EXEC | VM_READ] = __pgprot(__ACCESS_BITS | _PAGE_PL_3 |
- _PAGE_AR_RX),
- [VM_EXEC | VM_WRITE] = PAGE_COPY_EXEC,
- [VM_EXEC | VM_WRITE | VM_READ] = PAGE_COPY_EXEC,
- [VM_SHARED] = PAGE_NONE,
- [VM_SHARED | VM_READ] = PAGE_READONLY,
- [VM_SHARED | VM_WRITE] = PAGE_SHARED,
- [VM_SHARED | VM_WRITE | VM_READ] = PAGE_SHARED,
- [VM_SHARED | VM_EXEC] = __pgprot(__ACCESS_BITS | _PAGE_PL_3 |
- _PAGE_AR_X_RX),
- [VM_SHARED | VM_EXEC | VM_READ] = __pgprot(__ACCESS_BITS | _PAGE_PL_3 |
- _PAGE_AR_RX),
- [VM_SHARED | VM_EXEC | VM_WRITE] = __pgprot(__ACCESS_BITS | _PAGE_PL_3 |
- _PAGE_AR_RWX),
- [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = __pgprot(__ACCESS_BITS | _PAGE_PL_3 |
- _PAGE_AR_RWX)
-};
-DECLARE_VM_GET_PAGE_PROT
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c
deleted file mode 100644
index 711b6abc822e..000000000000
--- a/arch/ia64/mm/ioremap.c
+++ /dev/null
@@ -1,94 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * (c) Copyright 2006, 2007 Hewlett-Packard Development Company, L.P.
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- */
-
-#include <linux/compiler.h>
-#include <linux/module.h>
-#include <linux/efi.h>
-#include <linux/io.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <asm/io.h>
-#include <asm/meminit.h>
-
-static inline void __iomem *
-__ioremap_uc(unsigned long phys_addr)
-{
- return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr);
-}
-
-void __iomem *
-early_ioremap (unsigned long phys_addr, unsigned long size)
-{
- u64 attr;
- attr = kern_mem_attribute(phys_addr, size);
- if (attr & EFI_MEMORY_WB)
- return (void __iomem *) phys_to_virt(phys_addr);
- return __ioremap_uc(phys_addr);
-}
-
-void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
- unsigned long flags)
-{
- u64 attr;
- unsigned long gran_base, gran_size;
- unsigned long page_base;
-
- /*
- * For things in kern_memmap, we must use the same attribute
- * as the rest of the kernel. For more details, see
- * Documentation/arch/ia64/aliasing.rst.
- */
- attr = kern_mem_attribute(phys_addr, size);
- if (attr & EFI_MEMORY_WB)
- return (void __iomem *) phys_to_virt(phys_addr);
- else if (attr & EFI_MEMORY_UC)
- return __ioremap_uc(phys_addr);
-
- /*
- * Some chipsets don't support UC access to memory. If
- * WB is supported for the whole granule, we prefer that.
- */
- gran_base = GRANULEROUNDDOWN(phys_addr);
- gran_size = GRANULEROUNDUP(phys_addr + size) - gran_base;
- if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB)
- return (void __iomem *) phys_to_virt(phys_addr);
-
- /*
- * WB is not supported for the whole granule, so we can't use
- * the region 7 identity mapping. If we can safely cover the
- * area with kernel page table mappings, we can use those
- * instead.
- */
- page_base = phys_addr & PAGE_MASK;
- size = PAGE_ALIGN(phys_addr + size) - page_base;
- if (efi_mem_attribute(page_base, size) & EFI_MEMORY_WB)
- return generic_ioremap_prot(phys_addr, size, __pgprot(flags));
-
- return __ioremap_uc(phys_addr);
-}
-EXPORT_SYMBOL(ioremap_prot);
-
-void __iomem *
-ioremap_uc(unsigned long phys_addr, unsigned long size)
-{
- if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB)
- return NULL;
-
- return __ioremap_uc(phys_addr);
-}
-EXPORT_SYMBOL(ioremap_uc);
-
-void
-early_iounmap (volatile void __iomem *addr, unsigned long size)
-{
-}
-
-void iounmap(volatile void __iomem *addr)
-{
- if (REGION_NUMBER(addr) == RGN_GATE)
- vunmap((void *) ((unsigned long) addr & PAGE_MASK));
-}
-EXPORT_SYMBOL(iounmap);
diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c
deleted file mode 100644
index 4c7b1f50e3b7..000000000000
--- a/arch/ia64/mm/numa.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * This file contains NUMA specific variables and functions which are used on
- * NUMA machines with contiguous memory.
- *
- * 2002/08/07 Erich Focht <efocht@ess.nec.de>
- */
-
-#include <linux/cpu.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/node.h>
-#include <linux/init.h>
-#include <linux/memblock.h>
-#include <linux/module.h>
-#include <asm/mmzone.h>
-#include <asm/numa.h>
-
-
-/*
- * The following structures are usually initialized by ACPI or
- * similar mechanisms and describe the NUMA characteristics of the machine.
- */
-int num_node_memblks;
-struct node_memblk_s node_memblk[NR_NODE_MEMBLKS];
-struct node_cpuid_s node_cpuid[NR_CPUS] =
- { [0 ... NR_CPUS-1] = { .phys_id = 0, .nid = NUMA_NO_NODE } };
-
-/*
- * This is a matrix with "distances" between nodes, they should be
- * proportional to the memory access latency ratios.
- */
-u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
-
-int __node_distance(int from, int to)
-{
- return slit_distance(from, to);
-}
-EXPORT_SYMBOL(__node_distance);
-
-/* Identify which cnode a physical address resides on */
-int
-paddr_to_nid(unsigned long paddr)
-{
- int i;
-
- for (i = 0; i < num_node_memblks; i++)
- if (paddr >= node_memblk[i].start_paddr &&
- paddr < node_memblk[i].start_paddr + node_memblk[i].size)
- break;
-
- return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0);
-}
-EXPORT_SYMBOL(paddr_to_nid);
-
-#if defined(CONFIG_SPARSEMEM) && defined(CONFIG_NUMA)
-void numa_clear_node(int cpu)
-{
- unmap_cpu_from_node(cpu, NUMA_NO_NODE);
-}
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-/*
- * SRAT information is stored in node_memblk[], then we can use SRAT
- * information at memory-hot-add if necessary.
- */
-
-int memory_add_physaddr_to_nid(u64 addr)
-{
- int nid = paddr_to_nid(addr);
- if (nid < 0)
- return 0;
- return nid;
-}
-EXPORT_SYMBOL(memory_add_physaddr_to_nid);
-#endif
-#endif
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
deleted file mode 100644
index ca060e7a2a46..000000000000
--- a/arch/ia64/mm/tlb.c
+++ /dev/null
@@ -1,591 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TLB support routines.
- *
- * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 08/02/00 A. Mallick <asit.k.mallick@intel.com>
- * Modified RID allocation for SMP
- * Goutham Rao <goutham.rao@intel.com>
- * IPI based ptc implementation and A-step IPI implementation.
- * Rohit Seth <rohit.seth@intel.com>
- * Ken Chen <kenneth.w.chen@intel.com>
- * Christophe de Dinechin <ddd@hp.com>: Avoid ptc.e on memory allocation
- * Copyright (C) 2007 Intel Corp
- * Fenghua Yu <fenghua.yu@intel.com>
- * Add multiple ptc.g/ptc.ga instruction support in global tlb purge.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/mm.h>
-#include <linux/memblock.h>
-#include <linux/slab.h>
-
-#include <asm/delay.h>
-#include <asm/mmu_context.h>
-#include <asm/pal.h>
-#include <asm/tlbflush.h>
-#include <asm/dma.h>
-#include <asm/processor.h>
-#include <asm/sal.h>
-#include <asm/tlb.h>
-
-static struct {
- u64 mask; /* mask of supported purge page-sizes */
- unsigned long max_bits; /* log2 of largest supported purge page-size */
-} purge;
-
-struct ia64_ctx ia64_ctx = {
- .lock = __SPIN_LOCK_UNLOCKED(ia64_ctx.lock),
- .next = 1,
- .max_ctx = ~0U
-};
-
-DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
-DEFINE_PER_CPU(u8, ia64_tr_num); /*Number of TR slots in current processor*/
-DEFINE_PER_CPU(u8, ia64_tr_used); /*Max Slot number used by kernel*/
-
-struct ia64_tr_entry *ia64_idtrs[NR_CPUS];
-
-/*
- * Initializes the ia64_ctx.bitmap array based on max_ctx+1.
- * Called after cpu_init() has setup ia64_ctx.max_ctx based on
- * maximum RID that is supported by boot CPU.
- */
-void __init
-mmu_context_init (void)
-{
- ia64_ctx.bitmap = memblock_alloc((ia64_ctx.max_ctx + 1) >> 3,
- SMP_CACHE_BYTES);
- if (!ia64_ctx.bitmap)
- panic("%s: Failed to allocate %u bytes\n", __func__,
- (ia64_ctx.max_ctx + 1) >> 3);
- ia64_ctx.flushmap = memblock_alloc((ia64_ctx.max_ctx + 1) >> 3,
- SMP_CACHE_BYTES);
- if (!ia64_ctx.flushmap)
- panic("%s: Failed to allocate %u bytes\n", __func__,
- (ia64_ctx.max_ctx + 1) >> 3);
-}
-
-/*
- * Acquire the ia64_ctx.lock before calling this function!
- */
-void
-wrap_mmu_context (struct mm_struct *mm)
-{
- int i, cpu;
- unsigned long flush_bit;
-
- for (i=0; i <= ia64_ctx.max_ctx / BITS_PER_LONG; i++) {
- flush_bit = xchg(&ia64_ctx.flushmap[i], 0);
- ia64_ctx.bitmap[i] ^= flush_bit;
- }
-
- /* use offset at 300 to skip daemons */
- ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
- ia64_ctx.max_ctx, 300);
- ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
- ia64_ctx.max_ctx, ia64_ctx.next);
-
- /*
- * can't call flush_tlb_all() here because of race condition
- * with O(1) scheduler [EF]
- */
- cpu = get_cpu(); /* prevent preemption/migration */
- for_each_online_cpu(i)
- if (i != cpu)
- per_cpu(ia64_need_tlb_flush, i) = 1;
- put_cpu();
- local_flush_tlb_all();
-}
-
-/*
- * Implement "spinaphores" ... like counting semaphores, but they
- * spin instead of sleeping. If there are ever any other users for
- * this primitive it can be moved up to a spinaphore.h header.
- */
-struct spinaphore {
- unsigned long ticket;
- unsigned long serve;
-};
-
-static inline void spinaphore_init(struct spinaphore *ss, int val)
-{
- ss->ticket = 0;
- ss->serve = val;
-}
-
-static inline void down_spin(struct spinaphore *ss)
-{
- unsigned long t = ia64_fetchadd(1, &ss->ticket, acq), serve;
-
- if (time_before(t, ss->serve))
- return;
-
- ia64_invala();
-
- for (;;) {
- asm volatile ("ld8.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
- if (time_before(t, serve))
- return;
- cpu_relax();
- }
-}
-
-static inline void up_spin(struct spinaphore *ss)
-{
- ia64_fetchadd(1, &ss->serve, rel);
-}
-
-static struct spinaphore ptcg_sem;
-static u16 nptcg = 1;
-static int need_ptcg_sem = 1;
-static int toolatetochangeptcgsem = 0;
-
-/*
- * Kernel parameter "nptcg=" overrides max number of concurrent global TLB
- * purges which is reported from either PAL or SAL PALO.
- *
- * We don't have sanity checking for nptcg value. It's the user's responsibility
- * for valid nptcg value on the platform. Otherwise, kernel may hang in some
- * cases.
- */
-static int __init
-set_nptcg(char *str)
-{
- int value = 0;
-
- get_option(&str, &value);
- setup_ptcg_sem(value, NPTCG_FROM_KERNEL_PARAMETER);
-
- return 1;
-}
-
-__setup("nptcg=", set_nptcg);
-
-/*
- * Maximum number of simultaneous ptc.g purges in the system can
- * be defined by PAL_VM_SUMMARY (in which case we should take
- * the smallest value for any cpu in the system) or by the PAL
- * override table (in which case we should ignore the value from
- * PAL_VM_SUMMARY).
- *
- * Kernel parameter "nptcg=" overrides maximum number of simultaneous ptc.g
- * purges defined in either PAL_VM_SUMMARY or PAL override table. In this case,
- * we should ignore the value from either PAL_VM_SUMMARY or PAL override table.
- *
- * Complicating the logic here is the fact that num_possible_cpus()
- * isn't fully setup until we start bringing cpus online.
- */
-void
-setup_ptcg_sem(int max_purges, int nptcg_from)
-{
- static int kp_override;
- static int palo_override;
- static int firstcpu = 1;
-
- if (toolatetochangeptcgsem) {
- if (nptcg_from == NPTCG_FROM_PAL && max_purges == 0)
- BUG_ON(1 < nptcg);
- else
- BUG_ON(max_purges < nptcg);
- return;
- }
-
- if (nptcg_from == NPTCG_FROM_KERNEL_PARAMETER) {
- kp_override = 1;
- nptcg = max_purges;
- goto resetsema;
- }
- if (kp_override) {
- need_ptcg_sem = num_possible_cpus() > nptcg;
- return;
- }
-
- if (nptcg_from == NPTCG_FROM_PALO) {
- palo_override = 1;
-
- /* In PALO max_purges == 0 really means it! */
- if (max_purges == 0)
- panic("Whoa! Platform does not support global TLB purges.\n");
- nptcg = max_purges;
- if (nptcg == PALO_MAX_TLB_PURGES) {
- need_ptcg_sem = 0;
- return;
- }
- goto resetsema;
- }
- if (palo_override) {
- if (nptcg != PALO_MAX_TLB_PURGES)
- need_ptcg_sem = (num_possible_cpus() > nptcg);
- return;
- }
-
- /* In PAL_VM_SUMMARY max_purges == 0 actually means 1 */
- if (max_purges == 0) max_purges = 1;
-
- if (firstcpu) {
- nptcg = max_purges;
- firstcpu = 0;
- }
- if (max_purges < nptcg)
- nptcg = max_purges;
- if (nptcg == PAL_MAX_PURGES) {
- need_ptcg_sem = 0;
- return;
- } else
- need_ptcg_sem = (num_possible_cpus() > nptcg);
-
-resetsema:
- spinaphore_init(&ptcg_sem, max_purges);
-}
-
-#ifdef CONFIG_SMP
-static void
-ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
- unsigned long end, unsigned long nbits)
-{
- struct mm_struct *active_mm = current->active_mm;
-
- toolatetochangeptcgsem = 1;
-
- if (mm != active_mm) {
- /* Restore region IDs for mm */
- if (mm && active_mm) {
- activate_context(mm);
- } else {
- flush_tlb_all();
- return;
- }
- }
-
- if (need_ptcg_sem)
- down_spin(&ptcg_sem);
-
- do {
- /*
- * Flush ALAT entries also.
- */
- ia64_ptcga(start, (nbits << 2));
- ia64_srlz_i();
- start += (1UL << nbits);
- } while (start < end);
-
- if (need_ptcg_sem)
- up_spin(&ptcg_sem);
-
- if (mm != active_mm) {
- activate_context(active_mm);
- }
-}
-#endif /* CONFIG_SMP */
-
-void
-local_flush_tlb_all (void)
-{
- unsigned long i, j, flags, count0, count1, stride0, stride1, addr;
-
- addr = local_cpu_data->ptce_base;
- count0 = local_cpu_data->ptce_count[0];
- count1 = local_cpu_data->ptce_count[1];
- stride0 = local_cpu_data->ptce_stride[0];
- stride1 = local_cpu_data->ptce_stride[1];
-
- local_irq_save(flags);
- for (i = 0; i < count0; ++i) {
- for (j = 0; j < count1; ++j) {
- ia64_ptce(addr);
- addr += stride1;
- }
- addr += stride0;
- }
- local_irq_restore(flags);
- ia64_srlz_i(); /* srlz.i implies srlz.d */
-}
-
-static void
-__flush_tlb_range (struct vm_area_struct *vma, unsigned long start,
- unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- unsigned long size = end - start;
- unsigned long nbits;
-
-#ifndef CONFIG_SMP
- if (mm != current->active_mm) {
- mm->context = 0;
- return;
- }
-#endif
-
- nbits = ia64_fls(size + 0xfff);
- while (unlikely (((1UL << nbits) & purge.mask) == 0) &&
- (nbits < purge.max_bits))
- ++nbits;
- if (nbits > purge.max_bits)
- nbits = purge.max_bits;
- start &= ~((1UL << nbits) - 1);
-
- preempt_disable();
-#ifdef CONFIG_SMP
- if (mm != current->active_mm || cpumask_weight(mm_cpumask(mm)) != 1) {
- ia64_global_tlb_purge(mm, start, end, nbits);
- preempt_enable();
- return;
- }
-#endif
- do {
- ia64_ptcl(start, (nbits<<2));
- start += (1UL << nbits);
- } while (start < end);
- preempt_enable();
- ia64_srlz_i(); /* srlz.i implies srlz.d */
-}
-
-void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- if (unlikely(end - start >= 1024*1024*1024*1024UL
- || REGION_NUMBER(start) != REGION_NUMBER(end - 1))) {
- /*
- * If we flush more than a tera-byte or across regions, we're
- * probably better off just flushing the entire TLB(s). This
- * should be very rare and is not worth optimizing for.
- */
- flush_tlb_all();
- } else {
- /* flush the address range from the tlb */
- __flush_tlb_range(vma, start, end);
- /* flush the virt. page-table area mapping the addr range */
- __flush_tlb_range(vma, ia64_thash(start), ia64_thash(end));
- }
-}
-EXPORT_SYMBOL(flush_tlb_range);
-
-void ia64_tlb_init(void)
-{
- ia64_ptce_info_t ptce_info;
- u64 tr_pgbits;
- long status;
- pal_vm_info_1_u_t vm_info_1;
- pal_vm_info_2_u_t vm_info_2;
- int cpu = smp_processor_id();
-
- if ((status = ia64_pal_vm_page_size(&tr_pgbits, &purge.mask)) != 0) {
- printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld; "
- "defaulting to architected purge page-sizes.\n", status);
- purge.mask = 0x115557000UL;
- }
- purge.max_bits = ia64_fls(purge.mask);
-
- ia64_get_ptce(&ptce_info);
- local_cpu_data->ptce_base = ptce_info.base;
- local_cpu_data->ptce_count[0] = ptce_info.count[0];
- local_cpu_data->ptce_count[1] = ptce_info.count[1];
- local_cpu_data->ptce_stride[0] = ptce_info.stride[0];
- local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
-
- local_flush_tlb_all(); /* nuke left overs from bootstrapping... */
- status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2);
-
- if (status) {
- printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
- per_cpu(ia64_tr_num, cpu) = 8;
- return;
- }
- per_cpu(ia64_tr_num, cpu) = vm_info_1.pal_vm_info_1_s.max_itr_entry+1;
- if (per_cpu(ia64_tr_num, cpu) >
- (vm_info_1.pal_vm_info_1_s.max_dtr_entry+1))
- per_cpu(ia64_tr_num, cpu) =
- vm_info_1.pal_vm_info_1_s.max_dtr_entry+1;
- if (per_cpu(ia64_tr_num, cpu) > IA64_TR_ALLOC_MAX) {
- static int justonce = 1;
- per_cpu(ia64_tr_num, cpu) = IA64_TR_ALLOC_MAX;
- if (justonce) {
- justonce = 0;
- printk(KERN_DEBUG "TR register number exceeds "
- "IA64_TR_ALLOC_MAX!\n");
- }
- }
-}
-
-/*
- * is_tr_overlap
- *
- * Check overlap with inserted TRs.
- */
-static int is_tr_overlap(struct ia64_tr_entry *p, u64 va, u64 log_size)
-{
- u64 tr_log_size;
- u64 tr_end;
- u64 va_rr = ia64_get_rr(va);
- u64 va_rid = RR_TO_RID(va_rr);
- u64 va_end = va + (1<<log_size) - 1;
-
- if (va_rid != RR_TO_RID(p->rr))
- return 0;
- tr_log_size = (p->itir & 0xff) >> 2;
- tr_end = p->ifa + (1<<tr_log_size) - 1;
-
- if (va > tr_end || p->ifa > va_end)
- return 0;
- return 1;
-
-}
-
-/*
- * ia64_insert_tr in virtual mode. Allocate a TR slot
- *
- * target_mask : 0x1 : itr, 0x2 : dtr, 0x3 : idtr
- *
- * va : virtual address.
- * pte : pte entries inserted.
- * log_size: range to be covered.
- *
- * Return value: <0 : error No.
- *
- * >=0 : slot number allocated for TR.
- * Must be called with preemption disabled.
- */
-int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size)
-{
- int i, r;
- unsigned long psr;
- struct ia64_tr_entry *p;
- int cpu = smp_processor_id();
-
- if (!ia64_idtrs[cpu]) {
- ia64_idtrs[cpu] = kmalloc_array(2 * IA64_TR_ALLOC_MAX,
- sizeof(struct ia64_tr_entry),
- GFP_KERNEL);
- if (!ia64_idtrs[cpu])
- return -ENOMEM;
- }
- r = -EINVAL;
- /*Check overlap with existing TR entries*/
- if (target_mask & 0x1) {
- p = ia64_idtrs[cpu];
- for (i = IA64_TR_ALLOC_BASE; i <= per_cpu(ia64_tr_used, cpu);
- i++, p++) {
- if (p->pte & 0x1)
- if (is_tr_overlap(p, va, log_size)) {
- printk(KERN_DEBUG "Overlapped Entry"
- "Inserted for TR Register!!\n");
- goto out;
- }
- }
- }
- if (target_mask & 0x2) {
- p = ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX;
- for (i = IA64_TR_ALLOC_BASE; i <= per_cpu(ia64_tr_used, cpu);
- i++, p++) {
- if (p->pte & 0x1)
- if (is_tr_overlap(p, va, log_size)) {
- printk(KERN_DEBUG "Overlapped Entry"
- "Inserted for TR Register!!\n");
- goto out;
- }
- }
- }
-
- for (i = IA64_TR_ALLOC_BASE; i < per_cpu(ia64_tr_num, cpu); i++) {
- switch (target_mask & 0x3) {
- case 1:
- if (!((ia64_idtrs[cpu] + i)->pte & 0x1))
- goto found;
- continue;
- case 2:
- if (!((ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i)->pte & 0x1))
- goto found;
- continue;
- case 3:
- if (!((ia64_idtrs[cpu] + i)->pte & 0x1) &&
- !((ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i)->pte & 0x1))
- goto found;
- continue;
- default:
- r = -EINVAL;
- goto out;
- }
- }
-found:
- if (i >= per_cpu(ia64_tr_num, cpu))
- return -EBUSY;
-
- /*Record tr info for mca handler use!*/
- if (i > per_cpu(ia64_tr_used, cpu))
- per_cpu(ia64_tr_used, cpu) = i;
-
- psr = ia64_clear_ic();
- if (target_mask & 0x1) {
- ia64_itr(0x1, i, va, pte, log_size);
- ia64_srlz_i();
- p = ia64_idtrs[cpu] + i;
- p->ifa = va;
- p->pte = pte;
- p->itir = log_size << 2;
- p->rr = ia64_get_rr(va);
- }
- if (target_mask & 0x2) {
- ia64_itr(0x2, i, va, pte, log_size);
- ia64_srlz_i();
- p = ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i;
- p->ifa = va;
- p->pte = pte;
- p->itir = log_size << 2;
- p->rr = ia64_get_rr(va);
- }
- ia64_set_psr(psr);
- r = i;
-out:
- return r;
-}
-EXPORT_SYMBOL_GPL(ia64_itr_entry);
-
-/*
- * ia64_purge_tr
- *
- * target_mask: 0x1: purge itr, 0x2 : purge dtr, 0x3 purge idtr.
- * slot: slot number to be freed.
- *
- * Must be called with preemption disabled.
- */
-void ia64_ptr_entry(u64 target_mask, int slot)
-{
- int cpu = smp_processor_id();
- int i;
- struct ia64_tr_entry *p;
-
- if (slot < IA64_TR_ALLOC_BASE || slot >= per_cpu(ia64_tr_num, cpu))
- return;
-
- if (target_mask & 0x1) {
- p = ia64_idtrs[cpu] + slot;
- if ((p->pte&0x1) && is_tr_overlap(p, p->ifa, p->itir>>2)) {
- p->pte = 0;
- ia64_ptr(0x1, p->ifa, p->itir>>2);
- ia64_srlz_i();
- }
- }
-
- if (target_mask & 0x2) {
- p = ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + slot;
- if ((p->pte & 0x1) && is_tr_overlap(p, p->ifa, p->itir>>2)) {
- p->pte = 0;
- ia64_ptr(0x2, p->ifa, p->itir>>2);
- ia64_srlz_i();
- }
- }
-
- for (i = per_cpu(ia64_tr_used, cpu); i >= IA64_TR_ALLOC_BASE; i--) {
- if (((ia64_idtrs[cpu] + i)->pte & 0x1) ||
- ((ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i)->pte & 0x1))
- break;
- }
- per_cpu(ia64_tr_used, cpu) = i;
-}
-EXPORT_SYMBOL_GPL(ia64_ptr_entry);
diff --git a/arch/ia64/pci/Makefile b/arch/ia64/pci/Makefile
deleted file mode 100644
index 81ea50eeb527..000000000000
--- a/arch/ia64/pci/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the ia64-specific parts of the pci bus
-#
-obj-y := pci.o fixup.o
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
deleted file mode 100644
index 2bcdd7d3a1ad..000000000000
--- a/arch/ia64/pci/fixup.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
- * Derived from fixup.c of i386 tree.
- */
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/vgaarb.h>
-#include <linux/screen_info.h>
-#include <asm/uv/uv.h>
-
-/*
- * Fixup to mark boot BIOS video selected by BIOS before it changes
- *
- * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
- *
- * The standard boot ROM sequence for an x86 machine uses the BIOS
- * to select an initial video card for boot display. This boot video
- * card will have its BIOS copied to 0xC0000 in system RAM.
- * IORESOURCE_ROM_SHADOW is used to associate the boot video
- * card with this copy. On laptops this copy has to be used since
- * the main ROM may be compressed or combined with another image.
- * See pci_map_rom() for use of this flag. Before marking the device
- * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set
- * by either arch code or vga-arbitration; if so only apply the fixup to this
- * already-determined primary video card.
- */
-
-static void pci_fixup_video(struct pci_dev *pdev)
-{
- struct pci_dev *bridge;
- struct pci_bus *bus;
- u16 config;
- struct resource *res;
-
- if (is_uv_system())
- return;
- /* Maybe, this machine supports legacy memory map. */
-
- /* Is VGA routed to us? */
- bus = pdev->bus;
- while (bus) {
- bridge = bus->self;
-
- /*
- * From information provided by
- * "David Miller" <davem@davemloft.net>
- * The bridge control register is valid for PCI header
- * type BRIDGE, or CARDBUS. Host to PCI controllers use
- * PCI header type NORMAL.
- */
- if (bridge && (pci_is_bridge(bridge))) {
- pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
- &config);
- if (!(config & PCI_BRIDGE_CTL_VGA))
- return;
- }
- bus = bus->parent;
- }
- if (!vga_default_device() || pdev == vga_default_device()) {
- pci_read_config_word(pdev, PCI_COMMAND, &config);
- if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
- res = &pdev->resource[PCI_ROM_RESOURCE];
-
- pci_disable_rom(pdev);
- if (res->parent)
- release_resource(res);
-
- res->start = 0xC0000;
- res->end = res->start + 0x20000 - 1;
- res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
- IORESOURCE_PCI_FIXED;
- dev_info(&pdev->dev, "Video device with shadowed ROM at %pR\n",
- res);
- }
- }
-}
-DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video);
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
deleted file mode 100644
index 0a0328e61bef..000000000000
--- a/arch/ia64/pci/pci.c
+++ /dev/null
@@ -1,576 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * pci.c - Low-Level PCI Access in IA-64
- *
- * Derived from bios32.c of i386 tree.
- *
- * (c) Copyright 2002, 2005 Hewlett-Packard Development Company, L.P.
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- * Copyright (C) 2004 Silicon Graphics, Inc.
- *
- * Note: Above list of copyright holders is incomplete...
- */
-
-#include <linux/acpi.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/pci-acpi.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/memblock.h>
-#include <linux/export.h>
-
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/sal.h>
-#include <asm/smp.h>
-#include <asm/irq.h>
-#include <asm/hw_irq.h>
-
-/*
- * Low-level SAL-based PCI configuration access functions. Note that SAL
- * calls are already serialized (via sal_lock), so we don't need another
- * synchronization mechanism here.
- */
-
-#define PCI_SAL_ADDRESS(seg, bus, devfn, reg) \
- (((u64) seg << 24) | (bus << 16) | (devfn << 8) | (reg))
-
-/* SAL 3.2 adds support for extended config space. */
-
-#define PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg) \
- (((u64) seg << 28) | (bus << 20) | (devfn << 12) | (reg))
-
-int raw_pci_read(unsigned int seg, unsigned int bus, unsigned int devfn,
- int reg, int len, u32 *value)
-{
- u64 addr, data = 0;
- int mode, result;
-
- if (!value || (seg > 65535) || (bus > 255) || (devfn > 255) || (reg > 4095))
- return -EINVAL;
-
- if ((seg | reg) <= 255) {
- addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg);
- mode = 0;
- } else if (sal_revision >= SAL_VERSION_CODE(3,2)) {
- addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg);
- mode = 1;
- } else {
- return -EINVAL;
- }
-
- result = ia64_sal_pci_config_read(addr, mode, len, &data);
- if (result != 0)
- return -EINVAL;
-
- *value = (u32) data;
- return 0;
-}
-
-int raw_pci_write(unsigned int seg, unsigned int bus, unsigned int devfn,
- int reg, int len, u32 value)
-{
- u64 addr;
- int mode, result;
-
- if ((seg > 65535) || (bus > 255) || (devfn > 255) || (reg > 4095))
- return -EINVAL;
-
- if ((seg | reg) <= 255) {
- addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg);
- mode = 0;
- } else if (sal_revision >= SAL_VERSION_CODE(3,2)) {
- addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg);
- mode = 1;
- } else {
- return -EINVAL;
- }
- result = ia64_sal_pci_config_write(addr, mode, len, value);
- if (result != 0)
- return -EINVAL;
- return 0;
-}
-
-static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 *value)
-{
- return raw_pci_read(pci_domain_nr(bus), bus->number,
- devfn, where, size, value);
-}
-
-static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 value)
-{
- return raw_pci_write(pci_domain_nr(bus), bus->number,
- devfn, where, size, value);
-}
-
-struct pci_ops pci_root_ops = {
- .read = pci_read,
- .write = pci_write,
-};
-
-struct pci_root_info {
- struct acpi_pci_root_info common;
- struct pci_controller controller;
- struct list_head io_resources;
-};
-
-static unsigned int new_space(u64 phys_base, int sparse)
-{
- u64 mmio_base;
- int i;
-
- if (phys_base == 0)
- return 0; /* legacy I/O port space */
-
- mmio_base = (u64) ioremap(phys_base, 0);
- for (i = 0; i < num_io_spaces; i++)
- if (io_space[i].mmio_base == mmio_base &&
- io_space[i].sparse == sparse)
- return i;
-
- if (num_io_spaces == MAX_IO_SPACES) {
- pr_err("PCI: Too many IO port spaces "
- "(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
- return ~0;
- }
-
- i = num_io_spaces++;
- io_space[i].mmio_base = mmio_base;
- io_space[i].sparse = sparse;
-
- return i;
-}
-
-static int add_io_space(struct device *dev, struct pci_root_info *info,
- struct resource_entry *entry)
-{
- struct resource_entry *iospace;
- struct resource *resource, *res = entry->res;
- char *name;
- unsigned long base, min, max, base_port;
- unsigned int sparse = 0, space_nr, len;
-
- len = strlen(info->common.name) + 32;
- iospace = resource_list_create_entry(NULL, len);
- if (!iospace) {
- dev_err(dev, "PCI: No memory for %s I/O port space\n",
- info->common.name);
- return -ENOMEM;
- }
-
- if (res->flags & IORESOURCE_IO_SPARSE)
- sparse = 1;
- space_nr = new_space(entry->offset, sparse);
- if (space_nr == ~0)
- goto free_resource;
-
- name = (char *)(iospace + 1);
- min = res->start - entry->offset;
- max = res->end - entry->offset;
- base = __pa(io_space[space_nr].mmio_base);
- base_port = IO_SPACE_BASE(space_nr);
- snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->common.name,
- base_port + min, base_port + max);
-
- /*
- * The SDM guarantees the legacy 0-64K space is sparse, but if the
- * mapping is done by the processor (not the bridge), ACPI may not
- * mark it as sparse.
- */
- if (space_nr == 0)
- sparse = 1;
-
- resource = iospace->res;
- resource->name = name;
- resource->flags = IORESOURCE_MEM;
- resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
- resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
- if (insert_resource(&iomem_resource, resource)) {
- dev_err(dev,
- "can't allocate host bridge io space resource %pR\n",
- resource);
- goto free_resource;
- }
-
- entry->offset = base_port;
- res->start = min + base_port;
- res->end = max + base_port;
- resource_list_add_tail(iospace, &info->io_resources);
-
- return 0;
-
-free_resource:
- resource_list_free_entry(iospace);
- return -ENOSPC;
-}
-
-/*
- * An IO port or MMIO resource assigned to a PCI host bridge may be
- * consumed by the host bridge itself or available to its child
- * bus/devices. The ACPI specification defines a bit (Producer/Consumer)
- * to tell whether the resource is consumed by the host bridge itself,
- * but firmware hasn't used that bit consistently, so we can't rely on it.
- *
- * On x86 and IA64 platforms, all IO port and MMIO resources are assumed
- * to be available to child bus/devices except one special case:
- * IO port [0xCF8-0xCFF] is consumed by the host bridge itself
- * to access PCI configuration space.
- *
- * So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF].
- */
-static bool resource_is_pcicfg_ioport(struct resource *res)
-{
- return (res->flags & IORESOURCE_IO) &&
- res->start == 0xCF8 && res->end == 0xCFF;
-}
-
-static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
-{
- struct device *dev = &ci->bridge->dev;
- struct pci_root_info *info;
- struct resource *res;
- struct resource_entry *entry, *tmp;
- int status;
-
- status = acpi_pci_probe_root_resources(ci);
- if (status > 0) {
- info = container_of(ci, struct pci_root_info, common);
- resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
- res = entry->res;
- if (res->flags & IORESOURCE_MEM) {
- /*
- * HP's firmware has a hack to work around a
- * Windows bug. Ignore these tiny memory ranges.
- */
- if (resource_size(res) <= 16) {
- resource_list_del(entry);
- insert_resource(&iomem_resource,
- entry->res);
- resource_list_add_tail(entry,
- &info->io_resources);
- }
- } else if (res->flags & IORESOURCE_IO) {
- if (resource_is_pcicfg_ioport(entry->res))
- resource_list_destroy_entry(entry);
- else if (add_io_space(dev, info, entry))
- resource_list_destroy_entry(entry);
- }
- }
- }
-
- return status;
-}
-
-static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
-{
- struct pci_root_info *info;
- struct resource_entry *entry, *tmp;
-
- info = container_of(ci, struct pci_root_info, common);
- resource_list_for_each_entry_safe(entry, tmp, &info->io_resources) {
- release_resource(entry->res);
- resource_list_destroy_entry(entry);
- }
- kfree(info);
-}
-
-static struct acpi_pci_root_ops pci_acpi_root_ops = {
- .pci_ops = &pci_root_ops,
- .release_info = pci_acpi_root_release_info,
- .prepare_resources = pci_acpi_root_prepare_resources,
-};
-
-struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
-{
- struct acpi_device *device = root->device;
- struct pci_root_info *info;
-
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info) {
- dev_err(&device->dev,
- "pci_bus %04x:%02x: ignored (out of memory)\n",
- root->segment, (int)root->secondary.start);
- return NULL;
- }
-
- info->controller.segment = root->segment;
- info->controller.companion = device;
- info->controller.node = acpi_get_node(device->handle);
- INIT_LIST_HEAD(&info->io_resources);
- return acpi_pci_root_create(root, &pci_acpi_root_ops,
- &info->common, &info->controller);
-}
-
-int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
-{
- /*
- * We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
- * here, pci_create_root_bus() has been called by someone else and
- * sysdata is likely to be different from what we expect. Let it go in
- * that case.
- */
- if (!bridge->dev.parent) {
- struct pci_controller *controller = bridge->bus->sysdata;
- ACPI_COMPANION_SET(&bridge->dev, controller->companion);
- }
- return 0;
-}
-
-void pcibios_fixup_device_resources(struct pci_dev *dev)
-{
- int idx;
-
- if (!dev->bus)
- return;
-
- for (idx = 0; idx < PCI_BRIDGE_RESOURCES; idx++) {
- struct resource *r = &dev->resource[idx];
-
- if (!r->flags || r->parent || !r->start)
- continue;
-
- pci_claim_resource(dev, idx);
- }
-}
-EXPORT_SYMBOL_GPL(pcibios_fixup_device_resources);
-
-static void pcibios_fixup_bridge_resources(struct pci_dev *dev)
-{
- int idx;
-
- if (!dev->bus)
- return;
-
- for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
- struct resource *r = &dev->resource[idx];
-
- if (!r->flags || r->parent || !r->start)
- continue;
-
- pci_claim_bridge_resource(dev, idx);
- }
-}
-
-/*
- * Called after each bus is probed, but before its children are examined.
- */
-void pcibios_fixup_bus(struct pci_bus *b)
-{
- struct pci_dev *dev;
-
- if (b->self) {
- pci_read_bridge_bases(b);
- pcibios_fixup_bridge_resources(b->self);
- }
- list_for_each_entry(dev, &b->devices, bus_list)
- pcibios_fixup_device_resources(dev);
-}
-
-void pcibios_add_bus(struct pci_bus *bus)
-{
- acpi_pci_add_bus(bus);
-}
-
-void pcibios_remove_bus(struct pci_bus *bus)
-{
- acpi_pci_remove_bus(bus);
-}
-
-void pcibios_set_master (struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-
-int
-pcibios_enable_device (struct pci_dev *dev, int mask)
-{
- int ret;
-
- ret = pci_enable_resources(dev, mask);
- if (ret < 0)
- return ret;
-
- if (!pci_dev_msi_enabled(dev))
- return acpi_pci_irq_enable(dev);
- return 0;
-}
-
-void
-pcibios_disable_device (struct pci_dev *dev)
-{
- BUG_ON(atomic_read(&dev->enable_cnt));
- if (!pci_dev_msi_enabled(dev))
- acpi_pci_irq_disable(dev);
-}
-
-/**
- * pci_get_legacy_mem - generic legacy mem routine
- * @bus: bus to get legacy memory base address for
- *
- * Find the base of legacy memory for @bus. This is typically the first
- * megabyte of bus address space for @bus or is simply 0 on platforms whose
- * chipsets support legacy I/O and memory routing. Returns the base address
- * or an error pointer if an error occurred.
- *
- * This is the ia64 generic version of this routine. Other platforms
- * are free to override it with a machine vector.
- */
-char *pci_get_legacy_mem(struct pci_bus *bus)
-{
- return (char *)__IA64_UNCACHED_OFFSET;
-}
-
-/**
- * pci_mmap_legacy_page_range - map legacy memory space to userland
- * @bus: bus whose legacy space we're mapping
- * @vma: vma passed in by mmap
- *
- * Map legacy memory space for this device back to userspace using a machine
- * vector to get the base address.
- */
-int
-pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
- enum pci_mmap_state mmap_state)
-{
- unsigned long size = vma->vm_end - vma->vm_start;
- pgprot_t prot;
- char *addr;
-
- /* We only support mmap'ing of legacy memory space */
- if (mmap_state != pci_mmap_mem)
- return -ENOSYS;
-
- /*
- * Avoid attribute aliasing. See Documentation/arch/ia64/aliasing.rst
- * for more details.
- */
- if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
- return -EINVAL;
- prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size,
- vma->vm_page_prot);
-
- addr = pci_get_legacy_mem(bus);
- if (IS_ERR(addr))
- return PTR_ERR(addr);
-
- vma->vm_pgoff += (unsigned long)addr >> PAGE_SHIFT;
- vma->vm_page_prot = prot;
-
- if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
- size, vma->vm_page_prot))
- return -EAGAIN;
-
- return 0;
-}
-
-/**
- * pci_legacy_read - read from legacy I/O space
- * @bus: bus to read
- * @port: legacy port value
- * @val: caller allocated storage for returned value
- * @size: number of bytes to read
- *
- * Simply reads @size bytes from @port and puts the result in @val.
- *
- * Again, this (and the write routine) are generic versions that can be
- * overridden by the platform. This is necessary on platforms that don't
- * support legacy I/O routing or that hard fail on legacy I/O timeouts.
- */
-int pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
-{
- int ret = size;
-
- switch (size) {
- case 1:
- *val = inb(port);
- break;
- case 2:
- *val = inw(port);
- break;
- case 4:
- *val = inl(port);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-/**
- * pci_legacy_write - perform a legacy I/O write
- * @bus: bus pointer
- * @port: port to write
- * @val: value to write
- * @size: number of bytes to write from @val
- *
- * Simply writes @size bytes of @val to @port.
- */
-int pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
-{
- int ret = size;
-
- switch (size) {
- case 1:
- outb(val, port);
- break;
- case 2:
- outw(val, port);
- break;
- case 4:
- outl(val, port);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-/**
- * set_pci_cacheline_size - determine cacheline size for PCI devices
- *
- * We want to use the line-size of the outer-most cache. We assume
- * that this line-size is the same for all CPUs.
- *
- * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
- */
-static void __init set_pci_dfl_cacheline_size(void)
-{
- unsigned long levels, unique_caches;
- long status;
- pal_cache_config_info_t cci;
-
- status = ia64_pal_cache_summary(&levels, &unique_caches);
- if (status != 0) {
- pr_err("%s: ia64_pal_cache_summary() failed "
- "(status=%ld)\n", __func__, status);
- return;
- }
-
- status = ia64_pal_cache_config_info(levels - 1,
- /* cache_type (data_or_unified)= */ 2, &cci);
- if (status != 0) {
- pr_err("%s: ia64_pal_cache_config_info() failed "
- "(status=%ld)\n", __func__, status);
- return;
- }
- pci_dfl_cache_line_size = (1 << cci.pcci_line_size) / 4;
-}
-
-static int __init pcibios_init(void)
-{
- set_pci_dfl_cacheline_size();
- return 0;
-}
-
-subsys_initcall(pcibios_init);
diff --git a/arch/ia64/scripts/check-gas b/arch/ia64/scripts/check-gas
deleted file mode 100755
index 787cf9b6b04a..000000000000
--- a/arch/ia64/scripts/check-gas
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-dir=$(dirname $0)
-CC=$1
-OBJDUMP=$2
-tmp=${TMPDIR:-/tmp}
-out=$tmp/out$$.o
-$CC -c $dir/check-gas-asm.S -o $out
-res=$($OBJDUMP -r --section .data $out | fgrep 00004 | tr -s ' ' |cut -f3 -d' ')
-rm -f $out
-if [ $res != ".text" ]; then
- echo buggy
-else
- echo good
-fi
-exit 0
diff --git a/arch/ia64/scripts/check-gas-asm.S b/arch/ia64/scripts/check-gas-asm.S
deleted file mode 100644
index 010e1d227e5d..000000000000
--- a/arch/ia64/scripts/check-gas-asm.S
+++ /dev/null
@@ -1,2 +0,0 @@
-[1:] nop 0
- .xdata4 ".data", 0, 1b-.
diff --git a/arch/ia64/scripts/check-model.c b/arch/ia64/scripts/check-model.c
deleted file mode 100644
index e1d4e86e3d63..000000000000
--- a/arch/ia64/scripts/check-model.c
+++ /dev/null
@@ -1 +0,0 @@
-int __attribute__ ((__model__ (__small__))) x;
diff --git a/arch/ia64/scripts/check-segrel.S b/arch/ia64/scripts/check-segrel.S
deleted file mode 100644
index 65d6378adaaa..000000000000
--- a/arch/ia64/scripts/check-segrel.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
- .rodata
- data4 @segrel(start)
- .data
-start:
diff --git a/arch/ia64/scripts/check-segrel.lds b/arch/ia64/scripts/check-segrel.lds
deleted file mode 100644
index c385d246e458..000000000000
--- a/arch/ia64/scripts/check-segrel.lds
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-SECTIONS {
- . = SIZEOF_HEADERS;
- .rodata : { *(.rodata) } :ro
- .note : { *(.note*) }
- . = 0xa0000;
- .data : { *(.data) } :dat
- /DISCARD/ : { *(*) }
-}
-PHDRS {
- ro PT_LOAD FILEHDR PHDRS;
- dat PT_LOAD;
-}
diff --git a/arch/ia64/scripts/check-serialize.S b/arch/ia64/scripts/check-serialize.S
deleted file mode 100644
index 0400c106806c..000000000000
--- a/arch/ia64/scripts/check-serialize.S
+++ /dev/null
@@ -1,2 +0,0 @@
- .serialize.data
- .serialize.instruction
diff --git a/arch/ia64/scripts/check-text-align.S b/arch/ia64/scripts/check-text-align.S
deleted file mode 100644
index 107fa1c88c2e..000000000000
--- a/arch/ia64/scripts/check-text-align.S
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
- .proc foo
- .prologue
-foo: .save rp, r2
- nop 0
- .align 64
- .endp foo
diff --git a/arch/ia64/scripts/toolchain-flags b/arch/ia64/scripts/toolchain-flags
deleted file mode 100755
index 12dff5c981cf..000000000000
--- a/arch/ia64/scripts/toolchain-flags
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Check whether linker can handle cross-segment @segrel():
-#
-CPPFLAGS=""
-CC=$1
-OBJDUMP=$2
-READELF=$3
-dir=$(dirname $0)
-tmp=${TMPDIR:-/tmp}
-out=$tmp/out$$
-
-# Check whether cross-segment segment-relative relocs work fine. We need
-# that for building the gate DSO:
-
-$CC -nostdlib -static -Wl,-T$dir/check-segrel.lds $dir/check-segrel.S -o $out
-res=$($OBJDUMP --full --section .rodata $out | fgrep 000 | cut -f3 -d' ')
-rm -f $out
-if [ $res != 00000a00 ]; then
- CPPFLAGS="$CPPFLAGS -DHAVE_BUGGY_SEGREL"
- cat >&2 <<EOF
-warning: your linker cannot handle cross-segment segment-relative relocations.
- please upgrade to a newer version (it is safe to use this linker, but
- the kernel will be bigger than strictly necessary).
-EOF
-fi
-
-# Check whether .align inside a function works as expected.
-
-$CC -c $dir/check-text-align.S -o $out
-$READELF -u $out | fgrep -q 'prologue(rlen=12)'
-res=$?
-rm -f $out
-if [ $res -eq 0 ]; then
- CPPFLAGS="$CPPFLAGS -DHAVE_WORKING_TEXT_ALIGN"
-fi
-
-if ! $CC -c $dir/check-model.c -o $out 2>&1 | grep __model__ | grep -q attrib
-then
- CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE"
-fi
-rm -f $out
-
-# Check whether assembler supports .serialize.{data,instruction} directive.
-
-$CC -c $dir/check-serialize.S -o $out 2>/dev/null
-res=$?
-rm -f $out
-if [ $res -eq 0 ]; then
- CPPFLAGS="$CPPFLAGS -DHAVE_SERIALIZE_DIRECTIVE"
-fi
-
-echo $CPPFLAGS
diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py
deleted file mode 100644
index 9581742f0db2..000000000000
--- a/arch/ia64/scripts/unwcheck.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0
-#
-# Usage: unwcheck.py FILE
-#
-# This script checks the unwind info of each function in file FILE
-# and verifies that the sum of the region-lengths matches the total
-# length of the function.
-#
-# Based on a shell/awk script originally written by Harish Patil,
-# which was converted to Perl by Matthew Chapman, which was converted
-# to Python by David Mosberger.
-#
-import os
-import re
-import sys
-
-if len(sys.argv) != 2:
- print("Usage: %s FILE" % sys.argv[0])
- sys.exit(2)
-
-readelf = os.getenv("READELF", "readelf")
-
-start_pattern = re.compile("<([^>]*)>: \[0x([0-9a-f]+)-0x([0-9a-f]+)\]")
-rlen_pattern = re.compile(".*rlen=([0-9]+)")
-
-def check_func (func, slots, rlen_sum):
- if slots != rlen_sum:
- global num_errors
- num_errors += 1
- if not func: func = "[%#x-%#x]" % (start, end)
- print("ERROR: %s: %lu slots, total region length = %lu" % (func, slots, rlen_sum))
- return
-
-num_funcs = 0
-num_errors = 0
-func = False
-slots = 0
-rlen_sum = 0
-for line in os.popen("%s -u %s" % (readelf, sys.argv[1])):
- m = start_pattern.match(line)
- if m:
- check_func(func, slots, rlen_sum)
-
- func = m.group(1)
- start = int(m.group(2), 16)
- end = int(m.group(3), 16)
- slots = 3 * (end - start) / 16
- rlen_sum = 0
- num_funcs += 1
- else:
- m = rlen_pattern.match(line)
- if m:
- rlen_sum += int(m.group(1))
-check_func(func, slots, rlen_sum)
-
-if num_errors == 0:
- print("No errors detected in %u functions." % num_funcs)
-else:
- if num_errors > 1:
- err="errors"
- else:
- err="error"
- print("%u %s detected in %u functions." % (num_errors, err, num_funcs))
- sys.exit(1)
diff --git a/arch/ia64/uv/Makefile b/arch/ia64/uv/Makefile
deleted file mode 100644
index aa9f91947c49..000000000000
--- a/arch/ia64/uv/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# arch/ia64/uv/Makefile
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License. See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 2008 Silicon Graphics, Inc. All Rights Reserved.
-#
-# Makefile for the sn uv subplatform
-#
-
-obj-y += kernel/
diff --git a/arch/ia64/uv/kernel/Makefile b/arch/ia64/uv/kernel/Makefile
deleted file mode 100644
index 297196578d19..000000000000
--- a/arch/ia64/uv/kernel/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# arch/ia64/uv/kernel/Makefile
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License. See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 2008 Silicon Graphics, Inc. All Rights Reserved.
-#
-
-ccflags-y := -Iarch/ia64/sn/include
-
-obj-y += setup.o
diff --git a/arch/ia64/uv/kernel/setup.c b/arch/ia64/uv/kernel/setup.c
deleted file mode 100644
index bb025486d791..000000000000
--- a/arch/ia64/uv/kernel/setup.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * SGI UV Core Functions
- *
- * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/acpi.h>
-#include <linux/efi.h>
-#include <linux/module.h>
-#include <linux/percpu.h>
-#include <asm/uv/uv.h>
-#include <asm/uv/uv_mmrs.h>
-#include <asm/uv/uv_hub.h>
-
-bool ia64_is_uv;
-EXPORT_SYMBOL_GPL(ia64_is_uv);
-
-DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
-EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
-
-struct redir_addr {
- unsigned long redirect;
- unsigned long alias;
-};
-
-#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT
-
-static __initdata struct redir_addr redir_addrs[] = {
- {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG},
- {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG},
- {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG},
-};
-
-static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
-{
- union uvh_si_alias0_overlay_config_u alias;
- union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) {
- alias.v = uv_read_local_mmr(redir_addrs[i].alias);
- if (alias.s.base == 0) {
- *size = (1UL << alias.s.m_alias);
- redirect.v = uv_read_local_mmr(redir_addrs[i].redirect);
- *base = (unsigned long)redirect.s.dest_base << DEST_SHIFT;
- return;
- }
- }
- BUG();
-}
-
-void __init uv_probe_system_type(void)
-{
- struct acpi_table_rsdp *rsdp;
- struct acpi_table_xsdt *xsdt;
-
- if (efi.acpi20 == EFI_INVALID_TABLE_ADDR) {
- pr_err("ACPI 2.0 RSDP not found.\n");
- return;
- }
-
- rsdp = (struct acpi_table_rsdp *)__va(efi.acpi20);
- if (strncmp(rsdp->signature, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)) {
- pr_err("ACPI 2.0 RSDP signature incorrect.\n");
- return;
- }
-
- xsdt = (struct acpi_table_xsdt *)__va(rsdp->xsdt_physical_address);
- if (strncmp(xsdt->header.signature, ACPI_SIG_XSDT,
- sizeof(ACPI_SIG_XSDT) - 1)) {
- pr_err("ACPI 2.0 XSDT signature incorrect.\n");
- return;
- }
-
- if (!strcmp(xsdt->header.oem_id, "SGI") &&
- !strcmp(xsdt->header.oem_table_id + 4, "UV"))
- ia64_is_uv = true;
-}
-
-void __init uv_setup(char **cmdline_p)
-{
- union uvh_si_addr_map_config_u m_n_config;
- union uvh_node_id_u node_id;
- unsigned long gnode_upper;
- int nid, cpu, m_val, n_val;
- unsigned long mmr_base, lowmem_redir_base, lowmem_redir_size;
-
- get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size);
- node_id.v = uv_read_local_mmr(UVH_NODE_ID);
- m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG);
- mmr_base = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
- ~UV_MMR_ENABLE;
-
- m_val = m_n_config.s.m_skt;
- n_val = m_n_config.s.n_skt;
- printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base);
-
- gnode_upper = (((unsigned long)node_id.s.node_id) &
- ~((1 << n_val) - 1)) << m_val;
-
- for_each_present_cpu(cpu) {
- nid = cpu_to_node(cpu);
- uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base;
- uv_cpu_hub_info(cpu)->lowmem_remap_top =
- lowmem_redir_base + lowmem_redir_size;
- uv_cpu_hub_info(cpu)->m_val = m_val;
- uv_cpu_hub_info(cpu)->n_val = n_val;
- uv_cpu_hub_info(cpu)->pnode_mask = (1 << n_val) -1;
- uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
- uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
- uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
- uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */
- printk(KERN_DEBUG "UV cpu %d, nid %d\n", cpu, nid);
- }
-}
-
diff --git a/arch/m68k/68000/entry.S b/arch/m68k/68000/entry.S
index 7d63e2f1555a..72e95663b62f 100644
--- a/arch/m68k/68000/entry.S
+++ b/arch/m68k/68000/entry.S
@@ -1,12 +1,9 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
* entry.S -- non-mmu 68000 interrupt and exception entry points
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
- *
* Linux/m68k support by Hamish Macdonald
*/
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 3e318bf9504c..4b3e93cac723 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -6,19 +6,22 @@ config M68K
select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
select ARCH_HAS_CURRENT_STACK_POINTER
- select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
- select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
+ select ARCH_HAS_DMA_PREP_COHERENT if M68K_NONCOHERENT_DMA && !COLDFIRE
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE if M68K_NONCOHERENT_DMA
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
select ARCH_NO_PREEMPT if !COLDFIRE
select ARCH_USE_MEMTEST if MMU_MOTOROLA
select ARCH_WANT_IPC_PARSE_VERSION
select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
- select DMA_DIRECT_REMAP if HAS_DMA && MMU && !COLDFIRE
+ select DMA_DIRECT_REMAP if M68K_NONCOHERENT_DMA && !COLDFIRE
select GENERIC_ATOMIC64
select GENERIC_CPU_DEVICES
select GENERIC_IOMAP
select GENERIC_IRQ_SHOW
+ select GENERIC_LIB_ASHLDI3
+ select GENERIC_LIB_ASHRDI3
+ select GENERIC_LIB_LSHRDI3
select HAS_IOPORT if PCI || ISA || ATARI_ROM_ISA
select HAVE_ARCH_SECCOMP
select HAVE_ARCH_SECCOMP_FILTER
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu
index b826e9c677b2..ad69b466a08b 100644
--- a/arch/m68k/Kconfig.cpu
+++ b/arch/m68k/Kconfig.cpu
@@ -535,3 +535,15 @@ config CACHE_COPYBACK
The ColdFire CPU cache is set into Copy-back mode.
endchoice
endif # HAVE_CACHE_CB
+
+# Coldfire cores that do not have a data cache configured can do coherent DMA.
+config COLDFIRE_COHERENT_DMA
+ bool
+ default y
+ depends on COLDFIRE
+ depends on !HAVE_CACHE_CB && !CACHE_D && !CACHE_BOTH
+
+config M68K_NONCOHERENT_DMA
+ bool
+ default y
+ depends on HAS_DMA && !COLDFIRE_COHERENT_DMA
diff --git a/arch/m68k/amiga/amiga.h b/arch/m68k/amiga/amiga.h
new file mode 100644
index 000000000000..00392781442c
--- /dev/null
+++ b/arch/m68k/amiga/amiga.h
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* amisound.c */
+void amiga_init_sound(void);
+void amiga_mksound(unsigned int hz, unsigned int ticks);
diff --git a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
index 442bdeee6bd7..714fe8ec6afa 100644
--- a/arch/m68k/amiga/amisound.c
+++ b/arch/m68k/amiga/amisound.c
@@ -16,6 +16,8 @@
#include <asm/amigahw.h>
+#include "amiga.h"
+
static unsigned short *snd_data;
static const signed char sine_data[] = {
0, 39, 75, 103, 121, 127, 121, 103, 75, 39,
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index 3137b45750df..7791673e547b 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -39,6 +39,8 @@
#include <asm/io.h>
#include <asm/config.h>
+#include "amiga.h"
+
static unsigned long amiga_model;
unsigned long amiga_eclock;
@@ -96,9 +98,7 @@ static char amiga_model_name[13] = "Amiga ";
static void amiga_sched_init(void);
static void amiga_get_model(char *model);
static void amiga_get_hardware_list(struct seq_file *m);
-extern void amiga_mksound(unsigned int count, unsigned int ticks);
static void amiga_reset(void);
-extern void amiga_init_sound(void);
static void amiga_mem_console_write(struct console *co, const char *b,
unsigned int count);
#ifdef CONFIG_HEARTBEAT
diff --git a/arch/m68k/amiga/pcmcia.c b/arch/m68k/amiga/pcmcia.c
index 7106f0c3639b..63cce6b590df 100644
--- a/arch/m68k/amiga/pcmcia.c
+++ b/arch/m68k/amiga/pcmcia.c
@@ -26,11 +26,10 @@ static unsigned char cfg_byte = GAYLE_CFG_0V|GAYLE_CFG_150NS;
void pcmcia_reset(void)
{
unsigned long reset_start_time = jiffies;
- unsigned char b;
gayle_reset = 0x00;
while (time_before(jiffies, reset_start_time + 1*HZ/100));
- b = gayle_reset;
+ READ_ONCE(gayle_reset);
}
EXPORT_SYMBOL(pcmcia_reset);
diff --git a/arch/m68k/apollo/apollo.h b/arch/m68k/apollo/apollo.h
new file mode 100644
index 000000000000..1fe9d856df30
--- /dev/null
+++ b/arch/m68k/apollo/apollo.h
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* dn_ints.c */
+void dn_init_IRQ(void);
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
index 42a8b8e2b664..e161ecd76035 100644
--- a/arch/m68k/apollo/config.c
+++ b/arch/m68k/apollo/config.c
@@ -4,7 +4,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/console.h>
#include <linux/rtc.h>
#include <linux/vt_kern.h>
#include <linux/interrupt.h>
@@ -18,6 +17,8 @@
#include <asm/machdep.h>
#include <asm/config.h>
+#include "apollo.h"
+
u_long sio01_physaddr;
u_long sio23_physaddr;
u_long rtc_physaddr;
@@ -28,9 +29,8 @@ u_long timer_physaddr;
u_long apollo_model;
extern void dn_sched_init(void);
-extern void dn_init_IRQ(void);
extern int dn_dummy_hwclk(int, struct rtc_time *);
-extern void dn_dummy_reset(void);
+static void dn_dummy_reset(void);
#ifdef CONFIG_HEARTBEAT
static void dn_heartbeat(int on);
#endif
@@ -108,28 +108,7 @@ static void __init dn_setup_model(void)
}
-int dn_serial_console_wait_key(struct console *co) {
-
- while(!(sio01.srb_csrb & 1))
- barrier();
- return sio01.rhrb_thrb;
-}
-
-void dn_serial_console_write (struct console *co, const char *str,unsigned int count)
-{
- while(count--) {
- if (*str == '\n') {
- sio01.rhrb_thrb = (unsigned char)'\r';
- while (!(sio01.srb_csrb & 0x4))
- ;
- }
- sio01.rhrb_thrb = (unsigned char)*str++;
- while (!(sio01.srb_csrb & 0x4))
- ;
- }
-}
-
-void dn_serial_print (const char *str)
+static void dn_serial_print(const char *str)
{
while (*str) {
if (*str == '\n') {
@@ -168,13 +147,13 @@ void __init config_apollo(void)
irqreturn_t dn_timer_int(int irq, void *dev_id)
{
- volatile unsigned char x;
+ unsigned char *at = (unsigned char *)apollo_timer;
legacy_timer_tick(1);
timer_heartbeat();
- x = *(volatile unsigned char *)(apollo_timer + 3);
- x = *(volatile unsigned char *)(apollo_timer + 5);
+ READ_ONCE(*(at + 3));
+ READ_ONCE(*(at + 5));
return IRQ_HANDLED;
}
@@ -229,20 +208,14 @@ int dn_dummy_hwclk(int op, struct rtc_time *t) {
}
-void dn_dummy_reset(void) {
-
+static void dn_dummy_reset(void)
+{
dn_serial_print("The end !\n");
for(;;);
}
-void dn_dummy_waitbut(void) {
-
- dn_serial_print("waitbut\n");
-
-}
-
static void dn_get_model(char *model)
{
strcpy(model, "Apollo ");
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index 02cff7efc834..ba96a92f8f18 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -5,7 +5,9 @@
#include <asm/traps.h>
#include <asm/apollohw.h>
-unsigned int apollo_irq_startup(struct irq_data *data)
+#include "apollo.h"
+
+static unsigned int apollo_irq_startup(struct irq_data *data)
{
unsigned int irq = data->irq;
@@ -16,7 +18,7 @@ unsigned int apollo_irq_startup(struct irq_data *data)
return 0;
}
-void apollo_irq_shutdown(struct irq_data *data)
+static void apollo_irq_shutdown(struct irq_data *data)
{
unsigned int irq = data->irq;
@@ -26,7 +28,7 @@ void apollo_irq_shutdown(struct irq_data *data)
*(volatile unsigned char *)(picb+1) |= (1 << (irq - 8));
}
-void apollo_irq_eoi(struct irq_data *data)
+static void apollo_irq_eoi(struct irq_data *data)
{
*(volatile unsigned char *)(pica) = 0x20;
*(volatile unsigned char *)(picb) = 0x20;
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 56f02ea2c248..23256434191c 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -52,6 +52,7 @@
#include <asm/entry.h>
#include <asm/io.h>
+#include "atari.h"
/*
* Atari interrupt handling scheme:
@@ -81,8 +82,6 @@ __ALIGN_STR "\n\t"
"orw #0x200,%sp@\n\t" /* set saved ipl to 2 */
"rte");
-extern void atari_microwire_cmd(int cmd);
-
static unsigned int atari_irq_startup(struct irq_data *data)
{
unsigned int irq = data->irq;
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
index 5e0e682f9c61..49a9a459bdf4 100644
--- a/arch/m68k/atari/atakeyb.c
+++ b/arch/m68k/atari/atakeyb.c
@@ -332,7 +332,7 @@ void ikbd_write(const char *str, int len)
}
/* Reset (without touching the clock) */
-void ikbd_reset(void)
+static void ikbd_reset(void)
{
static const char cmd[2] = { 0x80, 0x01 };
diff --git a/arch/m68k/atari/atari.h b/arch/m68k/atari/atari.h
new file mode 100644
index 000000000000..494a03ddac3d
--- /dev/null
+++ b/arch/m68k/atari/atari.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+struct rtc_time;
+
+/* ataints.c */
+void atari_init_IRQ(void);
+
+/* atasound.c */
+void atari_microwire_cmd(int cmd);
+void atari_mksound(unsigned int hz, unsigned int ticks);
+
+/* time.c */
+void atari_sched_init(void);
+int atari_mste_hwclk(int op, struct rtc_time *t);
+int atari_tt_hwclk(int op, struct rtc_time *t);
diff --git a/arch/m68k/atari/atasound.c b/arch/m68k/atari/atasound.c
index a8724d998c39..c38ef0e6078e 100644
--- a/arch/m68k/atari/atasound.c
+++ b/arch/m68k/atari/atasound.c
@@ -28,6 +28,7 @@
#include <asm/irq.h>
#include <asm/atariints.h>
+#include "atari.h"
/*
* stuff from the old atasound.c
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 38a7c0578105..b48a0606a000 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -48,6 +48,8 @@
#include <asm/io.h>
#include <asm/config.h>
+#include "atari.h"
+
u_long atari_mch_cookie;
EXPORT_SYMBOL(atari_mch_cookie);
@@ -69,19 +71,10 @@ int atari_rtc_year_offset;
static void atari_reset(void);
static void atari_get_model(char *model);
static void atari_get_hardware_list(struct seq_file *m);
-
-/* atari specific irq functions */
-extern void atari_init_IRQ (void);
-extern void atari_mksound(unsigned int count, unsigned int ticks);
#ifdef CONFIG_HEARTBEAT
static void atari_heartbeat(int on);
#endif
-/* atari specific timer functions (in time.c) */
-extern void atari_sched_init(void);
-extern int atari_mste_hwclk (int, struct rtc_time *);
-extern int atari_tt_hwclk (int, struct rtc_time *);
-
/* ++roman: This is a more elaborate test for an SCC chip, since the plain
* Medusa board generates DTACK at the SCC's standard addresses, but a SCC
* board in the Medusa is possible. Also, the addresses where the ST_ESCC
@@ -880,7 +873,7 @@ static const struct resource atari_falconide_rsrc[] __initconst = {
DEFINE_RES_MEM(FALCON_IDE_BASE + 0x38, 2),
};
-int __init atari_platform_init(void)
+static int __init atari_platform_init(void)
{
struct platform_device *pdev;
int rv = 0;
diff --git a/arch/m68k/atari/stdma.c b/arch/m68k/atari/stdma.c
index ce6818eff75e..155fefff19b0 100644
--- a/arch/m68k/atari/stdma.c
+++ b/arch/m68k/atari/stdma.c
@@ -61,6 +61,7 @@ static irqreturn_t stdma_int (int irq, void *dummy);
/**
* stdma_try_lock - attempt to acquire ST DMA interrupt "lock"
* @handler: interrupt handler to use after acquisition
+ * @data: cookie passed to the interrupt handler function
*
* Returns !0 if lock was acquired; otherwise 0.
*/
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index ce79b322a99c..922e53bcb853 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -115,7 +115,7 @@ void __init atari_stram_reserve_pages(void *start_mem)
* This function is called as arch initcall to reserve the pages needed for
* ST-RAM management, if the kernel does not reside in ST-RAM.
*/
-int __init atari_stram_map_pages(void)
+static int __init atari_stram_map_pages(void)
{
if (!kernel_in_stram) {
/*
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 7e44d0e9d0f8..3453c6dc6b41 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -23,6 +23,8 @@
#include <asm/atariints.h>
#include <asm/machdep.h>
+#include "atari.h"
+
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL_GPL(rtc_lock);
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c
index 3a1d90e399e0..8a2ee69a09f6 100644
--- a/arch/m68k/bvme6000/config.c
+++ b/arch/m68k/bvme6000/config.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* arch/m68k/bvme6000/config.c
*
@@ -8,10 +9,6 @@
* linux/amiga/config.c
*
* Copyright (C) 1993 Hamish Macdonald
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
*/
#include <linux/types.h>
@@ -130,7 +127,7 @@ void __init config_bvme6000(void)
}
-irqreturn_t bvme6000_abort_int (int irq, void *dev_id)
+static irqreturn_t bvme6000_abort_int(int irq, void *dev_id)
{
unsigned long *new = (unsigned long *)vectors;
unsigned long *old = (unsigned long *)0xf8000000;
diff --git a/arch/m68k/coldfire/entry.S b/arch/m68k/coldfire/entry.S
index 35104c5417ff..4ea08336e2fb 100644
--- a/arch/m68k/coldfire/entry.S
+++ b/arch/m68k/coldfire/entry.S
@@ -1,4 +1,5 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
* entry.S -- interrupt and exception processing for ColdFire
*
* Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
@@ -13,10 +14,6 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
- *
* Linux/m68k support by Hamish Macdonald
*
* 68060 fixes by Jesper Skov
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index 6deb8faa564b..7e6b74b6eecd 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -299,6 +299,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_PARPORT=m
CONFIG_PARPORT_AMIGA=m
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index 802c161827f4..0b403e2efcd5 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -295,6 +295,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_ZRAM=m
CONFIG_BLK_DEV_LOOP=y
@@ -568,6 +569,7 @@ CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_PRIME_NUMBERS=m
CONFIG_CRC32_SELFTEST=m
CONFIG_XZ_DEC_TEST=m
+CONFIG_GLOB_SELFTEST=m
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 2cb3d755873b..57aac3f4b001 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -302,6 +302,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_PARPORT=m
CONFIG_PARPORT_ATARI=m
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index b13552caa6b3..3c160636a2e9 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -292,6 +292,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_ZRAM=m
CONFIG_BLK_DEV_LOOP=y
@@ -560,6 +561,7 @@ CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_PRIME_NUMBERS=m
CONFIG_CRC32_SELFTEST=m
CONFIG_XZ_DEC_TEST=m
+CONFIG_GLOB_SELFTEST=m
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index f88356c45440..23cf07c49d14 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -294,6 +294,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_ZRAM=m
CONFIG_BLK_DEV_LOOP=y
@@ -570,6 +571,7 @@ CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_PRIME_NUMBERS=m
CONFIG_CRC32_SELFTEST=m
CONFIG_XZ_DEC_TEST=m
+CONFIG_GLOB_SELFTEST=m
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 7c2ebb616fba..619a0d93ce5b 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -296,6 +296,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_BLK_DEV_SWIM=m
CONFIG_ZRAM=m
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index d3b272910b38..d9430bc2b2de 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -316,6 +316,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 4529bc4b843c..eb6132f29bf5 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -291,6 +291,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_ZRAM=m
CONFIG_BLK_DEV_LOOP=y
@@ -559,6 +560,7 @@ CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_PRIME_NUMBERS=m
CONFIG_CRC32_SELFTEST=m
CONFIG_XZ_DEC_TEST=m
+CONFIG_GLOB_SELFTEST=m
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index 30824032e4d5..d0bad674cbb7 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -292,6 +292,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_ZRAM=m
CONFIG_BLK_DEV_LOOP=y
@@ -560,6 +561,7 @@ CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_PRIME_NUMBERS=m
CONFIG_CRC32_SELFTEST=m
CONFIG_XZ_DEC_TEST=m
+CONFIG_GLOB_SELFTEST=m
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index 3911211410ed..dad6bcfcaeed 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -293,6 +293,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index 991730c50957..eb1b489b3139 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -288,6 +288,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_ZRAM=m
CONFIG_BLK_DEV_LOOP=y
@@ -558,6 +559,7 @@ CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_PRIME_NUMBERS=m
CONFIG_CRC32_SELFTEST=m
CONFIG_XZ_DEC_TEST=m
+CONFIG_GLOB_SELFTEST=m
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index e80d7509ab1d..939589826546 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -289,6 +289,7 @@ CONFIG_NET_IFE=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
+CONFIG_DM_KUNIT_TEST=m
CONFIG_CONNECTOR=m
CONFIG_ZRAM=m
CONFIG_BLK_DEV_LOOP=y
@@ -558,6 +559,7 @@ CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_PRIME_NUMBERS=m
CONFIG_CRC32_SELFTEST=m
CONFIG_XZ_DEC_TEST=m
+CONFIG_GLOB_SELFTEST=m
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/virt_defconfig b/arch/m68k/configs/virt_defconfig
index 311b57e73316..ce725d39e488 100644
--- a/arch/m68k/configs/virt_defconfig
+++ b/arch/m68k/configs/virt_defconfig
@@ -45,8 +45,9 @@ CONFIG_INPUT_EVDEV=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_DRM=y
+CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_VIRTIO_GPU=y
-CONFIG_FB=y
+CONFIG_FB_DEVICE=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_VIRTIO=y
diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c
index b19dc00026d9..777c7b42a50f 100644
--- a/arch/m68k/emu/natfeat.c
+++ b/arch/m68k/emu/natfeat.c
@@ -42,10 +42,10 @@ long nf_get_id(const char *feature_name)
{
/* feature_name may be in vmalloc()ed memory, so make a copy */
char name_copy[32];
- size_t n;
+ ssize_t n;
- n = strlcpy(name_copy, feature_name, sizeof(name_copy));
- if (n >= sizeof(name_copy))
+ n = strscpy(name_copy, feature_name, sizeof(name_copy));
+ if (n < 0)
return 0;
return nf_get_id_phys(virt_to_phys(name_copy));
@@ -56,10 +56,9 @@ void nfprint(const char *fmt, ...)
{
static char buf[256];
va_list ap;
- int n;
va_start(ap, fmt);
- n = vsnprintf(buf, 256, fmt, ap);
+ vsnprintf(buf, 256, fmt, ap);
nf_call(nf_get_id("NF_STDERR"), virt_to_phys(buf));
va_end(ap);
}
diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c
index 1a5d1e8eb4c8..26e68813f351 100644
--- a/arch/m68k/emu/nfeth.c
+++ b/arch/m68k/emu/nfeth.c
@@ -39,7 +39,7 @@ enum {
#define MAX_UNIT 8
/* These identify the driver base version and may not be removed. */
-static const char version[] =
+static const char version[] __maybe_unused =
KERN_INFO KBUILD_MODNAME ".c:v" DRV_VERSION " " DRV_RELDATE
" S.Opichal, M.Jurik, P.Stehlik\n"
KERN_INFO " http://aranym.org/\n";
diff --git a/arch/m68k/fpsp040/slogn.S b/arch/m68k/fpsp040/slogn.S
index d98eaf641ec4..5f3da4aa7e45 100644
--- a/arch/m68k/fpsp040/slogn.S
+++ b/arch/m68k/fpsp040/slogn.S
@@ -261,56 +261,56 @@ slognd:
|----the value TWOTO100 is no longer needed.
|----Note that this code assumes the denormalized input is NON-ZERO.
- moveml %d2-%d7,-(%a7) | ...save some registers
- movel #0x00000000,%d3 | ...D3 is exponent of smallest norm. #
- movel 4(%a0),%d4
- movel 8(%a0),%d5 | ...(D4,D5) is (Hi_X,Lo_X)
- clrl %d2 | ...D2 used for holding K
+ moveml %d2-%d7,-(%a7) | ...save some registers
+ movel #0x00000000,%d3 | ...D3 is exponent of smallest norm. #
+ movel 4(%a0),%d4
+ movel 8(%a0),%d5 | ...(D4,D5) is (Hi_X,Lo_X)
+ clrl %d2 | ...D2 used for holding K
- tstl %d4
- bnes HiX_not0
+ tstl %d4
+ bnes HiX_not0
HiX_0:
- movel %d5,%d4
- clrl %d5
- movel #32,%d2
- clrl %d6
- bfffo %d4{#0:#32},%d6
- lsll %d6,%d4
- addl %d6,%d2 | ...(D3,D4,D5) is normalized
-
- movel %d3,X(%a6)
- movel %d4,XFRAC(%a6)
- movel %d5,XFRAC+4(%a6)
- negl %d2
- movel %d2,ADJK(%a6)
- fmovex X(%a6),%fp0
- moveml (%a7)+,%d2-%d7 | ...restore registers
- lea X(%a6),%a0
- bras LOGBGN | ...begin regular log(X)
+ movel %d5,%d4
+ clrl %d5
+ movel #32,%d2
+ clrl %d6
+ bfffo %d4{#0:#32},%d6
+ lsll %d6,%d4
+ addl %d6,%d2 | ...(D3,D4,D5) is normalized
+
+ movel %d3,X(%a6)
+ movel %d4,XFRAC(%a6)
+ movel %d5,XFRAC+4(%a6)
+ negl %d2
+ movel %d2,ADJK(%a6)
+ fmovex X(%a6),%fp0
+ moveml (%a7)+,%d2-%d7 | ...restore registers
+ lea X(%a6),%a0
+ bras LOGBGN | ...begin regular log(X)
HiX_not0:
- clrl %d6
- bfffo %d4{#0:#32},%d6 | ...find first 1
- movel %d6,%d2 | ...get k
- lsll %d6,%d4
- movel %d5,%d7 | ...a copy of D5
- lsll %d6,%d5
- negl %d6
- addil #32,%d6
- lsrl %d6,%d7
- orl %d7,%d4 | ...(D3,D4,D5) normalized
-
- movel %d3,X(%a6)
- movel %d4,XFRAC(%a6)
- movel %d5,XFRAC+4(%a6)
- negl %d2
- movel %d2,ADJK(%a6)
- fmovex X(%a6),%fp0
- moveml (%a7)+,%d2-%d7 | ...restore registers
- lea X(%a6),%a0
- bras LOGBGN | ...begin regular log(X)
+ clrl %d6
+ bfffo %d4{#0:#32},%d6 | ...find first 1
+ movel %d6,%d2 | ...get k
+ lsll %d6,%d4
+ movel %d5,%d7 | ...a copy of D5
+ lsll %d6,%d5
+ negl %d6
+ addil #32,%d6
+ lsrl %d6,%d7
+ orl %d7,%d4 | ...(D3,D4,D5) normalized
+
+ movel %d3,X(%a6)
+ movel %d4,XFRAC(%a6)
+ movel %d5,XFRAC+4(%a6)
+ negl %d2
+ movel %d2,ADJK(%a6)
+ fmovex X(%a6),%fp0
+ moveml (%a7)+,%d2-%d7 | ...restore registers
+ lea X(%a6),%a0
+ bras LOGBGN | ...begin regular log(X)
.global slogn
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
index 1d1b7b3b5dd4..72621fb9f3e6 100644
--- a/arch/m68k/hp300/time.c
+++ b/arch/m68k/hp300/time.c
@@ -20,6 +20,8 @@
#include <asm/traps.h>
#include <asm/blinken.h>
+#include "time.h"
+
static u64 hp300_read_clk(struct clocksource *cs);
static struct clocksource hp300_clk = {
diff --git a/arch/m68k/ifpsp060/Makefile b/arch/m68k/ifpsp060/Makefile
index 56b530a96c2f..00d0621f547c 100644
--- a/arch/m68k/ifpsp060/Makefile
+++ b/arch/m68k/ifpsp060/Makefile
@@ -1,7 +1,5 @@
-# Makefile for 680x0 Linux 68060 integer/floating point support package
+# SPDX-License-Identifier: GPL-2.0-or-later
#
-# This file is subject to the terms and conditions of the GNU General Public
-# License. See the file "README.legal" in the main directory of this archive
-# for more details.
+# Makefile for 680x0 Linux 68060 integer/floating point support package
obj-y := fskeleton.o iskeleton.o os.o
diff --git a/arch/m68k/include/asm/dvma.h b/arch/m68k/include/asm/dvma.h
index f609ec1de36d..d1d66d04844d 100644
--- a/arch/m68k/include/asm/dvma.h
+++ b/arch/m68k/include/asm/dvma.h
@@ -58,12 +58,16 @@ extern void dvma_free(void *vaddr);
#define dvma_vtob(x) dvma_vtop(x)
#define dvma_btov(x) dvma_ptov(x)
+void sun3_dvma_init(void);
+
static inline int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr,
int len)
{
return 0;
}
+static inline void dvma_unmap_iommu(unsigned long baddr, int len) { }
+
#else /* Sun3x */
/* sun3x dvma page support */
@@ -78,9 +82,11 @@ static inline int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr,
#define dvma_vtob(x) ((unsigned long)(x) & 0x00ffffff)
#define dvma_btov(x) ((unsigned long)(x) | 0xff000000)
-extern int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, int len);
+static inline void sun3_dvma_init(void) { }
+int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, int len);
+void dvma_unmap_iommu(unsigned long baddr, int len);
/* everything below this line is specific to dma used for the onboard
ESP scsi on sun3x */
diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h
index 6a0abd4846c6..47525f2a57e1 100644
--- a/arch/m68k/include/asm/io_mm.h
+++ b/arch/m68k/include/asm/io_mm.h
@@ -272,20 +272,20 @@ static inline void isa_delay(void)
#define isa_outsb(port, buf, nr) raw_outsb(isa_itb(port), (u8 *)(buf), (nr))
#define isa_insw(port, buf, nr) \
- (ISA_SEX ? raw_insw(isa_itw(port), (u16 *)(buf), (nr)) : \
- raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
+ (ISA_SEX ? raw_insw(isa_itw(port), (u16 *)(buf), (nr)) : \
+ raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
#define isa_outsw(port, buf, nr) \
- (ISA_SEX ? raw_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \
- raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
+ (ISA_SEX ? raw_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \
+ raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
#define isa_insl(port, buf, nr) \
- (ISA_SEX ? raw_insl(isa_itl(port), (u32 *)(buf), (nr)) : \
- raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1))
+ (ISA_SEX ? raw_insl(isa_itl(port), (u32 *)(buf), (nr)) : \
+ raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1))
#define isa_outsl(port, buf, nr) \
- (ISA_SEX ? raw_outsl(isa_itl(port), (u32 *)(buf), (nr)) : \
- raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1))
+ (ISA_SEX ? raw_outsl(isa_itl(port), (u32 *)(buf), (nr)) : \
+ raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1))
#ifdef CONFIG_ATARI_ROM_ISA
@@ -297,14 +297,14 @@ static inline void isa_delay(void)
#define isa_rom_insb(port, buf, nr) raw_rom_insb(isa_itb(port), (u8 *)(buf), (nr))
#define isa_rom_insw(port, buf, nr) \
- (ISA_SEX ? raw_rom_insw(isa_itw(port), (u16 *)(buf), (nr)) : \
- raw_rom_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
+ (ISA_SEX ? raw_rom_insw(isa_itw(port), (u16 *)(buf), (nr)) : \
+ raw_rom_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
#define isa_rom_outsb(port, buf, nr) raw_rom_outsb(isa_itb(port), (u8 *)(buf), (nr))
#define isa_rom_outsw(port, buf, nr) \
- (ISA_SEX ? raw_rom_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \
- raw_rom_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
+ (ISA_SEX ? raw_rom_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \
+ raw_rom_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
#endif /* CONFIG_ATARI_ROM_ISA */
#endif /* CONFIG_ISA || CONFIG_ATARI_ROM_ISA */
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
index 7829e955ca04..14992fde7340 100644
--- a/arch/m68k/include/asm/irq.h
+++ b/arch/m68k/include/asm/irq.h
@@ -2,6 +2,9 @@
#ifndef _M68K_IRQ_H_
#define _M68K_IRQ_H_
+#include <linux/atomic.h>
+#include <linux/linkage.h>
+
/*
* This should be the same as the max(NUM_X_SOURCES) for all the
* different m68k hosts compiled into the kernel.
@@ -59,6 +62,8 @@
struct irq_data;
struct irq_chip;
struct irq_desc;
+struct pt_regs;
+
extern unsigned int m68k_irq_startup(struct irq_data *data);
extern unsigned int m68k_irq_startup_irq(unsigned int irq);
extern void m68k_irq_shutdown(struct irq_data *data);
diff --git a/arch/m68k/include/asm/oplib.h b/arch/m68k/include/asm/oplib.h
index 48cb4fd09f8d..6d5ea67c65d0 100644
--- a/arch/m68k/include/asm/oplib.h
+++ b/arch/m68k/include/asm/oplib.h
@@ -9,6 +9,8 @@
#ifndef __SPARC_OPLIB_H
#define __SPARC_OPLIB_H
+#include <linux/compiler.h>
+
#include <asm/openprom.h>
/* The master romvec pointer... */
@@ -149,7 +151,7 @@ extern char prom_getchar(void);
extern void prom_putchar(char character);
/* Prom's internal printf routine, don't use in kernel/boot code. */
-void prom_printf(char *fmt, ...);
+__printf(1, 2) void prom_printf(char *fmt, ...);
/* Query for input device type */
diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h
index 363aa0f9ba8a..e0ae4d5fc985 100644
--- a/arch/m68k/include/asm/page_mm.h
+++ b/arch/m68k/include/asm/page_mm.h
@@ -13,17 +13,16 @@
#ifdef CPU_M68040_OR_M68060_ONLY
static inline void copy_page(void *to, void *from)
{
- unsigned long tmp;
-
- __asm__ __volatile__("1:\t"
- ".chip 68040\n\t"
- "move16 %1@+,%0@+\n\t"
- "move16 %1@+,%0@+\n\t"
- ".chip 68k\n\t"
- "dbra %2,1b\n\t"
- : "=a" (to), "=a" (from), "=d" (tmp)
- : "0" (to), "1" (from) , "2" (PAGE_SIZE / 32 - 1)
- );
+ unsigned long tmp;
+
+ __asm__ __volatile__("1:\t"
+ ".chip 68040\n\t"
+ "move16 %1@+,%0@+\n\t"
+ "move16 %1@+,%0@+\n\t"
+ ".chip 68k\n\t"
+ "dbra %2,1b\n\t"
+ : "=a" (to), "=a" (from), "=d" (tmp)
+ : "0" (to), "1" (from), "2" (PAGE_SIZE / 32 - 1));
}
static inline void clear_page(void *page)
@@ -95,23 +94,23 @@ static inline void *__va(unsigned long paddr)
#define __pa(x) ___pa((unsigned long)(x))
static inline unsigned long ___pa(unsigned long x)
{
- if(x == 0)
- return 0;
- if(x >= PAGE_OFFSET)
- return (x-PAGE_OFFSET);
- else
- return (x+0x2000000);
+ if (x == 0)
+ return 0;
+ if (x >= PAGE_OFFSET)
+ return (x - PAGE_OFFSET);
+ else
+ return (x + 0x2000000);
}
static inline void *__va(unsigned long x)
{
- if(x == 0)
- return (void *)0;
+ if (x == 0)
+ return (void *)0;
- if(x < 0x2000000)
- return (void *)(x+PAGE_OFFSET);
- else
- return (void *)(x-0x2000000);
+ if (x < 0x2000000)
+ return (void *)(x + PAGE_OFFSET);
+ else
+ return (void *)(x - 0x2000000);
}
#endif /* CONFIG_SUN3 */
diff --git a/arch/m68k/include/asm/pgtable.h b/arch/m68k/include/asm/pgtable.h
index ad15d655a9bf..27525c6a12fd 100644
--- a/arch/m68k/include/asm/pgtable.h
+++ b/arch/m68k/include/asm/pgtable.h
@@ -1,6 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __M68K_PGTABLE_H
+#define __M68K_PGTABLE_H
+
#ifdef __uClinux__
#include <asm/pgtable_no.h>
#else
#include <asm/pgtable_mm.h>
#endif
+
+#ifndef __ASSEMBLY__
+extern void paging_init(void);
+#endif
+
+#endif /* __M68K_PGTABLE_H */
diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h
index fc044df52b96..1a86c15b9008 100644
--- a/arch/m68k/include/asm/pgtable_no.h
+++ b/arch/m68k/include/asm/pgtable_no.h
@@ -28,7 +28,6 @@
#define PAGE_READONLY __pgprot(0)
#define PAGE_KERNEL __pgprot(0)
-extern void paging_init(void);
#define swapper_pg_dir ((pgd_t *) 0)
/*
diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h
index 3ba40bc1dfaa..95a6ff694a68 100644
--- a/arch/m68k/include/asm/raw_io.h
+++ b/arch/m68k/include/asm/raw_io.h
@@ -17,15 +17,15 @@
* two accesses to memory, which may be undesirable for some devices.
*/
#define in_8(addr) \
- ({ u8 __v = (*(__force volatile u8 *) (unsigned long)(addr)); __v; })
+ ({ u8 __v = (*(__force const volatile u8 *) (unsigned long)(addr)); __v; })
#define in_be16(addr) \
- ({ u16 __v = (*(__force volatile u16 *) (unsigned long)(addr)); __v; })
+ ({ u16 __v = (*(__force const volatile u16 *) (unsigned long)(addr)); __v; })
#define in_be32(addr) \
- ({ u32 __v = (*(__force volatile u32 *) (unsigned long)(addr)); __v; })
+ ({ u32 __v = (*(__force const volatile u32 *) (unsigned long)(addr)); __v; })
#define in_le16(addr) \
- ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (unsigned long)(addr)); __v; })
+ ({ u16 __v = le16_to_cpu(*(__force const volatile __le16 *) (unsigned long)(addr)); __v; })
#define in_le32(addr) \
- ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (unsigned long)(addr)); __v; })
+ ({ u32 __v = le32_to_cpu(*(__force const volatile __le32 *) (unsigned long)(addr)); __v; })
#define out_8(addr,b) (void)((*(__force volatile u8 *) (unsigned long)(addr)) = (b))
#define out_be16(addr,w) (void)((*(__force volatile u16 *) (unsigned long)(addr)) = (w))
@@ -73,11 +73,11 @@
#if defined(CONFIG_ATARI_ROM_ISA)
#define rom_in_8(addr) \
- ({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
+ ({ u16 __v = (*(__force const volatile u16 *) (addr)); __v >>= 8; __v; })
#define rom_in_be16(addr) \
- ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
+ ({ u16 __v = (*(__force const volatile u16 *) (addr)); __v; })
#define rom_in_le16(addr) \
- ({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; })
+ ({ u16 __v = le16_to_cpu(*(__force const volatile u16 *) (addr)); __v; })
#define rom_out_8(addr, b) \
(void)({u8 __maybe_unused __w, __v = (b); u32 _addr = ((u32) (addr)); \
@@ -98,7 +98,8 @@
#define raw_rom_outw(val, port) rom_out_be16((port), (val))
#endif /* CONFIG_ATARI_ROM_ISA */
-static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
+static inline void raw_insb(const volatile u8 __iomem *port, u8 *buf,
+ unsigned int len)
{
unsigned int i;
@@ -146,7 +147,7 @@ static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf,
}
}
-static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr)
+static inline void raw_insw(volatile const u16 __iomem *port, u16 *buf, unsigned int nr)
{
unsigned int tmp;
@@ -225,7 +226,7 @@ static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf,
}
}
-static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr)
+static inline void raw_insl(const volatile u32 __iomem *port, u32 *buf, unsigned int nr)
{
unsigned int tmp;
@@ -305,7 +306,7 @@ static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf,
}
-static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf,
+static inline void raw_insw_swapw(const volatile u16 __iomem *port, u16 *buf,
unsigned int nr)
{
if ((nr) % 8)
@@ -413,7 +414,8 @@ static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
#if defined(CONFIG_ATARI_ROM_ISA)
-static inline void raw_rom_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
+static inline void raw_rom_insb(const volatile u8 __iomem *port, u8 *buf,
+ unsigned int len)
{
unsigned int i;
@@ -430,7 +432,7 @@ static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf,
rom_out_8(port, *buf++);
}
-static inline void raw_rom_insw(volatile u16 __iomem *port, u16 *buf,
+static inline void raw_rom_insw(const volatile u16 __iomem *port, u16 *buf,
unsigned int nr)
{
unsigned int i;
@@ -448,7 +450,7 @@ static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf,
rom_out_be16(port, *buf++);
}
-static inline void raw_rom_insw_swapw(volatile u16 __iomem *port, u16 *buf,
+static inline void raw_rom_insw_swapw(const volatile u16 __iomem *port, u16 *buf,
unsigned int nr)
{
unsigned int i;
diff --git a/arch/m68k/include/asm/sun3_pgalloc.h b/arch/m68k/include/asm/sun3_pgalloc.h
index ff48573db2c0..4a137eecb6fe 100644
--- a/arch/m68k/include/asm/sun3_pgalloc.h
+++ b/arch/m68k/include/asm/sun3_pgalloc.h
@@ -41,12 +41,12 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page
static inline pgd_t * pgd_alloc(struct mm_struct *mm)
{
- pgd_t *new_pgd;
+ pgd_t *new_pgd;
- new_pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL);
- memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
- memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT));
- return new_pgd;
+ new_pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL);
+ memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
+ memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT));
+ return new_pgd;
}
#endif /* SUN3_PGALLOC_H */
diff --git a/arch/m68k/include/asm/syscalls.h b/arch/m68k/include/asm/syscalls.h
new file mode 100644
index 000000000000..fb3639acd07b
--- /dev/null
+++ b/arch/m68k/include/asm/syscalls.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASM_M68K_SYSCALLS_H
+#define _ASM_M68K_SYSCALLS_H
+
+#include <linux/compiler_types.h>
+#include <linux/linkage.h>
+
+asmlinkage int sys_cacheflush(unsigned long addr, int scope, int cache,
+ unsigned long len);
+asmlinkage int sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3,
+ int d4, int d5, unsigned long __user *mem);
+asmlinkage int sys_getpagesize(void);
+asmlinkage unsigned long sys_get_thread_area(void);
+asmlinkage int sys_set_thread_area(unsigned long tp);
+asmlinkage int sys_atomic_barrier(void);
+
+#include <asm-generic/syscalls.h>
+
+#endif /* _ASM_M68K_SYSCALLS_H */
diff --git a/arch/m68k/include/asm/tlbflush.h b/arch/m68k/include/asm/tlbflush.h
index b882e2f4f551..6d42e2906887 100644
--- a/arch/m68k/include/asm/tlbflush.h
+++ b/arch/m68k/include/asm/tlbflush.h
@@ -112,53 +112,51 @@ extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
sun?) */
static inline void flush_tlb_all(void)
{
- unsigned long addr;
- unsigned char ctx, oldctx;
-
- oldctx = sun3_get_context();
- for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
- for(ctx = 0; ctx < 8; ctx++) {
- sun3_put_context(ctx);
- sun3_put_segmap(addr, SUN3_INVALID_PMEG);
- }
- }
-
- sun3_put_context(oldctx);
- /* erase all of the userspace pmeg maps, we've clobbered them
- all anyway */
- for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
- if(pmeg_alloc[addr] == 1) {
- pmeg_alloc[addr] = 0;
- pmeg_ctx[addr] = 0;
- pmeg_vaddr[addr] = 0;
- }
- }
+ unsigned long addr;
+ unsigned char ctx, oldctx;
+ oldctx = sun3_get_context();
+ for (addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
+ for (ctx = 0; ctx < 8; ctx++) {
+ sun3_put_context(ctx);
+ sun3_put_segmap(addr, SUN3_INVALID_PMEG);
+ }
+ }
+
+ sun3_put_context(oldctx);
+ /* erase all of the userspace pmeg maps, we've clobbered them
+ all anyway */
+ for (addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
+ if (pmeg_alloc[addr] == 1) {
+ pmeg_alloc[addr] = 0;
+ pmeg_ctx[addr] = 0;
+ pmeg_vaddr[addr] = 0;
+ }
+ }
}
/* Clear user TLB entries within the context named in mm */
static inline void flush_tlb_mm (struct mm_struct *mm)
{
- unsigned char oldctx;
- unsigned char seg;
- unsigned long i;
-
- oldctx = sun3_get_context();
- sun3_put_context(mm->context);
+ unsigned char oldctx;
+ unsigned char seg;
+ unsigned long i;
- for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
- seg = sun3_get_segmap(i);
- if(seg == SUN3_INVALID_PMEG)
- continue;
+ oldctx = sun3_get_context();
+ sun3_put_context(mm->context);
- sun3_put_segmap(i, SUN3_INVALID_PMEG);
- pmeg_alloc[seg] = 0;
- pmeg_ctx[seg] = 0;
- pmeg_vaddr[seg] = 0;
- }
+ for (i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
+ seg = sun3_get_segmap(i);
+ if (seg == SUN3_INVALID_PMEG)
+ continue;
- sun3_put_context(oldctx);
+ sun3_put_segmap(i, SUN3_INVALID_PMEG);
+ pmeg_alloc[seg] = 0;
+ pmeg_ctx[seg] = 0;
+ pmeg_vaddr[seg] = 0;
+ }
+ sun3_put_context(oldctx);
}
/* Flush a single TLB page. In this case, we're limited to flushing a
@@ -208,6 +206,7 @@ static inline void flush_tlb_range (struct vm_area_struct *vma,
next:
start += SUN3_PMEG_SIZE;
}
+ sun3_put_context(oldctx);
}
static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
index af015447dfb4..01fb69a5095f 100644
--- a/arch/m68k/kernel/Makefile
+++ b/arch/m68k/kernel/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_MMU_MOTOROLA) += ints.o vectors.o
obj-$(CONFIG_MMU_SUN3) += ints.o vectors.o
obj-$(CONFIG_PCI) += pcibios.o
-obj-$(CONFIG_HAS_DMA) += dma.o
+obj-$(CONFIG_M68K_NONCOHERENT_DMA) += dma.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_BOOTINFO_PROC) += bootinfo_proc.o
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 2e192a5df949..16063783aa80 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -4,20 +4,11 @@
* for more details.
*/
-#undef DEBUG
-
#include <linux/dma-map-ops.h>
-#include <linux/device.h>
#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/scatterlist.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/export.h>
-
#include <asm/cacheflush.h>
-#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
+#ifndef CONFIG_COLDFIRE
void arch_dma_prep_coherent(struct page *page, size_t size)
{
cache_push(page_to_phys(page), size);
@@ -33,29 +24,6 @@ pgprot_t pgprot_dmacoherent(pgprot_t prot)
}
return prot;
}
-#else
-void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t gfp, unsigned long attrs)
-{
- void *ret;
-
- if (dev == NULL || (*dev->dma_mask < 0xffffffff))
- gfp |= GFP_DMA;
- ret = (void *)__get_free_pages(gfp, get_order(size));
-
- if (ret != NULL) {
- memset(ret, 0, size);
- *dma_handle = virt_to_phys(ret);
- }
- return ret;
-}
-
-void arch_dma_free(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle, unsigned long attrs)
-{
- free_pages((unsigned long)vaddr, get_order(size));
-}
-
#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
void arch_sync_dma_for_device(phys_addr_t handle, size_t size,
diff --git a/arch/m68k/kernel/early_printk.c b/arch/m68k/kernel/early_printk.c
index 7d3fe08a48eb..3cc944df04f6 100644
--- a/arch/m68k/kernel/early_printk.c
+++ b/arch/m68k/kernel/early_printk.c
@@ -12,8 +12,8 @@
#include <linux/string.h>
#include <asm/setup.h>
-extern void mvme16x_cons_write(struct console *co,
- const char *str, unsigned count);
+
+#include "../mvme16x/mvme16x.h"
asmlinkage void __init debug_cons_nputs(const char *s, unsigned n);
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 4dd2fd7acba9..3bcdd32a6b36 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -1,13 +1,10 @@
-/* -*- mode: asm -*-
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * -*- mode: asm -*-
*
* linux/arch/m68k/kernel/entry.S
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
- *
* Linux/m68k support by Hamish Macdonald
*
* 68060 fixes by Jesper Skov
diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S
index 9e812d8606be..852255cf60de 100644
--- a/arch/m68k/kernel/head.S
+++ b/arch/m68k/kernel/head.S
@@ -1,4 +1,5 @@
-/* -*- mode: asm -*-
+/* SPDX-License-Identifier: GPL-2.0-or-later
+** -*- mode: asm -*-
**
** head.S -- This file contains the initial boot code for the
** Linux/68k kernel.
@@ -25,11 +26,6 @@
** for linux-2.1.115
** 1999/02/11 Richard Zidlicky: added Q40 support (initial version 99/01/01)
** 2004/05/13 Kars de Jong: Finalised HP300 support
-**
-** This file is subject to the terms and conditions of the GNU General Public
-** License. See the file README.legal in the main directory of this archive
-** for more details.
-**
*/
/*
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index 5b8d66fbf383..cf2b13488476 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -26,6 +26,8 @@
#include <asm/q40ints.h>
#endif
+#include "ints.h"
+
extern u32 auto_irqhandler_fixup[];
extern u16 user_irqvec_fixup[];
diff --git a/arch/m68k/kernel/ints.h b/arch/m68k/kernel/ints.h
new file mode 100644
index 000000000000..ecac6011c1a4
--- /dev/null
+++ b/arch/m68k/kernel/ints.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+
+struct pt_regs;
+
+asmlinkage void handle_badint(struct pt_regs *regs);
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index e06ce147c0b7..2584e94e2134 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -38,6 +38,7 @@
#include <asm/machdep.h>
#include <asm/setup.h>
+#include "process.h"
asmlinkage void ret_from_fork(void);
asmlinkage void ret_from_kernel_thread(void);
diff --git a/arch/m68k/kernel/process.h b/arch/m68k/kernel/process.h
new file mode 100644
index 000000000000..d31745f2e64b
--- /dev/null
+++ b/arch/m68k/kernel/process.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/linkage.h>
+
+struct pt_regs;
+
+asmlinkage int m68k_clone(struct pt_regs *regs);
+asmlinkage int m68k_clone3(struct pt_regs *regs);
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index cd0172d29430..c20d590e4297 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -26,6 +26,8 @@
#include <asm/page.h>
#include <asm/processor.h>
+#include "ptrace.h"
+
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
diff --git a/arch/m68k/kernel/ptrace.h b/arch/m68k/kernel/ptrace.h
new file mode 100644
index 000000000000..77018037f10f
--- /dev/null
+++ b/arch/m68k/kernel/ptrace.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+
+asmlinkage int syscall_trace_enter(void);
+asmlinkage void syscall_trace_leave(void);
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index 6f1ae01f322c..10310b04f77d 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -107,8 +107,6 @@ EXPORT_SYMBOL(isa_sex);
#define MASK_256K 0xfffc0000
-extern void paging_init(void);
-
static void __init m68k_parse_bootinfo(const struct bi_record *record)
{
const struct bi_record *first_record = record;
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index ba468b5f3f0b..e628b859ef21 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -51,6 +51,8 @@
#include <asm/ucontext.h>
#include <asm/cacheflush.h>
+#include "signal.h"
+
#ifdef CONFIG_MMU
/*
@@ -1109,7 +1111,7 @@ static void do_signal(struct pt_regs *regs)
restore_saved_sigmask();
}
-void do_notify_resume(struct pt_regs *regs)
+asmlinkage void do_notify_resume(struct pt_regs *regs)
{
if (test_thread_flag(TIF_NOTIFY_SIGNAL) ||
test_thread_flag(TIF_SIGPENDING))
diff --git a/arch/m68k/kernel/signal.h b/arch/m68k/kernel/signal.h
new file mode 100644
index 000000000000..498d84f82820
--- /dev/null
+++ b/arch/m68k/kernel/signal.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+
+asmlinkage void do_notify_resume(struct pt_regs *regs);
+asmlinkage void *do_sigreturn(struct pt_regs *regs, struct switch_stack *sw);
+asmlinkage void *do_rt_sigreturn(struct pt_regs *regs, struct switch_stack *sw);
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index c586034d2a7a..1af5e6082467 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -27,6 +27,7 @@
#include <asm/cachectl.h>
#include <asm/traps.h>
#include <asm/page.h>
+#include <asm/syscalls.h>
#include <asm/unistd.h>
#include <asm/cacheflush.h>
@@ -34,8 +35,7 @@
#include <asm/tlb.h>
-asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
- unsigned long error_code);
+#include "../mm/fault.h"
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index f7f997a88bab..7a4b780e82cb 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl
@@ -255,7 +255,7 @@
245 common io_cancel sys_io_cancel
246 common fadvise64 sys_fadvise64
247 common exit_group sys_exit_group
-248 common lookup_dcookie sys_lookup_dcookie
+248 common lookup_dcookie sys_ni_syscall
249 common epoll_create sys_epoll_create
250 common epoll_ctl sys_epoll_ctl
251 common epoll_wait sys_epoll_wait
@@ -452,6 +452,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index a700807c9b6d..53d0cf343d90 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -41,6 +41,9 @@
#include <asm/siginfo.h>
#include <asm/tlbflush.h>
+#include "traps.h"
+#include "../mm/fault.h"
+
static const char *vec_names[] = {
[VEC_RESETSP] = "RESET SP",
[VEC_RESETPC] = "RESET PC",
@@ -124,10 +127,6 @@ static const char *space_names[] = {
};
void die_if_kernel(char *,struct pt_regs *,int);
-asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
- unsigned long error_code);
-int send_fault_sig(struct pt_regs *regs);
-
asmlinkage void trap_c(struct frame *fp);
#if defined (CONFIG_M68060)
@@ -365,7 +364,7 @@ disable_wb:
#if defined(CONFIG_SUN3)
#include <asm/sun3mmu.h>
-extern int mmu_emu_handle_fault (unsigned long, int, int);
+#include "../sun3/sun3.h"
/* sun3 version of bus_error030 */
@@ -487,10 +486,10 @@ static inline void bus_error030 (struct frame *fp)
if (buserr_type & SUN3_BUSERR_INVALID) {
if (!mmu_emu_handle_fault(addr, 1, 0))
do_page_fault (&fp->ptregs, addr, 0);
- } else {
+ } else {
pr_debug("protection fault on insn access (segv).\n");
force_sig (SIGSEGV);
- }
+ }
}
#else
#if defined(CPU_M68020_OR_M68030)
@@ -851,9 +850,9 @@ void show_registers(struct pt_regs *regs)
pr_info("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
pr_info("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);
pr_info("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
- regs->d0, regs->d1, regs->d2, regs->d3);
+ regs->d0, regs->d1, regs->d2, regs->d3);
pr_info("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
- regs->d4, regs->d5, regs->a0, regs->a1);
+ regs->d4, regs->d5, regs->a0, regs->a1);
pr_info("Process %s (pid: %d, task=%p)\n",
current->comm, task_pid_nr(current), current);
@@ -965,7 +964,7 @@ void show_stack(struct task_struct *task, unsigned long *stack,
* real 68k parts, but it won't hurt either.
*/
-void bad_super_trap (struct frame *fp)
+static void bad_super_trap(struct frame *fp)
{
int vector = (fp->ptregs.vector >> 2) & 0xff;
diff --git a/arch/m68k/kernel/traps.h b/arch/m68k/kernel/traps.h
new file mode 100644
index 000000000000..6414b4a0e558
--- /dev/null
+++ b/arch/m68k/kernel/traps.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+
+struct frame;
+
+asmlinkage void buserr_c(struct frame *fp);
+asmlinkage void fpemu_signal(int signal, int code, void *addr);
+asmlinkage void fpsp040_die(void);
+asmlinkage void set_esp0(unsigned long ssp);
diff --git a/arch/m68k/kernel/vectors.c b/arch/m68k/kernel/vectors.c
index 322c977bb9ec..667e848070f4 100644
--- a/arch/m68k/kernel/vectors.c
+++ b/arch/m68k/kernel/vectors.c
@@ -17,6 +17,7 @@
/*
* Sets up all exception vectors
*/
+#include <linux/cpu.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/linkage.h>
@@ -27,6 +28,8 @@
#include <asm/fpu.h>
#include <asm/traps.h>
+#include "vectors.h"
+
/* assembler routines */
asmlinkage void system_call(void);
asmlinkage void buserr(void);
diff --git a/arch/m68k/kernel/vectors.h b/arch/m68k/kernel/vectors.h
new file mode 100644
index 000000000000..897330737ec5
--- /dev/null
+++ b/arch/m68k/kernel/vectors.h
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+void base_trap_init(void);
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
index eca17f14b4d5..9158688e6cc6 100644
--- a/arch/m68k/lib/Makefile
+++ b/arch/m68k/lib/Makefile
@@ -4,8 +4,7 @@
# Makefile for m68k-specific library files..
#
-lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
- memcpy.o memset.o memmove.o
+lib-y := muldi3.o memcpy.o memset.o memmove.o
lib-$(CONFIG_MMU) += uaccess.o
lib-$(CONFIG_CPU_HAS_NO_MULDIV64) += mulsi3.o divsi3.o udivsi3.o
diff --git a/arch/m68k/lib/ashldi3.c b/arch/m68k/lib/ashldi3.c
deleted file mode 100644
index ac08f8141390..000000000000
--- a/arch/m68k/lib/ashldi3.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details. */
-
-#include <linux/compiler.h>
-#include <linux/export.h>
-
-#define BITS_PER_UNIT 8
-
-typedef int SItype __mode(SI);
-typedef unsigned int USItype __mode(SI);
-typedef int DItype __mode(DI);
-typedef int word_type __mode(__word__);
-
-struct DIstruct {SItype high, low;};
-
-typedef union
-{
- struct DIstruct s;
- DItype ll;
-} DIunion;
-
-DItype
-__ashldi3 (DItype u, word_type b)
-{
- DIunion w;
- word_type bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
- if (bm <= 0)
- {
- w.s.low = 0;
- w.s.high = (USItype)uu.s.low << -bm;
- }
- else
- {
- USItype carries = (USItype)uu.s.low >> bm;
- w.s.low = (USItype)uu.s.low << b;
- w.s.high = ((USItype)uu.s.high << b) | carries;
- }
-
- return w.ll;
-}
-EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/m68k/lib/ashrdi3.c b/arch/m68k/lib/ashrdi3.c
deleted file mode 100644
index 5837b1dd3334..000000000000
--- a/arch/m68k/lib/ashrdi3.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
-/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details. */
-
-#include <linux/compiler.h>
-#include <linux/export.h>
-
-#define BITS_PER_UNIT 8
-
-typedef int SItype __mode(SI);
-typedef unsigned int USItype __mode(SI);
-typedef int DItype __mode(DI);
-typedef int word_type __mode(__word__);
-
-struct DIstruct {SItype high, low;};
-
-typedef union
-{
- struct DIstruct s;
- DItype ll;
-} DIunion;
-
-DItype
-__ashrdi3 (DItype u, word_type b)
-{
- DIunion w;
- word_type bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
- if (bm <= 0)
- {
- /* w.s.high = 1..1 or 0..0 */
- w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
- w.s.low = uu.s.high >> -bm;
- }
- else
- {
- USItype carries = (USItype)uu.s.high << bm;
- w.s.high = uu.s.high >> b;
- w.s.low = ((USItype)uu.s.low >> b) | carries;
- }
-
- return w.ll;
-}
-EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/m68k/lib/lshrdi3.c b/arch/m68k/lib/lshrdi3.c
deleted file mode 100644
index 7f40566be6c8..000000000000
--- a/arch/m68k/lib/lshrdi3.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
-/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details. */
-
-#include <linux/compiler.h>
-#include <linux/export.h>
-
-#define BITS_PER_UNIT 8
-
-typedef int SItype __mode(SI);
-typedef unsigned int USItype __mode(SI);
-typedef int DItype __mode(DI);
-typedef int word_type __mode(__word__);
-
-struct DIstruct {SItype high, low;};
-
-typedef union
-{
- struct DIstruct s;
- DItype ll;
-} DIunion;
-
-DItype
-__lshrdi3 (DItype u, word_type b)
-{
- DIunion w;
- word_type bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
- if (bm <= 0)
- {
- w.s.high = 0;
- w.s.low = (USItype)uu.s.high >> -bm;
- }
- else
- {
- USItype carries = (USItype)uu.s.high << bm;
- w.s.high = (USItype)uu.s.high >> b;
- w.s.low = ((USItype)uu.s.low >> b) | carries;
- }
-
- return w.ll;
-}
-EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/m68k/lib/muldi3.c b/arch/m68k/lib/muldi3.c
index eb7d9d86ff66..5012a9b218c7 100644
--- a/arch/m68k/lib/muldi3.c
+++ b/arch/m68k/lib/muldi3.c
@@ -16,6 +16,7 @@ GNU General Public License for more details. */
#include <linux/compiler.h>
#include <linux/export.h>
+#include <linux/libgcc.h>
#ifdef CONFIG_CPU_HAS_NO_MULDIV64
diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c
index a7d280220662..5c97a7058bcd 100644
--- a/arch/m68k/mac/baboon.c
+++ b/arch/m68k/mac/baboon.c
@@ -15,6 +15,8 @@
#include <asm/macints.h>
#include <asm/mac_baboon.h>
+#include "mac.h"
+
int baboon_present;
static volatile struct baboon *baboon;
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 382f656c29ea..e324410ef239 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -50,22 +50,14 @@
#include <asm/mac_psc.h>
#include <asm/config.h>
+#include "mac.h"
+
/* Mac bootinfo struct */
struct mac_booter_data mac_bi_data;
/* The phys. video addr. - might be bogus on some machines */
static unsigned long mac_orig_videoaddr;
-extern int mac_hwclk(int, struct rtc_time *);
-extern void iop_init(void);
-extern void via_init(void);
-extern void via_init_clock(void);
-extern void oss_init(void);
-extern void psc_init(void);
-extern void baboon_init(void);
-
-extern void mac_mksound(unsigned int, unsigned int);
-
static void mac_get_model(char *str);
static void mac_identify(void);
static void mac_report_hardware(void);
@@ -958,7 +950,7 @@ static const struct pata_platform_info mac_pata_data __initconst = {
.ioport_shift = 2,
};
-int __init mac_platform_init(void)
+static int __init mac_platform_init(void)
{
phys_addr_t swim_base = 0;
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
index 010b3b5ae8e8..a92740d530ac 100644
--- a/arch/m68k/mac/iop.c
+++ b/arch/m68k/mac/iop.c
@@ -119,6 +119,8 @@
#include <asm/macints.h>
#include <asm/mac_iop.h>
+#include "mac.h"
+
#ifdef DEBUG
#define iop_pr_debug(fmt, ...) \
printk(KERN_DEBUG "%s: " fmt, __func__, ##__VA_ARGS__)
diff --git a/arch/m68k/mac/mac.h b/arch/m68k/mac/mac.h
new file mode 100644
index 000000000000..d3d142cea3b4
--- /dev/null
+++ b/arch/m68k/mac/mac.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+struct rtc_time;
+
+/* baboon.c */
+void baboon_init(void);
+
+/* iop.c */
+void iop_init(void);
+
+/* misc.c */
+int mac_hwclk(int op, struct rtc_time *t);
+
+/* macboing.c */
+void mac_mksound(unsigned int freq, unsigned int length);
+
+/* oss.c */
+void oss_init(void);
+
+/* psc.c */
+void psc_init(void);
+
+/* via.c */
+void via_init(void);
+void via_init_clock(void);
diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c
index 4de6229c7bfd..faea2265a540 100644
--- a/arch/m68k/mac/macboing.c
+++ b/arch/m68k/mac/macboing.c
@@ -16,6 +16,8 @@
#include <asm/macintosh.h>
#include <asm/mac_asc.h>
+#include "mac.h"
+
static int mac_asc_inited;
/*
* dumb triangular wave table
@@ -23,15 +25,6 @@ static int mac_asc_inited;
static __u8 mac_asc_wave_tab[ 0x800 ];
/*
- * Alan's original sine table; needs interpolating to 0x800
- * (hint: interpolate or hardwire [0 -> Pi/2[, it's symmetric)
- */
-static const signed char sine_data[] = {
- 0, 39, 75, 103, 121, 127, 121, 103, 75, 39,
- 0, -39, -75, -103, -121, -127, -121, -103, -75, -39
-};
-
-/*
* where the ASC hides ...
*/
static volatile __u8* mac_asc_regs = ( void* )0x50F14000;
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index c7cb29f0ff01..4c8f8cbfa05f 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -25,6 +25,8 @@
#include <asm/machdep.h>
+#include "mac.h"
+
/*
* Offset between Unix time (1970-based) and Mac time (1904-based). Cuda and PMU
* times wrap in 2040. If we need to handle later times, the read_time functions
@@ -554,7 +556,7 @@ static void unmktime(time64_t time, long offset,
/* Leap years. */
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
- int days, rem, y, wday, yday;
+ int days, rem, y, wday;
const unsigned short int *ip;
days = div_u64_rem(time, SECS_PER_DAY, &rem);
@@ -592,7 +594,6 @@ static void unmktime(time64_t time, long offset,
y = yg;
}
*yearp = y - 1900;
- yday = days; /* day in the year. Not currently used. */
ip = __mon_yday[__isleap(y)];
for (y = 11; days < (long int) ip[y]; --y)
continue;
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c
index 921e6c092f2c..1641607f300d 100644
--- a/arch/m68k/mac/oss.c
+++ b/arch/m68k/mac/oss.c
@@ -27,6 +27,8 @@
#include <asm/mac_via.h>
#include <asm/mac_oss.h>
+#include "mac.h"
+
int oss_present;
volatile struct mac_oss *oss;
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index 0d0965b19c09..b4183cf66efe 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -26,6 +26,8 @@
#include <asm/macints.h>
#include <asm/mac_psc.h>
+#include "mac.h"
+
#define DEBUG_PSC
volatile __u8 *psc;
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 3d11d6219cdd..01e6b0e37f8d 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -38,6 +38,8 @@
#include <asm/mac_psc.h>
#include <asm/mac_oss.h>
+#include "mac.h"
+
volatile __u8 *via1, *via2;
int rbv_present;
int via_alt_mapping;
diff --git a/arch/m68k/math-emu/fp_arith.c b/arch/m68k/math-emu/fp_arith.c
index f4a06492cd7a..799c450fe322 100644
--- a/arch/m68k/math-emu/fp_arith.c
+++ b/arch/m68k/math-emu/fp_arith.c
@@ -28,8 +28,7 @@ const struct fp_ext fp_Inf =
/* let's start with the easy ones */
-struct fp_ext *
-fp_fabs(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fabs(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "fabs\n");
@@ -40,8 +39,7 @@ fp_fabs(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fneg(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fneg(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "fneg\n");
@@ -57,8 +55,7 @@ fp_fneg(struct fp_ext *dest, struct fp_ext *src)
/* fp_fadd: Implements the kernel of the FADD, FSADD, FDADD, FSUB,
FDSUB, and FCMP instructions. */
-struct fp_ext *
-fp_fadd(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fadd(struct fp_ext *dest, struct fp_ext *src)
{
int diff;
@@ -117,8 +114,7 @@ fp_fadd(struct fp_ext *dest, struct fp_ext *src)
Remember that the arguments are in assembler-syntax order! */
-struct fp_ext *
-fp_fsub(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsub(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "fsub ");
@@ -127,8 +123,7 @@ fp_fsub(struct fp_ext *dest, struct fp_ext *src)
}
-struct fp_ext *
-fp_fcmp(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fcmp(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "fcmp ");
@@ -137,8 +132,7 @@ fp_fcmp(struct fp_ext *dest, struct fp_ext *src)
return fp_fadd(&FPDATA->temp[1], src);
}
-struct fp_ext *
-fp_ftst(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_ftst(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "ftst\n");
@@ -147,8 +141,7 @@ fp_ftst(struct fp_ext *dest, struct fp_ext *src)
return src;
}
-struct fp_ext *
-fp_fmul(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fmul(struct fp_ext *dest, struct fp_ext *src)
{
union fp_mant128 temp;
int exp;
@@ -225,8 +218,7 @@ fp_fmul(struct fp_ext *dest, struct fp_ext *src)
Note that the order of the operands is counter-intuitive: instead
of src / dest, the result is actually dest / src. */
-struct fp_ext *
-fp_fdiv(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fdiv(struct fp_ext *dest, struct fp_ext *src)
{
union fp_mant128 temp;
int exp;
@@ -306,8 +298,7 @@ fp_fdiv(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fsglmul(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsglmul(struct fp_ext *dest, struct fp_ext *src)
{
int exp;
@@ -363,8 +354,7 @@ fp_fsglmul(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fsgldiv(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsgldiv(struct fp_ext *dest, struct fp_ext *src)
{
int exp;
unsigned long quot, rem;
@@ -573,8 +563,8 @@ static void fp_roundint(struct fp_ext *dest, int mode)
(which are exactly the same, except for the rounding used on the
intermediate value) */
-static struct fp_ext *
-modrem_kernel(struct fp_ext *dest, struct fp_ext *src, int mode)
+static struct fp_ext *modrem_kernel(struct fp_ext *dest, struct fp_ext *src,
+ int mode)
{
struct fp_ext tmp;
@@ -607,8 +597,7 @@ modrem_kernel(struct fp_ext *dest, struct fp_ext *src, int mode)
fmod(src,dest) = (dest - (src * floor(dest / src))) */
-struct fp_ext *
-fp_fmod(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fmod(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "fmod\n");
return modrem_kernel(dest, src, FPCR_ROUND_RZ);
@@ -619,15 +608,13 @@ fp_fmod(struct fp_ext *dest, struct fp_ext *src)
frem(src,dest) = (dest - (src * round(dest / src)))
*/
-struct fp_ext *
-fp_frem(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_frem(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "frem\n");
return modrem_kernel(dest, src, FPCR_ROUND_RN);
}
-struct fp_ext *
-fp_fint(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fint(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "fint\n");
@@ -638,8 +625,7 @@ fp_fint(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fintrz(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fintrz(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "fintrz\n");
@@ -650,8 +636,7 @@ fp_fintrz(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fscale(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fscale(struct fp_ext *dest, struct fp_ext *src)
{
int scale, oldround;
diff --git a/arch/m68k/math-emu/fp_arith.h b/arch/m68k/math-emu/fp_arith.h
index 0fd3ed217f66..3f9c58b6d504 100644
--- a/arch/m68k/math-emu/fp_arith.h
+++ b/arch/m68k/math-emu/fp_arith.h
@@ -12,39 +12,28 @@
*/
-#ifndef FP_ARITH_H
-#define FP_ARITH_H
+#ifndef _FP_ARITH_H
+#define _FP_ARITH_H
/* easy ones */
-struct fp_ext *
-fp_fabs(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_fneg(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fabs(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fneg(struct fp_ext *dest, struct fp_ext *src);
/* straightforward arithmetic */
-struct fp_ext *
-fp_fadd(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_fsub(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_fcmp(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_ftst(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_fmul(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_fdiv(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fadd(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsub(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fcmp(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_ftst(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fmul(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fdiv(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsglmul(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsgldiv(struct fp_ext *dest, struct fp_ext *src);
/* ones that do rounding and integer conversions */
-struct fp_ext *
-fp_fmod(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_frem(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_fint(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_fintrz(struct fp_ext *dest, struct fp_ext *src);
-struct fp_ext *
-fp_fscale(struct fp_ext *dest, struct fp_ext *src);
-
-#endif /* FP_ARITH__H */
+struct fp_ext *fp_fmod(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_frem(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fint(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fintrz(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fscale(struct fp_ext *dest, struct fp_ext *src);
+
+#endif /* _FP_ARITH_H */
diff --git a/arch/m68k/math-emu/fp_log.c b/arch/m68k/math-emu/fp_log.c
index 0663067870f2..71a8fc25575a 100644
--- a/arch/m68k/math-emu/fp_log.c
+++ b/arch/m68k/math-emu/fp_log.c
@@ -1,6 +1,6 @@
/*
- fp_trig.c: floating-point math routines for the Linux-m68k
+ fp_log.c: floating-point math routines for the Linux-m68k
floating point emulator.
Copyright (c) 1998-1999 David Huggins-Daines / Roman Zippel.
@@ -15,18 +15,15 @@
*/
+#include "fp_arith.h"
#include "fp_emu.h"
+#include "fp_log.h"
-static const struct fp_ext fp_one =
-{
+static const struct fp_ext fp_one = {
.exp = 0x3fff,
};
-extern struct fp_ext *fp_fadd(struct fp_ext *dest, const struct fp_ext *src);
-extern struct fp_ext *fp_fdiv(struct fp_ext *dest, const struct fp_ext *src);
-
-struct fp_ext *
-fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
{
struct fp_ext tmp, src2;
int i, exp;
@@ -70,7 +67,8 @@ fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
* sqrt(x) = 1 + 1/2*(x-1)
* = 1/2*(1+x)
*/
- fp_fadd(dest, &fp_one);
+ /* It is safe to cast away the constness, as fp_one is normalized */
+ fp_fadd(dest, (struct fp_ext *)&fp_one);
dest->exp--; /* * 1/2 */
/*
@@ -98,8 +96,7 @@ fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fetoxm1(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fetoxm1(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fetoxm1\n");
@@ -108,8 +105,7 @@ fp_fetoxm1(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fetox(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fetox(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fetox\n");
@@ -118,8 +114,7 @@ fp_fetox(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_ftwotox(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_ftwotox(struct fp_ext *dest, struct fp_ext *src)
{
uprint("ftwotox\n");
@@ -128,8 +123,7 @@ fp_ftwotox(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_ftentox(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_ftentox(struct fp_ext *dest, struct fp_ext *src)
{
uprint("ftentox\n");
@@ -138,8 +132,7 @@ fp_ftentox(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_flogn(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_flogn(struct fp_ext *dest, struct fp_ext *src)
{
uprint("flogn\n");
@@ -148,8 +141,7 @@ fp_flogn(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_flognp1(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_flognp1(struct fp_ext *dest, struct fp_ext *src)
{
uprint("flognp1\n");
@@ -158,8 +150,7 @@ fp_flognp1(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_flog10(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_flog10(struct fp_ext *dest, struct fp_ext *src)
{
uprint("flog10\n");
@@ -168,8 +159,7 @@ fp_flog10(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_flog2(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_flog2(struct fp_ext *dest, struct fp_ext *src)
{
uprint("flog2\n");
@@ -178,8 +168,7 @@ fp_flog2(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fgetexp(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fgetexp(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "fgetexp\n");
@@ -199,8 +188,7 @@ fp_fgetexp(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fgetman(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fgetman(struct fp_ext *dest, struct fp_ext *src)
{
dprint(PINSTR, "fgetman\n");
diff --git a/arch/m68k/math-emu/fp_log.h b/arch/m68k/math-emu/fp_log.h
new file mode 100644
index 000000000000..c2bcfff11994
--- /dev/null
+++ b/arch/m68k/math-emu/fp_log.h
@@ -0,0 +1,44 @@
+/*
+
+ fp_log.h: floating-point math routines for the Linux-m68k
+ floating point emulator.
+
+ Copyright (c) 1998-1999 David Huggins-Daines / Roman Zippel.
+
+ I hereby give permission, free of charge, to copy, modify, and
+ redistribute this software, in source or binary form, provided that
+ the above copyright notice and the following disclaimer are included
+ in all such copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS", WITH ABSOLUTELY NO WARRANTY, REAL
+ OR IMPLIED.
+
+*/
+
+#ifndef _FP_LOG_H
+#define _FP_LOG_H
+
+#include "fp_emu.h"
+
+/* floating point logarithmic instructions:
+
+ the arguments to these are in the "internal" extended format, that
+ is, an "exploded" version of the 96-bit extended fp format used by
+ the 68881.
+
+ they return a status code, which should end up in %d0, if all goes
+ well. */
+
+struct fp_ext *fp_fsqrt(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fetoxm1(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fetox(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_ftwotox(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_ftentox(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_flogn(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_flognp1(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_flog10(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_flog2(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fgetexp(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fgetman(struct fp_ext *dest, struct fp_ext *src);
+
+#endif /* _FP_LOG_H */
diff --git a/arch/m68k/math-emu/fp_trig.c b/arch/m68k/math-emu/fp_trig.c
index 6361d0784df2..5f49de373753 100644
--- a/arch/m68k/math-emu/fp_trig.c
+++ b/arch/m68k/math-emu/fp_trig.c
@@ -18,8 +18,7 @@
#include "fp_emu.h"
#include "fp_trig.h"
-struct fp_ext *
-fp_fsin(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsin(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsin\n");
@@ -28,8 +27,7 @@ fp_fsin(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fcos(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fcos(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fcos\n");
@@ -38,8 +36,7 @@ fp_fcos(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_ftan(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_ftan(struct fp_ext *dest, struct fp_ext *src)
{
uprint("ftan\n");
@@ -48,8 +45,7 @@ fp_ftan(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fasin(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fasin(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fasin\n");
@@ -58,8 +54,7 @@ fp_fasin(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_facos(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_facos(struct fp_ext *dest, struct fp_ext *src)
{
uprint("facos\n");
@@ -68,8 +63,7 @@ fp_facos(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fatan(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fatan(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fatan\n");
@@ -78,8 +72,7 @@ fp_fatan(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fsinh(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsinh(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsinh\n");
@@ -88,8 +81,7 @@ fp_fsinh(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fcosh(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fcosh(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fcosh\n");
@@ -98,8 +90,7 @@ fp_fcosh(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_ftanh(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_ftanh(struct fp_ext *dest, struct fp_ext *src)
{
uprint("ftanh\n");
@@ -108,8 +99,7 @@ fp_ftanh(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fatanh(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fatanh(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fatanh\n");
@@ -118,64 +108,56 @@ fp_fatanh(struct fp_ext *dest, struct fp_ext *src)
return dest;
}
-struct fp_ext *
-fp_fsincos0(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsincos0(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsincos0\n");
return dest;
}
-struct fp_ext *
-fp_fsincos1(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsincos1(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsincos1\n");
return dest;
}
-struct fp_ext *
-fp_fsincos2(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsincos2(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsincos2\n");
return dest;
}
-struct fp_ext *
-fp_fsincos3(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsincos3(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsincos3\n");
return dest;
}
-struct fp_ext *
-fp_fsincos4(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsincos4(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsincos4\n");
return dest;
}
-struct fp_ext *
-fp_fsincos5(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsincos5(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsincos5\n");
return dest;
}
-struct fp_ext *
-fp_fsincos6(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsincos6(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsincos6\n");
return dest;
}
-struct fp_ext *
-fp_fsincos7(struct fp_ext *dest, struct fp_ext *src)
+struct fp_ext *fp_fsincos7(struct fp_ext *dest, struct fp_ext *src)
{
uprint("fsincos7\n");
diff --git a/arch/m68k/math-emu/fp_trig.h b/arch/m68k/math-emu/fp_trig.h
index af8b247e9c98..1aae8ab1d41b 100644
--- a/arch/m68k/math-emu/fp_trig.h
+++ b/arch/m68k/math-emu/fp_trig.h
@@ -15,8 +15,8 @@
*/
-#ifndef FP_TRIG_H
-#define FP_TRIG_H
+#ifndef _FP_TRIG_H
+#define _FP_TRIG_H
#include "fp_emu.h"
@@ -29,4 +29,23 @@
they return a status code, which should end up in %d0, if all goes
well. */
-#endif /* FP_TRIG__H */
+struct fp_ext *fp_fsin(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fcos(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_ftan(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fasin(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_facos(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fatan(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsinh(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fcosh(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_ftanh(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fatanh(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsincos0(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsincos1(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsincos2(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsincos3(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsincos4(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsincos5(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsincos6(struct fp_ext *dest, struct fp_ext *src);
+struct fp_ext *fp_fsincos7(struct fp_ext *dest, struct fp_ext *src);
+
+#endif /* _FP_TRIG_H */
diff --git a/arch/m68k/math-emu/multi_arith.h b/arch/m68k/math-emu/multi_arith.h
index 232f58fe3483..f7d9e49fe259 100644
--- a/arch/m68k/math-emu/multi_arith.h
+++ b/arch/m68k/math-emu/multi_arith.h
@@ -15,8 +15,10 @@
implement the subset of integer arithmetic that we need in order to
multiply, divide, and normalize 128-bit unsigned mantissae. */
-#ifndef MULTI_ARITH_H
-#define MULTI_ARITH_H
+#ifndef _MULTI_ARITH_H
+#define _MULTI_ARITH_H
+
+#include "fp_emu.h"
static inline void fp_denormalize(struct fp_ext *reg, unsigned int cnt)
{
@@ -285,4 +287,4 @@ static inline void fp_putmant128(struct fp_ext *dest, union fp_mant128 *src,
}
}
-#endif /* MULTI_ARITH_H */
+#endif /* _MULTI_ARITH_H */
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index c290c5c0cfb9..fa3c5f38d989 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -17,6 +17,8 @@
#include <asm/setup.h>
#include <asm/traps.h>
+#include "fault.h"
+
extern void die_if_kernel(char *, struct pt_regs *, long);
int send_fault_sig(struct pt_regs *regs)
diff --git a/arch/m68k/mm/fault.h b/arch/m68k/mm/fault.h
new file mode 100644
index 000000000000..dab14ef7d4a1
--- /dev/null
+++ b/arch/m68k/mm/fault.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+struct pt_regs;
+
+int do_page_fault(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code);
+int send_fault_sig(struct pt_regs *regs);
diff --git a/arch/m68k/mm/hwtest.c b/arch/m68k/mm/hwtest.c
index fe99aa99987e..8ee7a3368688 100644
--- a/arch/m68k/mm/hwtest.c
+++ b/arch/m68k/mm/hwtest.c
@@ -26,6 +26,8 @@
#include <linux/module.h>
+#include <asm/hwtest.h>
+
int hwreg_present(volatile void *regp)
{
int ret = 0;
diff --git a/arch/m68k/mm/sun3kmap.c b/arch/m68k/mm/sun3kmap.c
index 4f2a7ef8348b..ac091892d82f 100644
--- a/arch/m68k/mm/sun3kmap.c
+++ b/arch/m68k/mm/sun3kmap.c
@@ -18,11 +18,9 @@
#include <asm/io.h>
#include <asm/sun3mmu.h>
-#undef SUN3_KMAP_DEBUG
+#include "../sun3/sun3.h"
-#ifdef SUN3_KMAP_DEBUG
-extern void print_pte_vaddr(unsigned long vaddr);
-#endif
+#undef SUN3_KMAP_DEBUG
extern void mmu_emu_map_pmeg (int context, int vaddr);
diff --git a/arch/m68k/mm/sun3mmu.c b/arch/m68k/mm/sun3mmu.c
index c5e6a23e0262..494739c1783e 100644
--- a/arch/m68k/mm/sun3mmu.c
+++ b/arch/m68k/mm/sun3mmu.c
@@ -24,7 +24,7 @@
#include <asm/machdep.h>
#include <asm/io.h>
-extern void mmu_emu_init (unsigned long bootmem_end);
+#include "../sun3/sun3.h"
const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
index 4e6218115f43..8b5dc07f0811 100644
--- a/arch/m68k/mvme147/config.c
+++ b/arch/m68k/mvme147/config.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* arch/m68k/mvme147/config.c
*
@@ -7,10 +8,6 @@
* Based on:
*
* Copyright (C) 1993 Hamish Macdonald
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
*/
#include <linux/types.h>
@@ -73,7 +70,7 @@ static void mvme147_get_model(char *model)
* the mvme147 IRQ handling routines.
*/
-void __init mvme147_init_IRQ(void)
+static void __init mvme147_init_IRQ(void)
{
m68k_setup_user_interrupt(VEC_USER, 192);
}
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index f00c7aa058de..d1fbd1704d65 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* arch/m68k/mvme16x/config.c
*
@@ -8,10 +9,6 @@
* linux/amiga/config.c
*
* Copyright (C) 1993 Hamish Macdonald
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
*/
#include <linux/types.h>
@@ -38,6 +35,8 @@
#include <asm/mvme16xhw.h>
#include <asm/config.h>
+#include "mvme16x.h"
+
extern t_bdid mvme_bdid;
static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
@@ -208,7 +207,6 @@ static void __init mvme16x_init_IRQ (void)
void mvme16x_cons_write(struct console *co, const char *str, unsigned count)
{
volatile unsigned char *base_addr = (u_char *)CD2401_ADDR;
- volatile u_char sink;
u_char ier;
int port;
u_char do_lf = 0;
@@ -229,7 +227,7 @@ void mvme16x_cons_write(struct console *co, const char *str, unsigned count)
if (in_8(PCCSCCTICR) & 0x20)
{
/* We have a Tx int. Acknowledge it */
- sink = in_8(PCCTPIACKR);
+ in_8(PCCTPIACKR);
if ((base_addr[CyLICR] >> 2) == port) {
if (i == count) {
/* Last char of string is now output */
diff --git a/arch/m68k/mvme16x/mvme16x.h b/arch/m68k/mvme16x/mvme16x.h
new file mode 100644
index 000000000000..159c34b70039
--- /dev/null
+++ b/arch/m68k/mvme16x/mvme16x.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+struct console;
+
+/* config.c */
+void mvme16x_cons_write(struct console *co, const char *str, unsigned count);
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index c78ee709b458..de7870ad2a30 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* arch/m68k/q40/config.c
*
@@ -6,10 +7,6 @@
* originally based on:
*
* linux/bvme/config.c
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
*/
#include <linux/errno.h>
@@ -36,16 +33,14 @@
#include <asm/q40_master.h>
#include <asm/config.h>
-extern void q40_init_IRQ(void);
+#include "q40.h"
+
static void q40_get_model(char *model);
-extern void q40_sched_init(void);
static int q40_hwclk(int, struct rtc_time *);
static int q40_get_rtc_pll(struct rtc_pll_info *pll);
static int q40_set_rtc_pll(struct rtc_pll_info *pll);
-extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/);
-
static void q40_mem_console_write(struct console *co, const char *b,
unsigned int count);
diff --git a/arch/m68k/q40/q40.h b/arch/m68k/q40/q40.h
new file mode 100644
index 000000000000..3146679bde0d
--- /dev/null
+++ b/arch/m68k/q40/q40.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* q40ints.c */
+void q40_init_IRQ(void);
+void q40_mksound(unsigned int hz, unsigned int ticks);
+void q40_sched_init(void);
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
index 127d7ecdbd49..10f1f294e91f 100644
--- a/arch/m68k/q40/q40ints.c
+++ b/arch/m68k/q40/q40ints.c
@@ -24,6 +24,8 @@
#include <asm/q40_master.h>
#include <asm/q40ints.h>
+#include "q40.h"
+
/*
* Q40 IRQs are defined as follows:
* 3,4,5,6,7,10,11,14,15 : ISA dev IRQs
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
index 203f428a0344..cd8af809e0ca 100644
--- a/arch/m68k/sun3/config.c
+++ b/arch/m68k/sun3/config.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/memblock.h>
#include <linux/platform_device.h>
+#include <linux/linkage.h>
#include <asm/oplib.h>
#include <asm/setup.h>
@@ -32,12 +33,13 @@
#include <asm/irq.h>
#include <asm/sections.h>
#include <asm/sun3ints.h>
+#include <asm/config.h>
+
+#include "sun3.h"
char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
static void sun3_sched_init(void);
-extern void sun3_get_model (char* model);
-extern int sun3_hwclk(int set, struct rtc_time *t);
volatile char* clock_va;
extern unsigned long availmem;
@@ -48,7 +50,7 @@ static void sun3_get_hardware_list(struct seq_file *m)
seq_printf(m, "PROM Revision:\t%s\n", romvec->pv_monid);
}
-void __init sun3_init(void)
+asmlinkage void __init sun3_init(void)
{
unsigned char enable_register;
int i;
@@ -107,13 +109,10 @@ static void sun3_halt (void)
static void __init sun3_bootmem_alloc(unsigned long memory_start,
unsigned long memory_end)
{
- unsigned long start_page;
-
/* align start/end to page boundaries */
memory_start = ((memory_start + (PAGE_SIZE-1)) & PAGE_MASK);
memory_end = memory_end & PAGE_MASK;
- start_page = __pa(memory_start) >> PAGE_SHIFT;
max_pfn = num_pages = __pa(memory_end) >> PAGE_SHIFT;
high_memory = (void *)memory_end;
@@ -200,7 +199,7 @@ static const struct resource sun3_scsi_rsrc[] __initconst = {
},
};
-int __init sun3_platform_init(void)
+static int __init sun3_platform_init(void)
{
switch (idprom->id_machtype) {
case SM_SUN3 | SM_3_160:
diff --git a/arch/m68k/sun3/idprom.c b/arch/m68k/sun3/idprom.c
index 1ace5353d78f..ca633a5f5eb1 100644
--- a/arch/m68k/sun3/idprom.c
+++ b/arch/m68k/sun3/idprom.c
@@ -17,6 +17,8 @@
#include <asm/idprom.h>
#include <asm/machines.h> /* Fun with Sun released architectures. */
+#include "sun3.h"
+
struct idprom *idprom;
EXPORT_SYMBOL(idprom);
@@ -83,7 +85,7 @@ static void __init display_system_type(unsigned char machtype)
prom_halt();
}
-void sun3_get_model(unsigned char* model)
+void sun3_get_model(char *model)
{
register int i;
diff --git a/arch/m68k/sun3/intersil.c b/arch/m68k/sun3/intersil.c
index 8fc74864de81..29674cfa9bb3 100644
--- a/arch/m68k/sun3/intersil.c
+++ b/arch/m68k/sun3/intersil.c
@@ -17,6 +17,7 @@
#include <asm/intersil.h>
#include <asm/machdep.h>
+#include "sun3.h"
/* bits to set for start/run of the intersil */
#define STOP_VAL (INTERSIL_STOP | INTERSIL_INT_ENABLE | INTERSIL_24H_MODE)
diff --git a/arch/m68k/sun3/leds.c b/arch/m68k/sun3/leds.c
index 7c67b58ebf13..4bb95318fd54 100644
--- a/arch/m68k/sun3/leds.c
+++ b/arch/m68k/sun3/leds.c
@@ -3,6 +3,8 @@
#include <asm/sun3mmu.h>
#include <asm/io.h>
+#include "sun3.h"
+
void sun3_leds(unsigned char byte)
{
unsigned char dfc;
diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c
index 7321b3b76283..119bd32efcfb 100644
--- a/arch/m68k/sun3/mmu_emu.c
+++ b/arch/m68k/sun3/mmu_emu.c
@@ -27,6 +27,7 @@
#include <asm/mmu_context.h>
#include <asm/dvma.h>
+#include "sun3.h"
#undef DEBUG_MMU_EMU
#define DEBUG_PROM_MAPS
@@ -67,7 +68,7 @@ static unsigned char ctx_avail = CONTEXTS_NUM-1;
unsigned long rom_pages[256];
/* Print a PTE value in symbolic form. For debugging. */
-void print_pte (pte_t pte)
+static void print_pte(pte_t pte)
{
#if 0
/* Verbose version. */
@@ -206,32 +207,32 @@ void __init mmu_emu_init(unsigned long bootmem_end)
context for when they're cleared */
void clear_context(unsigned long context)
{
- unsigned char oldctx;
- unsigned long i;
+ unsigned char oldctx;
+ unsigned long i;
- if(context) {
- if(!ctx_alloc[context])
- panic("%s: context not allocated\n", __func__);
+ if (context) {
+ if (!ctx_alloc[context])
+ panic("%s: context not allocated\n", __func__);
- ctx_alloc[context]->context = SUN3_INVALID_CONTEXT;
- ctx_alloc[context] = (struct mm_struct *)0;
- ctx_avail++;
- }
+ ctx_alloc[context]->context = SUN3_INVALID_CONTEXT;
+ ctx_alloc[context] = (struct mm_struct *)0;
+ ctx_avail++;
+ }
- oldctx = sun3_get_context();
+ oldctx = sun3_get_context();
- sun3_put_context(context);
+ sun3_put_context(context);
- for(i = 0; i < SUN3_INVALID_PMEG; i++) {
- if((pmeg_ctx[i] == context) && (pmeg_alloc[i] == 1)) {
- sun3_put_segmap(pmeg_vaddr[i], SUN3_INVALID_PMEG);
- pmeg_ctx[i] = 0;
- pmeg_alloc[i] = 0;
- pmeg_vaddr[i] = 0;
- }
- }
+ for (i = 0; i < SUN3_INVALID_PMEG; i++) {
+ if ((pmeg_ctx[i] == context) && (pmeg_alloc[i] == 1)) {
+ sun3_put_segmap(pmeg_vaddr[i], SUN3_INVALID_PMEG);
+ pmeg_ctx[i] = 0;
+ pmeg_alloc[i] = 0;
+ pmeg_vaddr[i] = 0;
+ }
+ }
- sun3_put_context(oldctx);
+ sun3_put_context(oldctx);
}
/* gets an empty context. if full, kills the next context listed to
diff --git a/arch/m68k/sun3/prom/printf.c b/arch/m68k/sun3/prom/printf.c
index b6724cc66795..db5537ef1250 100644
--- a/arch/m68k/sun3/prom/printf.c
+++ b/arch/m68k/sun3/prom/printf.c
@@ -25,15 +25,14 @@ prom_printf(char *fmt, ...)
{
va_list args;
char ch, *bptr;
- int i;
va_start(args, fmt);
#ifdef CONFIG_KGDB
ppbuf[0] = 'O';
- i = vsprintf(ppbuf + 1, fmt, args) + 1;
+ vsprintf(ppbuf + 1, fmt, args) + 1;
#else
- i = vsprintf(ppbuf, fmt, args);
+ vsprintf(ppbuf, fmt, args);
#endif
bptr = ppbuf;
diff --git a/arch/m68k/sun3/sun3.h b/arch/m68k/sun3/sun3.h
new file mode 100644
index 000000000000..8d98c0aaedc0
--- /dev/null
+++ b/arch/m68k/sun3/sun3.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/linkage.h>
+
+struct rtc_time;
+
+/* config.c */
+asmlinkage void sun3_init(void);
+
+/* idprom.c */
+void sun3_get_model(char *model);
+
+/* intersil.c */
+int sun3_hwclk(int set, struct rtc_time *t);
+
+/* leds.c */
+void sun3_leds(unsigned char byte);
+
+/* mmu_emu.c */
+void mmu_emu_init(unsigned long bootmem_end);
+int mmu_emu_handle_fault(unsigned long vaddr, int read_flag, int kernel_fault);
+void print_pte_vaddr(unsigned long vaddr);
diff --git a/arch/m68k/sun3/sun3dvma.c b/arch/m68k/sun3/sun3dvma.c
index 4b560f4d3960..6ebf52740ad7 100644
--- a/arch/m68k/sun3/sun3dvma.c
+++ b/arch/m68k/sun3/sun3dvma.c
@@ -20,18 +20,6 @@
#undef DVMA_DEBUG
-#ifdef CONFIG_SUN3X
-extern void dvma_unmap_iommu(unsigned long baddr, int len);
-#else
-static inline void dvma_unmap_iommu(unsigned long a, int b)
-{
-}
-#endif
-
-#ifdef CONFIG_SUN3
-extern void sun3_dvma_init(void);
-#endif
-
static unsigned long *iommu_use;
#define dvma_index(baddr) ((baddr - DVMA_START) >> DVMA_PAGE_SHIFT)
@@ -205,9 +193,7 @@ static inline int free_baddr(unsigned long baddr)
unsigned long len;
struct hole *hole;
struct list_head *cur;
- unsigned long orig_baddr;
- orig_baddr = baddr;
len = dvma_entry_use(baddr);
dvma_entry_use(baddr) = 0;
baddr &= DVMA_PAGE_MASK;
@@ -274,10 +260,7 @@ void __init dvma_init(void)
dvma_unmap_iommu(DVMA_START, DVMA_SIZE);
-#ifdef CONFIG_SUN3
sun3_dvma_init();
-#endif
-
}
unsigned long dvma_map_align(unsigned long kaddr, int len, int align)
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 36cc280a4505..32eaf55f87be 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -17,7 +17,7 @@
#include <asm/irq_regs.h>
#include <linux/seq_file.h>
-extern void sun3_leds (unsigned char);
+#include "sun3.h"
void sun3_disable_interrupts(void)
{
@@ -29,11 +29,11 @@ void sun3_enable_interrupts(void)
sun3_enable_irq(0);
}
-static int led_pattern[8] = {
- ~(0x80), ~(0x01),
- ~(0x40), ~(0x02),
- ~(0x20), ~(0x04),
- ~(0x10), ~(0x08)
+static unsigned char led_pattern[8] = {
+ (u8)~(0x80), (u8)~(0x01),
+ (u8)~(0x40), (u8)~(0x02),
+ (u8)~(0x20), (u8)~(0x04),
+ (u8)~(0x10), (u8)~(0x08)
};
volatile unsigned char* sun3_intreg;
diff --git a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c
index 37121a0f1253..798ea72a0ea3 100644
--- a/arch/m68k/sun3x/config.c
+++ b/arch/m68k/sun3x/config.c
@@ -19,14 +19,14 @@
#include <asm/sun3ints.h>
#include <asm/setup.h>
#include <asm/oplib.h>
+#include <asm/config.h>
#include "time.h"
+#include "../sun3/sun3.h"
volatile char *clock_va;
-extern void sun3_get_model(char *model);
-
-void sun3_leds(unsigned int i)
+void sun3_leds(unsigned char byte)
{
}
diff --git a/arch/m68k/sun3x/dvma.c b/arch/m68k/sun3x/dvma.c
index a6034ba05845..5185b4818d40 100644
--- a/arch/m68k/sun3x/dvma.c
+++ b/arch/m68k/sun3x/dvma.c
@@ -60,7 +60,7 @@ static volatile unsigned long *iommu_pte = (unsigned long *)SUN3X_IOMMU;
#ifdef DEBUG
/* code to print out a dvma mapping for debugging purposes */
-void dvma_print (unsigned long dvma_addr)
+static void dvma_print (unsigned long dvma_addr)
{
unsigned long index;
@@ -143,8 +143,7 @@ inline int dvma_map_cpu(unsigned long kaddr,
}
-inline int dvma_map_iommu(unsigned long kaddr, unsigned long baddr,
- int len)
+int dvma_map_iommu(unsigned long kaddr, unsigned long baddr, int len)
{
unsigned long end, index;
diff --git a/arch/m68k/sun3x/prom.c b/arch/m68k/sun3x/prom.c
index 64c23bfaa90c..8ac87d3dc607 100644
--- a/arch/m68k/sun3x/prom.c
+++ b/arch/m68k/sun3x/prom.c
@@ -30,7 +30,7 @@ struct linux_romvec *romvec;
e_vector *sun3x_prom_vbr;
/* Handle returning to the prom */
-void sun3x_halt(void)
+static void sun3x_halt(void)
{
unsigned long flags;
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index 2967ec26b978..5b6a0b02b7de 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
@@ -260,7 +260,7 @@
250 common fadvise64 sys_fadvise64
# 251 is available for reuse (was briefly sys_set_zone_reclaim)
252 common exit_group sys_exit_group
-253 common lookup_dcookie sys_lookup_dcookie
+253 common lookup_dcookie sys_ni_syscall
254 common epoll_create sys_epoll_create
255 common epoll_ctl sys_epoll_ctl
256 common epoll_wait sys_epoll_wait
@@ -458,6 +458,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index 383abb1713f4..a842b41c8e06 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -214,7 +214,7 @@
203 n32 io_submit compat_sys_io_submit
204 n32 io_cancel sys_io_cancel
205 n32 exit_group sys_exit_group
-206 n32 lookup_dcookie sys_lookup_dcookie
+206 n32 lookup_dcookie sys_ni_syscall
207 n32 epoll_create sys_epoll_create
208 n32 epoll_ctl sys_epoll_ctl
209 n32 epoll_wait sys_epoll_wait
@@ -391,6 +391,7 @@
450 n32 set_mempolicy_home_node sys_set_mempolicy_home_node
451 n32 cachestat sys_cachestat
452 n32 fchmodat2 sys_fchmodat2
+453 n32 map_shadow_stack sys_map_shadow_stack
454 n32 futex_wake sys_futex_wake
455 n32 futex_wait sys_futex_wait
456 n32 futex_requeue sys_futex_requeue
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index c9bd09ba905f..116ff501bf92 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -214,7 +214,7 @@
203 n64 io_submit sys_io_submit
204 n64 io_cancel sys_io_cancel
205 n64 exit_group sys_exit_group
-206 n64 lookup_dcookie sys_lookup_dcookie
+206 n64 lookup_dcookie sys_ni_syscall
207 n64 epoll_create sys_epoll_create
208 n64 epoll_ctl sys_epoll_ctl
209 n64 epoll_wait sys_epoll_wait
@@ -367,6 +367,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 n64 cachestat sys_cachestat
452 n64 fchmodat2 sys_fchmodat2
+453 n64 map_shadow_stack sys_map_shadow_stack
454 n64 futex_wake sys_futex_wake
455 n64 futex_wait sys_futex_wait
456 n64 futex_requeue sys_futex_requeue
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index ba5ef6cea97a..525cc54bc63b 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -258,7 +258,7 @@
244 o32 io_submit sys_io_submit compat_sys_io_submit
245 o32 io_cancel sys_io_cancel
246 o32 exit_group sys_exit_group
-247 o32 lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie
+247 o32 lookup_dcookie sys_ni_syscall
248 o32 epoll_create sys_epoll_create
249 o32 epoll_ctl sys_epoll_ctl
250 o32 epoll_wait sys_epoll_wait
@@ -440,6 +440,7 @@
450 o32 set_mempolicy_home_node sys_set_mempolicy_home_node
451 o32 cachestat sys_cachestat
452 o32 fchmodat2 sys_fchmodat2
+453 o32 map_shadow_stack sys_map_shadow_stack
454 o32 futex_wake sys_futex_wake
455 o32 futex_wait sys_futex_wait
456 o32 futex_requeue sys_futex_requeue
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index a15ab147af2e..fd69dfa0cdab 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -8,6 +8,7 @@ config PARISC
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_SYSCALL_TRACEPOINTS
select ARCH_WANT_FRAME_POINTERS
+ select ARCH_HAS_DMA_ALLOC if PA11
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_HAS_STRICT_MODULE_RWX
@@ -25,6 +26,7 @@ config PARISC
select INIT_ALL_POSSIBLE
select BUG
select BUILDTIME_TABLE_SORT
+ select HAVE_KERNEL_UNCOMPRESSED
select HAVE_PCI
select HAVE_PERF_EVENTS
select HAVE_KERNEL_BZIP2
diff --git a/arch/parisc/boot/Makefile b/arch/parisc/boot/Makefile
index b873ee4720ca..657f967240ee 100644
--- a/arch/parisc/boot/Makefile
+++ b/arch/parisc/boot/Makefile
@@ -10,7 +10,7 @@ subdir- := compressed
$(obj)/image: vmlinux FORCE
$(call if_changed,objcopy)
-$(obj)/bzImage: $(obj)/compressed/vmlinux FORCE
+$(obj)/bzImage: $(if $(CONFIG_KERNEL_UNCOMPRESSED),$(objtree)/vmlinux,$(obj)/compressed/vmlinux) FORCE
$(call if_changed,objcopy)
$(obj)/compressed/vmlinux: FORCE
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h
index ff6cbdb6903b..c05d121cf5d0 100644
--- a/arch/parisc/include/asm/processor.h
+++ b/arch/parisc/include/asm/processor.h
@@ -287,6 +287,7 @@ extern int _parisc_requires_coherency;
#endif
extern int running_on_qemu;
+extern int parisc_narrow_firmware;
extern void __noreturn toc_intr(struct pt_regs *regs);
extern void toc_handler(void);
diff --git a/arch/parisc/include/uapi/asm/pdc.h b/arch/parisc/include/uapi/asm/pdc.h
index 7a90070136e8..fef4f2e96160 100644
--- a/arch/parisc/include/uapi/asm/pdc.h
+++ b/arch/parisc/include/uapi/asm/pdc.h
@@ -58,8 +58,8 @@
#define PDC_MODEL_NVA_SUPPORTED (0 << 4)
#define PDC_MODEL_NVA_SLOW (1 << 4)
#define PDC_MODEL_NVA_UNSUPPORTED (3 << 4)
-#define PDC_MODEL_GET_BOOT__OP 8 /* returns boot test options */
-#define PDC_MODEL_SET_BOOT__OP 9 /* set boot test options */
+#define PDC_MODEL_FIRM_TEST_GET 8 /* returns boot test options */
+#define PDC_MODEL_FIRM_TEST_SET 9 /* set boot test options */
#define PDC_MODEL_GET_PLATFORM_INFO 10 /* returns platform info */
#define PDC_MODEL_GET_INSTALL_KERNEL 11 /* returns kernel for installation */
@@ -472,6 +472,7 @@ struct pdc_model { /* for PDC_MODEL */
unsigned long arch_rev;
unsigned long pot_key;
unsigned long curr_key;
+ unsigned long width; /* default of PSW_W bit (1=enabled) */
};
struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */
@@ -609,6 +610,12 @@ struct pdc_system_map_addr_info { /* PDC_SYSTEM_MAP/FIND_ADDRESS */
unsigned long mod_pgs;
};
+struct pdc_relocate_info_block { /* PDC_RELOCATE_INFO */
+ unsigned long pdc_size;
+ unsigned long pdc_alignment;
+ unsigned long pdc_address;
+};
+
struct pdc_initiator { /* PDC_INITIATOR */
int host_id;
int factor;
@@ -717,6 +724,23 @@ struct pdc_toc_pim_20 {
struct pim_cpu_state_cf cpu_state;
};
+/* for SpeedyBoot/firm_ctl funtionality */
+struct pdc_firm_test_get_rtn_block { /* PDC_MODEL/PDC_FIRM_TEST_GET */
+ unsigned long current_tests; /* u_R_addr Raddr_ints[0] */
+ unsigned long tests_supported; /* u_R_addr Raddr_ints[1] */
+ unsigned long default_tests; /* u_R_addr Raddr_ints[2] */
+};
+
+#define TORNADO_CPU_ID 0xB
+#define PCXL_CPU_ID 0xD
+#define PCXU_CPU_ID 0xE /* U and U+ for all but C-class with bug */
+#define VR_CPU_ID 0xF
+#define PCXU_PLUS_CPU_ID 0x10 /* U+ only on C-class with bug */
+#define PCXW_CPU_ID 0x11
+#define PCXW_PLUS_CPU_ID 0x12
+#define PIRANHA_CPU_ID 0x13
+#define MAKO_CPU_ID 0x14
+
#endif /* !defined(__ASSEMBLY__) */
#endif /* _UAPI_PARISC_PDC_H */
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index ed8b75948061..25f9b9e9d6df 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -927,8 +927,8 @@ static __init void qemu_header(void)
#define p ((unsigned long *)&boot_cpu_data.pdc.model)
pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, "
- "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n",
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
+ "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
#undef p
pr_info("#define PARISC_PDC_VERSION 0x%04lx\n\n",
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index ae03b8679696..cab1ec23e0d7 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -36,6 +36,24 @@
.level 2.0
#endif
+/*
+ * We need seven instructions after a TLB insert for it to take effect.
+ * The PA8800/PA8900 processors are an exception and need 12 instructions.
+ * The RFI changes both IAOQ_Back and IAOQ_Front, so it counts as one.
+ */
+#ifdef CONFIG_64BIT
+#define NUM_PIPELINE_INSNS 12
+#else
+#define NUM_PIPELINE_INSNS 7
+#endif
+
+ /* Insert num nops */
+ .macro insert_nops num
+ .rept \num
+ nop
+ .endr
+ .endm
+
/* Get aligned page_table_lock address for this mm from cr28/tr4 */
.macro get_ptl reg
mfctl %cr28,\reg
@@ -415,24 +433,20 @@
3:
.endm
- /* Release page_table_lock without reloading lock address.
- We use an ordered store to ensure all prior accesses are
- performed prior to releasing the lock. */
- .macro ptl_unlock0 spc,tmp,tmp2
+ /* Release page_table_lock if for user space. We use an ordered
+ store to ensure all prior accesses are performed prior to
+ releasing the lock. Note stw may not be executed, so we
+ provide one extra nop when CONFIG_TLB_PTLOCK is defined. */
+ .macro ptl_unlock spc,tmp,tmp2
#ifdef CONFIG_TLB_PTLOCK
-98: ldi __ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmp2
+98: get_ptl \tmp
+ ldi __ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmp2
or,COND(=) %r0,\spc,%r0
stw,ma \tmp2,0(\tmp)
99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
-#endif
- .endm
-
- /* Release page_table_lock. */
- .macro ptl_unlock1 spc,tmp,tmp2
-#ifdef CONFIG_TLB_PTLOCK
-98: get_ptl \tmp
- ptl_unlock0 \spc,\tmp,\tmp2
-99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+ insert_nops NUM_PIPELINE_INSNS - 4
+#else
+ insert_nops NUM_PIPELINE_INSNS - 1
#endif
.endm
@@ -1124,7 +1138,7 @@ dtlb_miss_20w:
idtlbt pte,prot
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1133,6 +1147,7 @@ dtlb_check_alias_20w:
idtlbt pte,prot
+ insert_nops NUM_PIPELINE_INSNS - 1
rfir
nop
@@ -1150,7 +1165,7 @@ nadtlb_miss_20w:
idtlbt pte,prot
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1159,6 +1174,7 @@ nadtlb_check_alias_20w:
idtlbt pte,prot
+ insert_nops NUM_PIPELINE_INSNS - 1
rfir
nop
@@ -1184,7 +1200,7 @@ dtlb_miss_11:
mtsp t1, %sr1 /* Restore sr1 */
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1194,6 +1210,7 @@ dtlb_check_alias_11:
idtlba pte,(va)
idtlbp prot,(va)
+ insert_nops NUM_PIPELINE_INSNS - 1
rfir
nop
@@ -1217,7 +1234,7 @@ nadtlb_miss_11:
mtsp t1, %sr1 /* Restore sr1 */
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1227,6 +1244,7 @@ nadtlb_check_alias_11:
idtlba pte,(va)
idtlbp prot,(va)
+ insert_nops NUM_PIPELINE_INSNS - 1
rfir
nop
@@ -1246,7 +1264,7 @@ dtlb_miss_20:
idtlbt pte,prot
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1255,6 +1273,7 @@ dtlb_check_alias_20:
idtlbt pte,prot
+ insert_nops NUM_PIPELINE_INSNS - 1
rfir
nop
@@ -1274,7 +1293,7 @@ nadtlb_miss_20:
idtlbt pte,prot
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1283,6 +1302,7 @@ nadtlb_check_alias_20:
idtlbt pte,prot
+ insert_nops NUM_PIPELINE_INSNS - 1
rfir
nop
@@ -1319,7 +1339,7 @@ itlb_miss_20w:
iitlbt pte,prot
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1343,7 +1363,7 @@ naitlb_miss_20w:
iitlbt pte,prot
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1352,6 +1372,7 @@ naitlb_check_alias_20w:
iitlbt pte,prot
+ insert_nops NUM_PIPELINE_INSNS - 1
rfir
nop
@@ -1377,7 +1398,7 @@ itlb_miss_11:
mtsp t1, %sr1 /* Restore sr1 */
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1401,7 +1422,7 @@ naitlb_miss_11:
mtsp t1, %sr1 /* Restore sr1 */
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1411,6 +1432,7 @@ naitlb_check_alias_11:
iitlba pte,(%sr0, va)
iitlbp prot,(%sr0, va)
+ insert_nops NUM_PIPELINE_INSNS - 1
rfir
nop
@@ -1431,7 +1453,7 @@ itlb_miss_20:
iitlbt pte,prot
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1451,7 +1473,7 @@ naitlb_miss_20:
iitlbt pte,prot
- ptl_unlock1 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1460,6 +1482,7 @@ naitlb_check_alias_20:
iitlbt pte,prot
+ insert_nops NUM_PIPELINE_INSNS - 1
rfir
nop
@@ -1481,7 +1504,7 @@ dbit_trap_20w:
idtlbt pte,prot
- ptl_unlock0 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
#else
@@ -1507,7 +1530,7 @@ dbit_trap_11:
mtsp t1, %sr1 /* Restore sr1 */
- ptl_unlock0 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
@@ -1527,7 +1550,7 @@ dbit_trap_20:
idtlbt pte,prot
- ptl_unlock0 spc,t0,t1
+ ptl_unlock spc,t0,t1
rfir
nop
#endif
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 81078abec521..904ca3b9e7a7 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -78,12 +78,12 @@ static unsigned long pdc_result[NUM_PDC_RESULT] __aligned(8);
static unsigned long pdc_result2[NUM_PDC_RESULT] __aligned(8);
#ifdef CONFIG_64BIT
-#define WIDE_FIRMWARE 0x1
-#define NARROW_FIRMWARE 0x2
+#define WIDE_FIRMWARE PDC_MODEL_OS64
+#define NARROW_FIRMWARE PDC_MODEL_OS32
-/* Firmware needs to be initially set to narrow to determine the
+/* Firmware needs to be initially set to narrow to determine the
* actual firmware width. */
-int parisc_narrow_firmware __ro_after_init = 2;
+int parisc_narrow_firmware __ro_after_init = NARROW_FIRMWARE;
#endif
/* On most currently-supported platforms, IODC I/O calls are 32-bit calls
@@ -166,10 +166,10 @@ void set_firmware_width_unlocked(void)
if (pdc_result[0] != NARROW_FIRMWARE)
parisc_narrow_firmware = 0;
}
-
+
/**
* set_firmware_width - Determine if the firmware is wide or narrow.
- *
+ *
* This function must be called before any pdc_* function that uses the
* convert_to_wide function.
*/
@@ -178,7 +178,7 @@ void set_firmware_width(void)
unsigned long flags;
/* already initialized? */
- if (parisc_narrow_firmware != 2)
+ if (parisc_narrow_firmware != NARROW_FIRMWARE)
return;
spin_lock_irqsave(&pdc_lock, flags);
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 1fc89fa2c2d2..29e2750f86a4 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -242,9 +242,9 @@ void __init collect_boot_cpu_data(void)
/* get CPU-Model Information... */
#define p ((unsigned long *)&boot_cpu_data.pdc.model)
if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) {
- printk(KERN_INFO
- "model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
+ printk(KERN_INFO
+ "model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
add_device_randomness(&boot_cpu_data.pdc.model,
sizeof(boot_cpu_data.pdc.model));
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index 2f434f2da185..ace483b6f19a 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -100,9 +100,6 @@ static void __init dma_ops_init(void)
void __init setup_arch(char **cmdline_p)
{
-#ifdef CONFIG_64BIT
- extern int parisc_narrow_firmware;
-#endif
unwind_init();
init_per_cpu(smp_processor_id()); /* Set Modes & Enable FP */
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 2019c1f04bd0..444154271f23 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -404,13 +404,7 @@ alive:
void __init smp_prepare_boot_cpu(void)
{
- int bootstrap_processor = per_cpu(cpu_data, 0).cpuid;
-
- /* Setup BSP mappings */
- printk(KERN_INFO "SMP: bootstrap CPU ID is %d\n", bootstrap_processor);
-
- set_cpu_online(bootstrap_processor, true);
- set_cpu_present(bootstrap_processor, true);
+ pr_info("SMP: bootstrap CPU ID is 0\n");
}
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index 9f0f6df55361..a47798fed54e 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -245,7 +245,7 @@
# 220 was alloc_hugepages
# 221 was free_hugepages
222 common exit_group sys_exit_group
-223 common lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie
+223 common lookup_dcookie sys_ni_syscall
224 common epoll_create sys_epoll_create
225 common epoll_ctl sys_epoll_ctl
226 common epoll_wait sys_epoll_wait
@@ -451,6 +451,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index c33c8ebf8641..eaf2f167c342 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -893,7 +893,7 @@ __start_interrupts:
*
* Call convention:
*
- * syscall register convention is in Documentation/powerpc/syscall64-abi.rst
+ * syscall register convention is in Documentation/arch/powerpc/syscall64-abi.rst
*/
EXC_VIRT_BEGIN(system_call_vectored, 0x3000, 0x1000)
/* SCV 0 */
@@ -1952,8 +1952,8 @@ EXC_VIRT_NONE(0x4b00, 0x100)
* Call convention:
*
* syscall and hypercalls register conventions are documented in
- * Documentation/powerpc/syscall64-abi.rst and
- * Documentation/powerpc/papr_hcalls.rst respectively.
+ * Documentation/arch/powerpc/syscall64-abi.rst and
+ * Documentation/arch/powerpc/papr_hcalls.rst respectively.
*
* The intersection of volatile registers that don't contain possible
* inputs is: cr0, xer, ctr. We may use these as scratch regs upon entry
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index b1c0418b25c8..30b56c67fa61 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -105,7 +105,6 @@ static struct ctl_table powersave_nap_ctl_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
- {}
};
static int __init
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index cda4e00b67c1..7502066c3c53 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -68,7 +68,7 @@ static void *__init alloc_shared_lppaca(unsigned long size, unsigned long limit,
memblock_set_bottom_up(true);
/*
- * See Documentation/powerpc/ultravisor.rst for more details.
+ * See Documentation/arch/powerpc/ultravisor.rst for more details.
*
* UV/HV data sharing is in PAGE_SIZE granularity. In order to
* minimize the number of pages shared, align the allocation to
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index 26fc41904266..7fab411378f2 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -294,7 +294,7 @@
233 32 fadvise64 sys_ppc32_fadvise64 compat_sys_ppc32_fadvise64
233 64 fadvise64 sys_fadvise64
234 nospu exit_group sys_exit_group
-235 nospu lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie
+235 nospu lookup_dcookie sys_ni_syscall
236 common epoll_create sys_epoll_create
237 common epoll_ctl sys_epoll_ctl
238 common epoll_wait sys_epoll_wait
@@ -539,6 +539,7 @@
450 nospu set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_ni_syscall
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
diff --git a/arch/powerpc/kvm/book3s_64_entry.S b/arch/powerpc/kvm/book3s_64_entry.S
index 3b361af87313..a9ab92abffe8 100644
--- a/arch/powerpc/kvm/book3s_64_entry.S
+++ b/arch/powerpc/kvm/book3s_64_entry.S
@@ -19,7 +19,7 @@
/*
* This is a hcall, so register convention is as
- * Documentation/powerpc/papr_hcalls.rst.
+ * Documentation/arch/powerpc/papr_hcalls.rst.
*
* This may also be a syscall from PR-KVM userspace that is to be
* reflected to the PR guest kernel, so registers may be set up for
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 4ebf2ef2845d..afc0f6a61337 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -164,6 +164,12 @@ config PSERIES_PLPKS
# This option is selected by in-kernel consumers that require
# access to the PKS.
+config PSERIES_PLPKS_SED
+ depends on PPC_PSERIES
+ bool
+ # This option is selected by in-kernel consumers that require
+ # access to the SED PKS keystore.
+
config PAPR_SCM
depends on PPC_PSERIES && MEMORY_HOTPLUG && LIBNVDIMM
tristate "Support for the PAPR Storage Class Memory interface"
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 53c3b91af2f7..1476c5e4433c 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_PPC_SVM) += svm.o
obj-$(CONFIG_FA_DUMP) += rtas-fadump.o
obj-$(CONFIG_PSERIES_PLPKS) += plpks.o
obj-$(CONFIG_PPC_SECURE_BOOT) += plpks-secvar.o
+obj-$(CONFIG_PSERIES_PLPKS_SED) += plpks_sed_ops.o
obj-$(CONFIG_SUSPEND) += suspend.o
obj-$(CONFIG_PPC_VAS) += vas.o vas-sysfs.o
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 0161226d8fec..1798f0f14d58 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -61,7 +61,6 @@ static struct ctl_table nmi_wd_lpm_factor_ctl_table[] = {
.mode = 0644,
.proc_handler = proc_douintvec_minmax,
},
- {}
};
static int __init register_nmi_wd_lpm_factor_sysctl(void)
diff --git a/arch/powerpc/platforms/pseries/plpks_sed_ops.c b/arch/powerpc/platforms/pseries/plpks_sed_ops.c
new file mode 100644
index 000000000000..7c873c9589ef
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/plpks_sed_ops.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * POWER Platform specific code for non-volatile SED key access
+ * Copyright (C) 2022 IBM Corporation
+ *
+ * Define operations for SED Opal to read/write keys
+ * from POWER LPAR Platform KeyStore(PLPKS).
+ *
+ * Self Encrypting Drives(SED) key storage using PLPKS
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/ioctl.h>
+#include <linux/sed-opal-key.h>
+#include <asm/plpks.h>
+
+static bool plpks_sed_initialized = false;
+static bool plpks_sed_available = false;
+
+/*
+ * structure that contains all SED data
+ */
+struct plpks_sed_object_data {
+ u_char version;
+ u_char pad1[7];
+ u_long authority;
+ u_long range;
+ u_int key_len;
+ u_char key[32];
+};
+
+#define PLPKS_SED_OBJECT_DATA_V0 0
+#define PLPKS_SED_MANGLED_LABEL "/default/pri"
+#define PLPKS_SED_COMPONENT "sed-opal"
+#define PLPKS_SED_KEY "opal-boot-pin"
+
+/*
+ * authority is admin1 and range is global
+ */
+#define PLPKS_SED_AUTHORITY 0x0000000900010001
+#define PLPKS_SED_RANGE 0x0000080200000001
+
+static void plpks_init_var(struct plpks_var *var, char *keyname)
+{
+ if (!plpks_sed_initialized) {
+ plpks_sed_initialized = true;
+ plpks_sed_available = plpks_is_available();
+ if (!plpks_sed_available)
+ pr_err("SED: plpks not available\n");
+ }
+
+ var->name = keyname;
+ var->namelen = strlen(keyname);
+ if (strcmp(PLPKS_SED_KEY, keyname) == 0) {
+ var->name = PLPKS_SED_MANGLED_LABEL;
+ var->namelen = strlen(keyname);
+ }
+ var->policy = PLPKS_WORLDREADABLE;
+ var->os = PLPKS_VAR_COMMON;
+ var->data = NULL;
+ var->datalen = 0;
+ var->component = PLPKS_SED_COMPONENT;
+}
+
+/*
+ * Read the SED Opal key from PLPKS given the label
+ */
+int sed_read_key(char *keyname, char *key, u_int *keylen)
+{
+ struct plpks_var var;
+ struct plpks_sed_object_data data;
+ int ret;
+ u_int len;
+
+ plpks_init_var(&var, keyname);
+
+ if (!plpks_sed_available)
+ return -EOPNOTSUPP;
+
+ var.data = (u8 *)&data;
+ var.datalen = sizeof(data);
+
+ ret = plpks_read_os_var(&var);
+ if (ret != 0)
+ return ret;
+
+ len = min_t(u16, be32_to_cpu(data.key_len), var.datalen);
+ memcpy(key, data.key, len);
+ key[len] = '\0';
+ *keylen = len;
+
+ return 0;
+}
+
+/*
+ * Write the SED Opal key to PLPKS given the label
+ */
+int sed_write_key(char *keyname, char *key, u_int keylen)
+{
+ struct plpks_var var;
+ struct plpks_sed_object_data data;
+ struct plpks_var_name vname;
+
+ plpks_init_var(&var, keyname);
+
+ if (!plpks_sed_available)
+ return -EOPNOTSUPP;
+
+ var.datalen = sizeof(struct plpks_sed_object_data);
+ var.data = (u8 *)&data;
+
+ /* initialize SED object */
+ data.version = PLPKS_SED_OBJECT_DATA_V0;
+ data.authority = cpu_to_be64(PLPKS_SED_AUTHORITY);
+ data.range = cpu_to_be64(PLPKS_SED_RANGE);
+ memset(&data.pad1, '\0', sizeof(data.pad1));
+ data.key_len = cpu_to_be32(keylen);
+ memcpy(data.key, (char *)key, keylen);
+
+ /*
+ * Key update requires remove first. The return value
+ * is ignored since it's okay if the key doesn't exist.
+ */
+ vname.namelen = var.namelen;
+ vname.name = var.name;
+ plpks_remove_var(var.component, var.os, vname);
+
+ return plpks_write_var(var);
+}
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 6833d01e2e70..e08e91c49abe 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -22,6 +22,11 @@ config SOC_SIFIVE
help
This enables support for SiFive SoC platform hardware.
+config ARCH_SOPHGO
+ bool "Sophgo SoCs"
+ help
+ This enables support for Sophgo SoC platform hardware.
+
config ARCH_STARFIVE
def_bool SOC_STARFIVE
@@ -29,6 +34,7 @@ config SOC_STARFIVE
bool "StarFive SoCs"
select PINCTRL
select RESET_CONTROLLER
+ select ARM_AMBA
help
This enables support for StarFive SoC platform hardware.
diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
index f60a280abb15..72030fd727af 100644
--- a/arch/riscv/boot/dts/Makefile
+++ b/arch/riscv/boot/dts/Makefile
@@ -4,6 +4,7 @@ subdir-y += canaan
subdir-y += microchip
subdir-y += renesas
subdir-y += sifive
+subdir-y += sophgo
subdir-y += starfive
subdir-y += thead
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-common-regulators.dtsi b/arch/riscv/boot/dts/allwinner/sun20i-common-regulators.dtsi
index 9b03fca2444c..ed7b12e65a10 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-common-regulators.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sun20i-common-regulators.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
/ {
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-dongshan-nezha-stu.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1-dongshan-nezha-stu.dts
index 8785de3c9224..3a2c3281eb88 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1-dongshan-nezha-stu.dts
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-dongshan-nezha-stu.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
#include <dt-bindings/gpio/gpio.h>
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-480p.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-480p.dts
index 4df8ffb71561..711450ffb602 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-480p.dts
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-480p.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
#include "sun20i-d1-lichee-rv-86-panel.dtsi"
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-720p.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-720p.dts
index 1874fc05359f..b217799e6166 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-720p.dts
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel-720p.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
#include "sun20i-d1-lichee-rv-86-panel.dtsi"
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel.dtsi b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel.dtsi
index 6cc7dd0c1ae2..10116fb3935a 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-86-panel.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
#include "sun20i-d1-lichee-rv.dts"
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts
index 52b91e1affed..08cf716328a0 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv-dock.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2022 Jisheng Zhang <jszhang@kernel.org>
// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv.dts
index d60a0562a8b1..204da82a5dc6 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv.dts
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-lichee-rv.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2022 Jisheng Zhang <jszhang@kernel.org>
// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts
index f2e07043afb3..e2bb6bc16c13 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-mangopi-mq-pro.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
#include <dt-bindings/gpio/gpio.h>
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1-nezha.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1-nezha.dts
index 4ed33c1e7c9c..8dbe717c79ce 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1-nezha.dts
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1-nezha.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
/*
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1.dtsi b/arch/riscv/boot/dts/allwinner/sun20i-d1.dtsi
index 97e7cbb32597..b18f368e06e0 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
#include "sun20i-d1s.dtsi"
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1s-mangopi-mq.dts b/arch/riscv/boot/dts/allwinner/sun20i-d1s-mangopi-mq.dts
index e6d924f671fd..1a7d6ef33f17 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1s-mangopi-mq.dts
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1s-mangopi-mq.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2022 Samuel Holland <samuel@sholland.org>
#include <dt-bindings/gpio/gpio.h>
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
index 8275630af977..64c3c2e6cbe0 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
#define SOC_PERIPHERAL_IRQ(nr) (nr + 16)
@@ -25,12 +25,14 @@
mmu-type = "riscv,sv39";
operating-points-v2 = <&opp_table_cpu>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
#cooling-cells = <2>;
cpu0_intc: interrupt-controller {
compatible = "riscv,cpu-intc";
interrupt-controller;
- #address-cells = <0>;
#interrupt-cells = <1>;
};
};
@@ -73,4 +75,43 @@
#interrupt-cells = <2>;
};
};
+
+ pmu {
+ compatible = "riscv,pmu";
+ riscv,event-to-mhpmcounters =
+ <0x00003 0x00003 0x00000008>,
+ <0x00004 0x00004 0x00000010>,
+ <0x00005 0x00005 0x00000200>,
+ <0x00006 0x00006 0x00000100>,
+ <0x10000 0x10000 0x00004000>,
+ <0x10001 0x10001 0x00008000>,
+ <0x10002 0x10002 0x00010000>,
+ <0x10003 0x10003 0x00020000>,
+ <0x10019 0x10019 0x00000040>,
+ <0x10021 0x10021 0x00000020>;
+ riscv,event-to-mhpmevent =
+ <0x00003 0x00000000 0x00000001>,
+ <0x00004 0x00000000 0x00000002>,
+ <0x00005 0x00000000 0x00000007>,
+ <0x00006 0x00000000 0x00000006>,
+ <0x10000 0x00000000 0x0000000c>,
+ <0x10001 0x00000000 0x0000000d>,
+ <0x10002 0x00000000 0x0000000e>,
+ <0x10003 0x00000000 0x0000000f>,
+ <0x10019 0x00000000 0x00000004>,
+ <0x10021 0x00000000 0x00000003>;
+ riscv,raw-event-to-mhpmcounters =
+ <0x00000000 0x00000001 0xffffffff 0xffffffff 0x00000008>,
+ <0x00000000 0x00000002 0xffffffff 0xffffffff 0x00000010>,
+ <0x00000000 0x00000003 0xffffffff 0xffffffff 0x00000020>,
+ <0x00000000 0x00000004 0xffffffff 0xffffffff 0x00000040>,
+ <0x00000000 0x00000005 0xffffffff 0xffffffff 0x00000080>,
+ <0x00000000 0x00000006 0xffffffff 0xffffffff 0x00000100>,
+ <0x00000000 0x00000007 0xffffffff 0xffffffff 0x00000200>,
+ <0x00000000 0x0000000b 0xffffffff 0xffffffff 0x00002000>,
+ <0x00000000 0x0000000c 0xffffffff 0xffffffff 0x00004000>,
+ <0x00000000 0x0000000d 0xffffffff 0xffffffff 0x00008000>,
+ <0x00000000 0x0000000e 0xffffffff 0xffffffff 0x00010000>,
+ <0x00000000 0x0000000f 0xffffffff 0xffffffff 0x00020000>;
+ };
};
diff --git a/arch/riscv/boot/dts/allwinner/sunxi-d1-t113.dtsi b/arch/riscv/boot/dts/allwinner/sunxi-d1-t113.dtsi
index b7156123df54..3b077dc086ab 100644
--- a/arch/riscv/boot/dts/allwinner/sunxi-d1-t113.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sunxi-d1-t113.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
/ {
diff --git a/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi b/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
index 822f022eec2d..5a9d7f5a75b4 100644
--- a/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
#include <dt-bindings/clock/sun6i-rtc.h>
diff --git a/arch/riscv/boot/dts/microchip/mpfs.dtsi b/arch/riscv/boot/dts/microchip/mpfs.dtsi
index 104504352e99..a6faf24f1dba 100644
--- a/arch/riscv/boot/dts/microchip/mpfs.dtsi
+++ b/arch/riscv/boot/dts/microchip/mpfs.dtsi
@@ -22,6 +22,9 @@
i-cache-size = <16384>;
reg = <0>;
riscv,isa = "rv64imac";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "c", "zicntr", "zicsr", "zifencei",
+ "zihpm";
clocks = <&clkcfg CLK_CPU>;
status = "disabled";
@@ -48,6 +51,9 @@
mmu-type = "riscv,sv39";
reg = <1>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
clocks = <&clkcfg CLK_CPU>;
tlb-split;
next-level-cache = <&cctrllr>;
@@ -76,6 +82,9 @@
mmu-type = "riscv,sv39";
reg = <2>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
clocks = <&clkcfg CLK_CPU>;
tlb-split;
next-level-cache = <&cctrllr>;
@@ -104,6 +113,9 @@
mmu-type = "riscv,sv39";
reg = <3>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
clocks = <&clkcfg CLK_CPU>;
tlb-split;
next-level-cache = <&cctrllr>;
@@ -132,6 +144,9 @@
mmu-type = "riscv,sv39";
reg = <4>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
clocks = <&clkcfg CLK_CPU>;
tlb-split;
next-level-cache = <&cctrllr>;
diff --git a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
index 6ec1c6f9a403..b0796015e36b 100644
--- a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
+++ b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
@@ -29,6 +29,7 @@
i-cache-line-size = <0x40>;
d-cache-size = <0x8000>;
d-cache-line-size = <0x40>;
+ next-level-cache = <&l2cache>;
clocks = <&cpg CPG_CORE R9A07G043_CLK_I>;
operating-points-v2 = <&cluster0_opp>;
@@ -42,6 +43,7 @@
};
&soc {
+ dma-noncoherent;
interrupt-parent = <&plic>;
plic: interrupt-controller@12c00000 {
@@ -56,4 +58,15 @@
resets = <&cpg R9A07G043_NCEPLIC_ARESETN>;
interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9>;
};
+
+ l2cache: cache-controller@13400000 {
+ compatible = "andestech,ax45mp-cache", "cache";
+ reg = <0x0 0x13400000 0x0 0x100000>;
+ interrupts = <SOC_PERIPHERAL_IRQ(476) IRQ_TYPE_LEVEL_HIGH>;
+ cache-size = <0x40000>;
+ cache-line-size = <64>;
+ cache-sets = <1024>;
+ cache-unified;
+ cache-level = <2>;
+ };
};
diff --git a/arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi b/arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi
index c62debc7ca7e..433ab5c6a626 100644
--- a/arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi
+++ b/arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi
@@ -7,25 +7,8 @@
#include <arm64/renesas/rzg2ul-smarc-som.dtsi>
-/ {
- aliases {
- /delete-property/ ethernet0;
- /delete-property/ ethernet1;
- };
-
- chosen {
- bootargs = "ignore_loglevel";
- };
-};
-
-&dmac {
- status = "disabled";
-};
-
#if (!SW_ET0_EN_N)
&eth0 {
- status = "disabled";
-
phy0: ethernet-phy@7 {
/delete-property/ interrupt-parent;
/delete-property/ interrupts;
@@ -34,14 +17,8 @@
#endif
&eth1 {
- status = "disabled";
-
phy1: ethernet-phy@7 {
/delete-property/ interrupt-parent;
/delete-property/ interrupts;
};
};
-
-&sdhi0 {
- status = "disabled";
-};
diff --git a/arch/riscv/boot/dts/renesas/rzfive-smarc.dtsi b/arch/riscv/boot/dts/renesas/rzfive-smarc.dtsi
index c07a487c4e5a..a8573fdfd8b1 100644
--- a/arch/riscv/boot/dts/renesas/rzfive-smarc.dtsi
+++ b/arch/riscv/boot/dts/renesas/rzfive-smarc.dtsi
@@ -6,59 +6,3 @@
*/
#include <arm64/renesas/rzg2ul-smarc.dtsi>
-
-&ehci0 {
- status = "disabled";
-};
-
-&ehci1 {
- status = "disabled";
-};
-
-&hsusb {
- status = "disabled";
-};
-
-&ohci0 {
- status = "disabled";
-};
-
-&ohci1 {
- status = "disabled";
-};
-
-&phyrst {
- status = "disabled";
-};
-
-&sdhi1 {
- status = "disabled";
-};
-
-&snd_rzg2l {
- status = "disabled";
-};
-
-&spi1 {
- status = "disabled";
-};
-
-&ssi1 {
- status = "disabled";
-};
-
-&usb0_vbus_otg {
- status = "disabled";
-};
-
-&usb2_phy0 {
- status = "disabled";
-};
-
-&usb2_phy1 {
- status = "disabled";
-};
-
-&vccq_sdhi1 {
- status = "disabled";
-};
diff --git a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
index 24bba83bec77..156330a9bbf3 100644
--- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
+++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
@@ -30,6 +30,9 @@
i-cache-size = <16384>;
reg = <0>;
riscv,isa = "rv64imac";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "c", "zicntr", "zicsr", "zifencei",
+ "zihpm";
status = "disabled";
cpu0_intc: interrupt-controller {
#interrupt-cells = <1>;
@@ -53,6 +56,9 @@
mmu-type = "riscv,sv39";
reg = <1>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
next-level-cache = <&l2cache>;
cpu1_intc: interrupt-controller {
@@ -77,6 +83,9 @@
mmu-type = "riscv,sv39";
reg = <2>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
next-level-cache = <&l2cache>;
cpu2_intc: interrupt-controller {
@@ -101,6 +110,9 @@
mmu-type = "riscv,sv39";
reg = <3>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
next-level-cache = <&l2cache>;
cpu3_intc: interrupt-controller {
@@ -125,6 +137,9 @@
mmu-type = "riscv,sv39";
reg = <4>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
next-level-cache = <&l2cache>;
cpu4_intc: interrupt-controller {
diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
index 5235fd1c9cb6..6150f3397bff 100644
--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
@@ -31,6 +31,9 @@
next-level-cache = <&ccache>;
reg = <0x0>;
riscv,isa = "rv64imac";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "c", "zicntr", "zicsr", "zifencei",
+ "zihpm";
status = "disabled";
cpu0_intc: interrupt-controller {
#interrupt-cells = <1>;
@@ -55,6 +58,9 @@
next-level-cache = <&ccache>;
reg = <0x1>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
cpu1_intc: interrupt-controller {
#interrupt-cells = <1>;
@@ -79,6 +85,9 @@
next-level-cache = <&ccache>;
reg = <0x2>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
cpu2_intc: interrupt-controller {
#interrupt-cells = <1>;
@@ -103,6 +112,9 @@
next-level-cache = <&ccache>;
reg = <0x3>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
cpu3_intc: interrupt-controller {
#interrupt-cells = <1>;
@@ -127,6 +139,9 @@
next-level-cache = <&ccache>;
reg = <0x4>;
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
cpu4_intc: interrupt-controller {
#interrupt-cells = <1>;
diff --git a/arch/riscv/boot/dts/sophgo/Makefile b/arch/riscv/boot/dts/sophgo/Makefile
new file mode 100644
index 000000000000..3fb65512c631
--- /dev/null
+++ b/arch/riscv/boot/dts/sophgo/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_SOPHGO) += cv1800b-milkv-duo.dtb
+dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-milkv-pioneer.dtb
diff --git a/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
new file mode 100644
index 000000000000..3af9e34b3bc7
--- /dev/null
+++ b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+/dts-v1/;
+
+#include "cv1800b.dtsi"
+
+/ {
+ model = "Milk-V Duo";
+ compatible = "milkv,duo", "sophgo,cv1800b";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x3f40000>;
+ };
+};
+
+&osc {
+ clock-frequency = <25000000>;
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/sophgo/cv1800b.dtsi b/arch/riscv/boot/dts/sophgo/cv1800b.dtsi
new file mode 100644
index 000000000000..df40e87ee063
--- /dev/null
+++ b/arch/riscv/boot/dts/sophgo/cv1800b.dtsi
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "sophgo,cv1800b";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus: cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <25000000>;
+
+ cpu0: cpu@0 {
+ compatible = "thead,c906", "riscv";
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <128>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ osc: oscillator {
+ compatible = "fixed-clock";
+ clock-output-names = "osc_25m";
+ #clock-cells = <0>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&plic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ dma-noncoherent;
+ ranges;
+
+ uart0: serial@4140000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x04140000 0x100>;
+ interrupts = <44 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart1: serial@4150000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x04150000 0x100>;
+ interrupts = <45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart2: serial@4160000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x04160000 0x100>;
+ interrupts = <46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart3: serial@4170000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x04170000 0x100>;
+ interrupts = <47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart4: serial@41c0000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x041c0000 0x100>;
+ interrupts = <48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ plic: interrupt-controller@70000000 {
+ compatible = "sophgo,cv1800b-plic", "thead,c900-plic";
+ reg = <0x70000000 0x4000000>;
+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ riscv,ndev = <101>;
+ };
+
+ clint: timer@74000000 {
+ compatible = "sophgo,cv1800b-clint", "thead,c900-clint";
+ reg = <0x74000000 0x10000>;
+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>;
+ };
+ };
+};
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-cpus.dtsi b/arch/riscv/boot/dts/sophgo/sg2042-cpus.dtsi
new file mode 100644
index 000000000000..b136b6c4128c
--- /dev/null
+++ b/arch/riscv/boot/dts/sophgo/sg2042-cpus.dtsi
@@ -0,0 +1,2000 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 Sophgo Technology Inc. All rights reserved.
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <50000000>;
+
+ cpu-map {
+ socket0 {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ core2 {
+ cpu = <&cpu2>;
+ };
+ core3 {
+ cpu = <&cpu3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu4>;
+ };
+ core1 {
+ cpu = <&cpu5>;
+ };
+ core2 {
+ cpu = <&cpu6>;
+ };
+ core3 {
+ cpu = <&cpu7>;
+ };
+ };
+
+ cluster2 {
+ core0 {
+ cpu = <&cpu16>;
+ };
+ core1 {
+ cpu = <&cpu17>;
+ };
+ core2 {
+ cpu = <&cpu18>;
+ };
+ core3 {
+ cpu = <&cpu19>;
+ };
+ };
+
+ cluster3 {
+ core0 {
+ cpu = <&cpu20>;
+ };
+ core1 {
+ cpu = <&cpu21>;
+ };
+ core2 {
+ cpu = <&cpu22>;
+ };
+ core3 {
+ cpu = <&cpu23>;
+ };
+ };
+
+ cluster4 {
+ core0 {
+ cpu = <&cpu8>;
+ };
+ core1 {
+ cpu = <&cpu9>;
+ };
+ core2 {
+ cpu = <&cpu10>;
+ };
+ core3 {
+ cpu = <&cpu11>;
+ };
+ };
+
+ cluster5 {
+ core0 {
+ cpu = <&cpu12>;
+ };
+ core1 {
+ cpu = <&cpu13>;
+ };
+ core2 {
+ cpu = <&cpu14>;
+ };
+ core3 {
+ cpu = <&cpu15>;
+ };
+ };
+
+ cluster6 {
+ core0 {
+ cpu = <&cpu24>;
+ };
+ core1 {
+ cpu = <&cpu25>;
+ };
+ core2 {
+ cpu = <&cpu26>;
+ };
+ core3 {
+ cpu = <&cpu27>;
+ };
+ };
+
+ cluster7 {
+ core0 {
+ cpu = <&cpu28>;
+ };
+ core1 {
+ cpu = <&cpu29>;
+ };
+ core2 {
+ cpu = <&cpu30>;
+ };
+ core3 {
+ cpu = <&cpu31>;
+ };
+ };
+
+ cluster8 {
+ core0 {
+ cpu = <&cpu32>;
+ };
+ core1 {
+ cpu = <&cpu33>;
+ };
+ core2 {
+ cpu = <&cpu34>;
+ };
+ core3 {
+ cpu = <&cpu35>;
+ };
+ };
+
+ cluster9 {
+ core0 {
+ cpu = <&cpu36>;
+ };
+ core1 {
+ cpu = <&cpu37>;
+ };
+ core2 {
+ cpu = <&cpu38>;
+ };
+ core3 {
+ cpu = <&cpu39>;
+ };
+ };
+
+ cluster10 {
+ core0 {
+ cpu = <&cpu48>;
+ };
+ core1 {
+ cpu = <&cpu49>;
+ };
+ core2 {
+ cpu = <&cpu50>;
+ };
+ core3 {
+ cpu = <&cpu51>;
+ };
+ };
+
+ cluster11 {
+ core0 {
+ cpu = <&cpu52>;
+ };
+ core1 {
+ cpu = <&cpu53>;
+ };
+ core2 {
+ cpu = <&cpu54>;
+ };
+ core3 {
+ cpu = <&cpu55>;
+ };
+ };
+
+ cluster12 {
+ core0 {
+ cpu = <&cpu40>;
+ };
+ core1 {
+ cpu = <&cpu41>;
+ };
+ core2 {
+ cpu = <&cpu42>;
+ };
+ core3 {
+ cpu = <&cpu43>;
+ };
+ };
+
+ cluster13 {
+ core0 {
+ cpu = <&cpu44>;
+ };
+ core1 {
+ cpu = <&cpu45>;
+ };
+ core2 {
+ cpu = <&cpu46>;
+ };
+ core3 {
+ cpu = <&cpu47>;
+ };
+ };
+
+ cluster14 {
+ core0 {
+ cpu = <&cpu56>;
+ };
+ core1 {
+ cpu = <&cpu57>;
+ };
+ core2 {
+ cpu = <&cpu58>;
+ };
+ core3 {
+ cpu = <&cpu59>;
+ };
+ };
+
+ cluster15 {
+ core0 {
+ cpu = <&cpu60>;
+ };
+ core1 {
+ cpu = <&cpu61>;
+ };
+ core2 {
+ cpu = <&cpu62>;
+ };
+ core3 {
+ cpu = <&cpu63>;
+ };
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <0>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache0>;
+ mmu-type = "riscv,sv39";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu1: cpu@1 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <1>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache0>;
+ mmu-type = "riscv,sv39";
+
+ cpu1_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu2: cpu@2 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <2>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache0>;
+ mmu-type = "riscv,sv39";
+
+ cpu2_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu3: cpu@3 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <3>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache0>;
+ mmu-type = "riscv,sv39";
+
+ cpu3_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu4: cpu@4 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <4>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache1>;
+ mmu-type = "riscv,sv39";
+
+ cpu4_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu5: cpu@5 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <5>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache1>;
+ mmu-type = "riscv,sv39";
+
+ cpu5_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu6: cpu@6 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <6>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache1>;
+ mmu-type = "riscv,sv39";
+
+ cpu6_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu7: cpu@7 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <7>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache1>;
+ mmu-type = "riscv,sv39";
+
+ cpu7_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu8: cpu@8 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <8>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache4>;
+ mmu-type = "riscv,sv39";
+
+ cpu8_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu9: cpu@9 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <9>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache4>;
+ mmu-type = "riscv,sv39";
+
+ cpu9_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu10: cpu@10 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <10>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache4>;
+ mmu-type = "riscv,sv39";
+
+ cpu10_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu11: cpu@11 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <11>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache4>;
+ mmu-type = "riscv,sv39";
+
+ cpu11_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu12: cpu@12 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <12>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache5>;
+ mmu-type = "riscv,sv39";
+
+ cpu12_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu13: cpu@13 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <13>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache5>;
+ mmu-type = "riscv,sv39";
+
+ cpu13_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu14: cpu@14 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <14>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache5>;
+ mmu-type = "riscv,sv39";
+
+ cpu14_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu15: cpu@15 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <15>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache5>;
+ mmu-type = "riscv,sv39";
+
+ cpu15_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu16: cpu@16 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <16>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache2>;
+ mmu-type = "riscv,sv39";
+
+ cpu16_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu17: cpu@17 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <17>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache2>;
+ mmu-type = "riscv,sv39";
+
+ cpu17_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu18: cpu@18 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <18>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache2>;
+ mmu-type = "riscv,sv39";
+
+ cpu18_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu19: cpu@19 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <19>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache2>;
+ mmu-type = "riscv,sv39";
+
+ cpu19_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu20: cpu@20 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <20>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache3>;
+ mmu-type = "riscv,sv39";
+
+ cpu20_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu21: cpu@21 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <21>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache3>;
+ mmu-type = "riscv,sv39";
+
+ cpu21_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu22: cpu@22 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <22>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache3>;
+ mmu-type = "riscv,sv39";
+
+ cpu22_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu23: cpu@23 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <23>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache3>;
+ mmu-type = "riscv,sv39";
+
+ cpu23_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu24: cpu@24 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <24>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache6>;
+ mmu-type = "riscv,sv39";
+
+ cpu24_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu25: cpu@25 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <25>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache6>;
+ mmu-type = "riscv,sv39";
+
+ cpu25_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu26: cpu@26 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <26>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache6>;
+ mmu-type = "riscv,sv39";
+
+ cpu26_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu27: cpu@27 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <27>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache6>;
+ mmu-type = "riscv,sv39";
+
+ cpu27_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu28: cpu@28 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <28>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache7>;
+ mmu-type = "riscv,sv39";
+
+ cpu28_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu29: cpu@29 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <29>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache7>;
+ mmu-type = "riscv,sv39";
+
+ cpu29_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu30: cpu@30 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <30>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache7>;
+ mmu-type = "riscv,sv39";
+
+ cpu30_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu31: cpu@31 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <31>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache7>;
+ mmu-type = "riscv,sv39";
+
+ cpu31_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu32: cpu@32 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <32>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache8>;
+ mmu-type = "riscv,sv39";
+
+ cpu32_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu33: cpu@33 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <33>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache8>;
+ mmu-type = "riscv,sv39";
+
+ cpu33_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu34: cpu@34 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <34>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache8>;
+ mmu-type = "riscv,sv39";
+
+ cpu34_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu35: cpu@35 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <35>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache8>;
+ mmu-type = "riscv,sv39";
+
+ cpu35_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu36: cpu@36 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <36>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache9>;
+ mmu-type = "riscv,sv39";
+
+ cpu36_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu37: cpu@37 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <37>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache9>;
+ mmu-type = "riscv,sv39";
+
+ cpu37_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu38: cpu@38 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <38>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache9>;
+ mmu-type = "riscv,sv39";
+
+ cpu38_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu39: cpu@39 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <39>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache9>;
+ mmu-type = "riscv,sv39";
+
+ cpu39_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu40: cpu@40 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <40>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache12>;
+ mmu-type = "riscv,sv39";
+
+ cpu40_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu41: cpu@41 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <41>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache12>;
+ mmu-type = "riscv,sv39";
+
+ cpu41_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu42: cpu@42 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <42>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache12>;
+ mmu-type = "riscv,sv39";
+
+ cpu42_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu43: cpu@43 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <43>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache12>;
+ mmu-type = "riscv,sv39";
+
+ cpu43_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu44: cpu@44 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <44>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache13>;
+ mmu-type = "riscv,sv39";
+
+ cpu44_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu45: cpu@45 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <45>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache13>;
+ mmu-type = "riscv,sv39";
+
+ cpu45_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu46: cpu@46 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <46>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache13>;
+ mmu-type = "riscv,sv39";
+
+ cpu46_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu47: cpu@47 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <47>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache13>;
+ mmu-type = "riscv,sv39";
+
+ cpu47_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu48: cpu@48 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <48>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache10>;
+ mmu-type = "riscv,sv39";
+
+ cpu48_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu49: cpu@49 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <49>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache10>;
+ mmu-type = "riscv,sv39";
+
+ cpu49_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu50: cpu@50 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <50>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache10>;
+ mmu-type = "riscv,sv39";
+
+ cpu50_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu51: cpu@51 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <51>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache10>;
+ mmu-type = "riscv,sv39";
+
+ cpu51_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu52: cpu@52 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <52>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache11>;
+ mmu-type = "riscv,sv39";
+
+ cpu52_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu53: cpu@53 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <53>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache11>;
+ mmu-type = "riscv,sv39";
+
+ cpu53_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu54: cpu@54 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <54>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache11>;
+ mmu-type = "riscv,sv39";
+
+ cpu54_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu55: cpu@55 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <55>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache11>;
+ mmu-type = "riscv,sv39";
+
+ cpu55_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu56: cpu@56 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <56>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache14>;
+ mmu-type = "riscv,sv39";
+
+ cpu56_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu57: cpu@57 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <57>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache14>;
+ mmu-type = "riscv,sv39";
+
+ cpu57_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu58: cpu@58 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <58>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache14>;
+ mmu-type = "riscv,sv39";
+
+ cpu58_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu59: cpu@59 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <59>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache14>;
+ mmu-type = "riscv,sv39";
+
+ cpu59_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu60: cpu@60 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <60>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache15>;
+ mmu-type = "riscv,sv39";
+
+ cpu60_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu61: cpu@61 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <61>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache15>;
+ mmu-type = "riscv,sv39";
+
+ cpu61_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu62: cpu@62 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <62>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache15>;
+ mmu-type = "riscv,sv39";
+
+ cpu62_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ cpu63: cpu@63 {
+ compatible = "thead,c920", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "zicntr", "zicsr", "zifencei",
+ "zihpm";
+ reg = <63>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache15>;
+ mmu-type = "riscv,sv39";
+
+ cpu63_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ l2_cache0: cache-controller-0 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache1: cache-controller-1 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache2: cache-controller-2 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache3: cache-controller-3 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache4: cache-controller-4 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache5: cache-controller-5 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache6: cache-controller-6 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache7: cache-controller-7 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache8: cache-controller-8 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache9: cache-controller-9 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache10: cache-controller-10 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache11: cache-controller-11 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache12: cache-controller-12 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache13: cache-controller-13 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache14: cache-controller-14 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+
+ l2_cache15: cache-controller-15 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+ };
+};
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
new file mode 100644
index 000000000000..49b4b9c2c101
--- /dev/null
+++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2022 Sophgo Technology Inc. All rights reserved.
+ */
+
+#include "sg2042.dtsi"
+
+/ {
+ model = "Milk-V Pioneer";
+ compatible = "milkv,pioneer", "sophgo,sg2042";
+
+ chosen {
+ stdout-path = "serial0";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
new file mode 100644
index 000000000000..93256540d078
--- /dev/null
+++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 Sophgo Technology Inc. All rights reserved.
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "sg2042-cpus.dtsi"
+
+/ {
+ compatible = "sophgo,sg2042";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-noncoherent;
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clint_mswi: interrupt-controller@7094000000 {
+ compatible = "sophgo,sg2042-aclint-mswi", "thead,c900-aclint-mswi";
+ reg = <0x00000070 0x94000000 0x00000000 0x00004000>;
+ interrupts-extended = <&cpu0_intc 3>,
+ <&cpu1_intc 3>,
+ <&cpu2_intc 3>,
+ <&cpu3_intc 3>,
+ <&cpu4_intc 3>,
+ <&cpu5_intc 3>,
+ <&cpu6_intc 3>,
+ <&cpu7_intc 3>,
+ <&cpu8_intc 3>,
+ <&cpu9_intc 3>,
+ <&cpu10_intc 3>,
+ <&cpu11_intc 3>,
+ <&cpu12_intc 3>,
+ <&cpu13_intc 3>,
+ <&cpu14_intc 3>,
+ <&cpu15_intc 3>,
+ <&cpu16_intc 3>,
+ <&cpu17_intc 3>,
+ <&cpu18_intc 3>,
+ <&cpu19_intc 3>,
+ <&cpu20_intc 3>,
+ <&cpu21_intc 3>,
+ <&cpu22_intc 3>,
+ <&cpu23_intc 3>,
+ <&cpu24_intc 3>,
+ <&cpu25_intc 3>,
+ <&cpu26_intc 3>,
+ <&cpu27_intc 3>,
+ <&cpu28_intc 3>,
+ <&cpu29_intc 3>,
+ <&cpu30_intc 3>,
+ <&cpu31_intc 3>,
+ <&cpu32_intc 3>,
+ <&cpu33_intc 3>,
+ <&cpu34_intc 3>,
+ <&cpu35_intc 3>,
+ <&cpu36_intc 3>,
+ <&cpu37_intc 3>,
+ <&cpu38_intc 3>,
+ <&cpu39_intc 3>,
+ <&cpu40_intc 3>,
+ <&cpu41_intc 3>,
+ <&cpu42_intc 3>,
+ <&cpu43_intc 3>,
+ <&cpu44_intc 3>,
+ <&cpu45_intc 3>,
+ <&cpu46_intc 3>,
+ <&cpu47_intc 3>,
+ <&cpu48_intc 3>,
+ <&cpu49_intc 3>,
+ <&cpu50_intc 3>,
+ <&cpu51_intc 3>,
+ <&cpu52_intc 3>,
+ <&cpu53_intc 3>,
+ <&cpu54_intc 3>,
+ <&cpu55_intc 3>,
+ <&cpu56_intc 3>,
+ <&cpu57_intc 3>,
+ <&cpu58_intc 3>,
+ <&cpu59_intc 3>,
+ <&cpu60_intc 3>,
+ <&cpu61_intc 3>,
+ <&cpu62_intc 3>,
+ <&cpu63_intc 3>;
+ };
+
+ clint_mtimer0: timer@70ac000000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac000000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu0_intc 7>,
+ <&cpu1_intc 7>,
+ <&cpu2_intc 7>,
+ <&cpu3_intc 7>;
+ };
+
+ clint_mtimer1: timer@70ac010000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac010000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu4_intc 7>,
+ <&cpu5_intc 7>,
+ <&cpu6_intc 7>,
+ <&cpu7_intc 7>;
+ };
+
+ clint_mtimer2: timer@70ac020000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac020000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu8_intc 7>,
+ <&cpu9_intc 7>,
+ <&cpu10_intc 7>,
+ <&cpu11_intc 7>;
+ };
+
+ clint_mtimer3: timer@70ac030000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac030000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu12_intc 7>,
+ <&cpu13_intc 7>,
+ <&cpu14_intc 7>,
+ <&cpu15_intc 7>;
+ };
+
+ clint_mtimer4: timer@70ac040000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac040000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu16_intc 7>,
+ <&cpu17_intc 7>,
+ <&cpu18_intc 7>,
+ <&cpu19_intc 7>;
+ };
+
+ clint_mtimer5: timer@70ac050000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac050000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu20_intc 7>,
+ <&cpu21_intc 7>,
+ <&cpu22_intc 7>,
+ <&cpu23_intc 7>;
+ };
+
+ clint_mtimer6: timer@70ac060000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac060000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu24_intc 7>,
+ <&cpu25_intc 7>,
+ <&cpu26_intc 7>,
+ <&cpu27_intc 7>;
+ };
+
+ clint_mtimer7: timer@70ac070000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac070000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu28_intc 7>,
+ <&cpu29_intc 7>,
+ <&cpu30_intc 7>,
+ <&cpu31_intc 7>;
+ };
+
+ clint_mtimer8: timer@70ac080000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac080000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu32_intc 7>,
+ <&cpu33_intc 7>,
+ <&cpu34_intc 7>,
+ <&cpu35_intc 7>;
+ };
+
+ clint_mtimer9: timer@70ac090000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac090000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu36_intc 7>,
+ <&cpu37_intc 7>,
+ <&cpu38_intc 7>,
+ <&cpu39_intc 7>;
+ };
+
+ clint_mtimer10: timer@70ac0a0000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac0a0000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu40_intc 7>,
+ <&cpu41_intc 7>,
+ <&cpu42_intc 7>,
+ <&cpu43_intc 7>;
+ };
+
+ clint_mtimer11: timer@70ac0b0000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac0b0000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu44_intc 7>,
+ <&cpu45_intc 7>,
+ <&cpu46_intc 7>,
+ <&cpu47_intc 7>;
+ };
+
+ clint_mtimer12: timer@70ac0c0000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac0c0000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu48_intc 7>,
+ <&cpu49_intc 7>,
+ <&cpu50_intc 7>,
+ <&cpu51_intc 7>;
+ };
+
+ clint_mtimer13: timer@70ac0d0000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac0d0000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu52_intc 7>,
+ <&cpu53_intc 7>,
+ <&cpu54_intc 7>,
+ <&cpu55_intc 7>;
+ };
+
+ clint_mtimer14: timer@70ac0e0000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac0e0000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu56_intc 7>,
+ <&cpu57_intc 7>,
+ <&cpu58_intc 7>,
+ <&cpu59_intc 7>;
+ };
+
+ clint_mtimer15: timer@70ac0f0000 {
+ compatible = "sophgo,sg2042-aclint-mtimer", "thead,c900-aclint-mtimer";
+ reg = <0x00000070 0xac0f0000 0x00000000 0x00007ff8>;
+ interrupts-extended = <&cpu60_intc 7>,
+ <&cpu61_intc 7>,
+ <&cpu62_intc 7>,
+ <&cpu63_intc 7>;
+ };
+
+ intc: interrupt-controller@7090000000 {
+ compatible = "sophgo,sg2042-plic", "thead,c900-plic";
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x00000070 0x90000000 0x00000000 0x04000000>;
+ interrupt-controller;
+ interrupts-extended =
+ <&cpu0_intc 11>, <&cpu0_intc 9>,
+ <&cpu1_intc 11>, <&cpu1_intc 9>,
+ <&cpu2_intc 11>, <&cpu2_intc 9>,
+ <&cpu3_intc 11>, <&cpu3_intc 9>,
+ <&cpu4_intc 11>, <&cpu4_intc 9>,
+ <&cpu5_intc 11>, <&cpu5_intc 9>,
+ <&cpu6_intc 11>, <&cpu6_intc 9>,
+ <&cpu7_intc 11>, <&cpu7_intc 9>,
+ <&cpu8_intc 11>, <&cpu8_intc 9>,
+ <&cpu9_intc 11>, <&cpu9_intc 9>,
+ <&cpu10_intc 11>, <&cpu10_intc 9>,
+ <&cpu11_intc 11>, <&cpu11_intc 9>,
+ <&cpu12_intc 11>, <&cpu12_intc 9>,
+ <&cpu13_intc 11>, <&cpu13_intc 9>,
+ <&cpu14_intc 11>, <&cpu14_intc 9>,
+ <&cpu15_intc 11>, <&cpu15_intc 9>,
+ <&cpu16_intc 11>, <&cpu16_intc 9>,
+ <&cpu17_intc 11>, <&cpu17_intc 9>,
+ <&cpu18_intc 11>, <&cpu18_intc 9>,
+ <&cpu19_intc 11>, <&cpu19_intc 9>,
+ <&cpu20_intc 11>, <&cpu20_intc 9>,
+ <&cpu21_intc 11>, <&cpu21_intc 9>,
+ <&cpu22_intc 11>, <&cpu22_intc 9>,
+ <&cpu23_intc 11>, <&cpu23_intc 9>,
+ <&cpu24_intc 11>, <&cpu24_intc 9>,
+ <&cpu25_intc 11>, <&cpu25_intc 9>,
+ <&cpu26_intc 11>, <&cpu26_intc 9>,
+ <&cpu27_intc 11>, <&cpu27_intc 9>,
+ <&cpu28_intc 11>, <&cpu28_intc 9>,
+ <&cpu29_intc 11>, <&cpu29_intc 9>,
+ <&cpu30_intc 11>, <&cpu30_intc 9>,
+ <&cpu31_intc 11>, <&cpu31_intc 9>,
+ <&cpu32_intc 11>, <&cpu32_intc 9>,
+ <&cpu33_intc 11>, <&cpu33_intc 9>,
+ <&cpu34_intc 11>, <&cpu34_intc 9>,
+ <&cpu35_intc 11>, <&cpu35_intc 9>,
+ <&cpu36_intc 11>, <&cpu36_intc 9>,
+ <&cpu37_intc 11>, <&cpu37_intc 9>,
+ <&cpu38_intc 11>, <&cpu38_intc 9>,
+ <&cpu39_intc 11>, <&cpu39_intc 9>,
+ <&cpu40_intc 11>, <&cpu40_intc 9>,
+ <&cpu41_intc 11>, <&cpu41_intc 9>,
+ <&cpu42_intc 11>, <&cpu42_intc 9>,
+ <&cpu43_intc 11>, <&cpu43_intc 9>,
+ <&cpu44_intc 11>, <&cpu44_intc 9>,
+ <&cpu45_intc 11>, <&cpu45_intc 9>,
+ <&cpu46_intc 11>, <&cpu46_intc 9>,
+ <&cpu47_intc 11>, <&cpu47_intc 9>,
+ <&cpu48_intc 11>, <&cpu48_intc 9>,
+ <&cpu49_intc 11>, <&cpu49_intc 9>,
+ <&cpu50_intc 11>, <&cpu50_intc 9>,
+ <&cpu51_intc 11>, <&cpu51_intc 9>,
+ <&cpu52_intc 11>, <&cpu52_intc 9>,
+ <&cpu53_intc 11>, <&cpu53_intc 9>,
+ <&cpu54_intc 11>, <&cpu54_intc 9>,
+ <&cpu55_intc 11>, <&cpu55_intc 9>,
+ <&cpu56_intc 11>, <&cpu56_intc 9>,
+ <&cpu57_intc 11>, <&cpu57_intc 9>,
+ <&cpu58_intc 11>, <&cpu58_intc 9>,
+ <&cpu59_intc 11>, <&cpu59_intc 9>,
+ <&cpu60_intc 11>, <&cpu60_intc 9>,
+ <&cpu61_intc 11>, <&cpu61_intc 9>,
+ <&cpu62_intc 11>, <&cpu62_intc 9>,
+ <&cpu63_intc 11>, <&cpu63_intc 9>;
+ riscv,ndev = <224>;
+ };
+
+ uart0: serial@7040000000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x00000070 0x40000000 0x00000000 0x00001000>;
+ interrupt-parent = <&intc>;
+ interrupts = <112 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <500000000>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
index 35ab54fb235f..e68cafe7545f 100644
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -33,6 +33,9 @@
i-tlb-size = <32>;
mmu-type = "riscv,sv39";
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
cpu0_intc: interrupt-controller {
@@ -58,6 +61,9 @@
i-tlb-size = <32>;
mmu-type = "riscv,sv39";
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
tlb-split;
cpu1_intc: interrupt-controller {
diff --git a/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
index fb0139b56723..256de17f5261 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
+++ b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
@@ -240,8 +240,8 @@
#define GPI_SYS_MCLK_EXT 30
#define GPI_SYS_I2SRX_BCLK 31
#define GPI_SYS_I2SRX_LRCK 32
-#define GPI_SYS_I2STX0_BCLK 33
-#define GPI_SYS_I2STX0_LRCK 34
+#define GPI_SYS_I2STX1_BCLK 33
+#define GPI_SYS_I2STX1_LRCK 34
#define GPI_SYS_TDM_CLK 35
#define GPI_SYS_TDM_RXD 36
#define GPI_SYS_TDM_SYNC 37
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
index 2c02358abd71..b89e9791efa7 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -40,6 +40,33 @@
gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
priority = <224>;
};
+
+ pwmdac_codec: pwmdac-codec {
+ compatible = "linux,spdif-dit";
+ #sound-dai-cells = <0>;
+ };
+
+ sound-pwmdac {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ simple-audio-card,dai-link@0 {
+ reg = <0>;
+ format = "left_j";
+ bitclock-master = <&sndcpu0>;
+ frame-master = <&sndcpu0>;
+
+ sndcpu0: cpu {
+ sound-dai = <&pwmdac>;
+ };
+
+ codec {
+ sound-dai = <&pwmdac_codec>;
+ };
+ };
+ };
};
&dvp_clk {
@@ -203,8 +230,28 @@
status = "okay";
};
+&i2srx {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2srx_pins>;
+ status = "okay";
+};
+
+&i2stx0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mclk_ext_pins>;
+ status = "okay";
+};
+
+&i2stx1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2stx1_pins>;
+ status = "okay";
+};
+
&mmc0 {
max-frequency = <100000000>;
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
+ assigned-clock-rates = <50000000>;
bus-width = <8>;
cap-mmc-highspeed;
mmc-ddr-1_8v;
@@ -221,6 +268,8 @@
&mmc1 {
max-frequency = <100000000>;
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO1_SDCARD>;
+ assigned-clock-rates = <50000000>;
bus-width = <4>;
no-sdio;
no-mmc;
@@ -232,6 +281,12 @@
status = "okay";
};
+&pwmdac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwmdac_pins>;
+ status = "okay";
+};
+
&qspi {
#address-cells = <1>;
#size-cells = <0>;
@@ -337,6 +392,46 @@
};
};
+ i2srx_pins: i2srx-0 {
+ clk-sd-pins {
+ pinmux = <GPIOMUX(38, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2SRX_BCLK)>,
+ <GPIOMUX(63, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2SRX_LRCK)>,
+ <GPIOMUX(38, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2STX1_BCLK)>,
+ <GPIOMUX(63, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2STX1_LRCK)>,
+ <GPIOMUX(61, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_I2SRX_SDIN0)>;
+ input-enable;
+ };
+ };
+
+ i2stx1_pins: i2stx1-0 {
+ sd-pins {
+ pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-disable;
+ input-disable;
+ };
+ };
+
+ mclk_ext_pins: mclk-ext-0 {
+ mclk-ext-pins {
+ pinmux = <GPIOMUX(4, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_MCLK_EXT)>;
+ input-enable;
+ };
+ };
+
mmc0_pins: mmc0-0 {
rst-pins {
pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
@@ -402,6 +497,22 @@
};
};
+ pwmdac_pins: pwmdac-0 {
+ pwmdac-pins {
+ pinmux = <GPIOMUX(33, GPOUT_SYS_PWMDAC_LEFT,
+ GPOEN_ENABLE,
+ GPI_NONE)>,
+ <GPIOMUX(34, GPOUT_SYS_PWMDAC_RIGHT,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-disable;
+ drive-strength = <2>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
spi0_pins: spi0-0 {
mosi-pins {
pinmux = <GPIOMUX(52, GPOUT_SYS_SPI0_TXD,
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index e85464c328d0..45213cdf50dc 100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -28,6 +28,9 @@
i-cache-size = <16384>;
next-level-cache = <&ccache>;
riscv,isa = "rv64imac_zba_zbb";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "c", "zba", "zbb", "zicntr", "zicsr",
+ "zifencei", "zihpm";
status = "disabled";
cpu0_intc: interrupt-controller {
@@ -54,6 +57,9 @@
mmu-type = "riscv,sv39";
next-level-cache = <&ccache>;
riscv,isa = "rv64imafdc_zba_zbb";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zba", "zbb", "zicntr",
+ "zicsr", "zifencei", "zihpm";
tlb-split;
operating-points-v2 = <&cpu_opp>;
clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
@@ -84,6 +90,9 @@
mmu-type = "riscv,sv39";
next-level-cache = <&ccache>;
riscv,isa = "rv64imafdc_zba_zbb";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zba", "zbb", "zicntr",
+ "zicsr", "zifencei", "zihpm";
tlb-split;
operating-points-v2 = <&cpu_opp>;
clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
@@ -114,6 +123,9 @@
mmu-type = "riscv,sv39";
next-level-cache = <&ccache>;
riscv,isa = "rv64imafdc_zba_zbb";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zba", "zbb", "zicntr",
+ "zicsr", "zifencei", "zihpm";
tlb-split;
operating-points-v2 = <&cpu_opp>;
clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
@@ -144,6 +156,9 @@
mmu-type = "riscv,sv39";
next-level-cache = <&ccache>;
riscv,isa = "rv64imafdc_zba_zbb";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zba", "zbb", "zicntr",
+ "zicsr", "zifencei", "zihpm";
tlb-split;
operating-points-v2 = <&cpu_opp>;
clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
@@ -512,6 +527,43 @@
status = "disabled";
};
+ i2srx: i2s@100e0000 {
+ compatible = "starfive,jh7110-i2srx";
+ reg = <0x0 0x100e0000 0x0 0x1000>;
+ clocks = <&syscrg JH7110_SYSCLK_I2SRX_BCLK_MST>,
+ <&syscrg JH7110_SYSCLK_I2SRX_APB>,
+ <&syscrg JH7110_SYSCLK_MCLK>,
+ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
+ <&mclk_ext>,
+ <&syscrg JH7110_SYSCLK_I2SRX_BCLK>,
+ <&syscrg JH7110_SYSCLK_I2SRX_LRCK>,
+ <&i2srx_bclk_ext>,
+ <&i2srx_lrck_ext>;
+ clock-names = "i2sclk", "apb", "mclk",
+ "mclk_inner", "mclk_ext", "bclk",
+ "lrck", "bclk_ext", "lrck_ext";
+ resets = <&syscrg JH7110_SYSRST_I2SRX_APB>,
+ <&syscrg JH7110_SYSRST_I2SRX_BCLK>;
+ dmas = <0>, <&dma 24>;
+ dma-names = "tx", "rx";
+ starfive,syscon = <&sys_syscon 0x18 0x2>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ pwmdac: pwmdac@100b0000 {
+ compatible = "starfive,jh7110-pwmdac";
+ reg = <0x0 0x100b0000 0x0 0x1000>;
+ clocks = <&syscrg JH7110_SYSCLK_PWMDAC_APB>,
+ <&syscrg JH7110_SYSCLK_PWMDAC_CORE>;
+ clock-names = "apb", "core";
+ resets = <&syscrg JH7110_SYSRST_PWMDAC_APB>;
+ dmas = <&dma 22>;
+ dma-names = "tx";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
usb0: usb@10100000 {
compatible = "starfive,jh7110-usb";
ranges = <0x0 0x0 0x10100000 0x100000>;
@@ -736,6 +788,47 @@
status = "disabled";
};
+ i2stx0: i2s@120b0000 {
+ compatible = "starfive,jh7110-i2stx0";
+ reg = <0x0 0x120b0000 0x0 0x1000>;
+ clocks = <&syscrg JH7110_SYSCLK_I2STX0_BCLK_MST>,
+ <&syscrg JH7110_SYSCLK_I2STX0_APB>,
+ <&syscrg JH7110_SYSCLK_MCLK>,
+ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
+ <&mclk_ext>;
+ clock-names = "i2sclk", "apb", "mclk",
+ "mclk_inner","mclk_ext";
+ resets = <&syscrg JH7110_SYSRST_I2STX0_APB>,
+ <&syscrg JH7110_SYSRST_I2STX0_BCLK>;
+ dmas = <&dma 47>;
+ dma-names = "tx";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2stx1: i2s@120c0000 {
+ compatible = "starfive,jh7110-i2stx1";
+ reg = <0x0 0x120c0000 0x0 0x1000>;
+ clocks = <&syscrg JH7110_SYSCLK_I2STX1_BCLK_MST>,
+ <&syscrg JH7110_SYSCLK_I2STX1_APB>,
+ <&syscrg JH7110_SYSCLK_MCLK>,
+ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
+ <&mclk_ext>,
+ <&syscrg JH7110_SYSCLK_I2STX1_BCLK>,
+ <&syscrg JH7110_SYSCLK_I2STX1_LRCK>,
+ <&i2stx_bclk_ext>,
+ <&i2stx_lrck_ext>;
+ clock-names = "i2sclk", "apb", "mclk",
+ "mclk_inner", "mclk_ext", "bclk",
+ "lrck", "bclk_ext", "lrck_ext";
+ resets = <&syscrg JH7110_SYSRST_I2STX1_APB>,
+ <&syscrg JH7110_SYSRST_I2STX1_BCLK>;
+ dmas = <&dma 48>;
+ dma-names = "tx";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
sfctemp: temperature-sensor@120e0000 {
compatible = "starfive,jh7110-temp";
reg = <0x0 0x120e0000 0x0 0x10000>;
diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
index ff364709a6df..ba4d2c673ac8 100644
--- a/arch/riscv/boot/dts/thead/th1520.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520.dtsi
@@ -20,6 +20,9 @@
compatible = "thead,c910", "riscv";
device_type = "cpu";
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
reg = <0>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
@@ -41,6 +44,9 @@
compatible = "thead,c910", "riscv";
device_type = "cpu";
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
reg = <1>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
@@ -62,6 +68,9 @@
compatible = "thead,c910", "riscv";
device_type = "cpu";
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
reg = <2>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
@@ -83,6 +92,9 @@
compatible = "thead,c910", "riscv";
device_type = "cpu";
riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
reg = <3>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index ab86ec3b9eab..1edf3cd886c5 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -27,10 +27,11 @@ CONFIG_EXPERT=y
CONFIG_PROFILING=y
CONFIG_SOC_MICROCHIP_POLARFIRE=y
CONFIG_ARCH_RENESAS=y
-CONFIG_ARCH_THEAD=y
CONFIG_SOC_SIFIVE=y
+CONFIG_ARCH_SOPHGO=y
CONFIG_SOC_STARFIVE=y
CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_THEAD=y
CONFIG_SOC_VIRT=y
CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y
diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
index 006bfb48343d..d43e306ce2f9 100644
--- a/arch/riscv/include/uapi/asm/hwprobe.h
+++ b/arch/riscv/include/uapi/asm/hwprobe.h
@@ -10,7 +10,7 @@
/*
* Interface for probing hardware capabilities from userspace, see
- * Documentation/riscv/hwprobe.rst for more information.
+ * Documentation/arch/riscv/hwprobe.rst for more information.
*/
struct riscv_hwprobe {
__s64 key;
diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
index 473159b5f303..b651ec698a91 100644
--- a/arch/riscv/kernel/sys_riscv.c
+++ b/arch/riscv/kernel/sys_riscv.c
@@ -79,7 +79,7 @@ SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end,
/*
* The hwprobe interface, for allowing userspace to probe to see which features
- * are supported by the hardware. See Documentation/riscv/hwprobe.rst for more
+ * are supported by the hardware. See Documentation/arch/riscv/hwprobe.rst for more
* details.
*/
static void hwprobe_arch_id(struct riscv_hwprobe *pair,
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 8d92fb6c522c..578b6292487e 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -255,7 +255,6 @@ static struct ctl_table riscv_v_default_vstate_table[] = {
.mode = 0644,
.proc_handler = proc_dobool,
},
- { }
};
static int __init riscv_v_sysctl_init(void)
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index 3b0994625652..c2978cb03b36 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -63,7 +63,6 @@ static struct ctl_table appldata_table[] = {
.mode = S_IRUGO | S_IWUSR,
.proc_handler = appldata_interval_handler,
},
- { },
};
/*
@@ -351,8 +350,7 @@ int appldata_register_ops(struct appldata_ops *ops)
if (ops->size > APPLDATA_MAX_REC_SIZE)
return -EINVAL;
- /* The last entry must be an empty one */
- ops->ctl_table = kcalloc(2, sizeof(struct ctl_table), GFP_KERNEL);
+ ops->ctl_table = kcalloc(1, sizeof(struct ctl_table), GFP_KERNEL);
if (!ops->ctl_table)
return -ENOMEM;
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index a85e0c3e7027..85328a0ef3b6 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -978,7 +978,6 @@ static struct ctl_table s390dbf_table[] = {
.mode = S_IRUGO | S_IWUSR,
.proc_handler = s390dbf_procactive,
},
- { }
};
static struct ctl_table_header *s390dbf_sysctl_header;
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index 31be90b241f7..86fec9b080f6 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -100,7 +100,7 @@
106 common stat sys_newstat compat_sys_newstat
107 common lstat sys_newlstat compat_sys_newlstat
108 common fstat sys_newfstat compat_sys_newfstat
-110 common lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie
+110 common lookup_dcookie - -
111 common vhangup sys_vhangup sys_vhangup
112 common idle - -
114 common wait4 sys_wait4 compat_sys_wait4
@@ -455,6 +455,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait sys_futex_wait
-456 common futex_requeue sys_futex_requeue sys_futex_requeue
+456 common futex_requeue sys_futex_requeue sys_futex_requeue
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 66bda6a8f918..89e91b8ce842 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -636,7 +636,6 @@ static struct ctl_table topology_ctl_table[] = {
.mode = 0644,
.proc_handler = topology_ctl_handler,
},
- { },
};
static int __init topology_init(void)
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index f47515313226..f8b13f247646 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -332,7 +332,6 @@ static struct ctl_table cmm_table[] = {
.mode = 0644,
.proc_handler = cmm_timeout_handler,
},
- { }
};
#ifdef CONFIG_CMM_IUCV
diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c
index 07fc660a24aa..75e1039f2ec5 100644
--- a/arch/s390/mm/pgalloc.c
+++ b/arch/s390/mm/pgalloc.c
@@ -30,7 +30,6 @@ static struct ctl_table page_table_sysctl[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
- { }
};
static int __init page_table_register_sysctl(void)
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index 4bc5d488ab17..363fae0fe9bf 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -260,7 +260,7 @@
250 common fadvise64 sys_fadvise64
# 251 is unused
252 common exit_group sys_exit_group
-253 common lookup_dcookie sys_lookup_dcookie
+253 common lookup_dcookie sys_ni_syscall
254 common epoll_create sys_epoll_create
255 common epoll_ctl sys_epoll_ctl
256 common epoll_wait sys_epoll_wait
@@ -455,6 +455,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 8404c8e50394..7bcaa3d5ea44 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -249,7 +249,7 @@
205 common readahead sys_readahead compat_sys_readahead
206 common socketcall sys_socketcall sys32_socketcall
207 common syslog sys_syslog
-208 common lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie
+208 common lookup_dcookie sys_ni_syscall
209 common fadvise64 sys_fadvise64 compat_sys_fadvise64
210 common fadvise64_64 sys_fadvise64_64 compat_sys_fadvise64_64
211 common tgkill sys_tgkill
@@ -498,6 +498,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ad478a2b49e2..433f5e1906d1 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1940,6 +1940,18 @@ config X86_USER_SHADOW_STACK
If unsure, say N.
+config INTEL_TDX_HOST
+ bool "Intel Trust Domain Extensions (TDX) host support"
+ depends on CPU_SUP_INTEL
+ depends on X86_64
+ depends on KVM_INTEL
+ help
+ Intel Trust Domain Extensions (TDX) protects guest VMs from malicious
+ host and certain physical attacks. This option enables necessary TDX
+ support in the host kernel to run confidential VMs.
+
+ If unsure, say N.
+
config EFI
bool "EFI runtime service support"
depends on ACPI
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 76da1e8b3eb0..4de6ddaf4b84 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -253,6 +253,8 @@ archheaders:
libs-y += arch/x86/lib/
+core-y += arch/x86/virt/
+
# drivers-y are linked after core-y
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
drivers-$(CONFIG_PCI) += arch/x86/pci/
diff --git a/arch/x86/boot/compressed/tdx.c b/arch/x86/boot/compressed/tdx.c
index 8841b945a1e2..8451d6a1030c 100644
--- a/arch/x86/boot/compressed/tdx.c
+++ b/arch/x86/boot/compressed/tdx.c
@@ -18,7 +18,7 @@ void __tdx_hypercall_failed(void)
static inline unsigned int tdx_io_in(int size, u16 port)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_IO_INSTRUCTION),
.r12 = size,
@@ -26,7 +26,7 @@ static inline unsigned int tdx_io_in(int size, u16 port)
.r14 = port,
};
- if (__tdx_hypercall_ret(&args))
+ if (__tdx_hypercall(&args))
return UINT_MAX;
return args.r11;
@@ -34,7 +34,7 @@ static inline unsigned int tdx_io_in(int size, u16 port)
static inline void tdx_io_out(int size, u16 port, u32 value)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_IO_INSTRUCTION),
.r12 = size,
diff --git a/arch/x86/coco/tdx/tdcall.S b/arch/x86/coco/tdx/tdcall.S
index b193c0a1d8db..52d9786da308 100644
--- a/arch/x86/coco/tdx/tdcall.S
+++ b/arch/x86/coco/tdx/tdcall.S
@@ -1,239 +1,63 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <asm/asm-offsets.h>
#include <asm/asm.h>
-#include <asm/frame.h>
-#include <asm/unwind_hints.h>
#include <linux/linkage.h>
-#include <linux/bits.h>
#include <linux/errno.h>
#include "../../virt/vmx/tdx/tdxcall.S"
-/*
- * Bitmasks of exposed registers (with VMM).
- */
-#define TDX_RDX BIT(2)
-#define TDX_RBX BIT(3)
-#define TDX_RSI BIT(6)
-#define TDX_RDI BIT(7)
-#define TDX_R8 BIT(8)
-#define TDX_R9 BIT(9)
-#define TDX_R10 BIT(10)
-#define TDX_R11 BIT(11)
-#define TDX_R12 BIT(12)
-#define TDX_R13 BIT(13)
-#define TDX_R14 BIT(14)
-#define TDX_R15 BIT(15)
-
-/*
- * These registers are clobbered to hold arguments for each
- * TDVMCALL. They are safe to expose to the VMM.
- * Each bit in this mask represents a register ID. Bit field
- * details can be found in TDX GHCI specification, section
- * titled "TDCALL [TDG.VP.VMCALL] leaf".
- */
-#define TDVMCALL_EXPOSE_REGS_MASK \
- ( TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8 | TDX_R9 | \
- TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15 )
-
.section .noinstr.text, "ax"
/*
- * __tdx_module_call() - Used by TDX guests to request services from
- * the TDX module (does not include VMM services) using TDCALL instruction.
- *
- * Transforms function call register arguments into the TDCALL register ABI.
- * After TDCALL operation, TDX module output is saved in @out (if it is
- * provided by the user).
- *
- *-------------------------------------------------------------------------
- * TDCALL ABI:
- *-------------------------------------------------------------------------
- * Input Registers:
- *
- * RAX - TDCALL Leaf number.
- * RCX,RDX,R8-R9 - TDCALL Leaf specific input registers.
- *
- * Output Registers:
+ * __tdcall() - Used by TDX guests to request services from the TDX
+ * module (does not include VMM services) using TDCALL instruction.
*
- * RAX - TDCALL instruction error code.
- * RCX,RDX,R8-R11 - TDCALL Leaf specific output registers.
+ * __tdcall() function ABI:
*
- *-------------------------------------------------------------------------
+ * @fn (RDI) - TDCALL Leaf ID, moved to RAX
+ * @args (RSI) - struct tdx_module_args for input
*
- * __tdx_module_call() function ABI:
- *
- * @fn (RDI) - TDCALL Leaf ID, moved to RAX
- * @rcx (RSI) - Input parameter 1, moved to RCX
- * @rdx (RDX) - Input parameter 2, moved to RDX
- * @r8 (RCX) - Input parameter 3, moved to R8
- * @r9 (R8) - Input parameter 4, moved to R9
- *
- * @out (R9) - struct tdx_module_output pointer
- * stored temporarily in R12 (not
- * shared with the TDX module). It
- * can be NULL.
+ * Only RCX/RDX/R8-R11 are used as input registers.
*
* Return status of TDCALL via RAX.
*/
-SYM_FUNC_START(__tdx_module_call)
- FRAME_BEGIN
+SYM_FUNC_START(__tdcall)
TDX_MODULE_CALL host=0
- FRAME_END
- RET
-SYM_FUNC_END(__tdx_module_call)
+SYM_FUNC_END(__tdcall)
/*
- * TDX_HYPERCALL - Make hypercalls to a TDX VMM using TDVMCALL leaf of TDCALL
- * instruction
- *
- * Transforms values in function call argument struct tdx_hypercall_args @args
- * into the TDCALL register ABI. After TDCALL operation, VMM output is saved
- * back in @args, if \ret is 1.
- *
- *-------------------------------------------------------------------------
- * TD VMCALL ABI:
- *-------------------------------------------------------------------------
- *
- * Input Registers:
+ * __tdcall_ret() - Used by TDX guests to request services from the TDX
+ * module (does not include VMM services) using TDCALL instruction, with
+ * saving output registers to the 'struct tdx_module_args' used as input.
*
- * RAX - TDCALL instruction leaf number (0 - TDG.VP.VMCALL)
- * RCX - BITMAP which controls which part of TD Guest GPR
- * is passed as-is to the VMM and back.
- * R10 - Set 0 to indicate TDCALL follows standard TDX ABI
- * specification. Non zero value indicates vendor
- * specific ABI.
- * R11 - VMCALL sub function number
- * RBX, RDX, RDI, RSI - Used to pass VMCALL sub function specific arguments.
- * R8-R9, R12-R15 - Same as above.
+ * __tdcall_ret() function ABI:
*
- * Output Registers:
+ * @fn (RDI) - TDCALL Leaf ID, moved to RAX
+ * @args (RSI) - struct tdx_module_args for input and output
*
- * RAX - TDCALL instruction status (Not related to hypercall
- * output).
- * RBX, RDX, RDI, RSI - Hypercall sub function specific output values.
- * R8-R15 - Same as above.
+ * Only RCX/RDX/R8-R11 are used as input/output registers.
*
+ * Return status of TDCALL via RAX.
*/
-.macro TDX_HYPERCALL ret:req
- FRAME_BEGIN
-
- /* Save callee-saved GPRs as mandated by the x86_64 ABI */
- push %r15
- push %r14
- push %r13
- push %r12
- push %rbx
-
- /* Free RDI to be used as TDVMCALL arguments */
- movq %rdi, %rax
-
- /* Copy hypercall registers from arg struct: */
- movq TDX_HYPERCALL_r8(%rax), %r8
- movq TDX_HYPERCALL_r9(%rax), %r9
- movq TDX_HYPERCALL_r10(%rax), %r10
- movq TDX_HYPERCALL_r11(%rax), %r11
- movq TDX_HYPERCALL_r12(%rax), %r12
- movq TDX_HYPERCALL_r13(%rax), %r13
- movq TDX_HYPERCALL_r14(%rax), %r14
- movq TDX_HYPERCALL_r15(%rax), %r15
- movq TDX_HYPERCALL_rdi(%rax), %rdi
- movq TDX_HYPERCALL_rsi(%rax), %rsi
- movq TDX_HYPERCALL_rbx(%rax), %rbx
- movq TDX_HYPERCALL_rdx(%rax), %rdx
-
- push %rax
-
- /* Mangle function call ABI into TDCALL ABI: */
- /* Set TDCALL leaf ID (TDVMCALL (0)) in RAX */
- xor %eax, %eax
-
- movl $TDVMCALL_EXPOSE_REGS_MASK, %ecx
-
- tdcall
-
- /*
- * RAX!=0 indicates a failure of the TDVMCALL mechanism itself and that
- * something has gone horribly wrong with the TDX module.
- *
- * The return status of the hypercall operation is in a separate
- * register (in R10). Hypercall errors are a part of normal operation
- * and are handled by callers.
- */
- testq %rax, %rax
- jne .Lpanic\@
-
- pop %rax
-
- .if \ret
- movq %r8, TDX_HYPERCALL_r8(%rax)
- movq %r9, TDX_HYPERCALL_r9(%rax)
- movq %r10, TDX_HYPERCALL_r10(%rax)
- movq %r11, TDX_HYPERCALL_r11(%rax)
- movq %r12, TDX_HYPERCALL_r12(%rax)
- movq %r13, TDX_HYPERCALL_r13(%rax)
- movq %r14, TDX_HYPERCALL_r14(%rax)
- movq %r15, TDX_HYPERCALL_r15(%rax)
- movq %rdi, TDX_HYPERCALL_rdi(%rax)
- movq %rsi, TDX_HYPERCALL_rsi(%rax)
- movq %rbx, TDX_HYPERCALL_rbx(%rax)
- movq %rdx, TDX_HYPERCALL_rdx(%rax)
- .endif
-
- /* TDVMCALL leaf return code is in R10 */
- movq %r10, %rax
-
- /*
- * Zero out registers exposed to the VMM to avoid speculative execution
- * with VMM-controlled values. This needs to include all registers
- * present in TDVMCALL_EXPOSE_REGS_MASK, except RBX, and R12-R15 which
- * will be restored.
- */
- xor %r8d, %r8d
- xor %r9d, %r9d
- xor %r10d, %r10d
- xor %r11d, %r11d
- xor %rdi, %rdi
- xor %rdx, %rdx
-
- /* Restore callee-saved GPRs as mandated by the x86_64 ABI */
- pop %rbx
- pop %r12
- pop %r13
- pop %r14
- pop %r15
-
- FRAME_END
-
- RET
-.Lpanic\@:
- call __tdx_hypercall_failed
- /* __tdx_hypercall_failed never returns */
- REACHABLE
- jmp .Lpanic\@
-.endm
+SYM_FUNC_START(__tdcall_ret)
+ TDX_MODULE_CALL host=0 ret=1
+SYM_FUNC_END(__tdcall_ret)
/*
+ * __tdcall_saved_ret() - Used by TDX guests to request services from the
+ * TDX module (including VMM services) using TDCALL instruction, with
+ * saving output registers to the 'struct tdx_module_args' used as input.
*
- * __tdx_hypercall() function ABI:
- *
- * @args (RDI) - struct tdx_hypercall_args for input
- *
- * On successful completion, return the hypercall error code.
- */
-SYM_FUNC_START(__tdx_hypercall)
- TDX_HYPERCALL ret=0
-SYM_FUNC_END(__tdx_hypercall)
-
-/*
+ * __tdcall_saved_ret() function ABI:
*
- * __tdx_hypercall_ret() function ABI:
+ * @fn (RDI) - TDCALL leaf ID, moved to RAX
+ * @args (RSI) - struct tdx_module_args for input/output
*
- * @args (RDI) - struct tdx_hypercall_args for input and output
+ * All registers in @args are used as input/output registers.
*
* On successful completion, return the hypercall error code.
*/
-SYM_FUNC_START(__tdx_hypercall_ret)
- TDX_HYPERCALL ret=1
-SYM_FUNC_END(__tdx_hypercall_ret)
+SYM_FUNC_START(__tdcall_saved_ret)
+ TDX_MODULE_CALL host=0 ret=1 saved=1
+SYM_FUNC_END(__tdcall_saved_ret)
diff --git a/arch/x86/coco/tdx/tdx-shared.c b/arch/x86/coco/tdx/tdx-shared.c
index ef20ddc37b58..78e413269791 100644
--- a/arch/x86/coco/tdx/tdx-shared.c
+++ b/arch/x86/coco/tdx/tdx-shared.c
@@ -5,7 +5,7 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len,
enum pg_level pg_level)
{
unsigned long accept_size = page_level_size(pg_level);
- u64 tdcall_rcx;
+ struct tdx_module_args args = {};
u8 page_size;
if (!IS_ALIGNED(start, accept_size))
@@ -34,8 +34,8 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len,
return 0;
}
- tdcall_rcx = start | page_size;
- if (__tdx_module_call(TDX_ACCEPT_PAGE, tdcall_rcx, 0, 0, 0, NULL))
+ args.rcx = start | page_size;
+ if (__tdcall(TDG_MEM_PAGE_ACCEPT, &args))
return 0;
return accept_size;
@@ -45,7 +45,7 @@ bool tdx_accept_memory(phys_addr_t start, phys_addr_t end)
{
/*
* For shared->private conversion, accept the page using
- * TDX_ACCEPT_PAGE TDX module call.
+ * TDG_MEM_PAGE_ACCEPT TDX module call.
*/
while (start < end) {
unsigned long len = end - start;
@@ -69,3 +69,23 @@ bool tdx_accept_memory(phys_addr_t start, phys_addr_t end)
return true;
}
+
+noinstr u64 __tdx_hypercall(struct tdx_module_args *args)
+{
+ /*
+ * For TDVMCALL explicitly set RCX to the bitmap of shared registers.
+ * The caller isn't expected to set @args->rcx anyway.
+ */
+ args->rcx = TDVMCALL_EXPOSE_REGS_MASK;
+
+ /*
+ * Failure of __tdcall_saved_ret() indicates a failure of the TDVMCALL
+ * mechanism itself and that something has gone horribly wrong with
+ * the TDX module. __tdx_hypercall_failed() never returns.
+ */
+ if (__tdcall_saved_ret(TDG_VP_VMCALL, args))
+ __tdx_hypercall_failed();
+
+ /* TDVMCALL leaf return code is in R10 */
+ return args->r10;
+}
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index 2e1be592c220..d11206ceff3b 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -38,7 +38,7 @@
#define TDREPORT_SUBTYPE_0 0
/* Called from __tdx_hypercall() for unrecoverable failure */
-noinstr void __tdx_hypercall_failed(void)
+noinstr void __noreturn __tdx_hypercall_failed(void)
{
instrumentation_begin();
panic("TDVMCALL failed. TDX module bug?");
@@ -48,7 +48,7 @@ noinstr void __tdx_hypercall_failed(void)
long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, unsigned long p2,
unsigned long p3, unsigned long p4)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = nr,
.r11 = p1,
.r12 = p2,
@@ -66,10 +66,9 @@ EXPORT_SYMBOL_GPL(tdx_kvm_hypercall);
* should only be used for calls that have no legitimate reason to fail
* or where the kernel can not survive the call failing.
*/
-static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
- struct tdx_module_output *out)
+static inline void tdcall(u64 fn, struct tdx_module_args *args)
{
- if (__tdx_module_call(fn, rcx, rdx, r8, r9, out))
+ if (__tdcall_ret(fn, args))
panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
}
@@ -89,11 +88,14 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
*/
int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport)
{
+ struct tdx_module_args args = {
+ .rcx = virt_to_phys(tdreport),
+ .rdx = virt_to_phys(reportdata),
+ .r8 = TDREPORT_SUBTYPE_0,
+ };
u64 ret;
- ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(tdreport),
- virt_to_phys(reportdata), TDREPORT_SUBTYPE_0,
- 0, NULL);
+ ret = __tdcall(TDG_MR_REPORT, &args);
if (ret) {
if (TDCALL_RETURN_CODE(ret) == TDCALL_INVALID_OPERAND)
return -EINVAL;
@@ -106,7 +108,7 @@ EXPORT_SYMBOL_GPL(tdx_mcall_get_report0);
static void __noreturn tdx_panic(const char *msg)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = TDVMCALL_REPORT_FATAL_ERROR,
.r12 = 0, /* Error code: 0 is Panic */
@@ -141,7 +143,7 @@ static void __noreturn tdx_panic(const char *msg)
static void tdx_parse_tdinfo(u64 *cc_mask)
{
- struct tdx_module_output out;
+ struct tdx_module_args args = {};
unsigned int gpa_width;
u64 td_attr;
@@ -152,7 +154,7 @@ static void tdx_parse_tdinfo(u64 *cc_mask)
* Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL
* [TDG.VP.INFO].
*/
- tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out);
+ tdcall(TDG_VP_INFO, &args);
/*
* The highest bit of a guest physical address is the "sharing" bit.
@@ -161,7 +163,7 @@ static void tdx_parse_tdinfo(u64 *cc_mask)
* The GPA width that comes out of this call is critical. TDX guests
* can not meaningfully run without it.
*/
- gpa_width = out.rcx & GENMASK(5, 0);
+ gpa_width = args.rcx & GENMASK(5, 0);
*cc_mask = BIT_ULL(gpa_width - 1);
/*
@@ -169,7 +171,7 @@ static void tdx_parse_tdinfo(u64 *cc_mask)
* memory. Ensure that no #VE will be delivered for accesses to
* TD-private memory. Only VMM-shared memory (MMIO) will #VE.
*/
- td_attr = out.rdx;
+ td_attr = args.rdx;
if (!(td_attr & ATTR_SEPT_VE_DISABLE)) {
const char *msg = "TD misconfiguration: SEPT_VE_DISABLE attribute must be set.";
@@ -228,7 +230,7 @@ static int ve_instr_len(struct ve_info *ve)
static u64 __cpuidle __halt(const bool irq_disabled)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_HLT),
.r12 = irq_disabled,
@@ -272,7 +274,7 @@ void __cpuidle tdx_safe_halt(void)
static int read_msr(struct pt_regs *regs, struct ve_info *ve)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_MSR_READ),
.r12 = regs->cx,
@@ -283,7 +285,7 @@ static int read_msr(struct pt_regs *regs, struct ve_info *ve)
* can be found in TDX Guest-Host-Communication Interface
* (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>".
*/
- if (__tdx_hypercall_ret(&args))
+ if (__tdx_hypercall(&args))
return -EIO;
regs->ax = lower_32_bits(args.r11);
@@ -293,7 +295,7 @@ static int read_msr(struct pt_regs *regs, struct ve_info *ve)
static int write_msr(struct pt_regs *regs, struct ve_info *ve)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_MSR_WRITE),
.r12 = regs->cx,
@@ -313,7 +315,7 @@ static int write_msr(struct pt_regs *regs, struct ve_info *ve)
static int handle_cpuid(struct pt_regs *regs, struct ve_info *ve)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_CPUID),
.r12 = regs->ax,
@@ -337,7 +339,7 @@ static int handle_cpuid(struct pt_regs *regs, struct ve_info *ve)
* ABI can be found in TDX Guest-Host-Communication Interface
* (GHCI), section titled "VP.VMCALL<Instruction.CPUID>".
*/
- if (__tdx_hypercall_ret(&args))
+ if (__tdx_hypercall(&args))
return -EIO;
/*
@@ -355,7 +357,7 @@ static int handle_cpuid(struct pt_regs *regs, struct ve_info *ve)
static bool mmio_read(int size, unsigned long addr, unsigned long *val)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_EPT_VIOLATION),
.r12 = size,
@@ -364,8 +366,9 @@ static bool mmio_read(int size, unsigned long addr, unsigned long *val)
.r15 = *val,
};
- if (__tdx_hypercall_ret(&args))
+ if (__tdx_hypercall(&args))
return false;
+
*val = args.r11;
return true;
}
@@ -483,7 +486,7 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
static bool handle_in(struct pt_regs *regs, int size, int port)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_IO_INSTRUCTION),
.r12 = size,
@@ -498,7 +501,7 @@ static bool handle_in(struct pt_regs *regs, int size, int port)
* in TDX Guest-Host-Communication Interface (GHCI) section titled
* "TDG.VP.VMCALL<Instruction.IO>".
*/
- success = !__tdx_hypercall_ret(&args);
+ success = !__tdx_hypercall(&args);
/* Update part of the register affected by the emulated instruction */
regs->ax &= ~mask;
@@ -577,7 +580,7 @@ __init bool tdx_early_handle_ve(struct pt_regs *regs)
void tdx_get_ve_info(struct ve_info *ve)
{
- struct tdx_module_output out;
+ struct tdx_module_args args = {};
/*
* Called during #VE handling to retrieve the #VE info from the
@@ -594,15 +597,15 @@ void tdx_get_ve_info(struct ve_info *ve)
* Note, the TDX module treats virtual NMIs as inhibited if the #VE
* valid flag is set. It means that NMI=>#VE will not result in a #DF.
*/
- tdx_module_call(TDX_GET_VEINFO, 0, 0, 0, 0, &out);
+ tdcall(TDG_VP_VEINFO_GET, &args);
/* Transfer the output parameters */
- ve->exit_reason = out.rcx;
- ve->exit_qual = out.rdx;
- ve->gla = out.r8;
- ve->gpa = out.r9;
- ve->instr_len = lower_32_bits(out.r10);
- ve->instr_info = upper_32_bits(out.r10);
+ ve->exit_reason = args.rcx;
+ ve->exit_qual = args.rdx;
+ ve->gla = args.r8;
+ ve->gpa = args.r9;
+ ve->instr_len = lower_32_bits(args.r10);
+ ve->instr_info = upper_32_bits(args.r10);
}
/*
@@ -703,14 +706,15 @@ static bool tdx_cache_flush_required(void)
}
/*
- * Inform the VMM of the guest's intent for this physical page: shared with
- * the VMM or private to the guest. The VMM is expected to change its mapping
- * of the page in response.
+ * Notify the VMM about page mapping conversion. More info about ABI
+ * can be found in TDX Guest-Host-Communication Interface (GHCI),
+ * section "TDG.VP.VMCALL<MapGPA>".
*/
-static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc)
+static bool tdx_map_gpa(phys_addr_t start, phys_addr_t end, bool enc)
{
- phys_addr_t start = __pa(vaddr);
- phys_addr_t end = __pa(vaddr + numpages * PAGE_SIZE);
+ /* Retrying the hypercall a second time should succeed; use 3 just in case */
+ const int max_retries_per_page = 3;
+ int retry_count = 0;
if (!enc) {
/* Set the shared (decrypted) bits: */
@@ -718,12 +722,51 @@ static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc)
end |= cc_mkdec(0);
}
- /*
- * Notify the VMM about page mapping conversion. More info about ABI
- * can be found in TDX Guest-Host-Communication Interface (GHCI),
- * section "TDG.VP.VMCALL<MapGPA>"
- */
- if (_tdx_hypercall(TDVMCALL_MAP_GPA, start, end - start, 0, 0))
+ while (retry_count < max_retries_per_page) {
+ struct tdx_module_args args = {
+ .r10 = TDX_HYPERCALL_STANDARD,
+ .r11 = TDVMCALL_MAP_GPA,
+ .r12 = start,
+ .r13 = end - start };
+
+ u64 map_fail_paddr;
+ u64 ret = __tdx_hypercall(&args);
+
+ if (ret != TDVMCALL_STATUS_RETRY)
+ return !ret;
+ /*
+ * The guest must retry the operation for the pages in the
+ * region starting at the GPA specified in R11. R11 comes
+ * from the untrusted VMM. Sanity check it.
+ */
+ map_fail_paddr = args.r11;
+ if (map_fail_paddr < start || map_fail_paddr >= end)
+ return false;
+
+ /* "Consume" a retry without forward progress */
+ if (map_fail_paddr == start) {
+ retry_count++;
+ continue;
+ }
+
+ start = map_fail_paddr;
+ retry_count = 0;
+ }
+
+ return false;
+}
+
+/*
+ * Inform the VMM of the guest's intent for this physical page: shared with
+ * the VMM or private to the guest. The VMM is expected to change its mapping
+ * of the page in response.
+ */
+static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc)
+{
+ phys_addr_t start = __pa(vaddr);
+ phys_addr_t end = __pa(vaddr + numpages * PAGE_SIZE);
+
+ if (!tdx_map_gpa(start, end, enc))
return false;
/* shared->private conversion requires memory to be accepted before use */
@@ -759,6 +802,10 @@ static bool tdx_enc_status_change_finish(unsigned long vaddr, int numpages,
void __init tdx_early_init(void)
{
+ struct tdx_module_args args = {
+ .rdx = TDCS_NOTIFY_ENABLES,
+ .r9 = -1ULL,
+ };
u64 cc_mask;
u32 eax, sig[3];
@@ -769,12 +816,15 @@ void __init tdx_early_init(void)
setup_force_cpu_cap(X86_FEATURE_TDX_GUEST);
+ /* TSC is the only reliable clock in TDX guest */
+ setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
cc_vendor = CC_VENDOR_INTEL;
tdx_parse_tdinfo(&cc_mask);
cc_set_mask(cc_mask);
/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */
- tdx_module_call(TDX_WR, 0, TDCS_NOTIFY_ENABLES, 0, -1ULL, NULL);
+ tdcall(TDG_VM_WR, &args);
/*
* All bits above GPA width are reserved and kernel treats shared bit
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 31c48bc2c3d8..c8fac5205803 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -264,7 +264,7 @@
250 i386 fadvise64 sys_ia32_fadvise64
# 251 is available for reuse (was briefly sys_set_zone_reclaim)
252 i386 exit_group sys_exit_group
-253 i386 lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie
+253 i386 lookup_dcookie
254 i386 epoll_create sys_epoll_create
255 i386 epoll_ctl sys_epoll_ctl
256 i386 epoll_wait sys_epoll_wait
@@ -457,6 +457,7 @@
450 i386 set_mempolicy_home_node sys_set_mempolicy_home_node
451 i386 cachestat sys_cachestat
452 i386 fchmodat2 sys_fchmodat2
+453 i386 map_shadow_stack sys_map_shadow_stack
454 i386 futex_wake sys_futex_wake
455 i386 futex_wait sys_futex_wait
456 i386 futex_requeue sys_futex_requeue
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index a577bb27c16d..8cb8bf68721c 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -220,7 +220,7 @@
209 64 io_submit sys_io_submit
210 common io_cancel sys_io_cancel
211 64 get_thread_area
-212 common lookup_dcookie sys_lookup_dcookie
+212 common lookup_dcookie
213 common epoll_create sys_epoll_create
214 64 epoll_ctl_old
215 64 epoll_wait_old
diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c
index f3b3cacbcbb0..76e4e74f35b5 100644
--- a/arch/x86/entry/vdso/vdso32-setup.c
+++ b/arch/x86/entry/vdso/vdso32-setup.c
@@ -67,7 +67,6 @@ static struct ctl_table abi_table2[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
- {}
};
static __init int ia32_binfmt_init(void)
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index c6edde1a1dec..02e55237d919 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -384,7 +384,7 @@ static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
#ifdef CONFIG_INTEL_TDX_GUEST
static void hv_tdx_msr_write(u64 msr, u64 val)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = EXIT_REASON_MSR_WRITE,
.r12 = msr,
@@ -398,13 +398,13 @@ static void hv_tdx_msr_write(u64 msr, u64 val)
static void hv_tdx_msr_read(u64 msr, u64 *val)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = EXIT_REASON_MSR_READ,
.r12 = msr,
};
- u64 ret = __tdx_hypercall_ret(&args);
+ u64 ret = __tdx_hypercall(&args);
if (WARN_ONCE(ret, "Failed to emulate MSR read: %lld\n", ret))
*val = 0;
@@ -414,13 +414,13 @@ static void hv_tdx_msr_read(u64 msr, u64 *val)
u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2)
{
- struct tdx_hypercall_args args = { };
+ struct tdx_module_args args = { };
args.r10 = control;
args.rdx = param1;
args.r8 = param2;
- (void)__tdx_hypercall_ret(&args);
+ (void)__tdx_hypercall(&args);
return args.r11;
}
diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
index 7513b3bb69b7..f74695dea217 100644
--- a/arch/x86/include/asm/shared/tdx.h
+++ b/arch/x86/include/asm/shared/tdx.h
@@ -11,11 +11,12 @@
#define TDX_IDENT "IntelTDX "
/* TDX module Call Leaf IDs */
-#define TDX_GET_INFO 1
-#define TDX_GET_VEINFO 3
-#define TDX_GET_REPORT 4
-#define TDX_ACCEPT_PAGE 6
-#define TDX_WR 8
+#define TDG_VP_VMCALL 0
+#define TDG_VP_INFO 1
+#define TDG_VP_VEINFO_GET 3
+#define TDG_MR_REPORT 4
+#define TDG_MEM_PAGE_ACCEPT 6
+#define TDG_VM_WR 8
/* TDCS fields. To be used by TDG.VM.WR and TDG.VM.RD module calls */
#define TDCS_NOTIFY_ENABLES 0x9100000000000010
@@ -24,32 +25,70 @@
#define TDVMCALL_MAP_GPA 0x10001
#define TDVMCALL_REPORT_FATAL_ERROR 0x10003
+#define TDVMCALL_STATUS_RETRY 1
+
+/*
+ * Bitmasks of exposed registers (with VMM).
+ */
+#define TDX_RDX BIT(2)
+#define TDX_RBX BIT(3)
+#define TDX_RSI BIT(6)
+#define TDX_RDI BIT(7)
+#define TDX_R8 BIT(8)
+#define TDX_R9 BIT(9)
+#define TDX_R10 BIT(10)
+#define TDX_R11 BIT(11)
+#define TDX_R12 BIT(12)
+#define TDX_R13 BIT(13)
+#define TDX_R14 BIT(14)
+#define TDX_R15 BIT(15)
+
+/*
+ * These registers are clobbered to hold arguments for each
+ * TDVMCALL. They are safe to expose to the VMM.
+ * Each bit in this mask represents a register ID. Bit field
+ * details can be found in TDX GHCI specification, section
+ * titled "TDCALL [TDG.VP.VMCALL] leaf".
+ */
+#define TDVMCALL_EXPOSE_REGS_MASK \
+ (TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8 | TDX_R9 | \
+ TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15)
+
#ifndef __ASSEMBLY__
+#include <linux/compiler_attributes.h>
+
/*
- * Used in __tdx_hypercall() to pass down and get back registers' values of
- * the TDCALL instruction when requesting services from the VMM.
- *
- * This is a software only structure and not part of the TDX module/VMM ABI.
+ * Used in __tdcall*() to gather the input/output registers' values of the
+ * TDCALL instruction when requesting services from the TDX module. This is a
+ * software only structure and not part of the TDX module/VMM ABI
*/
-struct tdx_hypercall_args {
+struct tdx_module_args {
+ /* callee-clobbered */
+ u64 rcx;
+ u64 rdx;
u64 r8;
u64 r9;
+ /* extra callee-clobbered */
u64 r10;
u64 r11;
+ /* callee-saved + rdi/rsi */
u64 r12;
u64 r13;
u64 r14;
u64 r15;
+ u64 rbx;
u64 rdi;
u64 rsi;
- u64 rbx;
- u64 rdx;
};
+/* Used to communicate with the TDX module */
+u64 __tdcall(u64 fn, struct tdx_module_args *args);
+u64 __tdcall_ret(u64 fn, struct tdx_module_args *args);
+u64 __tdcall_saved_ret(u64 fn, struct tdx_module_args *args);
+
/* Used to request services from the VMM */
-u64 __tdx_hypercall(struct tdx_hypercall_args *args);
-u64 __tdx_hypercall_ret(struct tdx_hypercall_args *args);
+u64 __tdx_hypercall(struct tdx_module_args *args);
/*
* Wrapper for standard use of __tdx_hypercall with no output aside from
@@ -57,7 +96,7 @@ u64 __tdx_hypercall_ret(struct tdx_hypercall_args *args);
*/
static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15)
{
- struct tdx_hypercall_args args = {
+ struct tdx_module_args args = {
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = fn,
.r12 = r12,
@@ -71,25 +110,7 @@ static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15)
/* Called from __tdx_hypercall() for unrecoverable failure */
-void __tdx_hypercall_failed(void);
-
-/*
- * Used in __tdx_module_call() to gather the output registers' values of the
- * TDCALL instruction when requesting services from the TDX module. This is a
- * software only structure and not part of the TDX module/VMM ABI
- */
-struct tdx_module_output {
- u64 rcx;
- u64 rdx;
- u64 r8;
- u64 r9;
- u64 r10;
- u64 r11;
-};
-
-/* Used to communicate with the TDX module */
-u64 __tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
- struct tdx_module_output *out);
+void __noreturn __tdx_hypercall_failed(void);
bool tdx_accept_memory(phys_addr_t start, phys_addr_t end);
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index 603e6d1e9d4a..adcbe3f1de30 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -8,6 +8,7 @@
#include <asm/errno.h>
#include <asm/ptrace.h>
+#include <asm/trapnr.h>
#include <asm/shared/tdx.h>
/*
@@ -20,6 +21,9 @@
#define TDX_SW_ERROR (TDX_ERROR | GENMASK_ULL(47, 40))
#define TDX_SEAMCALL_VMFAILINVALID (TDX_SW_ERROR | _UL(0xFFFF0000))
+#define TDX_SEAMCALL_GP (TDX_SW_ERROR | X86_TRAP_GP)
+#define TDX_SEAMCALL_UD (TDX_SW_ERROR | X86_TRAP_UD)
+
#ifndef __ASSEMBLY__
/*
@@ -72,5 +76,12 @@ static inline long tdx_kvm_hypercall(unsigned int nr, unsigned long p1,
return -ENODEV;
}
#endif /* CONFIG_INTEL_TDX_GUEST && CONFIG_KVM_GUEST */
+
+#ifdef CONFIG_INTEL_TDX_HOST
+u64 __seamcall(u64 fn, struct tdx_module_args *args);
+u64 __seamcall_ret(u64 fn, struct tdx_module_args *args);
+u64 __seamcall_saved_ret(u64 fn, struct tdx_module_args *args);
+#endif /* CONFIG_INTEL_TDX_HOST */
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_X86_TDX_H */
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index dc3576303f1a..6913b372ccf7 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -68,26 +68,19 @@ static void __used common(void)
#endif
BLANK();
- OFFSET(TDX_MODULE_rcx, tdx_module_output, rcx);
- OFFSET(TDX_MODULE_rdx, tdx_module_output, rdx);
- OFFSET(TDX_MODULE_r8, tdx_module_output, r8);
- OFFSET(TDX_MODULE_r9, tdx_module_output, r9);
- OFFSET(TDX_MODULE_r10, tdx_module_output, r10);
- OFFSET(TDX_MODULE_r11, tdx_module_output, r11);
-
- BLANK();
- OFFSET(TDX_HYPERCALL_r8, tdx_hypercall_args, r8);
- OFFSET(TDX_HYPERCALL_r9, tdx_hypercall_args, r9);
- OFFSET(TDX_HYPERCALL_r10, tdx_hypercall_args, r10);
- OFFSET(TDX_HYPERCALL_r11, tdx_hypercall_args, r11);
- OFFSET(TDX_HYPERCALL_r12, tdx_hypercall_args, r12);
- OFFSET(TDX_HYPERCALL_r13, tdx_hypercall_args, r13);
- OFFSET(TDX_HYPERCALL_r14, tdx_hypercall_args, r14);
- OFFSET(TDX_HYPERCALL_r15, tdx_hypercall_args, r15);
- OFFSET(TDX_HYPERCALL_rdi, tdx_hypercall_args, rdi);
- OFFSET(TDX_HYPERCALL_rsi, tdx_hypercall_args, rsi);
- OFFSET(TDX_HYPERCALL_rbx, tdx_hypercall_args, rbx);
- OFFSET(TDX_HYPERCALL_rdx, tdx_hypercall_args, rdx);
+ OFFSET(TDX_MODULE_rcx, tdx_module_args, rcx);
+ OFFSET(TDX_MODULE_rdx, tdx_module_args, rdx);
+ OFFSET(TDX_MODULE_r8, tdx_module_args, r8);
+ OFFSET(TDX_MODULE_r9, tdx_module_args, r9);
+ OFFSET(TDX_MODULE_r10, tdx_module_args, r10);
+ OFFSET(TDX_MODULE_r11, tdx_module_args, r11);
+ OFFSET(TDX_MODULE_r12, tdx_module_args, r12);
+ OFFSET(TDX_MODULE_r13, tdx_module_args, r13);
+ OFFSET(TDX_MODULE_r14, tdx_module_args, r14);
+ OFFSET(TDX_MODULE_r15, tdx_module_args, r15);
+ OFFSET(TDX_MODULE_rbx, tdx_module_args, rbx);
+ OFFSET(TDX_MODULE_rdi, tdx_module_args, rdi);
+ OFFSET(TDX_MODULE_rsi, tdx_module_args, rsi);
BLANK();
OFFSET(BP_scratch, boot_params, scratch);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 55efadb0e998..a927a8fc9624 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -1003,7 +1003,6 @@ static struct ctl_table sld_sysctls[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
- {}
};
static int __init sld_mitigate_sysctl_init(void)
diff --git a/arch/x86/kernel/itmt.c b/arch/x86/kernel/itmt.c
index ee4fe8cdb857..9a7c03d47861 100644
--- a/arch/x86/kernel/itmt.c
+++ b/arch/x86/kernel/itmt.c
@@ -74,7 +74,6 @@ static struct ctl_table itmt_kern_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
- {}
};
static struct ctl_table_header *itmt_sysctl_header;
diff --git a/arch/ia64/kernel/.gitignore b/arch/x86/virt/Makefile
index 0374827206e7..1e36502cd738 100644
--- a/arch/ia64/kernel/.gitignore
+++ b/arch/x86/virt/Makefile
@@ -1,3 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
-gate.lds
-vmlinux.lds
+obj-y += vmx/
diff --git a/arch/x86/virt/vmx/Makefile b/arch/x86/virt/vmx/Makefile
new file mode 100644
index 000000000000..feebda21d793
--- /dev/null
+++ b/arch/x86/virt/vmx/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_INTEL_TDX_HOST) += tdx/
diff --git a/arch/x86/virt/vmx/tdx/Makefile b/arch/x86/virt/vmx/tdx/Makefile
new file mode 100644
index 000000000000..46ef8f73aebb
--- /dev/null
+++ b/arch/x86/virt/vmx/tdx/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y += seamcall.o
diff --git a/arch/x86/virt/vmx/tdx/seamcall.S b/arch/x86/virt/vmx/tdx/seamcall.S
new file mode 100644
index 000000000000..5b1f2286aea9
--- /dev/null
+++ b/arch/x86/virt/vmx/tdx/seamcall.S
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <asm/frame.h>
+
+#include "tdxcall.S"
+
+/*
+ * __seamcall() - Host-side interface functions to SEAM software
+ * (the P-SEAMLDR or the TDX module).
+ *
+ * __seamcall() function ABI:
+ *
+ * @fn (RDI) - SEAMCALL Leaf number, moved to RAX
+ * @args (RSI) - struct tdx_module_args for input
+ *
+ * Only RCX/RDX/R8-R11 are used as input registers.
+ *
+ * Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself
+ * fails, or the completion status of the SEAMCALL leaf function.
+ */
+SYM_FUNC_START(__seamcall)
+ TDX_MODULE_CALL host=1
+SYM_FUNC_END(__seamcall)
+
+/*
+ * __seamcall_ret() - Host-side interface functions to SEAM software
+ * (the P-SEAMLDR or the TDX module), with saving output registers to
+ * the 'struct tdx_module_args' used as input.
+ *
+ * __seamcall_ret() function ABI:
+ *
+ * @fn (RDI) - SEAMCALL Leaf number, moved to RAX
+ * @args (RSI) - struct tdx_module_args for input and output
+ *
+ * Only RCX/RDX/R8-R11 are used as input/output registers.
+ *
+ * Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself
+ * fails, or the completion status of the SEAMCALL leaf function.
+ */
+SYM_FUNC_START(__seamcall_ret)
+ TDX_MODULE_CALL host=1 ret=1
+SYM_FUNC_END(__seamcall_ret)
+
+/*
+ * __seamcall_saved_ret() - Host-side interface functions to SEAM software
+ * (the P-SEAMLDR or the TDX module), with saving output registers to the
+ * 'struct tdx_module_args' used as input.
+ *
+ * __seamcall_saved_ret() function ABI:
+ *
+ * @fn (RDI) - SEAMCALL Leaf number, moved to RAX
+ * @args (RSI) - struct tdx_module_args for input and output
+ *
+ * All registers in @args are used as input/output registers.
+ *
+ * Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself
+ * fails, or the completion status of the SEAMCALL leaf function.
+ */
+SYM_FUNC_START(__seamcall_saved_ret)
+ TDX_MODULE_CALL host=1 ret=1 saved=1
+SYM_FUNC_END(__seamcall_saved_ret)
diff --git a/arch/x86/virt/vmx/tdx/tdxcall.S b/arch/x86/virt/vmx/tdx/tdxcall.S
index 49a54356ae99..016a2a1ec1d6 100644
--- a/arch/x86/virt/vmx/tdx/tdxcall.S
+++ b/arch/x86/virt/vmx/tdx/tdxcall.S
@@ -1,5 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <asm/asm-offsets.h>
+#include <asm/frame.h>
+#include <asm/asm.h>
#include <asm/tdx.h>
/*
@@ -16,35 +18,75 @@
* TDX module and hypercalls to the VMM.
* SEAMCALL - used by TDX hosts to make requests to the
* TDX module.
+ *
+ *-------------------------------------------------------------------------
+ * TDCALL/SEAMCALL ABI:
+ *-------------------------------------------------------------------------
+ * Input Registers:
+ *
+ * RAX - TDCALL/SEAMCALL Leaf number.
+ * RCX,RDX,RDI,RSI,RBX,R8-R15 - TDCALL/SEAMCALL Leaf specific input registers.
+ *
+ * Output Registers:
+ *
+ * RAX - TDCALL/SEAMCALL instruction error code.
+ * RCX,RDX,RDI,RSI,RBX,R8-R15 - TDCALL/SEAMCALL Leaf specific output registers.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * So while the common core (RAX,RCX,RDX,R8-R11) fits nicely in the
+ * callee-clobbered registers and even leaves RDI,RSI free to act as a
+ * base pointer, some leafs (e.g., VP.ENTER) make a giant mess of things.
+ *
+ * For simplicity, assume that anything that needs the callee-saved regs
+ * also tramples on RDI,RSI. This isn't strictly true, see for example
+ * TDH.EXPORT.MEM.
*/
-.macro TDX_MODULE_CALL host:req
- /*
- * R12 will be used as temporary storage for struct tdx_module_output
- * pointer. Since R12-R15 registers are not used by TDCALL/SEAMCALL
- * services supported by this function, it can be reused.
- */
+.macro TDX_MODULE_CALL host:req ret=0 saved=0
+ FRAME_BEGIN
- /* Callee saved, so preserve it */
- push %r12
+ /* Move Leaf ID to RAX */
+ mov %rdi, %rax
+
+ /* Move other input regs from 'struct tdx_module_args' */
+ movq TDX_MODULE_rcx(%rsi), %rcx
+ movq TDX_MODULE_rdx(%rsi), %rdx
+ movq TDX_MODULE_r8(%rsi), %r8
+ movq TDX_MODULE_r9(%rsi), %r9
+ movq TDX_MODULE_r10(%rsi), %r10
+ movq TDX_MODULE_r11(%rsi), %r11
+.if \saved
/*
- * Push output pointer to stack.
- * After the operation, it will be fetched into R12 register.
+ * Move additional input regs from the structure. For simplicity
+ * assume that anything needs the callee-saved regs also tramples
+ * on RDI/RSI (see VP.ENTER).
*/
- push %r9
+ /* Save those callee-saved GPRs as mandated by the x86_64 ABI */
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
- /* Mangle function call ABI into TDCALL/SEAMCALL ABI: */
- /* Move Leaf ID to RAX */
- mov %rdi, %rax
- /* Move input 4 to R9 */
- mov %r8, %r9
- /* Move input 3 to R8 */
- mov %rcx, %r8
- /* Move input 1 to RCX */
- mov %rsi, %rcx
- /* Leave input param 2 in RDX */
-
- .if \host
+ movq TDX_MODULE_r12(%rsi), %r12
+ movq TDX_MODULE_r13(%rsi), %r13
+ movq TDX_MODULE_r14(%rsi), %r14
+ movq TDX_MODULE_r15(%rsi), %r15
+ movq TDX_MODULE_rbx(%rsi), %rbx
+
+.if \ret
+ /* Save the structure pointer as RSI is about to be clobbered */
+ pushq %rsi
+.endif
+
+ movq TDX_MODULE_rdi(%rsi), %rdi
+ /* RSI needs to be done at last */
+ movq TDX_MODULE_rsi(%rsi), %rsi
+.endif /* \saved */
+
+.if \host
+.Lseamcall\@:
seamcall
/*
* SEAMCALL instruction is essentially a VMExit from VMX root
@@ -57,40 +99,122 @@
* This value will never be used as actual SEAMCALL error code as
* it is from the Reserved status code class.
*/
- jnc .Lno_vmfailinvalid
- mov $TDX_SEAMCALL_VMFAILINVALID, %rax
-.Lno_vmfailinvalid:
-
- .else
+ jc .Lseamcall_vmfailinvalid\@
+.else
tdcall
- .endif
+.endif
+.if \ret
+.if \saved
/*
- * Fetch output pointer from stack to R12 (It is used
- * as temporary storage)
+ * Restore the structure from stack to save the output registers
+ *
+ * In case of VP.ENTER returns due to TDVMCALL, all registers are
+ * valid thus no register can be used as spare to restore the
+ * structure from the stack (see "TDH.VP.ENTER Output Operands
+ * Definition on TDCALL(TDG.VP.VMCALL) Following a TD Entry").
+ * For this case, need to make one register as spare by saving it
+ * to the stack and then manually load the structure pointer to
+ * the spare register.
+ *
+ * Note for other TDCALLs/SEAMCALLs there are spare registers
+ * thus no need for such hack but just use this for all.
*/
- pop %r12
+ pushq %rax /* save the TDCALL/SEAMCALL return code */
+ movq 8(%rsp), %rax /* restore the structure pointer */
+ movq %rsi, TDX_MODULE_rsi(%rax) /* save RSI */
+ popq %rax /* restore the return code */
+ popq %rsi /* pop the structure pointer */
+
+ /* Copy additional output regs to the structure */
+ movq %r12, TDX_MODULE_r12(%rsi)
+ movq %r13, TDX_MODULE_r13(%rsi)
+ movq %r14, TDX_MODULE_r14(%rsi)
+ movq %r15, TDX_MODULE_r15(%rsi)
+ movq %rbx, TDX_MODULE_rbx(%rsi)
+ movq %rdi, TDX_MODULE_rdi(%rsi)
+.endif /* \saved */
+ /* Copy output registers to the structure */
+ movq %rcx, TDX_MODULE_rcx(%rsi)
+ movq %rdx, TDX_MODULE_rdx(%rsi)
+ movq %r8, TDX_MODULE_r8(%rsi)
+ movq %r9, TDX_MODULE_r9(%rsi)
+ movq %r10, TDX_MODULE_r10(%rsi)
+ movq %r11, TDX_MODULE_r11(%rsi)
+.endif /* \ret */
+
+.if \saved && \ret
/*
- * Since this macro can be invoked with NULL as an output pointer,
- * check if caller provided an output struct before storing output
- * registers.
+ * Clear registers shared by guest for VP.VMCALL/VP.ENTER to prevent
+ * speculative use of guest's/VMM's values, including those are
+ * restored from the stack.
+ *
+ * See arch/x86/kvm/vmx/vmenter.S:
*
- * Update output registers, even if the call failed (RAX != 0).
- * Other registers may contain details of the failure.
+ * In theory, a L1 cache miss when restoring register from stack
+ * could lead to speculative execution with guest's values.
+ *
+ * Note: RBP/RSP are not used as shared register. RSI has been
+ * restored already.
+ *
+ * XOR is cheap, thus unconditionally do for all leafs.
*/
- test %r12, %r12
- jz .Lno_output_struct
-
- /* Copy result registers to output struct: */
- movq %rcx, TDX_MODULE_rcx(%r12)
- movq %rdx, TDX_MODULE_rdx(%r12)
- movq %r8, TDX_MODULE_r8(%r12)
- movq %r9, TDX_MODULE_r9(%r12)
- movq %r10, TDX_MODULE_r10(%r12)
- movq %r11, TDX_MODULE_r11(%r12)
-
-.Lno_output_struct:
- /* Restore the state of R12 register */
- pop %r12
+ xorl %ecx, %ecx
+ xorl %edx, %edx
+ xorl %r8d, %r8d
+ xorl %r9d, %r9d
+ xorl %r10d, %r10d
+ xorl %r11d, %r11d
+ xorl %r12d, %r12d
+ xorl %r13d, %r13d
+ xorl %r14d, %r14d
+ xorl %r15d, %r15d
+ xorl %ebx, %ebx
+ xorl %edi, %edi
+.endif /* \ret && \host */
+
+.if \host
+.Lout\@:
+.endif
+
+.if \saved
+ /* Restore callee-saved GPRs as mandated by the x86_64 ABI */
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+.endif /* \saved */
+
+ FRAME_END
+ RET
+
+.if \host
+.Lseamcall_vmfailinvalid\@:
+ mov $TDX_SEAMCALL_VMFAILINVALID, %rax
+ jmp .Lseamcall_fail\@
+
+.Lseamcall_trap\@:
+ /*
+ * SEAMCALL caused #GP or #UD. By reaching here RAX contains
+ * the trap number. Convert the trap number to the TDX error
+ * code by setting TDX_SW_ERROR to the high 32-bits of RAX.
+ *
+ * Note cannot OR TDX_SW_ERROR directly to RAX as OR instruction
+ * only accepts 32-bit immediate at most.
+ */
+ movq $TDX_SW_ERROR, %rdi
+ orq %rdi, %rax
+
+.Lseamcall_fail\@:
+.if \ret && \saved
+ /* pop the unused structure pointer back to RSI */
+ popq %rsi
+.endif
+ jmp .Lout\@
+
+ _ASM_EXTABLE_FAULT(.Lseamcall\@, .Lseamcall_trap\@)
+.endif /* \host */
+
.endm
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index dd71ecce8b86..06eefa9c1458 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
@@ -273,7 +273,7 @@
252 common timer_getoverrun sys_timer_getoverrun
# System
253 common reserved253 sys_ni_syscall
-254 common lookup_dcookie sys_lookup_dcookie
+254 common lookup_dcookie sys_ni_syscall
255 common available255 sys_ni_syscall
256 common add_key sys_add_key
257 common request_key sys_request_key
@@ -423,6 +423,7 @@
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
+453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
diff --git a/block/Kconfig b/block/Kconfig
index f1364d1c0d93..55ae2286a4de 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -186,6 +186,7 @@ config BLK_SED_OPAL
bool "Logic for interfacing with Opal enabled SEDs"
depends on KEYS
select PSERIES_PLPKS if PPC_PSERIES
+ select PSERIES_PLPKS_SED if PPC_PSERIES
help
Builds Logic for interfacing with Opal enabled controllers.
Enabling this option enables users to setup/unlock/lock
diff --git a/block/badblocks.c b/block/badblocks.c
index 3afb550c0f7b..fc92d4e18aa3 100644
--- a/block/badblocks.c
+++ b/block/badblocks.c
@@ -16,119 +16,830 @@
#include <linux/types.h>
#include <linux/slab.h>
-/**
- * badblocks_check() - check a given range for bad sectors
- * @bb: the badblocks structure that holds all badblock information
- * @s: sector (start) at which to check for badblocks
- * @sectors: number of sectors to check for badblocks
- * @first_bad: pointer to store location of the first badblock
- * @bad_sectors: pointer to store number of badblocks after @first_bad
+/*
+ * The purpose of badblocks set/clear is to manage bad blocks ranges which are
+ * identified by LBA addresses.
*
- * We can record which blocks on each device are 'bad' and so just
- * fail those blocks, or that stripe, rather than the whole device.
- * Entries in the bad-block table are 64bits wide. This comprises:
- * Length of bad-range, in sectors: 0-511 for lengths 1-512
- * Start of bad-range, sector offset, 54 bits (allows 8 exbibytes)
- * A 'shift' can be set so that larger blocks are tracked and
- * consequently larger devices can be covered.
- * 'Acknowledged' flag - 1 bit. - the most significant bit.
+ * When the caller of badblocks_set() wants to set a range of bad blocks, the
+ * setting range can be acked or unacked. And the setting range may merge,
+ * overwrite, skip the overlapped already set range, depends on who they are
+ * overlapped or adjacent, and the acknowledgment type of the ranges. It can be
+ * more complicated when the setting range covers multiple already set bad block
+ * ranges, with restrictions of maximum length of each bad range and the bad
+ * table space limitation.
*
- * Locking of the bad-block table uses a seqlock so badblocks_check
- * might need to retry if it is very unlucky.
- * We will sometimes want to check for bad blocks in a bi_end_io function,
- * so we use the write_seqlock_irq variant.
+ * It is difficult and unnecessary to take care of all the possible situations,
+ * for setting a large range of bad blocks, we can handle it by dividing the
+ * large range into smaller ones when encounter overlap, max range length or
+ * bad table full conditions. Every time only a smaller piece of the bad range
+ * is handled with a limited number of conditions how it is interacted with
+ * possible overlapped or adjacent already set bad block ranges. Then the hard
+ * complicated problem can be much simpler to handle in proper way.
*
- * When looking for a bad block we specify a range and want to
- * know if any block in the range is bad. So we binary-search
- * to the last range that starts at-or-before the given endpoint,
- * (or "before the sector after the target range")
- * then see if it ends after the given start.
+ * When setting a range of bad blocks to the bad table, the simplified situations
+ * to be considered are, (The already set bad blocks ranges are naming with
+ * prefix E, and the setting bad blocks range is naming with prefix S)
*
- * Return:
- * 0: there are no known bad blocks in the range
- * 1: there are known bad block which are all acknowledged
- * -1: there are bad blocks which have not yet been acknowledged in metadata.
- * plus the start/length of the first bad section we overlap.
+ * 1) A setting range is not overlapped or adjacent to any other already set bad
+ * block range.
+ * +--------+
+ * | S |
+ * +--------+
+ * +-------------+ +-------------+
+ * | E1 | | E2 |
+ * +-------------+ +-------------+
+ * For this situation if the bad blocks table is not full, just allocate a
+ * free slot from the bad blocks table to mark the setting range S. The
+ * result is,
+ * +-------------+ +--------+ +-------------+
+ * | E1 | | S | | E2 |
+ * +-------------+ +--------+ +-------------+
+ * 2) A setting range starts exactly at a start LBA of an already set bad blocks
+ * range.
+ * 2.1) The setting range size < already set range size
+ * +--------+
+ * | S |
+ * +--------+
+ * +-------------+
+ * | E |
+ * +-------------+
+ * 2.1.1) If S and E are both acked or unacked range, the setting range S can
+ * be merged into existing bad range E. The result is,
+ * +-------------+
+ * | S |
+ * +-------------+
+ * 2.1.2) If S is unacked setting and E is acked, the setting will be denied, and
+ * the result is,
+ * +-------------+
+ * | E |
+ * +-------------+
+ * 2.1.3) If S is acked setting and E is unacked, range S can overwrite on E.
+ * An extra slot from the bad blocks table will be allocated for S, and head
+ * of E will move to end of the inserted range S. The result is,
+ * +--------+----+
+ * | S | E |
+ * +--------+----+
+ * 2.2) The setting range size == already set range size
+ * 2.2.1) If S and E are both acked or unacked range, the setting range S can
+ * be merged into existing bad range E. The result is,
+ * +-------------+
+ * | S |
+ * +-------------+
+ * 2.2.2) If S is unacked setting and E is acked, the setting will be denied, and
+ * the result is,
+ * +-------------+
+ * | E |
+ * +-------------+
+ * 2.2.3) If S is acked setting and E is unacked, range S can overwrite all of
+ bad blocks range E. The result is,
+ * +-------------+
+ * | S |
+ * +-------------+
+ * 2.3) The setting range size > already set range size
+ * +-------------------+
+ * | S |
+ * +-------------------+
+ * +-------------+
+ * | E |
+ * +-------------+
+ * For such situation, the setting range S can be treated as two parts, the
+ * first part (S1) is as same size as the already set range E, the second
+ * part (S2) is the rest of setting range.
+ * +-------------+-----+ +-------------+ +-----+
+ * | S1 | S2 | | S1 | | S2 |
+ * +-------------+-----+ ===> +-------------+ +-----+
+ * +-------------+ +-------------+
+ * | E | | E |
+ * +-------------+ +-------------+
+ * Now we only focus on how to handle the setting range S1 and already set
+ * range E, which are already explained in 2.2), for the rest S2 it will be
+ * handled later in next loop.
+ * 3) A setting range starts before the start LBA of an already set bad blocks
+ * range.
+ * +-------------+
+ * | S |
+ * +-------------+
+ * +-------------+
+ * | E |
+ * +-------------+
+ * For this situation, the setting range S can be divided into two parts, the
+ * first (S1) ends at the start LBA of already set range E, the second part
+ * (S2) starts exactly at a start LBA of the already set range E.
+ * +----+---------+ +----+ +---------+
+ * | S1 | S2 | | S1 | | S2 |
+ * +----+---------+ ===> +----+ +---------+
+ * +-------------+ +-------------+
+ * | E | | E |
+ * +-------------+ +-------------+
+ * Now only the first part S1 should be handled in this loop, which is in
+ * similar condition as 1). The rest part S2 has exact same start LBA address
+ * of the already set range E, they will be handled in next loop in one of
+ * situations in 2).
+ * 4) A setting range starts after the start LBA of an already set bad blocks
+ * range.
+ * 4.1) If the setting range S exactly matches the tail part of already set bad
+ * blocks range E, like the following chart shows,
+ * +---------+
+ * | S |
+ * +---------+
+ * +-------------+
+ * | E |
+ * +-------------+
+ * 4.1.1) If range S and E have same acknowledge value (both acked or unacked),
+ * they will be merged into one, the result is,
+ * +-------------+
+ * | S |
+ * +-------------+
+ * 4.1.2) If range E is acked and the setting range S is unacked, the setting
+ * request of S will be rejected, the result is,
+ * +-------------+
+ * | E |
+ * +-------------+
+ * 4.1.3) If range E is unacked, and the setting range S is acked, then S may
+ * overwrite the overlapped range of E, the result is,
+ * +---+---------+
+ * | E | S |
+ * +---+---------+
+ * 4.2) If the setting range S stays in middle of an already set range E, like
+ * the following chart shows,
+ * +----+
+ * | S |
+ * +----+
+ * +--------------+
+ * | E |
+ * +--------------+
+ * 4.2.1) If range S and E have same acknowledge value (both acked or unacked),
+ * they will be merged into one, the result is,
+ * +--------------+
+ * | S |
+ * +--------------+
+ * 4.2.2) If range E is acked and the setting range S is unacked, the setting
+ * request of S will be rejected, the result is also,
+ * +--------------+
+ * | E |
+ * +--------------+
+ * 4.2.3) If range E is unacked, and the setting range S is acked, then S will
+ * inserted into middle of E and split previous range E into two parts (E1
+ * and E2), the result is,
+ * +----+----+----+
+ * | E1 | S | E2 |
+ * +----+----+----+
+ * 4.3) If the setting bad blocks range S is overlapped with an already set bad
+ * blocks range E. The range S starts after the start LBA of range E, and
+ * ends after the end LBA of range E, as the following chart shows,
+ * +-------------------+
+ * | S |
+ * +-------------------+
+ * +-------------+
+ * | E |
+ * +-------------+
+ * For this situation the range S can be divided into two parts, the first
+ * part (S1) ends at end range E, and the second part (S2) has rest range of
+ * origin S.
+ * +---------+---------+ +---------+ +---------+
+ * | S1 | S2 | | S1 | | S2 |
+ * +---------+---------+ ===> +---------+ +---------+
+ * +-------------+ +-------------+
+ * | E | | E |
+ * +-------------+ +-------------+
+ * Now in this loop the setting range S1 and already set range E can be
+ * handled as the situations 4.1), the rest range S2 will be handled in next
+ * loop and ignored in this loop.
+ * 5) A setting bad blocks range S is adjacent to one or more already set bad
+ * blocks range(s), and they are all acked or unacked range.
+ * 5.1) Front merge: If the already set bad blocks range E is before setting
+ * range S and they are adjacent,
+ * +------+
+ * | S |
+ * +------+
+ * +-------+
+ * | E |
+ * +-------+
+ * 5.1.1) When total size of range S and E <= BB_MAX_LEN, and their acknowledge
+ * values are same, the setting range S can front merges into range E. The
+ * result is,
+ * +--------------+
+ * | S |
+ * +--------------+
+ * 5.1.2) Otherwise these two ranges cannot merge, just insert the setting
+ * range S right after already set range E into the bad blocks table. The
+ * result is,
+ * +--------+------+
+ * | E | S |
+ * +--------+------+
+ * 6) Special cases which above conditions cannot handle
+ * 6.1) Multiple already set ranges may merge into less ones in a full bad table
+ * +-------------------------------------------------------+
+ * | S |
+ * +-------------------------------------------------------+
+ * |<----- BB_MAX_LEN ----->|
+ * +-----+ +-----+ +-----+
+ * | E1 | | E2 | | E3 |
+ * +-----+ +-----+ +-----+
+ * In the above example, when the bad blocks table is full, inserting the
+ * first part of setting range S will fail because no more available slot
+ * can be allocated from bad blocks table. In this situation a proper
+ * setting method should be go though all the setting bad blocks range and
+ * look for chance to merge already set ranges into less ones. When there
+ * is available slot from bad blocks table, re-try again to handle more
+ * setting bad blocks ranges as many as possible.
+ * +------------------------+
+ * | S3 |
+ * +------------------------+
+ * |<----- BB_MAX_LEN ----->|
+ * +-----+-----+-----+---+-----+--+
+ * | S1 | S2 |
+ * +-----+-----+-----+---+-----+--+
+ * The above chart shows although the first part (S3) cannot be inserted due
+ * to no-space in bad blocks table, but the following E1, E2 and E3 ranges
+ * can be merged with rest part of S into less range S1 and S2. Now there is
+ * 1 free slot in bad blocks table.
+ * +------------------------+-----+-----+-----+---+-----+--+
+ * | S3 | S1 | S2 |
+ * +------------------------+-----+-----+-----+---+-----+--+
+ * Since the bad blocks table is not full anymore, re-try again for the
+ * origin setting range S. Now the setting range S3 can be inserted into the
+ * bad blocks table with previous freed slot from multiple ranges merge.
+ * 6.2) Front merge after overwrite
+ * In the following example, in bad blocks table, E1 is an acked bad blocks
+ * range and E2 is an unacked bad blocks range, therefore they are not able
+ * to merge into a larger range. The setting bad blocks range S is acked,
+ * therefore part of E2 can be overwritten by S.
+ * +--------+
+ * | S | acknowledged
+ * +--------+ S: 1
+ * +-------+-------------+ E1: 1
+ * | E1 | E2 | E2: 0
+ * +-------+-------------+
+ * With previous simplified routines, after overwriting part of E2 with S,
+ * the bad blocks table should be (E3 is remaining part of E2 which is not
+ * overwritten by S),
+ * acknowledged
+ * +-------+--------+----+ S: 1
+ * | E1 | S | E3 | E1: 1
+ * +-------+--------+----+ E3: 0
+ * The above result is correct but not perfect. Range E1 and S in the bad
+ * blocks table are all acked, merging them into a larger one range may
+ * occupy less bad blocks table space and make badblocks_check() faster.
+ * Therefore in such situation, after overwriting range S, the previous range
+ * E1 should be checked for possible front combination. Then the ideal
+ * result can be,
+ * +----------------+----+ acknowledged
+ * | E1 | E3 | E1: 1
+ * +----------------+----+ E3: 0
+ * 6.3) Behind merge: If the already set bad blocks range E is behind the setting
+ * range S and they are adjacent. Normally we don't need to care about this
+ * because front merge handles this while going though range S from head to
+ * tail, except for the tail part of range S. When the setting range S are
+ * fully handled, all the above simplified routine doesn't check whether the
+ * tail LBA of range S is adjacent to the next already set range and not
+ * merge them even it is possible.
+ * +------+
+ * | S |
+ * +------+
+ * +-------+
+ * | E |
+ * +-------+
+ * For the above special situation, when the setting range S are all handled
+ * and the loop ends, an extra check is necessary for whether next already
+ * set range E is right after S and mergeable.
+ * 6.3.1) When total size of range E and S <= BB_MAX_LEN, and their acknowledge
+ * values are same, the setting range S can behind merges into range E. The
+ * result is,
+ * +--------------+
+ * | S |
+ * +--------------+
+ * 6.3.2) Otherwise these two ranges cannot merge, just insert the setting range
+ * S in front of the already set range E in the bad blocks table. The result
+ * is,
+ * +------+-------+
+ * | S | E |
+ * +------+-------+
+ *
+ * All the above 5 simplified situations and 3 special cases may cover 99%+ of
+ * the bad block range setting conditions. Maybe there is some rare corner case
+ * is not considered and optimized, it won't hurt if badblocks_set() fails due
+ * to no space, or some ranges are not merged to save bad blocks table space.
+ *
+ * Inside badblocks_set() each loop starts by jumping to re_insert label, every
+ * time for the new loop prev_badblocks() is called to find an already set range
+ * which starts before or at current setting range. Since the setting bad blocks
+ * range is handled from head to tail, most of the cases it is unnecessary to do
+ * the binary search inside prev_badblocks(), it is possible to provide a hint
+ * to prev_badblocks() for a fast path, then the expensive binary search can be
+ * avoided. In my test with the hint to prev_badblocks(), except for the first
+ * loop, all rested calls to prev_badblocks() can go into the fast path and
+ * return correct bad blocks table index immediately.
+ *
+ *
+ * Clearing a bad blocks range from the bad block table has similar idea as
+ * setting does, but much more simpler. The only thing needs to be noticed is
+ * when the clearing range hits middle of a bad block range, the existing bad
+ * block range will split into two, and one more item should be added into the
+ * bad block table. The simplified situations to be considered are, (The already
+ * set bad blocks ranges in bad block table are naming with prefix E, and the
+ * clearing bad blocks range is naming with prefix C)
+ *
+ * 1) A clearing range is not overlapped to any already set ranges in bad block
+ * table.
+ * +-----+ | +-----+ | +-----+
+ * | C | | | C | | | C |
+ * +-----+ or +-----+ or +-----+
+ * +---+ | +----+ +----+ | +---+
+ * | E | | | E1 | | E2 | | | E |
+ * +---+ | +----+ +----+ | +---+
+ * For the above situations, no bad block to be cleared and no failure
+ * happens, simply returns 0.
+ * 2) The clearing range hits middle of an already setting bad blocks range in
+ * the bad block table.
+ * +---+
+ * | C |
+ * +---+
+ * +-----------------+
+ * | E |
+ * +-----------------+
+ * In this situation if the bad block table is not full, the range E will be
+ * split into two ranges E1 and E2. The result is,
+ * +------+ +------+
+ * | E1 | | E2 |
+ * +------+ +------+
+ * 3) The clearing range starts exactly at same LBA as an already set bad block range
+ * from the bad block table.
+ * 3.1) Partially covered at head part
+ * +------------+
+ * | C |
+ * +------------+
+ * +-----------------+
+ * | E |
+ * +-----------------+
+ * For this situation, the overlapped already set range will update the
+ * start LBA to end of C and shrink the range to BB_LEN(E) - BB_LEN(C). No
+ * item deleted from bad block table. The result is,
+ * +----+
+ * | E1 |
+ * +----+
+ * 3.2) Exact fully covered
+ * +-----------------+
+ * | C |
+ * +-----------------+
+ * +-----------------+
+ * | E |
+ * +-----------------+
+ * For this situation the whole bad blocks range E will be cleared and its
+ * corresponded item is deleted from the bad block table.
+ * 4) The clearing range exactly ends at same LBA as an already set bad block
+ * range.
+ * +-------+
+ * | C |
+ * +-------+
+ * +-----------------+
+ * | E |
+ * +-----------------+
+ * For the above situation, the already set range E is updated to shrink its
+ * end to the start of C, and reduce its length to BB_LEN(E) - BB_LEN(C).
+ * The result is,
+ * +---------+
+ * | E |
+ * +---------+
+ * 5) The clearing range is partially overlapped with an already set bad block
+ * range from the bad block table.
+ * 5.1) The already set bad block range is front overlapped with the clearing
+ * range.
+ * +----------+
+ * | C |
+ * +----------+
+ * +------------+
+ * | E |
+ * +------------+
+ * For such situation, the clearing range C can be treated as two parts. The
+ * first part ends at the start LBA of range E, and the second part starts at
+ * same LBA of range E.
+ * +----+-----+ +----+ +-----+
+ * | C1 | C2 | | C1 | | C2 |
+ * +----+-----+ ===> +----+ +-----+
+ * +------------+ +------------+
+ * | E | | E |
+ * +------------+ +------------+
+ * Now the first part C1 can be handled as condition 1), and the second part C2 can be
+ * handled as condition 3.1) in next loop.
+ * 5.2) The already set bad block range is behind overlaopped with the clearing
+ * range.
+ * +----------+
+ * | C |
+ * +----------+
+ * +------------+
+ * | E |
+ * +------------+
+ * For such situation, the clearing range C can be treated as two parts. The
+ * first part C1 ends at same end LBA of range E, and the second part starts
+ * at end LBA of range E.
+ * +----+-----+ +----+ +-----+
+ * | C1 | C2 | | C1 | | C2 |
+ * +----+-----+ ===> +----+ +-----+
+ * +------------+ +------------+
+ * | E | | E |
+ * +------------+ +------------+
+ * Now the first part clearing range C1 can be handled as condition 4), and
+ * the second part clearing range C2 can be handled as condition 1) in next
+ * loop.
+ *
+ * All bad blocks range clearing can be simplified into the above 5 situations
+ * by only handling the head part of the clearing range in each run of the
+ * while-loop. The idea is similar to bad blocks range setting but much
+ * simpler.
*/
-int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
- sector_t *first_bad, int *bad_sectors)
+
+/*
+ * Find the range starts at-or-before 's' from bad table. The search
+ * starts from index 'hint' and stops at index 'hint_end' from the bad
+ * table.
+ */
+static int prev_by_hint(struct badblocks *bb, sector_t s, int hint)
{
- int hi;
- int lo;
+ int hint_end = hint + 2;
u64 *p = bb->page;
- int rv;
- sector_t target = s + sectors;
- unsigned seq;
+ int ret = -1;
- if (bb->shift > 0) {
- /* round the start down, and the end up */
- s >>= bb->shift;
- target += (1<<bb->shift) - 1;
- target >>= bb->shift;
+ while ((hint < hint_end) && ((hint + 1) <= bb->count) &&
+ (BB_OFFSET(p[hint]) <= s)) {
+ if ((hint + 1) == bb->count || BB_OFFSET(p[hint + 1]) > s) {
+ ret = hint;
+ break;
+ }
+ hint++;
+ }
+
+ return ret;
+}
+
+/*
+ * Find the range starts at-or-before bad->start. If 'hint' is provided
+ * (hint >= 0) then search in the bad table from hint firstly. It is
+ * very probably the wanted bad range can be found from the hint index,
+ * then the unnecessary while-loop iteration can be avoided.
+ */
+static int prev_badblocks(struct badblocks *bb, struct badblocks_context *bad,
+ int hint)
+{
+ sector_t s = bad->start;
+ int ret = -1;
+ int lo, hi;
+ u64 *p;
+
+ if (!bb->count)
+ goto out;
+
+ if (hint >= 0) {
+ ret = prev_by_hint(bb, s, hint);
+ if (ret >= 0)
+ goto out;
}
- /* 'target' is now the first block after the bad range */
-retry:
- seq = read_seqbegin(&bb->lock);
lo = 0;
- rv = 0;
hi = bb->count;
+ p = bb->page;
- /* Binary search between lo and hi for 'target'
- * i.e. for the last range that starts before 'target'
- */
- /* INVARIANT: ranges before 'lo' and at-or-after 'hi'
- * are known not to be the last range before target.
- * VARIANT: hi-lo is the number of possible
- * ranges, and decreases until it reaches 1
- */
+ /* The following bisect search might be unnecessary */
+ if (BB_OFFSET(p[lo]) > s)
+ return -1;
+ if (BB_OFFSET(p[hi - 1]) <= s)
+ return hi - 1;
+
+ /* Do bisect search in bad table */
while (hi - lo > 1) {
- int mid = (lo + hi) / 2;
+ int mid = (lo + hi)/2;
sector_t a = BB_OFFSET(p[mid]);
- if (a < target)
- /* This could still be the one, earlier ranges
- * could not.
- */
+ if (a == s) {
+ ret = mid;
+ goto out;
+ }
+
+ if (a < s)
lo = mid;
else
- /* This and later ranges are definitely out. */
hi = mid;
}
- /* 'lo' might be the last that started before target, but 'hi' isn't */
- if (hi > lo) {
- /* need to check all range that end after 's' to see if
- * any are unacknowledged.
+
+ if (BB_OFFSET(p[lo]) <= s)
+ ret = lo;
+out:
+ return ret;
+}
+
+/*
+ * Return 'true' if the range indicated by 'bad' can be backward merged
+ * with the bad range (from the bad table) index by 'behind'.
+ */
+static bool can_merge_behind(struct badblocks *bb,
+ struct badblocks_context *bad, int behind)
+{
+ sector_t sectors = bad->len;
+ sector_t s = bad->start;
+ u64 *p = bb->page;
+
+ if ((s < BB_OFFSET(p[behind])) &&
+ ((s + sectors) >= BB_OFFSET(p[behind])) &&
+ ((BB_END(p[behind]) - s) <= BB_MAX_LEN) &&
+ BB_ACK(p[behind]) == bad->ack)
+ return true;
+ return false;
+}
+
+/*
+ * Do backward merge for range indicated by 'bad' and the bad range
+ * (from the bad table) indexed by 'behind'. The return value is merged
+ * sectors from bad->len.
+ */
+static int behind_merge(struct badblocks *bb, struct badblocks_context *bad,
+ int behind)
+{
+ sector_t sectors = bad->len;
+ sector_t s = bad->start;
+ u64 *p = bb->page;
+ int merged = 0;
+
+ WARN_ON(s >= BB_OFFSET(p[behind]));
+ WARN_ON((s + sectors) < BB_OFFSET(p[behind]));
+
+ if (s < BB_OFFSET(p[behind])) {
+ merged = BB_OFFSET(p[behind]) - s;
+ p[behind] = BB_MAKE(s, BB_LEN(p[behind]) + merged, bad->ack);
+
+ WARN_ON((BB_LEN(p[behind]) + merged) >= BB_MAX_LEN);
+ }
+
+ return merged;
+}
+
+/*
+ * Return 'true' if the range indicated by 'bad' can be forward
+ * merged with the bad range (from the bad table) indexed by 'prev'.
+ */
+static bool can_merge_front(struct badblocks *bb, int prev,
+ struct badblocks_context *bad)
+{
+ sector_t s = bad->start;
+ u64 *p = bb->page;
+
+ if (BB_ACK(p[prev]) == bad->ack &&
+ (s < BB_END(p[prev]) ||
+ (s == BB_END(p[prev]) && (BB_LEN(p[prev]) < BB_MAX_LEN))))
+ return true;
+ return false;
+}
+
+/*
+ * Do forward merge for range indicated by 'bad' and the bad range
+ * (from bad table) indexed by 'prev'. The return value is sectors
+ * merged from bad->len.
+ */
+static int front_merge(struct badblocks *bb, int prev, struct badblocks_context *bad)
+{
+ sector_t sectors = bad->len;
+ sector_t s = bad->start;
+ u64 *p = bb->page;
+ int merged = 0;
+
+ WARN_ON(s > BB_END(p[prev]));
+
+ if (s < BB_END(p[prev])) {
+ merged = min_t(sector_t, sectors, BB_END(p[prev]) - s);
+ } else {
+ merged = min_t(sector_t, sectors, BB_MAX_LEN - BB_LEN(p[prev]));
+ if ((prev + 1) < bb->count &&
+ merged > (BB_OFFSET(p[prev + 1]) - BB_END(p[prev]))) {
+ merged = BB_OFFSET(p[prev + 1]) - BB_END(p[prev]);
+ }
+
+ p[prev] = BB_MAKE(BB_OFFSET(p[prev]),
+ BB_LEN(p[prev]) + merged, bad->ack);
+ }
+
+ return merged;
+}
+
+/*
+ * 'Combine' is a special case which can_merge_front() is not able to
+ * handle: If a bad range (indexed by 'prev' from bad table) exactly
+ * starts as bad->start, and the bad range ahead of 'prev' (indexed by
+ * 'prev - 1' from bad table) exactly ends at where 'prev' starts, and
+ * the sum of their lengths does not exceed BB_MAX_LEN limitation, then
+ * these two bad range (from bad table) can be combined.
+ *
+ * Return 'true' if bad ranges indexed by 'prev' and 'prev - 1' from bad
+ * table can be combined.
+ */
+static bool can_combine_front(struct badblocks *bb, int prev,
+ struct badblocks_context *bad)
+{
+ u64 *p = bb->page;
+
+ if ((prev > 0) &&
+ (BB_OFFSET(p[prev]) == bad->start) &&
+ (BB_END(p[prev - 1]) == BB_OFFSET(p[prev])) &&
+ (BB_LEN(p[prev - 1]) + BB_LEN(p[prev]) <= BB_MAX_LEN) &&
+ (BB_ACK(p[prev - 1]) == BB_ACK(p[prev])))
+ return true;
+ return false;
+}
+
+/*
+ * Combine the bad ranges indexed by 'prev' and 'prev - 1' (from bad
+ * table) into one larger bad range, and the new range is indexed by
+ * 'prev - 1'.
+ * The caller of front_combine() will decrease bb->count, therefore
+ * it is unnecessary to clear p[perv] after front merge.
+ */
+static void front_combine(struct badblocks *bb, int prev)
+{
+ u64 *p = bb->page;
+
+ p[prev - 1] = BB_MAKE(BB_OFFSET(p[prev - 1]),
+ BB_LEN(p[prev - 1]) + BB_LEN(p[prev]),
+ BB_ACK(p[prev]));
+ if ((prev + 1) < bb->count)
+ memmove(p + prev, p + prev + 1, (bb->count - prev - 1) * 8);
+}
+
+/*
+ * Return 'true' if the range indicated by 'bad' is exactly forward
+ * overlapped with the bad range (from bad table) indexed by 'front'.
+ * Exactly forward overlap means the bad range (from bad table) indexed
+ * by 'prev' does not cover the whole range indicated by 'bad'.
+ */
+static bool overlap_front(struct badblocks *bb, int front,
+ struct badblocks_context *bad)
+{
+ u64 *p = bb->page;
+
+ if (bad->start >= BB_OFFSET(p[front]) &&
+ bad->start < BB_END(p[front]))
+ return true;
+ return false;
+}
+
+/*
+ * Return 'true' if the range indicated by 'bad' is exactly backward
+ * overlapped with the bad range (from bad table) indexed by 'behind'.
+ */
+static bool overlap_behind(struct badblocks *bb, struct badblocks_context *bad,
+ int behind)
+{
+ u64 *p = bb->page;
+
+ if (bad->start < BB_OFFSET(p[behind]) &&
+ (bad->start + bad->len) > BB_OFFSET(p[behind]))
+ return true;
+ return false;
+}
+
+/*
+ * Return 'true' if the range indicated by 'bad' can overwrite the bad
+ * range (from bad table) indexed by 'prev'.
+ *
+ * The range indicated by 'bad' can overwrite the bad range indexed by
+ * 'prev' when,
+ * 1) The whole range indicated by 'bad' can cover partial or whole bad
+ * range (from bad table) indexed by 'prev'.
+ * 2) The ack value of 'bad' is larger or equal to the ack value of bad
+ * range 'prev'.
+ *
+ * If the overwriting doesn't cover the whole bad range (from bad table)
+ * indexed by 'prev', new range might be split from existing bad range,
+ * 1) The overwrite covers head or tail part of existing bad range, 1
+ * extra bad range will be split and added into the bad table.
+ * 2) The overwrite covers middle of existing bad range, 2 extra bad
+ * ranges will be split (ahead and after the overwritten range) and
+ * added into the bad table.
+ * The number of extra split ranges of the overwriting is stored in
+ * 'extra' and returned for the caller.
+ */
+static bool can_front_overwrite(struct badblocks *bb, int prev,
+ struct badblocks_context *bad, int *extra)
+{
+ u64 *p = bb->page;
+ int len;
+
+ WARN_ON(!overlap_front(bb, prev, bad));
+
+ if (BB_ACK(p[prev]) >= bad->ack)
+ return false;
+
+ if (BB_END(p[prev]) <= (bad->start + bad->len)) {
+ len = BB_END(p[prev]) - bad->start;
+ if (BB_OFFSET(p[prev]) == bad->start)
+ *extra = 0;
+ else
+ *extra = 1;
+
+ bad->len = len;
+ } else {
+ if (BB_OFFSET(p[prev]) == bad->start)
+ *extra = 1;
+ else
+ /*
+ * prev range will be split into two, beside the overwritten
+ * one, an extra slot needed from bad table.
*/
- while (lo >= 0 &&
- BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > s) {
- if (BB_OFFSET(p[lo]) < target) {
- /* starts before the end, and finishes after
- * the start, so they must overlap
- */
- if (rv != -1 && BB_ACK(p[lo]))
- rv = 1;
- else
- rv = -1;
- *first_bad = BB_OFFSET(p[lo]);
- *bad_sectors = BB_LEN(p[lo]);
- }
- lo--;
+ *extra = 2;
+ }
+
+ if ((bb->count + (*extra)) >= MAX_BADBLOCKS)
+ return false;
+
+ return true;
+}
+
+/*
+ * Do the overwrite from the range indicated by 'bad' to the bad range
+ * (from bad table) indexed by 'prev'.
+ * The previously called can_front_overwrite() will provide how many
+ * extra bad range(s) might be split and added into the bad table. All
+ * the splitting cases in the bad table will be handled here.
+ */
+static int front_overwrite(struct badblocks *bb, int prev,
+ struct badblocks_context *bad, int extra)
+{
+ u64 *p = bb->page;
+ sector_t orig_end = BB_END(p[prev]);
+ int orig_ack = BB_ACK(p[prev]);
+
+ switch (extra) {
+ case 0:
+ p[prev] = BB_MAKE(BB_OFFSET(p[prev]), BB_LEN(p[prev]),
+ bad->ack);
+ break;
+ case 1:
+ if (BB_OFFSET(p[prev]) == bad->start) {
+ p[prev] = BB_MAKE(BB_OFFSET(p[prev]),
+ bad->len, bad->ack);
+ memmove(p + prev + 2, p + prev + 1,
+ (bb->count - prev - 1) * 8);
+ p[prev + 1] = BB_MAKE(bad->start + bad->len,
+ orig_end - BB_END(p[prev]),
+ orig_ack);
+ } else {
+ p[prev] = BB_MAKE(BB_OFFSET(p[prev]),
+ bad->start - BB_OFFSET(p[prev]),
+ orig_ack);
+ /*
+ * prev +2 -> prev + 1 + 1, which is for,
+ * 1) prev + 1: the slot index of the previous one
+ * 2) + 1: one more slot for extra being 1.
+ */
+ memmove(p + prev + 2, p + prev + 1,
+ (bb->count - prev - 1) * 8);
+ p[prev + 1] = BB_MAKE(bad->start, bad->len, bad->ack);
}
+ break;
+ case 2:
+ p[prev] = BB_MAKE(BB_OFFSET(p[prev]),
+ bad->start - BB_OFFSET(p[prev]),
+ orig_ack);
+ /*
+ * prev + 3 -> prev + 1 + 2, which is for,
+ * 1) prev + 1: the slot index of the previous one
+ * 2) + 2: two more slots for extra being 2.
+ */
+ memmove(p + prev + 3, p + prev + 1,
+ (bb->count - prev - 1) * 8);
+ p[prev + 1] = BB_MAKE(bad->start, bad->len, bad->ack);
+ p[prev + 2] = BB_MAKE(BB_END(p[prev + 1]),
+ orig_end - BB_END(p[prev + 1]),
+ orig_ack);
+ break;
+ default:
+ break;
}
- if (read_seqretry(&bb->lock, seq))
- goto retry;
+ return bad->len;
+}
- return rv;
+/*
+ * Explicitly insert a range indicated by 'bad' to the bad table, where
+ * the location is indexed by 'at'.
+ */
+static int insert_at(struct badblocks *bb, int at, struct badblocks_context *bad)
+{
+ u64 *p = bb->page;
+ int len;
+
+ WARN_ON(badblocks_full(bb));
+
+ len = min_t(sector_t, bad->len, BB_MAX_LEN);
+ if (at < bb->count)
+ memmove(p + at + 1, p + at, (bb->count - at) * 8);
+ p[at] = BB_MAKE(bad->start, len, bad->ack);
+
+ return len;
}
-EXPORT_SYMBOL_GPL(badblocks_check);
static void badblocks_update_acked(struct badblocks *bb)
{
+ bool unacked = false;
u64 *p = bb->page;
int i;
- bool unacked = false;
if (!bb->unacked_exist)
return;
@@ -144,281 +855,600 @@ static void badblocks_update_acked(struct badblocks *bb)
bb->unacked_exist = 0;
}
-/**
- * badblocks_set() - Add a range of bad blocks to the table.
- * @bb: the badblocks structure that holds all badblock information
- * @s: first sector to mark as bad
- * @sectors: number of sectors to mark as bad
- * @acknowledged: weather to mark the bad sectors as acknowledged
- *
- * This might extend the table, or might contract it if two adjacent ranges
- * can be merged. We binary-search to find the 'insertion' point, then
- * decide how best to handle it.
- *
- * Return:
- * 0: success
- * 1: failed to set badblocks (out of space)
- */
-int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
- int acknowledged)
+/* Do exact work to set bad block range into the bad block table */
+static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+ int acknowledged)
{
- u64 *p;
- int lo, hi;
- int rv = 0;
+ int retried = 0, space_desired = 0;
+ int orig_len, len = 0, added = 0;
+ struct badblocks_context bad;
+ int prev = -1, hint = -1;
+ sector_t orig_start;
unsigned long flags;
+ int rv = 0;
+ u64 *p;
if (bb->shift < 0)
/* badblocks are disabled */
return 1;
+ if (sectors == 0)
+ /* Invalid sectors number */
+ return 1;
+
if (bb->shift) {
/* round the start down, and the end up */
sector_t next = s + sectors;
- s >>= bb->shift;
- next += (1<<bb->shift) - 1;
- next >>= bb->shift;
+ rounddown(s, bb->shift);
+ roundup(next, bb->shift);
sectors = next - s;
}
write_seqlock_irqsave(&bb->lock, flags);
+ orig_start = s;
+ orig_len = sectors;
+ bad.ack = acknowledged;
p = bb->page;
- lo = 0;
- hi = bb->count;
- /* Find the last range that starts at-or-before 's' */
- while (hi - lo > 1) {
- int mid = (lo + hi) / 2;
- sector_t a = BB_OFFSET(p[mid]);
- if (a <= s)
- lo = mid;
- else
- hi = mid;
+re_insert:
+ bad.start = s;
+ bad.len = sectors;
+ len = 0;
+
+ if (badblocks_empty(bb)) {
+ len = insert_at(bb, 0, &bad);
+ bb->count++;
+ added++;
+ goto update_sectors;
}
- if (hi > lo && BB_OFFSET(p[lo]) > s)
- hi = lo;
- if (hi > lo) {
- /* we found a range that might merge with the start
- * of our new range
- */
- sector_t a = BB_OFFSET(p[lo]);
- sector_t e = a + BB_LEN(p[lo]);
- int ack = BB_ACK(p[lo]);
-
- if (e >= s) {
- /* Yes, we can merge with a previous range */
- if (s == a && s + sectors >= e)
- /* new range covers old */
- ack = acknowledged;
- else
- ack = ack && acknowledged;
-
- if (e < s + sectors)
- e = s + sectors;
- if (e - a <= BB_MAX_LEN) {
- p[lo] = BB_MAKE(a, e-a, ack);
- s = e;
+ prev = prev_badblocks(bb, &bad, hint);
+
+ /* start before all badblocks */
+ if (prev < 0) {
+ if (!badblocks_full(bb)) {
+ /* insert on the first */
+ if (bad.len > (BB_OFFSET(p[0]) - bad.start))
+ bad.len = BB_OFFSET(p[0]) - bad.start;
+ len = insert_at(bb, 0, &bad);
+ bb->count++;
+ added++;
+ hint = 0;
+ goto update_sectors;
+ }
+
+ /* No sapce, try to merge */
+ if (overlap_behind(bb, &bad, 0)) {
+ if (can_merge_behind(bb, &bad, 0)) {
+ len = behind_merge(bb, &bad, 0);
+ added++;
} else {
- /* does not all fit in one range,
- * make p[lo] maximal
- */
- if (BB_LEN(p[lo]) != BB_MAX_LEN)
- p[lo] = BB_MAKE(a, BB_MAX_LEN, ack);
- s = a + BB_MAX_LEN;
+ len = BB_OFFSET(p[0]) - s;
+ space_desired = 1;
}
- sectors = e - s;
+ hint = 0;
+ goto update_sectors;
}
+
+ /* no table space and give up */
+ goto out;
}
- if (sectors && hi < bb->count) {
- /* 'hi' points to the first range that starts after 's'.
- * Maybe we can merge with the start of that range
- */
- sector_t a = BB_OFFSET(p[hi]);
- sector_t e = a + BB_LEN(p[hi]);
- int ack = BB_ACK(p[hi]);
-
- if (a <= s + sectors) {
- /* merging is possible */
- if (e <= s + sectors) {
- /* full overlap */
- e = s + sectors;
- ack = acknowledged;
- } else
- ack = ack && acknowledged;
-
- a = s;
- if (e - a <= BB_MAX_LEN) {
- p[hi] = BB_MAKE(a, e-a, ack);
- s = e;
- } else {
- p[hi] = BB_MAKE(a, BB_MAX_LEN, ack);
- s = a + BB_MAX_LEN;
+
+ /* in case p[prev-1] can be merged with p[prev] */
+ if (can_combine_front(bb, prev, &bad)) {
+ front_combine(bb, prev);
+ bb->count--;
+ added++;
+ hint = prev;
+ goto update_sectors;
+ }
+
+ if (overlap_front(bb, prev, &bad)) {
+ if (can_merge_front(bb, prev, &bad)) {
+ len = front_merge(bb, prev, &bad);
+ added++;
+ } else {
+ int extra = 0;
+
+ if (!can_front_overwrite(bb, prev, &bad, &extra)) {
+ len = min_t(sector_t,
+ BB_END(p[prev]) - s, sectors);
+ hint = prev;
+ goto update_sectors;
+ }
+
+ len = front_overwrite(bb, prev, &bad, extra);
+ added++;
+ bb->count += extra;
+
+ if (can_combine_front(bb, prev, &bad)) {
+ front_combine(bb, prev);
+ bb->count--;
}
- sectors = e - s;
- lo = hi;
- hi++;
}
+ hint = prev;
+ goto update_sectors;
+ }
+
+ if (can_merge_front(bb, prev, &bad)) {
+ len = front_merge(bb, prev, &bad);
+ added++;
+ hint = prev;
+ goto update_sectors;
}
- if (sectors == 0 && hi < bb->count) {
- /* we might be able to combine lo and hi */
- /* Note: 's' is at the end of 'lo' */
- sector_t a = BB_OFFSET(p[hi]);
- int lolen = BB_LEN(p[lo]);
- int hilen = BB_LEN(p[hi]);
- int newlen = lolen + hilen - (s - a);
-
- if (s >= a && newlen < BB_MAX_LEN) {
- /* yes, we can combine them */
- int ack = BB_ACK(p[lo]) && BB_ACK(p[hi]);
-
- p[lo] = BB_MAKE(BB_OFFSET(p[lo]), newlen, ack);
- memmove(p + hi, p + hi + 1,
- (bb->count - hi - 1) * 8);
- bb->count--;
+
+ /* if no space in table, still try to merge in the covered range */
+ if (badblocks_full(bb)) {
+ /* skip the cannot-merge range */
+ if (((prev + 1) < bb->count) &&
+ overlap_behind(bb, &bad, prev + 1) &&
+ ((s + sectors) >= BB_END(p[prev + 1]))) {
+ len = BB_END(p[prev + 1]) - s;
+ hint = prev + 1;
+ goto update_sectors;
}
+
+ /* no retry any more */
+ len = sectors;
+ space_desired = 1;
+ hint = -1;
+ goto update_sectors;
}
- while (sectors) {
- /* didn't merge (it all).
- * Need to add a range just before 'hi'
- */
- if (bb->count >= MAX_BADBLOCKS) {
- /* No room for more */
- rv = 1;
- break;
- } else {
- int this_sectors = sectors;
- memmove(p + hi + 1, p + hi,
- (bb->count - hi) * 8);
- bb->count++;
+ /* cannot merge and there is space in bad table */
+ if ((prev + 1) < bb->count &&
+ overlap_behind(bb, &bad, prev + 1))
+ bad.len = min_t(sector_t,
+ bad.len, BB_OFFSET(p[prev + 1]) - bad.start);
- if (this_sectors > BB_MAX_LEN)
- this_sectors = BB_MAX_LEN;
- p[hi] = BB_MAKE(s, this_sectors, acknowledged);
- sectors -= this_sectors;
- s += this_sectors;
- }
+ len = insert_at(bb, prev + 1, &bad);
+ bb->count++;
+ added++;
+ hint = prev + 1;
+
+update_sectors:
+ s += len;
+ sectors -= len;
+
+ if (sectors > 0)
+ goto re_insert;
+
+ WARN_ON(sectors < 0);
+
+ /*
+ * Check whether the following already set range can be
+ * merged. (prev < 0) condition is not handled here,
+ * because it's already complicated enough.
+ */
+ if (prev >= 0 &&
+ (prev + 1) < bb->count &&
+ BB_END(p[prev]) == BB_OFFSET(p[prev + 1]) &&
+ (BB_LEN(p[prev]) + BB_LEN(p[prev + 1])) <= BB_MAX_LEN &&
+ BB_ACK(p[prev]) == BB_ACK(p[prev + 1])) {
+ p[prev] = BB_MAKE(BB_OFFSET(p[prev]),
+ BB_LEN(p[prev]) + BB_LEN(p[prev + 1]),
+ BB_ACK(p[prev]));
+
+ if ((prev + 2) < bb->count)
+ memmove(p + prev + 1, p + prev + 2,
+ (bb->count - (prev + 2)) * 8);
+ bb->count--;
+ }
+
+ if (space_desired && !badblocks_full(bb)) {
+ s = orig_start;
+ sectors = orig_len;
+ space_desired = 0;
+ if (retried++ < 3)
+ goto re_insert;
+ }
+
+out:
+ if (added) {
+ set_changed(bb);
+
+ if (!acknowledged)
+ bb->unacked_exist = 1;
+ else
+ badblocks_update_acked(bb);
}
- bb->changed = 1;
- if (!acknowledged)
- bb->unacked_exist = 1;
- else
- badblocks_update_acked(bb);
write_sequnlock_irqrestore(&bb->lock, flags);
+ if (!added)
+ rv = 1;
+
return rv;
}
-EXPORT_SYMBOL_GPL(badblocks_set);
-/**
- * badblocks_clear() - Remove a range of bad blocks to the table.
- * @bb: the badblocks structure that holds all badblock information
- * @s: first sector to mark as bad
- * @sectors: number of sectors to mark as bad
- *
- * This may involve extending the table if we spilt a region,
- * but it must not fail. So if the table becomes full, we just
- * drop the remove request.
- *
- * Return:
- * 0: success
- * 1: failed to clear badblocks
+/*
+ * Clear the bad block range from bad block table which is front overlapped
+ * with the clearing range. The return value is how many sectors from an
+ * already set bad block range are cleared. If the whole bad block range is
+ * covered by the clearing range and fully cleared, 'delete' is set as 1 for
+ * the caller to reduce bb->count.
*/
-int badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+static int front_clear(struct badblocks *bb, int prev,
+ struct badblocks_context *bad, int *deleted)
{
- u64 *p;
- int lo, hi;
- sector_t target = s + sectors;
+ sector_t sectors = bad->len;
+ sector_t s = bad->start;
+ u64 *p = bb->page;
+ int cleared = 0;
+
+ *deleted = 0;
+ if (s == BB_OFFSET(p[prev])) {
+ if (BB_LEN(p[prev]) > sectors) {
+ p[prev] = BB_MAKE(BB_OFFSET(p[prev]) + sectors,
+ BB_LEN(p[prev]) - sectors,
+ BB_ACK(p[prev]));
+ cleared = sectors;
+ } else {
+ /* BB_LEN(p[prev]) <= sectors */
+ cleared = BB_LEN(p[prev]);
+ if ((prev + 1) < bb->count)
+ memmove(p + prev, p + prev + 1,
+ (bb->count - prev - 1) * 8);
+ *deleted = 1;
+ }
+ } else if (s > BB_OFFSET(p[prev])) {
+ if (BB_END(p[prev]) <= (s + sectors)) {
+ cleared = BB_END(p[prev]) - s;
+ p[prev] = BB_MAKE(BB_OFFSET(p[prev]),
+ s - BB_OFFSET(p[prev]),
+ BB_ACK(p[prev]));
+ } else {
+ /* Splitting is handled in front_splitting_clear() */
+ BUG();
+ }
+ }
+
+ return cleared;
+}
+
+/*
+ * Handle the condition that the clearing range hits middle of an already set
+ * bad block range from bad block table. In this condition the existing bad
+ * block range is split into two after the middle part is cleared.
+ */
+static int front_splitting_clear(struct badblocks *bb, int prev,
+ struct badblocks_context *bad)
+{
+ u64 *p = bb->page;
+ u64 end = BB_END(p[prev]);
+ int ack = BB_ACK(p[prev]);
+ sector_t sectors = bad->len;
+ sector_t s = bad->start;
+
+ p[prev] = BB_MAKE(BB_OFFSET(p[prev]),
+ s - BB_OFFSET(p[prev]),
+ ack);
+ memmove(p + prev + 2, p + prev + 1, (bb->count - prev - 1) * 8);
+ p[prev + 1] = BB_MAKE(s + sectors, end - s - sectors, ack);
+ return sectors;
+}
+
+/* Do the exact work to clear bad block range from the bad block table */
+static int _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+{
+ struct badblocks_context bad;
+ int prev = -1, hint = -1;
+ int len = 0, cleared = 0;
int rv = 0;
+ u64 *p;
+
+ if (bb->shift < 0)
+ /* badblocks are disabled */
+ return 1;
+
+ if (sectors == 0)
+ /* Invalid sectors number */
+ return 1;
+
+ if (bb->shift) {
+ sector_t target;
- if (bb->shift > 0) {
/* When clearing we round the start up and the end down.
* This should not matter as the shift should align with
* the block size and no rounding should ever be needed.
* However it is better the think a block is bad when it
* isn't than to think a block is not bad when it is.
*/
- s += (1<<bb->shift) - 1;
- s >>= bb->shift;
- target >>= bb->shift;
+ target = s + sectors;
+ roundup(s, bb->shift);
+ rounddown(target, bb->shift);
+ sectors = target - s;
}
write_seqlock_irq(&bb->lock);
+ bad.ack = true;
p = bb->page;
- lo = 0;
- hi = bb->count;
- /* Find the last range that starts before 'target' */
- while (hi - lo > 1) {
- int mid = (lo + hi) / 2;
- sector_t a = BB_OFFSET(p[mid]);
- if (a < target)
- lo = mid;
- else
- hi = mid;
+re_clear:
+ bad.start = s;
+ bad.len = sectors;
+
+ if (badblocks_empty(bb)) {
+ len = sectors;
+ cleared++;
+ goto update_sectors;
}
- if (hi > lo) {
- /* p[lo] is the last range that could overlap the
- * current range. Earlier ranges could also overlap,
- * but only this one can overlap the end of the range.
- */
- if ((BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > target) &&
- (BB_OFFSET(p[lo]) < target)) {
- /* Partial overlap, leave the tail of this range */
- int ack = BB_ACK(p[lo]);
- sector_t a = BB_OFFSET(p[lo]);
- sector_t end = a + BB_LEN(p[lo]);
-
- if (a < s) {
- /* we need to split this range */
- if (bb->count >= MAX_BADBLOCKS) {
- rv = -ENOSPC;
- goto out;
- }
- memmove(p+lo+1, p+lo, (bb->count - lo) * 8);
- bb->count++;
- p[lo] = BB_MAKE(a, s-a, ack);
- lo++;
- }
- p[lo] = BB_MAKE(target, end - target, ack);
- /* there is no longer an overlap */
- hi = lo;
- lo--;
- }
- while (lo >= 0 &&
- (BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > s) &&
- (BB_OFFSET(p[lo]) < target)) {
- /* This range does overlap */
- if (BB_OFFSET(p[lo]) < s) {
- /* Keep the early parts of this range. */
- int ack = BB_ACK(p[lo]);
- sector_t start = BB_OFFSET(p[lo]);
-
- p[lo] = BB_MAKE(start, s - start, ack);
- /* now low doesn't overlap, so.. */
- break;
- }
- lo--;
+
+
+ prev = prev_badblocks(bb, &bad, hint);
+
+ /* Start before all badblocks */
+ if (prev < 0) {
+ if (overlap_behind(bb, &bad, 0)) {
+ len = BB_OFFSET(p[0]) - s;
+ hint = 0;
+ } else {
+ len = sectors;
}
- /* 'lo' is strictly before, 'hi' is strictly after,
- * anything between needs to be discarded
+ /*
+ * Both situations are to clear non-bad range,
+ * should be treated as successful
*/
- if (hi - lo > 1) {
- memmove(p+lo+1, p+hi, (bb->count - hi) * 8);
- bb->count -= (hi - lo - 1);
+ cleared++;
+ goto update_sectors;
+ }
+
+ /* Start after all badblocks */
+ if ((prev + 1) >= bb->count && !overlap_front(bb, prev, &bad)) {
+ len = sectors;
+ cleared++;
+ goto update_sectors;
+ }
+
+ /* Clear will split a bad record but the table is full */
+ if (badblocks_full(bb) && (BB_OFFSET(p[prev]) < bad.start) &&
+ (BB_END(p[prev]) > (bad.start + sectors))) {
+ len = sectors;
+ goto update_sectors;
+ }
+
+ if (overlap_front(bb, prev, &bad)) {
+ if ((BB_OFFSET(p[prev]) < bad.start) &&
+ (BB_END(p[prev]) > (bad.start + bad.len))) {
+ /* Splitting */
+ if ((bb->count + 1) < MAX_BADBLOCKS) {
+ len = front_splitting_clear(bb, prev, &bad);
+ bb->count += 1;
+ cleared++;
+ } else {
+ /* No space to split, give up */
+ len = sectors;
+ }
+ } else {
+ int deleted = 0;
+
+ len = front_clear(bb, prev, &bad, &deleted);
+ bb->count -= deleted;
+ cleared++;
+ hint = prev;
}
+
+ goto update_sectors;
+ }
+
+ /* Not front overlap, but behind overlap */
+ if ((prev + 1) < bb->count && overlap_behind(bb, &bad, prev + 1)) {
+ len = BB_OFFSET(p[prev + 1]) - bad.start;
+ hint = prev + 1;
+ /* Clear non-bad range should be treated as successful */
+ cleared++;
+ goto update_sectors;
+ }
+
+ /* Not cover any badblocks range in the table */
+ len = sectors;
+ /* Clear non-bad range should be treated as successful */
+ cleared++;
+
+update_sectors:
+ s += len;
+ sectors -= len;
+
+ if (sectors > 0)
+ goto re_clear;
+
+ WARN_ON(sectors < 0);
+
+ if (cleared) {
+ badblocks_update_acked(bb);
+ set_changed(bb);
}
- badblocks_update_acked(bb);
- bb->changed = 1;
-out:
write_sequnlock_irq(&bb->lock);
+
+ if (!cleared)
+ rv = 1;
+
return rv;
}
+
+/* Do the exact work to check bad blocks range from the bad block table */
+static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+ sector_t *first_bad, int *bad_sectors)
+{
+ int unacked_badblocks, acked_badblocks;
+ int prev = -1, hint = -1, set = 0;
+ struct badblocks_context bad;
+ unsigned int seq;
+ int len, rv;
+ u64 *p;
+
+ WARN_ON(bb->shift < 0 || sectors == 0);
+
+ if (bb->shift > 0) {
+ sector_t target;
+
+ /* round the start down, and the end up */
+ target = s + sectors;
+ rounddown(s, bb->shift);
+ roundup(target, bb->shift);
+ sectors = target - s;
+ }
+
+retry:
+ seq = read_seqbegin(&bb->lock);
+
+ p = bb->page;
+ unacked_badblocks = 0;
+ acked_badblocks = 0;
+
+re_check:
+ bad.start = s;
+ bad.len = sectors;
+
+ if (badblocks_empty(bb)) {
+ len = sectors;
+ goto update_sectors;
+ }
+
+ prev = prev_badblocks(bb, &bad, hint);
+
+ /* start after all badblocks */
+ if ((prev + 1) >= bb->count && !overlap_front(bb, prev, &bad)) {
+ len = sectors;
+ goto update_sectors;
+ }
+
+ if (overlap_front(bb, prev, &bad)) {
+ if (BB_ACK(p[prev]))
+ acked_badblocks++;
+ else
+ unacked_badblocks++;
+
+ if (BB_END(p[prev]) >= (s + sectors))
+ len = sectors;
+ else
+ len = BB_END(p[prev]) - s;
+
+ if (set == 0) {
+ *first_bad = BB_OFFSET(p[prev]);
+ *bad_sectors = BB_LEN(p[prev]);
+ set = 1;
+ }
+ goto update_sectors;
+ }
+
+ /* Not front overlap, but behind overlap */
+ if ((prev + 1) < bb->count && overlap_behind(bb, &bad, prev + 1)) {
+ len = BB_OFFSET(p[prev + 1]) - bad.start;
+ hint = prev + 1;
+ goto update_sectors;
+ }
+
+ /* not cover any badblocks range in the table */
+ len = sectors;
+
+update_sectors:
+ s += len;
+ sectors -= len;
+
+ if (sectors > 0)
+ goto re_check;
+
+ WARN_ON(sectors < 0);
+
+ if (unacked_badblocks > 0)
+ rv = -1;
+ else if (acked_badblocks > 0)
+ rv = 1;
+ else
+ rv = 0;
+
+ if (read_seqretry(&bb->lock, seq))
+ goto retry;
+
+ return rv;
+}
+
+/**
+ * badblocks_check() - check a given range for bad sectors
+ * @bb: the badblocks structure that holds all badblock information
+ * @s: sector (start) at which to check for badblocks
+ * @sectors: number of sectors to check for badblocks
+ * @first_bad: pointer to store location of the first badblock
+ * @bad_sectors: pointer to store number of badblocks after @first_bad
+ *
+ * We can record which blocks on each device are 'bad' and so just
+ * fail those blocks, or that stripe, rather than the whole device.
+ * Entries in the bad-block table are 64bits wide. This comprises:
+ * Length of bad-range, in sectors: 0-511 for lengths 1-512
+ * Start of bad-range, sector offset, 54 bits (allows 8 exbibytes)
+ * A 'shift' can be set so that larger blocks are tracked and
+ * consequently larger devices can be covered.
+ * 'Acknowledged' flag - 1 bit. - the most significant bit.
+ *
+ * Locking of the bad-block table uses a seqlock so badblocks_check
+ * might need to retry if it is very unlucky.
+ * We will sometimes want to check for bad blocks in a bi_end_io function,
+ * so we use the write_seqlock_irq variant.
+ *
+ * When looking for a bad block we specify a range and want to
+ * know if any block in the range is bad. So we binary-search
+ * to the last range that starts at-or-before the given endpoint,
+ * (or "before the sector after the target range")
+ * then see if it ends after the given start.
+ *
+ * Return:
+ * 0: there are no known bad blocks in the range
+ * 1: there are known bad block which are all acknowledged
+ * -1: there are bad blocks which have not yet been acknowledged in metadata.
+ * plus the start/length of the first bad section we overlap.
+ */
+int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+ sector_t *first_bad, int *bad_sectors)
+{
+ return _badblocks_check(bb, s, sectors, first_bad, bad_sectors);
+}
+EXPORT_SYMBOL_GPL(badblocks_check);
+
+/**
+ * badblocks_set() - Add a range of bad blocks to the table.
+ * @bb: the badblocks structure that holds all badblock information
+ * @s: first sector to mark as bad
+ * @sectors: number of sectors to mark as bad
+ * @acknowledged: weather to mark the bad sectors as acknowledged
+ *
+ * This might extend the table, or might contract it if two adjacent ranges
+ * can be merged. We binary-search to find the 'insertion' point, then
+ * decide how best to handle it.
+ *
+ * Return:
+ * 0: success
+ * 1: failed to set badblocks (out of space)
+ */
+int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+ int acknowledged)
+{
+ return _badblocks_set(bb, s, sectors, acknowledged);
+}
+EXPORT_SYMBOL_GPL(badblocks_set);
+
+/**
+ * badblocks_clear() - Remove a range of bad blocks to the table.
+ * @bb: the badblocks structure that holds all badblock information
+ * @s: first sector to mark as bad
+ * @sectors: number of sectors to mark as bad
+ *
+ * This may involve extending the table if we spilt a region,
+ * but it must not fail. So if the table becomes full, we just
+ * drop the remove request.
+ *
+ * Return:
+ * 0: success
+ * 1: failed to clear badblocks
+ */
+int badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+{
+ return _badblocks_clear(bb, s, sectors);
+}
EXPORT_SYMBOL_GPL(badblocks_clear);
/**
diff --git a/block/blk-flush.c b/block/blk-flush.c
index e73dc22d05c1..3f4d41952ef2 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -323,16 +323,9 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
flush_rq->mq_ctx = first_rq->mq_ctx;
flush_rq->mq_hctx = first_rq->mq_hctx;
- if (!q->elevator) {
+ if (!q->elevator)
flush_rq->tag = first_rq->tag;
-
- /*
- * We borrow data request's driver tag, so have to mark
- * this flush request as INFLIGHT for avoiding double
- * account of this driver tag
- */
- flush_rq->rq_flags |= RQF_MQ_INFLIGHT;
- } else
+ else
flush_rq->internal_tag = first_rq->internal_tag;
flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
index c3b5930106b2..5cbeb9344f2f 100644
--- a/block/blk-mq-debugfs.c
+++ b/block/blk-mq-debugfs.c
@@ -246,7 +246,6 @@ static const char *const rqf_name[] = {
RQF_NAME(STARTED),
RQF_NAME(FLUSH_SEQ),
RQF_NAME(MIXED_MERGE),
- RQF_NAME(MQ_INFLIGHT),
RQF_NAME(DONTPREP),
RQF_NAME(SCHED_TAGS),
RQF_NAME(USE_SCHED),
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 1fafd54dce3c..e2d11183f62e 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -426,6 +426,8 @@ __blk_mq_alloc_requests_batch(struct blk_mq_alloc_data *data)
rq_list_add(data->cached_rq, rq);
nr++;
}
+ if (!(data->rq_flags & RQF_SCHED_TAGS))
+ blk_mq_add_active_requests(data->hctx, nr);
/* caller already holds a reference, add for remainder */
percpu_ref_get_many(&data->q->q_usage_counter, nr - 1);
data->nr_tags -= nr;
@@ -510,6 +512,8 @@ retry:
goto retry;
}
+ if (!(data->rq_flags & RQF_SCHED_TAGS))
+ blk_mq_inc_active_requests(data->hctx);
rq = blk_mq_rq_ctx_init(data, blk_mq_tags_from_data(data), tag);
blk_mq_rq_time_init(rq, alloc_time_ns);
return rq;
@@ -669,6 +673,8 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
tag = blk_mq_get_tag(&data);
if (tag == BLK_MQ_NO_TAG)
goto out_queue_exit;
+ if (!(data.rq_flags & RQF_SCHED_TAGS))
+ blk_mq_inc_active_requests(data.hctx);
rq = blk_mq_rq_ctx_init(&data, blk_mq_tags_from_data(&data), tag);
blk_mq_rq_time_init(rq, alloc_time_ns);
rq->__data_len = 0;
@@ -708,11 +714,10 @@ static void __blk_mq_free_request(struct request *rq)
blk_pm_mark_last_busy(rq);
rq->mq_hctx = NULL;
- if (rq->rq_flags & RQF_MQ_INFLIGHT)
- __blk_mq_dec_active_requests(hctx);
-
- if (rq->tag != BLK_MQ_NO_TAG)
+ if (rq->tag != BLK_MQ_NO_TAG) {
+ blk_mq_dec_active_requests(hctx);
blk_mq_put_tag(hctx->tags, ctx, rq->tag);
+ }
if (sched_tag != BLK_MQ_NO_TAG)
blk_mq_put_tag(hctx->sched_tags, ctx, sched_tag);
blk_mq_sched_restart(hctx);
@@ -1061,12 +1066,7 @@ static inline void blk_mq_flush_tag_batch(struct blk_mq_hw_ctx *hctx,
{
struct request_queue *q = hctx->queue;
- /*
- * All requests should have been marked as RQF_MQ_INFLIGHT, so
- * update hctx->nr_active in batch
- */
- if (hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED)
- __blk_mq_sub_active_requests(hctx, nr_tags);
+ blk_mq_sub_active_requests(hctx, nr_tags);
blk_mq_put_tags(hctx->tags, tag_array, nr_tags);
percpu_ref_put_many(&q->q_usage_counter, nr_tags);
@@ -1259,6 +1259,7 @@ void blk_mq_start_request(struct request *rq)
blk_add_timer(rq);
WRITE_ONCE(rq->state, MQ_RQ_IN_FLIGHT);
+ rq->mq_hctx->tags->rqs[rq->tag] = rq;
#ifdef CONFIG_BLK_DEV_INTEGRITY
if (blk_integrity_rq(rq) && req_op(rq) == REQ_OP_WRITE)
@@ -1748,7 +1749,7 @@ struct request *blk_mq_dequeue_from_ctx(struct blk_mq_hw_ctx *hctx,
return data.rq;
}
-static bool __blk_mq_alloc_driver_tag(struct request *rq)
+bool __blk_mq_alloc_driver_tag(struct request *rq)
{
struct sbitmap_queue *bt = &rq->mq_hctx->tags->bitmap_tags;
unsigned int tag_offset = rq->mq_hctx->tags->nr_reserved_tags;
@@ -1769,20 +1770,7 @@ static bool __blk_mq_alloc_driver_tag(struct request *rq)
return false;
rq->tag = tag + tag_offset;
- return true;
-}
-
-bool __blk_mq_get_driver_tag(struct blk_mq_hw_ctx *hctx, struct request *rq)
-{
- if (rq->tag == BLK_MQ_NO_TAG && !__blk_mq_alloc_driver_tag(rq))
- return false;
-
- if ((hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED) &&
- !(rq->rq_flags & RQF_MQ_INFLIGHT)) {
- rq->rq_flags |= RQF_MQ_INFLIGHT;
- __blk_mq_inc_active_requests(hctx);
- }
- hctx->tags->rqs[rq->tag] = rq;
+ blk_mq_inc_active_requests(rq->mq_hctx);
return true;
}
@@ -2794,13 +2782,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
* If we do, we can dispatch the whole plug list in one go. We
* already know at this point that all requests belong to the
* same queue, caller must ensure that's the case.
- *
- * Since we pass off the full list to the driver at this point,
- * we do not increment the active request count for the queue.
- * Bypass shared tags for now because of that.
*/
- if (q->mq_ops->queue_rqs &&
- !(rq->mq_hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED)) {
+ if (q->mq_ops->queue_rqs) {
blk_mq_run_dispatch_ops(q,
__blk_mq_flush_plug_list(q, plug));
if (rq_list_empty(plug->mq_list))
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 1743857e0b01..f75a9ecfebde 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -271,12 +271,18 @@ static inline int blk_mq_get_rq_budget_token(struct request *rq)
return -1;
}
-static inline void __blk_mq_inc_active_requests(struct blk_mq_hw_ctx *hctx)
+static inline void __blk_mq_add_active_requests(struct blk_mq_hw_ctx *hctx,
+ int val)
{
if (blk_mq_is_shared_tags(hctx->flags))
- atomic_inc(&hctx->queue->nr_active_requests_shared_tags);
+ atomic_add(val, &hctx->queue->nr_active_requests_shared_tags);
else
- atomic_inc(&hctx->nr_active);
+ atomic_add(val, &hctx->nr_active);
+}
+
+static inline void __blk_mq_inc_active_requests(struct blk_mq_hw_ctx *hctx)
+{
+ __blk_mq_add_active_requests(hctx, 1);
}
static inline void __blk_mq_sub_active_requests(struct blk_mq_hw_ctx *hctx,
@@ -293,6 +299,32 @@ static inline void __blk_mq_dec_active_requests(struct blk_mq_hw_ctx *hctx)
__blk_mq_sub_active_requests(hctx, 1);
}
+static inline void blk_mq_add_active_requests(struct blk_mq_hw_ctx *hctx,
+ int val)
+{
+ if (hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED)
+ __blk_mq_add_active_requests(hctx, val);
+}
+
+static inline void blk_mq_inc_active_requests(struct blk_mq_hw_ctx *hctx)
+{
+ if (hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED)
+ __blk_mq_inc_active_requests(hctx);
+}
+
+static inline void blk_mq_sub_active_requests(struct blk_mq_hw_ctx *hctx,
+ int val)
+{
+ if (hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED)
+ __blk_mq_sub_active_requests(hctx, val);
+}
+
+static inline void blk_mq_dec_active_requests(struct blk_mq_hw_ctx *hctx)
+{
+ if (hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED)
+ __blk_mq_dec_active_requests(hctx);
+}
+
static inline int __blk_mq_active_requests(struct blk_mq_hw_ctx *hctx)
{
if (blk_mq_is_shared_tags(hctx->flags))
@@ -302,13 +334,9 @@ static inline int __blk_mq_active_requests(struct blk_mq_hw_ctx *hctx)
static inline void __blk_mq_put_driver_tag(struct blk_mq_hw_ctx *hctx,
struct request *rq)
{
+ blk_mq_dec_active_requests(hctx);
blk_mq_put_tag(hctx->tags, rq->mq_ctx, rq->tag);
rq->tag = BLK_MQ_NO_TAG;
-
- if (rq->rq_flags & RQF_MQ_INFLIGHT) {
- rq->rq_flags &= ~RQF_MQ_INFLIGHT;
- __blk_mq_dec_active_requests(hctx);
- }
}
static inline void blk_mq_put_driver_tag(struct request *rq)
@@ -319,19 +347,14 @@ static inline void blk_mq_put_driver_tag(struct request *rq)
__blk_mq_put_driver_tag(rq->mq_hctx, rq);
}
-bool __blk_mq_get_driver_tag(struct blk_mq_hw_ctx *hctx, struct request *rq);
+bool __blk_mq_alloc_driver_tag(struct request *rq);
static inline bool blk_mq_get_driver_tag(struct request *rq)
{
- struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
-
- if (rq->tag != BLK_MQ_NO_TAG &&
- !(hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED)) {
- hctx->tags->rqs[rq->tag] = rq;
- return true;
- }
+ if (rq->tag == BLK_MQ_NO_TAG && !__blk_mq_alloc_driver_tag(rq))
+ return false;
- return __blk_mq_get_driver_tag(hctx, rq);
+ return true;
}
static inline void blk_mq_clear_mq_map(struct blk_mq_queue_map *qmap)
diff --git a/block/partitions/ibm.c b/block/partitions/ibm.c
index 403756dbd50d..82d9c4c3fb41 100644
--- a/block/partitions/ibm.c
+++ b/block/partitions/ibm.c
@@ -61,6 +61,47 @@ static sector_t cchhb2blk(struct vtoc_cchhb *ptr, struct hd_geometry *geo)
ptr->b;
}
+/* Volume Label Type/ID Length */
+#define DASD_VOL_TYPE_LEN 4
+#define DASD_VOL_ID_LEN 6
+
+/* Volume Label Types */
+#define DASD_VOLLBL_TYPE_VOL1 0
+#define DASD_VOLLBL_TYPE_LNX1 1
+#define DASD_VOLLBL_TYPE_CMS1 2
+
+struct dasd_vollabel {
+ char *type;
+ int idx;
+};
+
+static struct dasd_vollabel dasd_vollabels[] = {
+ [DASD_VOLLBL_TYPE_VOL1] = {
+ .type = "VOL1",
+ .idx = DASD_VOLLBL_TYPE_VOL1,
+ },
+ [DASD_VOLLBL_TYPE_LNX1] = {
+ .type = "LNX1",
+ .idx = DASD_VOLLBL_TYPE_LNX1,
+ },
+ [DASD_VOLLBL_TYPE_CMS1] = {
+ .type = "CMS1",
+ .idx = DASD_VOLLBL_TYPE_CMS1,
+ },
+};
+
+static int get_label_by_type(const char *type)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dasd_vollabels); i++) {
+ if (!memcmp(type, dasd_vollabels[i].type, DASD_VOL_TYPE_LEN))
+ return dasd_vollabels[i].idx;
+ }
+
+ return -1;
+}
+
static int find_label(struct parsed_partitions *state,
dasd_information2_t *info,
struct hd_geometry *geo,
@@ -70,12 +111,10 @@ static int find_label(struct parsed_partitions *state,
char type[],
union label_t *label)
{
- Sector sect;
- unsigned char *data;
sector_t testsect[3];
- unsigned char temp[5];
- int found = 0;
int i, testcount;
+ Sector sect;
+ void *data;
/* There a three places where we may find a valid label:
* - on an ECKD disk it's block 2
@@ -103,31 +142,27 @@ static int find_label(struct parsed_partitions *state,
if (data == NULL)
continue;
memcpy(label, data, sizeof(*label));
- memcpy(temp, data, 4);
- temp[4] = 0;
- EBCASC(temp, 4);
+ memcpy(type, data, DASD_VOL_TYPE_LEN);
+ EBCASC(type, DASD_VOL_TYPE_LEN);
put_dev_sector(sect);
- if (!strcmp(temp, "VOL1") ||
- !strcmp(temp, "LNX1") ||
- !strcmp(temp, "CMS1")) {
- if (!strcmp(temp, "VOL1")) {
- strncpy(type, label->vol.vollbl, 4);
- strncpy(name, label->vol.volid, 6);
- } else {
- strncpy(type, label->lnx.vollbl, 4);
- strncpy(name, label->lnx.volid, 6);
- }
- EBCASC(type, 4);
- EBCASC(name, 6);
+ switch (get_label_by_type(type)) {
+ case DASD_VOLLBL_TYPE_VOL1:
+ memcpy(name, label->vol.volid, DASD_VOL_ID_LEN);
+ EBCASC(name, DASD_VOL_ID_LEN);
+ *labelsect = testsect[i];
+ return 1;
+ case DASD_VOLLBL_TYPE_LNX1:
+ case DASD_VOLLBL_TYPE_CMS1:
+ memcpy(name, label->lnx.volid, DASD_VOL_ID_LEN);
+ EBCASC(name, DASD_VOL_ID_LEN);
*labelsect = testsect[i];
- found = 1;
+ return 1;
+ default:
break;
}
}
- if (!found)
- memset(label, 0, sizeof(*label));
- return found;
+ return 0;
}
static int find_vol1_partitions(struct parsed_partitions *state,
@@ -297,8 +332,8 @@ int ibm_partition(struct parsed_partitions *state)
sector_t nr_sectors;
dasd_information2_t *info;
struct hd_geometry *geo;
- char type[5] = {0,};
- char name[7] = {0,};
+ char type[DASD_VOL_TYPE_LEN + 1] = "";
+ char name[DASD_VOL_ID_LEN + 1] = "";
sector_t labelsect;
union label_t *label;
@@ -330,18 +365,21 @@ int ibm_partition(struct parsed_partitions *state)
info = NULL;
}
- if (find_label(state, info, geo, blocksize, &labelsect, name, type,
- label)) {
- if (!strncmp(type, "VOL1", 4)) {
+ if (find_label(state, info, geo, blocksize, &labelsect, name, type, label)) {
+ switch (get_label_by_type(type)) {
+ case DASD_VOLLBL_TYPE_VOL1:
res = find_vol1_partitions(state, geo, blocksize, name,
label);
- } else if (!strncmp(type, "LNX1", 4)) {
+ break;
+ case DASD_VOLLBL_TYPE_LNX1:
res = find_lnx1_partitions(state, geo, blocksize, name,
label, labelsect, nr_sectors,
info);
- } else if (!strncmp(type, "CMS1", 4)) {
+ break;
+ case DASD_VOLLBL_TYPE_CMS1:
res = find_cms1_partitions(state, geo, blocksize, name,
label, labelsect);
+ break;
}
} else if (info) {
/*
diff --git a/block/sed-opal.c b/block/sed-opal.c
index 04f38a3f5d95..3d9e9cd250bd 100644
--- a/block/sed-opal.c
+++ b/block/sed-opal.c
@@ -18,6 +18,7 @@
#include <linux/uaccess.h>
#include <uapi/linux/sed-opal.h>
#include <linux/sed-opal.h>
+#include <linux/sed-opal-key.h>
#include <linux/string.h>
#include <linux/kdev_t.h>
#include <linux/key.h>
@@ -3018,7 +3019,13 @@ static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
if (ret)
return ret;
- /* update keyring with new password */
+ /* update keyring and key store with new password */
+ ret = sed_write_key(OPAL_AUTH_KEY,
+ opal_pw->new_user_pw.opal_key.key,
+ opal_pw->new_user_pw.opal_key.key_len);
+ if (ret != -EOPNOTSUPP)
+ pr_warn("error updating SED key: %d\n", ret);
+
ret = update_sed_opal_key(OPAL_AUTH_KEY,
opal_pw->new_user_pw.opal_key.key,
opal_pw->new_user_pw.opal_key.key_len);
@@ -3291,6 +3298,8 @@ EXPORT_SYMBOL_GPL(sed_ioctl);
static int __init sed_opal_init(void)
{
struct key *kr;
+ char init_sed_key[OPAL_KEY_MAX];
+ int keylen = OPAL_KEY_MAX - 1;
kr = keyring_alloc(".sed_opal",
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
@@ -3303,6 +3312,11 @@ static int __init sed_opal_init(void)
sed_opal_keyring = kr;
- return 0;
+ if (sed_read_key(OPAL_AUTH_KEY, init_sed_key, &keylen) < 0) {
+ memset(init_sed_key, '\0', sizeof(init_sed_key));
+ keylen = OPAL_KEY_MAX - 1;
+ }
+
+ return update_sed_opal_key(OPAL_AUTH_KEY, init_sed_key, keylen);
}
late_initcall(sed_opal_init);
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 8ba3e8b9ad72..9826907eb06e 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -175,6 +175,8 @@ source "drivers/soundwire/Kconfig"
source "drivers/soc/Kconfig"
+source "drivers/pmdomain/Kconfig"
+
source "drivers/devfreq/Kconfig"
source "drivers/extcon/Kconfig"
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index cee82b473dc5..554e487cbfab 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -257,7 +257,7 @@ config ACPI_CPU_FREQ_PSS
config ACPI_PROCESSOR_CSTATE
def_bool y
depends on ACPI_PROCESSOR
- depends on IA64 || X86
+ depends on X86
config ACPI_PROCESSOR_IDLE
bool
@@ -281,9 +281,9 @@ config ACPI_CPPC_LIB
config ACPI_PROCESSOR
tristate "Processor"
- depends on X86 || IA64 || ARM64 || LOONGARCH
+ depends on X86 || ARM64 || LOONGARCH
select ACPI_PROCESSOR_IDLE
- select ACPI_CPU_FREQ_PSS if X86 || IA64 || LOONGARCH
+ select ACPI_CPU_FREQ_PSS if X86 || LOONGARCH
select THERMAL
default y
help
diff --git a/drivers/acpi/numa/Kconfig b/drivers/acpi/numa/Kconfig
index 39b1f34c21df..849c2bd820b9 100644
--- a/drivers/acpi/numa/Kconfig
+++ b/drivers/acpi/numa/Kconfig
@@ -2,8 +2,8 @@
config ACPI_NUMA
bool "NUMA support"
depends on NUMA
- depends on (X86 || IA64 || ARM64 || LOONGARCH)
- default y if IA64 || ARM64
+ depends on (X86 || ARM64 || LOONGARCH)
+ default y if ARM64
config ACPI_HMAT
bool "ACPI Heterogeneous Memory Attribute Table Support"
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index e154ad0be263..c09cc3c68633 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -276,7 +276,7 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
return NULL;
}
-#if defined(CONFIG_IA64) || defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
+#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
/* ioremap will take care of cache attributes */
#define should_use_kmap(pfn) 0
#else
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 7dd6dbaa98c3..b203cfe28550 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -90,7 +90,7 @@ static int map_gicc_mpidr(struct acpi_subtable_header *entry,
struct acpi_madt_generic_interrupt *gicc =
container_of(entry, struct acpi_madt_generic_interrupt, header);
- if (!(gicc->flags & ACPI_MADT_ENABLED))
+ if (!acpi_gicc_is_usable(gicc))
return -ENODEV;
/* device_declaration means Device object in DSDT, in the
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 08745e7db820..3a5f3255f51b 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -423,6 +423,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */
/* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */
{ PCI_VDEVICE(INTEL, 0x4b63), board_ahci_low_power }, /* Elkhart Lake AHCI */
+ { PCI_VDEVICE(INTEL, 0x7ae2), board_ahci_low_power }, /* Alder Lake-P AHCI */
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -604,6 +605,11 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci }, /* ASM1061R */
{ PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci }, /* ASM1062R */
{ PCI_VDEVICE(ASMEDIA, 0x0624), board_ahci }, /* ASM1062+JMB575 */
+ { PCI_VDEVICE(ASMEDIA, 0x1062), board_ahci }, /* ASM1062A */
+ { PCI_VDEVICE(ASMEDIA, 0x1064), board_ahci }, /* ASM1064 */
+ { PCI_VDEVICE(ASMEDIA, 0x1164), board_ahci }, /* ASM1164 */
+ { PCI_VDEVICE(ASMEDIA, 0x1165), board_ahci }, /* ASM1165 */
+ { PCI_VDEVICE(ASMEDIA, 0x1166), board_ahci }, /* ASM1166 */
/*
* Samsung SSDs found on some macbooks. NCQ times out if MSI is
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 9fa005965f3b..cb768f66f0a7 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -9,10 +9,11 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/ahci_platform.h>
#include <linux/gpio/consumer.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/libata.h>
@@ -1050,16 +1051,11 @@ static int imx8_sata_probe(struct device *dev, struct imx_ahci_priv *imxpriv)
static int imx_ahci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- const struct of_device_id *of_id;
struct ahci_host_priv *hpriv;
struct imx_ahci_priv *imxpriv;
unsigned int reg_val;
int ret;
- of_id = of_match_device(imx_ahci_of_match, dev);
- if (!of_id)
- return -EINVAL;
-
imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
if (!imxpriv)
return -ENOMEM;
@@ -1067,7 +1063,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
imxpriv->ahci_pdev = pdev;
imxpriv->no_device = false;
imxpriv->first_time = true;
- imxpriv->type = (unsigned long)of_id->data;
+ imxpriv->type = (enum ahci_imx_type)device_get_match_data(dev);
imxpriv->sata_clk = devm_clk_get(dev, "sata");
if (IS_ERR(imxpriv->sata_clk)) {
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index ccef5e63bdf9..81a1d838c0fc 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -13,9 +13,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/ahci_platform.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
+#include <linux/of.h>
#include <linux/phy/phy.h>
#include "ahci.h"
@@ -735,7 +733,6 @@ static int xgene_ahci_probe(struct platform_device *pdev)
struct ahci_host_priv *hpriv;
struct xgene_ahci_context *ctx;
struct resource *res;
- const struct of_device_id *of_devid;
enum xgene_ahci_version version = XGENE_AHCI_V1;
const struct ata_port_info *ppi[] = { &xgene_ahci_v1_port_info,
&xgene_ahci_v2_port_info };
@@ -778,10 +775,8 @@ static int xgene_ahci_probe(struct platform_device *pdev)
ctx->csr_mux = csr;
}
- of_devid = of_match_device(xgene_ahci_of_match, dev);
- if (of_devid) {
- if (of_devid->data)
- version = (unsigned long) of_devid->data;
+ if (dev->of_node) {
+ version = (enum xgene_ahci_version)of_device_get_match_data(dev);
}
#ifdef CONFIG_ACPI
else {
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index f1263364fa97..1a63200ea437 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -2730,7 +2730,7 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host,
if (rc)
return rc;
- ata_port_desc(host->ports[i], "irq %d", irq);
+ ata_port_desc_misc(host->ports[i], irq);
}
return ata_host_register(host, sht);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index d8cc1e27a125..6fb4e8dc8c3c 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1972,6 +1972,35 @@ retry:
return rc;
}
+bool ata_dev_power_init_tf(struct ata_device *dev, struct ata_taskfile *tf,
+ bool set_active)
+{
+ /* Only applies to ATA and ZAC devices */
+ if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC)
+ return false;
+
+ ata_tf_init(dev, tf);
+ tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+ tf->protocol = ATA_PROT_NODATA;
+
+ if (set_active) {
+ /* VERIFY for 1 sector at lba=0 */
+ tf->command = ATA_CMD_VERIFY;
+ tf->nsect = 1;
+ if (dev->flags & ATA_DFLAG_LBA) {
+ tf->flags |= ATA_TFLAG_LBA;
+ tf->device |= ATA_LBA;
+ } else {
+ /* CHS */
+ tf->lbal = 0x1; /* sect */
+ }
+ } else {
+ tf->command = ATA_CMD_STANDBYNOW1;
+ }
+
+ return true;
+}
+
/**
* ata_dev_power_set_standby - Set a device power mode to standby
* @dev: target device
@@ -1988,10 +2017,6 @@ void ata_dev_power_set_standby(struct ata_device *dev)
struct ata_taskfile tf;
unsigned int err_mask;
- /* Issue STANDBY IMMEDIATE command only if supported by the device */
- if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC)
- return;
-
/*
* Some odd clown BIOSes issue spindown on power off (ACPI S4 or S5)
* causing some drives to spin up and down again. For these, do nothing
@@ -2005,10 +2030,9 @@ void ata_dev_power_set_standby(struct ata_device *dev)
system_entering_hibernation())
return;
- ata_tf_init(dev, &tf);
- tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
- tf.protocol = ATA_PROT_NODATA;
- tf.command = ATA_CMD_STANDBYNOW1;
+ /* Issue STANDBY IMMEDIATE command only if supported by the device */
+ if (!ata_dev_power_init_tf(dev, &tf, false))
+ return;
ata_dev_notice(dev, "Entering standby power mode\n");
@@ -2018,6 +2042,33 @@ void ata_dev_power_set_standby(struct ata_device *dev)
err_mask);
}
+static bool ata_dev_power_is_active(struct ata_device *dev)
+{
+ struct ata_taskfile tf;
+ unsigned int err_mask;
+
+ ata_tf_init(dev, &tf);
+ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+ tf.protocol = ATA_PROT_NODATA;
+ tf.command = ATA_CMD_CHK_POWER;
+
+ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
+ if (err_mask) {
+ ata_dev_err(dev, "Check power mode failed (err_mask=0x%x)\n",
+ err_mask);
+ /*
+ * Assume we are in standby mode so that we always force a
+ * spinup in ata_dev_power_set_active().
+ */
+ return false;
+ }
+
+ ata_dev_dbg(dev, "Power mode: 0x%02x\n", tf.nsect);
+
+ /* Active or idle */
+ return tf.nsect == 0xff;
+}
+
/**
* ata_dev_power_set_active - Set a device power mode to active
* @dev: target device
@@ -2038,21 +2089,15 @@ void ata_dev_power_set_active(struct ata_device *dev)
* Issue READ VERIFY SECTORS command for 1 sector at lba=0 only
* if supported by the device.
*/
- if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC)
+ if (!ata_dev_power_init_tf(dev, &tf, true))
return;
- ata_tf_init(dev, &tf);
- tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
- tf.protocol = ATA_PROT_NODATA;
- tf.command = ATA_CMD_VERIFY;
- tf.nsect = 1;
- if (dev->flags & ATA_DFLAG_LBA) {
- tf.flags |= ATA_TFLAG_LBA;
- tf.device |= ATA_LBA;
- } else {
- /* CHS */
- tf.lbal = 0x1; /* sect */
- }
+ /*
+ * Check the device power state & condition and force a spinup with
+ * VERIFY command only if the drive is not already ACTIVE or IDLE.
+ */
+ if (ata_dev_power_is_active(dev))
+ return;
ata_dev_notice(dev, "Entering active power mode\n");
@@ -5155,18 +5200,8 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
ata_port_wait_eh(ap);
}
-/*
- * On some hardware, device fails to respond after spun down for suspend. As
- * the device won't be used before being resumed, we don't need to touch the
- * device. Ask EH to skip the usual stuff and proceed directly to suspend.
- *
- * http://thread.gmane.org/gmane.linux.ide/46764
- */
-static const unsigned int ata_port_suspend_ehi = ATA_EHI_QUIET
- | ATA_EHI_NO_AUTOPSY
- | ATA_EHI_NO_RECOVERY;
-
-static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg)
+static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg,
+ bool async)
{
/*
* We are about to suspend the port, so we do not care about
@@ -5176,20 +5211,18 @@ static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg)
*/
cancel_delayed_work_sync(&ap->scsi_rescan_task);
- ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false);
-}
-
-static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg)
-{
/*
- * We are about to suspend the port, so we do not care about
- * scsi_rescan_device() calls scheduled by previous resume operations.
- * The next resume will schedule the rescan again. So cancel any rescan
- * that is not done yet.
+ * On some hardware, device fails to respond after spun down for
+ * suspend. As the device will not be used until being resumed, we
+ * do not need to touch the device. Ask EH to skip the usual stuff
+ * and proceed directly to suspend.
+ *
+ * http://thread.gmane.org/gmane.linux.ide/46764
*/
- cancel_delayed_work_sync(&ap->scsi_rescan_task);
-
- ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true);
+ ata_port_request_pm(ap, mesg, 0,
+ ATA_EHI_QUIET | ATA_EHI_NO_AUTOPSY |
+ ATA_EHI_NO_RECOVERY,
+ async);
}
static int ata_port_pm_suspend(struct device *dev)
@@ -5199,7 +5232,7 @@ static int ata_port_pm_suspend(struct device *dev)
if (pm_runtime_suspended(dev))
return 0;
- ata_port_suspend(ap, PMSG_SUSPEND);
+ ata_port_suspend(ap, PMSG_SUSPEND, false);
return 0;
}
@@ -5210,35 +5243,29 @@ static int ata_port_pm_freeze(struct device *dev)
if (pm_runtime_suspended(dev))
return 0;
- ata_port_suspend(ap, PMSG_FREEZE);
+ ata_port_suspend(ap, PMSG_FREEZE, false);
return 0;
}
static int ata_port_pm_poweroff(struct device *dev)
{
- ata_port_suspend(to_ata_port(dev), PMSG_HIBERNATE);
+ if (!pm_runtime_suspended(dev))
+ ata_port_suspend(to_ata_port(dev), PMSG_HIBERNATE, false);
return 0;
}
-static const unsigned int ata_port_resume_ehi = ATA_EHI_NO_AUTOPSY
- | ATA_EHI_QUIET;
-
-static void ata_port_resume(struct ata_port *ap, pm_message_t mesg)
-{
- ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, false);
-}
-
-static void ata_port_resume_async(struct ata_port *ap, pm_message_t mesg)
+static void ata_port_resume(struct ata_port *ap, pm_message_t mesg,
+ bool async)
{
- ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, true);
+ ata_port_request_pm(ap, mesg, ATA_EH_RESET,
+ ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET,
+ async);
}
static int ata_port_pm_resume(struct device *dev)
{
- ata_port_resume_async(to_ata_port(dev), PMSG_RESUME);
- pm_runtime_disable(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
+ if (!pm_runtime_suspended(dev))
+ ata_port_resume(to_ata_port(dev), PMSG_RESUME, true);
return 0;
}
@@ -5268,13 +5295,13 @@ static int ata_port_runtime_idle(struct device *dev)
static int ata_port_runtime_suspend(struct device *dev)
{
- ata_port_suspend(to_ata_port(dev), PMSG_AUTO_SUSPEND);
+ ata_port_suspend(to_ata_port(dev), PMSG_AUTO_SUSPEND, false);
return 0;
}
static int ata_port_runtime_resume(struct device *dev)
{
- ata_port_resume(to_ata_port(dev), PMSG_AUTO_RESUME);
+ ata_port_resume(to_ata_port(dev), PMSG_AUTO_RESUME, false);
return 0;
}
@@ -5298,13 +5325,13 @@ static const struct dev_pm_ops ata_port_pm_ops = {
*/
void ata_sas_port_suspend(struct ata_port *ap)
{
- ata_port_suspend_async(ap, PMSG_SUSPEND);
+ ata_port_suspend(ap, PMSG_SUSPEND, true);
}
EXPORT_SYMBOL_GPL(ata_sas_port_suspend);
void ata_sas_port_resume(struct ata_port *ap)
{
- ata_port_resume_async(ap, PMSG_RESUME);
+ ata_port_resume(ap, PMSG_RESUME, true);
}
EXPORT_SYMBOL_GPL(ata_sas_port_resume);
@@ -6026,7 +6053,7 @@ int ata_host_activate(struct ata_host *host, int irq,
return rc;
for (i = 0; i < host->n_ports; i++)
- ata_port_desc(host->ports[i], "irq %d", irq);
+ ata_port_desc_misc(host->ports[i], irq);
rc = ata_host_register(host, sht);
/* if failed, just free the IRQ and leave ports alone */
@@ -6054,6 +6081,9 @@ static void ata_port_detach(struct ata_port *ap)
struct ata_link *link;
struct ata_device *dev;
+ /* Ensure ata_port probe has completed */
+ async_synchronize_cookie(ap->cookie + 1);
+
/* Wait for any ongoing EH */
ata_port_wait_eh(ap);
@@ -6118,11 +6148,8 @@ void ata_host_detach(struct ata_host *host)
{
int i;
- for (i = 0; i < host->n_ports; i++) {
- /* Ensure ata_port probe has completed */
- async_synchronize_cookie(host->ports[i]->cookie + 1);
+ for (i = 0; i < host->n_ports; i++)
ata_port_detach(host->ports[i]);
- }
/* the host is dead now, dissociate ACPI */
ata_acpi_dissociate(host);
@@ -6153,10 +6180,24 @@ EXPORT_SYMBOL_GPL(ata_pci_remove_one);
void ata_pci_shutdown_one(struct pci_dev *pdev)
{
struct ata_host *host = pci_get_drvdata(pdev);
+ struct ata_port *ap;
+ unsigned long flags;
int i;
+ /* Tell EH to disable all devices */
for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
+ ap = host->ports[i];
+ spin_lock_irqsave(ap->lock, flags);
+ ap->pflags |= ATA_PFLAG_UNLOADING;
+ ata_port_schedule_eh(ap);
+ spin_unlock_irqrestore(ap->lock, flags);
+ }
+
+ for (i = 0; i < host->n_ports; i++) {
+ ap = host->ports[i];
+
+ /* Wait for EH to complete before freezing the port */
+ ata_port_wait_eh(ap);
ap->pflags |= ATA_PFLAG_FROZEN;
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 5686353e442c..b0d6e69c4a5b 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -494,6 +494,18 @@ void ata_eh_release(struct ata_port *ap)
mutex_unlock(&ap->host->eh_mutex);
}
+static void ata_eh_dev_disable(struct ata_device *dev)
+{
+ ata_acpi_on_disable(dev);
+ ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET);
+ dev->class++;
+
+ /* From now till the next successful probe, ering is used to
+ * track probe failures. Clear accumulated device error info.
+ */
+ ata_ering_clear(&dev->ering);
+}
+
static void ata_eh_unload(struct ata_port *ap)
{
struct ata_link *link;
@@ -517,8 +529,8 @@ static void ata_eh_unload(struct ata_port *ap)
*/
ata_for_each_link(link, ap, PMP_FIRST) {
sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0);
- ata_for_each_dev(dev, link, ALL)
- ata_dev_disable(dev);
+ ata_for_each_dev(dev, link, ENABLED)
+ ata_eh_dev_disable(dev);
}
/* freeze and set UNLOADED */
@@ -1211,14 +1223,8 @@ void ata_dev_disable(struct ata_device *dev)
return;
ata_dev_warn(dev, "disable device\n");
- ata_acpi_on_disable(dev);
- ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET);
- dev->class++;
- /* From now till the next successful probe, ering is used to
- * track probe failures. Clear accumulated device error info.
- */
- ata_ering_clear(&dev->ering);
+ ata_eh_dev_disable(dev);
}
EXPORT_SYMBOL_GPL(ata_dev_disable);
@@ -1240,12 +1246,12 @@ void ata_eh_detach_dev(struct ata_device *dev)
/*
* If the device is still enabled, transition it to standby power mode
- * (i.e. spin down HDDs).
+ * (i.e. spin down HDDs) and disable it.
*/
- if (ata_dev_enabled(dev))
+ if (ata_dev_enabled(dev)) {
ata_dev_power_set_standby(dev);
-
- ata_dev_disable(dev);
+ ata_eh_dev_disable(dev);
+ }
spin_lock_irqsave(ap->lock, flags);
@@ -2909,6 +2915,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
*/
if (ata_is_host_link(link))
ata_eh_thaw_port(ap);
+ ata_link_warn(link, "%s failed\n",
+ reset == hardreset ? "hardreset" : "softreset");
goto out;
}
@@ -3043,15 +3051,6 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
if (ehc->i.flags & ATA_EHI_DID_RESET)
readid_flags |= ATA_READID_POSTRESET;
- /*
- * When resuming, before executing any command, make sure to
- * transition the device to the active power mode.
- */
- if ((action & ATA_EH_SET_ACTIVE) && ata_dev_enabled(dev)) {
- ata_dev_power_set_active(dev);
- ata_eh_done(link, dev, ATA_EH_SET_ACTIVE);
- }
-
if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
WARN_ON(dev->class == ATA_DEV_PMP);
@@ -3848,6 +3847,17 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
}
}
+ /*
+ * Make sure to transition devices to the active power mode
+ * if needed (e.g. if we were scheduled on system resume).
+ */
+ ata_for_each_dev(dev, link, ENABLED) {
+ if (ehc->i.dev_action[dev->devno] & ATA_EH_SET_ACTIVE) {
+ ata_dev_power_set_active(dev);
+ ata_eh_done(link, dev, ATA_EH_SET_ACTIVE);
+ }
+ }
+
/* retry flush if necessary */
ata_for_each_dev(dev, link, ALL) {
if (dev->class != ATA_DEV_ATA &&
diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c
index a701e1538482..b6656c287175 100644
--- a/drivers/ata/libata-sata.c
+++ b/drivers/ata/libata-sata.c
@@ -621,7 +621,6 @@ int sata_link_hardreset(struct ata_link *link, const unsigned int *timing,
/* online is set iff link is online && reset succeeded */
if (online)
*online = false;
- ata_link_err(link, "COMRESET failed (errno=%d)\n", rc);
}
return rc;
}
@@ -1182,8 +1181,8 @@ EXPORT_SYMBOL_GPL(ata_sas_tport_delete);
int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap)
{
ata_scsi_sdev_config(sdev);
- ata_scsi_dev_config(sdev, ap->link.device);
- return 0;
+
+ return ata_scsi_dev_config(sdev, ap->link.device);
}
EXPORT_SYMBOL_GPL(ata_sas_slave_configure);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 3a957c4da409..c10ff8985203 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1203,7 +1203,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *scmd = qc->scsicmd;
- struct ata_taskfile *tf = &qc->tf;
const u8 *cdb = scmd->cmnd;
u16 fp;
u8 bp = 0xff;
@@ -1213,54 +1212,24 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
goto invalid_fld;
}
- tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
- tf->protocol = ATA_PROT_NODATA;
- if (cdb[1] & 0x1) {
- ; /* ignore IMMED bit, violates sat-r05 */
- }
+ /* LOEJ bit set not supported */
if (cdb[4] & 0x2) {
fp = 4;
bp = 1;
- goto invalid_fld; /* LOEJ bit set not supported */
+ goto invalid_fld;
}
+
+ /* Power conditions not supported */
if (((cdb[4] >> 4) & 0xf) != 0) {
fp = 4;
bp = 3;
- goto invalid_fld; /* power conditions not supported */
+ goto invalid_fld;
}
- if (cdb[4] & 0x1) {
- tf->nsect = 1; /* 1 sector, lba=0 */
-
- if (qc->dev->flags & ATA_DFLAG_LBA) {
- tf->flags |= ATA_TFLAG_LBA;
-
- tf->lbah = 0x0;
- tf->lbam = 0x0;
- tf->lbal = 0x0;
- tf->device |= ATA_LBA;
- } else {
- /* CHS */
- tf->lbal = 0x1; /* sect */
- tf->lbam = 0x0; /* cyl low */
- tf->lbah = 0x0; /* cyl high */
- }
-
- tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
- } else {
- /* Some odd clown BIOSen issue spindown on power off (ACPI S4
- * or S5) causing some drives to spin up and down again.
- */
- if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) &&
- system_state == SYSTEM_POWER_OFF)
- goto skip;
-
- if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) &&
- system_entering_hibernation())
- goto skip;
-
- /* Issue ATA STANDBY IMMEDIATE command */
- tf->command = ATA_CMD_STANDBYNOW1;
+ /* Ignore IMMED bit (cdb[1] & 0x1), violates sat-r05 */
+ if (!ata_dev_power_init_tf(qc->dev, &qc->tf, cdb[4] & 0x1)) {
+ ata_scsi_set_sense(qc->dev, scmd, ABORTED_COMMAND, 0, 0);
+ return 1;
}
/*
@@ -1275,12 +1244,8 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
invalid_fld:
ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp);
return 1;
- skip:
- scmd->result = SAM_STAT_GOOD;
- return 1;
}
-
/**
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
* @qc: Storage for translated ATA taskfile
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 8fcc622fcb3d..95a19c4ef2a1 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2316,7 +2316,7 @@ int ata_pci_sff_activate_host(struct ata_host *host,
for (i = 0; i < 2; i++) {
if (ata_port_is_dummy(host->ports[i]))
continue;
- ata_port_desc(host->ports[i], "irq %d", pdev->irq);
+ ata_port_desc_misc(host->ports[i], pdev->irq);
}
} else if (legacy_mode) {
if (!ata_port_is_dummy(host->ports[0])) {
@@ -2326,8 +2326,8 @@ int ata_pci_sff_activate_host(struct ata_host *host,
if (rc)
goto out;
- ata_port_desc(host->ports[0], "irq %d",
- ATA_PRIMARY_IRQ(pdev));
+ ata_port_desc_misc(host->ports[0],
+ ATA_PRIMARY_IRQ(pdev));
}
if (!ata_port_is_dummy(host->ports[1])) {
@@ -2337,8 +2337,8 @@ int ata_pci_sff_activate_host(struct ata_host *host,
if (rc)
goto out;
- ata_port_desc(host->ports[1], "irq %d",
- ATA_SECONDARY_IRQ(pdev));
+ ata_port_desc_misc(host->ports[1],
+ ATA_SECONDARY_IRQ(pdev));
}
}
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 05ac80da8ebc..5c685bb1939e 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -62,6 +62,8 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
unsigned int readid_flags);
extern int ata_dev_configure(struct ata_device *dev);
+extern bool ata_dev_power_init_tf(struct ata_device *dev,
+ struct ata_taskfile *tf, bool set_active);
extern void ata_dev_power_set_standby(struct ata_device *dev);
extern void ata_dev_power_set_active(struct ata_device *dev);
extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 422d42761a1d..38795508c2e9 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -212,7 +212,7 @@ static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;
- ata_port_desc(ap, "irq %d", irq[i]);
+ ata_port_desc_misc(ap, irq[i]);
}
return ata_host_register(host, &cs5520_sht);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 45e48d653c60..e82786c63fbd 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -4123,10 +4123,13 @@ static int mv_platform_probe(struct platform_device *pdev)
hpriv->base -= SATAHC0_REG_BASE;
hpriv->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(hpriv->clk))
+ if (IS_ERR(hpriv->clk)) {
dev_notice(&pdev->dev, "cannot get optional clkdev\n");
- else
- clk_prepare_enable(hpriv->clk);
+ } else {
+ rc = clk_prepare_enable(hpriv->clk);
+ if (rc)
+ goto err;
+ }
for (port = 0; port < n_ports; port++) {
char port_number[16];
diff --git a/drivers/base/firmware_loader/fallback_table.c b/drivers/base/firmware_loader/fallback_table.c
index e5ac098d0742..8432ab2c3b3c 100644
--- a/drivers/base/firmware_loader/fallback_table.c
+++ b/drivers/base/firmware_loader/fallback_table.c
@@ -44,7 +44,6 @@ static struct ctl_table firmware_config_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
- { }
};
static struct ctl_table_header *firmware_config_sysct_table_header;
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index e38fc140d113..da1777e39eaa 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -130,6 +130,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
#define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
#define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
#define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
+#define genpd_is_opp_table_fw(genpd) (genpd->flags & GENPD_FLAG_OPP_TABLE_FW)
static inline bool irq_safe_dev_in_sleep_domain(struct device *dev,
const struct generic_pm_domain *genpd)
@@ -2337,7 +2338,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
genpd->dev.of_node = np;
/* Parse genpd OPP table */
- if (genpd->set_performance_state) {
+ if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
ret = dev_pm_opp_of_add_table(&genpd->dev);
if (ret)
return dev_err_probe(&genpd->dev, ret, "Failed to add OPP table\n");
@@ -2352,7 +2353,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
ret = genpd_add_provider(np, genpd_xlate_simple, genpd);
if (ret) {
- if (genpd->set_performance_state) {
+ if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
dev_pm_opp_put_opp_table(genpd->opp_table);
dev_pm_opp_of_remove_table(&genpd->dev);
}
@@ -2396,7 +2397,7 @@ int of_genpd_add_provider_onecell(struct device_node *np,
genpd->dev.of_node = np;
/* Parse genpd OPP table */
- if (genpd->set_performance_state) {
+ if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i);
if (ret) {
dev_err_probe(&genpd->dev, ret,
@@ -2432,7 +2433,7 @@ error:
genpd->provider = NULL;
genpd->has_provider = false;
- if (genpd->set_performance_state) {
+ if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
dev_pm_opp_put_opp_table(genpd->opp_table);
dev_pm_opp_of_remove_table(&genpd->dev);
}
@@ -2464,7 +2465,7 @@ void of_genpd_del_provider(struct device_node *np)
if (gpd->provider == &np->fwnode) {
gpd->has_provider = false;
- if (!gpd->set_performance_state)
+ if (genpd_is_opp_table_fw(gpd) || !gpd->set_performance_state)
continue;
dev_pm_opp_put_opp_table(gpd->opp_table);
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 63773a90581d..c51ea95bc2ce 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -39,8 +39,7 @@ static struct ktstate kts;
#ifndef MODULE
static int __init aoe_iflist_setup(char *str)
{
- strncpy(aoe_iflist, str, IFLISTSZ);
- aoe_iflist[IFLISTSZ - 1] = '\0';
+ strscpy(aoe_iflist, str, IFLISTSZ);
return 1;
}
diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
index 968090935eb2..22a3cf7f32e2 100644
--- a/drivers/block/null_blk/main.c
+++ b/drivers/block/null_blk/main.c
@@ -1750,6 +1750,25 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
return null_handle_cmd(cmd, sector, nr_sectors, req_op(rq));
}
+static void null_queue_rqs(struct request **rqlist)
+{
+ struct request *requeue_list = NULL;
+ struct request **requeue_lastp = &requeue_list;
+ struct blk_mq_queue_data bd = { };
+ blk_status_t ret;
+
+ do {
+ struct request *rq = rq_list_pop(rqlist);
+
+ bd.rq = rq;
+ ret = null_queue_rq(rq->mq_hctx, &bd);
+ if (ret != BLK_STS_OK)
+ rq_list_add_tail(&requeue_lastp, rq);
+ } while (!rq_list_empty(*rqlist));
+
+ *rqlist = requeue_list;
+}
+
static void cleanup_queue(struct nullb_queue *nq)
{
bitmap_free(nq->tag_map);
@@ -1802,6 +1821,7 @@ static int null_init_hctx(struct blk_mq_hw_ctx *hctx, void *driver_data,
static const struct blk_mq_ops null_mq_ops = {
.queue_rq = null_queue_rq,
+ .queue_rqs = null_queue_rqs,
.complete = null_complete_rq,
.timeout = null_timeout_rq,
.poll = null_poll,
@@ -1946,7 +1966,7 @@ static int null_gendisk_register(struct nullb *nullb)
else
disk->fops = &null_bio_ops;
disk->private_data = nullb;
- strncpy(disk->disk_name, nullb->disk_name, DISK_NAME_LEN);
+ strscpy_pad(disk->disk_name, nullb->disk_name, DISK_NAME_LEN);
if (nullb->dev->zoned) {
int ret = null_register_zoned_dev(nullb);
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 630ddfe6657b..83600b45e12a 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -75,6 +75,7 @@ struct ublk_rq_data {
struct ublk_uring_cmd_pdu {
struct ublk_queue *ubq;
+ u16 tag;
};
/*
@@ -115,6 +116,9 @@ struct ublk_uring_cmd_pdu {
*/
#define UBLK_IO_FLAG_NEED_GET_DATA 0x08
+/* atomic RW with ubq->cancel_lock */
+#define UBLK_IO_FLAG_CANCELED 0x80000000
+
struct ublk_io {
/* userspace buffer address from io cmd */
__u64 addr;
@@ -138,13 +142,13 @@ struct ublk_queue {
unsigned int max_io_sz;
bool force_abort;
bool timeout;
+ bool canceling;
unsigned short nr_io_ready; /* how many ios setup */
+ spinlock_t cancel_lock;
struct ublk_device *dev;
struct ublk_io ios[];
};
-#define UBLK_DAEMON_MONITOR_PERIOD (5 * HZ)
-
struct ublk_device {
struct gendisk *ub_disk;
@@ -166,7 +170,7 @@ struct ublk_device {
struct mutex mutex;
- spinlock_t mm_lock;
+ spinlock_t lock;
struct mm_struct *mm;
struct ublk_params params;
@@ -175,11 +179,6 @@ struct ublk_device {
unsigned int nr_queues_ready;
unsigned int nr_privileged_daemon;
- /*
- * Our ubq->daemon may be killed without any notification, so
- * monitor each queue's daemon periodically
- */
- struct delayed_work monitor_work;
struct work_struct quiesce_work;
struct work_struct stop_work;
};
@@ -190,10 +189,11 @@ struct ublk_params_header {
__u32 types;
};
+static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq);
+
static inline unsigned int ublk_req_build_flags(struct request *req);
static inline struct ublksrv_io_desc *ublk_get_iod(struct ublk_queue *ubq,
int tag);
-
static inline bool ublk_dev_is_user_copy(const struct ublk_device *ub)
{
return ub->dev_info.flags & UBLK_F_USER_COPY;
@@ -470,6 +470,7 @@ static DEFINE_MUTEX(ublk_ctl_mutex);
* It can be extended to one per-user limit in future or even controlled
* by cgroup.
*/
+#define UBLK_MAX_UBLKS UBLK_MINORS
static unsigned int ublks_max = 64;
static unsigned int ublks_added; /* protected by ublk_ctl_mutex */
@@ -1083,13 +1084,10 @@ static void __ublk_fail_req(struct ublk_queue *ubq, struct ublk_io *io,
{
WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_ACTIVE);
- if (!(io->flags & UBLK_IO_FLAG_ABORTED)) {
- io->flags |= UBLK_IO_FLAG_ABORTED;
- if (ublk_queue_can_use_recovery_reissue(ubq))
- blk_mq_requeue_request(req, false);
- else
- ublk_put_req_ref(ubq, req);
- }
+ if (ublk_queue_can_use_recovery_reissue(ubq))
+ blk_mq_requeue_request(req, false);
+ else
+ ublk_put_req_ref(ubq, req);
}
static void ubq_complete_io_cmd(struct ublk_io *io, int res,
@@ -1118,8 +1116,6 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq,
blk_mq_requeue_request(rq, false);
else
blk_mq_end_request(rq, BLK_STS_IOERR);
-
- mod_delayed_work(system_wq, &ubq->dev->monitor_work, 0);
}
static inline void __ublk_rq_task_work(struct request *req,
@@ -1212,15 +1208,6 @@ static inline void ublk_forward_io_cmds(struct ublk_queue *ubq,
__ublk_rq_task_work(blk_mq_rq_from_pdu(data), issue_flags);
}
-static inline void ublk_abort_io_cmds(struct ublk_queue *ubq)
-{
- struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds);
- struct ublk_rq_data *data, *tmp;
-
- llist_for_each_entry_safe(data, tmp, io_cmds, node)
- __ublk_abort_rq(ubq, blk_mq_rq_from_pdu(data));
-}
-
static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, unsigned issue_flags)
{
struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
@@ -1232,38 +1219,19 @@ static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, unsigned issue_flags)
static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq)
{
struct ublk_rq_data *data = blk_mq_rq_to_pdu(rq);
- struct ublk_io *io;
- if (!llist_add(&data->node, &ubq->io_cmds))
- return;
+ if (llist_add(&data->node, &ubq->io_cmds)) {
+ struct ublk_io *io = &ubq->ios[rq->tag];
- io = &ubq->ios[rq->tag];
- /*
- * If the check pass, we know that this is a re-issued request aborted
- * previously in monitor_work because the ubq_daemon(cmd's task) is
- * PF_EXITING. We cannot call io_uring_cmd_complete_in_task() anymore
- * because this ioucmd's io_uring context may be freed now if no inflight
- * ioucmd exists. Otherwise we may cause null-deref in ctx->fallback_work.
- *
- * Note: monitor_work sets UBLK_IO_FLAG_ABORTED and ends this request(releasing
- * the tag). Then the request is re-started(allocating the tag) and we are here.
- * Since releasing/allocating a tag implies smp_mb(), finding UBLK_IO_FLAG_ABORTED
- * guarantees that here is a re-issued request aborted previously.
- */
- if (unlikely(io->flags & UBLK_IO_FLAG_ABORTED)) {
- ublk_abort_io_cmds(ubq);
- } else {
- struct io_uring_cmd *cmd = io->cmd;
- struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
-
- pdu->ubq = ubq;
- io_uring_cmd_complete_in_task(cmd, ublk_rq_task_work_cb);
+ io_uring_cmd_complete_in_task(io->cmd, ublk_rq_task_work_cb);
}
}
static enum blk_eh_timer_return ublk_timeout(struct request *rq)
{
struct ublk_queue *ubq = rq->mq_hctx->driver_data;
+ unsigned int nr_inflight = 0;
+ int i;
if (ubq->flags & UBLK_F_UNPRIVILEGED_DEV) {
if (!ubq->timeout) {
@@ -1274,6 +1242,29 @@ static enum blk_eh_timer_return ublk_timeout(struct request *rq)
return BLK_EH_DONE;
}
+ if (!ubq_daemon_is_dying(ubq))
+ return BLK_EH_RESET_TIMER;
+
+ for (i = 0; i < ubq->q_depth; i++) {
+ struct ublk_io *io = &ubq->ios[i];
+
+ if (!(io->flags & UBLK_IO_FLAG_ACTIVE))
+ nr_inflight++;
+ }
+
+ /* cancelable uring_cmd can't help us if all commands are in-flight */
+ if (nr_inflight == ubq->q_depth) {
+ struct ublk_device *ub = ubq->dev;
+
+ if (ublk_abort_requests(ub, ubq)) {
+ if (ublk_can_use_recovery(ub))
+ schedule_work(&ub->quiesce_work);
+ else
+ schedule_work(&ub->stop_work);
+ }
+ return BLK_EH_DONE;
+ }
+
return BLK_EH_RESET_TIMER;
}
@@ -1301,13 +1292,12 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
if (ublk_queue_can_use_recovery(ubq) && unlikely(ubq->force_abort))
return BLK_STS_IOERR;
- blk_mq_start_request(bd->rq);
-
- if (unlikely(ubq_daemon_is_dying(ubq))) {
+ if (unlikely(ubq->canceling)) {
__ublk_abort_rq(ubq, rq);
return BLK_STS_OK;
}
+ blk_mq_start_request(bd->rq);
ublk_queue_cmd(ubq, rq);
return BLK_STS_OK;
@@ -1357,12 +1347,12 @@ static int ublk_ch_mmap(struct file *filp, struct vm_area_struct *vma)
unsigned long pfn, end, phys_off = vma->vm_pgoff << PAGE_SHIFT;
int q_id, ret = 0;
- spin_lock(&ub->mm_lock);
+ spin_lock(&ub->lock);
if (!ub->mm)
ub->mm = current->mm;
if (current->mm != ub->mm)
ret = -EINVAL;
- spin_unlock(&ub->mm_lock);
+ spin_unlock(&ub->lock);
if (ret)
return ret;
@@ -1411,17 +1401,14 @@ static void ublk_commit_completion(struct ublk_device *ub,
}
/*
- * When ->ubq_daemon is exiting, either new request is ended immediately,
- * or any queued io command is drained, so it is safe to abort queue
- * lockless
+ * Called from ubq_daemon context via cancel fn, meantime quiesce ublk
+ * blk-mq queue, so we are called exclusively with blk-mq and ubq_daemon
+ * context, so everything is serialized.
*/
static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq)
{
int i;
- if (!ublk_get_device(ub))
- return;
-
for (i = 0; i < ubq->q_depth; i++) {
struct ublk_io *io = &ubq->ios[i];
@@ -1433,72 +1420,114 @@ static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq)
* will do it
*/
rq = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], i);
- if (rq)
+ if (rq && blk_mq_request_started(rq)) {
+ io->flags |= UBLK_IO_FLAG_ABORTED;
__ublk_fail_req(ubq, io, rq);
+ }
}
}
- ublk_put_device(ub);
}
-static void ublk_daemon_monitor_work(struct work_struct *work)
+static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq)
{
- struct ublk_device *ub =
- container_of(work, struct ublk_device, monitor_work.work);
- int i;
+ struct gendisk *disk;
- for (i = 0; i < ub->dev_info.nr_hw_queues; i++) {
- struct ublk_queue *ubq = ublk_get_queue(ub, i);
+ spin_lock(&ubq->cancel_lock);
+ if (ubq->canceling) {
+ spin_unlock(&ubq->cancel_lock);
+ return false;
+ }
+ ubq->canceling = true;
+ spin_unlock(&ubq->cancel_lock);
- if (ubq_daemon_is_dying(ubq)) {
- if (ublk_queue_can_use_recovery(ubq))
- schedule_work(&ub->quiesce_work);
- else
- schedule_work(&ub->stop_work);
+ spin_lock(&ub->lock);
+ disk = ub->ub_disk;
+ if (disk)
+ get_device(disk_to_dev(disk));
+ spin_unlock(&ub->lock);
- /* abort queue is for making forward progress */
- ublk_abort_queue(ub, ubq);
- }
- }
+ /* Our disk has been dead */
+ if (!disk)
+ return false;
- /*
- * We can't schedule monitor work after ub's state is not UBLK_S_DEV_LIVE.
- * after ublk_remove() or __ublk_quiesce_dev() is started.
- *
- * No need ub->mutex, monitor work are canceled after state is marked
- * as not LIVE, so new state is observed reliably.
- */
- if (ub->dev_info.state == UBLK_S_DEV_LIVE)
- schedule_delayed_work(&ub->monitor_work,
- UBLK_DAEMON_MONITOR_PERIOD);
-}
+ /* Now we are serialized with ublk_queue_rq() */
+ blk_mq_quiesce_queue(disk->queue);
+ /* abort queue is for making forward progress */
+ ublk_abort_queue(ub, ubq);
+ blk_mq_unquiesce_queue(disk->queue);
+ put_device(disk_to_dev(disk));
-static inline bool ublk_queue_ready(struct ublk_queue *ubq)
-{
- return ubq->nr_io_ready == ubq->q_depth;
+ return true;
}
-static void ublk_cmd_cancel_cb(struct io_uring_cmd *cmd, unsigned issue_flags)
+static void ublk_cancel_cmd(struct ublk_queue *ubq, struct ublk_io *io,
+ unsigned int issue_flags)
{
- io_uring_cmd_done(cmd, UBLK_IO_RES_ABORT, 0, issue_flags);
+ bool done;
+
+ if (!(io->flags & UBLK_IO_FLAG_ACTIVE))
+ return;
+
+ spin_lock(&ubq->cancel_lock);
+ done = !!(io->flags & UBLK_IO_FLAG_CANCELED);
+ if (!done)
+ io->flags |= UBLK_IO_FLAG_CANCELED;
+ spin_unlock(&ubq->cancel_lock);
+
+ if (!done)
+ io_uring_cmd_done(io->cmd, UBLK_IO_RES_ABORT, 0, issue_flags);
}
-static void ublk_cancel_queue(struct ublk_queue *ubq)
+/*
+ * The ublk char device won't be closed when calling cancel fn, so both
+ * ublk device and queue are guaranteed to be live
+ */
+static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
{
- int i;
+ struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
+ struct ublk_queue *ubq = pdu->ubq;
+ struct task_struct *task;
+ struct ublk_device *ub;
+ bool need_schedule;
+ struct ublk_io *io;
- if (!ublk_queue_ready(ubq))
+ if (WARN_ON_ONCE(!ubq))
return;
- for (i = 0; i < ubq->q_depth; i++) {
- struct ublk_io *io = &ubq->ios[i];
+ if (WARN_ON_ONCE(pdu->tag >= ubq->q_depth))
+ return;
+
+ task = io_uring_cmd_get_task(cmd);
+ if (WARN_ON_ONCE(task && task != ubq->ubq_daemon))
+ return;
+
+ ub = ubq->dev;
+ need_schedule = ublk_abort_requests(ub, ubq);
+
+ io = &ubq->ios[pdu->tag];
+ WARN_ON_ONCE(io->cmd != cmd);
+ ublk_cancel_cmd(ubq, io, issue_flags);
- if (io->flags & UBLK_IO_FLAG_ACTIVE)
- io_uring_cmd_complete_in_task(io->cmd,
- ublk_cmd_cancel_cb);
+ if (need_schedule) {
+ if (ublk_can_use_recovery(ub))
+ schedule_work(&ub->quiesce_work);
+ else
+ schedule_work(&ub->stop_work);
}
+}
- /* all io commands are canceled */
- ubq->nr_io_ready = 0;
+static inline bool ublk_queue_ready(struct ublk_queue *ubq)
+{
+ return ubq->nr_io_ready == ubq->q_depth;
+}
+
+static void ublk_cancel_queue(struct ublk_queue *ubq)
+{
+ int i;
+
+ for (i = 0; i < ubq->q_depth; i++)
+ ublk_cancel_cmd(ubq, &ubq->ios[i], IO_URING_F_UNLOCKED);
}
/* Cancel all pending commands, must be called after del_gendisk() returns */
@@ -1545,16 +1574,6 @@ static void __ublk_quiesce_dev(struct ublk_device *ub)
blk_mq_quiesce_queue(ub->ub_disk->queue);
ublk_wait_tagset_rqs_idle(ub);
ub->dev_info.state = UBLK_S_DEV_QUIESCED;
- ublk_cancel_dev(ub);
- /* we are going to release task_struct of ubq_daemon and resets
- * ->ubq_daemon to NULL. So in monitor_work, check on ubq_daemon causes UAF.
- * Besides, monitor_work is not necessary in QUIESCED state since we have
- * already scheduled quiesce_work and quiesced all ubqs.
- *
- * Do not let monitor_work schedule itself if state it QUIESCED. And we cancel
- * it here and re-schedule it in END_USER_RECOVERY to avoid UAF.
- */
- cancel_delayed_work_sync(&ub->monitor_work);
}
static void ublk_quiesce_work_fn(struct work_struct *work)
@@ -1568,6 +1587,7 @@ static void ublk_quiesce_work_fn(struct work_struct *work)
__ublk_quiesce_dev(ub);
unlock:
mutex_unlock(&ub->mutex);
+ ublk_cancel_dev(ub);
}
static void ublk_unquiesce_dev(struct ublk_device *ub)
@@ -1593,6 +1613,8 @@ static void ublk_unquiesce_dev(struct ublk_device *ub)
static void ublk_stop_dev(struct ublk_device *ub)
{
+ struct gendisk *disk;
+
mutex_lock(&ub->mutex);
if (ub->dev_info.state == UBLK_S_DEV_DEAD)
goto unlock;
@@ -1602,14 +1624,18 @@ static void ublk_stop_dev(struct ublk_device *ub)
ublk_unquiesce_dev(ub);
}
del_gendisk(ub->ub_disk);
+
+ /* Sync with ublk_abort_queue() by holding the lock */
+ spin_lock(&ub->lock);
+ disk = ub->ub_disk;
ub->dev_info.state = UBLK_S_DEV_DEAD;
ub->dev_info.ublksrv_pid = -1;
- put_disk(ub->ub_disk);
ub->ub_disk = NULL;
+ spin_unlock(&ub->lock);
+ put_disk(disk);
unlock:
- ublk_cancel_dev(ub);
mutex_unlock(&ub->mutex);
- cancel_delayed_work_sync(&ub->monitor_work);
+ ublk_cancel_dev(ub);
}
/* device can only be started after all IOs are ready */
@@ -1660,6 +1686,21 @@ static inline void ublk_fill_io_cmd(struct ublk_io *io,
io->addr = buf_addr;
}
+static inline void ublk_prep_cancel(struct io_uring_cmd *cmd,
+ unsigned int issue_flags,
+ struct ublk_queue *ubq, unsigned int tag)
+{
+ struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
+
+ /*
+ * Safe to refer to @ubq since ublk_queue won't be died until its
+ * commands are completed
+ */
+ pdu->ubq = ubq;
+ pdu->tag = tag;
+ io_uring_cmd_mark_cancelable(cmd, issue_flags);
+}
+
static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
unsigned int issue_flags,
const struct ublksrv_io_cmd *ub_cmd)
@@ -1775,6 +1816,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
default:
goto out;
}
+ ublk_prep_cancel(cmd, issue_flags, ubq, tag);
return -EIOCBQUEUED;
out:
@@ -1814,7 +1856,8 @@ fail_put:
return NULL;
}
-static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
+static inline int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
{
/*
* Not necessary for async retry, but let's keep it simple and always
@@ -1828,9 +1871,33 @@ static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
.addr = READ_ONCE(ub_src->addr)
};
+ WARN_ON_ONCE(issue_flags & IO_URING_F_UNLOCKED);
+
return __ublk_ch_uring_cmd(cmd, issue_flags, &ub_cmd);
}
+static void ublk_ch_uring_cmd_cb(struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
+{
+ ublk_ch_uring_cmd_local(cmd, issue_flags);
+}
+
+static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
+{
+ if (unlikely(issue_flags & IO_URING_F_CANCEL)) {
+ ublk_uring_cmd_cancel_fn(cmd, issue_flags);
+ return 0;
+ }
+
+ /* well-implemented server won't run into unlocked */
+ if (unlikely(issue_flags & IO_URING_F_UNLOCKED)) {
+ io_uring_cmd_complete_in_task(cmd, ublk_ch_uring_cmd_cb);
+ return -EIOCBQUEUED;
+ }
+
+ return ublk_ch_uring_cmd_local(cmd, issue_flags);
+}
+
static inline bool ublk_check_ubuf_dir(const struct request *req,
int ubuf_dir)
{
@@ -1962,6 +2029,7 @@ static int ublk_init_queue(struct ublk_device *ub, int q_id)
void *ptr;
int size;
+ spin_lock_init(&ubq->cancel_lock);
ubq->flags = ub->dev_info.flags;
ubq->q_id = q_id;
ubq->q_depth = ub->dev_info.queue_depth;
@@ -2026,7 +2094,8 @@ static int ublk_alloc_dev_number(struct ublk_device *ub, int idx)
if (err == -ENOSPC)
err = -EEXIST;
} else {
- err = idr_alloc(&ublk_index_idr, ub, 0, 0, GFP_NOWAIT);
+ err = idr_alloc(&ublk_index_idr, ub, 0, UBLK_MAX_UBLKS,
+ GFP_NOWAIT);
}
spin_unlock(&ublk_idr_lock);
@@ -2151,8 +2220,6 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
if (wait_for_completion_interruptible(&ub->completion) != 0)
return -EINTR;
- schedule_delayed_work(&ub->monitor_work, UBLK_DAEMON_MONITOR_PERIOD);
-
mutex_lock(&ub->mutex);
if (ub->dev_info.state == UBLK_S_DEV_LIVE ||
test_bit(UB_STATE_USED, &ub->state)) {
@@ -2305,6 +2372,12 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
return -EINVAL;
}
+ if (header->dev_id != U32_MAX && header->dev_id >= UBLK_MAX_UBLKS) {
+ pr_warn("%s: dev id is too large. Max supported is %d\n",
+ __func__, UBLK_MAX_UBLKS - 1);
+ return -EINVAL;
+ }
+
ublk_dump_dev_info(&info);
ret = mutex_lock_killable(&ublk_ctl_mutex);
@@ -2320,10 +2393,9 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
if (!ub)
goto out_unlock;
mutex_init(&ub->mutex);
- spin_lock_init(&ub->mm_lock);
+ spin_lock_init(&ub->lock);
INIT_WORK(&ub->quiesce_work, ublk_quiesce_work_fn);
INIT_WORK(&ub->stop_work, ublk_stop_work_fn);
- INIT_DELAYED_WORK(&ub->monitor_work, ublk_daemon_monitor_work);
ret = ublk_alloc_dev_number(ub, header->dev_id);
if (ret < 0)
@@ -2569,13 +2641,15 @@ static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq)
int i;
WARN_ON_ONCE(!(ubq->ubq_daemon && ubq_daemon_is_dying(ubq)));
+
/* All old ioucmds have to be completed */
- WARN_ON_ONCE(ubq->nr_io_ready);
+ ubq->nr_io_ready = 0;
/* old daemon is PF_EXITING, put it now */
put_task_struct(ubq->ubq_daemon);
/* We have to reset it to NULL, otherwise ub won't accept new FETCH_REQ */
ubq->ubq_daemon = NULL;
ubq->timeout = false;
+ ubq->canceling = false;
for (i = 0; i < ubq->q_depth; i++) {
struct ublk_io *io = &ubq->ios[i];
@@ -2661,7 +2735,6 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
__func__, header->dev_id);
blk_mq_kick_requeue_list(ub->ub_disk->queue);
ub->dev_info.state = UBLK_S_DEV_LIVE;
- schedule_delayed_work(&ub->monitor_work, UBLK_DAEMON_MONITOR_PERIOD);
ret = 0;
out_unlock:
mutex_unlock(&ub->mutex);
@@ -2932,7 +3005,22 @@ static void __exit ublk_exit(void)
module_init(ublk_init);
module_exit(ublk_exit);
-module_param(ublks_max, int, 0444);
+static int ublk_set_max_ublks(const char *buf, const struct kernel_param *kp)
+{
+ return param_set_uint_minmax(buf, kp, 0, UBLK_MAX_UBLKS);
+}
+
+static int ublk_get_max_ublks(char *buf, const struct kernel_param *kp)
+{
+ return sysfs_emit(buf, "%u\n", ublks_max);
+}
+
+static const struct kernel_param_ops ublk_max_ublks_ops = {
+ .set = ublk_set_max_ublks,
+ .get = ublk_get_max_ublks,
+};
+
+module_param_cb(ublks_max, &ublk_max_ublks_ops, &ublks_max, 0644);
MODULE_PARM_DESC(ublks_max, "max number of ublk devices allowed to add(default: 64)");
MODULE_AUTHOR("Ming Lei <ming.lei@redhat.com>");
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 1fe011676d07..4689ac2e0c0e 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -470,8 +470,6 @@ static bool virtblk_prep_rq_batch(struct request *req)
struct virtio_blk *vblk = req->mq_hctx->queue->queuedata;
struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
- req->mq_hctx->tags->rqs[req->tag] = req;
-
return virtblk_prep_rq(req->mq_hctx, vblk, req, vbr) == BLK_STS_OK;
}
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index c98dd6ca2629..e6742998f372 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -31,7 +31,7 @@ config ARM_INTEGRATOR_LM
config BRCMSTB_GISB_ARB
tristate "Broadcom STB GISB bus arbiter"
- depends on ARM || ARM64 || MIPS
+ depends on ARCH_BRCMSTB || BMIPS_GENERIC
default ARCH_BRCMSTB || BMIPS_GENERIC
help
Driver for the Broadcom Set Top Box System-on-a-chip internal bus
diff --git a/drivers/bus/vexpress-config.c b/drivers/bus/vexpress-config.c
index c4e1becbb2d2..d2c7ada90186 100644
--- a/drivers/bus/vexpress-config.c
+++ b/drivers/bus/vexpress-config.c
@@ -54,7 +54,7 @@ struct vexpress_syscfg_func {
struct vexpress_syscfg *syscfg;
struct regmap *regmap;
int num_templates;
- u32 template[]; /* Keep it last! */
+ u32 template[] __counted_by(num_templates); /* Keep it last! */
};
struct vexpress_config_bridge_ops {
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index cc2839805983..a5e07270e0d4 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -3655,7 +3655,6 @@ static struct ctl_table cdrom_table[] = {
.mode = 0644,
.proc_handler = cdrom_sysctl_handler
},
- { }
};
static struct ctl_table_header *cdrom_sysctl_header;
diff --git a/drivers/cdx/cdx.c b/drivers/cdx/cdx.c
index d2cad4c670a0..9efb7584f952 100644
--- a/drivers/cdx/cdx.c
+++ b/drivers/cdx/cdx.c
@@ -182,6 +182,38 @@ cdx_match_id(const struct cdx_device_id *ids, struct cdx_device *dev)
return NULL;
}
+int cdx_set_master(struct cdx_device *cdx_dev)
+{
+ struct cdx_controller *cdx = cdx_dev->cdx;
+ struct cdx_device_config dev_config;
+ int ret = -EOPNOTSUPP;
+
+ dev_config.type = CDX_DEV_BUS_MASTER_CONF;
+ dev_config.bus_master_enable = true;
+ if (cdx->ops->dev_configure)
+ ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,
+ cdx_dev->dev_num, &dev_config);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(cdx_set_master);
+
+int cdx_clear_master(struct cdx_device *cdx_dev)
+{
+ struct cdx_controller *cdx = cdx_dev->cdx;
+ struct cdx_device_config dev_config;
+ int ret = -EOPNOTSUPP;
+
+ dev_config.type = CDX_DEV_BUS_MASTER_CONF;
+ dev_config.bus_master_enable = false;
+ if (cdx->ops->dev_configure)
+ ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,
+ cdx_dev->dev_num, &dev_config);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(cdx_clear_master);
+
/**
* cdx_bus_match - device to driver matching callback
* @dev: the cdx device to match against
diff --git a/drivers/cdx/controller/cdx_controller.c b/drivers/cdx/controller/cdx_controller.c
index bb4ae7970e21..7828dac8edb1 100644
--- a/drivers/cdx/controller/cdx_controller.c
+++ b/drivers/cdx/controller/cdx_controller.c
@@ -56,6 +56,10 @@ static int cdx_configure_device(struct cdx_controller *cdx,
case CDX_DEV_RESET_CONF:
ret = cdx_mcdi_reset_device(cdx->priv, bus_num, dev_num);
break;
+ case CDX_DEV_BUS_MASTER_CONF:
+ ret = cdx_mcdi_bus_master_enable(cdx->priv, bus_num, dev_num,
+ dev_config->bus_master_enable);
+ break;
default:
ret = -EINVAL;
}
diff --git a/drivers/cdx/controller/mcdi_functions.c b/drivers/cdx/controller/mcdi_functions.c
index 0158f26533dd..fc82435d5dea 100644
--- a/drivers/cdx/controller/mcdi_functions.c
+++ b/drivers/cdx/controller/mcdi_functions.c
@@ -137,3 +137,61 @@ int cdx_mcdi_reset_device(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num)
return ret;
}
+
+static int cdx_mcdi_ctrl_flag_get(struct cdx_mcdi *cdx, u8 bus_num,
+ u8 dev_num, u32 *flags)
+{
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_IN_LEN);
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN);
+ size_t outlen;
+ int ret;
+
+ MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_BUS, bus_num);
+ MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_DEVICE, dev_num);
+ ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_GET, inbuf,
+ sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
+ if (ret)
+ return ret;
+
+ if (outlen != MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN)
+ return -EIO;
+
+ *flags = MCDI_DWORD(outbuf, CDX_DEVICE_CONTROL_GET_OUT_FLAGS);
+
+ return 0;
+}
+
+static int cdx_mcdi_ctrl_flag_set(struct cdx_mcdi *cdx, u8 bus_num,
+ u8 dev_num, bool enable, int bit_pos)
+{
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_SET_IN_LEN);
+ u32 flags;
+ int ret;
+
+ /*
+ * Get flags and then set/reset bit at bit_pos according to
+ * the input params.
+ */
+ ret = cdx_mcdi_ctrl_flag_get(cdx, bus_num, dev_num, &flags);
+ if (ret)
+ return ret;
+
+ flags = flags & (u32)(~(BIT(bit_pos)));
+ if (enable)
+ flags |= (1 << bit_pos);
+
+ MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_BUS, bus_num);
+ MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_DEVICE, dev_num);
+ MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_FLAGS, flags);
+ ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_SET, inbuf,
+ sizeof(inbuf), NULL, 0, NULL);
+
+ return ret;
+}
+
+int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num,
+ u8 dev_num, bool enable)
+{
+ return cdx_mcdi_ctrl_flag_set(cdx, bus_num, dev_num, enable,
+ MC_CMD_CDX_DEVICE_CONTROL_SET_IN_BUS_MASTER_ENABLE_LBN);
+}
diff --git a/drivers/cdx/controller/mcdi_functions.h b/drivers/cdx/controller/mcdi_functions.h
index 7440ace5539a..a448d6581eb4 100644
--- a/drivers/cdx/controller/mcdi_functions.h
+++ b/drivers/cdx/controller/mcdi_functions.h
@@ -58,4 +58,17 @@ int cdx_mcdi_get_dev_config(struct cdx_mcdi *cdx,
int cdx_mcdi_reset_device(struct cdx_mcdi *cdx,
u8 bus_num, u8 dev_num);
+/**
+ * cdx_mcdi_bus_master_enable - Set/Reset bus mastering for cdx device
+ * represented by bus_num:dev_num
+ * @cdx: pointer to MCDI interface.
+ * @bus_num: Bus number.
+ * @dev_num: Device number.
+ * @enable: Enable bus mastering if set, disable otherwise.
+ *
+ * Return: 0 on success, <0 on failure
+ */
+int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num,
+ u8 dev_num, bool enable);
+
#endif /* CDX_MCDI_FUNCTIONS_H */
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 625af75833fc..7c8dd0abcfdf 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -348,7 +348,7 @@ config DEVPORT
device is similar to /dev/mem, but for I/O ports.
config HPET
- bool "HPET - High Precision Event Timer" if (X86 || IA64)
+ bool "HPET - High Precision Event Timer" if X86
default n
depends on ACPI
help
@@ -377,7 +377,7 @@ config HPET_MMAP_DEFAULT
config HANGCHECK_TIMER
tristate "Hangcheck timer"
- depends on X86 || IA64 || PPC64 || S390
+ depends on X86 || PPC64 || S390
help
The hangcheck-timer module detects when the system has gone
out to lunch past a certain margin. It can reboot the system
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index c5f532e412f1..e9b360cdc99a 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o
obj-y += misc.o
obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
-obj-$(CONFIG_MSPEC) += mspec.o
obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o
obj-$(CONFIG_IBM_BSR) += bsr.o
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 4f501e4842ab..c47eb7bf06d4 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
menuconfig AGP
tristate "/dev/agpgart (AGP Support)"
- depends on ALPHA || IA64 || PARISC || PPC || X86
+ depends on ALPHA || PARISC || PPC || X86
depends on PCI
help
AGP (Accelerated Graphics Port) is a bus system mainly used to
@@ -109,20 +109,6 @@ config AGP_VIA
This option gives you AGP support for the GLX component of
X on VIA MVP3/Apollo Pro chipsets.
-config AGP_I460
- tristate "Intel 460GX chipset support"
- depends on AGP && IA64
- help
- This option gives you AGP GART support for the Intel 460GX chipset
- for IA64 processors.
-
-config AGP_HP_ZX1
- tristate "HP ZX1 chipset AGP support"
- depends on AGP && IA64
- help
- This option gives you AGP GART support for the HP ZX1 chipset
- for IA64 processors.
-
config AGP_PARISC
tristate "HP Quicksilver AGP support"
depends on AGP && PARISC && 64BIT && IOMMU_SBA
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
index 90ed8c789e48..25834557e486 100644
--- a/drivers/char/agp/Makefile
+++ b/drivers/char/agp/Makefile
@@ -14,9 +14,7 @@ obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o
obj-$(CONFIG_AGP_AMD64) += amd64-agp.o
obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o
obj-$(CONFIG_AGP_EFFICEON) += efficeon-agp.o
-obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o
obj-$(CONFIG_AGP_PARISC) += parisc-agp.o
-obj-$(CONFIG_AGP_I460) += i460-agp.o
obj-$(CONFIG_AGP_INTEL) += intel-agp.o
obj-$(CONFIG_INTEL_GTT) += intel-gtt.o
obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
deleted file mode 100644
index 84d9adbb62f6..000000000000
--- a/drivers/char/agp/hp-agp.c
+++ /dev/null
@@ -1,550 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * HP zx1 AGPGART routines.
- *
- * (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P.
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- */
-
-#include <linux/acpi.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/agp_backend.h>
-#include <linux/log2.h>
-#include <linux/slab.h>
-
-#include <asm/acpi-ext.h>
-
-#include "agp.h"
-
-#define HP_ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */
-
-/* HP ZX1 IOC registers */
-#define HP_ZX1_IBASE 0x300
-#define HP_ZX1_IMASK 0x308
-#define HP_ZX1_PCOM 0x310
-#define HP_ZX1_TCNFG 0x318
-#define HP_ZX1_PDIR_BASE 0x320
-
-#define HP_ZX1_IOVA_BASE GB(1UL)
-#define HP_ZX1_IOVA_SIZE GB(1UL)
-#define HP_ZX1_GART_SIZE (HP_ZX1_IOVA_SIZE / 2)
-#define HP_ZX1_SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL
-
-#define HP_ZX1_PDIR_VALID_BIT 0x8000000000000000UL
-#define HP_ZX1_IOVA_TO_PDIR(va) ((va - hp_private.iova_base) >> hp_private.io_tlb_shift)
-
-#define AGP8X_MODE_BIT 3
-#define AGP8X_MODE (1 << AGP8X_MODE_BIT)
-
-/* AGP bridge need not be PCI device, but DRM thinks it is. */
-static struct pci_dev fake_bridge_dev;
-
-static int hp_zx1_gart_found;
-
-static struct aper_size_info_fixed hp_zx1_sizes[] =
-{
- {0, 0, 0}, /* filled in by hp_zx1_fetch_size() */
-};
-
-static struct gatt_mask hp_zx1_masks[] =
-{
- {.mask = HP_ZX1_PDIR_VALID_BIT, .type = 0}
-};
-
-static struct _hp_private {
- volatile u8 __iomem *ioc_regs;
- volatile u8 __iomem *lba_regs;
- int lba_cap_offset;
- u64 *io_pdir; // PDIR for entire IOVA
- u64 *gatt; // PDIR just for GART (subset of above)
- u64 gatt_entries;
- u64 iova_base;
- u64 gart_base;
- u64 gart_size;
- u64 io_pdir_size;
- int io_pdir_owner; // do we own it, or share it with sba_iommu?
- int io_page_size;
- int io_tlb_shift;
- int io_tlb_ps; // IOC ps config
- int io_pages_per_kpage;
-} hp_private;
-
-static int __init hp_zx1_ioc_shared(void)
-{
- struct _hp_private *hp = &hp_private;
-
- printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR shared with sba_iommu\n");
-
- /*
- * IOC already configured by sba_iommu module; just use
- * its setup. We assume:
- * - IOVA space is 1Gb in size
- * - first 512Mb is IOMMU, second 512Mb is GART
- */
- hp->io_tlb_ps = readq(hp->ioc_regs+HP_ZX1_TCNFG);
- switch (hp->io_tlb_ps) {
- case 0: hp->io_tlb_shift = 12; break;
- case 1: hp->io_tlb_shift = 13; break;
- case 2: hp->io_tlb_shift = 14; break;
- case 3: hp->io_tlb_shift = 16; break;
- default:
- printk(KERN_ERR PFX "Invalid IOTLB page size "
- "configuration 0x%x\n", hp->io_tlb_ps);
- hp->gatt = NULL;
- hp->gatt_entries = 0;
- return -ENODEV;
- }
- hp->io_page_size = 1 << hp->io_tlb_shift;
- hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
-
- hp->iova_base = readq(hp->ioc_regs+HP_ZX1_IBASE) & ~0x1;
- hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE;
-
- hp->gart_size = HP_ZX1_GART_SIZE;
- hp->gatt_entries = hp->gart_size / hp->io_page_size;
-
- hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
- hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
-
- if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
- /* Normal case when no AGP device in system */
- hp->gatt = NULL;
- hp->gatt_entries = 0;
- printk(KERN_ERR PFX "No reserved IO PDIR entry found; "
- "GART disabled\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int __init
-hp_zx1_ioc_owner (void)
-{
- struct _hp_private *hp = &hp_private;
-
- printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR dedicated to GART\n");
-
- /*
- * Select an IOV page size no larger than system page size.
- */
- if (PAGE_SIZE >= KB(64)) {
- hp->io_tlb_shift = 16;
- hp->io_tlb_ps = 3;
- } else if (PAGE_SIZE >= KB(16)) {
- hp->io_tlb_shift = 14;
- hp->io_tlb_ps = 2;
- } else if (PAGE_SIZE >= KB(8)) {
- hp->io_tlb_shift = 13;
- hp->io_tlb_ps = 1;
- } else {
- hp->io_tlb_shift = 12;
- hp->io_tlb_ps = 0;
- }
- hp->io_page_size = 1 << hp->io_tlb_shift;
- hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
-
- hp->iova_base = HP_ZX1_IOVA_BASE;
- hp->gart_size = HP_ZX1_GART_SIZE;
- hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - hp->gart_size;
-
- hp->gatt_entries = hp->gart_size / hp->io_page_size;
- hp->io_pdir_size = (HP_ZX1_IOVA_SIZE / hp->io_page_size) * sizeof(u64);
-
- return 0;
-}
-
-static int __init
-hp_zx1_ioc_init (u64 hpa)
-{
- struct _hp_private *hp = &hp_private;
-
- hp->ioc_regs = ioremap(hpa, 1024);
- if (!hp->ioc_regs)
- return -ENOMEM;
-
- /*
- * If the IOTLB is currently disabled, we can take it over.
- * Otherwise, we have to share with sba_iommu.
- */
- hp->io_pdir_owner = (readq(hp->ioc_regs+HP_ZX1_IBASE) & 0x1) == 0;
-
- if (hp->io_pdir_owner)
- return hp_zx1_ioc_owner();
-
- return hp_zx1_ioc_shared();
-}
-
-static int
-hp_zx1_lba_find_capability (volatile u8 __iomem *hpa, int cap)
-{
- u16 status;
- u8 pos, id;
- int ttl = 48;
-
- status = readw(hpa+PCI_STATUS);
- if (!(status & PCI_STATUS_CAP_LIST))
- return 0;
- pos = readb(hpa+PCI_CAPABILITY_LIST);
- while (ttl-- && pos >= 0x40) {
- pos &= ~3;
- id = readb(hpa+pos+PCI_CAP_LIST_ID);
- if (id == 0xff)
- break;
- if (id == cap)
- return pos;
- pos = readb(hpa+pos+PCI_CAP_LIST_NEXT);
- }
- return 0;
-}
-
-static int __init
-hp_zx1_lba_init (u64 hpa)
-{
- struct _hp_private *hp = &hp_private;
- int cap;
-
- hp->lba_regs = ioremap(hpa, 256);
- if (!hp->lba_regs)
- return -ENOMEM;
-
- hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP);
-
- cap = readl(hp->lba_regs+hp->lba_cap_offset) & 0xff;
- if (cap != PCI_CAP_ID_AGP) {
- printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
- cap, hp->lba_cap_offset);
- iounmap(hp->lba_regs);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int
-hp_zx1_fetch_size(void)
-{
- int size;
-
- size = hp_private.gart_size / MB(1);
- hp_zx1_sizes[0].size = size;
- agp_bridge->current_size = (void *) &hp_zx1_sizes[0];
- return size;
-}
-
-static int
-hp_zx1_configure (void)
-{
- struct _hp_private *hp = &hp_private;
-
- agp_bridge->gart_bus_addr = hp->gart_base;
- agp_bridge->capndx = hp->lba_cap_offset;
- agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
-
- if (hp->io_pdir_owner) {
- writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
- readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
- writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
- readl(hp->ioc_regs+HP_ZX1_TCNFG);
- writel((unsigned int)(~(HP_ZX1_IOVA_SIZE-1)), hp->ioc_regs+HP_ZX1_IMASK);
- readl(hp->ioc_regs+HP_ZX1_IMASK);
- writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE);
- readl(hp->ioc_regs+HP_ZX1_IBASE);
- writel(hp->iova_base|ilog2(HP_ZX1_IOVA_SIZE), hp->ioc_regs+HP_ZX1_PCOM);
- readl(hp->ioc_regs+HP_ZX1_PCOM);
- }
-
- return 0;
-}
-
-static void
-hp_zx1_cleanup (void)
-{
- struct _hp_private *hp = &hp_private;
-
- if (hp->ioc_regs) {
- if (hp->io_pdir_owner) {
- writeq(0, hp->ioc_regs+HP_ZX1_IBASE);
- readq(hp->ioc_regs+HP_ZX1_IBASE);
- }
- iounmap(hp->ioc_regs);
- }
- if (hp->lba_regs)
- iounmap(hp->lba_regs);
-}
-
-static void
-hp_zx1_tlbflush (struct agp_memory *mem)
-{
- struct _hp_private *hp = &hp_private;
-
- writeq(hp->gart_base | ilog2(hp->gart_size), hp->ioc_regs+HP_ZX1_PCOM);
- readq(hp->ioc_regs+HP_ZX1_PCOM);
-}
-
-static int
-hp_zx1_create_gatt_table (struct agp_bridge_data *bridge)
-{
- struct _hp_private *hp = &hp_private;
- int i;
-
- if (hp->io_pdir_owner) {
- hp->io_pdir = (u64 *) __get_free_pages(GFP_KERNEL,
- get_order(hp->io_pdir_size));
- if (!hp->io_pdir) {
- printk(KERN_ERR PFX "Couldn't allocate contiguous "
- "memory for I/O PDIR\n");
- hp->gatt = NULL;
- hp->gatt_entries = 0;
- return -ENOMEM;
- }
- memset(hp->io_pdir, 0, hp->io_pdir_size);
-
- hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
- }
-
- for (i = 0; i < hp->gatt_entries; i++) {
- hp->gatt[i] = (unsigned long) agp_bridge->scratch_page;
- }
-
- return 0;
-}
-
-static int
-hp_zx1_free_gatt_table (struct agp_bridge_data *bridge)
-{
- struct _hp_private *hp = &hp_private;
-
- if (hp->io_pdir_owner)
- free_pages((unsigned long) hp->io_pdir,
- get_order(hp->io_pdir_size));
- else
- hp->gatt[0] = HP_ZX1_SBA_IOMMU_COOKIE;
- return 0;
-}
-
-static int
-hp_zx1_insert_memory (struct agp_memory *mem, off_t pg_start, int type)
-{
- struct _hp_private *hp = &hp_private;
- int i, k;
- off_t j, io_pg_start;
- int io_pg_count;
-
- if (type != mem->type ||
- agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
- return -EINVAL;
- }
-
- io_pg_start = hp->io_pages_per_kpage * pg_start;
- io_pg_count = hp->io_pages_per_kpage * mem->page_count;
- if ((io_pg_start + io_pg_count) > hp->gatt_entries) {
- return -EINVAL;
- }
-
- j = io_pg_start;
- while (j < (io_pg_start + io_pg_count)) {
- if (hp->gatt[j]) {
- return -EBUSY;
- }
- j++;
- }
-
- if (!mem->is_flushed) {
- global_cache_flush();
- mem->is_flushed = true;
- }
-
- for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
- unsigned long paddr;
-
- paddr = page_to_phys(mem->pages[i]);
- for (k = 0;
- k < hp->io_pages_per_kpage;
- k++, j++, paddr += hp->io_page_size) {
- hp->gatt[j] = HP_ZX1_PDIR_VALID_BIT | paddr;
- }
- }
-
- agp_bridge->driver->tlb_flush(mem);
- return 0;
-}
-
-static int
-hp_zx1_remove_memory (struct agp_memory *mem, off_t pg_start, int type)
-{
- struct _hp_private *hp = &hp_private;
- int i, io_pg_start, io_pg_count;
-
- if (type != mem->type ||
- agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
- return -EINVAL;
- }
-
- io_pg_start = hp->io_pages_per_kpage * pg_start;
- io_pg_count = hp->io_pages_per_kpage * mem->page_count;
- for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
- hp->gatt[i] = agp_bridge->scratch_page;
- }
-
- agp_bridge->driver->tlb_flush(mem);
- return 0;
-}
-
-static unsigned long
-hp_zx1_mask_memory (struct agp_bridge_data *bridge, dma_addr_t addr, int type)
-{
- return HP_ZX1_PDIR_VALID_BIT | addr;
-}
-
-static void
-hp_zx1_enable (struct agp_bridge_data *bridge, u32 mode)
-{
- struct _hp_private *hp = &hp_private;
- u32 command;
-
- command = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
- command = agp_collect_device_status(bridge, mode, command);
- command |= 0x00000100;
-
- writel(command, hp->lba_regs+hp->lba_cap_offset+PCI_AGP_COMMAND);
-
- agp_device_command(command, (mode & AGP8X_MODE) != 0);
-}
-
-const struct agp_bridge_driver hp_zx1_driver = {
- .owner = THIS_MODULE,
- .size_type = FIXED_APER_SIZE,
- .configure = hp_zx1_configure,
- .fetch_size = hp_zx1_fetch_size,
- .cleanup = hp_zx1_cleanup,
- .tlb_flush = hp_zx1_tlbflush,
- .mask_memory = hp_zx1_mask_memory,
- .masks = hp_zx1_masks,
- .agp_enable = hp_zx1_enable,
- .cache_flush = global_cache_flush,
- .create_gatt_table = hp_zx1_create_gatt_table,
- .free_gatt_table = hp_zx1_free_gatt_table,
- .insert_memory = hp_zx1_insert_memory,
- .remove_memory = hp_zx1_remove_memory,
- .alloc_by_type = agp_generic_alloc_by_type,
- .free_by_type = agp_generic_free_by_type,
- .agp_alloc_page = agp_generic_alloc_page,
- .agp_alloc_pages = agp_generic_alloc_pages,
- .agp_destroy_page = agp_generic_destroy_page,
- .agp_destroy_pages = agp_generic_destroy_pages,
- .agp_type_to_mask_type = agp_generic_type_to_mask_type,
- .cant_use_aperture = true,
-};
-
-static int __init
-hp_zx1_setup (u64 ioc_hpa, u64 lba_hpa)
-{
- struct agp_bridge_data *bridge;
- int error = 0;
-
- error = hp_zx1_ioc_init(ioc_hpa);
- if (error)
- goto fail;
-
- error = hp_zx1_lba_init(lba_hpa);
- if (error)
- goto fail;
-
- bridge = agp_alloc_bridge();
- if (!bridge) {
- error = -ENOMEM;
- goto fail;
- }
- bridge->driver = &hp_zx1_driver;
-
- fake_bridge_dev.vendor = PCI_VENDOR_ID_HP;
- fake_bridge_dev.device = PCI_DEVICE_ID_HP_PCIX_LBA;
- bridge->dev = &fake_bridge_dev;
-
- error = agp_add_bridge(bridge);
- fail:
- if (error)
- hp_zx1_cleanup();
- return error;
-}
-
-static acpi_status __init
-zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret)
-{
- acpi_handle handle, parent;
- acpi_status status;
- struct acpi_device_info *info;
- u64 lba_hpa, sba_hpa, length;
- int match;
-
- status = hp_acpi_csr_space(obj, &lba_hpa, &length);
- if (ACPI_FAILURE(status))
- return AE_OK; /* keep looking for another bridge */
-
- /* Look for an enclosing IOC scope and find its CSR space */
- handle = obj;
- do {
- status = acpi_get_object_info(handle, &info);
- if (ACPI_SUCCESS(status) && (info->valid & ACPI_VALID_HID)) {
- /* TBD check _CID also */
- match = (strcmp(info->hardware_id.string, "HWP0001") == 0);
- kfree(info);
- if (match) {
- status = hp_acpi_csr_space(handle, &sba_hpa, &length);
- if (ACPI_SUCCESS(status))
- break;
- else {
- printk(KERN_ERR PFX "Detected HP ZX1 "
- "AGP LBA but no IOC.\n");
- return AE_OK;
- }
- }
- }
-
- status = acpi_get_parent(handle, &parent);
- handle = parent;
- } while (ACPI_SUCCESS(status));
-
- if (ACPI_FAILURE(status))
- return AE_OK; /* found no enclosing IOC */
-
- if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa))
- return AE_OK;
-
- printk(KERN_INFO PFX "Detected HP ZX1 %s AGP chipset "
- "(ioc=%llx, lba=%llx)\n", (char *)context,
- sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa);
-
- hp_zx1_gart_found = 1;
- return AE_CTRL_TERMINATE; /* we only support one bridge; quit looking */
-}
-
-static int __init
-agp_hp_init (void)
-{
- if (agp_off)
- return -EINVAL;
-
- acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003", NULL);
- if (hp_zx1_gart_found)
- return 0;
-
- acpi_get_devices("HWP0007", zx1_gart_probe, "HWP0007", NULL);
- if (hp_zx1_gart_found)
- return 0;
-
- return -ENODEV;
-}
-
-static void __exit
-agp_hp_cleanup (void)
-{
-}
-
-module_init(agp_hp_init);
-module_exit(agp_hp_cleanup);
-
-MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
deleted file mode 100644
index 15b240ea4848..000000000000
--- a/drivers/char/agp/i460-agp.c
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * For documentation on the i460 AGP interface, see Chapter 7 (AGP Subsystem) of
- * the "Intel 460GTX Chipset Software Developer's Manual":
- * http://www.intel.com/design/archives/itanium/downloads/248704.htm
- */
-/*
- * 460GX support by Chris Ahna <christopher.j.ahna@intel.com>
- * Clean up & simplification by David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/agp_backend.h>
-#include <linux/log2.h>
-
-#include "agp.h"
-
-#define INTEL_I460_BAPBASE 0x98
-#define INTEL_I460_GXBCTL 0xa0
-#define INTEL_I460_AGPSIZ 0xa2
-#define INTEL_I460_ATTBASE 0xfe200000
-#define INTEL_I460_GATT_VALID (1UL << 24)
-#define INTEL_I460_GATT_COHERENT (1UL << 25)
-
-/*
- * The i460 can operate with large (4MB) pages, but there is no sane way to support this
- * within the current kernel/DRM environment, so we disable the relevant code for now.
- * See also comments in ia64_alloc_page()...
- */
-#define I460_LARGE_IO_PAGES 0
-
-#if I460_LARGE_IO_PAGES
-# define I460_IO_PAGE_SHIFT i460.io_page_shift
-#else
-# define I460_IO_PAGE_SHIFT 12
-#endif
-
-#define I460_IOPAGES_PER_KPAGE (PAGE_SIZE >> I460_IO_PAGE_SHIFT)
-#define I460_KPAGES_PER_IOPAGE (1 << (I460_IO_PAGE_SHIFT - PAGE_SHIFT))
-#define I460_SRAM_IO_DISABLE (1 << 4)
-#define I460_BAPBASE_ENABLE (1 << 3)
-#define I460_AGPSIZ_MASK 0x7
-#define I460_4M_PS (1 << 1)
-
-/* Control bits for Out-Of-GART coherency and Burst Write Combining */
-#define I460_GXBCTL_OOG (1UL << 0)
-#define I460_GXBCTL_BWC (1UL << 2)
-
-/*
- * gatt_table entries are 32-bits wide on the i460; the generic code ought to declare the
- * gatt_table and gatt_table_real pointers a "void *"...
- */
-#define RD_GATT(index) readl((u32 *) i460.gatt + (index))
-#define WR_GATT(index, val) writel((val), (u32 *) i460.gatt + (index))
-/*
- * The 460 spec says we have to read the last location written to make sure that all
- * writes have taken effect
- */
-#define WR_FLUSH_GATT(index) RD_GATT(index)
-
-static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
- dma_addr_t addr, int type);
-
-static struct {
- void *gatt; /* ioremap'd GATT area */
-
- /* i460 supports multiple GART page sizes, so GART pageshift is dynamic: */
- u8 io_page_shift;
-
- /* BIOS configures chipset to one of 2 possible apbase values: */
- u8 dynamic_apbase;
-
- /* structure for tracking partial use of 4MB GART pages: */
- struct lp_desc {
- unsigned long *alloced_map; /* bitmap of kernel-pages in use */
- int refcount; /* number of kernel pages using the large page */
- u64 paddr; /* physical address of large page */
- struct page *page; /* page pointer */
- } *lp_desc;
-} i460;
-
-static const struct aper_size_info_8 i460_sizes[3] =
-{
- /*
- * The 32GB aperture is only available with a 4M GART page size. Due to the
- * dynamic GART page size, we can't figure out page_order or num_entries until
- * runtime.
- */
- {32768, 0, 0, 4},
- {1024, 0, 0, 2},
- {256, 0, 0, 1}
-};
-
-static struct gatt_mask i460_masks[] =
-{
- {
- .mask = INTEL_I460_GATT_VALID | INTEL_I460_GATT_COHERENT,
- .type = 0
- }
-};
-
-static int i460_fetch_size (void)
-{
- int i;
- u8 temp;
- struct aper_size_info_8 *values;
-
- /* Determine the GART page size */
- pci_read_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL, &temp);
- i460.io_page_shift = (temp & I460_4M_PS) ? 22 : 12;
- pr_debug("i460_fetch_size: io_page_shift=%d\n", i460.io_page_shift);
-
- if (i460.io_page_shift != I460_IO_PAGE_SHIFT) {
- printk(KERN_ERR PFX
- "I/O (GART) page-size %luKB doesn't match expected "
- "size %luKB\n",
- 1UL << (i460.io_page_shift - 10),
- 1UL << (I460_IO_PAGE_SHIFT));
- return 0;
- }
-
- values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
-
- pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp);
-
- /* Exit now if the IO drivers for the GART SRAMS are turned off */
- if (temp & I460_SRAM_IO_DISABLE) {
- printk(KERN_ERR PFX "GART SRAMS disabled on 460GX chipset\n");
- printk(KERN_ERR PFX "AGPGART operation not possible\n");
- return 0;
- }
-
- /* Make sure we don't try to create an 2 ^ 23 entry GATT */
- if ((i460.io_page_shift == 0) && ((temp & I460_AGPSIZ_MASK) == 4)) {
- printk(KERN_ERR PFX "We can't have a 32GB aperture with 4KB GART pages\n");
- return 0;
- }
-
- /* Determine the proper APBASE register */
- if (temp & I460_BAPBASE_ENABLE)
- i460.dynamic_apbase = INTEL_I460_BAPBASE;
- else
- i460.dynamic_apbase = AGP_APBASE;
-
- for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
- /*
- * Dynamically calculate the proper num_entries and page_order values for
- * the define aperture sizes. Take care not to shift off the end of
- * values[i].size.
- */
- values[i].num_entries = (values[i].size << 8) >> (I460_IO_PAGE_SHIFT - 12);
- values[i].page_order = ilog2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT);
- }
-
- for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
- /* Neglect control bits when matching up size_value */
- if ((temp & I460_AGPSIZ_MASK) == values[i].size_value) {
- agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
- agp_bridge->aperture_size_idx = i;
- return values[i].size;
- }
- }
-
- return 0;
-}
-
-/* There isn't anything to do here since 460 has no GART TLB. */
-static void i460_tlb_flush (struct agp_memory *mem)
-{
- return;
-}
-
-/*
- * This utility function is needed to prevent corruption of the control bits
- * which are stored along with the aperture size in 460's AGPSIZ register
- */
-static void i460_write_agpsiz (u8 size_value)
-{
- u8 temp;
-
- pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp);
- pci_write_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ,
- ((temp & ~I460_AGPSIZ_MASK) | size_value));
-}
-
-static void i460_cleanup (void)
-{
- struct aper_size_info_8 *previous_size;
-
- previous_size = A_SIZE_8(agp_bridge->previous_size);
- i460_write_agpsiz(previous_size->size_value);
-
- if (I460_IO_PAGE_SHIFT > PAGE_SHIFT)
- kfree(i460.lp_desc);
-}
-
-static int i460_configure (void)
-{
- union {
- u32 small[2];
- u64 large;
- } temp;
- size_t size;
- u8 scratch;
- struct aper_size_info_8 *current_size;
-
- temp.large = 0;
-
- current_size = A_SIZE_8(agp_bridge->current_size);
- i460_write_agpsiz(current_size->size_value);
-
- /*
- * Do the necessary rigmarole to read all eight bytes of APBASE.
- * This has to be done since the AGP aperture can be above 4GB on
- * 460 based systems.
- */
- pci_read_config_dword(agp_bridge->dev, i460.dynamic_apbase, &(temp.small[0]));
- pci_read_config_dword(agp_bridge->dev, i460.dynamic_apbase + 4, &(temp.small[1]));
-
- /* Clear BAR control bits */
- agp_bridge->gart_bus_addr = temp.large & ~((1UL << 3) - 1);
-
- pci_read_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL, &scratch);
- pci_write_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL,
- (scratch & 0x02) | I460_GXBCTL_OOG | I460_GXBCTL_BWC);
-
- /*
- * Initialize partial allocation trackers if a GART page is bigger than a kernel
- * page.
- */
- if (I460_IO_PAGE_SHIFT > PAGE_SHIFT) {
- size = current_size->num_entries * sizeof(i460.lp_desc[0]);
- i460.lp_desc = kzalloc(size, GFP_KERNEL);
- if (!i460.lp_desc)
- return -ENOMEM;
- }
- return 0;
-}
-
-static int i460_create_gatt_table (struct agp_bridge_data *bridge)
-{
- int page_order, num_entries, i;
- void *temp;
-
- /*
- * Load up the fixed address of the GART SRAMS which hold our GATT table.
- */
- temp = agp_bridge->current_size;
- page_order = A_SIZE_8(temp)->page_order;
- num_entries = A_SIZE_8(temp)->num_entries;
-
- i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order);
- if (!i460.gatt) {
- printk(KERN_ERR PFX "ioremap failed\n");
- return -ENOMEM;
- }
-
- /* These are no good, the should be removed from the agp_bridge strucure... */
- agp_bridge->gatt_table_real = NULL;
- agp_bridge->gatt_table = NULL;
- agp_bridge->gatt_bus_addr = 0;
-
- for (i = 0; i < num_entries; ++i)
- WR_GATT(i, 0);
- WR_FLUSH_GATT(i - 1);
- return 0;
-}
-
-static int i460_free_gatt_table (struct agp_bridge_data *bridge)
-{
- int num_entries, i;
- void *temp;
-
- temp = agp_bridge->current_size;
-
- num_entries = A_SIZE_8(temp)->num_entries;
-
- for (i = 0; i < num_entries; ++i)
- WR_GATT(i, 0);
- WR_FLUSH_GATT(num_entries - 1);
-
- iounmap(i460.gatt);
- return 0;
-}
-
-/*
- * The following functions are called when the I/O (GART) page size is smaller than
- * PAGE_SIZE.
- */
-
-static int i460_insert_memory_small_io_page (struct agp_memory *mem,
- off_t pg_start, int type)
-{
- unsigned long paddr, io_pg_start, io_page_size;
- int i, j, k, num_entries;
- void *temp;
-
- pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n",
- mem, pg_start, type, page_to_phys(mem->pages[0]));
-
- if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
- return -EINVAL;
-
- io_pg_start = I460_IOPAGES_PER_KPAGE * pg_start;
-
- temp = agp_bridge->current_size;
- num_entries = A_SIZE_8(temp)->num_entries;
-
- if ((io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count) > num_entries) {
- printk(KERN_ERR PFX "Looks like we're out of AGP memory\n");
- return -EINVAL;
- }
-
- j = io_pg_start;
- while (j < (io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count)) {
- if (!PGE_EMPTY(agp_bridge, RD_GATT(j))) {
- pr_debug("i460_insert_memory_small_io_page: GATT[%d]=0x%x is busy\n",
- j, RD_GATT(j));
- return -EBUSY;
- }
- j++;
- }
-
- io_page_size = 1UL << I460_IO_PAGE_SHIFT;
- for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
- paddr = page_to_phys(mem->pages[i]);
- for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size)
- WR_GATT(j, i460_mask_memory(agp_bridge, paddr, mem->type));
- }
- WR_FLUSH_GATT(j - 1);
- return 0;
-}
-
-static int i460_remove_memory_small_io_page(struct agp_memory *mem,
- off_t pg_start, int type)
-{
- int i;
-
- pr_debug("i460_remove_memory_small_io_page(mem=%p, pg_start=%ld, type=%d)\n",
- mem, pg_start, type);
-
- pg_start = I460_IOPAGES_PER_KPAGE * pg_start;
-
- for (i = pg_start; i < (pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count); i++)
- WR_GATT(i, 0);
- WR_FLUSH_GATT(i - 1);
- return 0;
-}
-
-#if I460_LARGE_IO_PAGES
-
-/*
- * These functions are called when the I/O (GART) page size exceeds PAGE_SIZE.
- *
- * This situation is interesting since AGP memory allocations that are smaller than a
- * single GART page are possible. The i460.lp_desc array tracks partial allocation of the
- * large GART pages to work around this issue.
- *
- * i460.lp_desc[pg_num].refcount tracks the number of kernel pages in use within GART page
- * pg_num. i460.lp_desc[pg_num].paddr is the physical address of the large page and
- * i460.lp_desc[pg_num].alloced_map is a bitmap of kernel pages that are in use (allocated).
- */
-
-static int i460_alloc_large_page (struct lp_desc *lp)
-{
- unsigned long order = I460_IO_PAGE_SHIFT - PAGE_SHIFT;
- size_t map_size;
-
- lp->page = alloc_pages(GFP_KERNEL, order);
- if (!lp->page) {
- printk(KERN_ERR PFX "Couldn't alloc 4M GART page...\n");
- return -ENOMEM;
- }
-
- map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8;
- lp->alloced_map = kzalloc(map_size, GFP_KERNEL);
- if (!lp->alloced_map) {
- __free_pages(lp->page, order);
- printk(KERN_ERR PFX "Out of memory, we're in trouble...\n");
- return -ENOMEM;
- }
-
- lp->paddr = page_to_phys(lp->page);
- lp->refcount = 0;
- atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
- return 0;
-}
-
-static void i460_free_large_page (struct lp_desc *lp)
-{
- kfree(lp->alloced_map);
- lp->alloced_map = NULL;
-
- __free_pages(lp->page, I460_IO_PAGE_SHIFT - PAGE_SHIFT);
- atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
-}
-
-static int i460_insert_memory_large_io_page (struct agp_memory *mem,
- off_t pg_start, int type)
-{
- int i, start_offset, end_offset, idx, pg, num_entries;
- struct lp_desc *start, *end, *lp;
- void *temp;
-
- if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
- return -EINVAL;
-
- temp = agp_bridge->current_size;
- num_entries = A_SIZE_8(temp)->num_entries;
-
- /* Figure out what pg_start means in terms of our large GART pages */
- start = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE];
- end = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE];
- start_offset = pg_start % I460_KPAGES_PER_IOPAGE;
- end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE;
-
- if (end > i460.lp_desc + num_entries) {
- printk(KERN_ERR PFX "Looks like we're out of AGP memory\n");
- return -EINVAL;
- }
-
- /* Check if the requested region of the aperture is free */
- for (lp = start; lp <= end; ++lp) {
- if (!lp->alloced_map)
- continue; /* OK, the entire large page is available... */
-
- for (idx = ((lp == start) ? start_offset : 0);
- idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
- idx++)
- {
- if (test_bit(idx, lp->alloced_map))
- return -EBUSY;
- }
- }
-
- for (lp = start, i = 0; lp <= end; ++lp) {
- if (!lp->alloced_map) {
- /* Allocate new GART pages... */
- if (i460_alloc_large_page(lp) < 0)
- return -ENOMEM;
- pg = lp - i460.lp_desc;
- WR_GATT(pg, i460_mask_memory(agp_bridge,
- lp->paddr, 0));
- WR_FLUSH_GATT(pg);
- }
-
- for (idx = ((lp == start) ? start_offset : 0);
- idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
- idx++, i++)
- {
- mem->pages[i] = lp->page;
- __set_bit(idx, lp->alloced_map);
- ++lp->refcount;
- }
- }
- return 0;
-}
-
-static int i460_remove_memory_large_io_page (struct agp_memory *mem,
- off_t pg_start, int type)
-{
- int i, pg, start_offset, end_offset, idx, num_entries;
- struct lp_desc *start, *end, *lp;
- void *temp;
-
- temp = agp_bridge->current_size;
- num_entries = A_SIZE_8(temp)->num_entries;
-
- /* Figure out what pg_start means in terms of our large GART pages */
- start = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE];
- end = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE];
- start_offset = pg_start % I460_KPAGES_PER_IOPAGE;
- end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE;
-
- for (i = 0, lp = start; lp <= end; ++lp) {
- for (idx = ((lp == start) ? start_offset : 0);
- idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
- idx++, i++)
- {
- mem->pages[i] = NULL;
- __clear_bit(idx, lp->alloced_map);
- --lp->refcount;
- }
-
- /* Free GART pages if they are unused */
- if (lp->refcount == 0) {
- pg = lp - i460.lp_desc;
- WR_GATT(pg, 0);
- WR_FLUSH_GATT(pg);
- i460_free_large_page(lp);
- }
- }
- return 0;
-}
-
-/* Wrapper routines to call the approriate {small_io_page,large_io_page} function */
-
-static int i460_insert_memory (struct agp_memory *mem,
- off_t pg_start, int type)
-{
- if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
- return i460_insert_memory_small_io_page(mem, pg_start, type);
- else
- return i460_insert_memory_large_io_page(mem, pg_start, type);
-}
-
-static int i460_remove_memory (struct agp_memory *mem,
- off_t pg_start, int type)
-{
- if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
- return i460_remove_memory_small_io_page(mem, pg_start, type);
- else
- return i460_remove_memory_large_io_page(mem, pg_start, type);
-}
-
-/*
- * If the I/O (GART) page size is bigger than the kernel page size, we don't want to
- * allocate memory until we know where it is to be bound in the aperture (a
- * multi-kernel-page alloc might fit inside of an already allocated GART page).
- *
- * Let's just hope nobody counts on the allocated AGP memory being there before bind time
- * (I don't think current drivers do)...
- */
-static struct page *i460_alloc_page (struct agp_bridge_data *bridge)
-{
- void *page;
-
- if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
- page = agp_generic_alloc_page(agp_bridge);
- } else
- /* Returning NULL would cause problems */
- /* AK: really dubious code. */
- page = (void *)~0UL;
- return page;
-}
-
-static void i460_destroy_page (struct page *page, int flags)
-{
- if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
- agp_generic_destroy_page(page, flags);
- }
-}
-
-#endif /* I460_LARGE_IO_PAGES */
-
-static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
- dma_addr_t addr, int type)
-{
- /* Make sure the returned address is a valid GATT entry */
- return bridge->driver->masks[0].mask
- | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
-}
-
-const struct agp_bridge_driver intel_i460_driver = {
- .owner = THIS_MODULE,
- .aperture_sizes = i460_sizes,
- .size_type = U8_APER_SIZE,
- .num_aperture_sizes = 3,
- .configure = i460_configure,
- .fetch_size = i460_fetch_size,
- .cleanup = i460_cleanup,
- .tlb_flush = i460_tlb_flush,
- .mask_memory = i460_mask_memory,
- .masks = i460_masks,
- .agp_enable = agp_generic_enable,
- .cache_flush = global_cache_flush,
- .create_gatt_table = i460_create_gatt_table,
- .free_gatt_table = i460_free_gatt_table,
-#if I460_LARGE_IO_PAGES
- .insert_memory = i460_insert_memory,
- .remove_memory = i460_remove_memory,
- .agp_alloc_page = i460_alloc_page,
- .agp_destroy_page = i460_destroy_page,
-#else
- .insert_memory = i460_insert_memory_small_io_page,
- .remove_memory = i460_remove_memory_small_io_page,
- .agp_alloc_page = agp_generic_alloc_page,
- .agp_alloc_pages = agp_generic_alloc_pages,
- .agp_destroy_page = agp_generic_destroy_page,
- .agp_destroy_pages = agp_generic_destroy_pages,
-#endif
- .alloc_by_type = agp_generic_alloc_by_type,
- .free_by_type = agp_generic_free_by_type,
- .agp_type_to_mask_type = agp_generic_type_to_mask_type,
- .cant_use_aperture = true,
-};
-
-static int agp_intel_i460_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct agp_bridge_data *bridge;
- u8 cap_ptr;
-
- cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
- if (!cap_ptr)
- return -ENODEV;
-
- bridge = agp_alloc_bridge();
- if (!bridge)
- return -ENOMEM;
-
- bridge->driver = &intel_i460_driver;
- bridge->dev = pdev;
- bridge->capndx = cap_ptr;
-
- printk(KERN_INFO PFX "Detected Intel 460GX chipset\n");
-
- pci_set_drvdata(pdev, bridge);
- return agp_add_bridge(bridge);
-}
-
-static void agp_intel_i460_remove(struct pci_dev *pdev)
-{
- struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
-
- agp_remove_bridge(bridge);
- agp_put_bridge(bridge);
-}
-
-static struct pci_device_id agp_intel_i460_pci_table[] = {
- {
- .class = (PCI_CLASS_BRIDGE_HOST << 8),
- .class_mask = ~0,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_84460GX,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },
- { }
-};
-
-MODULE_DEVICE_TABLE(pci, agp_intel_i460_pci_table);
-
-static struct pci_driver agp_intel_i460_pci_driver = {
- .name = "agpgart-intel-i460",
- .id_table = agp_intel_i460_pci_table,
- .probe = agp_intel_i460_probe,
- .remove = agp_intel_i460_remove,
-};
-
-static int __init agp_intel_i460_init(void)
-{
- if (agp_off)
- return -EINVAL;
- return pci_register_driver(&agp_intel_i460_pci_driver);
-}
-
-static void __exit agp_intel_i460_cleanup(void)
-{
- pci_unregister_driver(&agp_intel_i460_pci_driver);
-}
-
-module_init(agp_intel_i460_init);
-module_exit(agp_intel_i460_cleanup);
-
-MODULE_AUTHOR("Chris Ahna <Christopher.J.Ahna@intel.com>");
-MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index c6f181702b9a..edbc4d338117 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -38,7 +38,7 @@ static struct _parisc_agp_info {
int lba_cap_offset;
- u64 *gatt;
+ __le64 *gatt;
u64 gatt_entries;
u64 gart_base;
@@ -104,7 +104,7 @@ parisc_agp_create_gatt_table(struct agp_bridge_data *bridge)
int i;
for (i = 0; i < info->gatt_entries; i++) {
- info->gatt[i] = (unsigned long)agp_bridge->scratch_page;
+ info->gatt[i] = cpu_to_le64(agp_bridge->scratch_page);
}
return 0;
@@ -158,9 +158,9 @@ parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
for (k = 0;
k < info->io_pages_per_kpage;
k++, j++, paddr += info->io_page_size) {
- info->gatt[j] =
+ info->gatt[j] = cpu_to_le64(
parisc_agp_mask_memory(agp_bridge,
- paddr, type);
+ paddr, type));
asm_io_fdc(&info->gatt[j]);
}
}
@@ -184,7 +184,7 @@ parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
io_pg_start = info->io_pages_per_kpage * pg_start;
io_pg_count = info->io_pages_per_kpage * mem->page_count;
for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
- info->gatt[i] = agp_bridge->scratch_page;
+ info->gatt[i] = cpu_to_le64(agp_bridge->scratch_page);
}
agp_bridge->driver->tlb_flush(mem);
@@ -204,7 +204,8 @@ parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr,
pa |= (ci >> PAGE_SHIFT) & 0xff;/* move CI (8 bits) into lowest byte */
pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */
- return cpu_to_le64(pa);
+ /* return native (big-endian) PDIR entry */
+ return pa;
}
static void
@@ -251,7 +252,8 @@ static int __init
agp_ioc_init(void __iomem *ioc_regs)
{
struct _parisc_agp_info *info = &parisc_agp_info;
- u64 iova_base, *io_pdir, io_tlb_ps;
+ u64 iova_base, io_tlb_ps;
+ __le64 *io_pdir;
int io_tlb_shift;
printk(KERN_INFO DRVPFX "IO PDIR shared with sba_iommu\n");
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index ee71376f174b..e1deb7a69b8a 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -64,25 +64,6 @@
static DEFINE_MUTEX(hpet_mutex); /* replaces BKL */
static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
-/* This clocksource driver currently only works on ia64 */
-#ifdef CONFIG_IA64
-static void __iomem *hpet_mctr;
-
-static u64 read_hpet(struct clocksource *cs)
-{
- return (u64)read_counter((void __iomem *)hpet_mctr);
-}
-
-static struct clocksource clocksource_hpet = {
- .name = "hpet",
- .rating = 250,
- .read = read_hpet,
- .mask = CLOCKSOURCE_MASK(64),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-static struct clocksource *hpet_clocksource;
-#endif
-
/* A lock for concurrent access by app and isr hpet activity. */
static DEFINE_SPINLOCK(hpet_lock);
@@ -728,7 +709,6 @@ static struct ctl_table hpet_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
- {}
};
static struct ctl_table_header *sysctl_header;
@@ -907,17 +887,6 @@ int hpet_alloc(struct hpet_data *hdp)
hpetp->hp_delta = hpet_calibrate(hpetp);
-/* This clocksource driver currently only works on ia64 */
-#ifdef CONFIG_IA64
- if (!hpet_clocksource) {
- hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc;
- clocksource_hpet.archdata.fsys_mmio = hpet_mctr;
- clocksource_register_hz(&clocksource_hpet, hpetp->hp_tick_freq);
- hpetp->hp_clocksource = &clocksource_hpet;
- hpet_clocksource = &clocksource_hpet;
- }
-#endif
-
return 0;
}
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 8de74dcfa18c..442c40efb200 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -37,7 +37,7 @@ config HW_RANDOM_TIMERIOMEM
config HW_RANDOM_INTEL
tristate "Intel HW Random Number Generator support"
- depends on (X86 || IA64 || COMPILE_TEST) && PCI
+ depends on (X86 || COMPILE_TEST) && PCI
default HW_RANDOM
help
This driver provides kernel-side support for the Random Number
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index 870659d91db2..941d2dcc8c9d 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -656,7 +656,6 @@ static struct ctl_table ipmi_table[] = {
.maxlen = sizeof(poweroff_powercycle),
.mode = 0644,
.proc_handler = proc_dointvec },
- { }
};
static struct ctl_table_header *ipmi_table_header;
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 1052b0f2d4cf..8d27aa6b5b50 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -31,10 +31,6 @@
#include <linux/uaccess.h>
#include <linux/security.h>
-#ifdef CONFIG_IA64
-# include <linux/efi.h>
-#endif
-
#define DEVMEM_MINOR 1
#define DEVPORT_MINOR 4
@@ -277,13 +273,6 @@ int __weak phys_mem_access_prot_allowed(struct file *file,
#ifdef pgprot_noncached
static int uncached_access(struct file *file, phys_addr_t addr)
{
-#if defined(CONFIG_IA64)
- /*
- * On ia64, we ignore O_DSYNC because we cannot tolerate memory
- * attribute aliases.
- */
- return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
-#else
/*
* Accessing memory above the top the kernel knows about or through a
* file pointer
@@ -292,7 +281,6 @@ static int uncached_access(struct file *file, phys_addr_t addr)
if (file->f_flags & O_DSYNC)
return 1;
return addr >= __pa(high_memory);
-#endif
}
#endif
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
deleted file mode 100644
index b35f651837c8..000000000000
--- a/drivers/char/mspec.c
+++ /dev/null
@@ -1,295 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights
- * reserved.
- */
-
-/*
- * SN Platform Special Memory (mspec) Support
- *
- * This driver exports the SN special memory (mspec) facility to user
- * processes.
- * There are two types of memory made available thru this driver:
- * uncached and cached.
- *
- * Uncached are used for memory write combining feature of the ia64
- * cpu.
- *
- * Cached are used for areas of memory that are used as cached addresses
- * on our partition and used as uncached addresses from other partitions.
- * Due to a design constraint of the SN2 Shub, you can not have processors
- * on the same FSB perform both a cached and uncached reference to the
- * same cache line. These special memory cached regions prevent the
- * kernel from ever dropping in a TLB entry and therefore prevent the
- * processor from ever speculating a cache line from this page.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/vmalloc.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/numa.h>
-#include <linux/refcount.h>
-#include <asm/page.h>
-#include <linux/atomic.h>
-#include <asm/tlbflush.h>
-#include <asm/uncached.h>
-
-
-#define CACHED_ID "Cached,"
-#define UNCACHED_ID "Uncached"
-#define REVISION "4.0"
-#define MSPEC_BASENAME "mspec"
-
-/*
- * Page types allocated by the device.
- */
-enum mspec_page_type {
- MSPEC_CACHED = 2,
- MSPEC_UNCACHED
-};
-
-/*
- * One of these structures is allocated when an mspec region is mmaped. The
- * structure is pointed to by the vma->vm_private_data field in the vma struct.
- * This structure is used to record the addresses of the mspec pages.
- * This structure is shared by all vma's that are split off from the
- * original vma when split_vma()'s are done.
- *
- * The refcnt is incremented atomically because mm->mmap_lock does not
- * protect in fork case where multiple tasks share the vma_data.
- */
-struct vma_data {
- refcount_t refcnt; /* Number of vmas sharing the data. */
- spinlock_t lock; /* Serialize access to this structure. */
- int count; /* Number of pages allocated. */
- enum mspec_page_type type; /* Type of pages allocated. */
- unsigned long vm_start; /* Original (unsplit) base. */
- unsigned long vm_end; /* Original (unsplit) end. */
- unsigned long maddr[]; /* Array of MSPEC addresses. */
-};
-
-/*
- * mspec_open
- *
- * Called when a device mapping is created by a means other than mmap
- * (via fork, munmap, etc.). Increments the reference count on the
- * underlying mspec data so it is not freed prematurely.
- */
-static void
-mspec_open(struct vm_area_struct *vma)
-{
- struct vma_data *vdata;
-
- vdata = vma->vm_private_data;
- refcount_inc(&vdata->refcnt);
-}
-
-/*
- * mspec_close
- *
- * Called when unmapping a device mapping. Frees all mspec pages
- * belonging to all the vma's sharing this vma_data structure.
- */
-static void
-mspec_close(struct vm_area_struct *vma)
-{
- struct vma_data *vdata;
- int index, last_index;
- unsigned long my_page;
-
- vdata = vma->vm_private_data;
-
- if (!refcount_dec_and_test(&vdata->refcnt))
- return;
-
- last_index = (vdata->vm_end - vdata->vm_start) >> PAGE_SHIFT;
- for (index = 0; index < last_index; index++) {
- if (vdata->maddr[index] == 0)
- continue;
- /*
- * Clear the page before sticking it back
- * into the pool.
- */
- my_page = vdata->maddr[index];
- vdata->maddr[index] = 0;
- memset((char *)my_page, 0, PAGE_SIZE);
- uncached_free_page(my_page, 1);
- }
-
- kvfree(vdata);
-}
-
-/*
- * mspec_fault
- *
- * Creates a mspec page and maps it to user space.
- */
-static vm_fault_t
-mspec_fault(struct vm_fault *vmf)
-{
- unsigned long paddr, maddr;
- unsigned long pfn;
- pgoff_t index = vmf->pgoff;
- struct vma_data *vdata = vmf->vma->vm_private_data;
-
- maddr = (volatile unsigned long) vdata->maddr[index];
- if (maddr == 0) {
- maddr = uncached_alloc_page(numa_node_id(), 1);
- if (maddr == 0)
- return VM_FAULT_OOM;
-
- spin_lock(&vdata->lock);
- if (vdata->maddr[index] == 0) {
- vdata->count++;
- vdata->maddr[index] = maddr;
- } else {
- uncached_free_page(maddr, 1);
- maddr = vdata->maddr[index];
- }
- spin_unlock(&vdata->lock);
- }
-
- paddr = maddr & ~__IA64_UNCACHED_OFFSET;
- pfn = paddr >> PAGE_SHIFT;
-
- return vmf_insert_pfn(vmf->vma, vmf->address, pfn);
-}
-
-static const struct vm_operations_struct mspec_vm_ops = {
- .open = mspec_open,
- .close = mspec_close,
- .fault = mspec_fault,
-};
-
-/*
- * mspec_mmap
- *
- * Called when mmapping the device. Initializes the vma with a fault handler
- * and private data structure necessary to allocate, track, and free the
- * underlying pages.
- */
-static int
-mspec_mmap(struct file *file, struct vm_area_struct *vma,
- enum mspec_page_type type)
-{
- struct vma_data *vdata;
- int pages, vdata_size;
-
- if (vma->vm_pgoff != 0)
- return -EINVAL;
-
- if ((vma->vm_flags & VM_SHARED) == 0)
- return -EINVAL;
-
- if ((vma->vm_flags & VM_WRITE) == 0)
- return -EPERM;
-
- pages = vma_pages(vma);
- vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
- vdata = kvzalloc(vdata_size, GFP_KERNEL);
- if (!vdata)
- return -ENOMEM;
-
- vdata->vm_start = vma->vm_start;
- vdata->vm_end = vma->vm_end;
- vdata->type = type;
- spin_lock_init(&vdata->lock);
- refcount_set(&vdata->refcnt, 1);
- vma->vm_private_data = vdata;
-
- vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
- if (vdata->type == MSPEC_UNCACHED)
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- vma->vm_ops = &mspec_vm_ops;
-
- return 0;
-}
-
-static int
-cached_mmap(struct file *file, struct vm_area_struct *vma)
-{
- return mspec_mmap(file, vma, MSPEC_CACHED);
-}
-
-static int
-uncached_mmap(struct file *file, struct vm_area_struct *vma)
-{
- return mspec_mmap(file, vma, MSPEC_UNCACHED);
-}
-
-static const struct file_operations cached_fops = {
- .owner = THIS_MODULE,
- .mmap = cached_mmap,
- .llseek = noop_llseek,
-};
-
-static struct miscdevice cached_miscdev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "mspec_cached",
- .fops = &cached_fops
-};
-
-static const struct file_operations uncached_fops = {
- .owner = THIS_MODULE,
- .mmap = uncached_mmap,
- .llseek = noop_llseek,
-};
-
-static struct miscdevice uncached_miscdev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "mspec_uncached",
- .fops = &uncached_fops
-};
-
-/*
- * mspec_init
- *
- * Called at boot time to initialize the mspec facility.
- */
-static int __init
-mspec_init(void)
-{
- int ret;
-
- ret = misc_register(&cached_miscdev);
- if (ret) {
- printk(KERN_ERR "%s: failed to register device %i\n",
- CACHED_ID, ret);
- return ret;
- }
- ret = misc_register(&uncached_miscdev);
- if (ret) {
- printk(KERN_ERR "%s: failed to register device %i\n",
- UNCACHED_ID, ret);
- misc_deregister(&cached_miscdev);
- return ret;
- }
-
- printk(KERN_INFO "%s %s initialized devices: %s %s\n",
- MSPEC_BASENAME, REVISION, CACHED_ID, UNCACHED_ID);
-
- return 0;
-}
-
-static void __exit
-mspec_exit(void)
-{
- misc_deregister(&uncached_miscdev);
- misc_deregister(&cached_miscdev);
-}
-
-module_init(mspec_init);
-module_exit(mspec_exit);
-
-MODULE_AUTHOR("Silicon Graphics, Inc. <linux-altix@sgi.com>");
-MODULE_DESCRIPTION("Driver for SGI SN special memory operations");
-MODULE_LICENSE("GPL");
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 3cb37760dfec..4a9c79391dee 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1683,7 +1683,6 @@ static struct ctl_table random_table[] = {
.mode = 0444,
.proc_handler = proc_do_uuid,
},
- { }
};
/*
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 2c7a830ce308..8cbe24789c24 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -13,13 +13,18 @@
#include <linux/scmi_protocol.h>
#include <asm/div64.h>
+#define NOT_ATOMIC false
+#define ATOMIC true
+
static const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
struct scmi_clk {
u32 id;
+ struct device *dev;
struct clk_hw hw;
const struct scmi_clock_info *info;
const struct scmi_protocol_handle *ph;
+ struct clk_parent_data *parent_data;
};
#define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw)
@@ -74,38 +79,89 @@ static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
return scmi_proto_clk_ops->rate_set(clk->ph, clk->id, rate);
}
+static int scmi_clk_set_parent(struct clk_hw *hw, u8 parent_index)
+{
+ struct scmi_clk *clk = to_scmi_clk(hw);
+
+ return scmi_proto_clk_ops->parent_set(clk->ph, clk->id, parent_index);
+}
+
+static u8 scmi_clk_get_parent(struct clk_hw *hw)
+{
+ struct scmi_clk *clk = to_scmi_clk(hw);
+ u32 parent_id, p_idx;
+ int ret;
+
+ ret = scmi_proto_clk_ops->parent_get(clk->ph, clk->id, &parent_id);
+ if (ret)
+ return 0;
+
+ for (p_idx = 0; p_idx < clk->info->num_parents; p_idx++) {
+ if (clk->parent_data[p_idx].index == parent_id)
+ break;
+ }
+
+ if (p_idx == clk->info->num_parents)
+ return 0;
+
+ return p_idx;
+}
+
+static int scmi_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ /*
+ * Suppose all the requested rates are supported, and let firmware
+ * to handle the left work.
+ */
+ return 0;
+}
+
static int scmi_clk_enable(struct clk_hw *hw)
{
struct scmi_clk *clk = to_scmi_clk(hw);
- return scmi_proto_clk_ops->enable(clk->ph, clk->id);
+ return scmi_proto_clk_ops->enable(clk->ph, clk->id, NOT_ATOMIC);
}
static void scmi_clk_disable(struct clk_hw *hw)
{
struct scmi_clk *clk = to_scmi_clk(hw);
- scmi_proto_clk_ops->disable(clk->ph, clk->id);
+ scmi_proto_clk_ops->disable(clk->ph, clk->id, NOT_ATOMIC);
}
static int scmi_clk_atomic_enable(struct clk_hw *hw)
{
struct scmi_clk *clk = to_scmi_clk(hw);
- return scmi_proto_clk_ops->enable_atomic(clk->ph, clk->id);
+ return scmi_proto_clk_ops->enable(clk->ph, clk->id, ATOMIC);
}
static void scmi_clk_atomic_disable(struct clk_hw *hw)
{
struct scmi_clk *clk = to_scmi_clk(hw);
- scmi_proto_clk_ops->disable_atomic(clk->ph, clk->id);
+ scmi_proto_clk_ops->disable(clk->ph, clk->id, ATOMIC);
+}
+
+static int scmi_clk_atomic_is_enabled(struct clk_hw *hw)
+{
+ int ret;
+ bool enabled = false;
+ struct scmi_clk *clk = to_scmi_clk(hw);
+
+ ret = scmi_proto_clk_ops->state_get(clk->ph, clk->id, &enabled, ATOMIC);
+ if (ret)
+ dev_warn(clk->dev,
+ "Failed to get state for clock ID %d\n", clk->id);
+
+ return !!enabled;
}
/*
- * We can provide enable/disable atomic callbacks only if the underlying SCMI
- * transport for an SCMI instance is configured to handle SCMI commands in an
- * atomic manner.
+ * We can provide enable/disable/is_enabled atomic callbacks only if the
+ * underlying SCMI transport for an SCMI instance is configured to handle
+ * SCMI commands in an atomic manner.
*
* When no SCMI atomic transport support is available we instead provide only
* the prepare/unprepare API, as allowed by the clock framework when atomic
@@ -121,6 +177,9 @@ static const struct clk_ops scmi_clk_ops = {
.set_rate = scmi_clk_set_rate,
.prepare = scmi_clk_enable,
.unprepare = scmi_clk_disable,
+ .set_parent = scmi_clk_set_parent,
+ .get_parent = scmi_clk_get_parent,
+ .determine_rate = scmi_clk_determine_rate,
};
static const struct clk_ops scmi_atomic_clk_ops = {
@@ -129,6 +188,10 @@ static const struct clk_ops scmi_atomic_clk_ops = {
.set_rate = scmi_clk_set_rate,
.enable = scmi_clk_atomic_enable,
.disable = scmi_clk_atomic_disable,
+ .is_enabled = scmi_clk_atomic_is_enabled,
+ .set_parent = scmi_clk_set_parent,
+ .get_parent = scmi_clk_get_parent,
+ .determine_rate = scmi_clk_determine_rate,
};
static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
@@ -139,9 +202,10 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
struct clk_init_data init = {
.flags = CLK_GET_RATE_NOCACHE,
- .num_parents = 0,
+ .num_parents = sclk->info->num_parents,
.ops = scmi_ops,
.name = sclk->info->name,
+ .parent_data = sclk->parent_data,
};
sclk->hw.init = &init;
@@ -213,11 +277,13 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
sclk->info = scmi_proto_clk_ops->info_get(ph, idx);
if (!sclk->info) {
dev_dbg(dev, "invalid clock info for idx %d\n", idx);
+ devm_kfree(dev, sclk);
continue;
}
sclk->id = idx;
sclk->ph = ph;
+ sclk->dev = dev;
/*
* Note that when transport is atomic but SCMI protocol did not
@@ -230,9 +296,23 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
else
scmi_ops = &scmi_clk_ops;
+ /* Initialize clock parent data. */
+ if (sclk->info->num_parents > 0) {
+ sclk->parent_data = devm_kcalloc(dev, sclk->info->num_parents,
+ sizeof(*sclk->parent_data), GFP_KERNEL);
+ if (!sclk->parent_data)
+ return -ENOMEM;
+
+ for (int i = 0; i < sclk->info->num_parents; i++) {
+ sclk->parent_data[i].index = sclk->info->parents[i];
+ sclk->parent_data[i].hw = hws[sclk->info->parents[i]];
+ }
+ }
+
err = scmi_clk_ops_init(dev, sclk, scmi_ops);
if (err) {
dev_err(dev, "failed to register clock %d\n", idx);
+ devm_kfree(dev, sclk->parent_data);
devm_kfree(dev, sclk);
hws[idx] = NULL;
} else {
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 7dd2c615bce2..e054de92de91 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -836,8 +836,9 @@ static u64 __arch_timer_check_delta(void)
* Note that TVAL is signed, thus has only 31 of its
* 32 bits to express magnitude.
*/
- MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM,
- APM_CPU_PART_POTENZA)),
+ MIDR_REV_RANGE(MIDR_CPU_MODEL(ARM_CPU_IMP_APM,
+ APM_CPU_PART_XGENE),
+ APM_CPU_VAR_POTENZA, 0x0, 0xf),
{},
};
@@ -917,7 +918,7 @@ static void arch_timer_evtstrm_enable(unsigned int divider)
#ifdef CONFIG_ARM64
/* ECV is likely to require a large divider. Use the EVNTIS flag. */
- if (cpus_have_const_cap(ARM64_HAS_ECV) && divider > 15) {
+ if (cpus_have_final_cap(ARM64_HAS_ECV) && divider > 15) {
cntkctl |= ARCH_TIMER_EVT_INTERVAL_SCALE;
divider -= 8;
}
@@ -955,6 +956,30 @@ static void arch_timer_configure_evtstream(void)
arch_timer_evtstrm_enable(max(0, lsb));
}
+static int arch_timer_evtstrm_starting_cpu(unsigned int cpu)
+{
+ arch_timer_configure_evtstream();
+ return 0;
+}
+
+static int arch_timer_evtstrm_dying_cpu(unsigned int cpu)
+{
+ cpumask_clear_cpu(smp_processor_id(), &evtstrm_available);
+ return 0;
+}
+
+static int __init arch_timer_evtstrm_register(void)
+{
+ if (!arch_timer_evt || !evtstrm_enable)
+ return 0;
+
+ return cpuhp_setup_state(CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING,
+ "clockevents/arm/arch_timer_evtstrm:starting",
+ arch_timer_evtstrm_starting_cpu,
+ arch_timer_evtstrm_dying_cpu);
+}
+core_initcall(arch_timer_evtstrm_register);
+
static void arch_counter_set_user_access(void)
{
u32 cntkctl = arch_timer_get_cntkctl();
@@ -1016,8 +1041,6 @@ static int arch_timer_starting_cpu(unsigned int cpu)
}
arch_counter_set_user_access();
- if (evtstrm_enable)
- arch_timer_configure_evtstream();
return 0;
}
@@ -1164,8 +1187,6 @@ static int arch_timer_dying_cpu(unsigned int cpu)
{
struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt);
- cpumask_clear_cpu(smp_processor_id(), &evtstrm_available);
-
arch_timer_stop(clk);
return 0;
}
@@ -1279,6 +1300,7 @@ out_unreg_notify:
out_free:
free_percpu(arch_timer_evt);
+ arch_timer_evt = NULL;
out:
return err;
}
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index f429b9b37b76..35efb53d5492 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -239,17 +239,6 @@ if PPC32 || PPC64
source "drivers/cpufreq/Kconfig.powerpc"
endif
-if IA64
-config IA64_ACPI_CPUFREQ
- tristate "ACPI Processor P-States driver"
- depends on ACPI_PROCESSOR
- help
- This driver adds a CPUFreq driver which utilizes the ACPI
- Processor Performance States.
-
- If in doubt, say N.
-endif
-
if MIPS
config BMIPS_CPUFREQ
tristate "BMIPS CPUfreq Driver"
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index ef8510774913..8d141c71b016 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -102,7 +102,6 @@ obj-$(CONFIG_POWERNV_CPUFREQ) += powernv-cpufreq.o
##################################################################################
# Other platform drivers
obj-$(CONFIG_BMIPS_CPUFREQ) += bmips-cpufreq.o
-obj-$(CONFIG_IA64_ACPI_CPUFREQ) += ia64-acpi-cpufreq.o
obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o
obj-$(CONFIG_SH_CPU_FREQ) += sh-cpufreq.o
obj-$(CONFIG_SPARC_US2E_CPUFREQ) += sparc-us2e-cpufreq.o
diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c
deleted file mode 100644
index c6bdc455517f..000000000000
--- a/drivers/cpufreq/ia64-acpi-cpufreq.c
+++ /dev/null
@@ -1,353 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * This file provides the ACPI based P-state support. This
- * module works with generic cpufreq infrastructure. Most of
- * the code is based on i386 version
- * (arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c)
- *
- * Copyright (C) 2005 Intel Corp
- * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/proc_fs.h>
-#include <asm/io.h>
-#include <linux/uaccess.h>
-#include <asm/pal.h>
-
-#include <linux/acpi.h>
-#include <acpi/processor.h>
-
-MODULE_AUTHOR("Venkatesh Pallipadi");
-MODULE_DESCRIPTION("ACPI Processor P-States Driver");
-MODULE_LICENSE("GPL");
-
-struct cpufreq_acpi_io {
- struct acpi_processor_performance acpi_data;
- unsigned int resume;
-};
-
-struct cpufreq_acpi_req {
- unsigned int cpu;
- unsigned int state;
-};
-
-static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS];
-
-static struct cpufreq_driver acpi_cpufreq_driver;
-
-
-static int
-processor_set_pstate (
- u32 value)
-{
- s64 retval;
-
- pr_debug("processor_set_pstate\n");
-
- retval = ia64_pal_set_pstate((u64)value);
-
- if (retval) {
- pr_debug("Failed to set freq to 0x%x, with error 0x%llx\n",
- value, retval);
- return -ENODEV;
- }
- return (int)retval;
-}
-
-
-static int
-processor_get_pstate (
- u32 *value)
-{
- u64 pstate_index = 0;
- s64 retval;
-
- pr_debug("processor_get_pstate\n");
-
- retval = ia64_pal_get_pstate(&pstate_index,
- PAL_GET_PSTATE_TYPE_INSTANT);
- *value = (u32) pstate_index;
-
- if (retval)
- pr_debug("Failed to get current freq with "
- "error 0x%llx, idx 0x%x\n", retval, *value);
-
- return (int)retval;
-}
-
-
-/* To be used only after data->acpi_data is initialized */
-static unsigned
-extract_clock (
- struct cpufreq_acpi_io *data,
- unsigned value)
-{
- unsigned long i;
-
- pr_debug("extract_clock\n");
-
- for (i = 0; i < data->acpi_data.state_count; i++) {
- if (value == data->acpi_data.states[i].status)
- return data->acpi_data.states[i].core_frequency;
- }
- return data->acpi_data.states[i-1].core_frequency;
-}
-
-
-static long
-processor_get_freq (
- void *arg)
-{
- struct cpufreq_acpi_req *req = arg;
- unsigned int cpu = req->cpu;
- struct cpufreq_acpi_io *data = acpi_io_data[cpu];
- u32 value;
- int ret;
-
- pr_debug("processor_get_freq\n");
- if (smp_processor_id() != cpu)
- return -EAGAIN;
-
- /* processor_get_pstate gets the instantaneous frequency */
- ret = processor_get_pstate(&value);
- if (ret) {
- pr_warn("get performance failed with error %d\n", ret);
- return ret;
- }
- return 1000 * extract_clock(data, value);
-}
-
-
-static long
-processor_set_freq (
- void *arg)
-{
- struct cpufreq_acpi_req *req = arg;
- unsigned int cpu = req->cpu;
- struct cpufreq_acpi_io *data = acpi_io_data[cpu];
- int ret, state = req->state;
- u32 value;
-
- pr_debug("processor_set_freq\n");
- if (smp_processor_id() != cpu)
- return -EAGAIN;
-
- if (state == data->acpi_data.state) {
- if (unlikely(data->resume)) {
- pr_debug("Called after resume, resetting to P%d\n", state);
- data->resume = 0;
- } else {
- pr_debug("Already at target state (P%d)\n", state);
- return 0;
- }
- }
-
- pr_debug("Transitioning from P%d to P%d\n",
- data->acpi_data.state, state);
-
- /*
- * First we write the target state's 'control' value to the
- * control_register.
- */
- value = (u32) data->acpi_data.states[state].control;
-
- pr_debug("Transitioning to state: 0x%08x\n", value);
-
- ret = processor_set_pstate(value);
- if (ret) {
- pr_warn("Transition failed with error %d\n", ret);
- return -ENODEV;
- }
-
- data->acpi_data.state = state;
- return 0;
-}
-
-
-static unsigned int
-acpi_cpufreq_get (
- unsigned int cpu)
-{
- struct cpufreq_acpi_req req;
- long ret;
-
- req.cpu = cpu;
- ret = work_on_cpu(cpu, processor_get_freq, &req);
-
- return ret > 0 ? (unsigned int) ret : 0;
-}
-
-
-static int
-acpi_cpufreq_target (
- struct cpufreq_policy *policy,
- unsigned int index)
-{
- struct cpufreq_acpi_req req;
-
- req.cpu = policy->cpu;
- req.state = index;
-
- return work_on_cpu(req.cpu, processor_set_freq, &req);
-}
-
-static int
-acpi_cpufreq_cpu_init (
- struct cpufreq_policy *policy)
-{
- unsigned int i;
- unsigned int cpu = policy->cpu;
- struct cpufreq_acpi_io *data;
- unsigned int result = 0;
- struct cpufreq_frequency_table *freq_table;
-
- pr_debug("acpi_cpufreq_cpu_init\n");
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data)
- return (-ENOMEM);
-
- acpi_io_data[cpu] = data;
-
- result = acpi_processor_register_performance(&data->acpi_data, cpu);
-
- if (result)
- goto err_free;
-
- /* capability check */
- if (data->acpi_data.state_count <= 1) {
- pr_debug("No P-States\n");
- result = -ENODEV;
- goto err_unreg;
- }
-
- if ((data->acpi_data.control_register.space_id !=
- ACPI_ADR_SPACE_FIXED_HARDWARE) ||
- (data->acpi_data.status_register.space_id !=
- ACPI_ADR_SPACE_FIXED_HARDWARE)) {
- pr_debug("Unsupported address space [%d, %d]\n",
- (u32) (data->acpi_data.control_register.space_id),
- (u32) (data->acpi_data.status_register.space_id));
- result = -ENODEV;
- goto err_unreg;
- }
-
- /* alloc freq_table */
- freq_table = kcalloc(data->acpi_data.state_count + 1,
- sizeof(*freq_table),
- GFP_KERNEL);
- if (!freq_table) {
- result = -ENOMEM;
- goto err_unreg;
- }
-
- /* detect transition latency */
- policy->cpuinfo.transition_latency = 0;
- for (i=0; i<data->acpi_data.state_count; i++) {
- if ((data->acpi_data.states[i].transition_latency * 1000) >
- policy->cpuinfo.transition_latency) {
- policy->cpuinfo.transition_latency =
- data->acpi_data.states[i].transition_latency * 1000;
- }
- }
-
- /* table init */
- for (i = 0; i <= data->acpi_data.state_count; i++)
- {
- if (i < data->acpi_data.state_count) {
- freq_table[i].frequency =
- data->acpi_data.states[i].core_frequency * 1000;
- } else {
- freq_table[i].frequency = CPUFREQ_TABLE_END;
- }
- }
-
- policy->freq_table = freq_table;
-
- /* notify BIOS that we exist */
- acpi_processor_notify_smm(THIS_MODULE);
-
- pr_info("CPU%u - ACPI performance management activated\n", cpu);
-
- for (i = 0; i < data->acpi_data.state_count; i++)
- pr_debug(" %cP%d: %d MHz, %d mW, %d uS, %d uS, 0x%x 0x%x\n",
- (i == data->acpi_data.state?'*':' '), i,
- (u32) data->acpi_data.states[i].core_frequency,
- (u32) data->acpi_data.states[i].power,
- (u32) data->acpi_data.states[i].transition_latency,
- (u32) data->acpi_data.states[i].bus_master_latency,
- (u32) data->acpi_data.states[i].status,
- (u32) data->acpi_data.states[i].control);
-
- /* the first call to ->target() should result in us actually
- * writing something to the appropriate registers. */
- data->resume = 1;
-
- return (result);
-
- err_unreg:
- acpi_processor_unregister_performance(cpu);
- err_free:
- kfree(data);
- acpi_io_data[cpu] = NULL;
-
- return (result);
-}
-
-
-static int
-acpi_cpufreq_cpu_exit (
- struct cpufreq_policy *policy)
-{
- struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
-
- pr_debug("acpi_cpufreq_cpu_exit\n");
-
- if (data) {
- acpi_io_data[policy->cpu] = NULL;
- acpi_processor_unregister_performance(policy->cpu);
- kfree(policy->freq_table);
- kfree(data);
- }
-
- return (0);
-}
-
-
-static struct cpufreq_driver acpi_cpufreq_driver = {
- .verify = cpufreq_generic_frequency_table_verify,
- .target_index = acpi_cpufreq_target,
- .get = acpi_cpufreq_get,
- .init = acpi_cpufreq_cpu_init,
- .exit = acpi_cpufreq_cpu_exit,
- .name = "acpi-cpufreq",
- .attr = cpufreq_generic_attr,
-};
-
-
-static int __init
-acpi_cpufreq_init (void)
-{
- pr_debug("acpi_cpufreq_init\n");
-
- return cpufreq_register_driver(&acpi_cpufreq_driver);
-}
-
-
-static void __exit
-acpi_cpufreq_exit (void)
-{
- pr_debug("acpi_cpufreq_exit\n");
-
- cpufreq_unregister_driver(&acpi_cpufreq_driver);
-}
-
-late_initcall(acpi_cpufreq_init);
-module_exit(acpi_cpufreq_exit);
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index f34e6382a4c5..c8a7ccc42c16 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -70,16 +70,36 @@ static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
return 0;
}
+static int scmi_cpu_domain_id(struct device *cpu_dev)
+{
+ struct device_node *np = cpu_dev->of_node;
+ struct of_phandle_args domain_id;
+ int index;
+
+ if (of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0,
+ &domain_id)) {
+ /* Find the corresponding index for power-domain "perf". */
+ index = of_property_match_string(np, "power-domain-names",
+ "perf");
+ if (index < 0)
+ return -EINVAL;
+
+ if (of_parse_phandle_with_args(np, "power-domains",
+ "#power-domain-cells", index,
+ &domain_id))
+ return -EINVAL;
+ }
+
+ return domain_id.args[0];
+}
+
static int
-scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
+scmi_get_sharing_cpus(struct device *cpu_dev, int domain,
+ struct cpumask *cpumask)
{
- int cpu, domain, tdomain;
+ int cpu, tdomain;
struct device *tcpu_dev;
- domain = perf_ops->device_domain_id(cpu_dev);
- if (domain < 0)
- return domain;
-
for_each_possible_cpu(cpu) {
if (cpu == cpu_dev->id)
continue;
@@ -88,7 +108,7 @@ scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
if (!tcpu_dev)
continue;
- tdomain = perf_ops->device_domain_id(tcpu_dev);
+ tdomain = scmi_cpu_domain_id(tcpu_dev);
if (tdomain == domain)
cpumask_set_cpu(cpu, cpumask);
}
@@ -104,7 +124,7 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
unsigned long Hz;
int ret, domain;
- domain = perf_ops->device_domain_id(cpu_dev);
+ domain = scmi_cpu_domain_id(cpu_dev);
if (domain < 0)
return domain;
@@ -126,7 +146,7 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
static int scmi_cpufreq_init(struct cpufreq_policy *policy)
{
- int ret, nr_opp;
+ int ret, nr_opp, domain;
unsigned int latency;
struct device *cpu_dev;
struct scmi_data *priv;
@@ -138,6 +158,10 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
return -ENODEV;
}
+ domain = scmi_cpu_domain_id(cpu_dev);
+ if (domain < 0)
+ return domain;
+
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -148,7 +172,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
}
/* Obtain CPUs that share SCMI performance controls */
- ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
+ ret = scmi_get_sharing_cpus(cpu_dev, domain, policy->cpus);
if (ret) {
dev_warn(cpu_dev, "failed to get sharing cpumask\n");
goto out_free_cpumask;
@@ -176,7 +200,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
*/
nr_opp = dev_pm_opp_get_opp_count(cpu_dev);
if (nr_opp <= 0) {
- ret = perf_ops->device_opps_add(ph, cpu_dev);
+ ret = perf_ops->device_opps_add(ph, cpu_dev, domain);
if (ret) {
dev_warn(cpu_dev, "failed to add opps to the device\n");
goto out_free_cpumask;
@@ -209,7 +233,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
}
priv->cpu_dev = cpu_dev;
- priv->domain_id = perf_ops->device_domain_id(cpu_dev);
+ priv->domain_id = domain;
policy->driver_data = priv;
policy->freq_table = freq_table;
@@ -217,14 +241,14 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
/* SCMI allows DVFS request for any domain from any CPU */
policy->dvfs_possible_from_any_cpu = true;
- latency = perf_ops->transition_latency_get(ph, cpu_dev);
+ latency = perf_ops->transition_latency_get(ph, domain);
if (!latency)
latency = CPUFREQ_ETERNAL;
policy->cpuinfo.transition_latency = latency;
policy->fast_switch_possible =
- perf_ops->fast_switch_possible(ph, cpu_dev);
+ perf_ops->fast_switch_possible(ph, domain);
return 0;
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index b59e3041fd62..74d00b0c83fe 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -77,30 +77,6 @@ config FIRMWARE_MEMMAP
See also Documentation/ABI/testing/sysfs-firmware-memmap.
-config EFI_PCDP
- bool "Console device selection via EFI PCDP or HCDP table"
- depends on ACPI && EFI && IA64
- default y if IA64
- help
- If your firmware supplies the PCDP table, and you want to
- automatically use the primary console device it describes
- as the Linux console, say Y here.
-
- If your firmware supplies the HCDP table, and you want to
- use the first serial port it describes as the Linux console,
- say Y here. If your EFI ConOut path contains only a UART
- device, it will become the console automatically. Otherwise,
- you must specify the "console=hcdp" kernel boot argument.
-
- Neither the PCDP nor the HCDP affects naming of serial devices,
- so a serial console may be /dev/ttyS0, /dev/ttyS1, etc, depending
- on how the driver discovers devices.
-
- You must also enable the appropriate drivers (serial, VGA, etc.)
-
- See DIG64_HCDPv20_042804.pdf available from
- <http://www.dig64.org/specifications/>
-
config DMIID
bool "Export DMI identification via sysfs to userspace"
depends on DMI
@@ -212,20 +188,6 @@ config MTK_ADSP_IPC
ADSP exists on some mtk processors.
Client might use shared memory to exchange information with ADSP.
-config QCOM_SCM
- tristate
-
-config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
- bool "Qualcomm download mode enabled by default"
- depends on QCOM_SCM
- help
- A device with "download mode" enabled will upon an unexpected
- warm-restart enter a special debug mode that allows the user to
- "download" memory content over USB for offline postmortem analysis.
- The feature can be enabled/disabled on the kernel command line.
-
- Say Y here to enable "download mode" by default.
-
config SYSFB
bool
select BOOT_VESA_SUPPORT
@@ -311,6 +273,7 @@ source "drivers/firmware/efi/Kconfig"
source "drivers/firmware/imx/Kconfig"
source "drivers/firmware/meson/Kconfig"
source "drivers/firmware/psci/Kconfig"
+source "drivers/firmware/qcom/Kconfig"
source "drivers/firmware/smccc/Kconfig"
source "drivers/firmware/tegra/Kconfig"
source "drivers/firmware/xilinx/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 28fcddcd688f..5f9dab82e1a0 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_ARM_SDE_INTERFACE) += arm_sdei.o
obj-$(CONFIG_DMI) += dmi_scan.o
obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o
obj-$(CONFIG_EDD) += edd.o
-obj-$(CONFIG_EFI_PCDP) += pcdp.o
obj-$(CONFIG_DMIID) += dmi-id.o
obj-$(CONFIG_INTEL_STRATIX10_SERVICE) += stratix10-svc.o
obj-$(CONFIG_INTEL_STRATIX10_RSU) += stratix10-rsu.o
@@ -18,8 +17,6 @@ obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
obj-$(CONFIG_MTK_ADSP_IPC) += mtk-adsp-ipc.o
obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
-obj-$(CONFIG_QCOM_SCM) += qcom-scm.o
-qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
obj-$(CONFIG_SYSFB) += sysfb.o
obj-$(CONFIG_SYSFB_SIMPLEFB) += sysfb_simplefb.o
obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o
@@ -35,6 +32,7 @@ obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
obj-y += efi/
obj-y += imx/
obj-y += psci/
+obj-y += qcom/
obj-y += smccc/
obj-y += tegra/
obj-y += xilinx/
diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
index 2b8bfcd010f5..1c7940ba5539 100644
--- a/drivers/firmware/arm_ffa/bus.c
+++ b/drivers/firmware/arm_ffa/bus.c
@@ -15,6 +15,8 @@
#include "common.h"
+#define SCMI_UEVENT_MODALIAS_FMT "arm_ffa:%04x:%pUb"
+
static DEFINE_IDA(ffa_bus_id);
static int ffa_device_match(struct device *dev, struct device_driver *drv)
@@ -63,10 +65,20 @@ static int ffa_device_uevent(const struct device *dev, struct kobj_uevent_env *e
{
const struct ffa_device *ffa_dev = to_ffa_dev(dev);
- return add_uevent_var(env, "MODALIAS=arm_ffa:%04x:%pUb",
+ return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT,
ffa_dev->vm_id, &ffa_dev->uuid);
}
+static ssize_t modalias_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ffa_device *ffa_dev = to_ffa_dev(dev);
+
+ return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT, ffa_dev->vm_id,
+ &ffa_dev->uuid);
+}
+static DEVICE_ATTR_RO(modalias);
+
static ssize_t partition_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -88,6 +100,7 @@ static DEVICE_ATTR_RO(uuid);
static struct attribute *ffa_device_attributes_attrs[] = {
&dev_attr_partition_id.attr,
&dev_attr_uuid.attr,
+ &dev_attr_modalias.attr,
NULL,
};
ATTRIBUTE_GROUPS(ffa_device_attributes);
@@ -193,6 +206,7 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
dev->release = ffa_release_device;
dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id);
+ ffa_dev->id = id;
ffa_dev->vm_id = vm_id;
ffa_dev->ops = ops;
uuid_copy(&ffa_dev->uuid, uuid);
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 121f4fc903cd..07b72c679247 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -22,20 +22,28 @@
#define DRIVER_NAME "ARM FF-A"
#define pr_fmt(fmt) DRIVER_NAME ": " fmt
+#include <linux/acpi.h>
#include <linux/arm_ffa.h>
#include <linux/bitfield.h>
+#include <linux/cpuhotplug.h>
#include <linux/device.h>
+#include <linux/hashtable.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/of_irq.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
+#include <linux/smp.h>
#include <linux/uuid.h>
+#include <linux/xarray.h>
#include "common.h"
-#define FFA_DRIVER_VERSION FFA_VERSION_1_0
+#define FFA_DRIVER_VERSION FFA_VERSION_1_1
#define FFA_MIN_VERSION FFA_VERSION_1_0
#define SENDER_ID_MASK GENMASK(31, 16)
@@ -51,6 +59,8 @@
*/
#define RXTX_BUFFER_SIZE SZ_4K
+#define FFA_MAX_NOTIFICATIONS 64
+
static ffa_fn *invoke_ffa_fn;
static const int ffa_linux_errmap[] = {
@@ -64,6 +74,7 @@ static const int ffa_linux_errmap[] = {
-EACCES, /* FFA_RET_DENIED */
-EAGAIN, /* FFA_RET_RETRY */
-ECANCELED, /* FFA_RET_ABORTED */
+ -ENODATA, /* FFA_RET_NO_DATA */
};
static inline int ffa_to_linux_errno(int errno)
@@ -75,6 +86,10 @@ static inline int ffa_to_linux_errno(int errno)
return -EINVAL;
}
+struct ffa_pcpu_irq {
+ struct ffa_drv_info *info;
+};
+
struct ffa_drv_info {
u32 version;
u16 vm_id;
@@ -83,6 +98,17 @@ struct ffa_drv_info {
void *rx_buffer;
void *tx_buffer;
bool mem_ops_native;
+ bool bitmap_created;
+ unsigned int sched_recv_irq;
+ unsigned int cpuhp_state;
+ struct ffa_pcpu_irq __percpu *irq_pcpu;
+ struct workqueue_struct *notif_pcpu_wq;
+ struct work_struct notif_pcpu_work;
+ struct work_struct irq_work;
+ struct xarray partition_info;
+ unsigned int partition_count;
+ DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS));
+ struct mutex notify_lock; /* lock to protect notifier hashtable */
};
static struct ffa_drv_info *drv_info;
@@ -397,7 +423,7 @@ static u32 ffa_get_num_pages_sg(struct scatterlist *sg)
return num_pages;
}
-static u8 ffa_memory_attributes_get(u32 func_id)
+static u16 ffa_memory_attributes_get(u32 func_id)
{
/*
* For the memory lend or donate operation, if the receiver is a PE or
@@ -416,38 +442,47 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
{
int rc = 0;
bool first = true;
+ u32 composite_offset;
phys_addr_t addr = 0;
+ struct ffa_mem_region *mem_region = buffer;
struct ffa_composite_mem_region *composite;
struct ffa_mem_region_addr_range *constituents;
struct ffa_mem_region_attributes *ep_mem_access;
- struct ffa_mem_region *mem_region = buffer;
u32 idx, frag_len, length, buf_sz = 0, num_entries = sg_nents(args->sg);
mem_region->tag = args->tag;
mem_region->flags = args->flags;
mem_region->sender_id = drv_info->vm_id;
mem_region->attributes = ffa_memory_attributes_get(func_id);
- ep_mem_access = &mem_region->ep_mem_access[0];
+ ep_mem_access = buffer +
+ ffa_mem_desc_offset(buffer, 0, drv_info->version);
+ composite_offset = ffa_mem_desc_offset(buffer, args->nattrs,
+ drv_info->version);
for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) {
ep_mem_access->receiver = args->attrs[idx].receiver;
ep_mem_access->attrs = args->attrs[idx].attrs;
- ep_mem_access->composite_off = COMPOSITE_OFFSET(args->nattrs);
+ ep_mem_access->composite_off = composite_offset;
ep_mem_access->flag = 0;
ep_mem_access->reserved = 0;
}
mem_region->handle = 0;
- mem_region->reserved_0 = 0;
- mem_region->reserved_1 = 0;
mem_region->ep_count = args->nattrs;
+ if (drv_info->version <= FFA_VERSION_1_0) {
+ mem_region->ep_mem_size = 0;
+ } else {
+ mem_region->ep_mem_size = sizeof(*ep_mem_access);
+ mem_region->ep_mem_offset = sizeof(*mem_region);
+ memset(mem_region->reserved, 0, 12);
+ }
- composite = buffer + COMPOSITE_OFFSET(args->nattrs);
+ composite = buffer + composite_offset;
composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg);
composite->addr_range_cnt = num_entries;
composite->reserved = 0;
- length = COMPOSITE_CONSTITUENTS_OFFSET(args->nattrs, num_entries);
- frag_len = COMPOSITE_CONSTITUENTS_OFFSET(args->nattrs, 0);
+ length = composite_offset + CONSTITUENTS_OFFSET(num_entries);
+ frag_len = composite_offset + CONSTITUENTS_OFFSET(0);
if (frag_len > max_fragsize)
return -ENXIO;
@@ -554,6 +589,236 @@ static int ffa_features(u32 func_feat_id, u32 input_props,
return 0;
}
+static int ffa_notification_bitmap_create(void)
+{
+ ffa_value_t ret;
+ u16 vcpu_count = nr_cpu_ids;
+
+ invoke_ffa_fn((ffa_value_t){
+ .a0 = FFA_NOTIFICATION_BITMAP_CREATE,
+ .a1 = drv_info->vm_id, .a2 = vcpu_count,
+ }, &ret);
+
+ if (ret.a0 == FFA_ERROR)
+ return ffa_to_linux_errno((int)ret.a2);
+
+ return 0;
+}
+
+static int ffa_notification_bitmap_destroy(void)
+{
+ ffa_value_t ret;
+
+ invoke_ffa_fn((ffa_value_t){
+ .a0 = FFA_NOTIFICATION_BITMAP_DESTROY,
+ .a1 = drv_info->vm_id,
+ }, &ret);
+
+ if (ret.a0 == FFA_ERROR)
+ return ffa_to_linux_errno((int)ret.a2);
+
+ return 0;
+}
+
+#define NOTIFICATION_LOW_MASK GENMASK(31, 0)
+#define NOTIFICATION_HIGH_MASK GENMASK(63, 32)
+#define NOTIFICATION_BITMAP_HIGH(x) \
+ ((u32)(FIELD_GET(NOTIFICATION_HIGH_MASK, (x))))
+#define NOTIFICATION_BITMAP_LOW(x) \
+ ((u32)(FIELD_GET(NOTIFICATION_LOW_MASK, (x))))
+#define PACK_NOTIFICATION_BITMAP(low, high) \
+ (FIELD_PREP(NOTIFICATION_LOW_MASK, (low)) | \
+ FIELD_PREP(NOTIFICATION_HIGH_MASK, (high)))
+
+#define RECEIVER_VCPU_MASK GENMASK(31, 16)
+#define PACK_NOTIFICATION_GET_RECEIVER_INFO(vcpu_r, r) \
+ (FIELD_PREP(RECEIVER_VCPU_MASK, (vcpu_r)) | \
+ FIELD_PREP(RECEIVER_ID_MASK, (r)))
+
+#define NOTIFICATION_INFO_GET_MORE_PEND_MASK BIT(0)
+#define NOTIFICATION_INFO_GET_ID_COUNT GENMASK(11, 7)
+#define ID_LIST_MASK_64 GENMASK(51, 12)
+#define ID_LIST_MASK_32 GENMASK(31, 12)
+#define MAX_IDS_64 20
+#define MAX_IDS_32 10
+
+#define PER_VCPU_NOTIFICATION_FLAG BIT(0)
+#define SECURE_PARTITION_BITMAP BIT(0)
+#define NON_SECURE_VM_BITMAP BIT(1)
+#define SPM_FRAMEWORK_BITMAP BIT(2)
+#define NS_HYP_FRAMEWORK_BITMAP BIT(3)
+
+static int ffa_notification_bind_common(u16 dst_id, u64 bitmap,
+ u32 flags, bool is_bind)
+{
+ ffa_value_t ret;
+ u32 func, src_dst_ids = PACK_TARGET_INFO(dst_id, drv_info->vm_id);
+
+ func = is_bind ? FFA_NOTIFICATION_BIND : FFA_NOTIFICATION_UNBIND;
+
+ invoke_ffa_fn((ffa_value_t){
+ .a0 = func, .a1 = src_dst_ids, .a2 = flags,
+ .a3 = NOTIFICATION_BITMAP_LOW(bitmap),
+ .a4 = NOTIFICATION_BITMAP_HIGH(bitmap),
+ }, &ret);
+
+ if (ret.a0 == FFA_ERROR)
+ return ffa_to_linux_errno((int)ret.a2);
+ else if (ret.a0 != FFA_SUCCESS)
+ return -EINVAL;
+
+ return 0;
+}
+
+static
+int ffa_notification_set(u16 src_id, u16 dst_id, u32 flags, u64 bitmap)
+{
+ ffa_value_t ret;
+ u32 src_dst_ids = PACK_TARGET_INFO(dst_id, src_id);
+
+ invoke_ffa_fn((ffa_value_t) {
+ .a0 = FFA_NOTIFICATION_SET, .a1 = src_dst_ids, .a2 = flags,
+ .a3 = NOTIFICATION_BITMAP_LOW(bitmap),
+ .a4 = NOTIFICATION_BITMAP_HIGH(bitmap),
+ }, &ret);
+
+ if (ret.a0 == FFA_ERROR)
+ return ffa_to_linux_errno((int)ret.a2);
+ else if (ret.a0 != FFA_SUCCESS)
+ return -EINVAL;
+
+ return 0;
+}
+
+struct ffa_notify_bitmaps {
+ u64 sp_map;
+ u64 vm_map;
+ u64 arch_map;
+};
+
+static int ffa_notification_get(u32 flags, struct ffa_notify_bitmaps *notify)
+{
+ ffa_value_t ret;
+ u16 src_id = drv_info->vm_id;
+ u16 cpu_id = smp_processor_id();
+ u32 rec_vcpu_ids = PACK_NOTIFICATION_GET_RECEIVER_INFO(cpu_id, src_id);
+
+ invoke_ffa_fn((ffa_value_t){
+ .a0 = FFA_NOTIFICATION_GET, .a1 = rec_vcpu_ids, .a2 = flags,
+ }, &ret);
+
+ if (ret.a0 == FFA_ERROR)
+ return ffa_to_linux_errno((int)ret.a2);
+ else if (ret.a0 != FFA_SUCCESS)
+ return -EINVAL; /* Something else went wrong. */
+
+ notify->sp_map = PACK_NOTIFICATION_BITMAP(ret.a2, ret.a3);
+ notify->vm_map = PACK_NOTIFICATION_BITMAP(ret.a4, ret.a5);
+ notify->arch_map = PACK_NOTIFICATION_BITMAP(ret.a6, ret.a7);
+
+ return 0;
+}
+
+struct ffa_dev_part_info {
+ ffa_sched_recv_cb callback;
+ void *cb_data;
+ rwlock_t rw_lock;
+};
+
+static void __do_sched_recv_cb(u16 part_id, u16 vcpu, bool is_per_vcpu)
+{
+ struct ffa_dev_part_info *partition;
+ ffa_sched_recv_cb callback;
+ void *cb_data;
+
+ partition = xa_load(&drv_info->partition_info, part_id);
+ read_lock(&partition->rw_lock);
+ callback = partition->callback;
+ cb_data = partition->cb_data;
+ read_unlock(&partition->rw_lock);
+
+ if (callback)
+ callback(vcpu, is_per_vcpu, cb_data);
+}
+
+static void ffa_notification_info_get(void)
+{
+ int idx, list, max_ids, lists_cnt, ids_processed, ids_count[MAX_IDS_64];
+ bool is_64b_resp;
+ ffa_value_t ret;
+ u64 id_list;
+
+ do {
+ invoke_ffa_fn((ffa_value_t){
+ .a0 = FFA_FN_NATIVE(NOTIFICATION_INFO_GET),
+ }, &ret);
+
+ if (ret.a0 != FFA_FN_NATIVE(SUCCESS) && ret.a0 != FFA_SUCCESS) {
+ if (ret.a2 != FFA_RET_NO_DATA)
+ pr_err("Notification Info fetch failed: 0x%lx (0x%lx)",
+ ret.a0, ret.a2);
+ return;
+ }
+
+ is_64b_resp = (ret.a0 == FFA_FN64_SUCCESS);
+
+ ids_processed = 0;
+ lists_cnt = FIELD_GET(NOTIFICATION_INFO_GET_ID_COUNT, ret.a2);
+ if (is_64b_resp) {
+ max_ids = MAX_IDS_64;
+ id_list = FIELD_GET(ID_LIST_MASK_64, ret.a2);
+ } else {
+ max_ids = MAX_IDS_32;
+ id_list = FIELD_GET(ID_LIST_MASK_32, ret.a2);
+ }
+
+ for (idx = 0; idx < lists_cnt; idx++, id_list >>= 2)
+ ids_count[idx] = (id_list & 0x3) + 1;
+
+ /* Process IDs */
+ for (list = 0; list < lists_cnt; list++) {
+ u16 vcpu_id, part_id, *packed_id_list = (u16 *)&ret.a3;
+
+ if (ids_processed >= max_ids - 1)
+ break;
+
+ part_id = packed_id_list[++ids_processed];
+
+ if (!ids_count[list]) { /* Global Notification */
+ __do_sched_recv_cb(part_id, 0, false);
+ continue;
+ }
+
+ /* Per vCPU Notification */
+ for (idx = 0; idx < ids_count[list]; idx++) {
+ if (ids_processed >= max_ids - 1)
+ break;
+
+ vcpu_id = packed_id_list[++ids_processed];
+
+ __do_sched_recv_cb(part_id, vcpu_id, true);
+ }
+ }
+ } while (ret.a2 & NOTIFICATION_INFO_GET_MORE_PEND_MASK);
+}
+
+static int ffa_run(struct ffa_device *dev, u16 vcpu)
+{
+ ffa_value_t ret;
+ u32 target = dev->vm_id << 16 | vcpu;
+
+ invoke_ffa_fn((ffa_value_t){ .a0 = FFA_RUN, .a1 = target, }, &ret);
+
+ while (ret.a0 == FFA_INTERRUPT)
+ invoke_ffa_fn((ffa_value_t){ .a0 = FFA_RUN, .a1 = ret.a1, },
+ &ret);
+
+ if (ret.a0 == FFA_ERROR)
+ return ffa_to_linux_errno((int)ret.a2);
+
+ return 0;
+}
+
static void ffa_set_up_mem_ops_native_flag(void)
{
if (!ffa_features(FFA_FN_NATIVE(MEM_LEND), 0, NULL, NULL) ||
@@ -587,17 +852,9 @@ static int ffa_partition_info_get(const char *uuid_str,
return 0;
}
-static void _ffa_mode_32bit_set(struct ffa_device *dev)
-{
- dev->mode_32bit = true;
-}
-
static void ffa_mode_32bit_set(struct ffa_device *dev)
{
- if (drv_info->version > FFA_VERSION_1_0)
- return;
-
- _ffa_mode_32bit_set(dev);
+ dev->mode_32bit = true;
}
static int ffa_sync_send_receive(struct ffa_device *dev,
@@ -630,6 +887,231 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
return ffa_memory_ops(FFA_MEM_LEND, args);
}
+#define FFA_SECURE_PARTITION_ID_FLAG BIT(15)
+
+enum notify_type {
+ NON_SECURE_VM,
+ SECURE_PARTITION,
+ FRAMEWORK,
+};
+
+struct notifier_cb_info {
+ struct hlist_node hnode;
+ ffa_notifier_cb cb;
+ void *cb_data;
+ enum notify_type type;
+};
+
+static int ffa_sched_recv_cb_update(u16 part_id, ffa_sched_recv_cb callback,
+ void *cb_data, bool is_registration)
+{
+ struct ffa_dev_part_info *partition;
+ bool cb_valid;
+
+ partition = xa_load(&drv_info->partition_info, part_id);
+ write_lock(&partition->rw_lock);
+
+ cb_valid = !!partition->callback;
+ if (!(is_registration ^ cb_valid)) {
+ write_unlock(&partition->rw_lock);
+ return -EINVAL;
+ }
+
+ partition->callback = callback;
+ partition->cb_data = cb_data;
+
+ write_unlock(&partition->rw_lock);
+ return 0;
+}
+
+static int ffa_sched_recv_cb_register(struct ffa_device *dev,
+ ffa_sched_recv_cb cb, void *cb_data)
+{
+ return ffa_sched_recv_cb_update(dev->vm_id, cb, cb_data, true);
+}
+
+static int ffa_sched_recv_cb_unregister(struct ffa_device *dev)
+{
+ return ffa_sched_recv_cb_update(dev->vm_id, NULL, NULL, false);
+}
+
+static int ffa_notification_bind(u16 dst_id, u64 bitmap, u32 flags)
+{
+ return ffa_notification_bind_common(dst_id, bitmap, flags, true);
+}
+
+static int ffa_notification_unbind(u16 dst_id, u64 bitmap)
+{
+ return ffa_notification_bind_common(dst_id, bitmap, 0, false);
+}
+
+/* Should be called while the notify_lock is taken */
+static struct notifier_cb_info *
+notifier_hash_node_get(u16 notify_id, enum notify_type type)
+{
+ struct notifier_cb_info *node;
+
+ hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id)
+ if (type == node->type)
+ return node;
+
+ return NULL;
+}
+
+static int
+update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
+ void *cb_data, bool is_registration)
+{
+ struct notifier_cb_info *cb_info = NULL;
+ bool cb_found;
+
+ cb_info = notifier_hash_node_get(notify_id, type);
+ cb_found = !!cb_info;
+
+ if (!(is_registration ^ cb_found))
+ return -EINVAL;
+
+ if (is_registration) {
+ cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
+ if (!cb_info)
+ return -ENOMEM;
+
+ cb_info->type = type;
+ cb_info->cb = cb;
+ cb_info->cb_data = cb_data;
+
+ hash_add(drv_info->notifier_hash, &cb_info->hnode, notify_id);
+ } else {
+ hash_del(&cb_info->hnode);
+ }
+
+ return 0;
+}
+
+static enum notify_type ffa_notify_type_get(u16 vm_id)
+{
+ if (vm_id & FFA_SECURE_PARTITION_ID_FLAG)
+ return SECURE_PARTITION;
+ else
+ return NON_SECURE_VM;
+}
+
+static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
+{
+ int rc;
+ enum notify_type type = ffa_notify_type_get(dev->vm_id);
+
+ if (notify_id >= FFA_MAX_NOTIFICATIONS)
+ return -EINVAL;
+
+ mutex_lock(&drv_info->notify_lock);
+
+ rc = update_notifier_cb(notify_id, type, NULL, NULL, false);
+ if (rc) {
+ pr_err("Could not unregister notification callback\n");
+ mutex_unlock(&drv_info->notify_lock);
+ return rc;
+ }
+
+ rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id));
+
+ mutex_unlock(&drv_info->notify_lock);
+
+ return rc;
+}
+
+static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
+ ffa_notifier_cb cb, void *cb_data, int notify_id)
+{
+ int rc;
+ u32 flags = 0;
+ enum notify_type type = ffa_notify_type_get(dev->vm_id);
+
+ if (notify_id >= FFA_MAX_NOTIFICATIONS)
+ return -EINVAL;
+
+ mutex_lock(&drv_info->notify_lock);
+
+ if (is_per_vcpu)
+ flags = PER_VCPU_NOTIFICATION_FLAG;
+
+ rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
+ if (rc) {
+ mutex_unlock(&drv_info->notify_lock);
+ return rc;
+ }
+
+ rc = update_notifier_cb(notify_id, type, cb, cb_data, true);
+ if (rc) {
+ pr_err("Failed to register callback for %d - %d\n",
+ notify_id, rc);
+ ffa_notification_unbind(dev->vm_id, BIT(notify_id));
+ }
+ mutex_unlock(&drv_info->notify_lock);
+
+ return rc;
+}
+
+static int ffa_notify_send(struct ffa_device *dev, int notify_id,
+ bool is_per_vcpu, u16 vcpu)
+{
+ u32 flags = 0;
+
+ if (is_per_vcpu)
+ flags |= (PER_VCPU_NOTIFICATION_FLAG | vcpu << 16);
+
+ return ffa_notification_set(dev->vm_id, drv_info->vm_id, flags,
+ BIT(notify_id));
+}
+
+static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
+{
+ int notify_id;
+ struct notifier_cb_info *cb_info = NULL;
+
+ for (notify_id = 0; notify_id <= FFA_MAX_NOTIFICATIONS && bitmap;
+ notify_id++, bitmap >>= 1) {
+ if (!(bitmap & 1))
+ continue;
+
+ mutex_lock(&drv_info->notify_lock);
+ cb_info = notifier_hash_node_get(notify_id, type);
+ mutex_unlock(&drv_info->notify_lock);
+
+ if (cb_info && cb_info->cb)
+ cb_info->cb(notify_id, cb_info->cb_data);
+ }
+}
+
+static void notif_pcpu_irq_work_fn(struct work_struct *work)
+{
+ int rc;
+ struct ffa_notify_bitmaps bitmaps;
+
+ rc = ffa_notification_get(SECURE_PARTITION_BITMAP |
+ SPM_FRAMEWORK_BITMAP, &bitmaps);
+ if (rc) {
+ pr_err("Failed to retrieve notifications with %d!\n", rc);
+ return;
+ }
+
+ handle_notif_callbacks(bitmaps.vm_map, NON_SECURE_VM);
+ handle_notif_callbacks(bitmaps.sp_map, SECURE_PARTITION);
+ handle_notif_callbacks(bitmaps.arch_map, FRAMEWORK);
+}
+
+static void
+ffa_self_notif_handle(u16 vcpu, bool is_per_vcpu, void *cb_data)
+{
+ struct ffa_drv_info *info = cb_data;
+
+ if (!is_per_vcpu)
+ notif_pcpu_irq_work_fn(&info->notif_pcpu_work);
+ else
+ queue_work_on(vcpu, info->notif_pcpu_wq,
+ &info->notif_pcpu_work);
+}
+
static const struct ffa_info_ops ffa_drv_info_ops = {
.api_version_get = ffa_api_version_get,
.partition_info_get = ffa_partition_info_get,
@@ -646,10 +1128,24 @@ static const struct ffa_mem_ops ffa_drv_mem_ops = {
.memory_lend = ffa_memory_lend,
};
+static const struct ffa_cpu_ops ffa_drv_cpu_ops = {
+ .run = ffa_run,
+};
+
+static const struct ffa_notifier_ops ffa_drv_notifier_ops = {
+ .sched_recv_cb_register = ffa_sched_recv_cb_register,
+ .sched_recv_cb_unregister = ffa_sched_recv_cb_unregister,
+ .notify_request = ffa_notify_request,
+ .notify_relinquish = ffa_notify_relinquish,
+ .notify_send = ffa_notify_send,
+};
+
static const struct ffa_ops ffa_drv_ops = {
.info_ops = &ffa_drv_info_ops,
.msg_ops = &ffa_drv_msg_ops,
.mem_ops = &ffa_drv_mem_ops,
+ .cpu_ops = &ffa_drv_cpu_ops,
+ .notifier_ops = &ffa_drv_notifier_ops,
};
void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid)
@@ -680,6 +1176,7 @@ static void ffa_setup_partitions(void)
int count, idx;
uuid_t uuid;
struct ffa_device *ffa_dev;
+ struct ffa_dev_part_info *info;
struct ffa_partition_info *pbuf, *tpbuf;
count = ffa_partition_probe(&uuid_null, &pbuf);
@@ -688,6 +1185,7 @@ static void ffa_setup_partitions(void)
return;
}
+ xa_init(&drv_info->partition_info);
for (idx = 0, tpbuf = pbuf; idx < count; idx++, tpbuf++) {
import_uuid(&uuid, (u8 *)tpbuf->uuid);
@@ -706,9 +1204,232 @@ static void ffa_setup_partitions(void)
if (drv_info->version > FFA_VERSION_1_0 &&
!(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
- _ffa_mode_32bit_set(ffa_dev);
+ ffa_mode_32bit_set(ffa_dev);
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ ffa_device_unregister(ffa_dev);
+ continue;
+ }
+ xa_store(&drv_info->partition_info, tpbuf->id, info, GFP_KERNEL);
}
+ drv_info->partition_count = count;
+
kfree(pbuf);
+
+ /* Allocate for the host */
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return;
+ xa_store(&drv_info->partition_info, drv_info->vm_id, info, GFP_KERNEL);
+ drv_info->partition_count++;
+}
+
+static void ffa_partitions_cleanup(void)
+{
+ struct ffa_dev_part_info **info;
+ int idx, count = drv_info->partition_count;
+
+ if (!count)
+ return;
+
+ info = kcalloc(count, sizeof(**info), GFP_KERNEL);
+ if (!info)
+ return;
+
+ xa_extract(&drv_info->partition_info, (void **)info, 0, VM_ID_MASK,
+ count, XA_PRESENT);
+
+ for (idx = 0; idx < count; idx++)
+ kfree(info[idx]);
+ kfree(info);
+
+ drv_info->partition_count = 0;
+ xa_destroy(&drv_info->partition_info);
+}
+
+/* FFA FEATURE IDs */
+#define FFA_FEAT_NOTIFICATION_PENDING_INT (1)
+#define FFA_FEAT_SCHEDULE_RECEIVER_INT (2)
+#define FFA_FEAT_MANAGED_EXIT_INT (3)
+
+static irqreturn_t irq_handler(int irq, void *irq_data)
+{
+ struct ffa_pcpu_irq *pcpu = irq_data;
+ struct ffa_drv_info *info = pcpu->info;
+
+ queue_work(info->notif_pcpu_wq, &info->irq_work);
+
+ return IRQ_HANDLED;
+}
+
+static void ffa_sched_recv_irq_work_fn(struct work_struct *work)
+{
+ ffa_notification_info_get();
+}
+
+static int ffa_sched_recv_irq_map(void)
+{
+ int ret, irq, sr_intid;
+
+ /* The returned sr_intid is assumed to be SGI donated to NS world */
+ ret = ffa_features(FFA_FEAT_SCHEDULE_RECEIVER_INT, 0, &sr_intid, NULL);
+ if (ret < 0) {
+ if (ret != -EOPNOTSUPP)
+ pr_err("Failed to retrieve scheduler Rx interrupt\n");
+ return ret;
+ }
+
+ if (acpi_disabled) {
+ struct of_phandle_args oirq = {};
+ struct device_node *gic;
+
+ /* Only GICv3 supported currently with the device tree */
+ gic = of_find_compatible_node(NULL, NULL, "arm,gic-v3");
+ if (!gic)
+ return -ENXIO;
+
+ oirq.np = gic;
+ oirq.args_count = 1;
+ oirq.args[0] = sr_intid;
+ irq = irq_create_of_mapping(&oirq);
+ of_node_put(gic);
+#ifdef CONFIG_ACPI
+ } else {
+ irq = acpi_register_gsi(NULL, sr_intid, ACPI_EDGE_SENSITIVE,
+ ACPI_ACTIVE_HIGH);
+#endif
+ }
+
+ if (irq <= 0) {
+ pr_err("Failed to create IRQ mapping!\n");
+ return -ENODATA;
+ }
+
+ return irq;
+}
+
+static void ffa_sched_recv_irq_unmap(void)
+{
+ if (drv_info->sched_recv_irq)
+ irq_dispose_mapping(drv_info->sched_recv_irq);
+}
+
+static int ffa_cpuhp_pcpu_irq_enable(unsigned int cpu)
+{
+ enable_percpu_irq(drv_info->sched_recv_irq, IRQ_TYPE_NONE);
+ return 0;
+}
+
+static int ffa_cpuhp_pcpu_irq_disable(unsigned int cpu)
+{
+ disable_percpu_irq(drv_info->sched_recv_irq);
+ return 0;
+}
+
+static void ffa_uninit_pcpu_irq(void)
+{
+ if (drv_info->cpuhp_state)
+ cpuhp_remove_state(drv_info->cpuhp_state);
+
+ if (drv_info->notif_pcpu_wq)
+ destroy_workqueue(drv_info->notif_pcpu_wq);
+
+ if (drv_info->sched_recv_irq)
+ free_percpu_irq(drv_info->sched_recv_irq, drv_info->irq_pcpu);
+
+ if (drv_info->irq_pcpu)
+ free_percpu(drv_info->irq_pcpu);
+}
+
+static int ffa_init_pcpu_irq(unsigned int irq)
+{
+ struct ffa_pcpu_irq __percpu *irq_pcpu;
+ int ret, cpu;
+
+ irq_pcpu = alloc_percpu(struct ffa_pcpu_irq);
+ if (!irq_pcpu)
+ return -ENOMEM;
+
+ for_each_present_cpu(cpu)
+ per_cpu_ptr(irq_pcpu, cpu)->info = drv_info;
+
+ drv_info->irq_pcpu = irq_pcpu;
+
+ ret = request_percpu_irq(irq, irq_handler, "ARM-FFA", irq_pcpu);
+ if (ret) {
+ pr_err("Error registering notification IRQ %d: %d\n", irq, ret);
+ return ret;
+ }
+
+ INIT_WORK(&drv_info->irq_work, ffa_sched_recv_irq_work_fn);
+ INIT_WORK(&drv_info->notif_pcpu_work, notif_pcpu_irq_work_fn);
+ drv_info->notif_pcpu_wq = create_workqueue("ffa_pcpu_irq_notification");
+ if (!drv_info->notif_pcpu_wq)
+ return -EINVAL;
+
+ ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "ffa/pcpu-irq:starting",
+ ffa_cpuhp_pcpu_irq_enable,
+ ffa_cpuhp_pcpu_irq_disable);
+
+ if (ret < 0)
+ return ret;
+
+ drv_info->cpuhp_state = ret;
+ return 0;
+}
+
+static void ffa_notifications_cleanup(void)
+{
+ ffa_uninit_pcpu_irq();
+ ffa_sched_recv_irq_unmap();
+
+ if (drv_info->bitmap_created) {
+ ffa_notification_bitmap_destroy();
+ drv_info->bitmap_created = false;
+ }
+}
+
+static int ffa_notifications_setup(void)
+{
+ int ret, irq;
+
+ ret = ffa_features(FFA_NOTIFICATION_BITMAP_CREATE, 0, NULL, NULL);
+ if (ret) {
+ pr_err("Notifications not supported, continuing with it ..\n");
+ return 0;
+ }
+
+ ret = ffa_notification_bitmap_create();
+ if (ret) {
+ pr_err("notification_bitmap_create error %d\n", ret);
+ return ret;
+ }
+ drv_info->bitmap_created = true;
+
+ irq = ffa_sched_recv_irq_map();
+ if (irq <= 0) {
+ ret = irq;
+ goto cleanup;
+ }
+
+ drv_info->sched_recv_irq = irq;
+
+ ret = ffa_init_pcpu_irq(irq);
+ if (ret)
+ goto cleanup;
+
+ hash_init(drv_info->notifier_hash);
+ mutex_init(&drv_info->notify_lock);
+
+ /* Register internal scheduling callback */
+ ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle,
+ drv_info, true);
+ if (!ret)
+ return ret;
+cleanup:
+ ffa_notifications_cleanup();
+ return ret;
}
static int __init ffa_init(void)
@@ -766,7 +1487,13 @@ static int __init ffa_init(void)
ffa_set_up_mem_ops_native_flag();
+ ret = ffa_notifications_setup();
+ if (ret)
+ goto partitions_cleanup;
+
return 0;
+partitions_cleanup:
+ ffa_partitions_cleanup();
free_pages:
if (drv_info->tx_buffer)
free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE);
@@ -781,9 +1508,12 @@ subsys_initcall(ffa_init);
static void __exit ffa_exit(void)
{
+ ffa_notifications_cleanup();
+ ffa_partitions_cleanup();
ffa_rxtx_unmap(drv_info->vm_id);
free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE);
free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE);
+ xa_destroy(&drv_info->partition_info);
kfree(drv_info);
arm_ffa_bus_exit();
}
diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index ea0f5083ac47..706d1264d038 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -181,6 +181,18 @@ config ARM_SCMI_POWER_DOMAIN
will be called scmi_pm_domain. Note this may needed early in boot
before rootfs may be available.
+config ARM_SCMI_PERF_DOMAIN
+ tristate "SCMI performance domain driver"
+ depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
+ default y
+ select PM_GENERIC_DOMAINS if PM
+ help
+ This enables support for the SCMI performance domains which can be
+ enabled or disabled via the SCP firmware.
+
+ This driver can also be built as a module. If so, the module will be
+ called scmi_perf_domain.
+
config ARM_SCMI_POWER_CONTROL
tristate "SCMI system power control driver"
depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index b31d78fa66cc..a7bc4796519c 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -16,7 +16,6 @@ scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o
-obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
obj-$(CONFIG_ARM_SCMI_POWER_CONTROL) += scmi_power_control.o
ifeq ($(CONFIG_THUMB2_KERNEL)$(CONFIG_CC_IS_CLANG),yy)
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 96060bf90a24..42b81c181d68 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -21,6 +21,17 @@ enum scmi_clock_protocol_cmd {
CLOCK_NAME_GET = 0x8,
CLOCK_RATE_NOTIFY = 0x9,
CLOCK_RATE_CHANGE_REQUESTED_NOTIFY = 0xA,
+ CLOCK_CONFIG_GET = 0xB,
+ CLOCK_POSSIBLE_PARENTS_GET = 0xC,
+ CLOCK_PARENT_SET = 0xD,
+ CLOCK_PARENT_GET = 0xE,
+};
+
+enum clk_state {
+ CLK_STATE_DISABLE,
+ CLK_STATE_ENABLE,
+ CLK_STATE_RESERVED,
+ CLK_STATE_UNCHANGED,
};
struct scmi_msg_resp_clock_protocol_attributes {
@@ -31,17 +42,57 @@ struct scmi_msg_resp_clock_protocol_attributes {
struct scmi_msg_resp_clock_attributes {
__le32 attributes;
-#define CLOCK_ENABLE BIT(0)
#define SUPPORTS_RATE_CHANGED_NOTIF(x) ((x) & BIT(31))
#define SUPPORTS_RATE_CHANGE_REQUESTED_NOTIF(x) ((x) & BIT(30))
#define SUPPORTS_EXTENDED_NAMES(x) ((x) & BIT(29))
+#define SUPPORTS_PARENT_CLOCK(x) ((x) & BIT(28))
u8 name[SCMI_SHORT_NAME_MAX_SIZE];
__le32 clock_enable_latency;
};
-struct scmi_clock_set_config {
+struct scmi_msg_clock_possible_parents {
+ __le32 id;
+ __le32 skip_parents;
+};
+
+struct scmi_msg_resp_clock_possible_parents {
+ __le32 num_parent_flags;
+#define NUM_PARENTS_RETURNED(x) ((x) & 0xff)
+#define NUM_PARENTS_REMAINING(x) ((x) >> 24)
+ __le32 possible_parents[];
+};
+
+struct scmi_msg_clock_set_parent {
+ __le32 id;
+ __le32 parent_id;
+};
+
+struct scmi_msg_clock_config_set {
+ __le32 id;
+ __le32 attributes;
+};
+
+/* Valid only from SCMI clock v2.1 */
+struct scmi_msg_clock_config_set_v2 {
__le32 id;
__le32 attributes;
+#define NULL_OEM_TYPE 0
+#define REGMASK_OEM_TYPE_SET GENMASK(23, 16)
+#define REGMASK_CLK_STATE GENMASK(1, 0)
+ __le32 oem_config_val;
+};
+
+struct scmi_msg_clock_config_get {
+ __le32 id;
+ __le32 flags;
+#define REGMASK_OEM_TYPE_GET GENMASK(7, 0)
+};
+
+struct scmi_msg_resp_clock_config_get {
+ __le32 attributes;
+ __le32 config;
+#define IS_CLK_ENABLED(x) le32_get_bits((x), BIT(0))
+ __le32 oem_config_val;
};
struct scmi_msg_clock_describe_rates {
@@ -100,6 +151,12 @@ struct clock_info {
int max_async_req;
atomic_t cur_async_req;
struct scmi_clock_info *clk;
+ int (*clock_config_set)(const struct scmi_protocol_handle *ph,
+ u32 clk_id, enum clk_state state,
+ u8 oem_type, u32 oem_val, bool atomic);
+ int (*clock_config_get)(const struct scmi_protocol_handle *ph,
+ u32 clk_id, u8 oem_type, u32 *attributes,
+ bool *enabled, u32 *oem_val, bool atomic);
};
static enum scmi_clock_protocol_cmd evt_2_cmd[] = {
@@ -132,6 +189,98 @@ scmi_clock_protocol_attributes_get(const struct scmi_protocol_handle *ph,
return ret;
}
+struct scmi_clk_ipriv {
+ struct device *dev;
+ u32 clk_id;
+ struct scmi_clock_info *clk;
+};
+
+static void iter_clk_possible_parents_prepare_message(void *message, unsigned int desc_index,
+ const void *priv)
+{
+ struct scmi_msg_clock_possible_parents *msg = message;
+ const struct scmi_clk_ipriv *p = priv;
+
+ msg->id = cpu_to_le32(p->clk_id);
+ /* Set the number of OPPs to be skipped/already read */
+ msg->skip_parents = cpu_to_le32(desc_index);
+}
+
+static int iter_clk_possible_parents_update_state(struct scmi_iterator_state *st,
+ const void *response, void *priv)
+{
+ const struct scmi_msg_resp_clock_possible_parents *r = response;
+ struct scmi_clk_ipriv *p = priv;
+ struct device *dev = ((struct scmi_clk_ipriv *)p)->dev;
+ u32 flags;
+
+ flags = le32_to_cpu(r->num_parent_flags);
+ st->num_returned = NUM_PARENTS_RETURNED(flags);
+ st->num_remaining = NUM_PARENTS_REMAINING(flags);
+
+ /*
+ * num parents is not declared previously anywhere so we
+ * assume it's returned+remaining on first call.
+ */
+ if (!st->max_resources) {
+ p->clk->num_parents = st->num_returned + st->num_remaining;
+ p->clk->parents = devm_kcalloc(dev, p->clk->num_parents,
+ sizeof(*p->clk->parents),
+ GFP_KERNEL);
+ if (!p->clk->parents) {
+ p->clk->num_parents = 0;
+ return -ENOMEM;
+ }
+ st->max_resources = st->num_returned + st->num_remaining;
+ }
+
+ return 0;
+}
+
+static int iter_clk_possible_parents_process_response(const struct scmi_protocol_handle *ph,
+ const void *response,
+ struct scmi_iterator_state *st,
+ void *priv)
+{
+ const struct scmi_msg_resp_clock_possible_parents *r = response;
+ struct scmi_clk_ipriv *p = priv;
+
+ u32 *parent = &p->clk->parents[st->desc_index + st->loop_idx];
+
+ *parent = le32_to_cpu(r->possible_parents[st->loop_idx]);
+
+ return 0;
+}
+
+static int scmi_clock_possible_parents(const struct scmi_protocol_handle *ph, u32 clk_id,
+ struct scmi_clock_info *clk)
+{
+ struct scmi_iterator_ops ops = {
+ .prepare_message = iter_clk_possible_parents_prepare_message,
+ .update_state = iter_clk_possible_parents_update_state,
+ .process_response = iter_clk_possible_parents_process_response,
+ };
+
+ struct scmi_clk_ipriv ppriv = {
+ .clk_id = clk_id,
+ .clk = clk,
+ .dev = ph->dev,
+ };
+ void *iter;
+ int ret;
+
+ iter = ph->hops->iter_response_init(ph, &ops, 0,
+ CLOCK_POSSIBLE_PARENTS_GET,
+ sizeof(struct scmi_msg_clock_possible_parents),
+ &ppriv);
+ if (IS_ERR(iter))
+ return PTR_ERR(iter);
+
+ ret = ph->hops->iter_response_run(iter);
+
+ return ret;
+}
+
static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
u32 clk_id, struct scmi_clock_info *clk,
u32 version)
@@ -176,6 +325,8 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
clk->rate_changed_notifications = true;
if (SUPPORTS_RATE_CHANGE_REQUESTED_NOTIF(attributes))
clk->rate_change_requested_notifications = true;
+ if (SUPPORTS_PARENT_CLOCK(attributes))
+ scmi_clock_possible_parents(ph, clk_id, clk);
}
return ret;
@@ -193,12 +344,6 @@ static int rate_cmp_func(const void *_r1, const void *_r2)
return 1;
}
-struct scmi_clk_ipriv {
- struct device *dev;
- u32 clk_id;
- struct scmi_clock_info *clk;
-};
-
static void iter_clk_describe_prepare_message(void *message,
const unsigned int desc_index,
const void *priv)
@@ -395,11 +540,105 @@ static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph,
static int
scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
- u32 config, bool atomic)
+ enum clk_state state, u8 __unused0, u32 __unused1,
+ bool atomic)
+{
+ int ret;
+ struct scmi_xfer *t;
+ struct scmi_msg_clock_config_set *cfg;
+
+ if (state >= CLK_STATE_RESERVED)
+ return -EINVAL;
+
+ ret = ph->xops->xfer_get_init(ph, CLOCK_CONFIG_SET,
+ sizeof(*cfg), 0, &t);
+ if (ret)
+ return ret;
+
+ t->hdr.poll_completion = atomic;
+
+ cfg = t->tx.buf;
+ cfg->id = cpu_to_le32(clk_id);
+ cfg->attributes = cpu_to_le32(state);
+
+ ret = ph->xops->do_xfer(ph, t);
+
+ ph->xops->xfer_put(ph, t);
+ return ret;
+}
+
+static int
+scmi_clock_set_parent(const struct scmi_protocol_handle *ph, u32 clk_id,
+ u32 parent_id)
+{
+ int ret;
+ struct scmi_xfer *t;
+ struct scmi_msg_clock_set_parent *cfg;
+ struct clock_info *ci = ph->get_priv(ph);
+ struct scmi_clock_info *clk;
+
+ if (clk_id >= ci->num_clocks)
+ return -EINVAL;
+
+ clk = ci->clk + clk_id;
+
+ if (parent_id >= clk->num_parents)
+ return -EINVAL;
+
+ ret = ph->xops->xfer_get_init(ph, CLOCK_PARENT_SET,
+ sizeof(*cfg), 0, &t);
+ if (ret)
+ return ret;
+
+ t->hdr.poll_completion = false;
+
+ cfg = t->tx.buf;
+ cfg->id = cpu_to_le32(clk_id);
+ cfg->parent_id = cpu_to_le32(clk->parents[parent_id]);
+
+ ret = ph->xops->do_xfer(ph, t);
+
+ ph->xops->xfer_put(ph, t);
+
+ return ret;
+}
+
+static int
+scmi_clock_get_parent(const struct scmi_protocol_handle *ph, u32 clk_id,
+ u32 *parent_id)
{
int ret;
struct scmi_xfer *t;
- struct scmi_clock_set_config *cfg;
+
+ ret = ph->xops->xfer_get_init(ph, CLOCK_PARENT_GET,
+ sizeof(__le32), sizeof(u32), &t);
+ if (ret)
+ return ret;
+
+ put_unaligned_le32(clk_id, t->tx.buf);
+
+ ret = ph->xops->do_xfer(ph, t);
+ if (!ret)
+ *parent_id = get_unaligned_le32(t->rx.buf);
+
+ ph->xops->xfer_put(ph, t);
+ return ret;
+}
+
+/* For SCMI clock v2.1 and onwards */
+static int
+scmi_clock_config_set_v2(const struct scmi_protocol_handle *ph, u32 clk_id,
+ enum clk_state state, u8 oem_type, u32 oem_val,
+ bool atomic)
+{
+ int ret;
+ u32 attrs;
+ struct scmi_xfer *t;
+ struct scmi_msg_clock_config_set_v2 *cfg;
+
+ if (state == CLK_STATE_RESERVED ||
+ (!oem_type && state == CLK_STATE_UNCHANGED))
+ return -EINVAL;
ret = ph->xops->xfer_get_init(ph, CLOCK_CONFIG_SET,
sizeof(*cfg), 0, &t);
@@ -408,9 +647,16 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
t->hdr.poll_completion = atomic;
+ attrs = FIELD_PREP(REGMASK_OEM_TYPE_SET, oem_type) |
+ FIELD_PREP(REGMASK_CLK_STATE, state);
+
cfg = t->tx.buf;
cfg->id = cpu_to_le32(clk_id);
- cfg->attributes = cpu_to_le32(config);
+ cfg->attributes = cpu_to_le32(attrs);
+ /* Clear in any case */
+ cfg->oem_config_val = cpu_to_le32(0);
+ if (oem_type)
+ cfg->oem_config_val = cpu_to_le32(oem_val);
ret = ph->xops->do_xfer(ph, t);
@@ -418,26 +664,124 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
return ret;
}
-static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id)
+static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id,
+ bool atomic)
{
- return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, false);
+ struct clock_info *ci = ph->get_priv(ph);
+
+ return ci->clock_config_set(ph, clk_id, CLK_STATE_ENABLE,
+ NULL_OEM_TYPE, 0, atomic);
}
-static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id)
+static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id,
+ bool atomic)
{
- return scmi_clock_config_set(ph, clk_id, 0, false);
+ struct clock_info *ci = ph->get_priv(ph);
+
+ return ci->clock_config_set(ph, clk_id, CLK_STATE_DISABLE,
+ NULL_OEM_TYPE, 0, atomic);
}
-static int scmi_clock_enable_atomic(const struct scmi_protocol_handle *ph,
- u32 clk_id)
+/* For SCMI clock v2.1 and onwards */
+static int
+scmi_clock_config_get_v2(const struct scmi_protocol_handle *ph, u32 clk_id,
+ u8 oem_type, u32 *attributes, bool *enabled,
+ u32 *oem_val, bool atomic)
{
- return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, true);
+ int ret;
+ u32 flags;
+ struct scmi_xfer *t;
+ struct scmi_msg_clock_config_get *cfg;
+
+ ret = ph->xops->xfer_get_init(ph, CLOCK_CONFIG_GET,
+ sizeof(*cfg), 0, &t);
+ if (ret)
+ return ret;
+
+ t->hdr.poll_completion = atomic;
+
+ flags = FIELD_PREP(REGMASK_OEM_TYPE_GET, oem_type);
+
+ cfg = t->tx.buf;
+ cfg->id = cpu_to_le32(clk_id);
+ cfg->flags = cpu_to_le32(flags);
+
+ ret = ph->xops->do_xfer(ph, t);
+ if (!ret) {
+ struct scmi_msg_resp_clock_config_get *resp = t->rx.buf;
+
+ if (attributes)
+ *attributes = le32_to_cpu(resp->attributes);
+
+ if (enabled)
+ *enabled = IS_CLK_ENABLED(resp->config);
+
+ if (oem_val && oem_type)
+ *oem_val = le32_to_cpu(resp->oem_config_val);
+ }
+
+ ph->xops->xfer_put(ph, t);
+
+ return ret;
+}
+
+static int
+scmi_clock_config_get(const struct scmi_protocol_handle *ph, u32 clk_id,
+ u8 oem_type, u32 *attributes, bool *enabled,
+ u32 *oem_val, bool atomic)
+{
+ int ret;
+ struct scmi_xfer *t;
+ struct scmi_msg_resp_clock_attributes *resp;
+
+ if (!enabled)
+ return -EINVAL;
+
+ ret = ph->xops->xfer_get_init(ph, CLOCK_ATTRIBUTES,
+ sizeof(clk_id), sizeof(*resp), &t);
+ if (ret)
+ return ret;
+
+ t->hdr.poll_completion = atomic;
+ put_unaligned_le32(clk_id, t->tx.buf);
+ resp = t->rx.buf;
+
+ ret = ph->xops->do_xfer(ph, t);
+ if (!ret)
+ *enabled = IS_CLK_ENABLED(resp->attributes);
+
+ ph->xops->xfer_put(ph, t);
+
+ return ret;
}
-static int scmi_clock_disable_atomic(const struct scmi_protocol_handle *ph,
- u32 clk_id)
+static int scmi_clock_state_get(const struct scmi_protocol_handle *ph,
+ u32 clk_id, bool *enabled, bool atomic)
{
- return scmi_clock_config_set(ph, clk_id, 0, true);
+ struct clock_info *ci = ph->get_priv(ph);
+
+ return ci->clock_config_get(ph, clk_id, NULL_OEM_TYPE, NULL,
+ enabled, NULL, atomic);
+}
+
+static int scmi_clock_config_oem_set(const struct scmi_protocol_handle *ph,
+ u32 clk_id, u8 oem_type, u32 oem_val,
+ bool atomic)
+{
+ struct clock_info *ci = ph->get_priv(ph);
+
+ return ci->clock_config_set(ph, clk_id, CLK_STATE_UNCHANGED,
+ oem_type, oem_val, atomic);
+}
+
+static int scmi_clock_config_oem_get(const struct scmi_protocol_handle *ph,
+ u32 clk_id, u8 oem_type, u32 *oem_val,
+ u32 *attributes, bool atomic)
+{
+ struct clock_info *ci = ph->get_priv(ph);
+
+ return ci->clock_config_get(ph, clk_id, oem_type, attributes,
+ NULL, oem_val, atomic);
}
static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
@@ -470,8 +814,11 @@ static const struct scmi_clk_proto_ops clk_proto_ops = {
.rate_set = scmi_clock_rate_set,
.enable = scmi_clock_enable,
.disable = scmi_clock_disable,
- .enable_atomic = scmi_clock_enable_atomic,
- .disable_atomic = scmi_clock_disable_atomic,
+ .state_get = scmi_clock_state_get,
+ .config_oem_get = scmi_clock_config_oem_get,
+ .config_oem_set = scmi_clock_config_oem_set,
+ .parent_set = scmi_clock_set_parent,
+ .parent_get = scmi_clock_get_parent,
};
static int scmi_clk_rate_notify(const struct scmi_protocol_handle *ph,
@@ -604,6 +951,15 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
scmi_clock_describe_rates_get(ph, clkid, clk);
}
+ if (PROTOCOL_REV_MAJOR(version) >= 0x2 &&
+ PROTOCOL_REV_MINOR(version) >= 0x1) {
+ cinfo->clock_config_set = scmi_clock_config_set_v2;
+ cinfo->clock_config_get = scmi_clock_config_get_v2;
+ } else {
+ cinfo->clock_config_set = scmi_clock_config_set;
+ cinfo->clock_config_get = scmi_clock_config_get;
+ }
+
cinfo->version = version;
return ph->set_priv(ph, cinfo);
}
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 87383c05424b..09371f40d61f 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2915,6 +2915,7 @@ static const struct of_device_id scmi_of_match[] = {
#ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
{ .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},
{ .compatible = "arm,scmi-smc-param", .data = &scmi_smc_desc},
+ { .compatible = "qcom,scmi-smc", .data = &scmi_smc_desc},
#endif
#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO
{ .compatible = "arm,scmi-virtio", .data = &scmi_virtio_desc},
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index 30dedd6ebfde..c2435be0ae1b 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -145,7 +145,6 @@ struct scmi_msg_resp_perf_describe_levels_v4 {
struct perf_dom_info {
u32 id;
bool set_limits;
- bool set_perf;
bool perf_limit_notify;
bool perf_level_notify;
bool perf_fastchannels;
@@ -154,7 +153,7 @@ struct perf_dom_info {
u32 sustained_freq_khz;
u32 sustained_perf_level;
u32 mult_factor;
- char name[SCMI_MAX_STR_SIZE];
+ struct scmi_perf_domain_info info;
struct scmi_opp opp[MAX_OPPS];
struct scmi_fc_info *fc_info;
struct xarray opps_by_idx;
@@ -257,7 +256,7 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
flags = le32_to_cpu(attr->flags);
dom_info->set_limits = SUPPORTS_SET_LIMITS(flags);
- dom_info->set_perf = SUPPORTS_SET_PERF_LVL(flags);
+ dom_info->info.set_perf = SUPPORTS_SET_PERF_LVL(flags);
dom_info->perf_limit_notify = SUPPORTS_PERF_LIMIT_NOTIFY(flags);
dom_info->perf_level_notify = SUPPORTS_PERF_LEVEL_NOTIFY(flags);
dom_info->perf_fastchannels = SUPPORTS_PERF_FASTCHANNELS(flags);
@@ -276,7 +275,8 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
dom_info->mult_factor =
(dom_info->sustained_freq_khz * 1000) /
dom_info->sustained_perf_level;
- strscpy(dom_info->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE);
+ strscpy(dom_info->info.name, attr->name,
+ SCMI_SHORT_NAME_MAX_SIZE);
}
ph->xops->xfer_put(ph, t);
@@ -288,7 +288,7 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
if (!ret && PROTOCOL_REV_MAJOR(version) >= 0x3 &&
SUPPORTS_EXTENDED_NAMES(flags))
ph->hops->extended_name_get(ph, PERF_DOMAIN_NAME_GET,
- dom_info->id, dom_info->name,
+ dom_info->id, dom_info->info.name,
SCMI_MAX_STR_SIZE);
if (dom_info->level_indexing_mode) {
@@ -423,6 +423,36 @@ scmi_perf_describe_levels_get(const struct scmi_protocol_handle *ph,
return ret;
}
+static int scmi_perf_num_domains_get(const struct scmi_protocol_handle *ph)
+{
+ struct scmi_perf_info *pi = ph->get_priv(ph);
+
+ return pi->num_domains;
+}
+
+static inline struct perf_dom_info *
+scmi_perf_domain_lookup(const struct scmi_protocol_handle *ph, u32 domain)
+{
+ struct scmi_perf_info *pi = ph->get_priv(ph);
+
+ if (domain >= pi->num_domains)
+ return ERR_PTR(-EINVAL);
+
+ return pi->dom_info + domain;
+}
+
+static const struct scmi_perf_domain_info *
+scmi_perf_info_get(const struct scmi_protocol_handle *ph, u32 domain)
+{
+ struct perf_dom_info *dom;
+
+ dom = scmi_perf_domain_lookup(ph, domain);
+ if (IS_ERR(dom))
+ return ERR_PTR(-EINVAL);
+
+ return &dom->info;
+}
+
static int scmi_perf_msg_limits_set(const struct scmi_protocol_handle *ph,
u32 domain, u32 max_perf, u32 min_perf)
{
@@ -446,17 +476,6 @@ static int scmi_perf_msg_limits_set(const struct scmi_protocol_handle *ph,
return ret;
}
-static inline struct perf_dom_info *
-scmi_perf_domain_lookup(const struct scmi_protocol_handle *ph, u32 domain)
-{
- struct scmi_perf_info *pi = ph->get_priv(ph);
-
- if (domain >= pi->num_domains)
- return ERR_PTR(-EINVAL);
-
- return pi->dom_info + domain;
-}
-
static int __scmi_perf_limits_set(const struct scmi_protocol_handle *ph,
struct perf_dom_info *dom, u32 max_perf,
u32 min_perf)
@@ -763,71 +782,46 @@ static void scmi_perf_domain_init_fc(const struct scmi_protocol_handle *ph,
*p_fc = fc;
}
-/* Device specific ops */
-static int scmi_dev_domain_id(struct device *dev)
-{
- struct of_phandle_args clkspec;
-
- if (of_parse_phandle_with_args(dev->of_node, "clocks", "#clock-cells",
- 0, &clkspec))
- return -EINVAL;
-
- return clkspec.args[0];
-}
-
static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
- struct device *dev)
+ struct device *dev, u32 domain)
{
- int idx, ret, domain;
+ int idx, ret;
unsigned long freq;
- struct scmi_opp *opp;
+ struct dev_pm_opp_data data = {};
struct perf_dom_info *dom;
- domain = scmi_dev_domain_id(dev);
- if (domain < 0)
- return -EINVAL;
-
dom = scmi_perf_domain_lookup(ph, domain);
if (IS_ERR(dom))
return PTR_ERR(dom);
- for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) {
+ for (idx = 0; idx < dom->opp_count; idx++) {
if (!dom->level_indexing_mode)
- freq = opp->perf * dom->mult_factor;
+ freq = dom->opp[idx].perf * dom->mult_factor;
else
- freq = opp->indicative_freq * 1000;
+ freq = dom->opp[idx].indicative_freq * 1000;
+
+ data.level = dom->opp[idx].perf;
+ data.freq = freq;
- ret = dev_pm_opp_add(dev, freq, 0);
+ ret = dev_pm_opp_add_dynamic(dev, &data);
if (ret) {
dev_warn(dev, "failed to add opp %luHz\n", freq);
-
- while (idx-- > 0) {
- if (!dom->level_indexing_mode)
- freq = (--opp)->perf * dom->mult_factor;
- else
- freq = (--opp)->indicative_freq * 1000;
- dev_pm_opp_remove(dev, freq);
- }
+ dev_pm_opp_remove_all_dynamic(dev);
return ret;
}
dev_dbg(dev, "[%d][%s]:: Registered OPP[%d] %lu\n",
- domain, dom->name, idx, freq);
+ domain, dom->info.name, idx, freq);
}
return 0;
}
static int
scmi_dvfs_transition_latency_get(const struct scmi_protocol_handle *ph,
- struct device *dev)
+ u32 domain)
{
- int domain;
struct perf_dom_info *dom;
- domain = scmi_dev_domain_id(dev);
- if (domain < 0)
- return -EINVAL;
-
dom = scmi_perf_domain_lookup(ph, domain);
if (IS_ERR(dom))
return PTR_ERR(dom);
@@ -923,15 +917,10 @@ static int scmi_dvfs_est_power_get(const struct scmi_protocol_handle *ph,
}
static bool scmi_fast_switch_possible(const struct scmi_protocol_handle *ph,
- struct device *dev)
+ u32 domain)
{
- int domain;
struct perf_dom_info *dom;
- domain = scmi_dev_domain_id(dev);
- if (domain < 0)
- return false;
-
dom = scmi_perf_domain_lookup(ph, domain);
if (IS_ERR(dom))
return false;
@@ -948,11 +937,12 @@ scmi_power_scale_get(const struct scmi_protocol_handle *ph)
}
static const struct scmi_perf_proto_ops perf_proto_ops = {
+ .num_domains_get = scmi_perf_num_domains_get,
+ .info_get = scmi_perf_info_get,
.limits_set = scmi_perf_limits_set,
.limits_get = scmi_perf_limits_get,
.level_set = scmi_perf_level_set,
.level_get = scmi_perf_level_get,
- .device_domain_id = scmi_dev_domain_id,
.transition_latency_get = scmi_dvfs_transition_latency_get,
.device_opps_add = scmi_dvfs_device_opps_add,
.freq_set = scmi_dvfs_freq_set,
diff --git a/drivers/firmware/arm_scmi/powercap.c b/drivers/firmware/arm_scmi/powercap.c
index 244929cb4f3e..cb5617443a14 100644
--- a/drivers/firmware/arm_scmi/powercap.c
+++ b/drivers/firmware/arm_scmi/powercap.c
@@ -360,8 +360,8 @@ static int scmi_powercap_xfer_cap_set(const struct scmi_protocol_handle *ph,
msg = t->tx.buf;
msg->domain = cpu_to_le32(pc->id);
msg->flags =
- cpu_to_le32(FIELD_PREP(CAP_SET_ASYNC, !!pc->async_powercap_cap_set) |
- FIELD_PREP(CAP_SET_IGNORE_DRESP, !!ignore_dresp));
+ cpu_to_le32(FIELD_PREP(CAP_SET_ASYNC, pc->async_powercap_cap_set) |
+ FIELD_PREP(CAP_SET_IGNORE_DRESP, ignore_dresp));
msg->value = cpu_to_le32(power_cap);
if (!pc->async_powercap_cap_set || ignore_dresp) {
diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
index c193516a254d..7611e9665038 100644
--- a/drivers/firmware/arm_scmi/smc.c
+++ b/drivers/firmware/arm_scmi/smc.c
@@ -15,6 +15,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
+#include <linux/limits.h>
#include <linux/processor.h>
#include <linux/slab.h>
@@ -50,6 +51,8 @@
* @func_id: smc/hvc call function id
* @param_page: 4K page number of the shmem channel
* @param_offset: Offset within the 4K page of the shmem channel
+ * @cap_id: smc/hvc doorbell's capability id to be used on Qualcomm virtual
+ * platforms
*/
struct scmi_smc {
@@ -60,9 +63,10 @@ struct scmi_smc {
struct mutex shmem_lock;
#define INFLIGHT_NONE MSG_TOKEN_MAX
atomic_t inflight;
- u32 func_id;
- u32 param_page;
- u32 param_offset;
+ unsigned long func_id;
+ unsigned long param_page;
+ unsigned long param_offset;
+ unsigned long cap_id;
};
static irqreturn_t smc_msg_done_isr(int irq, void *data)
@@ -124,6 +128,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
bool tx)
{
struct device *cdev = cinfo->dev;
+ unsigned long cap_id = ULONG_MAX;
struct scmi_smc *scmi_info;
resource_size_t size;
struct resource res;
@@ -162,6 +167,18 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
if (ret < 0)
return ret;
+ if (of_device_is_compatible(dev->of_node, "qcom,scmi-smc")) {
+ void __iomem *ptr = (void __iomem *)scmi_info->shmem + size - 8;
+ /* The capability-id is kept in last 8 bytes of shmem.
+ * +-------+ <-- 0
+ * | shmem |
+ * +-------+ <-- size - 8
+ * | capId |
+ * +-------+ <-- size
+ */
+ memcpy_fromio(&cap_id, ptr, sizeof(cap_id));
+ }
+
if (of_device_is_compatible(dev->of_node, "arm,scmi-smc-param")) {
scmi_info->param_page = SHMEM_PAGE(res.start);
scmi_info->param_offset = SHMEM_OFFSET(res.start);
@@ -184,6 +201,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
}
scmi_info->func_id = func_id;
+ scmi_info->cap_id = cap_id;
scmi_info->cinfo = cinfo;
smc_channel_lock_init(scmi_info);
cinfo->transport_info = scmi_info;
@@ -211,8 +229,6 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
{
struct scmi_smc *scmi_info = cinfo->transport_info;
struct arm_smccc_res res;
- unsigned long page = scmi_info->param_page;
- unsigned long offset = scmi_info->param_offset;
/*
* Channel will be released only once response has been
@@ -222,8 +238,13 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
shmem_tx_prepare(scmi_info->shmem, xfer, cinfo);
- arm_smccc_1_1_invoke(scmi_info->func_id, page, offset, 0, 0, 0, 0, 0,
- &res);
+ if (scmi_info->cap_id != ULONG_MAX)
+ arm_smccc_1_1_invoke(scmi_info->func_id, scmi_info->cap_id, 0,
+ 0, 0, 0, 0, 0, &res);
+ else
+ arm_smccc_1_1_invoke(scmi_info->func_id, scmi_info->param_page,
+ scmi_info->param_offset, 0, 0, 0, 0, 0,
+ &res);
/* Only SMCCC_RET_NOT_SUPPORTED is valid error code */
if (res.a0) {
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index 435d0e2658a4..3f123f592cb4 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -26,9 +26,12 @@
#include <linux/list.h>
#include <linux/mailbox_client.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
+#include <linux/platform_device.h>
#include <linux/printk.h>
+#include <linux/property.h>
#include <linux/pm_opp.h>
#include <linux/scpi_protocol.h>
#include <linux/slab.h>
@@ -894,11 +897,6 @@ static int scpi_alloc_xfer_list(struct device *dev, struct scpi_chan *ch)
return 0;
}
-static const struct of_device_id legacy_scpi_of_match[] = {
- {.compatible = "arm,scpi-pre-1.0"},
- {},
-};
-
static const struct of_device_id shmem_of_match[] __maybe_unused = {
{ .compatible = "amlogic,meson-gxbb-scp-shmem", },
{ .compatible = "amlogic,meson-axg-scp-shmem", },
@@ -919,8 +917,7 @@ static int scpi_probe(struct platform_device *pdev)
if (!scpi_drvinfo)
return -ENOMEM;
- if (of_match_device(legacy_scpi_of_match, &pdev->dev))
- scpi_drvinfo->is_legacy = true;
+ scpi_drvinfo->is_legacy = !!device_get_match_data(dev);
count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells");
if (count < 0) {
@@ -1038,7 +1035,7 @@ static int scpi_probe(struct platform_device *pdev)
static const struct of_device_id scpi_of_match[] = {
{.compatible = "arm,scpi"},
- {.compatible = "arm,scpi-pre-1.0"},
+ {.compatible = "arm,scpi-pre-1.0", .data = (void *)1UL },
{},
};
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 231f1c70d1db..cb374b2da9b7 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -4,7 +4,7 @@ menu "EFI (Extensible Firmware Interface) Support"
config EFI_ESRT
bool
- depends on EFI && !IA64
+ depends on EFI
default y
config EFI_VARS_PSTORE
@@ -123,7 +123,7 @@ config EFI_BOOTLOADER_CONTROL
config EFI_CAPSULE_LOADER
tristate "EFI capsule loader"
- depends on EFI && !IA64
+ depends on EFI
help
This option exposes a loader interface "/dev/efi_capsule_loader" for
users to load EFI capsules. This driver requires working runtime
@@ -224,7 +224,7 @@ config EFI_DISABLE_PCI_DMA
config EFI_EARLYCON
def_bool y
- depends on SERIAL_EARLYCON && !ARM && !IA64
+ depends on SERIAL_EARLYCON && !ARM
select FONT_SUPPORT
select ARCH_USE_MEMREMAP_PROT
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 1974f0ad32ba..9d3910d1abe1 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -147,7 +147,7 @@ static ssize_t systab_show(struct kobject *kobj,
if (efi.smbios != EFI_INVALID_TABLE_ADDR)
str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
- if (IS_ENABLED(CONFIG_IA64) || IS_ENABLED(CONFIG_X86))
+ if (IS_ENABLED(CONFIG_X86))
str = efi_systab_show_arch(str);
return str - buf;
@@ -807,7 +807,6 @@ int __init efi_systab_check_header(const efi_table_hdr_t *systab_hdr)
return 0;
}
-#ifndef CONFIG_IA64
static const efi_char16_t *__init map_fw_vendor(unsigned long fw_vendor,
size_t size)
{
@@ -823,10 +822,6 @@ static void __init unmap_fw_vendor(const void *fw_vendor, size_t size)
{
early_memunmap((void *)fw_vendor, size);
}
-#else
-#define map_fw_vendor(p, s) __va(p)
-#define unmap_fw_vendor(v, s)
-#endif
void __init efi_systab_report_header(const efi_table_hdr_t *systab_hdr,
unsigned long fw_vendor)
@@ -930,11 +925,6 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
}
/*
- * IA64 has a funky EFI memory map that doesn't work the same way as
- * other architectures.
- */
-#ifndef CONFIG_IA64
-/*
* efi_mem_attributes - lookup memmap attributes for physical address
* @phys_addr: the physical address to lookup
*
@@ -981,7 +971,6 @@ int efi_mem_type(unsigned long phys_addr)
}
return -EINVAL;
}
-#endif
int efi_status_to_err(efi_status_t status)
{
diff --git a/drivers/firmware/imx/Kconfig b/drivers/firmware/imx/Kconfig
index c027d99f2a59..183613f82a11 100644
--- a/drivers/firmware/imx/Kconfig
+++ b/drivers/firmware/imx/Kconfig
@@ -22,9 +22,3 @@ config IMX_SCU
This driver manages the IPC interface between host CPU and the
SCU firmware running on M4.
-
-config IMX_SCU_PD
- bool "IMX SCU Power Domain driver"
- depends on IMX_SCU
- help
- The System Controller Firmware (SCFW) based power domain driver.
diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index 9a2656d73600..ed60f1103053 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -13,9 +13,10 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
+#include <linux/property.h>
#include <linux/types.h>
#include <linux/sizes.h>
#include <linux/slab.h>
@@ -67,7 +68,7 @@ static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip,
return cmd->smc_id;
}
-static u32 __meson_sm_call(u32 cmd, u32 arg0, u32 arg1, u32 arg2,
+static s32 __meson_sm_call(u32 cmd, u32 arg0, u32 arg1, u32 arg2,
u32 arg3, u32 arg4)
{
struct arm_smccc_res res;
@@ -102,9 +103,10 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
* Return: 0 on success, a negative value on error
*/
int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
- u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+ s32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
- u32 cmd, lret;
+ u32 cmd;
+ s32 lret;
if (!fw->chip)
return -ENOENT;
@@ -143,7 +145,7 @@ int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
unsigned int bsize, unsigned int cmd_index, u32 arg0,
u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
- u32 size;
+ s32 size;
int ret;
if (!fw->chip)
@@ -158,11 +160,16 @@ int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
return -EINVAL;
- if (size > bsize)
+ if (size < 0 || size > bsize)
return -EINVAL;
ret = size;
+ /* In some cases (for example GET_CHIP_ID command),
+ * SMC doesn't return the number of bytes read, even
+ * though the bytes were actually read into sm_shmem_out.
+ * So this check is needed.
+ */
if (!size)
size = bsize;
@@ -192,7 +199,7 @@ int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
unsigned int size, unsigned int cmd_index, u32 arg0,
u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
- u32 written;
+ s32 written;
if (!fw->chip)
return -ENOENT;
@@ -208,7 +215,7 @@ int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
return -EINVAL;
- if (!written)
+ if (written <= 0 || written > size)
return -EINVAL;
return written;
@@ -291,7 +298,7 @@ static int __init meson_sm_probe(struct platform_device *pdev)
if (!fw)
return -ENOMEM;
- chip = of_match_device(meson_sm_ids, dev)->data;
+ chip = device_get_match_data(dev);
if (!chip)
return -EINVAL;
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
deleted file mode 100644
index 715a45442d1c..000000000000
--- a/drivers/firmware/pcdp.c
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Parse the EFI PCDP table to locate the console device.
- *
- * (c) Copyright 2002, 2003, 2004 Hewlett-Packard Development Company, L.P.
- * Khalid Aziz <khalid.aziz@hp.com>
- * Alex Williamson <alex.williamson@hp.com>
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- */
-
-#include <linux/acpi.h>
-#include <linux/console.h>
-#include <linux/efi.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <asm/vga.h>
-#include "pcdp.h"
-
-static int __init
-setup_serial_console(struct pcdp_uart *uart)
-{
-#ifdef CONFIG_SERIAL_8250_CONSOLE
- int mmio;
- static char options[64], *p = options;
- char parity;
-
- mmio = (uart->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
- p += sprintf(p, "uart8250,%s,0x%llx",
- mmio ? "mmio" : "io", uart->addr.address);
- if (uart->baud) {
- p += sprintf(p, ",%llu", uart->baud);
- if (uart->bits) {
- switch (uart->parity) {
- case 0x2: parity = 'e'; break;
- case 0x3: parity = 'o'; break;
- default: parity = 'n';
- }
- p += sprintf(p, "%c%d", parity, uart->bits);
- }
- }
-
- add_preferred_console("uart", 8250, &options[9]);
- return setup_earlycon(options);
-#else
- return -ENODEV;
-#endif
-}
-
-static int __init
-setup_vga_console(struct pcdp_device *dev)
-{
-#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
- u8 *if_ptr;
-
- if_ptr = ((u8 *)dev + sizeof(struct pcdp_device));
- if (if_ptr[0] == PCDP_IF_PCI) {
- struct pcdp_if_pci if_pci;
-
- /* struct copy since ifptr might not be correctly aligned */
-
- memcpy(&if_pci, if_ptr, sizeof(if_pci));
-
- if (if_pci.trans & PCDP_PCI_TRANS_IOPORT)
- vga_console_iobase = if_pci.ioport_tra;
-
- if (if_pci.trans & PCDP_PCI_TRANS_MMIO)
- vga_console_membase = if_pci.mmio_tra;
- }
-
- if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) {
- printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n");
- return -ENODEV;
- }
-
- conswitchp = &vga_con;
- printk(KERN_INFO "PCDP: VGA console\n");
- return 0;
-#else
- return -ENODEV;
-#endif
-}
-
-extern unsigned long hcdp_phys;
-
-int __init
-efi_setup_pcdp_console(char *cmdline)
-{
- struct pcdp *pcdp;
- struct pcdp_uart *uart;
- struct pcdp_device *dev, *end;
- int i, serial = 0;
- int rc = -ENODEV;
-
- if (hcdp_phys == EFI_INVALID_TABLE_ADDR)
- return -ENODEV;
-
- pcdp = early_memremap(hcdp_phys, 4096);
- printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, hcdp_phys);
-
- if (strstr(cmdline, "console=hcdp")) {
- if (pcdp->rev < 3)
- serial = 1;
- } else if (strstr(cmdline, "console=")) {
- printk(KERN_INFO "Explicit \"console=\"; ignoring PCDP\n");
- goto out;
- }
-
- if (pcdp->rev < 3 && efi_uart_console_only())
- serial = 1;
-
- for (i = 0, uart = pcdp->uart; i < pcdp->num_uarts; i++, uart++) {
- if (uart->flags & PCDP_UART_PRIMARY_CONSOLE || serial) {
- if (uart->type == PCDP_CONSOLE_UART) {
- rc = setup_serial_console(uart);
- goto out;
- }
- }
- }
-
- end = (struct pcdp_device *) ((u8 *) pcdp + pcdp->length);
- for (dev = (struct pcdp_device *) (pcdp->uart + pcdp->num_uarts);
- dev < end;
- dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
- if (dev->flags & PCDP_PRIMARY_CONSOLE) {
- if (dev->type == PCDP_CONSOLE_VGA) {
- rc = setup_vga_console(dev);
- goto out;
- }
- }
- }
-
-out:
- early_memunmap(pcdp, 4096);
- return rc;
-}
diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h
deleted file mode 100644
index e02540571c52..000000000000
--- a/drivers/firmware/pcdp.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Definitions for PCDP-defined console devices
- *
- * For DIG64_HCDPv10a_01.pdf and DIG64_PCDPv20.pdf (v1.0a and v2.0 resp.),
- * please see <http://www.dig64.org/specifications/>
- *
- * (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P.
- * Khalid Aziz <khalid.aziz@hp.com>
- * Bjorn Helgaas <bjorn.helgaas@hp.com>
- */
-
-#define PCDP_CONSOLE 0
-#define PCDP_DEBUG 1
-#define PCDP_CONSOLE_OUTPUT 2
-#define PCDP_CONSOLE_INPUT 3
-
-#define PCDP_UART (0 << 3)
-#define PCDP_VGA (1 << 3)
-#define PCDP_USB (2 << 3)
-
-/* pcdp_uart.type and pcdp_device.type */
-#define PCDP_CONSOLE_UART (PCDP_UART | PCDP_CONSOLE)
-#define PCDP_DEBUG_UART (PCDP_UART | PCDP_DEBUG)
-#define PCDP_CONSOLE_VGA (PCDP_VGA | PCDP_CONSOLE_OUTPUT)
-#define PCDP_CONSOLE_USB (PCDP_USB | PCDP_CONSOLE_INPUT)
-
-/* pcdp_uart.flags */
-#define PCDP_UART_EDGE_SENSITIVE (1 << 0)
-#define PCDP_UART_ACTIVE_LOW (1 << 1)
-#define PCDP_UART_PRIMARY_CONSOLE (1 << 2)
-#define PCDP_UART_IRQ (1 << 6) /* in pci_func for rev < 3 */
-#define PCDP_UART_PCI (1 << 7) /* in pci_func for rev < 3 */
-
-struct pcdp_uart {
- u8 type;
- u8 bits;
- u8 parity;
- u8 stop_bits;
- u8 pci_seg;
- u8 pci_bus;
- u8 pci_dev;
- u8 pci_func;
- u64 baud;
- struct acpi_generic_address addr;
- u16 pci_dev_id;
- u16 pci_vendor_id;
- u32 gsi;
- u32 clock_rate;
- u8 pci_prog_intfc;
- u8 flags;
- u16 conout_index;
- u32 reserved;
-} __attribute__((packed));
-
-#define PCDP_IF_PCI 1
-
-/* pcdp_if_pci.trans */
-#define PCDP_PCI_TRANS_IOPORT 0x02
-#define PCDP_PCI_TRANS_MMIO 0x01
-
-struct pcdp_if_pci {
- u8 interconnect;
- u8 reserved;
- u16 length;
- u8 segment;
- u8 bus;
- u8 dev;
- u8 fun;
- u16 dev_id;
- u16 vendor_id;
- u32 acpi_interrupt;
- u64 mmio_tra;
- u64 ioport_tra;
- u8 flags;
- u8 trans;
-} __attribute__((packed));
-
-struct pcdp_vga {
- u8 count; /* address space descriptors */
-} __attribute__((packed));
-
-/* pcdp_device.flags */
-#define PCDP_PRIMARY_CONSOLE 1
-
-struct pcdp_device {
- u8 type;
- u8 flags;
- u16 length;
- u16 efi_index;
- /* next data is pcdp_if_pci or pcdp_if_acpi (not yet supported) */
- /* next data is device specific type (currently only pcdp_vga) */
-} __attribute__((packed));
-
-struct pcdp {
- u8 signature[4];
- u32 length;
- u8 rev; /* PCDP v2.0 is rev 3 */
- u8 chksum;
- u8 oemid[6];
- u8 oem_tabid[8];
- u32 oem_rev;
- u8 creator_id[4];
- u32 creator_rev;
- u32 num_uarts;
- struct pcdp_uart uart[]; /* actual size is num_uarts */
- /* remainder of table is pcdp_device structures */
-} __attribute__((packed));
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
new file mode 100644
index 000000000000..3f05d9854ddf
--- /dev/null
+++ b/drivers/firmware/qcom/Kconfig
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.rst.
+#
+
+menu "Qualcomm firmware drivers"
+
+config QCOM_SCM
+ tristate
+
+config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
+ bool "Qualcomm download mode enabled by default"
+ depends on QCOM_SCM
+ help
+ A device with "download mode" enabled will upon an unexpected
+ warm-restart enter a special debug mode that allows the user to
+ "download" memory content over USB for offline postmortem analysis.
+ The feature can be enabled/disabled on the kernel command line.
+
+ Say Y here to enable "download mode" by default.
+
+config QCOM_QSEECOM
+ bool "Qualcomm QSEECOM interface driver"
+ depends on QCOM_SCM=y
+ select AUXILIARY_BUS
+ help
+ Various Qualcomm SoCs have a Secure Execution Environment (SEE) running
+ in the Trust Zone. This module provides an interface to that via the
+ QSEECOM mechanism, using SCM calls.
+
+ The QSEECOM interface allows, among other things, access to applications
+ running in the SEE. An example of such an application is 'uefisecapp',
+ which is required to access UEFI variables on certain systems. If
+ selected, the interface will also attempt to detect and register client
+ devices for supported applications.
+
+ Select Y here to enable the QSEECOM interface driver.
+
+config QCOM_QSEECOM_UEFISECAPP
+ bool "Qualcomm SEE UEFI Secure App client driver"
+ depends on QCOM_QSEECOM
+ depends on EFI
+ help
+ Various Qualcomm SoCs do not allow direct access to EFI variables.
+ Instead, these need to be accessed via the UEFI Secure Application
+ (uefisecapp), residing in the Secure Execution Environment (SEE).
+
+ This module provides a client driver for uefisecapp, installing efivar
+ operations to allow the kernel accessing EFI variables, and via that also
+ provide user-space with access to EFI variables via efivarfs.
+
+ Select Y here to provide access to EFI variables on the aforementioned
+ platforms.
+
+endmenu
diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
new file mode 100644
index 000000000000..c9f12ee8224a
--- /dev/null
+++ b/drivers/firmware/qcom/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the linux kernel.
+#
+
+obj-$(CONFIG_QCOM_SCM) += qcom-scm.o
+qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
+obj-$(CONFIG_QCOM_QSEECOM) += qcom_qseecom.o
+obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o
diff --git a/drivers/firmware/qcom/qcom_qseecom.c b/drivers/firmware/qcom/qcom_qseecom.c
new file mode 100644
index 000000000000..731e6d5719f9
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_qseecom.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Driver for Qualcomm Secure Execution Environment (SEE) interface (QSEECOM).
+ * Responsible for setting up and managing QSEECOM client devices.
+ *
+ * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
+ */
+#include <linux/auxiliary_bus.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <linux/firmware/qcom/qcom_qseecom.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+
+struct qseecom_app_desc {
+ const char *app_name;
+ const char *dev_name;
+};
+
+static void qseecom_client_release(struct device *dev)
+{
+ struct qseecom_client *client;
+
+ client = container_of(dev, struct qseecom_client, aux_dev.dev);
+ kfree(client);
+}
+
+static void qseecom_client_remove(void *data)
+{
+ struct qseecom_client *client = data;
+
+ auxiliary_device_delete(&client->aux_dev);
+ auxiliary_device_uninit(&client->aux_dev);
+}
+
+static int qseecom_client_register(struct platform_device *qseecom_dev,
+ const struct qseecom_app_desc *desc)
+{
+ struct qseecom_client *client;
+ u32 app_id;
+ int ret;
+
+ /* Try to find the app ID, skip device if not found */
+ ret = qcom_scm_qseecom_app_get_id(desc->app_name, &app_id);
+ if (ret)
+ return ret == -ENOENT ? 0 : ret;
+
+ dev_info(&qseecom_dev->dev, "setting up client for %s\n", desc->app_name);
+
+ /* Allocate and set-up the client device */
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
+ if (!client)
+ return -ENOMEM;
+
+ client->aux_dev.name = desc->dev_name;
+ client->aux_dev.dev.parent = &qseecom_dev->dev;
+ client->aux_dev.dev.release = qseecom_client_release;
+ client->app_id = app_id;
+
+ ret = auxiliary_device_init(&client->aux_dev);
+ if (ret) {
+ kfree(client);
+ return ret;
+ }
+
+ ret = auxiliary_device_add(&client->aux_dev);
+ if (ret) {
+ auxiliary_device_uninit(&client->aux_dev);
+ return ret;
+ }
+
+ ret = devm_add_action_or_reset(&qseecom_dev->dev, qseecom_client_remove, client);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * List of supported applications. One client device will be created per entry,
+ * assuming the app has already been loaded (usually by firmware bootloaders)
+ * and its ID can be queried successfully.
+ */
+static const struct qseecom_app_desc qcom_qseecom_apps[] = {
+ { "qcom.tz.uefisecapp", "uefisecapp" },
+};
+
+static int qcom_qseecom_probe(struct platform_device *qseecom_dev)
+{
+ int ret;
+ int i;
+
+ /* Set up client devices for each base application */
+ for (i = 0; i < ARRAY_SIZE(qcom_qseecom_apps); i++) {
+ ret = qseecom_client_register(qseecom_dev, &qcom_qseecom_apps[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct platform_driver qcom_qseecom_driver = {
+ .driver = {
+ .name = "qcom_qseecom",
+ },
+ .probe = qcom_qseecom_probe,
+};
+
+static int __init qcom_qseecom_init(void)
+{
+ return platform_driver_register(&qcom_qseecom_driver);
+}
+subsys_initcall(qcom_qseecom_init);
+
+MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
+MODULE_DESCRIPTION("Driver for the Qualcomm SEE (QSEECOM) interface");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
new file mode 100644
index 000000000000..a33acdaf7b78
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -0,0 +1,871 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Client driver for Qualcomm UEFI Secure Application (qcom.tz.uefisecapp).
+ * Provides access to UEFI variables on platforms where they are secured by the
+ * aforementioned Secure Execution Environment (SEE) application.
+ *
+ * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
+ */
+
+#include <linux/efi.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/ucs2_string.h>
+
+#include <linux/firmware/qcom/qcom_qseecom.h>
+
+/* -- Qualcomm "uefisecapp" interface definitions. -------------------------- */
+
+/* Maximum length of name string with null-terminator */
+#define QSEE_MAX_NAME_LEN 1024
+
+#define QSEE_CMD_UEFI(x) (0x8000 | (x))
+#define QSEE_CMD_UEFI_GET_VARIABLE QSEE_CMD_UEFI(0)
+#define QSEE_CMD_UEFI_SET_VARIABLE QSEE_CMD_UEFI(1)
+#define QSEE_CMD_UEFI_GET_NEXT_VARIABLE QSEE_CMD_UEFI(2)
+#define QSEE_CMD_UEFI_QUERY_VARIABLE_INFO QSEE_CMD_UEFI(3)
+
+/**
+ * struct qsee_req_uefi_get_variable - Request for GetVariable command.
+ * @command_id: The ID of the command. Must be %QSEE_CMD_UEFI_GET_VARIABLE.
+ * @length: Length of the request in bytes, including this struct and any
+ * parameters (name, GUID) stored after it as well as any padding
+ * thereof for alignment.
+ * @name_offset: Offset from the start of this struct to where the variable
+ * name is stored (as utf-16 string), in bytes.
+ * @name_size: Size of the name parameter in bytes, including null-terminator.
+ * @guid_offset: Offset from the start of this struct to where the GUID
+ * parameter is stored, in bytes.
+ * @guid_size: Size of the GUID parameter in bytes, i.e. sizeof(efi_guid_t).
+ * @data_size: Size of the output buffer, in bytes.
+ */
+struct qsee_req_uefi_get_variable {
+ u32 command_id;
+ u32 length;
+ u32 name_offset;
+ u32 name_size;
+ u32 guid_offset;
+ u32 guid_size;
+ u32 data_size;
+} __packed;
+
+/**
+ * struct qsee_rsp_uefi_get_variable - Response for GetVariable command.
+ * @command_id: The ID of the command. Should be %QSEE_CMD_UEFI_GET_VARIABLE.
+ * @length: Length of the response in bytes, including this struct and the
+ * returned data.
+ * @status: Status of this command.
+ * @attributes: EFI variable attributes.
+ * @data_offset: Offset from the start of this struct to where the data is
+ * stored, in bytes.
+ * @data_size: Size of the returned data, in bytes. In case status indicates
+ * that the buffer is too small, this will be the size required
+ * to store the EFI variable data.
+ */
+struct qsee_rsp_uefi_get_variable {
+ u32 command_id;
+ u32 length;
+ u32 status;
+ u32 attributes;
+ u32 data_offset;
+ u32 data_size;
+} __packed;
+
+/**
+ * struct qsee_req_uefi_set_variable - Request for the SetVariable command.
+ * @command_id: The ID of the command. Must be %QSEE_CMD_UEFI_SET_VARIABLE.
+ * @length: Length of the request in bytes, including this struct and any
+ * parameters (name, GUID, data) stored after it as well as any
+ * padding thereof required for alignment.
+ * @name_offset: Offset from the start of this struct to where the variable
+ * name is stored (as utf-16 string), in bytes.
+ * @name_size: Size of the name parameter in bytes, including null-terminator.
+ * @guid_offset: Offset from the start of this struct to where the GUID
+ * parameter is stored, in bytes.
+ * @guid_size: Size of the GUID parameter in bytes, i.e. sizeof(efi_guid_t).
+ * @attributes: The EFI variable attributes to set for this variable.
+ * @data_offset: Offset from the start of this struct to where the EFI variable
+ * data is stored, in bytes.
+ * @data_size: Size of EFI variable data, in bytes.
+ *
+ */
+struct qsee_req_uefi_set_variable {
+ u32 command_id;
+ u32 length;
+ u32 name_offset;
+ u32 name_size;
+ u32 guid_offset;
+ u32 guid_size;
+ u32 attributes;
+ u32 data_offset;
+ u32 data_size;
+} __packed;
+
+/**
+ * struct qsee_rsp_uefi_set_variable - Response for the SetVariable command.
+ * @command_id: The ID of the command. Should be %QSEE_CMD_UEFI_SET_VARIABLE.
+ * @length: The length of this response, i.e. the size of this struct in
+ * bytes.
+ * @status: Status of this command.
+ * @_unknown1: Unknown response field.
+ * @_unknown2: Unknown response field.
+ */
+struct qsee_rsp_uefi_set_variable {
+ u32 command_id;
+ u32 length;
+ u32 status;
+ u32 _unknown1;
+ u32 _unknown2;
+} __packed;
+
+/**
+ * struct qsee_req_uefi_get_next_variable - Request for the
+ * GetNextVariableName command.
+ * @command_id: The ID of the command. Must be
+ * %QSEE_CMD_UEFI_GET_NEXT_VARIABLE.
+ * @length: Length of the request in bytes, including this struct and any
+ * parameters (name, GUID) stored after it as well as any padding
+ * thereof for alignment.
+ * @guid_offset: Offset from the start of this struct to where the GUID
+ * parameter is stored, in bytes.
+ * @guid_size: Size of the GUID parameter in bytes, i.e. sizeof(efi_guid_t).
+ * @name_offset: Offset from the start of this struct to where the variable
+ * name is stored (as utf-16 string), in bytes.
+ * @name_size: Size of the name parameter in bytes, including null-terminator.
+ */
+struct qsee_req_uefi_get_next_variable {
+ u32 command_id;
+ u32 length;
+ u32 guid_offset;
+ u32 guid_size;
+ u32 name_offset;
+ u32 name_size;
+} __packed;
+
+/**
+ * struct qsee_rsp_uefi_get_next_variable - Response for the
+ * GetNextVariableName command.
+ * @command_id: The ID of the command. Should be
+ * %QSEE_CMD_UEFI_GET_NEXT_VARIABLE.
+ * @length: Length of the response in bytes, including this struct and any
+ * parameters (name, GUID) stored after it as well as any padding
+ * thereof for alignment.
+ * @status: Status of this command.
+ * @guid_offset: Offset from the start of this struct to where the GUID
+ * parameter is stored, in bytes.
+ * @guid_size: Size of the GUID parameter in bytes, i.e. sizeof(efi_guid_t).
+ * @name_offset: Offset from the start of this struct to where the variable
+ * name is stored (as utf-16 string), in bytes.
+ * @name_size: Size of the name parameter in bytes, including null-terminator.
+ */
+struct qsee_rsp_uefi_get_next_variable {
+ u32 command_id;
+ u32 length;
+ u32 status;
+ u32 guid_offset;
+ u32 guid_size;
+ u32 name_offset;
+ u32 name_size;
+} __packed;
+
+/**
+ * struct qsee_req_uefi_query_variable_info - Response for the
+ * GetNextVariableName command.
+ * @command_id: The ID of the command. Must be
+ * %QSEE_CMD_UEFI_QUERY_VARIABLE_INFO.
+ * @length: The length of this request, i.e. the size of this struct in
+ * bytes.
+ * @attributes: The storage attributes to query the info for.
+ */
+struct qsee_req_uefi_query_variable_info {
+ u32 command_id;
+ u32 length;
+ u32 attributes;
+} __packed;
+
+/**
+ * struct qsee_rsp_uefi_query_variable_info - Response for the
+ * GetNextVariableName command.
+ * @command_id: The ID of the command. Must be
+ * %QSEE_CMD_UEFI_QUERY_VARIABLE_INFO.
+ * @length: The length of this response, i.e. the size of this
+ * struct in bytes.
+ * @status: Status of this command.
+ * @_pad: Padding.
+ * @storage_space: Full storage space size, in bytes.
+ * @remaining_space: Free storage space available, in bytes.
+ * @max_variable_size: Maximum variable data size, in bytes.
+ */
+struct qsee_rsp_uefi_query_variable_info {
+ u32 command_id;
+ u32 length;
+ u32 status;
+ u32 _pad;
+ u64 storage_space;
+ u64 remaining_space;
+ u64 max_variable_size;
+} __packed;
+
+/* -- Alignment helpers ----------------------------------------------------- */
+
+/*
+ * Helper macro to ensure proper alignment of types (fields and arrays) when
+ * stored in some (contiguous) buffer.
+ *
+ * Note: The driver from which this one has been reverse-engineered expects an
+ * alignment of 8 bytes (64 bits) for GUIDs. Our definition of efi_guid_t,
+ * however, has an alignment of 4 byte (32 bits). So far, this seems to work
+ * fine here. See also the comment on the typedef of efi_guid_t.
+ */
+#define qcuefi_buf_align_fields(fields...) \
+ ({ \
+ size_t __len = 0; \
+ fields \
+ __len; \
+ })
+
+#define __field_impl(size, align, offset) \
+ ({ \
+ size_t *__offset = (offset); \
+ size_t __aligned; \
+ \
+ __aligned = ALIGN(__len, align); \
+ __len = __aligned + (size); \
+ \
+ if (__offset) \
+ *__offset = __aligned; \
+ });
+
+#define __array_offs(type, count, offset) \
+ __field_impl(sizeof(type) * (count), __alignof__(type), offset)
+
+#define __array(type, count) __array_offs(type, count, NULL)
+#define __field_offs(type, offset) __array_offs(type, 1, offset)
+#define __field(type) __array_offs(type, 1, NULL)
+
+/* -- UEFI app interface. --------------------------------------------------- */
+
+struct qcuefi_client {
+ struct qseecom_client *client;
+ struct efivars efivars;
+};
+
+static struct device *qcuefi_dev(struct qcuefi_client *qcuefi)
+{
+ return &qcuefi->client->aux_dev.dev;
+}
+
+static efi_status_t qsee_uefi_status_to_efi(u32 status)
+{
+ u64 category = status & 0xf0000000;
+ u64 code = status & 0x0fffffff;
+
+ return category << (BITS_PER_LONG - 32) | code;
+}
+
+static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const efi_char16_t *name,
+ const efi_guid_t *guid, u32 *attributes,
+ unsigned long *data_size, void *data)
+{
+ struct qsee_req_uefi_get_variable *req_data;
+ struct qsee_rsp_uefi_get_variable *rsp_data;
+ unsigned long buffer_size = *data_size;
+ efi_status_t efi_status = EFI_SUCCESS;
+ unsigned long name_length;
+ size_t guid_offs;
+ size_t name_offs;
+ size_t req_size;
+ size_t rsp_size;
+ ssize_t status;
+
+ if (!name || !guid)
+ return EFI_INVALID_PARAMETER;
+
+ name_length = ucs2_strnlen(name, QSEE_MAX_NAME_LEN) + 1;
+ if (name_length > QSEE_MAX_NAME_LEN)
+ return EFI_INVALID_PARAMETER;
+
+ if (buffer_size && !data)
+ return EFI_INVALID_PARAMETER;
+
+ req_size = qcuefi_buf_align_fields(
+ __field(*req_data)
+ __array_offs(*name, name_length, &name_offs)
+ __field_offs(*guid, &guid_offs)
+ );
+
+ rsp_size = qcuefi_buf_align_fields(
+ __field(*rsp_data)
+ __array(u8, buffer_size)
+ );
+
+ req_data = kzalloc(req_size, GFP_KERNEL);
+ if (!req_data) {
+ efi_status = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ rsp_data = kzalloc(rsp_size, GFP_KERNEL);
+ if (!rsp_data) {
+ efi_status = EFI_OUT_OF_RESOURCES;
+ goto out_free_req;
+ }
+
+ req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE;
+ req_data->data_size = buffer_size;
+ req_data->name_offset = name_offs;
+ req_data->name_size = name_length * sizeof(*name);
+ req_data->guid_offset = guid_offs;
+ req_data->guid_size = sizeof(*guid);
+ req_data->length = req_size;
+
+ status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
+ if (status < 0)
+ return EFI_INVALID_PARAMETER;
+
+ memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
+
+ status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
+ if (status) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->length < sizeof(*rsp_data)) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->status) {
+ dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
+ __func__, rsp_data->status);
+ efi_status = qsee_uefi_status_to_efi(rsp_data->status);
+
+ /* Update size and attributes in case buffer is too small. */
+ if (efi_status == EFI_BUFFER_TOO_SMALL) {
+ *data_size = rsp_data->data_size;
+ if (attributes)
+ *attributes = rsp_data->attributes;
+ }
+
+ goto out_free;
+ }
+
+ if (rsp_data->length > rsp_size) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ /*
+ * Note: We need to set attributes and data size even if the buffer is
+ * too small and we won't copy any data. This is described in spec, so
+ * that callers can either allocate a buffer properly (with two calls
+ * to this function) or just read back attributes withouth having to
+ * deal with that.
+ *
+ * Specifically:
+ * - If we have a buffer size of zero and no buffer, just return the
+ * attributes, required size, and indicate success.
+ * - If the buffer size is nonzero but too small, indicate that as an
+ * error.
+ * - Otherwise, we are good to copy the data.
+ *
+ * Note that we have already ensured above that the buffer pointer is
+ * non-NULL if its size is nonzero.
+ */
+ *data_size = rsp_data->data_size;
+ if (attributes)
+ *attributes = rsp_data->attributes;
+
+ if (buffer_size == 0 && !data) {
+ efi_status = EFI_SUCCESS;
+ goto out_free;
+ }
+
+ if (buffer_size < rsp_data->data_size) {
+ efi_status = EFI_BUFFER_TOO_SMALL;
+ goto out_free;
+ }
+
+ memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size);
+
+out_free:
+ kfree(rsp_data);
+out_free_req:
+ kfree(req_data);
+out:
+ return efi_status;
+}
+
+static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const efi_char16_t *name,
+ const efi_guid_t *guid, u32 attributes,
+ unsigned long data_size, const void *data)
+{
+ struct qsee_req_uefi_set_variable *req_data;
+ struct qsee_rsp_uefi_set_variable *rsp_data;
+ efi_status_t efi_status = EFI_SUCCESS;
+ unsigned long name_length;
+ size_t name_offs;
+ size_t guid_offs;
+ size_t data_offs;
+ size_t req_size;
+ ssize_t status;
+
+ if (!name || !guid)
+ return EFI_INVALID_PARAMETER;
+
+ name_length = ucs2_strnlen(name, QSEE_MAX_NAME_LEN) + 1;
+ if (name_length > QSEE_MAX_NAME_LEN)
+ return EFI_INVALID_PARAMETER;
+
+ /*
+ * Make sure we have some data if data_size is nonzero. Note that using
+ * a size of zero is a valid use-case described in spec and deletes the
+ * variable.
+ */
+ if (data_size && !data)
+ return EFI_INVALID_PARAMETER;
+
+ req_size = qcuefi_buf_align_fields(
+ __field(*req_data)
+ __array_offs(*name, name_length, &name_offs)
+ __field_offs(*guid, &guid_offs)
+ __array_offs(u8, data_size, &data_offs)
+ );
+
+ req_data = kzalloc(req_size, GFP_KERNEL);
+ if (!req_data) {
+ efi_status = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
+ if (!rsp_data) {
+ efi_status = EFI_OUT_OF_RESOURCES;
+ goto out_free_req;
+ }
+
+ req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
+ req_data->attributes = attributes;
+ req_data->name_offset = name_offs;
+ req_data->name_size = name_length * sizeof(*name);
+ req_data->guid_offset = guid_offs;
+ req_data->guid_size = sizeof(*guid);
+ req_data->data_offset = data_offs;
+ req_data->data_size = data_size;
+ req_data->length = req_size;
+
+ status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
+ if (status < 0)
+ return EFI_INVALID_PARAMETER;
+
+ memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
+
+ if (data_size)
+ memcpy(((void *)req_data) + req_data->data_offset, data, req_data->data_size);
+
+ status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data,
+ sizeof(*rsp_data));
+ if (status) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->length != sizeof(*rsp_data)) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->status) {
+ dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
+ __func__, rsp_data->status);
+ efi_status = qsee_uefi_status_to_efi(rsp_data->status);
+ }
+
+out_free:
+ kfree(rsp_data);
+out_free_req:
+ kfree(req_data);
+out:
+ return efi_status;
+}
+
+static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
+ unsigned long *name_size, efi_char16_t *name,
+ efi_guid_t *guid)
+{
+ struct qsee_req_uefi_get_next_variable *req_data;
+ struct qsee_rsp_uefi_get_next_variable *rsp_data;
+ efi_status_t efi_status = EFI_SUCCESS;
+ size_t guid_offs;
+ size_t name_offs;
+ size_t req_size;
+ size_t rsp_size;
+ ssize_t status;
+
+ if (!name_size || !name || !guid)
+ return EFI_INVALID_PARAMETER;
+
+ if (*name_size == 0)
+ return EFI_INVALID_PARAMETER;
+
+ req_size = qcuefi_buf_align_fields(
+ __field(*req_data)
+ __field_offs(*guid, &guid_offs)
+ __array_offs(*name, *name_size / sizeof(*name), &name_offs)
+ );
+
+ rsp_size = qcuefi_buf_align_fields(
+ __field(*rsp_data)
+ __field(*guid)
+ __array(*name, *name_size / sizeof(*name))
+ );
+
+ req_data = kzalloc(req_size, GFP_KERNEL);
+ if (!req_data) {
+ efi_status = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ rsp_data = kzalloc(rsp_size, GFP_KERNEL);
+ if (!rsp_data) {
+ efi_status = EFI_OUT_OF_RESOURCES;
+ goto out_free_req;
+ }
+
+ req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE;
+ req_data->guid_offset = guid_offs;
+ req_data->guid_size = sizeof(*guid);
+ req_data->name_offset = name_offs;
+ req_data->name_size = *name_size;
+ req_data->length = req_size;
+
+ memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
+ status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name,
+ *name_size / sizeof(*name));
+ if (status < 0)
+ return EFI_INVALID_PARAMETER;
+
+ status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
+ if (status) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->length < sizeof(*rsp_data)) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->status) {
+ dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
+ __func__, rsp_data->status);
+ efi_status = qsee_uefi_status_to_efi(rsp_data->status);
+
+ /*
+ * If the buffer to hold the name is too small, update the
+ * name_size with the required size, so that callers can
+ * reallocate it accordingly.
+ */
+ if (efi_status == EFI_BUFFER_TOO_SMALL)
+ *name_size = rsp_data->name_size;
+
+ goto out_free;
+ }
+
+ if (rsp_data->length > rsp_size) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->name_size > *name_size) {
+ *name_size = rsp_data->name_size;
+ efi_status = EFI_BUFFER_TOO_SMALL;
+ goto out_free;
+ }
+
+ if (rsp_data->guid_size != sizeof(*guid)) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ memcpy(guid, ((void *)rsp_data) + rsp_data->guid_offset, rsp_data->guid_size);
+ status = ucs2_strscpy(name, ((void *)rsp_data) + rsp_data->name_offset,
+ rsp_data->name_size / sizeof(*name));
+ *name_size = rsp_data->name_size;
+
+ if (status < 0) {
+ /*
+ * Return EFI_DEVICE_ERROR here because the buffer size should
+ * have already been validated above, causing this function to
+ * bail with EFI_BUFFER_TOO_SMALL.
+ */
+ return EFI_DEVICE_ERROR;
+ }
+
+out_free:
+ kfree(rsp_data);
+out_free_req:
+ kfree(req_data);
+out:
+ return efi_status;
+}
+
+static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, u32 attr,
+ u64 *storage_space, u64 *remaining_space,
+ u64 *max_variable_size)
+{
+ struct qsee_req_uefi_query_variable_info *req_data;
+ struct qsee_rsp_uefi_query_variable_info *rsp_data;
+ efi_status_t efi_status = EFI_SUCCESS;
+ int status;
+
+ req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
+ if (!req_data) {
+ efi_status = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
+ if (!rsp_data) {
+ efi_status = EFI_OUT_OF_RESOURCES;
+ goto out_free_req;
+ }
+
+ req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
+ req_data->attributes = attr;
+ req_data->length = sizeof(*req_data);
+
+ status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data,
+ sizeof(*rsp_data));
+ if (status) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->length != sizeof(*rsp_data)) {
+ efi_status = EFI_DEVICE_ERROR;
+ goto out_free;
+ }
+
+ if (rsp_data->status) {
+ dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
+ __func__, rsp_data->status);
+ efi_status = qsee_uefi_status_to_efi(rsp_data->status);
+ goto out_free;
+ }
+
+ if (storage_space)
+ *storage_space = rsp_data->storage_space;
+
+ if (remaining_space)
+ *remaining_space = rsp_data->remaining_space;
+
+ if (max_variable_size)
+ *max_variable_size = rsp_data->max_variable_size;
+
+out_free:
+ kfree(rsp_data);
+out_free_req:
+ kfree(req_data);
+out:
+ return efi_status;
+}
+
+/* -- Global efivar interface. ---------------------------------------------- */
+
+static struct qcuefi_client *__qcuefi;
+static DEFINE_MUTEX(__qcuefi_lock);
+
+static int qcuefi_set_reference(struct qcuefi_client *qcuefi)
+{
+ mutex_lock(&__qcuefi_lock);
+
+ if (qcuefi && __qcuefi) {
+ mutex_unlock(&__qcuefi_lock);
+ return -EEXIST;
+ }
+
+ __qcuefi = qcuefi;
+
+ mutex_unlock(&__qcuefi_lock);
+ return 0;
+}
+
+static struct qcuefi_client *qcuefi_acquire(void)
+{
+ mutex_lock(&__qcuefi_lock);
+ return __qcuefi;
+}
+
+static void qcuefi_release(void)
+{
+ mutex_unlock(&__qcuefi_lock);
+}
+
+static efi_status_t qcuefi_get_variable(efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
+ unsigned long *data_size, void *data)
+{
+ struct qcuefi_client *qcuefi;
+ efi_status_t status;
+
+ qcuefi = qcuefi_acquire();
+ if (!qcuefi)
+ return EFI_NOT_READY;
+
+ status = qsee_uefi_get_variable(qcuefi, name, vendor, attr, data_size, data);
+
+ qcuefi_release();
+ return status;
+}
+
+static efi_status_t qcuefi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 attr, unsigned long data_size, void *data)
+{
+ struct qcuefi_client *qcuefi;
+ efi_status_t status;
+
+ qcuefi = qcuefi_acquire();
+ if (!qcuefi)
+ return EFI_NOT_READY;
+
+ status = qsee_uefi_set_variable(qcuefi, name, vendor, attr, data_size, data);
+
+ qcuefi_release();
+ return status;
+}
+
+static efi_status_t qcuefi_get_next_variable(unsigned long *name_size, efi_char16_t *name,
+ efi_guid_t *vendor)
+{
+ struct qcuefi_client *qcuefi;
+ efi_status_t status;
+
+ qcuefi = qcuefi_acquire();
+ if (!qcuefi)
+ return EFI_NOT_READY;
+
+ status = qsee_uefi_get_next_variable(qcuefi, name_size, name, vendor);
+
+ qcuefi_release();
+ return status;
+}
+
+static efi_status_t qcuefi_query_variable_info(u32 attr, u64 *storage_space, u64 *remaining_space,
+ u64 *max_variable_size)
+{
+ struct qcuefi_client *qcuefi;
+ efi_status_t status;
+
+ qcuefi = qcuefi_acquire();
+ if (!qcuefi)
+ return EFI_NOT_READY;
+
+ status = qsee_uefi_query_variable_info(qcuefi, attr, storage_space, remaining_space,
+ max_variable_size);
+
+ qcuefi_release();
+ return status;
+}
+
+static const struct efivar_operations qcom_efivar_ops = {
+ .get_variable = qcuefi_get_variable,
+ .set_variable = qcuefi_set_variable,
+ .get_next_variable = qcuefi_get_next_variable,
+ .query_variable_info = qcuefi_query_variable_info,
+};
+
+/* -- Driver setup. --------------------------------------------------------- */
+
+static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
+ const struct auxiliary_device_id *aux_dev_id)
+{
+ struct qcuefi_client *qcuefi;
+ int status;
+
+ qcuefi = devm_kzalloc(&aux_dev->dev, sizeof(*qcuefi), GFP_KERNEL);
+ if (!qcuefi)
+ return -ENOMEM;
+
+ qcuefi->client = container_of(aux_dev, struct qseecom_client, aux_dev);
+
+ auxiliary_set_drvdata(aux_dev, qcuefi);
+ status = qcuefi_set_reference(qcuefi);
+ if (status)
+ return status;
+
+ status = efivars_register(&qcuefi->efivars, &qcom_efivar_ops);
+ if (status)
+ qcuefi_set_reference(NULL);
+
+ return status;
+}
+
+static void qcom_uefisecapp_remove(struct auxiliary_device *aux_dev)
+{
+ struct qcuefi_client *qcuefi = auxiliary_get_drvdata(aux_dev);
+
+ efivars_unregister(&qcuefi->efivars);
+ qcuefi_set_reference(NULL);
+}
+
+static const struct auxiliary_device_id qcom_uefisecapp_id_table[] = {
+ { .name = "qcom_qseecom.uefisecapp" },
+ {}
+};
+MODULE_DEVICE_TABLE(auxiliary, qcom_uefisecapp_id_table);
+
+static struct auxiliary_driver qcom_uefisecapp_driver = {
+ .probe = qcom_uefisecapp_probe,
+ .remove = qcom_uefisecapp_remove,
+ .id_table = qcom_uefisecapp_id_table,
+ .driver = {
+ .name = "qcom_qseecom_uefisecapp",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+};
+module_auxiliary_driver(qcom_uefisecapp_driver);
+
+MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
+MODULE_DESCRIPTION("Client driver for Qualcomm SEE UEFI Secure App");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/qcom_scm-legacy.c b/drivers/firmware/qcom/qcom_scm-legacy.c
index 029e6d117cb8..029e6d117cb8 100644
--- a/drivers/firmware/qcom_scm-legacy.c
+++ b/drivers/firmware/qcom/qcom_scm-legacy.c
diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom/qcom_scm-smc.c
index 16cf88acfa8e..16cf88acfa8e 100644
--- a/drivers/firmware/qcom_scm-smc.c
+++ b/drivers/firmware/qcom/qcom_scm-smc.c
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 06fe8aca870d..520de9b5633a 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -2,24 +2,25 @@
/* Copyright (c) 2010,2015,2019 The Linux Foundation. All rights reserved.
* Copyright (C) 2015 Linaro Ltd.
*/
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
+
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/cpumask.h>
-#include <linux/export.h>
#include <linux/dma-mapping.h>
+#include <linux/export.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/init.h>
#include <linux/interconnect.h>
+#include <linux/interrupt.h>
#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
-#include <linux/clk.h>
+#include <linux/platform_device.h>
#include <linux/reset-controller.h>
-#include <linux/arm-smccc.h>
+#include <linux/types.h>
#include "qcom_scm.h"
@@ -55,6 +56,53 @@ struct qcom_scm_mem_map_info {
__le64 mem_size;
};
+/**
+ * struct qcom_scm_qseecom_resp - QSEECOM SCM call response.
+ * @result: Result or status of the SCM call. See &enum qcom_scm_qseecom_result.
+ * @resp_type: Type of the response. See &enum qcom_scm_qseecom_resp_type.
+ * @data: Response data. The type of this data is given in @resp_type.
+ */
+struct qcom_scm_qseecom_resp {
+ u64 result;
+ u64 resp_type;
+ u64 data;
+};
+
+enum qcom_scm_qseecom_result {
+ QSEECOM_RESULT_SUCCESS = 0,
+ QSEECOM_RESULT_INCOMPLETE = 1,
+ QSEECOM_RESULT_BLOCKED_ON_LISTENER = 2,
+ QSEECOM_RESULT_FAILURE = 0xFFFFFFFF,
+};
+
+enum qcom_scm_qseecom_resp_type {
+ QSEECOM_SCM_RES_APP_ID = 0xEE01,
+ QSEECOM_SCM_RES_QSEOS_LISTENER_ID = 0xEE02,
+};
+
+enum qcom_scm_qseecom_tz_owner {
+ QSEECOM_TZ_OWNER_SIP = 2,
+ QSEECOM_TZ_OWNER_TZ_APPS = 48,
+ QSEECOM_TZ_OWNER_QSEE_OS = 50
+};
+
+enum qcom_scm_qseecom_tz_svc {
+ QSEECOM_TZ_SVC_APP_ID_PLACEHOLDER = 0,
+ QSEECOM_TZ_SVC_APP_MGR = 1,
+ QSEECOM_TZ_SVC_INFO = 6,
+};
+
+enum qcom_scm_qseecom_tz_cmd_app {
+ QSEECOM_TZ_CMD_APP_SEND = 1,
+ QSEECOM_TZ_CMD_APP_LOOKUP = 3,
+};
+
+enum qcom_scm_qseecom_tz_cmd_info {
+ QSEECOM_TZ_CMD_INFO_VERSION = 3,
+};
+
+#define QSEECOM_MAX_APP_NAME_SIZE 64
+
/* Each bit configures cold/warm boot address for one of the 4 CPUs */
static const u8 qcom_scm_cpu_cold_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
0, BIT(0), BIT(3), BIT(5)
@@ -168,6 +216,12 @@ static enum qcom_scm_convention __get_convention(void)
return qcom_scm_convention;
/*
+ * Per the "SMC calling convention specification", the 64-bit calling
+ * convention can only be used when the client is 64-bit, otherwise
+ * system will encounter the undefined behaviour.
+ */
+#if IS_ENABLED(CONFIG_ARM64)
+ /*
* Device isn't required as there is only one argument - no device
* needed to dma_map_single to secure world
*/
@@ -187,6 +241,7 @@ static enum qcom_scm_convention __get_convention(void)
forced = true;
goto found;
}
+#endif
probed_convention = SMC_CONVENTION_ARM_32;
ret = __scm_smc_call(NULL, &desc, probed_convention, &res, true);
@@ -403,6 +458,29 @@ int qcom_scm_set_remote_state(u32 state, u32 id)
}
EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state);
+static int qcom_scm_disable_sdi(void)
+{
+ int ret;
+ struct qcom_scm_desc desc = {
+ .svc = QCOM_SCM_SVC_BOOT,
+ .cmd = QCOM_SCM_BOOT_SDI_CONFIG,
+ .args[0] = 1, /* Disable watchdog debug */
+ .args[1] = 0, /* Disable SDI */
+ .arginfo = QCOM_SCM_ARGS(2),
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+ struct qcom_scm_res res;
+
+ ret = qcom_scm_clk_enable();
+ if (ret)
+ return ret;
+ ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+ qcom_scm_clk_disable();
+
+ return ret ? : res.result[0];
+}
+
static int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
{
struct qcom_scm_desc desc = {
@@ -1321,6 +1399,340 @@ static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)
return 0;
}
+#ifdef CONFIG_QCOM_QSEECOM
+
+/* Lock for QSEECOM SCM call executions */
+static DEFINE_MUTEX(qcom_scm_qseecom_call_lock);
+
+static int __qcom_scm_qseecom_call(const struct qcom_scm_desc *desc,
+ struct qcom_scm_qseecom_resp *res)
+{
+ struct qcom_scm_res scm_res = {};
+ int status;
+
+ /*
+ * QSEECOM SCM calls should not be executed concurrently. Therefore, we
+ * require the respective call lock to be held.
+ */
+ lockdep_assert_held(&qcom_scm_qseecom_call_lock);
+
+ status = qcom_scm_call(__scm->dev, desc, &scm_res);
+
+ res->result = scm_res.result[0];
+ res->resp_type = scm_res.result[1];
+ res->data = scm_res.result[2];
+
+ if (status)
+ return status;
+
+ return 0;
+}
+
+/**
+ * qcom_scm_qseecom_call() - Perform a QSEECOM SCM call.
+ * @desc: SCM call descriptor.
+ * @res: SCM call response (output).
+ *
+ * Performs the QSEECOM SCM call described by @desc, returning the response in
+ * @rsp.
+ *
+ * Return: Zero on success, nonzero on failure.
+ */
+static int qcom_scm_qseecom_call(const struct qcom_scm_desc *desc,
+ struct qcom_scm_qseecom_resp *res)
+{
+ int status;
+
+ /*
+ * Note: Multiple QSEECOM SCM calls should not be executed same time,
+ * so lock things here. This needs to be extended to callback/listener
+ * handling when support for that is implemented.
+ */
+
+ mutex_lock(&qcom_scm_qseecom_call_lock);
+ status = __qcom_scm_qseecom_call(desc, res);
+ mutex_unlock(&qcom_scm_qseecom_call_lock);
+
+ dev_dbg(__scm->dev, "%s: owner=%x, svc=%x, cmd=%x, result=%lld, type=%llx, data=%llx\n",
+ __func__, desc->owner, desc->svc, desc->cmd, res->result,
+ res->resp_type, res->data);
+
+ if (status) {
+ dev_err(__scm->dev, "qseecom: scm call failed with error %d\n", status);
+ return status;
+ }
+
+ /*
+ * TODO: Handle incomplete and blocked calls:
+ *
+ * Incomplete and blocked calls are not supported yet. Some devices
+ * and/or commands require those, some don't. Let's warn about them
+ * prominently in case someone attempts to try these commands with a
+ * device/command combination that isn't supported yet.
+ */
+ WARN_ON(res->result == QSEECOM_RESULT_INCOMPLETE);
+ WARN_ON(res->result == QSEECOM_RESULT_BLOCKED_ON_LISTENER);
+
+ return 0;
+}
+
+/**
+ * qcom_scm_qseecom_get_version() - Query the QSEECOM version.
+ * @version: Pointer where the QSEECOM version will be stored.
+ *
+ * Performs the QSEECOM SCM querying the QSEECOM version currently running in
+ * the TrustZone.
+ *
+ * Return: Zero on success, nonzero on failure.
+ */
+static int qcom_scm_qseecom_get_version(u32 *version)
+{
+ struct qcom_scm_desc desc = {};
+ struct qcom_scm_qseecom_resp res = {};
+ u32 feature = 10;
+ int ret;
+
+ desc.owner = QSEECOM_TZ_OWNER_SIP;
+ desc.svc = QSEECOM_TZ_SVC_INFO;
+ desc.cmd = QSEECOM_TZ_CMD_INFO_VERSION;
+ desc.arginfo = QCOM_SCM_ARGS(1, QCOM_SCM_VAL);
+ desc.args[0] = feature;
+
+ ret = qcom_scm_qseecom_call(&desc, &res);
+ if (ret)
+ return ret;
+
+ *version = res.result;
+ return 0;
+}
+
+/**
+ * qcom_scm_qseecom_app_get_id() - Query the app ID for a given QSEE app name.
+ * @app_name: The name of the app.
+ * @app_id: The returned app ID.
+ *
+ * Query and return the application ID of the SEE app identified by the given
+ * name. This returned ID is the unique identifier of the app required for
+ * subsequent communication.
+ *
+ * Return: Zero on success, nonzero on failure, -ENOENT if the app has not been
+ * loaded or could not be found.
+ */
+int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id)
+{
+ unsigned long name_buf_size = QSEECOM_MAX_APP_NAME_SIZE;
+ unsigned long app_name_len = strlen(app_name);
+ struct qcom_scm_desc desc = {};
+ struct qcom_scm_qseecom_resp res = {};
+ dma_addr_t name_buf_phys;
+ char *name_buf;
+ int status;
+
+ if (app_name_len >= name_buf_size)
+ return -EINVAL;
+
+ name_buf = kzalloc(name_buf_size, GFP_KERNEL);
+ if (!name_buf)
+ return -ENOMEM;
+
+ memcpy(name_buf, app_name, app_name_len);
+
+ name_buf_phys = dma_map_single(__scm->dev, name_buf, name_buf_size, DMA_TO_DEVICE);
+ status = dma_mapping_error(__scm->dev, name_buf_phys);
+ if (status) {
+ kfree(name_buf);
+ dev_err(__scm->dev, "qseecom: failed to map dma address\n");
+ return status;
+ }
+
+ desc.owner = QSEECOM_TZ_OWNER_QSEE_OS;
+ desc.svc = QSEECOM_TZ_SVC_APP_MGR;
+ desc.cmd = QSEECOM_TZ_CMD_APP_LOOKUP;
+ desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL);
+ desc.args[0] = name_buf_phys;
+ desc.args[1] = app_name_len;
+
+ status = qcom_scm_qseecom_call(&desc, &res);
+ dma_unmap_single(__scm->dev, name_buf_phys, name_buf_size, DMA_TO_DEVICE);
+ kfree(name_buf);
+
+ if (status)
+ return status;
+
+ if (res.result == QSEECOM_RESULT_FAILURE)
+ return -ENOENT;
+
+ if (res.result != QSEECOM_RESULT_SUCCESS)
+ return -EINVAL;
+
+ if (res.resp_type != QSEECOM_SCM_RES_APP_ID)
+ return -EINVAL;
+
+ *app_id = res.data;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id);
+
+/**
+ * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
+ * @app_id: The ID of the target app.
+ * @req: Request buffer sent to the app (must be DMA-mappable).
+ * @req_size: Size of the request buffer.
+ * @rsp: Response buffer, written to by the app (must be DMA-mappable).
+ * @rsp_size: Size of the response buffer.
+ *
+ * Sends a request to the QSEE app associated with the given ID and read back
+ * its response. The caller must provide two DMA memory regions, one for the
+ * request and one for the response, and fill out the @req region with the
+ * respective (app-specific) request data. The QSEE app reads this and returns
+ * its response in the @rsp region.
+ *
+ * Return: Zero on success, nonzero on failure.
+ */
+int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
+ size_t rsp_size)
+{
+ struct qcom_scm_qseecom_resp res = {};
+ struct qcom_scm_desc desc = {};
+ dma_addr_t req_phys;
+ dma_addr_t rsp_phys;
+ int status;
+
+ /* Map request buffer */
+ req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE);
+ status = dma_mapping_error(__scm->dev, req_phys);
+ if (status) {
+ dev_err(__scm->dev, "qseecom: failed to map request buffer\n");
+ return status;
+ }
+
+ /* Map response buffer */
+ rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE);
+ status = dma_mapping_error(__scm->dev, rsp_phys);
+ if (status) {
+ dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
+ dev_err(__scm->dev, "qseecom: failed to map response buffer\n");
+ return status;
+ }
+
+ /* Set up SCM call data */
+ desc.owner = QSEECOM_TZ_OWNER_TZ_APPS;
+ desc.svc = QSEECOM_TZ_SVC_APP_ID_PLACEHOLDER;
+ desc.cmd = QSEECOM_TZ_CMD_APP_SEND;
+ desc.arginfo = QCOM_SCM_ARGS(5, QCOM_SCM_VAL,
+ QCOM_SCM_RW, QCOM_SCM_VAL,
+ QCOM_SCM_RW, QCOM_SCM_VAL);
+ desc.args[0] = app_id;
+ desc.args[1] = req_phys;
+ desc.args[2] = req_size;
+ desc.args[3] = rsp_phys;
+ desc.args[4] = rsp_size;
+
+ /* Perform call */
+ status = qcom_scm_qseecom_call(&desc, &res);
+
+ /* Unmap buffers */
+ dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE);
+ dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
+
+ if (status)
+ return status;
+
+ if (res.result != QSEECOM_RESULT_SUCCESS)
+ return -EIO;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send);
+
+/*
+ * We do not yet support re-entrant calls via the qseecom interface. To prevent
+ + any potential issues with this, only allow validated machines for now.
+ */
+static const struct of_device_id qcom_scm_qseecom_allowlist[] = {
+ { .compatible = "lenovo,thinkpad-x13s", },
+ { }
+};
+
+static bool qcom_scm_qseecom_machine_is_allowed(void)
+{
+ struct device_node *np;
+ bool match;
+
+ np = of_find_node_by_path("/");
+ if (!np)
+ return false;
+
+ match = of_match_node(qcom_scm_qseecom_allowlist, np);
+ of_node_put(np);
+
+ return match;
+}
+
+static void qcom_scm_qseecom_free(void *data)
+{
+ struct platform_device *qseecom_dev = data;
+
+ platform_device_del(qseecom_dev);
+ platform_device_put(qseecom_dev);
+}
+
+static int qcom_scm_qseecom_init(struct qcom_scm *scm)
+{
+ struct platform_device *qseecom_dev;
+ u32 version;
+ int ret;
+
+ /*
+ * Note: We do two steps of validation here: First, we try to query the
+ * QSEECOM version as a check to see if the interface exists on this
+ * device. Second, we check against known good devices due to current
+ * driver limitations (see comment in qcom_scm_qseecom_allowlist).
+ *
+ * Note that we deliberately do the machine check after the version
+ * check so that we can log potentially supported devices. This should
+ * be safe as downstream sources indicate that the version query is
+ * neither blocking nor reentrant.
+ */
+ ret = qcom_scm_qseecom_get_version(&version);
+ if (ret)
+ return 0;
+
+ dev_info(scm->dev, "qseecom: found qseecom with version 0x%x\n", version);
+
+ if (!qcom_scm_qseecom_machine_is_allowed()) {
+ dev_info(scm->dev, "qseecom: untested machine, skipping\n");
+ return 0;
+ }
+
+ /*
+ * Set up QSEECOM interface device. All application clients will be
+ * set up and managed by the corresponding driver for it.
+ */
+ qseecom_dev = platform_device_alloc("qcom_qseecom", -1);
+ if (!qseecom_dev)
+ return -ENOMEM;
+
+ qseecom_dev->dev.parent = scm->dev;
+
+ ret = platform_device_add(qseecom_dev);
+ if (ret) {
+ platform_device_put(qseecom_dev);
+ return ret;
+ }
+
+ return devm_add_action_or_reset(scm->dev, qcom_scm_qseecom_free, qseecom_dev);
+}
+
+#else /* CONFIG_QCOM_QSEECOM */
+
+static int qcom_scm_qseecom_init(struct qcom_scm *scm)
+{
+ return 0;
+}
+
+#endif /* CONFIG_QCOM_QSEECOM */
+
/**
* qcom_scm_is_available() - Checks if SCM is available
*/
@@ -1468,6 +1880,26 @@ static int qcom_scm_probe(struct platform_device *pdev)
if (download_mode)
qcom_scm_set_download_mode(true);
+
+ /*
+ * Disable SDI if indicated by DT that it is enabled by default.
+ */
+ if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
+ qcom_scm_disable_sdi();
+
+ /*
+ * Initialize the QSEECOM interface.
+ *
+ * Note: QSEECOM is fairly self-contained and this only adds the
+ * interface device (the driver of which does most of the heavy
+ * lifting). So any errors returned here should be either -ENOMEM or
+ * -EINVAL (with the latter only in case there's a bug in our code).
+ * This means that there is no need to bring down the whole SCM driver.
+ * Just log the error instead and let SCM live.
+ */
+ ret = qcom_scm_qseecom_init(scm);
+ WARN(ret < 0, "failed to initialize qseecom: %d\n", ret);
+
return 0;
}
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index e6e512bd57d1..4532907e8489 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -4,6 +4,8 @@
#ifndef __QCOM_SCM_INT_H
#define __QCOM_SCM_INT_H
+struct device;
+
enum qcom_scm_convention {
SMC_CONVENTION_UNKNOWN,
SMC_CONVENTION_LEGACY,
@@ -64,22 +66,22 @@ int qcom_scm_wait_for_wq_completion(u32 wq_ctx);
int scm_get_wq_ctx(u32 *wq_ctx, u32 *flags, u32 *more_pending);
#define SCM_SMC_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF))
-extern int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
- enum qcom_scm_convention qcom_convention,
- struct qcom_scm_res *res, bool atomic);
+int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
+ enum qcom_scm_convention qcom_convention,
+ struct qcom_scm_res *res, bool atomic);
#define scm_smc_call(dev, desc, res, atomic) \
__scm_smc_call((dev), (desc), qcom_scm_convention, (res), (atomic))
#define SCM_LEGACY_FNID(s, c) (((s) << 10) | ((c) & 0x3ff))
-extern int scm_legacy_call_atomic(struct device *dev,
- const struct qcom_scm_desc *desc,
- struct qcom_scm_res *res);
-extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
+int scm_legacy_call_atomic(struct device *dev, const struct qcom_scm_desc *desc,
struct qcom_scm_res *res);
+int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
+ struct qcom_scm_res *res);
#define QCOM_SCM_SVC_BOOT 0x01
#define QCOM_SCM_BOOT_SET_ADDR 0x01
#define QCOM_SCM_BOOT_TERMINATE_PC 0x02
+#define QCOM_SCM_BOOT_SDI_CONFIG 0x09
#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10
#define QCOM_SCM_BOOT_SET_ADDR_MC 0x11
#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index f66efaa5196d..4cd290a60fba 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -378,6 +378,7 @@ EXPORT_SYMBOL_GPL(rpi_firmware_get);
/**
* devm_rpi_firmware_get - Get pointer to rpi_firmware structure.
+ * @dev: The firmware device structure
* @firmware_node: Pointer to the firmware Device Tree node.
*
* Returns NULL is the firmware device is not ready.
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
index 51d062e0c3f1..c1590d3aa9cb 100644
--- a/drivers/firmware/tegra/bpmp.c
+++ b/drivers/firmware/tegra/bpmp.c
@@ -313,6 +313,8 @@ static ssize_t tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel,
return __tegra_bpmp_channel_write(channel, mrq, flags, data, size);
}
+static int __maybe_unused tegra_bpmp_resume(struct device *dev);
+
int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
struct tegra_bpmp_message *msg)
{
@@ -325,6 +327,14 @@ int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
if (!tegra_bpmp_message_valid(msg))
return -EINVAL;
+ if (bpmp->suspended) {
+ /* Reset BPMP IPC channels during resume based on flags passed */
+ if (msg->flags & TEGRA_BPMP_MESSAGE_RESET)
+ tegra_bpmp_resume(bpmp->dev);
+ else
+ return -EAGAIN;
+ }
+
channel = bpmp->tx_channel;
spin_lock(&bpmp->atomic_tx_lock);
@@ -364,6 +374,14 @@ int tegra_bpmp_transfer(struct tegra_bpmp *bpmp,
if (!tegra_bpmp_message_valid(msg))
return -EINVAL;
+ if (bpmp->suspended) {
+ /* Reset BPMP IPC channels during resume based on flags passed */
+ if (msg->flags & TEGRA_BPMP_MESSAGE_RESET)
+ tegra_bpmp_resume(bpmp->dev);
+ else
+ return -EAGAIN;
+ }
+
channel = tegra_bpmp_write_threaded(bpmp, msg->mrq, msg->tx.data,
msg->tx.size);
if (IS_ERR(channel))
@@ -796,10 +814,21 @@ deinit:
return err;
}
+static int __maybe_unused tegra_bpmp_suspend(struct device *dev)
+{
+ struct tegra_bpmp *bpmp = dev_get_drvdata(dev);
+
+ bpmp->suspended = true;
+
+ return 0;
+}
+
static int __maybe_unused tegra_bpmp_resume(struct device *dev)
{
struct tegra_bpmp *bpmp = dev_get_drvdata(dev);
+ bpmp->suspended = false;
+
if (bpmp->soc->ops->resume)
return bpmp->soc->ops->resume(bpmp);
else
@@ -807,6 +836,7 @@ static int __maybe_unused tegra_bpmp_resume(struct device *dev)
}
static const struct dev_pm_ops tegra_bpmp_pm_ops = {
+ .suspend_noirq = tegra_bpmp_suspend,
.resume_noirq = tegra_bpmp_resume,
};
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 26a37f47f4ca..7041befc756a 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -16,7 +16,10 @@
#include <linux/kernel.h>
#include <linux/mailbox_client.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/semaphore.h>
#include <linux/slab.h>
#include <linux/soc/ti/ti-msgmgr.h>
@@ -190,19 +193,6 @@ static int ti_sci_debugfs_create(struct platform_device *pdev,
return 0;
}
-/**
- * ti_sci_debugfs_destroy() - clean up log debug file
- * @pdev: platform device pointer
- * @info: Pointer to SCI entity information
- */
-static void ti_sci_debugfs_destroy(struct platform_device *pdev,
- struct ti_sci_info *info)
-{
- if (IS_ERR(info->debug_region))
- return;
-
- debugfs_remove(info->d);
-}
#else /* CONFIG_DEBUG_FS */
static inline int ti_sci_debugfs_create(struct platform_device *dev,
struct ti_sci_info *info)
@@ -485,7 +475,7 @@ static int ti_sci_cmd_get_revision(struct ti_sci_info *info)
ver->abi_major = rev_info->abi_major;
ver->abi_minor = rev_info->abi_minor;
ver->firmware_revision = rev_info->firmware_revision;
- strncpy(ver->firmware_description, rev_info->firmware_description,
+ strscpy(ver->firmware_description, rev_info->firmware_description,
sizeof(ver->firmware_description));
fail:
@@ -2886,7 +2876,6 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
const struct ti_sci_handle *ti_sci_get_handle(struct device *dev)
{
struct device_node *ti_sci_np;
- struct list_head *p;
struct ti_sci_handle *handle = NULL;
struct ti_sci_info *info;
@@ -2901,8 +2890,7 @@ const struct ti_sci_handle *ti_sci_get_handle(struct device *dev)
}
mutex_lock(&ti_sci_list_mutex);
- list_for_each(p, &ti_sci_list) {
- info = list_entry(p, struct ti_sci_info, node);
+ list_for_each_entry(info, &ti_sci_list, node) {
if (ti_sci_np == info->dev->of_node) {
handle = &info->handle;
info->users++;
@@ -3012,7 +3000,6 @@ const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
struct ti_sci_handle *handle = NULL;
struct device_node *ti_sci_np;
struct ti_sci_info *info;
- struct list_head *p;
if (!np) {
pr_err("I need a device pointer\n");
@@ -3024,8 +3011,7 @@ const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
return ERR_PTR(-ENODEV);
mutex_lock(&ti_sci_list_mutex);
- list_for_each(p, &ti_sci_list) {
- info = list_entry(p, struct ti_sci_info, node);
+ list_for_each_entry(info, &ti_sci_list, node) {
if (ti_sci_np == info->dev->of_node) {
handle = &info->handle;
info->users++;
@@ -3310,7 +3296,6 @@ MODULE_DEVICE_TABLE(of, ti_sci_of_match);
static int ti_sci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- const struct of_device_id *of_id;
const struct ti_sci_desc *desc;
struct ti_sci_xfer *xfer;
struct ti_sci_info *info = NULL;
@@ -3321,12 +3306,7 @@ static int ti_sci_probe(struct platform_device *pdev)
int reboot = 0;
u32 h_id;
- of_id = of_match_device(ti_sci_of_match, dev);
- if (!of_id) {
- dev_err(dev, "OF data missing\n");
- return -EINVAL;
- }
- desc = of_id->data;
+ desc = device_get_match_data(dev);
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
if (!info)
@@ -3449,43 +3429,12 @@ out:
return ret;
}
-static int ti_sci_remove(struct platform_device *pdev)
-{
- struct ti_sci_info *info;
- struct device *dev = &pdev->dev;
- int ret = 0;
-
- of_platform_depopulate(dev);
-
- info = platform_get_drvdata(pdev);
-
- if (info->nb.notifier_call)
- unregister_restart_handler(&info->nb);
-
- mutex_lock(&ti_sci_list_mutex);
- if (info->users)
- ret = -EBUSY;
- else
- list_del(&info->node);
- mutex_unlock(&ti_sci_list_mutex);
-
- if (!ret) {
- ti_sci_debugfs_destroy(pdev, info);
-
- /* Safe to free channels since no more users */
- mbox_free_channel(info->chan_tx);
- mbox_free_channel(info->chan_rx);
- }
-
- return ret;
-}
-
static struct platform_driver ti_sci_driver = {
.probe = ti_sci_probe,
- .remove = ti_sci_remove,
.driver = {
.name = "ti-sci",
.of_match_table = of_match_ptr(ti_sci_of_match),
+ .suppress_bind_attrs = true,
},
};
module_platform_driver(ti_sci_driver);
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index 49a743f62b4a..025dc558c94e 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -945,11 +945,11 @@ static struct {
DRM_IOCTL32_DEF(DRM_IOCTL_SG_ALLOC, compat_drm_sg_alloc),
DRM_IOCTL32_DEF(DRM_IOCTL_SG_FREE, compat_drm_sg_free),
#endif
-#if defined(CONFIG_X86) || defined(CONFIG_IA64)
+#if defined(CONFIG_X86)
DRM_IOCTL32_DEF(DRM_IOCTL_UPDATE_DRAW, compat_drm_update_draw),
#endif
DRM_IOCTL32_DEF(DRM_IOCTL_WAIT_VBLANK, compat_drm_wait_vblank),
-#if defined(CONFIG_X86) || defined(CONFIG_IA64)
+#if defined(CONFIG_X86)
DRM_IOCTL32_DEF(DRM_IOCTL_MODE_ADDFB2, compat_drm_mode_addfb2),
#endif
};
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 42ce20e72db7..faf21be724c3 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1379,7 +1379,7 @@ static long intel_vgpu_ioctl(struct vfio_device *vfio_dev, unsigned int cmd,
intel_gvt_reset_vgpu(vgpu);
return 0;
} else if (cmd == VFIO_DEVICE_QUERY_GFX_PLANE) {
- struct vfio_device_gfx_plane_info dmabuf;
+ struct vfio_device_gfx_plane_info dmabuf = {};
int ret = 0;
minsz = offsetofend(struct vfio_device_gfx_plane_info,
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 7178f298b3e6..2f3ecd7d4804 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -4836,7 +4836,6 @@ static struct ctl_table oa_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = &oa_sample_rate_hard_limit,
},
- {}
};
static u32 num_perf_groups_per_gt(struct intel_gt *gt)
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index ccad7bca3fd3..4372f5d146ab 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -148,7 +148,6 @@ static struct ctl_table hv_ctl_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE
},
- {}
};
static int hv_die_panic_notify_crash(struct notifier_block *self,
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 2b47073c61a6..0301fcad4b48 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -111,7 +111,6 @@ static struct ctl_table iwcm_ctl_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
- { }
};
/*
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index bf42650f125b..5f5ad8faf86e 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -71,7 +71,6 @@ static struct ctl_table ucma_ctl_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
- { }
};
struct ucma_file {
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index adb5173372d3..5f61672d55b7 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -19,7 +19,7 @@
#include "i8042-snirm.h"
#elif defined(CONFIG_SPARC)
#include "i8042-sparcio.h"
-#elif defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_LOONGARCH)
+#elif defined(CONFIG_X86) || defined(CONFIG_LOONGARCH)
#include "i8042-acpipnpio.h"
#else
#include "i8042-io.h"
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 2b12b583ef4b..ee9e2a2edbf5 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -7,6 +7,10 @@ config IOMMU_IOVA
config IOMMU_API
bool
+config IOMMUFD_DRIVER
+ bool
+ default n
+
menuconfig IOMMU_SUPPORT
bool "IOMMU Hardware Support"
depends on MMU
@@ -91,7 +95,7 @@ config IOMMU_DEBUGFS
choice
prompt "IOMMU default domain type"
depends on IOMMU_API
- default IOMMU_DEFAULT_DMA_LAZY if X86 || IA64
+ default IOMMU_DEFAULT_DMA_LAZY if X86
default IOMMU_DEFAULT_DMA_STRICT
help
Choose the type of IOMMU domain used to manage DMA API usage by
@@ -146,7 +150,7 @@ config OF_IOMMU
# IOMMU-agnostic DMA-mapping layer
config IOMMU_DMA
- def_bool ARM64 || IA64 || X86
+ def_bool ARM64 || X86
select DMA_OPS
select IOMMU_API
select IOMMU_IOVA
diff --git a/drivers/iommu/amd/Kconfig b/drivers/iommu/amd/Kconfig
index 9b5fc3356bf2..8bd4c3b183ec 100644
--- a/drivers/iommu/amd/Kconfig
+++ b/drivers/iommu/amd/Kconfig
@@ -10,6 +10,7 @@ config AMD_IOMMU
select IOMMU_API
select IOMMU_IOVA
select IOMMU_IO_PGTABLE
+ select IOMMUFD_DRIVER if IOMMUFD
depends on X86_64 && PCI && ACPI && HAVE_CMPXCHG_DOUBLE
help
With this option you can enable support for AMD IOMMU hardware in
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index 7dc30c2b56b3..dec4e5c2b66b 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -97,7 +97,9 @@
#define FEATURE_GATS_MASK (3ULL)
#define FEATURE_GAM_VAPIC BIT_ULL(21)
#define FEATURE_GIOSUP BIT_ULL(48)
+#define FEATURE_HASUP BIT_ULL(49)
#define FEATURE_EPHSUP BIT_ULL(50)
+#define FEATURE_HDSUP BIT_ULL(52)
#define FEATURE_SNP BIT_ULL(63)
#define FEATURE_PASID_SHIFT 32
@@ -212,6 +214,7 @@
/* macros and definitions for device table entries */
#define DEV_ENTRY_VALID 0x00
#define DEV_ENTRY_TRANSLATION 0x01
+#define DEV_ENTRY_HAD 0x07
#define DEV_ENTRY_PPR 0x34
#define DEV_ENTRY_IR 0x3d
#define DEV_ENTRY_IW 0x3e
@@ -371,9 +374,15 @@
(1ULL << (12 + (9 * (level))))
/*
+ * The IOPTE dirty bit
+ */
+#define IOMMU_PTE_HD_BIT (6)
+
+/*
* Bit value definition for I/O PTE fields
*/
#define IOMMU_PTE_PR BIT_ULL(0)
+#define IOMMU_PTE_HD BIT_ULL(IOMMU_PTE_HD_BIT)
#define IOMMU_PTE_U BIT_ULL(59)
#define IOMMU_PTE_FC BIT_ULL(60)
#define IOMMU_PTE_IR BIT_ULL(61)
@@ -384,6 +393,7 @@
*/
#define DTE_FLAG_V BIT_ULL(0)
#define DTE_FLAG_TV BIT_ULL(1)
+#define DTE_FLAG_HAD (3ULL << 7)
#define DTE_FLAG_GIOV BIT_ULL(54)
#define DTE_FLAG_GV BIT_ULL(55)
#define DTE_GLX_SHIFT (56)
@@ -413,6 +423,7 @@
#define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL)
#define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_PR)
+#define IOMMU_PTE_DIRTY(pte) ((pte) & IOMMU_PTE_HD)
#define IOMMU_PTE_PAGE(pte) (iommu_phys_to_virt((pte) & IOMMU_PAGE_MASK))
#define IOMMU_PTE_MODE(pte) (((pte) >> 9) & 0x07)
@@ -563,6 +574,7 @@ struct protection_domain {
int nid; /* Node ID */
u64 *gcr3_tbl; /* Guest CR3 table */
unsigned long flags; /* flags to find out type of domain */
+ bool dirty_tracking; /* dirty tracking is enabled in the domain */
unsigned dev_cnt; /* devices assigned to this domain */
unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
};
diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
index 2892aa1b4dc1..6c0621f6f572 100644
--- a/drivers/iommu/amd/io_pgtable.c
+++ b/drivers/iommu/amd/io_pgtable.c
@@ -486,6 +486,73 @@ static phys_addr_t iommu_v1_iova_to_phys(struct io_pgtable_ops *ops, unsigned lo
return (__pte & ~offset_mask) | (iova & offset_mask);
}
+static bool pte_test_and_clear_dirty(u64 *ptep, unsigned long size,
+ unsigned long flags)
+{
+ bool test_only = flags & IOMMU_DIRTY_NO_CLEAR;
+ bool dirty = false;
+ int i, count;
+
+ /*
+ * 2.2.3.2 Host Dirty Support
+ * When a non-default page size is used , software must OR the
+ * Dirty bits in all of the replicated host PTEs used to map
+ * the page. The IOMMU does not guarantee the Dirty bits are
+ * set in all of the replicated PTEs. Any portion of the page
+ * may have been written even if the Dirty bit is set in only
+ * one of the replicated PTEs.
+ */
+ count = PAGE_SIZE_PTE_COUNT(size);
+ for (i = 0; i < count && test_only; i++) {
+ if (test_bit(IOMMU_PTE_HD_BIT, (unsigned long *)&ptep[i])) {
+ dirty = true;
+ break;
+ }
+ }
+
+ for (i = 0; i < count && !test_only; i++) {
+ if (test_and_clear_bit(IOMMU_PTE_HD_BIT,
+ (unsigned long *)&ptep[i])) {
+ dirty = true;
+ }
+ }
+
+ return dirty;
+}
+
+static int iommu_v1_read_and_clear_dirty(struct io_pgtable_ops *ops,
+ unsigned long iova, size_t size,
+ unsigned long flags,
+ struct iommu_dirty_bitmap *dirty)
+{
+ struct amd_io_pgtable *pgtable = io_pgtable_ops_to_data(ops);
+ unsigned long end = iova + size - 1;
+
+ do {
+ unsigned long pgsize = 0;
+ u64 *ptep, pte;
+
+ ptep = fetch_pte(pgtable, iova, &pgsize);
+ if (ptep)
+ pte = READ_ONCE(*ptep);
+ if (!ptep || !IOMMU_PTE_PRESENT(pte)) {
+ pgsize = pgsize ?: PTE_LEVEL_PAGE_SIZE(0);
+ iova += pgsize;
+ continue;
+ }
+
+ /*
+ * Mark the whole IOVA range as dirty even if only one of
+ * the replicated PTEs were marked dirty.
+ */
+ if (pte_test_and_clear_dirty(ptep, pgsize, flags))
+ iommu_dirty_bitmap_record(dirty, iova, pgsize);
+ iova += pgsize;
+ } while (iova < end);
+
+ return 0;
+}
+
/*
* ----------------------------------------------------
*/
@@ -527,6 +594,7 @@ static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *coo
pgtable->iop.ops.map_pages = iommu_v1_map_pages;
pgtable->iop.ops.unmap_pages = iommu_v1_unmap_pages;
pgtable->iop.ops.iova_to_phys = iommu_v1_iova_to_phys;
+ pgtable->iop.ops.read_and_clear_dirty = iommu_v1_read_and_clear_dirty;
return &pgtable->iop;
}
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 95bd7c25ba6f..b399c5741378 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -37,6 +37,7 @@
#include <asm/iommu.h>
#include <asm/gart.h>
#include <asm/dma.h>
+#include <uapi/linux/iommufd.h>
#include "amd_iommu.h"
#include "../dma-iommu.h"
@@ -65,6 +66,7 @@ LIST_HEAD(hpet_map);
LIST_HEAD(acpihid_map);
const struct iommu_ops amd_iommu_ops;
+const struct iommu_dirty_ops amd_dirty_ops;
static ATOMIC_NOTIFIER_HEAD(ppr_notifier);
int amd_iommu_max_glx_val = -1;
@@ -1610,6 +1612,9 @@ static void set_dte_entry(struct amd_iommu *iommu, u16 devid,
pte_root |= 1ULL << DEV_ENTRY_PPR;
}
+ if (domain->dirty_tracking)
+ pte_root |= DTE_FLAG_HAD;
+
if (domain->flags & PD_IOMMUV2_MASK) {
u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
u64 glx = domain->glx;
@@ -2155,28 +2160,79 @@ static inline u64 dma_max_address(void)
return ((1ULL << PM_LEVEL_SHIFT(amd_iommu_gpt_level)) - 1);
}
-static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
+static bool amd_iommu_hd_support(struct amd_iommu *iommu)
{
+ return iommu && (iommu->features & FEATURE_HDSUP);
+}
+
+static struct iommu_domain *do_iommu_domain_alloc(unsigned int type,
+ struct device *dev, u32 flags)
+{
+ bool dirty_tracking = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
struct protection_domain *domain;
+ struct amd_iommu *iommu = NULL;
+
+ if (dev) {
+ iommu = rlookup_amd_iommu(dev);
+ if (!iommu)
+ return ERR_PTR(-ENODEV);
+ }
/*
* Since DTE[Mode]=0 is prohibited on SNP-enabled system,
* default to use IOMMU_DOMAIN_DMA[_FQ].
*/
if (amd_iommu_snp_en && (type == IOMMU_DOMAIN_IDENTITY))
- return NULL;
+ return ERR_PTR(-EINVAL);
+
+ if (dirty_tracking && !amd_iommu_hd_support(iommu))
+ return ERR_PTR(-EOPNOTSUPP);
domain = protection_domain_alloc(type);
if (!domain)
- return NULL;
+ return ERR_PTR(-ENOMEM);
domain->domain.geometry.aperture_start = 0;
domain->domain.geometry.aperture_end = dma_max_address();
domain->domain.geometry.force_aperture = true;
+ if (iommu) {
+ domain->domain.type = type;
+ domain->domain.pgsize_bitmap = iommu->iommu.ops->pgsize_bitmap;
+ domain->domain.ops = iommu->iommu.ops->default_domain_ops;
+
+ if (dirty_tracking)
+ domain->domain.dirty_ops = &amd_dirty_ops;
+ }
+
return &domain->domain;
}
+static struct iommu_domain *amd_iommu_domain_alloc(unsigned int type)
+{
+ struct iommu_domain *domain;
+
+ domain = do_iommu_domain_alloc(type, NULL, 0);
+ if (IS_ERR(domain))
+ return NULL;
+
+ return domain;
+}
+
+static struct iommu_domain *
+amd_iommu_domain_alloc_user(struct device *dev, u32 flags,
+ struct iommu_domain *parent,
+ const struct iommu_user_data *user_data)
+
+{
+ unsigned int type = IOMMU_DOMAIN_UNMANAGED;
+
+ if ((flags & ~IOMMU_HWPT_ALLOC_DIRTY_TRACKING) || parent || user_data)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ return do_iommu_domain_alloc(type, dev, flags);
+}
+
static void amd_iommu_domain_free(struct iommu_domain *dom)
{
struct protection_domain *domain;
@@ -2214,6 +2270,13 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
dev_data->defer_attach = false;
+ /*
+ * Restrict to devices with compatible IOMMU hardware support
+ * when enforcement of dirty tracking is enabled.
+ */
+ if (dom->dirty_ops && !amd_iommu_hd_support(iommu))
+ return -EINVAL;
+
if (dev_data->domain)
detach_device(dev);
@@ -2332,6 +2395,11 @@ static bool amd_iommu_capable(struct device *dev, enum iommu_cap cap)
return true;
case IOMMU_CAP_DEFERRED_FLUSH:
return true;
+ case IOMMU_CAP_DIRTY_TRACKING: {
+ struct amd_iommu *iommu = rlookup_amd_iommu(dev);
+
+ return amd_iommu_hd_support(iommu);
+ }
default:
break;
}
@@ -2339,6 +2407,73 @@ static bool amd_iommu_capable(struct device *dev, enum iommu_cap cap)
return false;
}
+static int amd_iommu_set_dirty_tracking(struct iommu_domain *domain,
+ bool enable)
+{
+ struct protection_domain *pdomain = to_pdomain(domain);
+ struct dev_table_entry *dev_table;
+ struct iommu_dev_data *dev_data;
+ bool domain_flush = false;
+ struct amd_iommu *iommu;
+ unsigned long flags;
+ u64 pte_root;
+
+ spin_lock_irqsave(&pdomain->lock, flags);
+ if (!(pdomain->dirty_tracking ^ enable)) {
+ spin_unlock_irqrestore(&pdomain->lock, flags);
+ return 0;
+ }
+
+ list_for_each_entry(dev_data, &pdomain->dev_list, list) {
+ iommu = rlookup_amd_iommu(dev_data->dev);
+ if (!iommu)
+ continue;
+
+ dev_table = get_dev_table(iommu);
+ pte_root = dev_table[dev_data->devid].data[0];
+
+ pte_root = (enable ? pte_root | DTE_FLAG_HAD :
+ pte_root & ~DTE_FLAG_HAD);
+
+ /* Flush device DTE */
+ dev_table[dev_data->devid].data[0] = pte_root;
+ device_flush_dte(dev_data);
+ domain_flush = true;
+ }
+
+ /* Flush IOTLB to mark IOPTE dirty on the next translation(s) */
+ if (domain_flush) {
+ amd_iommu_domain_flush_tlb_pde(pdomain);
+ amd_iommu_domain_flush_complete(pdomain);
+ }
+ pdomain->dirty_tracking = enable;
+ spin_unlock_irqrestore(&pdomain->lock, flags);
+
+ return 0;
+}
+
+static int amd_iommu_read_and_clear_dirty(struct iommu_domain *domain,
+ unsigned long iova, size_t size,
+ unsigned long flags,
+ struct iommu_dirty_bitmap *dirty)
+{
+ struct protection_domain *pdomain = to_pdomain(domain);
+ struct io_pgtable_ops *ops = &pdomain->iop.iop.ops;
+ unsigned long lflags;
+
+ if (!ops || !ops->read_and_clear_dirty)
+ return -EOPNOTSUPP;
+
+ spin_lock_irqsave(&pdomain->lock, lflags);
+ if (!pdomain->dirty_tracking && dirty->bitmap) {
+ spin_unlock_irqrestore(&pdomain->lock, lflags);
+ return -EINVAL;
+ }
+ spin_unlock_irqrestore(&pdomain->lock, lflags);
+
+ return ops->read_and_clear_dirty(ops, iova, size, flags, dirty);
+}
+
static void amd_iommu_get_resv_regions(struct device *dev,
struct list_head *head)
{
@@ -2461,9 +2596,15 @@ static bool amd_iommu_enforce_cache_coherency(struct iommu_domain *domain)
return true;
}
+const struct iommu_dirty_ops amd_dirty_ops = {
+ .set_dirty_tracking = amd_iommu_set_dirty_tracking,
+ .read_and_clear_dirty = amd_iommu_read_and_clear_dirty,
+};
+
const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
.domain_alloc = amd_iommu_domain_alloc,
+ .domain_alloc_user = amd_iommu_domain_alloc_user,
.probe_device = amd_iommu_probe_device,
.release_device = amd_iommu_release_device,
.probe_finalize = amd_iommu_probe_finalize,
diff --git a/drivers/iommu/intel/Kconfig b/drivers/iommu/intel/Kconfig
index 2e56bd79f589..012cd2541a68 100644
--- a/drivers/iommu/intel/Kconfig
+++ b/drivers/iommu/intel/Kconfig
@@ -11,10 +11,11 @@ config DMAR_DEBUG
config INTEL_IOMMU
bool "Support for Intel IOMMU using DMA Remapping Devices"
- depends on PCI_MSI && ACPI && (X86 || IA64)
+ depends on PCI_MSI && ACPI && X86
select DMA_OPS
select IOMMU_API
select IOMMU_IOVA
+ select IOMMUFD_DRIVER if IOMMUFD
select NEED_DMA_MAP_STATE
select DMAR_TABLE
select SWIOTLB
diff --git a/drivers/iommu/intel/Makefile b/drivers/iommu/intel/Makefile
index 7af3b8a4f2a0..5dabf081a779 100644
--- a/drivers/iommu/intel/Makefile
+++ b/drivers/iommu/intel/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_DMAR_TABLE) += dmar.o
-obj-$(CONFIG_INTEL_IOMMU) += iommu.o pasid.o
+obj-$(CONFIG_INTEL_IOMMU) += iommu.o pasid.o nested.o
obj-$(CONFIG_DMAR_TABLE) += trace.o cap_audit.o
obj-$(CONFIG_DMAR_PERF) += perf.o
obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += debugfs.o
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 3685ba90ec88..d1037280abf7 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -282,7 +282,6 @@ static LIST_HEAD(dmar_satc_units);
#define for_each_rmrr_units(rmrr) \
list_for_each_entry(rmrr, &dmar_rmrr_units, list)
-static void device_block_translation(struct device *dev);
static void intel_iommu_domain_free(struct iommu_domain *domain);
int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
@@ -300,6 +299,7 @@ static int iommu_skip_te_disable;
#define IDENTMAP_AZALIA 4
const struct iommu_ops intel_iommu_ops;
+const struct iommu_dirty_ops intel_dirty_ops;
static bool translation_pre_enabled(struct intel_iommu *iommu)
{
@@ -560,7 +560,7 @@ static unsigned long domain_super_pgsize_bitmap(struct dmar_domain *domain)
}
/* Some capabilities may be different across iommus */
-static void domain_update_iommu_cap(struct dmar_domain *domain)
+void domain_update_iommu_cap(struct dmar_domain *domain)
{
domain_update_iommu_coherency(domain);
domain->iommu_superpage = domain_update_iommu_superpage(domain, NULL);
@@ -1778,8 +1778,7 @@ static struct dmar_domain *alloc_domain(unsigned int type)
return domain;
}
-static int domain_attach_iommu(struct dmar_domain *domain,
- struct intel_iommu *iommu)
+int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu)
{
struct iommu_domain_info *info, *curr;
unsigned long ndomains;
@@ -1828,8 +1827,7 @@ err_unlock:
return ret;
}
-static void domain_detach_iommu(struct dmar_domain *domain,
- struct intel_iommu *iommu)
+void domain_detach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu)
{
struct iommu_domain_info *info;
@@ -2196,6 +2194,11 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
return -EINVAL;
+ if (!(prot & DMA_PTE_WRITE) && domain->nested_parent) {
+ pr_err_ratelimited("Read-only mapping is disallowed on the domain which serves as the parent in a nested configuration, due to HW errata (ERRATA_772415_SPR17)\n");
+ return -EINVAL;
+ }
+
attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP);
attr |= DMA_FL_PTE_PRESENT;
if (domain->use_first_level) {
@@ -3958,7 +3961,7 @@ static void dmar_remove_one_dev_info(struct device *dev)
* all DMA requests without PASID from the device are blocked. If the page
* table has been set, clean up the data structures.
*/
-static void device_block_translation(struct device *dev)
+void device_block_translation(struct device *dev)
{
struct device_domain_info *info = dev_iommu_priv_get(dev);
struct intel_iommu *iommu = info->iommu;
@@ -4058,14 +4061,62 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
return NULL;
}
+static struct iommu_domain *
+intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
+ struct iommu_domain *parent,
+ const struct iommu_user_data *user_data)
+{
+ struct device_domain_info *info = dev_iommu_priv_get(dev);
+ bool dirty_tracking = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
+ bool nested_parent = flags & IOMMU_HWPT_ALLOC_NEST_PARENT;
+ struct intel_iommu *iommu = info->iommu;
+ struct iommu_domain *domain;
+
+ /* Must be NESTING domain */
+ if (parent) {
+ if (!nested_supported(iommu) || flags)
+ return ERR_PTR(-EOPNOTSUPP);
+ return intel_nested_domain_alloc(parent, user_data);
+ }
+
+ if (flags &
+ (~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING)))
+ return ERR_PTR(-EOPNOTSUPP);
+ if (nested_parent && !nested_supported(iommu))
+ return ERR_PTR(-EOPNOTSUPP);
+ if (user_data || (dirty_tracking && !ssads_supported(iommu)))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ /*
+ * domain_alloc_user op needs to fully initialize a domain before
+ * return, so uses iommu_domain_alloc() here for simple.
+ */
+ domain = iommu_domain_alloc(dev->bus);
+ if (!domain)
+ return ERR_PTR(-ENOMEM);
+
+ if (nested_parent)
+ to_dmar_domain(domain)->nested_parent = true;
+
+ if (dirty_tracking) {
+ if (to_dmar_domain(domain)->use_first_level) {
+ iommu_domain_free(domain);
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+ domain->dirty_ops = &intel_dirty_ops;
+ }
+
+ return domain;
+}
+
static void intel_iommu_domain_free(struct iommu_domain *domain)
{
if (domain != &si_domain->domain && domain != &blocking_domain)
domain_exit(to_dmar_domain(domain));
}
-static int prepare_domain_attach_device(struct iommu_domain *domain,
- struct device *dev)
+int prepare_domain_attach_device(struct iommu_domain *domain,
+ struct device *dev)
{
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
struct intel_iommu *iommu;
@@ -4078,6 +4129,9 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
if (dmar_domain->force_snooping && !ecap_sc_support(iommu->ecap))
return -EINVAL;
+ if (domain->dirty_ops && !ssads_supported(iommu))
+ return -EINVAL;
+
/* check if this iommu agaw is sufficient for max mapped address */
addr_width = agaw_to_width(iommu->agaw);
if (addr_width > cap_mgaw(iommu->cap))
@@ -4332,6 +4386,8 @@ static bool intel_iommu_capable(struct device *dev, enum iommu_cap cap)
return dmar_platform_optin();
case IOMMU_CAP_ENFORCE_CACHE_COHERENCY:
return ecap_sc_support(info->iommu->ecap);
+ case IOMMU_CAP_DIRTY_TRACKING:
+ return ssads_supported(info->iommu);
default:
return false;
}
@@ -4729,6 +4785,9 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
if (!pasid_supported(iommu) || dev_is_real_dma_subdevice(dev))
return -EOPNOTSUPP;
+ if (domain->dirty_ops)
+ return -EINVAL;
+
if (context_copied(iommu, info->bus, info->devfn))
return -EBUSY;
@@ -4780,6 +4839,7 @@ static void *intel_iommu_hw_info(struct device *dev, u32 *length, u32 *type)
if (!vtd)
return ERR_PTR(-ENOMEM);
+ vtd->flags = IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17;
vtd->cap_reg = iommu->cap;
vtd->ecap_reg = iommu->ecap;
*length = sizeof(*vtd);
@@ -4787,10 +4847,88 @@ static void *intel_iommu_hw_info(struct device *dev, u32 *length, u32 *type)
return vtd;
}
+static int intel_iommu_set_dirty_tracking(struct iommu_domain *domain,
+ bool enable)
+{
+ struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+ struct device_domain_info *info;
+ int ret;
+
+ spin_lock(&dmar_domain->lock);
+ if (dmar_domain->dirty_tracking == enable)
+ goto out_unlock;
+
+ list_for_each_entry(info, &dmar_domain->devices, link) {
+ ret = intel_pasid_setup_dirty_tracking(info->iommu,
+ info->domain, info->dev,
+ IOMMU_NO_PASID, enable);
+ if (ret)
+ goto err_unwind;
+ }
+
+ dmar_domain->dirty_tracking = enable;
+out_unlock:
+ spin_unlock(&dmar_domain->lock);
+
+ return 0;
+
+err_unwind:
+ list_for_each_entry(info, &dmar_domain->devices, link)
+ intel_pasid_setup_dirty_tracking(info->iommu, dmar_domain,
+ info->dev, IOMMU_NO_PASID,
+ dmar_domain->dirty_tracking);
+ spin_unlock(&dmar_domain->lock);
+ return ret;
+}
+
+static int intel_iommu_read_and_clear_dirty(struct iommu_domain *domain,
+ unsigned long iova, size_t size,
+ unsigned long flags,
+ struct iommu_dirty_bitmap *dirty)
+{
+ struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+ unsigned long end = iova + size - 1;
+ unsigned long pgsize;
+
+ /*
+ * IOMMUFD core calls into a dirty tracking disabled domain without an
+ * IOVA bitmap set in order to clean dirty bits in all PTEs that might
+ * have occurred when we stopped dirty tracking. This ensures that we
+ * never inherit dirtied bits from a previous cycle.
+ */
+ if (!dmar_domain->dirty_tracking && dirty->bitmap)
+ return -EINVAL;
+
+ do {
+ struct dma_pte *pte;
+ int lvl = 0;
+
+ pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &lvl,
+ GFP_ATOMIC);
+ pgsize = level_size(lvl) << VTD_PAGE_SHIFT;
+ if (!pte || !dma_pte_present(pte)) {
+ iova += pgsize;
+ continue;
+ }
+
+ if (dma_sl_pte_test_and_clear_dirty(pte, flags))
+ iommu_dirty_bitmap_record(dirty, iova, pgsize);
+ iova += pgsize;
+ } while (iova < end);
+
+ return 0;
+}
+
+const struct iommu_dirty_ops intel_dirty_ops = {
+ .set_dirty_tracking = intel_iommu_set_dirty_tracking,
+ .read_and_clear_dirty = intel_iommu_read_and_clear_dirty,
+};
+
const struct iommu_ops intel_iommu_ops = {
.capable = intel_iommu_capable,
.hw_info = intel_iommu_hw_info,
.domain_alloc = intel_iommu_domain_alloc,
+ .domain_alloc_user = intel_iommu_domain_alloc_user,
.probe_device = intel_iommu_probe_device,
.probe_finalize = intel_iommu_probe_finalize,
.release_device = intel_iommu_release_device,
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index 7dac94f62b4e..d796d0d9b114 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -25,6 +25,7 @@
#include <asm/cacheflush.h>
#include <asm/iommu.h>
+#include <uapi/linux/iommufd.h>
/*
* VT-d hardware uses 4KiB page size regardless of host page size.
@@ -48,6 +49,9 @@
#define DMA_FL_PTE_DIRTY BIT_ULL(6)
#define DMA_FL_PTE_XD BIT_ULL(63)
+#define DMA_SL_PTE_DIRTY_BIT 9
+#define DMA_SL_PTE_DIRTY BIT_ULL(DMA_SL_PTE_DIRTY_BIT)
+
#define ADDR_WIDTH_5LEVEL (57)
#define ADDR_WIDTH_4LEVEL (48)
@@ -539,6 +543,10 @@ enum {
#define sm_supported(iommu) (intel_iommu_sm && ecap_smts((iommu)->ecap))
#define pasid_supported(iommu) (sm_supported(iommu) && \
ecap_pasid((iommu)->ecap))
+#define ssads_supported(iommu) (sm_supported(iommu) && \
+ ecap_slads((iommu)->ecap))
+#define nested_supported(iommu) (sm_supported(iommu) && \
+ ecap_nest((iommu)->ecap))
struct pasid_entry;
struct pasid_state_entry;
@@ -592,20 +600,45 @@ struct dmar_domain {
* otherwise, goes through the second
* level.
*/
+ u8 dirty_tracking:1; /* Dirty tracking is enabled */
+ u8 nested_parent:1; /* Has other domains nested on it */
spinlock_t lock; /* Protect device tracking lists */
struct list_head devices; /* all devices' list */
struct list_head dev_pasids; /* all attached pasids */
- struct dma_pte *pgd; /* virtual address */
- int gaw; /* max guest address width */
-
- /* adjusted guest address width, 0 is level 2 30-bit */
- int agaw;
int iommu_superpage;/* Level of superpages supported:
0 == 4KiB (no superpages), 1 == 2MiB,
2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
- u64 max_addr; /* maximum mapped address */
+ union {
+ /* DMA remapping domain */
+ struct {
+ /* virtual address */
+ struct dma_pte *pgd;
+ /* max guest address width */
+ int gaw;
+ /*
+ * adjusted guest address width:
+ * 0: level 2 30-bit
+ * 1: level 3 39-bit
+ * 2: level 4 48-bit
+ * 3: level 5 57-bit
+ */
+ int agaw;
+ /* maximum mapped address */
+ u64 max_addr;
+ };
+
+ /* Nested user domain */
+ struct {
+ /* parent page table which the user domain is nested on */
+ struct dmar_domain *s2_domain;
+ /* user page table pointer (in GPA) */
+ unsigned long s1_pgtbl;
+ /* page table attributes */
+ struct iommu_hwpt_vtd_s1 s1_cfg;
+ };
+ };
struct iommu_domain domain; /* generic domain data structure for
iommu core */
@@ -781,6 +814,16 @@ static inline bool dma_pte_present(struct dma_pte *pte)
return (pte->val & 3) != 0;
}
+static inline bool dma_sl_pte_test_and_clear_dirty(struct dma_pte *pte,
+ unsigned long flags)
+{
+ if (flags & IOMMU_DIRTY_NO_CLEAR)
+ return (pte->val & DMA_SL_PTE_DIRTY) != 0;
+
+ return test_and_clear_bit(DMA_SL_PTE_DIRTY_BIT,
+ (unsigned long *)&pte->val);
+}
+
static inline bool dma_pte_superpage(struct dma_pte *pte)
{
return (pte->val & DMA_PTE_LARGE_PAGE);
@@ -836,12 +879,21 @@ int qi_submit_sync(struct intel_iommu *iommu, struct qi_desc *desc,
*/
#define QI_OPT_WAIT_DRAIN BIT(0)
+int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu);
+void domain_detach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu);
+void device_block_translation(struct device *dev);
+int prepare_domain_attach_device(struct iommu_domain *domain,
+ struct device *dev);
+void domain_update_iommu_cap(struct dmar_domain *domain);
+
int dmar_ir_support(void);
void *alloc_pgtable_page(int node, gfp_t gfp);
void free_pgtable_page(void *vaddr);
void iommu_flush_write_buffer(struct intel_iommu *iommu);
struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn);
+struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
+ const struct iommu_user_data *user_data);
#ifdef CONFIG_INTEL_IOMMU_SVM
void intel_svm_check(struct intel_iommu *iommu);
diff --git a/drivers/iommu/intel/nested.c b/drivers/iommu/intel/nested.c
new file mode 100644
index 000000000000..b5a5563ab32c
--- /dev/null
+++ b/drivers/iommu/intel/nested.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * nested.c - nested mode translation support
+ *
+ * Copyright (C) 2023 Intel Corporation
+ *
+ * Author: Lu Baolu <baolu.lu@linux.intel.com>
+ * Jacob Pan <jacob.jun.pan@linux.intel.com>
+ * Yi Liu <yi.l.liu@intel.com>
+ */
+
+#define pr_fmt(fmt) "DMAR: " fmt
+
+#include <linux/iommu.h>
+#include <linux/pci.h>
+#include <linux/pci-ats.h>
+
+#include "iommu.h"
+#include "pasid.h"
+
+static int intel_nested_attach_dev(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct device_domain_info *info = dev_iommu_priv_get(dev);
+ struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+ struct intel_iommu *iommu = info->iommu;
+ unsigned long flags;
+ int ret = 0;
+
+ if (info->domain)
+ device_block_translation(dev);
+
+ if (iommu->agaw < dmar_domain->s2_domain->agaw) {
+ dev_err_ratelimited(dev, "Adjusted guest address width not compatible\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Stage-1 domain cannot work alone, it is nested on a s2_domain.
+ * The s2_domain will be used in nested translation, hence needs
+ * to ensure the s2_domain is compatible with this IOMMU.
+ */
+ ret = prepare_domain_attach_device(&dmar_domain->s2_domain->domain, dev);
+ if (ret) {
+ dev_err_ratelimited(dev, "s2 domain is not compatible\n");
+ return ret;
+ }
+
+ ret = domain_attach_iommu(dmar_domain, iommu);
+ if (ret) {
+ dev_err_ratelimited(dev, "Failed to attach domain to iommu\n");
+ return ret;
+ }
+
+ ret = intel_pasid_setup_nested(iommu, dev,
+ IOMMU_NO_PASID, dmar_domain);
+ if (ret) {
+ domain_detach_iommu(dmar_domain, iommu);
+ dev_err_ratelimited(dev, "Failed to setup pasid entry\n");
+ return ret;
+ }
+
+ info->domain = dmar_domain;
+ spin_lock_irqsave(&dmar_domain->lock, flags);
+ list_add(&info->link, &dmar_domain->devices);
+ spin_unlock_irqrestore(&dmar_domain->lock, flags);
+
+ return 0;
+}
+
+static void intel_nested_domain_free(struct iommu_domain *domain)
+{
+ kfree(to_dmar_domain(domain));
+}
+
+static const struct iommu_domain_ops intel_nested_domain_ops = {
+ .attach_dev = intel_nested_attach_dev,
+ .free = intel_nested_domain_free,
+};
+
+struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
+ const struct iommu_user_data *user_data)
+{
+ struct dmar_domain *s2_domain = to_dmar_domain(parent);
+ struct iommu_hwpt_vtd_s1 vtd;
+ struct dmar_domain *domain;
+ int ret;
+
+ /* Must be nested domain */
+ if (user_data->type != IOMMU_HWPT_DATA_VTD_S1)
+ return ERR_PTR(-EOPNOTSUPP);
+ if (parent->ops != intel_iommu_ops.default_domain_ops ||
+ !s2_domain->nested_parent)
+ return ERR_PTR(-EINVAL);
+
+ ret = iommu_copy_struct_from_user(&vtd, user_data,
+ IOMMU_HWPT_DATA_VTD_S1, __reserved);
+ if (ret)
+ return ERR_PTR(ret);
+
+ domain = kzalloc(sizeof(*domain), GFP_KERNEL_ACCOUNT);
+ if (!domain)
+ return ERR_PTR(-ENOMEM);
+
+ domain->use_first_level = true;
+ domain->s2_domain = s2_domain;
+ domain->s1_pgtbl = vtd.pgtbl_addr;
+ domain->s1_cfg = vtd;
+ domain->domain.ops = &intel_nested_domain_ops;
+ domain->domain.type = IOMMU_DOMAIN_NESTED;
+ INIT_LIST_HEAD(&domain->devices);
+ INIT_LIST_HEAD(&domain->dev_pasids);
+ spin_lock_init(&domain->lock);
+ xa_init(&domain->iommu_array);
+
+ return &domain->domain;
+}
diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index 8f92b92f3d2a..74e8e4c17e81 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -277,6 +277,11 @@ static inline void pasid_set_bits(u64 *ptr, u64 mask, u64 bits)
WRITE_ONCE(*ptr, (old & ~mask) | bits);
}
+static inline u64 pasid_get_bits(u64 *ptr)
+{
+ return READ_ONCE(*ptr);
+}
+
/*
* Setup the DID(Domain Identifier) field (Bit 64~79) of scalable mode
* PASID entry.
@@ -336,6 +341,45 @@ static inline void pasid_set_fault_enable(struct pasid_entry *pe)
}
/*
+ * Enable second level A/D bits by setting the SLADE (Second Level
+ * Access Dirty Enable) field (Bit 9) of a scalable mode PASID
+ * entry.
+ */
+static inline void pasid_set_ssade(struct pasid_entry *pe)
+{
+ pasid_set_bits(&pe->val[0], 1 << 9, 1 << 9);
+}
+
+/*
+ * Disable second level A/D bits by clearing the SLADE (Second Level
+ * Access Dirty Enable) field (Bit 9) of a scalable mode PASID
+ * entry.
+ */
+static inline void pasid_clear_ssade(struct pasid_entry *pe)
+{
+ pasid_set_bits(&pe->val[0], 1 << 9, 0);
+}
+
+/*
+ * Checks if second level A/D bits specifically the SLADE (Second Level
+ * Access Dirty Enable) field (Bit 9) of a scalable mode PASID
+ * entry is set.
+ */
+static inline bool pasid_get_ssade(struct pasid_entry *pe)
+{
+ return pasid_get_bits(&pe->val[0]) & (1 << 9);
+}
+
+/*
+ * Setup the SRE(Supervisor Request Enable) field (Bit 128) of a
+ * scalable mode PASID entry.
+ */
+static inline void pasid_set_sre(struct pasid_entry *pe)
+{
+ pasid_set_bits(&pe->val[2], 1 << 0, 1);
+}
+
+/*
* Setup the WPE(Write Protect Enable) field (Bit 132) of a
* scalable mode PASID entry.
*/
@@ -402,6 +446,15 @@ pasid_set_flpm(struct pasid_entry *pe, u64 value)
pasid_set_bits(&pe->val[2], GENMASK_ULL(3, 2), value << 2);
}
+/*
+ * Setup the Extended Access Flag Enable (EAFE) field (Bit 135)
+ * of a scalable mode PASID entry.
+ */
+static inline void pasid_set_eafe(struct pasid_entry *pe)
+{
+ pasid_set_bits(&pe->val[2], 1 << 7, 1 << 7);
+}
+
static void
pasid_cache_invalidation_with_pasid(struct intel_iommu *iommu,
u16 did, u32 pasid)
@@ -627,6 +680,8 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
pasid_set_translation_type(pte, PASID_ENTRY_PGTT_SL_ONLY);
pasid_set_fault_enable(pte);
pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap));
+ if (domain->dirty_tracking)
+ pasid_set_ssade(pte);
pasid_set_present(pte);
spin_unlock(&iommu->lock);
@@ -637,6 +692,78 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
}
/*
+ * Set up dirty tracking on a second only or nested translation type.
+ */
+int intel_pasid_setup_dirty_tracking(struct intel_iommu *iommu,
+ struct dmar_domain *domain,
+ struct device *dev, u32 pasid,
+ bool enabled)
+{
+ struct pasid_entry *pte;
+ u16 did, pgtt;
+
+ spin_lock(&iommu->lock);
+
+ pte = intel_pasid_get_entry(dev, pasid);
+ if (!pte) {
+ spin_unlock(&iommu->lock);
+ dev_err_ratelimited(
+ dev, "Failed to get pasid entry of PASID %d\n", pasid);
+ return -ENODEV;
+ }
+
+ did = domain_id_iommu(domain, iommu);
+ pgtt = pasid_pte_get_pgtt(pte);
+ if (pgtt != PASID_ENTRY_PGTT_SL_ONLY &&
+ pgtt != PASID_ENTRY_PGTT_NESTED) {
+ spin_unlock(&iommu->lock);
+ dev_err_ratelimited(
+ dev,
+ "Dirty tracking not supported on translation type %d\n",
+ pgtt);
+ return -EOPNOTSUPP;
+ }
+
+ if (pasid_get_ssade(pte) == enabled) {
+ spin_unlock(&iommu->lock);
+ return 0;
+ }
+
+ if (enabled)
+ pasid_set_ssade(pte);
+ else
+ pasid_clear_ssade(pte);
+ spin_unlock(&iommu->lock);
+
+ if (!ecap_coherent(iommu->ecap))
+ clflush_cache_range(pte, sizeof(*pte));
+
+ /*
+ * From VT-d spec table 25 "Guidance to Software for Invalidations":
+ *
+ * - PASID-selective-within-Domain PASID-cache invalidation
+ * If (PGTT=SS or Nested)
+ * - Domain-selective IOTLB invalidation
+ * Else
+ * - PASID-selective PASID-based IOTLB invalidation
+ * - If (pasid is RID_PASID)
+ * - Global Device-TLB invalidation to affected functions
+ * Else
+ * - PASID-based Device-TLB invalidation (with S=1 and
+ * Addr[63:12]=0x7FFFFFFF_FFFFF) to affected functions
+ */
+ pasid_cache_invalidation_with_pasid(iommu, did, pasid);
+
+ iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
+
+ /* Device IOTLB doesn't need to be flushed in caching mode. */
+ if (!cap_caching_mode(iommu->cap))
+ devtlb_invalidation_with_pasid(iommu, dev, pasid);
+
+ return 0;
+}
+
+/*
* Set up the scalable mode pasid entry for passthrough translation type.
*/
int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
@@ -713,3 +840,97 @@ void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu,
if (!cap_caching_mode(iommu->cap))
devtlb_invalidation_with_pasid(iommu, dev, pasid);
}
+
+/**
+ * intel_pasid_setup_nested() - Set up PASID entry for nested translation.
+ * @iommu: IOMMU which the device belong to
+ * @dev: Device to be set up for translation
+ * @pasid: PASID to be programmed in the device PASID table
+ * @domain: User stage-1 domain nested on a stage-2 domain
+ *
+ * This is used for nested translation. The input domain should be
+ * nested type and nested on a parent with 'is_nested_parent' flag
+ * set.
+ */
+int intel_pasid_setup_nested(struct intel_iommu *iommu, struct device *dev,
+ u32 pasid, struct dmar_domain *domain)
+{
+ struct iommu_hwpt_vtd_s1 *s1_cfg = &domain->s1_cfg;
+ pgd_t *s1_gpgd = (pgd_t *)(uintptr_t)domain->s1_pgtbl;
+ struct dmar_domain *s2_domain = domain->s2_domain;
+ u16 did = domain_id_iommu(domain, iommu);
+ struct dma_pte *pgd = s2_domain->pgd;
+ struct pasid_entry *pte;
+
+ /* Address width should match the address width supported by hardware */
+ switch (s1_cfg->addr_width) {
+ case ADDR_WIDTH_4LEVEL:
+ break;
+ case ADDR_WIDTH_5LEVEL:
+ if (!cap_fl5lp_support(iommu->cap)) {
+ dev_err_ratelimited(dev,
+ "5-level paging not supported\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ dev_err_ratelimited(dev, "Invalid stage-1 address width %d\n",
+ s1_cfg->addr_width);
+ return -EINVAL;
+ }
+
+ if ((s1_cfg->flags & IOMMU_VTD_S1_SRE) && !ecap_srs(iommu->ecap)) {
+ pr_err_ratelimited("No supervisor request support on %s\n",
+ iommu->name);
+ return -EINVAL;
+ }
+
+ if ((s1_cfg->flags & IOMMU_VTD_S1_EAFE) && !ecap_eafs(iommu->ecap)) {
+ pr_err_ratelimited("No extended access flag support on %s\n",
+ iommu->name);
+ return -EINVAL;
+ }
+
+ spin_lock(&iommu->lock);
+ pte = intel_pasid_get_entry(dev, pasid);
+ if (!pte) {
+ spin_unlock(&iommu->lock);
+ return -ENODEV;
+ }
+ if (pasid_pte_is_present(pte)) {
+ spin_unlock(&iommu->lock);
+ return -EBUSY;
+ }
+
+ pasid_clear_entry(pte);
+
+ if (s1_cfg->addr_width == ADDR_WIDTH_5LEVEL)
+ pasid_set_flpm(pte, 1);
+
+ pasid_set_flptr(pte, (uintptr_t)s1_gpgd);
+
+ if (s1_cfg->flags & IOMMU_VTD_S1_SRE) {
+ pasid_set_sre(pte);
+ if (s1_cfg->flags & IOMMU_VTD_S1_WPE)
+ pasid_set_wpe(pte);
+ }
+
+ if (s1_cfg->flags & IOMMU_VTD_S1_EAFE)
+ pasid_set_eafe(pte);
+
+ if (s2_domain->force_snooping)
+ pasid_set_pgsnp(pte);
+
+ pasid_set_slptr(pte, virt_to_phys(pgd));
+ pasid_set_fault_enable(pte);
+ pasid_set_domain_id(pte, did);
+ pasid_set_address_width(pte, s2_domain->agaw);
+ pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap));
+ pasid_set_translation_type(pte, PASID_ENTRY_PGTT_NESTED);
+ pasid_set_present(pte);
+ spin_unlock(&iommu->lock);
+
+ pasid_flush_caches(iommu, pte, pasid, did);
+
+ return 0;
+}
diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h
index 4e9e68c3c388..dd37611175cc 100644
--- a/drivers/iommu/intel/pasid.h
+++ b/drivers/iommu/intel/pasid.h
@@ -106,9 +106,15 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
int intel_pasid_setup_second_level(struct intel_iommu *iommu,
struct dmar_domain *domain,
struct device *dev, u32 pasid);
+int intel_pasid_setup_dirty_tracking(struct intel_iommu *iommu,
+ struct dmar_domain *domain,
+ struct device *dev, u32 pasid,
+ bool enabled);
int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
struct dmar_domain *domain,
struct device *dev, u32 pasid);
+int intel_pasid_setup_nested(struct intel_iommu *iommu, struct device *dev,
+ u32 pasid, struct dmar_domain *domain);
void intel_pasid_tear_down_entry(struct intel_iommu *iommu,
struct device *dev, u32 pasid,
bool fault_ignore);
diff --git a/drivers/iommu/iommufd/Makefile b/drivers/iommu/iommufd/Makefile
index 8aeba81800c5..34b446146961 100644
--- a/drivers/iommu/iommufd/Makefile
+++ b/drivers/iommu/iommufd/Makefile
@@ -11,3 +11,4 @@ iommufd-y := \
iommufd-$(CONFIG_IOMMUFD_TEST) += selftest.o
obj-$(CONFIG_IOMMUFD) += iommufd.o
+obj-$(CONFIG_IOMMUFD_DRIVER) += iova_bitmap.o
diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
index ce78c3671539..59d3a07300d9 100644
--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -293,7 +293,7 @@ u32 iommufd_device_to_id(struct iommufd_device *idev)
EXPORT_SYMBOL_NS_GPL(iommufd_device_to_id, IOMMUFD);
static int iommufd_group_setup_msi(struct iommufd_group *igroup,
- struct iommufd_hw_pagetable *hwpt)
+ struct iommufd_hwpt_paging *hwpt_paging)
{
phys_addr_t sw_msi_start = igroup->sw_msi_start;
int rc;
@@ -311,8 +311,9 @@ static int iommufd_group_setup_msi(struct iommufd_group *igroup,
* matches what the IRQ layer actually expects in a newly created
* domain.
*/
- if (sw_msi_start != PHYS_ADDR_MAX && !hwpt->msi_cookie) {
- rc = iommu_get_msi_cookie(hwpt->domain, sw_msi_start);
+ if (sw_msi_start != PHYS_ADDR_MAX && !hwpt_paging->msi_cookie) {
+ rc = iommu_get_msi_cookie(hwpt_paging->common.domain,
+ sw_msi_start);
if (rc)
return rc;
@@ -320,7 +321,31 @@ static int iommufd_group_setup_msi(struct iommufd_group *igroup,
* iommu_get_msi_cookie() can only be called once per domain,
* it returns -EBUSY on later calls.
*/
- hwpt->msi_cookie = true;
+ hwpt_paging->msi_cookie = true;
+ }
+ return 0;
+}
+
+static int iommufd_hwpt_paging_attach(struct iommufd_hwpt_paging *hwpt_paging,
+ struct iommufd_device *idev)
+{
+ int rc;
+
+ lockdep_assert_held(&idev->igroup->lock);
+
+ rc = iopt_table_enforce_dev_resv_regions(&hwpt_paging->ioas->iopt,
+ idev->dev,
+ &idev->igroup->sw_msi_start);
+ if (rc)
+ return rc;
+
+ if (list_empty(&idev->igroup->device_list)) {
+ rc = iommufd_group_setup_msi(idev->igroup, hwpt_paging);
+ if (rc) {
+ iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt,
+ idev->dev);
+ return rc;
+ }
}
return 0;
}
@@ -337,18 +362,12 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
goto err_unlock;
}
- /* Try to upgrade the domain we have */
- if (idev->enforce_cache_coherency) {
- rc = iommufd_hw_pagetable_enforce_cc(hwpt);
+ if (hwpt_is_paging(hwpt)) {
+ rc = iommufd_hwpt_paging_attach(to_hwpt_paging(hwpt), idev);
if (rc)
goto err_unlock;
}
- rc = iopt_table_enforce_dev_resv_regions(&hwpt->ioas->iopt, idev->dev,
- &idev->igroup->sw_msi_start);
- if (rc)
- goto err_unlock;
-
/*
* Only attach to the group once for the first device that is in the
* group. All the other devices will follow this attachment. The user
@@ -357,10 +376,6 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
* attachment.
*/
if (list_empty(&idev->igroup->device_list)) {
- rc = iommufd_group_setup_msi(idev->igroup, hwpt);
- if (rc)
- goto err_unresv;
-
rc = iommu_attach_group(hwpt->domain, idev->igroup->group);
if (rc)
goto err_unresv;
@@ -371,7 +386,9 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
mutex_unlock(&idev->igroup->lock);
return 0;
err_unresv:
- iopt_remove_reserved_iova(&hwpt->ioas->iopt, idev->dev);
+ if (hwpt_is_paging(hwpt))
+ iopt_remove_reserved_iova(&to_hwpt_paging(hwpt)->ioas->iopt,
+ idev->dev);
err_unlock:
mutex_unlock(&idev->igroup->lock);
return rc;
@@ -388,7 +405,9 @@ iommufd_hw_pagetable_detach(struct iommufd_device *idev)
iommu_detach_group(hwpt->domain, idev->igroup->group);
idev->igroup->hwpt = NULL;
}
- iopt_remove_reserved_iova(&hwpt->ioas->iopt, idev->dev);
+ if (hwpt_is_paging(hwpt))
+ iopt_remove_reserved_iova(&to_hwpt_paging(hwpt)->ioas->iopt,
+ idev->dev);
mutex_unlock(&idev->igroup->lock);
/* Caller must destroy hwpt */
@@ -407,14 +426,55 @@ iommufd_device_do_attach(struct iommufd_device *idev,
return NULL;
}
+static void
+iommufd_group_remove_reserved_iova(struct iommufd_group *igroup,
+ struct iommufd_hwpt_paging *hwpt_paging)
+{
+ struct iommufd_device *cur;
+
+ lockdep_assert_held(&igroup->lock);
+
+ list_for_each_entry(cur, &igroup->device_list, group_item)
+ iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, cur->dev);
+}
+
+static int
+iommufd_group_do_replace_paging(struct iommufd_group *igroup,
+ struct iommufd_hwpt_paging *hwpt_paging)
+{
+ struct iommufd_hw_pagetable *old_hwpt = igroup->hwpt;
+ struct iommufd_device *cur;
+ int rc;
+
+ lockdep_assert_held(&igroup->lock);
+
+ if (!hwpt_is_paging(old_hwpt) ||
+ hwpt_paging->ioas != to_hwpt_paging(old_hwpt)->ioas) {
+ list_for_each_entry(cur, &igroup->device_list, group_item) {
+ rc = iopt_table_enforce_dev_resv_regions(
+ &hwpt_paging->ioas->iopt, cur->dev, NULL);
+ if (rc)
+ goto err_unresv;
+ }
+ }
+
+ rc = iommufd_group_setup_msi(igroup, hwpt_paging);
+ if (rc)
+ goto err_unresv;
+ return 0;
+
+err_unresv:
+ iommufd_group_remove_reserved_iova(igroup, hwpt_paging);
+ return rc;
+}
+
static struct iommufd_hw_pagetable *
iommufd_device_do_replace(struct iommufd_device *idev,
struct iommufd_hw_pagetable *hwpt)
{
struct iommufd_group *igroup = idev->igroup;
struct iommufd_hw_pagetable *old_hwpt;
- unsigned int num_devices = 0;
- struct iommufd_device *cur;
+ unsigned int num_devices;
int rc;
mutex_lock(&idev->igroup->lock);
@@ -429,42 +489,27 @@ iommufd_device_do_replace(struct iommufd_device *idev,
return NULL;
}
- /* Try to upgrade the domain we have */
- list_for_each_entry(cur, &igroup->device_list, group_item) {
- num_devices++;
- if (cur->enforce_cache_coherency) {
- rc = iommufd_hw_pagetable_enforce_cc(hwpt);
- if (rc)
- goto err_unlock;
- }
- }
-
old_hwpt = igroup->hwpt;
- if (hwpt->ioas != old_hwpt->ioas) {
- list_for_each_entry(cur, &igroup->device_list, group_item) {
- rc = iopt_table_enforce_dev_resv_regions(
- &hwpt->ioas->iopt, cur->dev, NULL);
- if (rc)
- goto err_unresv;
- }
+ if (hwpt_is_paging(hwpt)) {
+ rc = iommufd_group_do_replace_paging(igroup,
+ to_hwpt_paging(hwpt));
+ if (rc)
+ goto err_unlock;
}
- rc = iommufd_group_setup_msi(idev->igroup, hwpt);
- if (rc)
- goto err_unresv;
-
rc = iommu_group_replace_domain(igroup->group, hwpt->domain);
if (rc)
goto err_unresv;
- if (hwpt->ioas != old_hwpt->ioas) {
- list_for_each_entry(cur, &igroup->device_list, group_item)
- iopt_remove_reserved_iova(&old_hwpt->ioas->iopt,
- cur->dev);
- }
+ if (hwpt_is_paging(old_hwpt) &&
+ (!hwpt_is_paging(hwpt) ||
+ to_hwpt_paging(hwpt)->ioas != to_hwpt_paging(old_hwpt)->ioas))
+ iommufd_group_remove_reserved_iova(igroup,
+ to_hwpt_paging(old_hwpt));
igroup->hwpt = hwpt;
+ num_devices = list_count_nodes(&igroup->device_list);
/*
* Move the refcounts held by the device_list to the new hwpt. Retain a
* refcount for this thread as the caller will free it.
@@ -478,8 +523,9 @@ iommufd_device_do_replace(struct iommufd_device *idev,
/* Caller must destroy old_hwpt */
return old_hwpt;
err_unresv:
- list_for_each_entry(cur, &igroup->device_list, group_item)
- iopt_remove_reserved_iova(&hwpt->ioas->iopt, cur->dev);
+ if (hwpt_is_paging(hwpt))
+ iommufd_group_remove_reserved_iova(igroup,
+ to_hwpt_paging(old_hwpt));
err_unlock:
mutex_unlock(&idev->igroup->lock);
return ERR_PTR(rc);
@@ -507,6 +553,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
*/
bool immediate_attach = do_attach == iommufd_device_do_attach;
struct iommufd_hw_pagetable *destroy_hwpt;
+ struct iommufd_hwpt_paging *hwpt_paging;
struct iommufd_hw_pagetable *hwpt;
/*
@@ -515,10 +562,11 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
* other.
*/
mutex_lock(&ioas->mutex);
- list_for_each_entry(hwpt, &ioas->hwpt_list, hwpt_item) {
- if (!hwpt->auto_domain)
+ list_for_each_entry(hwpt_paging, &ioas->hwpt_list, hwpt_item) {
+ if (!hwpt_paging->auto_domain)
continue;
+ hwpt = &hwpt_paging->common;
if (!iommufd_lock_obj(&hwpt->obj))
continue;
destroy_hwpt = (*do_attach)(idev, hwpt);
@@ -539,12 +587,13 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
goto out_unlock;
}
- hwpt = iommufd_hw_pagetable_alloc(idev->ictx, ioas, idev,
- immediate_attach);
- if (IS_ERR(hwpt)) {
- destroy_hwpt = ERR_CAST(hwpt);
+ hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, 0,
+ immediate_attach, NULL);
+ if (IS_ERR(hwpt_paging)) {
+ destroy_hwpt = ERR_CAST(hwpt_paging);
goto out_unlock;
}
+ hwpt = &hwpt_paging->common;
if (!immediate_attach) {
destroy_hwpt = (*do_attach)(idev, hwpt);
@@ -554,7 +603,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
destroy_hwpt = NULL;
}
- hwpt->auto_domain = true;
+ hwpt_paging->auto_domain = true;
*pt_id = hwpt->obj.id;
iommufd_object_finalize(idev->ictx, &hwpt->obj);
@@ -579,7 +628,8 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
return PTR_ERR(pt_obj);
switch (pt_obj->type) {
- case IOMMUFD_OBJ_HW_PAGETABLE: {
+ case IOMMUFD_OBJ_HWPT_NESTED:
+ case IOMMUFD_OBJ_HWPT_PAGING: {
struct iommufd_hw_pagetable *hwpt =
container_of(pt_obj, struct iommufd_hw_pagetable, obj);
@@ -617,8 +667,8 @@ out_put_pt_obj:
/**
* iommufd_device_attach - Connect a device to an iommu_domain
* @idev: device to attach
- * @pt_id: Input a IOMMUFD_OBJ_IOAS, or IOMMUFD_OBJ_HW_PAGETABLE
- * Output the IOMMUFD_OBJ_HW_PAGETABLE ID
+ * @pt_id: Input a IOMMUFD_OBJ_IOAS, or IOMMUFD_OBJ_HWPT_PAGING
+ * Output the IOMMUFD_OBJ_HWPT_PAGING ID
*
* This connects the device to an iommu_domain, either automatically or manually
* selected. Once this completes the device could do DMA.
@@ -646,8 +696,8 @@ EXPORT_SYMBOL_NS_GPL(iommufd_device_attach, IOMMUFD);
/**
* iommufd_device_replace - Change the device's iommu_domain
* @idev: device to change
- * @pt_id: Input a IOMMUFD_OBJ_IOAS, or IOMMUFD_OBJ_HW_PAGETABLE
- * Output the IOMMUFD_OBJ_HW_PAGETABLE ID
+ * @pt_id: Input a IOMMUFD_OBJ_IOAS, or IOMMUFD_OBJ_HWPT_PAGING
+ * Output the IOMMUFD_OBJ_HWPT_PAGING ID
*
* This is the same as::
*
@@ -1185,6 +1235,10 @@ int iommufd_get_hw_info(struct iommufd_ucmd *ucmd)
*/
cmd->data_len = data_len;
+ cmd->out_capabilities = 0;
+ if (device_iommu_capable(idev->dev, IOMMU_CAP_DIRTY_TRACKING))
+ cmd->out_capabilities |= IOMMU_HW_CAP_DIRTY_TRACKING;
+
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
out_free:
kfree(data);
diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c
index cf2c1504e20d..2abbeafdbd22 100644
--- a/drivers/iommu/iommufd/hw_pagetable.c
+++ b/drivers/iommu/iommufd/hw_pagetable.c
@@ -5,62 +5,87 @@
#include <linux/iommu.h>
#include <uapi/linux/iommufd.h>
+#include "../iommu-priv.h"
#include "iommufd_private.h"
-void iommufd_hw_pagetable_destroy(struct iommufd_object *obj)
+void iommufd_hwpt_paging_destroy(struct iommufd_object *obj)
{
- struct iommufd_hw_pagetable *hwpt =
- container_of(obj, struct iommufd_hw_pagetable, obj);
+ struct iommufd_hwpt_paging *hwpt_paging =
+ container_of(obj, struct iommufd_hwpt_paging, common.obj);
- if (!list_empty(&hwpt->hwpt_item)) {
- mutex_lock(&hwpt->ioas->mutex);
- list_del(&hwpt->hwpt_item);
- mutex_unlock(&hwpt->ioas->mutex);
+ if (!list_empty(&hwpt_paging->hwpt_item)) {
+ mutex_lock(&hwpt_paging->ioas->mutex);
+ list_del(&hwpt_paging->hwpt_item);
+ mutex_unlock(&hwpt_paging->ioas->mutex);
- iopt_table_remove_domain(&hwpt->ioas->iopt, hwpt->domain);
+ iopt_table_remove_domain(&hwpt_paging->ioas->iopt,
+ hwpt_paging->common.domain);
}
- if (hwpt->domain)
- iommu_domain_free(hwpt->domain);
+ if (hwpt_paging->common.domain)
+ iommu_domain_free(hwpt_paging->common.domain);
- refcount_dec(&hwpt->ioas->obj.users);
+ refcount_dec(&hwpt_paging->ioas->obj.users);
}
-void iommufd_hw_pagetable_abort(struct iommufd_object *obj)
+void iommufd_hwpt_paging_abort(struct iommufd_object *obj)
{
- struct iommufd_hw_pagetable *hwpt =
- container_of(obj, struct iommufd_hw_pagetable, obj);
+ struct iommufd_hwpt_paging *hwpt_paging =
+ container_of(obj, struct iommufd_hwpt_paging, common.obj);
/* The ioas->mutex must be held until finalize is called. */
- lockdep_assert_held(&hwpt->ioas->mutex);
+ lockdep_assert_held(&hwpt_paging->ioas->mutex);
- if (!list_empty(&hwpt->hwpt_item)) {
- list_del_init(&hwpt->hwpt_item);
- iopt_table_remove_domain(&hwpt->ioas->iopt, hwpt->domain);
+ if (!list_empty(&hwpt_paging->hwpt_item)) {
+ list_del_init(&hwpt_paging->hwpt_item);
+ iopt_table_remove_domain(&hwpt_paging->ioas->iopt,
+ hwpt_paging->common.domain);
}
- iommufd_hw_pagetable_destroy(obj);
+ iommufd_hwpt_paging_destroy(obj);
}
-int iommufd_hw_pagetable_enforce_cc(struct iommufd_hw_pagetable *hwpt)
+void iommufd_hwpt_nested_destroy(struct iommufd_object *obj)
{
- if (hwpt->enforce_cache_coherency)
+ struct iommufd_hwpt_nested *hwpt_nested =
+ container_of(obj, struct iommufd_hwpt_nested, common.obj);
+
+ if (hwpt_nested->common.domain)
+ iommu_domain_free(hwpt_nested->common.domain);
+
+ refcount_dec(&hwpt_nested->parent->common.obj.users);
+}
+
+void iommufd_hwpt_nested_abort(struct iommufd_object *obj)
+{
+ iommufd_hwpt_nested_destroy(obj);
+}
+
+static int
+iommufd_hwpt_paging_enforce_cc(struct iommufd_hwpt_paging *hwpt_paging)
+{
+ struct iommu_domain *paging_domain = hwpt_paging->common.domain;
+
+ if (hwpt_paging->enforce_cache_coherency)
return 0;
- if (hwpt->domain->ops->enforce_cache_coherency)
- hwpt->enforce_cache_coherency =
- hwpt->domain->ops->enforce_cache_coherency(
- hwpt->domain);
- if (!hwpt->enforce_cache_coherency)
+ if (paging_domain->ops->enforce_cache_coherency)
+ hwpt_paging->enforce_cache_coherency =
+ paging_domain->ops->enforce_cache_coherency(
+ paging_domain);
+ if (!hwpt_paging->enforce_cache_coherency)
return -EINVAL;
return 0;
}
/**
- * iommufd_hw_pagetable_alloc() - Get an iommu_domain for a device
+ * iommufd_hwpt_paging_alloc() - Get a PAGING iommu_domain for a device
* @ictx: iommufd context
* @ioas: IOAS to associate the domain with
* @idev: Device to get an iommu_domain for
+ * @flags: Flags from userspace
* @immediate_attach: True if idev should be attached to the hwpt
+ * @user_data: The user provided driver specific data describing the domain to
+ * create
*
* Allocate a new iommu_domain and return it as a hw_pagetable. The HWPT
* will be linked to the given ioas and upon return the underlying iommu_domain
@@ -70,28 +95,52 @@ int iommufd_hw_pagetable_enforce_cc(struct iommufd_hw_pagetable *hwpt)
* iommufd_object_abort_and_destroy() or iommufd_object_finalize() is called on
* the returned hwpt.
*/
-struct iommufd_hw_pagetable *
-iommufd_hw_pagetable_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
- struct iommufd_device *idev, bool immediate_attach)
+struct iommufd_hwpt_paging *
+iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
+ struct iommufd_device *idev, u32 flags,
+ bool immediate_attach,
+ const struct iommu_user_data *user_data)
{
+ const u32 valid_flags = IOMMU_HWPT_ALLOC_NEST_PARENT |
+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
+ const struct iommu_ops *ops = dev_iommu_ops(idev->dev);
+ struct iommufd_hwpt_paging *hwpt_paging;
struct iommufd_hw_pagetable *hwpt;
int rc;
lockdep_assert_held(&ioas->mutex);
- hwpt = iommufd_object_alloc(ictx, hwpt, IOMMUFD_OBJ_HW_PAGETABLE);
- if (IS_ERR(hwpt))
- return hwpt;
+ if ((flags || user_data) && !ops->domain_alloc_user)
+ return ERR_PTR(-EOPNOTSUPP);
+ if (flags & ~valid_flags)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ hwpt_paging = __iommufd_object_alloc(
+ ictx, hwpt_paging, IOMMUFD_OBJ_HWPT_PAGING, common.obj);
+ if (IS_ERR(hwpt_paging))
+ return ERR_CAST(hwpt_paging);
+ hwpt = &hwpt_paging->common;
- INIT_LIST_HEAD(&hwpt->hwpt_item);
+ INIT_LIST_HEAD(&hwpt_paging->hwpt_item);
/* Pairs with iommufd_hw_pagetable_destroy() */
refcount_inc(&ioas->obj.users);
- hwpt->ioas = ioas;
+ hwpt_paging->ioas = ioas;
+ hwpt_paging->nest_parent = flags & IOMMU_HWPT_ALLOC_NEST_PARENT;
- hwpt->domain = iommu_domain_alloc(idev->dev->bus);
- if (!hwpt->domain) {
- rc = -ENOMEM;
- goto out_abort;
+ if (ops->domain_alloc_user) {
+ hwpt->domain = ops->domain_alloc_user(idev->dev, flags, NULL,
+ user_data);
+ if (IS_ERR(hwpt->domain)) {
+ rc = PTR_ERR(hwpt->domain);
+ hwpt->domain = NULL;
+ goto out_abort;
+ }
+ } else {
+ hwpt->domain = iommu_domain_alloc(idev->dev->bus);
+ if (!hwpt->domain) {
+ rc = -ENOMEM;
+ goto out_abort;
+ }
}
/*
@@ -100,9 +149,16 @@ iommufd_hw_pagetable_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
* doing any maps. It is an iommu driver bug to report
* IOMMU_CAP_ENFORCE_CACHE_COHERENCY but fail enforce_cache_coherency on
* a new domain.
+ *
+ * The cache coherency mode must be configured here and unchanged later.
+ * Note that a HWPT (non-CC) created for a device (non-CC) can be later
+ * reused by another device (either non-CC or CC). However, A HWPT (CC)
+ * created for a device (CC) cannot be reused by another device (non-CC)
+ * but only devices (CC). Instead user space in this case would need to
+ * allocate a separate HWPT (non-CC).
*/
if (idev->enforce_cache_coherency) {
- rc = iommufd_hw_pagetable_enforce_cc(hwpt);
+ rc = iommufd_hwpt_paging_enforce_cc(hwpt_paging);
if (WARN_ON(rc))
goto out_abort;
}
@@ -119,11 +175,11 @@ iommufd_hw_pagetable_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
goto out_abort;
}
- rc = iopt_table_add_domain(&hwpt->ioas->iopt, hwpt->domain);
+ rc = iopt_table_add_domain(&ioas->iopt, hwpt->domain);
if (rc)
goto out_detach;
- list_add_tail(&hwpt->hwpt_item, &hwpt->ioas->hwpt_list);
- return hwpt;
+ list_add_tail(&hwpt_paging->hwpt_item, &ioas->hwpt_list);
+ return hwpt_paging;
out_detach:
if (immediate_attach)
@@ -133,32 +189,120 @@ out_abort:
return ERR_PTR(rc);
}
+/**
+ * iommufd_hwpt_nested_alloc() - Get a NESTED iommu_domain for a device
+ * @ictx: iommufd context
+ * @parent: Parent PAGING-type hwpt to associate the domain with
+ * @idev: Device to get an iommu_domain for
+ * @flags: Flags from userspace
+ * @user_data: user_data pointer. Must be valid
+ *
+ * Allocate a new iommu_domain (must be IOMMU_DOMAIN_NESTED) and return it as
+ * a NESTED hw_pagetable. The given parent PAGING-type hwpt must be capable of
+ * being a parent.
+ */
+static struct iommufd_hwpt_nested *
+iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
+ struct iommufd_hwpt_paging *parent,
+ struct iommufd_device *idev, u32 flags,
+ const struct iommu_user_data *user_data)
+{
+ const struct iommu_ops *ops = dev_iommu_ops(idev->dev);
+ struct iommufd_hwpt_nested *hwpt_nested;
+ struct iommufd_hw_pagetable *hwpt;
+ int rc;
+
+ if (flags || !user_data->len || !ops->domain_alloc_user)
+ return ERR_PTR(-EOPNOTSUPP);
+ if (parent->auto_domain || !parent->nest_parent)
+ return ERR_PTR(-EINVAL);
+
+ hwpt_nested = __iommufd_object_alloc(
+ ictx, hwpt_nested, IOMMUFD_OBJ_HWPT_NESTED, common.obj);
+ if (IS_ERR(hwpt_nested))
+ return ERR_CAST(hwpt_nested);
+ hwpt = &hwpt_nested->common;
+
+ refcount_inc(&parent->common.obj.users);
+ hwpt_nested->parent = parent;
+
+ hwpt->domain = ops->domain_alloc_user(idev->dev, flags,
+ parent->common.domain, user_data);
+ if (IS_ERR(hwpt->domain)) {
+ rc = PTR_ERR(hwpt->domain);
+ hwpt->domain = NULL;
+ goto out_abort;
+ }
+
+ if (WARN_ON_ONCE(hwpt->domain->type != IOMMU_DOMAIN_NESTED)) {
+ rc = -EINVAL;
+ goto out_abort;
+ }
+ return hwpt_nested;
+
+out_abort:
+ iommufd_object_abort_and_destroy(ictx, &hwpt->obj);
+ return ERR_PTR(rc);
+}
+
int iommufd_hwpt_alloc(struct iommufd_ucmd *ucmd)
{
struct iommu_hwpt_alloc *cmd = ucmd->cmd;
+ const struct iommu_user_data user_data = {
+ .type = cmd->data_type,
+ .uptr = u64_to_user_ptr(cmd->data_uptr),
+ .len = cmd->data_len,
+ };
struct iommufd_hw_pagetable *hwpt;
+ struct iommufd_ioas *ioas = NULL;
+ struct iommufd_object *pt_obj;
struct iommufd_device *idev;
- struct iommufd_ioas *ioas;
int rc;
- if (cmd->flags || cmd->__reserved)
+ if (cmd->__reserved)
return -EOPNOTSUPP;
+ if (cmd->data_type == IOMMU_HWPT_DATA_NONE && cmd->data_len)
+ return -EINVAL;
idev = iommufd_get_device(ucmd, cmd->dev_id);
if (IS_ERR(idev))
return PTR_ERR(idev);
- ioas = iommufd_get_ioas(ucmd->ictx, cmd->pt_id);
- if (IS_ERR(ioas)) {
- rc = PTR_ERR(ioas);
+ pt_obj = iommufd_get_object(ucmd->ictx, cmd->pt_id, IOMMUFD_OBJ_ANY);
+ if (IS_ERR(pt_obj)) {
+ rc = -EINVAL;
goto out_put_idev;
}
- mutex_lock(&ioas->mutex);
- hwpt = iommufd_hw_pagetable_alloc(ucmd->ictx, ioas, idev, false);
- if (IS_ERR(hwpt)) {
- rc = PTR_ERR(hwpt);
- goto out_unlock;
+ if (pt_obj->type == IOMMUFD_OBJ_IOAS) {
+ struct iommufd_hwpt_paging *hwpt_paging;
+
+ ioas = container_of(pt_obj, struct iommufd_ioas, obj);
+ mutex_lock(&ioas->mutex);
+ hwpt_paging = iommufd_hwpt_paging_alloc(
+ ucmd->ictx, ioas, idev, cmd->flags, false,
+ user_data.len ? &user_data : NULL);
+ if (IS_ERR(hwpt_paging)) {
+ rc = PTR_ERR(hwpt_paging);
+ goto out_unlock;
+ }
+ hwpt = &hwpt_paging->common;
+ } else if (pt_obj->type == IOMMUFD_OBJ_HWPT_PAGING) {
+ struct iommufd_hwpt_nested *hwpt_nested;
+
+ hwpt_nested = iommufd_hwpt_nested_alloc(
+ ucmd->ictx,
+ container_of(pt_obj, struct iommufd_hwpt_paging,
+ common.obj),
+ idev, cmd->flags, &user_data);
+ if (IS_ERR(hwpt_nested)) {
+ rc = PTR_ERR(hwpt_nested);
+ goto out_unlock;
+ }
+ hwpt = &hwpt_nested->common;
+ } else {
+ rc = -EINVAL;
+ goto out_put_pt;
}
cmd->out_hwpt_id = hwpt->obj.id;
@@ -171,9 +315,59 @@ int iommufd_hwpt_alloc(struct iommufd_ucmd *ucmd)
out_hwpt:
iommufd_object_abort_and_destroy(ucmd->ictx, &hwpt->obj);
out_unlock:
- mutex_unlock(&ioas->mutex);
- iommufd_put_object(&ioas->obj);
+ if (ioas)
+ mutex_unlock(&ioas->mutex);
+out_put_pt:
+ iommufd_put_object(pt_obj);
out_put_idev:
iommufd_put_object(&idev->obj);
return rc;
}
+
+int iommufd_hwpt_set_dirty_tracking(struct iommufd_ucmd *ucmd)
+{
+ struct iommu_hwpt_set_dirty_tracking *cmd = ucmd->cmd;
+ struct iommufd_hwpt_paging *hwpt_paging;
+ struct iommufd_ioas *ioas;
+ int rc = -EOPNOTSUPP;
+ bool enable;
+
+ if (cmd->flags & ~IOMMU_HWPT_DIRTY_TRACKING_ENABLE)
+ return rc;
+
+ hwpt_paging = iommufd_get_hwpt_paging(ucmd, cmd->hwpt_id);
+ if (IS_ERR(hwpt_paging))
+ return PTR_ERR(hwpt_paging);
+
+ ioas = hwpt_paging->ioas;
+ enable = cmd->flags & IOMMU_HWPT_DIRTY_TRACKING_ENABLE;
+
+ rc = iopt_set_dirty_tracking(&ioas->iopt, hwpt_paging->common.domain,
+ enable);
+
+ iommufd_put_object(&hwpt_paging->common.obj);
+ return rc;
+}
+
+int iommufd_hwpt_get_dirty_bitmap(struct iommufd_ucmd *ucmd)
+{
+ struct iommu_hwpt_get_dirty_bitmap *cmd = ucmd->cmd;
+ struct iommufd_hwpt_paging *hwpt_paging;
+ struct iommufd_ioas *ioas;
+ int rc = -EOPNOTSUPP;
+
+ if ((cmd->flags & ~(IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR)) ||
+ cmd->__reserved)
+ return -EOPNOTSUPP;
+
+ hwpt_paging = iommufd_get_hwpt_paging(ucmd, cmd->hwpt_id);
+ if (IS_ERR(hwpt_paging))
+ return PTR_ERR(hwpt_paging);
+
+ ioas = hwpt_paging->ioas;
+ rc = iopt_read_and_clear_dirty_data(
+ &ioas->iopt, hwpt_paging->common.domain, cmd->flags, cmd);
+
+ iommufd_put_object(&hwpt_paging->common.obj);
+ return rc;
+}
diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c
index 3a598182b761..504ac1b01b2d 100644
--- a/drivers/iommu/iommufd/io_pagetable.c
+++ b/drivers/iommu/iommufd/io_pagetable.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/errno.h>
+#include <uapi/linux/iommufd.h>
#include "io_pagetable.h"
#include "double_span.h"
@@ -221,6 +222,18 @@ static int iopt_insert_area(struct io_pagetable *iopt, struct iopt_area *area,
return 0;
}
+static struct iopt_area *iopt_area_alloc(void)
+{
+ struct iopt_area *area;
+
+ area = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT);
+ if (!area)
+ return NULL;
+ RB_CLEAR_NODE(&area->node.rb);
+ RB_CLEAR_NODE(&area->pages_node.rb);
+ return area;
+}
+
static int iopt_alloc_area_pages(struct io_pagetable *iopt,
struct list_head *pages_list,
unsigned long length, unsigned long *dst_iova,
@@ -231,7 +244,7 @@ static int iopt_alloc_area_pages(struct io_pagetable *iopt,
int rc = 0;
list_for_each_entry(elm, pages_list, next) {
- elm->area = kzalloc(sizeof(*elm->area), GFP_KERNEL_ACCOUNT);
+ elm->area = iopt_area_alloc();
if (!elm->area)
return -ENOMEM;
}
@@ -412,6 +425,177 @@ int iopt_map_user_pages(struct iommufd_ctx *ictx, struct io_pagetable *iopt,
return 0;
}
+struct iova_bitmap_fn_arg {
+ unsigned long flags;
+ struct io_pagetable *iopt;
+ struct iommu_domain *domain;
+ struct iommu_dirty_bitmap *dirty;
+};
+
+static int __iommu_read_and_clear_dirty(struct iova_bitmap *bitmap,
+ unsigned long iova, size_t length,
+ void *opaque)
+{
+ struct iopt_area *area;
+ struct iopt_area_contig_iter iter;
+ struct iova_bitmap_fn_arg *arg = opaque;
+ struct iommu_domain *domain = arg->domain;
+ struct iommu_dirty_bitmap *dirty = arg->dirty;
+ const struct iommu_dirty_ops *ops = domain->dirty_ops;
+ unsigned long last_iova = iova + length - 1;
+ unsigned long flags = arg->flags;
+ int ret;
+
+ iopt_for_each_contig_area(&iter, area, arg->iopt, iova, last_iova) {
+ unsigned long last = min(last_iova, iopt_area_last_iova(area));
+
+ ret = ops->read_and_clear_dirty(domain, iter.cur_iova,
+ last - iter.cur_iova + 1, flags,
+ dirty);
+ if (ret)
+ return ret;
+ }
+
+ if (!iopt_area_contig_done(&iter))
+ return -EINVAL;
+ return 0;
+}
+
+static int
+iommu_read_and_clear_dirty(struct iommu_domain *domain,
+ struct io_pagetable *iopt, unsigned long flags,
+ struct iommu_hwpt_get_dirty_bitmap *bitmap)
+{
+ const struct iommu_dirty_ops *ops = domain->dirty_ops;
+ struct iommu_iotlb_gather gather;
+ struct iommu_dirty_bitmap dirty;
+ struct iova_bitmap_fn_arg arg;
+ struct iova_bitmap *iter;
+ int ret = 0;
+
+ if (!ops || !ops->read_and_clear_dirty)
+ return -EOPNOTSUPP;
+
+ iter = iova_bitmap_alloc(bitmap->iova, bitmap->length,
+ bitmap->page_size,
+ u64_to_user_ptr(bitmap->data));
+ if (IS_ERR(iter))
+ return -ENOMEM;
+
+ iommu_dirty_bitmap_init(&dirty, iter, &gather);
+
+ arg.flags = flags;
+ arg.iopt = iopt;
+ arg.domain = domain;
+ arg.dirty = &dirty;
+ iova_bitmap_for_each(iter, &arg, __iommu_read_and_clear_dirty);
+
+ if (!(flags & IOMMU_DIRTY_NO_CLEAR))
+ iommu_iotlb_sync(domain, &gather);
+
+ iova_bitmap_free(iter);
+
+ return ret;
+}
+
+int iommufd_check_iova_range(struct io_pagetable *iopt,
+ struct iommu_hwpt_get_dirty_bitmap *bitmap)
+{
+ size_t iommu_pgsize = iopt->iova_alignment;
+ u64 last_iova;
+
+ if (check_add_overflow(bitmap->iova, bitmap->length - 1, &last_iova))
+ return -EOVERFLOW;
+
+ if (bitmap->iova > ULONG_MAX || last_iova > ULONG_MAX)
+ return -EOVERFLOW;
+
+ if ((bitmap->iova & (iommu_pgsize - 1)) ||
+ ((last_iova + 1) & (iommu_pgsize - 1)))
+ return -EINVAL;
+
+ if (!bitmap->page_size)
+ return -EINVAL;
+
+ if ((bitmap->iova & (bitmap->page_size - 1)) ||
+ ((last_iova + 1) & (bitmap->page_size - 1)))
+ return -EINVAL;
+
+ return 0;
+}
+
+int iopt_read_and_clear_dirty_data(struct io_pagetable *iopt,
+ struct iommu_domain *domain,
+ unsigned long flags,
+ struct iommu_hwpt_get_dirty_bitmap *bitmap)
+{
+ int ret;
+
+ ret = iommufd_check_iova_range(iopt, bitmap);
+ if (ret)
+ return ret;
+
+ down_read(&iopt->iova_rwsem);
+ ret = iommu_read_and_clear_dirty(domain, iopt, flags, bitmap);
+ up_read(&iopt->iova_rwsem);
+
+ return ret;
+}
+
+static int iopt_clear_dirty_data(struct io_pagetable *iopt,
+ struct iommu_domain *domain)
+{
+ const struct iommu_dirty_ops *ops = domain->dirty_ops;
+ struct iommu_iotlb_gather gather;
+ struct iommu_dirty_bitmap dirty;
+ struct iopt_area *area;
+ int ret = 0;
+
+ lockdep_assert_held_read(&iopt->iova_rwsem);
+
+ iommu_dirty_bitmap_init(&dirty, NULL, &gather);
+
+ for (area = iopt_area_iter_first(iopt, 0, ULONG_MAX); area;
+ area = iopt_area_iter_next(area, 0, ULONG_MAX)) {
+ if (!area->pages)
+ continue;
+
+ ret = ops->read_and_clear_dirty(domain, iopt_area_iova(area),
+ iopt_area_length(area), 0,
+ &dirty);
+ if (ret)
+ break;
+ }
+
+ iommu_iotlb_sync(domain, &gather);
+ return ret;
+}
+
+int iopt_set_dirty_tracking(struct io_pagetable *iopt,
+ struct iommu_domain *domain, bool enable)
+{
+ const struct iommu_dirty_ops *ops = domain->dirty_ops;
+ int ret = 0;
+
+ if (!ops)
+ return -EOPNOTSUPP;
+
+ down_read(&iopt->iova_rwsem);
+
+ /* Clear dirty bits from PTEs to ensure a clean snapshot */
+ if (enable) {
+ ret = iopt_clear_dirty_data(iopt, domain);
+ if (ret)
+ goto out_unlock;
+ }
+
+ ret = ops->set_dirty_tracking(domain, enable);
+
+out_unlock:
+ up_read(&iopt->iova_rwsem);
+ return ret;
+}
+
int iopt_get_pages(struct io_pagetable *iopt, unsigned long iova,
unsigned long length, struct list_head *pages_list)
{
@@ -1005,11 +1189,11 @@ static int iopt_area_split(struct iopt_area *area, unsigned long iova)
iopt_area_start_byte(area, new_start) & (alignment - 1))
return -EINVAL;
- lhs = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT);
+ lhs = iopt_area_alloc();
if (!lhs)
return -ENOMEM;
- rhs = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT);
+ rhs = iopt_area_alloc();
if (!rhs) {
rc = -ENOMEM;
goto err_free_lhs;
@@ -1048,6 +1232,16 @@ static int iopt_area_split(struct iopt_area *area, unsigned long iova)
if (WARN_ON(rc))
goto err_remove_lhs;
+ /*
+ * If the original area has filled a domain, domains_itree has to be
+ * updated.
+ */
+ if (area->storage_domain) {
+ interval_tree_remove(&area->pages_node, &pages->domains_itree);
+ interval_tree_insert(&lhs->pages_node, &pages->domains_itree);
+ interval_tree_insert(&rhs->pages_node, &pages->domains_itree);
+ }
+
lhs->storage_domain = area->storage_domain;
lhs->pages = area->pages;
rhs->storage_domain = area->storage_domain;
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index 2c58670011fe..a74cfefffbc6 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -8,6 +8,9 @@
#include <linux/xarray.h>
#include <linux/refcount.h>
#include <linux/uaccess.h>
+#include <linux/iommu.h>
+#include <linux/iova_bitmap.h>
+#include <uapi/linux/iommufd.h>
struct iommu_domain;
struct iommu_group;
@@ -70,6 +73,13 @@ int iopt_unmap_iova(struct io_pagetable *iopt, unsigned long iova,
unsigned long length, unsigned long *unmapped);
int iopt_unmap_all(struct io_pagetable *iopt, unsigned long *unmapped);
+int iopt_read_and_clear_dirty_data(struct io_pagetable *iopt,
+ struct iommu_domain *domain,
+ unsigned long flags,
+ struct iommu_hwpt_get_dirty_bitmap *bitmap);
+int iopt_set_dirty_tracking(struct io_pagetable *iopt,
+ struct iommu_domain *domain, bool enable);
+
void iommufd_access_notify_unmap(struct io_pagetable *iopt, unsigned long iova,
unsigned long length);
int iopt_table_add_domain(struct io_pagetable *iopt,
@@ -113,7 +123,8 @@ enum iommufd_object_type {
IOMMUFD_OBJ_NONE,
IOMMUFD_OBJ_ANY = IOMMUFD_OBJ_NONE,
IOMMUFD_OBJ_DEVICE,
- IOMMUFD_OBJ_HW_PAGETABLE,
+ IOMMUFD_OBJ_HWPT_PAGING,
+ IOMMUFD_OBJ_HWPT_NESTED,
IOMMUFD_OBJ_IOAS,
IOMMUFD_OBJ_ACCESS,
#ifdef CONFIG_IOMMUFD_TEST
@@ -171,7 +182,7 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
size_t size,
enum iommufd_object_type type);
-#define iommufd_object_alloc(ictx, ptr, type) \
+#define __iommufd_object_alloc(ictx, ptr, type, obj) \
container_of(_iommufd_object_alloc( \
ictx, \
sizeof(*(ptr)) + BUILD_BUG_ON_ZERO( \
@@ -180,6 +191,9 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
type), \
typeof(*(ptr)), obj)
+#define iommufd_object_alloc(ictx, ptr, type) \
+ __iommufd_object_alloc(ictx, ptr, type, obj)
+
/*
* The IO Address Space (IOAS) pagetable is a virtual page table backed by the
* io_pagetable object. It is a user controlled mapping of IOVA -> PFNs. The
@@ -222,6 +236,8 @@ int iommufd_option_rlimit_mode(struct iommu_option *cmd,
struct iommufd_ctx *ictx);
int iommufd_vfio_ioas(struct iommufd_ucmd *ucmd);
+int iommufd_check_iova_range(struct io_pagetable *iopt,
+ struct iommu_hwpt_get_dirty_bitmap *bitmap);
/*
* A HW pagetable is called an iommu_domain inside the kernel. This user object
@@ -231,35 +247,75 @@ int iommufd_vfio_ioas(struct iommufd_ucmd *ucmd);
*/
struct iommufd_hw_pagetable {
struct iommufd_object obj;
- struct iommufd_ioas *ioas;
struct iommu_domain *domain;
+};
+
+struct iommufd_hwpt_paging {
+ struct iommufd_hw_pagetable common;
+ struct iommufd_ioas *ioas;
bool auto_domain : 1;
bool enforce_cache_coherency : 1;
bool msi_cookie : 1;
+ bool nest_parent : 1;
/* Head at iommufd_ioas::hwpt_list */
struct list_head hwpt_item;
};
-struct iommufd_hw_pagetable *
-iommufd_hw_pagetable_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
- struct iommufd_device *idev, bool immediate_attach);
-int iommufd_hw_pagetable_enforce_cc(struct iommufd_hw_pagetable *hwpt);
+struct iommufd_hwpt_nested {
+ struct iommufd_hw_pagetable common;
+ struct iommufd_hwpt_paging *parent;
+};
+
+static inline bool hwpt_is_paging(struct iommufd_hw_pagetable *hwpt)
+{
+ return hwpt->obj.type == IOMMUFD_OBJ_HWPT_PAGING;
+}
+
+static inline struct iommufd_hwpt_paging *
+to_hwpt_paging(struct iommufd_hw_pagetable *hwpt)
+{
+ return container_of(hwpt, struct iommufd_hwpt_paging, common);
+}
+
+static inline struct iommufd_hwpt_paging *
+iommufd_get_hwpt_paging(struct iommufd_ucmd *ucmd, u32 id)
+{
+ return container_of(iommufd_get_object(ucmd->ictx, id,
+ IOMMUFD_OBJ_HWPT_PAGING),
+ struct iommufd_hwpt_paging, common.obj);
+}
+int iommufd_hwpt_set_dirty_tracking(struct iommufd_ucmd *ucmd);
+int iommufd_hwpt_get_dirty_bitmap(struct iommufd_ucmd *ucmd);
+
+struct iommufd_hwpt_paging *
+iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
+ struct iommufd_device *idev, u32 flags,
+ bool immediate_attach,
+ const struct iommu_user_data *user_data);
int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
struct iommufd_device *idev);
struct iommufd_hw_pagetable *
iommufd_hw_pagetable_detach(struct iommufd_device *idev);
-void iommufd_hw_pagetable_destroy(struct iommufd_object *obj);
-void iommufd_hw_pagetable_abort(struct iommufd_object *obj);
+void iommufd_hwpt_paging_destroy(struct iommufd_object *obj);
+void iommufd_hwpt_paging_abort(struct iommufd_object *obj);
+void iommufd_hwpt_nested_destroy(struct iommufd_object *obj);
+void iommufd_hwpt_nested_abort(struct iommufd_object *obj);
int iommufd_hwpt_alloc(struct iommufd_ucmd *ucmd);
static inline void iommufd_hw_pagetable_put(struct iommufd_ctx *ictx,
struct iommufd_hw_pagetable *hwpt)
{
- lockdep_assert_not_held(&hwpt->ioas->mutex);
- if (hwpt->auto_domain)
- iommufd_object_deref_user(ictx, &hwpt->obj);
- else
- refcount_dec(&hwpt->obj.users);
+ if (hwpt->obj.type == IOMMUFD_OBJ_HWPT_PAGING) {
+ struct iommufd_hwpt_paging *hwpt_paging = to_hwpt_paging(hwpt);
+
+ lockdep_assert_not_held(&hwpt_paging->ioas->mutex);
+
+ if (hwpt_paging->auto_domain) {
+ iommufd_object_deref_user(ictx, &hwpt->obj);
+ return;
+ }
+ }
+ refcount_dec(&hwpt->obj.users);
}
struct iommufd_group {
diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h
index 3f3644375bf1..7910fbe1962d 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -19,6 +19,8 @@ enum {
IOMMU_TEST_OP_SET_TEMP_MEMORY_LIMIT,
IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE,
IOMMU_TEST_OP_ACCESS_REPLACE_IOAS,
+ IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS,
+ IOMMU_TEST_OP_DIRTY,
};
enum {
@@ -40,6 +42,15 @@ enum {
MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES = 1 << 0,
};
+enum {
+ MOCK_FLAGS_DEVICE_NO_DIRTY = 1 << 0,
+};
+
+enum {
+ MOCK_NESTED_DOMAIN_IOTLB_ID_MAX = 3,
+ MOCK_NESTED_DOMAIN_IOTLB_NUM = 4,
+};
+
struct iommu_test_cmd {
__u32 size;
__u32 op;
@@ -57,6 +68,13 @@ struct iommu_test_cmd {
__u32 out_idev_id;
} mock_domain;
struct {
+ __u32 out_stdev_id;
+ __u32 out_hwpt_id;
+ __u32 out_idev_id;
+ /* Expand mock_domain to set mock device flags */
+ __u32 dev_flags;
+ } mock_domain_flags;
+ struct {
__u32 pt_id;
} mock_domain_replace;
struct {
@@ -95,6 +113,14 @@ struct iommu_test_cmd {
struct {
__u32 ioas_id;
} access_replace_ioas;
+ struct {
+ __u32 flags;
+ __aligned_u64 iova;
+ __aligned_u64 length;
+ __aligned_u64 page_size;
+ __aligned_u64 uptr;
+ __aligned_u64 out_nr_dirty;
+ } dirty;
};
__u32 last;
};
@@ -109,4 +135,17 @@ struct iommu_test_hw_info {
__u32 test_reg;
};
+/* Should not be equal to any defined value in enum iommu_hwpt_data_type */
+#define IOMMU_HWPT_DATA_SELFTEST 0xdead
+#define IOMMU_TEST_IOTLB_DEFAULT 0xbadbeef
+
+/**
+ * struct iommu_hwpt_selftest
+ *
+ * @iotlb: default mock iotlb value, IOMMU_TEST_IOTLB_DEFAULT
+ */
+struct iommu_hwpt_selftest {
+ __u32 iotlb;
+};
+
#endif
diff --git a/drivers/vfio/iova_bitmap.c b/drivers/iommu/iommufd/iova_bitmap.c
index 0848f920efb7..0a92c9eeaf7f 100644
--- a/drivers/vfio/iova_bitmap.c
+++ b/drivers/iommu/iommufd/iova_bitmap.c
@@ -268,6 +268,7 @@ err:
iova_bitmap_free(bitmap);
return ERR_PTR(rc);
}
+EXPORT_SYMBOL_NS_GPL(iova_bitmap_alloc, IOMMUFD);
/**
* iova_bitmap_free() - Frees an IOVA bitmap object
@@ -289,6 +290,7 @@ void iova_bitmap_free(struct iova_bitmap *bitmap)
kfree(bitmap);
}
+EXPORT_SYMBOL_NS_GPL(iova_bitmap_free, IOMMUFD);
/*
* Returns the remaining bitmap indexes from mapped_total_index to process for
@@ -387,6 +389,7 @@ int iova_bitmap_for_each(struct iova_bitmap *bitmap, void *opaque,
return ret;
}
+EXPORT_SYMBOL_NS_GPL(iova_bitmap_for_each, IOMMUFD);
/**
* iova_bitmap_set() - Records an IOVA range in bitmap
@@ -420,4 +423,4 @@ void iova_bitmap_set(struct iova_bitmap *bitmap,
cur_bit += nbits;
} while (cur_bit <= last_bit);
}
-EXPORT_SYMBOL_GPL(iova_bitmap_set);
+EXPORT_SYMBOL_NS_GPL(iova_bitmap_set, IOMMUFD);
diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index e71523cbd0de..45b9d40773b1 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -307,6 +307,8 @@ union ucmd_buffer {
struct iommu_destroy destroy;
struct iommu_hw_info info;
struct iommu_hwpt_alloc hwpt;
+ struct iommu_hwpt_get_dirty_bitmap get_dirty_bitmap;
+ struct iommu_hwpt_set_dirty_tracking set_dirty_tracking;
struct iommu_ioas_alloc alloc;
struct iommu_ioas_allow_iovas allow_iovas;
struct iommu_ioas_copy ioas_copy;
@@ -342,6 +344,10 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = {
__reserved),
IOCTL_OP(IOMMU_HWPT_ALLOC, iommufd_hwpt_alloc, struct iommu_hwpt_alloc,
__reserved),
+ IOCTL_OP(IOMMU_HWPT_GET_DIRTY_BITMAP, iommufd_hwpt_get_dirty_bitmap,
+ struct iommu_hwpt_get_dirty_bitmap, data),
+ IOCTL_OP(IOMMU_HWPT_SET_DIRTY_TRACKING, iommufd_hwpt_set_dirty_tracking,
+ struct iommu_hwpt_set_dirty_tracking, __reserved),
IOCTL_OP(IOMMU_IOAS_ALLOC, iommufd_ioas_alloc_ioctl,
struct iommu_ioas_alloc, out_ioas_id),
IOCTL_OP(IOMMU_IOAS_ALLOW_IOVAS, iommufd_ioas_allow_iovas,
@@ -482,9 +488,13 @@ static const struct iommufd_object_ops iommufd_object_ops[] = {
[IOMMUFD_OBJ_IOAS] = {
.destroy = iommufd_ioas_destroy,
},
- [IOMMUFD_OBJ_HW_PAGETABLE] = {
- .destroy = iommufd_hw_pagetable_destroy,
- .abort = iommufd_hw_pagetable_abort,
+ [IOMMUFD_OBJ_HWPT_PAGING] = {
+ .destroy = iommufd_hwpt_paging_destroy,
+ .abort = iommufd_hwpt_paging_abort,
+ },
+ [IOMMUFD_OBJ_HWPT_NESTED] = {
+ .destroy = iommufd_hwpt_nested_destroy,
+ .abort = iommufd_hwpt_nested_abort,
},
#ifdef CONFIG_IOMMUFD_TEST
[IOMMUFD_OBJ_SELFTEST] = {
@@ -552,5 +562,6 @@ MODULE_ALIAS_MISCDEV(VFIO_MINOR);
MODULE_ALIAS("devname:vfio/vfio");
#endif
MODULE_IMPORT_NS(IOMMUFD_INTERNAL);
+MODULE_IMPORT_NS(IOMMUFD);
MODULE_DESCRIPTION("I/O Address Space Management for passthrough devices");
MODULE_LICENSE("GPL");
diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c
index 8d9aa297c117..528f356238b3 100644
--- a/drivers/iommu/iommufd/pages.c
+++ b/drivers/iommu/iommufd/pages.c
@@ -1507,6 +1507,8 @@ void iopt_area_unfill_domains(struct iopt_area *area, struct iopt_pages *pages)
area, domain, iopt_area_index(area),
iopt_area_last_index(area));
+ if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
+ WARN_ON(RB_EMPTY_NODE(&area->pages_node.rb));
interval_tree_remove(&area->pages_node, &pages->domains_itree);
iopt_area_unfill_domain(area, pages, area->storage_domain);
area->storage_domain = NULL;
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index 56506d5753f1..d43a87737c1e 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -20,10 +20,13 @@
static DECLARE_FAULT_ATTR(fail_iommufd);
static struct dentry *dbgfs_root;
static struct platform_device *selftest_iommu_dev;
+static const struct iommu_ops mock_ops;
+static struct iommu_domain_ops domain_nested_ops;
size_t iommufd_test_memory_limit = 65536;
enum {
+ MOCK_DIRTY_TRACK = 1,
MOCK_IO_PAGE_SIZE = PAGE_SIZE / 2,
/*
@@ -36,6 +39,7 @@ enum {
_MOCK_PFN_START = MOCK_PFN_MASK + 1,
MOCK_PFN_START_IOVA = _MOCK_PFN_START,
MOCK_PFN_LAST_IOVA = _MOCK_PFN_START,
+ MOCK_PFN_DIRTY_IOVA = _MOCK_PFN_START << 1,
};
/*
@@ -86,16 +90,24 @@ void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,
}
struct mock_iommu_domain {
+ unsigned long flags;
struct iommu_domain domain;
struct xarray pfns;
};
+struct mock_iommu_domain_nested {
+ struct iommu_domain domain;
+ struct mock_iommu_domain *parent;
+ u32 iotlb[MOCK_NESTED_DOMAIN_IOTLB_NUM];
+};
+
enum selftest_obj_type {
TYPE_IDEV,
};
struct mock_dev {
struct device dev;
+ unsigned long flags;
};
struct selftest_obj {
@@ -118,6 +130,11 @@ static void mock_domain_blocking_free(struct iommu_domain *domain)
static int mock_domain_nop_attach(struct iommu_domain *domain,
struct device *dev)
{
+ struct mock_dev *mdev = container_of(dev, struct mock_dev, dev);
+
+ if (domain->dirty_ops && (mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
+ return -EINVAL;
+
return 0;
}
@@ -146,15 +163,70 @@ static void *mock_domain_hw_info(struct device *dev, u32 *length, u32 *type)
return info;
}
-static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type)
+static int mock_domain_set_dirty_tracking(struct iommu_domain *domain,
+ bool enable)
{
- struct mock_iommu_domain *mock;
+ struct mock_iommu_domain *mock =
+ container_of(domain, struct mock_iommu_domain, domain);
+ unsigned long flags = mock->flags;
- if (iommu_domain_type == IOMMU_DOMAIN_BLOCKED)
- return &mock_blocking_domain;
+ if (enable && !domain->dirty_ops)
+ return -EINVAL;
- if (iommu_domain_type != IOMMU_DOMAIN_UNMANAGED)
- return NULL;
+ /* No change? */
+ if (!(enable ^ !!(flags & MOCK_DIRTY_TRACK)))
+ return 0;
+
+ flags = (enable ? flags | MOCK_DIRTY_TRACK : flags & ~MOCK_DIRTY_TRACK);
+
+ mock->flags = flags;
+ return 0;
+}
+
+static int mock_domain_read_and_clear_dirty(struct iommu_domain *domain,
+ unsigned long iova, size_t size,
+ unsigned long flags,
+ struct iommu_dirty_bitmap *dirty)
+{
+ struct mock_iommu_domain *mock =
+ container_of(domain, struct mock_iommu_domain, domain);
+ unsigned long i, max = size / MOCK_IO_PAGE_SIZE;
+ void *ent, *old;
+
+ if (!(mock->flags & MOCK_DIRTY_TRACK) && dirty->bitmap)
+ return -EINVAL;
+
+ for (i = 0; i < max; i++) {
+ unsigned long cur = iova + i * MOCK_IO_PAGE_SIZE;
+
+ ent = xa_load(&mock->pfns, cur / MOCK_IO_PAGE_SIZE);
+ if (ent && (xa_to_value(ent) & MOCK_PFN_DIRTY_IOVA)) {
+ /* Clear dirty */
+ if (!(flags & IOMMU_DIRTY_NO_CLEAR)) {
+ unsigned long val;
+
+ val = xa_to_value(ent) & ~MOCK_PFN_DIRTY_IOVA;
+ old = xa_store(&mock->pfns,
+ cur / MOCK_IO_PAGE_SIZE,
+ xa_mk_value(val), GFP_KERNEL);
+ WARN_ON_ONCE(ent != old);
+ }
+ iommu_dirty_bitmap_record(dirty, cur,
+ MOCK_IO_PAGE_SIZE);
+ }
+ }
+
+ return 0;
+}
+
+const struct iommu_dirty_ops dirty_ops = {
+ .set_dirty_tracking = mock_domain_set_dirty_tracking,
+ .read_and_clear_dirty = mock_domain_read_and_clear_dirty,
+};
+
+static struct iommu_domain *mock_domain_alloc_paging(struct device *dev)
+{
+ struct mock_iommu_domain *mock;
mock = kzalloc(sizeof(*mock), GFP_KERNEL);
if (!mock)
@@ -162,10 +234,87 @@ static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type)
mock->domain.geometry.aperture_start = MOCK_APERTURE_START;
mock->domain.geometry.aperture_end = MOCK_APERTURE_LAST;
mock->domain.pgsize_bitmap = MOCK_IO_PAGE_SIZE;
+ mock->domain.ops = mock_ops.default_domain_ops;
+ mock->domain.type = IOMMU_DOMAIN_UNMANAGED;
xa_init(&mock->pfns);
return &mock->domain;
}
+static struct iommu_domain *
+__mock_domain_alloc_nested(struct mock_iommu_domain *mock_parent,
+ const struct iommu_hwpt_selftest *user_cfg)
+{
+ struct mock_iommu_domain_nested *mock_nested;
+ int i;
+
+ mock_nested = kzalloc(sizeof(*mock_nested), GFP_KERNEL);
+ if (!mock_nested)
+ return ERR_PTR(-ENOMEM);
+ mock_nested->parent = mock_parent;
+ mock_nested->domain.ops = &domain_nested_ops;
+ mock_nested->domain.type = IOMMU_DOMAIN_NESTED;
+ for (i = 0; i < MOCK_NESTED_DOMAIN_IOTLB_NUM; i++)
+ mock_nested->iotlb[i] = user_cfg->iotlb;
+ return &mock_nested->domain;
+}
+
+static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type)
+{
+ if (iommu_domain_type == IOMMU_DOMAIN_BLOCKED)
+ return &mock_blocking_domain;
+ if (iommu_domain_type == IOMMU_DOMAIN_UNMANAGED)
+ return mock_domain_alloc_paging(NULL);
+ return NULL;
+}
+
+static struct iommu_domain *
+mock_domain_alloc_user(struct device *dev, u32 flags,
+ struct iommu_domain *parent,
+ const struct iommu_user_data *user_data)
+{
+ struct mock_iommu_domain *mock_parent;
+ struct iommu_hwpt_selftest user_cfg;
+ int rc;
+
+ /* must be mock_domain */
+ if (!parent) {
+ struct mock_dev *mdev = container_of(dev, struct mock_dev, dev);
+ bool has_dirty_flag = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
+ bool no_dirty_ops = mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY;
+ struct iommu_domain *domain;
+
+ if (flags & (~(IOMMU_HWPT_ALLOC_NEST_PARENT |
+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING)))
+ return ERR_PTR(-EOPNOTSUPP);
+ if (user_data || (has_dirty_flag && no_dirty_ops))
+ return ERR_PTR(-EOPNOTSUPP);
+ domain = mock_domain_alloc_paging(NULL);
+ if (!domain)
+ return ERR_PTR(-ENOMEM);
+ if (has_dirty_flag)
+ container_of(domain, struct mock_iommu_domain, domain)
+ ->domain.dirty_ops = &dirty_ops;
+ return domain;
+ }
+
+ /* must be mock_domain_nested */
+ if (user_data->type != IOMMU_HWPT_DATA_SELFTEST || flags)
+ return ERR_PTR(-EOPNOTSUPP);
+ if (!parent || parent->ops != mock_ops.default_domain_ops)
+ return ERR_PTR(-EINVAL);
+
+ mock_parent = container_of(parent, struct mock_iommu_domain, domain);
+ if (!mock_parent)
+ return ERR_PTR(-EINVAL);
+
+ rc = iommu_copy_struct_from_user(&user_cfg, user_data,
+ IOMMU_HWPT_DATA_SELFTEST, iotlb);
+ if (rc)
+ return ERR_PTR(rc);
+
+ return __mock_domain_alloc_nested(mock_parent, &user_cfg);
+}
+
static void mock_domain_free(struct iommu_domain *domain)
{
struct mock_iommu_domain *mock =
@@ -243,7 +392,7 @@ static size_t mock_domain_unmap_pages(struct iommu_domain *domain,
for (cur = 0; cur != pgsize; cur += MOCK_IO_PAGE_SIZE) {
ent = xa_erase(&mock->pfns, iova / MOCK_IO_PAGE_SIZE);
- WARN_ON(!ent);
+
/*
* iommufd generates unmaps that must be a strict
* superset of the map's performend So every starting
@@ -253,13 +402,13 @@ static size_t mock_domain_unmap_pages(struct iommu_domain *domain,
* passed to map_pages
*/
if (first) {
- WARN_ON(!(xa_to_value(ent) &
- MOCK_PFN_START_IOVA));
+ WARN_ON(ent && !(xa_to_value(ent) &
+ MOCK_PFN_START_IOVA));
first = false;
}
if (pgcount == 1 && cur + MOCK_IO_PAGE_SIZE == pgsize)
- WARN_ON(!(xa_to_value(ent) &
- MOCK_PFN_LAST_IOVA));
+ WARN_ON(ent && !(xa_to_value(ent) &
+ MOCK_PFN_LAST_IOVA));
iova += MOCK_IO_PAGE_SIZE;
ret += MOCK_IO_PAGE_SIZE;
@@ -283,7 +432,18 @@ static phys_addr_t mock_domain_iova_to_phys(struct iommu_domain *domain,
static bool mock_domain_capable(struct device *dev, enum iommu_cap cap)
{
- return cap == IOMMU_CAP_CACHE_COHERENCY;
+ struct mock_dev *mdev = container_of(dev, struct mock_dev, dev);
+
+ switch (cap) {
+ case IOMMU_CAP_CACHE_COHERENCY:
+ return true;
+ case IOMMU_CAP_DIRTY_TRACKING:
+ return !(mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY);
+ default:
+ break;
+ }
+
+ return false;
}
static void mock_domain_set_plaform_dma_ops(struct device *dev)
@@ -307,6 +467,7 @@ static const struct iommu_ops mock_ops = {
.pgsize_bitmap = MOCK_IO_PAGE_SIZE,
.hw_info = mock_domain_hw_info,
.domain_alloc = mock_domain_alloc,
+ .domain_alloc_user = mock_domain_alloc_user,
.capable = mock_domain_capable,
.set_platform_dma_ops = mock_domain_set_plaform_dma_ops,
.device_group = generic_device_group,
@@ -321,19 +482,41 @@ static const struct iommu_ops mock_ops = {
},
};
+static void mock_domain_free_nested(struct iommu_domain *domain)
+{
+ struct mock_iommu_domain_nested *mock_nested =
+ container_of(domain, struct mock_iommu_domain_nested, domain);
+
+ kfree(mock_nested);
+}
+
+static struct iommu_domain_ops domain_nested_ops = {
+ .free = mock_domain_free_nested,
+ .attach_dev = mock_domain_nop_attach,
+};
+
static inline struct iommufd_hw_pagetable *
-get_md_pagetable(struct iommufd_ucmd *ucmd, u32 mockpt_id,
- struct mock_iommu_domain **mock)
+__get_md_pagetable(struct iommufd_ucmd *ucmd, u32 mockpt_id, u32 hwpt_type)
{
- struct iommufd_hw_pagetable *hwpt;
struct iommufd_object *obj;
- obj = iommufd_get_object(ucmd->ictx, mockpt_id,
- IOMMUFD_OBJ_HW_PAGETABLE);
+ obj = iommufd_get_object(ucmd->ictx, mockpt_id, hwpt_type);
if (IS_ERR(obj))
return ERR_CAST(obj);
- hwpt = container_of(obj, struct iommufd_hw_pagetable, obj);
- if (hwpt->domain->ops != mock_ops.default_domain_ops) {
+ return container_of(obj, struct iommufd_hw_pagetable, obj);
+}
+
+static inline struct iommufd_hw_pagetable *
+get_md_pagetable(struct iommufd_ucmd *ucmd, u32 mockpt_id,
+ struct mock_iommu_domain **mock)
+{
+ struct iommufd_hw_pagetable *hwpt;
+
+ hwpt = __get_md_pagetable(ucmd, mockpt_id, IOMMUFD_OBJ_HWPT_PAGING);
+ if (IS_ERR(hwpt))
+ return hwpt;
+ if (hwpt->domain->type != IOMMU_DOMAIN_UNMANAGED ||
+ hwpt->domain->ops != mock_ops.default_domain_ops) {
iommufd_put_object(&hwpt->obj);
return ERR_PTR(-EINVAL);
}
@@ -341,6 +524,25 @@ get_md_pagetable(struct iommufd_ucmd *ucmd, u32 mockpt_id,
return hwpt;
}
+static inline struct iommufd_hw_pagetable *
+get_md_pagetable_nested(struct iommufd_ucmd *ucmd, u32 mockpt_id,
+ struct mock_iommu_domain_nested **mock_nested)
+{
+ struct iommufd_hw_pagetable *hwpt;
+
+ hwpt = __get_md_pagetable(ucmd, mockpt_id, IOMMUFD_OBJ_HWPT_NESTED);
+ if (IS_ERR(hwpt))
+ return hwpt;
+ if (hwpt->domain->type != IOMMU_DOMAIN_NESTED ||
+ hwpt->domain->ops != &domain_nested_ops) {
+ iommufd_put_object(&hwpt->obj);
+ return ERR_PTR(-EINVAL);
+ }
+ *mock_nested = container_of(hwpt->domain,
+ struct mock_iommu_domain_nested, domain);
+ return hwpt;
+}
+
struct mock_bus_type {
struct bus_type bus;
struct notifier_block nb;
@@ -362,16 +564,20 @@ static void mock_dev_release(struct device *dev)
kfree(mdev);
}
-static struct mock_dev *mock_dev_create(void)
+static struct mock_dev *mock_dev_create(unsigned long dev_flags)
{
struct mock_dev *mdev;
int rc;
+ if (dev_flags & ~(MOCK_FLAGS_DEVICE_NO_DIRTY))
+ return ERR_PTR(-EINVAL);
+
mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
if (!mdev)
return ERR_PTR(-ENOMEM);
device_initialize(&mdev->dev);
+ mdev->flags = dev_flags;
mdev->dev.release = mock_dev_release;
mdev->dev.bus = &iommufd_mock_bus_type.bus;
@@ -407,6 +613,7 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd,
struct iommufd_device *idev;
struct selftest_obj *sobj;
u32 pt_id = cmd->id;
+ u32 dev_flags = 0;
u32 idev_id;
int rc;
@@ -417,7 +624,10 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd,
sobj->idev.ictx = ucmd->ictx;
sobj->type = TYPE_IDEV;
- sobj->idev.mock_dev = mock_dev_create();
+ if (cmd->op == IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS)
+ dev_flags = cmd->mock_domain_flags.dev_flags;
+
+ sobj->idev.mock_dev = mock_dev_create(dev_flags);
if (IS_ERR(sobj->idev.mock_dev)) {
rc = PTR_ERR(sobj->idev.mock_dev);
goto out_sobj;
@@ -977,6 +1187,73 @@ static_assert((unsigned int)MOCK_ACCESS_RW_WRITE == IOMMUFD_ACCESS_RW_WRITE);
static_assert((unsigned int)MOCK_ACCESS_RW_SLOW_PATH ==
__IOMMUFD_ACCESS_RW_SLOW_PATH);
+static int iommufd_test_dirty(struct iommufd_ucmd *ucmd, unsigned int mockpt_id,
+ unsigned long iova, size_t length,
+ unsigned long page_size, void __user *uptr,
+ u32 flags)
+{
+ unsigned long bitmap_size, i, max;
+ struct iommu_test_cmd *cmd = ucmd->cmd;
+ struct iommufd_hw_pagetable *hwpt;
+ struct mock_iommu_domain *mock;
+ int rc, count = 0;
+ void *tmp;
+
+ if (!page_size || !length || iova % page_size || length % page_size ||
+ !uptr)
+ return -EINVAL;
+
+ hwpt = get_md_pagetable(ucmd, mockpt_id, &mock);
+ if (IS_ERR(hwpt))
+ return PTR_ERR(hwpt);
+
+ if (!(mock->flags & MOCK_DIRTY_TRACK)) {
+ rc = -EINVAL;
+ goto out_put;
+ }
+
+ max = length / page_size;
+ bitmap_size = max / BITS_PER_BYTE;
+
+ tmp = kvzalloc(bitmap_size, GFP_KERNEL_ACCOUNT);
+ if (!tmp) {
+ rc = -ENOMEM;
+ goto out_put;
+ }
+
+ if (copy_from_user(tmp, uptr, bitmap_size)) {
+ rc = -EFAULT;
+ goto out_free;
+ }
+
+ for (i = 0; i < max; i++) {
+ unsigned long cur = iova + i * page_size;
+ void *ent, *old;
+
+ if (!test_bit(i, (unsigned long *)tmp))
+ continue;
+
+ ent = xa_load(&mock->pfns, cur / page_size);
+ if (ent) {
+ unsigned long val;
+
+ val = xa_to_value(ent) | MOCK_PFN_DIRTY_IOVA;
+ old = xa_store(&mock->pfns, cur / page_size,
+ xa_mk_value(val), GFP_KERNEL);
+ WARN_ON_ONCE(ent != old);
+ count++;
+ }
+ }
+
+ cmd->dirty.out_nr_dirty = count;
+ rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
+out_free:
+ kvfree(tmp);
+out_put:
+ iommufd_put_object(&hwpt->obj);
+ return rc;
+}
+
void iommufd_selftest_destroy(struct iommufd_object *obj)
{
struct selftest_obj *sobj = container_of(obj, struct selftest_obj, obj);
@@ -1000,6 +1277,7 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
cmd->add_reserved.start,
cmd->add_reserved.length);
case IOMMU_TEST_OP_MOCK_DOMAIN:
+ case IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS:
return iommufd_test_mock_domain(ucmd, cmd);
case IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE:
return iommufd_test_mock_domain_replace(
@@ -1041,6 +1319,12 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
return -EINVAL;
iommufd_test_memory_limit = cmd->memory_limit.limit;
return 0;
+ case IOMMU_TEST_OP_DIRTY:
+ return iommufd_test_dirty(ucmd, cmd->id, cmd->dirty.iova,
+ cmd->dirty.length,
+ cmd->dirty.page_size,
+ u64_to_user_ptr(cmd->dirty.uptr),
+ cmd->dirty.flags);
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/iommu/iommufd/vfio_compat.c b/drivers/iommu/iommufd/vfio_compat.c
index 6c810bf80f99..538fbf76354d 100644
--- a/drivers/iommu/iommufd/vfio_compat.c
+++ b/drivers/iommu/iommufd/vfio_compat.c
@@ -255,7 +255,7 @@ err_put:
static int iommufd_vfio_cc_iommu(struct iommufd_ctx *ictx)
{
- struct iommufd_hw_pagetable *hwpt;
+ struct iommufd_hwpt_paging *hwpt_paging;
struct iommufd_ioas *ioas;
int rc = 1;
@@ -264,8 +264,8 @@ static int iommufd_vfio_cc_iommu(struct iommufd_ctx *ictx)
return PTR_ERR(ioas);
mutex_lock(&ioas->mutex);
- list_for_each_entry(hwpt, &ioas->hwpt_list, hwpt_item) {
- if (!hwpt->enforce_cache_coherency) {
+ list_for_each_entry(hwpt_paging, &ioas->hwpt_list, hwpt_item) {
+ if (!hwpt_paging->enforce_cache_coherency) {
rc = 0;
break;
}
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index f59ac9586b7b..68d11ccee441 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -79,6 +79,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
#define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
/*
+ * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs
+ * are potentially stolen by the secure side. Some code, especially code dealing
+ * with hwirq IDs, is simplified by accounting for all 16.
+ */
+#define SGI_NR 16
+
+/*
* The behaviours of RPR and PMR registers differ depending on the value of
* SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
* distributor and redistributors depends on whether security is enabled in the
@@ -99,7 +106,7 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
* - Figure 4-7 Secure read of the priority field for a Non-secure Group 1
* interrupt.
*/
-static DEFINE_STATIC_KEY_FALSE(supports_pseudo_nmis);
+DEFINE_STATIC_KEY_FALSE(supports_pseudo_nmis);
DEFINE_STATIC_KEY_FALSE(gic_nonsecure_priorities);
EXPORT_SYMBOL(gic_nonsecure_priorities);
@@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
__priority; \
})
-/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
-static refcount_t *ppi_nmi_refs;
+/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
+static refcount_t *rdist_nmi_refs;
static struct gic_kvm_info gic_v3_kvm_info __initdata;
static DEFINE_PER_CPU(bool, has_rss);
@@ -270,17 +277,6 @@ static void gic_redist_wait_for_rwp(void)
gic_do_wait_for_rwp(gic_data_rdist_rd_base(), GICR_CTLR_RWP);
}
-#ifdef CONFIG_ARM64
-
-static u64 __maybe_unused gic_read_iar(void)
-{
- if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_23154))
- return gic_read_iar_cavium_thunderx();
- else
- return gic_read_iar_common();
-}
-#endif
-
static void gic_enable_redist(bool enable)
{
void __iomem *rbase;
@@ -519,9 +515,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
}
}
-static u32 gic_get_ppi_index(struct irq_data *d)
+static u32 __gic_get_rdist_index(irq_hw_number_t hwirq)
+{
+ switch (__get_intid_range(hwirq)) {
+ case SGI_RANGE:
+ case PPI_RANGE:
+ return hwirq;
+ case EPPI_RANGE:
+ return hwirq - EPPI_BASE_INTID + 32;
+ default:
+ unreachable();
+ }
+}
+
+static u32 gic_get_rdist_index(struct irq_data *d)
{
- return __gic_get_ppi_index(d->hwirq);
+ return __gic_get_rdist_index(d->hwirq);
}
static int gic_irq_nmi_setup(struct irq_data *d)
@@ -545,11 +554,14 @@ static int gic_irq_nmi_setup(struct irq_data *d)
/* desc lock should already be held */
if (gic_irq_in_rdist(d)) {
- u32 idx = gic_get_ppi_index(d);
+ u32 idx = gic_get_rdist_index(d);
- /* Setting up PPI as NMI, only switch handler for first NMI */
- if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) {
- refcount_set(&ppi_nmi_refs[idx], 1);
+ /*
+ * Setting up a percpu interrupt as NMI, only switch handler
+ * for first NMI
+ */
+ if (!refcount_inc_not_zero(&rdist_nmi_refs[idx])) {
+ refcount_set(&rdist_nmi_refs[idx], 1);
desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
}
} else {
@@ -582,10 +594,10 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
/* desc lock should already be held */
if (gic_irq_in_rdist(d)) {
- u32 idx = gic_get_ppi_index(d);
+ u32 idx = gic_get_rdist_index(d);
/* Tearing down NMI, only switch handler for last NMI */
- if (refcount_dec_and_test(&ppi_nmi_refs[idx]))
+ if (refcount_dec_and_test(&rdist_nmi_refs[idx]))
desc->handle_irq = handle_percpu_devid_irq;
} else {
desc->handle_irq = handle_fasteoi_irq;
@@ -1279,10 +1291,10 @@ static void gic_cpu_init(void)
rbase = gic_data_rdist_sgi_base();
/* Configure SGIs/PPIs as non-secure Group-1 */
- for (i = 0; i < gic_data.ppi_nr + 16; i += 32)
+ for (i = 0; i < gic_data.ppi_nr + SGI_NR; i += 32)
writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8);
- gic_cpu_config(rbase, gic_data.ppi_nr + 16, gic_redist_wait_for_rwp);
+ gic_cpu_config(rbase, gic_data.ppi_nr + SGI_NR, gic_redist_wait_for_rwp);
/* initialise system registers */
gic_cpu_sys_reg_init();
@@ -1952,12 +1964,13 @@ static void gic_enable_nmi_support(void)
return;
}
- ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
- if (!ppi_nmi_refs)
+ rdist_nmi_refs = kcalloc(gic_data.ppi_nr + SGI_NR,
+ sizeof(*rdist_nmi_refs), GFP_KERNEL);
+ if (!rdist_nmi_refs)
return;
- for (i = 0; i < gic_data.ppi_nr; i++)
- refcount_set(&ppi_nmi_refs[i], 0);
+ for (i = 0; i < gic_data.ppi_nr + SGI_NR; i++)
+ refcount_set(&rdist_nmi_refs[i], 0);
pr_info("Pseudo-NMIs enabled using %s ICC_PMR_EL1 synchronisation\n",
gic_has_relaxed_pmr_sync() ? "relaxed" : "forced");
@@ -2074,6 +2087,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
gic_dist_init();
gic_cpu_init();
+ gic_enable_nmi_support();
gic_smp_init();
gic_cpu_pm_init();
@@ -2086,8 +2100,6 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
gicv2m_init(handle, gic_data.domain);
}
- gic_enable_nmi_support();
-
return 0;
out_free:
@@ -2380,8 +2392,7 @@ gic_acpi_parse_madt_gicc(union acpi_subtable_headers *header,
u32 size = reg == GIC_PIDR2_ARCH_GICv4 ? SZ_64K * 4 : SZ_64K * 2;
void __iomem *redist_base;
- /* GICC entry which has !ACPI_MADT_ENABLED is not unusable so skip */
- if (!(gicc->flags & ACPI_MADT_ENABLED))
+ if (!acpi_gicc_is_usable(gicc))
return 0;
redist_base = ioremap(gicc->gicr_base_address, size);
@@ -2431,7 +2442,7 @@ static int __init gic_acpi_match_gicc(union acpi_subtable_headers *header,
* If GICC is enabled and has valid gicr base address, then it means
* GICR base is presented via GICC
*/
- if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) {
+ if (acpi_gicc_is_usable(gicc) && gicc->gicr_base_address) {
acpi_data.enabled_rdists++;
return 0;
}
@@ -2440,7 +2451,7 @@ static int __init gic_acpi_match_gicc(union acpi_subtable_headers *header,
* It's perfectly valid firmware can pass disabled GICC entry, driver
* should not treat as errors, skip the entry instead of probe fail.
*/
- if (!(gicc->flags & ACPI_MADT_ENABLED))
+ if (!acpi_gicc_is_usable(gicc))
return 0;
return -ENODEV;
@@ -2499,8 +2510,7 @@ static int __init gic_acpi_parse_virt_madt_gicc(union acpi_subtable_headers *hea
int maint_irq_mode;
static int first_madt = true;
- /* Skip unusable CPUs */
- if (!(gicc->flags & ACPI_MADT_ENABLED))
+ if (!acpi_gicc_is_usable(gicc))
return 0;
maint_irq_mode = (gicc->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index d8c4d5664145..1ae3539beff5 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -236,7 +236,6 @@ static struct ctl_table mac_hid_files[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
- { }
};
static struct ctl_table_header *mac_hid_sysctl_header;
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
index acffed750e3e..5a18b80d3666 100644
--- a/drivers/md/dm-cache-metadata.c
+++ b/drivers/md/dm-cache-metadata.c
@@ -597,7 +597,7 @@ static void read_superblock_fields(struct dm_cache_metadata *cmd,
cmd->discard_nr_blocks = to_dblock(le64_to_cpu(disk_super->discard_nr_blocks));
cmd->data_block_size = le32_to_cpu(disk_super->data_block_size);
cmd->cache_blocks = to_cblock(le32_to_cpu(disk_super->cache_blocks));
- strncpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name));
+ strscpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name));
cmd->policy_version[0] = le32_to_cpu(disk_super->policy_version[0]);
cmd->policy_version[1] = le32_to_cpu(disk_super->policy_version[1]);
cmd->policy_version[2] = le32_to_cpu(disk_super->policy_version[2]);
@@ -707,7 +707,7 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
disk_super->discard_block_size = cpu_to_le64(cmd->discard_block_size);
disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks));
disk_super->cache_blocks = cpu_to_le32(from_cblock(cmd->cache_blocks));
- strncpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name));
+ strscpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name));
disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]);
disk_super->policy_version[1] = cpu_to_le32(cmd->policy_version[1]);
disk_super->policy_version[2] = cpu_to_le32(cmd->policy_version[2]);
@@ -1726,7 +1726,7 @@ static int write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po
(strlen(policy_name) > sizeof(cmd->policy_name) - 1))
return -EINVAL;
- strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name));
+ strscpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name));
memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version));
hint_size = dm_cache_policy_get_hint_size(policy);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index be32a290c90a..6de107aff331 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -652,13 +652,7 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc,
/* calculate crc32 for every 32bit part and xor it */
desc->tfm = tcw->crc32_tfm;
for (i = 0; i < 4; i++) {
- r = crypto_shash_init(desc);
- if (r)
- goto out;
- r = crypto_shash_update(desc, &buf[i * 4], 4);
- if (r)
- goto out;
- r = crypto_shash_final(desc, &buf[i * 4]);
+ r = crypto_shash_digest(desc, &buf[i * 4], 4, &buf[i * 4]);
if (r)
goto out;
}
@@ -1699,11 +1693,17 @@ retry:
order = min(order, remaining_order);
while (order > 0) {
+ if (unlikely(percpu_counter_read_positive(&cc->n_allocated_pages) +
+ (1 << order) > dm_crypt_pages_per_client))
+ goto decrease_order;
pages = alloc_pages(gfp_mask
| __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | __GFP_COMP,
order);
- if (likely(pages != NULL))
+ if (likely(pages != NULL)) {
+ percpu_counter_add(&cc->n_allocated_pages, 1 << order);
goto have_pages;
+ }
+decrease_order:
order--;
}
@@ -1741,10 +1741,13 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
if (clone->bi_vcnt > 0) { /* bio_for_each_folio_all crashes with an empty bio */
bio_for_each_folio_all(fi, clone) {
- if (folio_test_large(fi.folio))
+ if (folio_test_large(fi.folio)) {
+ percpu_counter_sub(&cc->n_allocated_pages,
+ 1 << folio_order(fi.folio));
folio_put(fi.folio);
- else
+ } else {
mempool_free(&fi.folio->page, &cc->page_pool);
+ }
}
}
}
@@ -2859,10 +2862,9 @@ static int crypt_ctr_auth_cipher(struct crypt_config *cc, char *cipher_api)
if (!start || !end || ++start > end)
return -EINVAL;
- mac_alg = kzalloc(end - start + 1, GFP_KERNEL);
+ mac_alg = kmemdup_nul(start, end - start, GFP_KERNEL);
if (!mac_alg)
return -ENOMEM;
- strncpy(mac_alg, start, end - start);
mac = crypto_alloc_ahash(mac_alg, 0, CRYPTO_ALG_ALLOCATES_MEMORY);
kfree(mac_alg);
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index 7433525e5985..efd510984e25 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -13,6 +13,7 @@
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/slab.h>
+#include <linux/kthread.h>
#include <linux/device-mapper.h>
@@ -31,6 +32,7 @@ struct delay_c {
struct workqueue_struct *kdelayd_wq;
struct work_struct flush_expired_bios;
struct list_head delayed_bios;
+ struct task_struct *worker;
atomic_t may_delay;
struct delay_class read;
@@ -66,6 +68,44 @@ static void queue_timeout(struct delay_c *dc, unsigned long expires)
mutex_unlock(&dc->timer_lock);
}
+static inline bool delay_is_fast(struct delay_c *dc)
+{
+ return !!dc->worker;
+}
+
+static void flush_delayed_bios_fast(struct delay_c *dc, bool flush_all)
+{
+ struct dm_delay_info *delayed, *next;
+
+ mutex_lock(&delayed_bios_lock);
+ list_for_each_entry_safe(delayed, next, &dc->delayed_bios, list) {
+ if (flush_all || time_after_eq(jiffies, delayed->expires)) {
+ struct bio *bio = dm_bio_from_per_bio_data(delayed,
+ sizeof(struct dm_delay_info));
+ list_del(&delayed->list);
+ dm_submit_bio_remap(bio, NULL);
+ delayed->class->ops--;
+ }
+ }
+ mutex_unlock(&delayed_bios_lock);
+}
+
+static int flush_worker_fn(void *data)
+{
+ struct delay_c *dc = data;
+
+ while (1) {
+ flush_delayed_bios_fast(dc, false);
+ if (unlikely(list_empty(&dc->delayed_bios))) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ } else
+ cond_resched();
+ }
+
+ return 0;
+}
+
static void flush_bios(struct bio *bio)
{
struct bio *n;
@@ -78,7 +118,7 @@ static void flush_bios(struct bio *bio)
}
}
-static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
+static struct bio *flush_delayed_bios(struct delay_c *dc, bool flush_all)
{
struct dm_delay_info *delayed, *next;
unsigned long next_expires = 0;
@@ -115,7 +155,10 @@ static void flush_expired_bios(struct work_struct *work)
struct delay_c *dc;
dc = container_of(work, struct delay_c, flush_expired_bios);
- flush_bios(flush_delayed_bios(dc, 0));
+ if (delay_is_fast(dc))
+ flush_delayed_bios_fast(dc, false);
+ else
+ flush_bios(flush_delayed_bios(dc, false));
}
static void delay_dtr(struct dm_target *ti)
@@ -131,8 +174,11 @@ static void delay_dtr(struct dm_target *ti)
dm_put_device(ti, dc->write.dev);
if (dc->flush.dev)
dm_put_device(ti, dc->flush.dev);
+ if (dc->worker)
+ kthread_stop(dc->worker);
- mutex_destroy(&dc->timer_lock);
+ if (!delay_is_fast(dc))
+ mutex_destroy(&dc->timer_lock);
kfree(dc);
}
@@ -175,6 +221,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{
struct delay_c *dc;
int ret;
+ unsigned int max_delay;
if (argc != 3 && argc != 6 && argc != 9) {
ti->error = "Requires exactly 3, 6 or 9 arguments";
@@ -188,16 +235,14 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
ti->private = dc;
- timer_setup(&dc->delay_timer, handle_delayed_timer, 0);
- INIT_WORK(&dc->flush_expired_bios, flush_expired_bios);
INIT_LIST_HEAD(&dc->delayed_bios);
- mutex_init(&dc->timer_lock);
atomic_set(&dc->may_delay, 1);
dc->argc = argc;
ret = delay_class_ctr(ti, &dc->read, argv);
if (ret)
goto bad;
+ max_delay = dc->read.delay;
if (argc == 3) {
ret = delay_class_ctr(ti, &dc->write, argv);
@@ -206,6 +251,8 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
ret = delay_class_ctr(ti, &dc->flush, argv);
if (ret)
goto bad;
+ max_delay = max(max_delay, dc->write.delay);
+ max_delay = max(max_delay, dc->flush.delay);
goto out;
}
@@ -216,19 +263,37 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
ret = delay_class_ctr(ti, &dc->flush, argv + 3);
if (ret)
goto bad;
+ max_delay = max(max_delay, dc->flush.delay);
goto out;
}
ret = delay_class_ctr(ti, &dc->flush, argv + 6);
if (ret)
goto bad;
+ max_delay = max(max_delay, dc->flush.delay);
out:
- dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
- if (!dc->kdelayd_wq) {
- ret = -EINVAL;
- DMERR("Couldn't start kdelayd");
- goto bad;
+ if (max_delay < 50) {
+ /*
+ * In case of small requested delays, use kthread instead of
+ * timers and workqueue to achieve better latency.
+ */
+ dc->worker = kthread_create(&flush_worker_fn, dc,
+ "dm-delay-flush-worker");
+ if (IS_ERR(dc->worker)) {
+ ret = PTR_ERR(dc->worker);
+ goto bad;
+ }
+ } else {
+ timer_setup(&dc->delay_timer, handle_delayed_timer, 0);
+ INIT_WORK(&dc->flush_expired_bios, flush_expired_bios);
+ mutex_init(&dc->timer_lock);
+ dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
+ if (!dc->kdelayd_wq) {
+ ret = -EINVAL;
+ DMERR("Couldn't start kdelayd");
+ goto bad;
+ }
}
ti->num_flush_bios = 1;
@@ -260,7 +325,10 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio)
list_add_tail(&delayed->list, &dc->delayed_bios);
mutex_unlock(&delayed_bios_lock);
- queue_timeout(dc, expires);
+ if (delay_is_fast(dc))
+ wake_up_process(dc->worker);
+ else
+ queue_timeout(dc, expires);
return DM_MAPIO_SUBMITTED;
}
@@ -270,8 +338,13 @@ static void delay_presuspend(struct dm_target *ti)
struct delay_c *dc = ti->private;
atomic_set(&dc->may_delay, 0);
- del_timer_sync(&dc->delay_timer);
- flush_bios(flush_delayed_bios(dc, 1));
+
+ if (delay_is_fast(dc))
+ flush_delayed_bios_fast(dc, true);
+ else {
+ del_timer_sync(&dc->delay_timer);
+ flush_bios(flush_delayed_bios(dc, true));
+ }
}
static void delay_resume(struct dm_target *ti)
@@ -356,7 +429,7 @@ out:
static struct target_type delay_target = {
.name = "delay",
- .version = {1, 3, 0},
+ .version = {1, 4, 0},
.features = DM_TARGET_PASSES_INTEGRITY,
.module = THIS_MODULE,
.ctr = delay_ctr,
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 97a8d5fc9ebb..e85c688fd91e 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -493,42 +493,32 @@ static int sb_mac(struct dm_integrity_c *ic, bool wr)
{
SHASH_DESC_ON_STACK(desc, ic->journal_mac);
int r;
- unsigned int size = crypto_shash_digestsize(ic->journal_mac);
+ unsigned int mac_size = crypto_shash_digestsize(ic->journal_mac);
+ __u8 *sb = (__u8 *)ic->sb;
+ __u8 *mac = sb + (1 << SECTOR_SHIFT) - mac_size;
- if (sizeof(struct superblock) + size > 1 << SECTOR_SHIFT) {
+ if (sizeof(struct superblock) + mac_size > 1 << SECTOR_SHIFT) {
dm_integrity_io_error(ic, "digest is too long", -EINVAL);
return -EINVAL;
}
desc->tfm = ic->journal_mac;
- r = crypto_shash_init(desc);
- if (unlikely(r < 0)) {
- dm_integrity_io_error(ic, "crypto_shash_init", r);
- return r;
- }
-
- r = crypto_shash_update(desc, (__u8 *)ic->sb, (1 << SECTOR_SHIFT) - size);
- if (unlikely(r < 0)) {
- dm_integrity_io_error(ic, "crypto_shash_update", r);
- return r;
- }
-
if (likely(wr)) {
- r = crypto_shash_final(desc, (__u8 *)ic->sb + (1 << SECTOR_SHIFT) - size);
+ r = crypto_shash_digest(desc, sb, mac - sb, mac);
if (unlikely(r < 0)) {
- dm_integrity_io_error(ic, "crypto_shash_final", r);
+ dm_integrity_io_error(ic, "crypto_shash_digest", r);
return r;
}
} else {
- __u8 result[HASH_MAX_DIGESTSIZE];
+ __u8 actual_mac[HASH_MAX_DIGESTSIZE];
- r = crypto_shash_final(desc, result);
+ r = crypto_shash_digest(desc, sb, mac - sb, actual_mac);
if (unlikely(r < 0)) {
- dm_integrity_io_error(ic, "crypto_shash_final", r);
+ dm_integrity_io_error(ic, "crypto_shash_digest", r);
return r;
}
- if (memcmp((__u8 *)ic->sb + (1 << SECTOR_SHIFT) - size, result, size)) {
+ if (memcmp(mac, actual_mac, mac_size)) {
dm_integrity_io_error(ic, "superblock mac", -EILSEQ);
dm_audit_log_target(DM_MSG_PREFIX, "mac-superblock", ic->ti, 0);
return -EILSEQ;
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 21ebb6c39394..e65058e0ed06 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1295,8 +1295,8 @@ static void retrieve_status(struct dm_table *table,
spec->status = 0;
spec->sector_start = ti->begin;
spec->length = ti->len;
- strncpy(spec->target_type, ti->type->name,
- sizeof(spec->target_type) - 1);
+ strscpy_pad(spec->target_type, ti->type->name,
+ sizeof(spec->target_type));
outptr += sizeof(struct dm_target_spec);
remaining = len - (outptr - outbuf);
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index f4448d520ee9..2d3e186ca87e 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -85,7 +85,7 @@ static sector_t linear_map_sector(struct dm_target *ti, sector_t bi_sector)
return lc->start + dm_target_offset(ti, bi_sector);
}
-static int linear_map(struct dm_target *ti, struct bio *bio)
+int linear_map(struct dm_target *ti, struct bio *bio)
{
struct linear_c *lc = ti->private;
diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index 5aace6ee6d47..7e4f27e86150 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -224,7 +224,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
lc->usr_argc = argc;
- strncpy(lc->uuid, argv[0], DM_UUID_LEN);
+ strscpy(lc->uuid, argv[0], sizeof(lc->uuid));
argc--;
argv++;
spin_lock_init(&lc->flush_lock);
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 9755788e8b78..91ebdcc6e9a8 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -749,7 +749,11 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r
return ERR_PTR(-ENOMEM);
}
- mddev_init(&rs->md);
+ if (mddev_init(&rs->md)) {
+ kfree(rs);
+ ti->error = "Cannot initialize raid context";
+ return ERR_PTR(-ENOMEM);
+ }
rs->raid_disks = raid_devs;
rs->delta_disks = 0;
@@ -798,6 +802,7 @@ static void raid_set_free(struct raid_set *rs)
dm_put_device(rs->ti, rs->dev[i].data_dev);
}
+ mddev_destroy(&rs->md);
kfree(rs);
}
@@ -3239,7 +3244,7 @@ size_check:
set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
/* Has to be held on running the array */
- mddev_lock_nointr(&rs->md);
+ mddev_suspend_and_lock_nointr(&rs->md);
r = md_run(&rs->md);
rs->md.in_sync = 0; /* Assume already marked dirty */
if (r) {
@@ -3263,7 +3268,6 @@ size_check:
}
}
- mddev_suspend(&rs->md);
set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags);
/* Try to adjust the raid4/5/6 stripe cache size to the stripe size */
@@ -3793,9 +3797,7 @@ static void raid_postsuspend(struct dm_target *ti)
if (!test_bit(MD_RECOVERY_FROZEN, &rs->md.recovery))
md_stop_writes(&rs->md);
- mddev_lock_nointr(&rs->md);
- mddev_suspend(&rs->md);
- mddev_unlock(&rs->md);
+ mddev_suspend(&rs->md, false);
}
}
@@ -4054,8 +4056,7 @@ static void raid_resume(struct dm_target *ti)
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
mddev->ro = 0;
mddev->in_sync = 0;
- mddev_resume(mddev);
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
}
}
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 5e70f5ae394d..16b93ae51d96 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -268,7 +268,7 @@ static int stripe_map_range(struct stripe_c *sc, struct bio *bio,
return DM_MAPIO_SUBMITTED;
}
-static int stripe_map(struct dm_target *ti, struct bio *bio)
+int stripe_map(struct dm_target *ti, struct bio *bio)
{
struct stripe_c *sc = ti->private;
uint32_t stripe;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 37b48f63ae6a..198d38b53322 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -844,7 +844,8 @@ static bool dm_table_supports_dax(struct dm_table *t,
if (!ti->type->direct_access)
return false;
- if (!ti->type->iterate_devices ||
+ if (dm_target_is_wildcard(ti->type) ||
+ !ti->type->iterate_devices ||
ti->type->iterate_devices(ti, iterate_fn, NULL))
return false;
}
@@ -1587,6 +1588,14 @@ static int device_not_zoned_model(struct dm_target *ti, struct dm_dev *dev,
return blk_queue_zoned_model(q) != *zoned_model;
}
+static int device_is_zoned_model(struct dm_target *ti, struct dm_dev *dev,
+ sector_t start, sector_t len, void *data)
+{
+ struct request_queue *q = bdev_get_queue(dev->bdev);
+
+ return blk_queue_zoned_model(q) != BLK_ZONED_NONE;
+}
+
/*
* Check the device zoned model based on the target feature flag. If the target
* has the DM_TARGET_ZONED_HM feature flag set, host-managed zoned devices are
@@ -1600,6 +1609,18 @@ static bool dm_table_supports_zoned_model(struct dm_table *t,
for (unsigned int i = 0; i < t->num_targets; i++) {
struct dm_target *ti = dm_table_get_target(t, i);
+ /*
+ * For the wildcard target (dm-error), if we do not have a
+ * backing device, we must always return false. If we have a
+ * backing device, the result must depend on checking zoned
+ * model, like for any other target. So for this, check directly
+ * if the target backing device is zoned as we get "false" when
+ * dm-error was set without a backing device.
+ */
+ if (dm_target_is_wildcard(ti->type) &&
+ !ti->type->iterate_devices(ti, device_is_zoned_model, NULL))
+ return false;
+
if (dm_target_supports_zoned_hm(ti->type)) {
if (!ti->type->iterate_devices ||
ti->type->iterate_devices(ti, device_not_zoned_model,
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index 27e2992ff249..0c4efb0bef8a 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -116,9 +116,63 @@ EXPORT_SYMBOL(dm_unregister_target);
* io-err: always fails an io, useful for bringing
* up LVs that have holes in them.
*/
+struct io_err_c {
+ struct dm_dev *dev;
+ sector_t start;
+};
+
+static int io_err_get_args(struct dm_target *tt, unsigned int argc, char **args)
+{
+ unsigned long long start;
+ struct io_err_c *ioec;
+ char dummy;
+ int ret;
+
+ ioec = kmalloc(sizeof(*ioec), GFP_KERNEL);
+ if (!ioec) {
+ tt->error = "Cannot allocate io_err context";
+ return -ENOMEM;
+ }
+
+ ret = -EINVAL;
+ if (sscanf(args[1], "%llu%c", &start, &dummy) != 1 ||
+ start != (sector_t)start) {
+ tt->error = "Invalid device sector";
+ goto bad;
+ }
+ ioec->start = start;
+
+ ret = dm_get_device(tt, args[0], dm_table_get_mode(tt->table), &ioec->dev);
+ if (ret) {
+ tt->error = "Device lookup failed";
+ goto bad;
+ }
+
+ tt->private = ioec;
+
+ return 0;
+
+bad:
+ kfree(ioec);
+
+ return ret;
+}
+
static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
{
/*
+ * If we have arguments, assume it is the path to the backing
+ * block device and its mapping start sector (same as dm-linear).
+ * In this case, get the device so that we can get its limits.
+ */
+ if (argc == 2) {
+ int ret = io_err_get_args(tt, argc, args);
+
+ if (ret)
+ return ret;
+ }
+
+ /*
* Return error for discards instead of -EOPNOTSUPP
*/
tt->num_discard_bios = 1;
@@ -129,7 +183,12 @@ static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
static void io_err_dtr(struct dm_target *tt)
{
- /* empty */
+ struct io_err_c *ioec = tt->private;
+
+ if (ioec) {
+ dm_put_device(tt, ioec->dev);
+ kfree(ioec);
+ }
}
static int io_err_map(struct dm_target *tt, struct bio *bio)
@@ -149,6 +208,45 @@ static void io_err_release_clone_rq(struct request *clone,
{
}
+#ifdef CONFIG_BLK_DEV_ZONED
+static sector_t io_err_map_sector(struct dm_target *ti, sector_t bi_sector)
+{
+ struct io_err_c *ioec = ti->private;
+
+ return ioec->start + dm_target_offset(ti, bi_sector);
+}
+
+static int io_err_report_zones(struct dm_target *ti,
+ struct dm_report_zones_args *args, unsigned int nr_zones)
+{
+ struct io_err_c *ioec = ti->private;
+
+ /*
+ * This should never be called when we do not have a backing device
+ * as that mean the target is not a zoned one.
+ */
+ if (WARN_ON_ONCE(!ioec))
+ return -EIO;
+
+ return dm_report_zones(ioec->dev->bdev, ioec->start,
+ io_err_map_sector(ti, args->next_sector),
+ args, nr_zones);
+}
+#else
+#define io_err_report_zones NULL
+#endif
+
+static int io_err_iterate_devices(struct dm_target *ti,
+ iterate_devices_callout_fn fn, void *data)
+{
+ struct io_err_c *ioec = ti->private;
+
+ if (!ioec)
+ return 0;
+
+ return fn(ti, ioec->dev, ioec->start, ti->len, data);
+}
+
static void io_err_io_hints(struct dm_target *ti, struct queue_limits *limits)
{
limits->max_discard_sectors = UINT_MAX;
@@ -165,15 +263,17 @@ static long io_err_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
static struct target_type error_target = {
.name = "error",
- .version = {1, 6, 0},
- .features = DM_TARGET_WILDCARD,
+ .version = {1, 7, 0},
+ .features = DM_TARGET_WILDCARD | DM_TARGET_ZONED_HM,
.ctr = io_err_ctr,
.dtr = io_err_dtr,
.map = io_err_map,
.clone_and_map_rq = io_err_clone_and_map_rq,
.release_clone_rq = io_err_release_clone_rq,
+ .iterate_devices = io_err_iterate_devices,
.io_hints = io_err_io_hints,
.direct_access = io_err_dax_direct_access,
+ .report_zones = io_err_report_zones,
};
int __init dm_target_init(void)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index f7212e8fc27f..23c32cd1f1d8 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -570,13 +570,15 @@ static void dm_end_io_acct(struct dm_io *io)
dm_io_acct(io, true);
}
-static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio)
+static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio, gfp_t gfp_mask)
{
struct dm_io *io;
struct dm_target_io *tio;
struct bio *clone;
- clone = bio_alloc_clone(NULL, bio, GFP_NOIO, &md->mempools->io_bs);
+ clone = bio_alloc_clone(NULL, bio, gfp_mask, &md->mempools->io_bs);
+ if (unlikely(!clone))
+ return NULL;
tio = clone_to_tio(clone);
tio->flags = 0;
dm_tio_set_flag(tio, DM_TIO_INSIDE_DM_IO);
@@ -1426,9 +1428,16 @@ static void __map_bio(struct bio *clone)
if (unlikely(dm_emulate_zone_append(md)))
r = dm_zone_map_bio(tio);
else
+ goto do_map;
+ } else {
+do_map:
+ if (likely(ti->type->map == linear_map))
+ r = linear_map(ti, clone);
+ else if (ti->type->map == stripe_map)
+ r = stripe_map(ti, clone);
+ else
r = ti->type->map(ti, clone);
- } else
- r = ti->type->map(ti, clone);
+ }
switch (r) {
case DM_MAPIO_SUBMITTED:
@@ -1473,15 +1482,15 @@ static void setup_split_accounting(struct clone_info *ci, unsigned int len)
static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
struct dm_target *ti, unsigned int num_bios,
- unsigned *len)
+ unsigned *len, gfp_t gfp_flag)
{
struct bio *bio;
- int try;
+ int try = (gfp_flag & GFP_NOWAIT) ? 0 : 1;
- for (try = 0; try < 2; try++) {
+ for (; try < 2; try++) {
int bio_nr;
- if (try)
+ if (try && num_bios > 1)
mutex_lock(&ci->io->md->table_devices_lock);
for (bio_nr = 0; bio_nr < num_bios; bio_nr++) {
bio = alloc_tio(ci, ti, bio_nr, len,
@@ -1491,7 +1500,7 @@ static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
bio_list_add(blist, bio);
}
- if (try)
+ if (try && num_bios > 1)
mutex_unlock(&ci->io->md->table_devices_lock);
if (bio_nr == num_bios)
return;
@@ -1501,34 +1510,31 @@ static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
}
}
-static int __send_duplicate_bios(struct clone_info *ci, struct dm_target *ti,
- unsigned int num_bios, unsigned int *len)
+static unsigned int __send_duplicate_bios(struct clone_info *ci, struct dm_target *ti,
+ unsigned int num_bios, unsigned int *len,
+ gfp_t gfp_flag)
{
struct bio_list blist = BIO_EMPTY_LIST;
struct bio *clone;
unsigned int ret = 0;
- switch (num_bios) {
- case 0:
- break;
- case 1:
- if (len)
- setup_split_accounting(ci, *len);
- clone = alloc_tio(ci, ti, 0, len, GFP_NOIO);
- __map_bio(clone);
- ret = 1;
- break;
- default:
- if (len)
- setup_split_accounting(ci, *len);
- /* dm_accept_partial_bio() is not supported with shared tio->len_ptr */
- alloc_multiple_bios(&blist, ci, ti, num_bios, len);
- while ((clone = bio_list_pop(&blist))) {
+ if (WARN_ON_ONCE(num_bios == 0)) /* num_bios = 0 is a bug in caller */
+ return 0;
+
+ /* dm_accept_partial_bio() is not supported with shared tio->len_ptr */
+ if (len)
+ setup_split_accounting(ci, *len);
+
+ /*
+ * Using alloc_multiple_bios(), even if num_bios is 1, to consistently
+ * support allocating using GFP_NOWAIT with GFP_NOIO fallback.
+ */
+ alloc_multiple_bios(&blist, ci, ti, num_bios, len, gfp_flag);
+ while ((clone = bio_list_pop(&blist))) {
+ if (num_bios > 1)
dm_tio_set_flag(clone_to_tio(clone), DM_TIO_IS_DUPLICATE_BIO);
- __map_bio(clone);
- ret += 1;
- }
- break;
+ __map_bio(clone);
+ ret += 1;
}
return ret;
@@ -1555,8 +1561,12 @@ static void __send_empty_flush(struct clone_info *ci)
unsigned int bios;
struct dm_target *ti = dm_table_get_target(t, i);
+ if (unlikely(ti->num_flush_bios == 0))
+ continue;
+
atomic_add(ti->num_flush_bios, &ci->io->io_count);
- bios = __send_duplicate_bios(ci, ti, ti->num_flush_bios, NULL);
+ bios = __send_duplicate_bios(ci, ti, ti->num_flush_bios,
+ NULL, GFP_NOWAIT);
atomic_sub(ti->num_flush_bios - bios, &ci->io->io_count);
}
@@ -1569,10 +1579,9 @@ static void __send_empty_flush(struct clone_info *ci)
bio_uninit(ci->bio);
}
-static void __send_changing_extent_only(struct clone_info *ci, struct dm_target *ti,
- unsigned int num_bios,
- unsigned int max_granularity,
- unsigned int max_sectors)
+static void __send_abnormal_io(struct clone_info *ci, struct dm_target *ti,
+ unsigned int num_bios, unsigned int max_granularity,
+ unsigned int max_sectors)
{
unsigned int len, bios;
@@ -1580,7 +1589,7 @@ static void __send_changing_extent_only(struct clone_info *ci, struct dm_target
__max_io_len(ti, ci->sector, max_granularity, max_sectors));
atomic_add(num_bios, &ci->io->io_count);
- bios = __send_duplicate_bios(ci, ti, num_bios, &len);
+ bios = __send_duplicate_bios(ci, ti, num_bios, &len, GFP_NOIO);
/*
* alloc_io() takes one extra reference for submission, so the
* reference won't reach 0 without the following (+1) subtraction
@@ -1649,8 +1658,8 @@ static blk_status_t __process_abnormal_io(struct clone_info *ci,
if (unlikely(!num_bios))
return BLK_STS_NOTSUPP;
- __send_changing_extent_only(ci, ti, num_bios,
- max_granularity, max_sectors);
+ __send_abnormal_io(ci, ti, num_bios, max_granularity, max_sectors);
+
return BLK_STS_OK;
}
@@ -1709,10 +1718,6 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
if (unlikely(!ti))
return BLK_STS_IOERR;
- if (unlikely((ci->bio->bi_opf & REQ_NOWAIT) != 0) &&
- unlikely(!dm_target_supports_nowait(ti->type)))
- return BLK_STS_NOTSUPP;
-
if (unlikely(ci->is_abnormal_io))
return __process_abnormal_io(ci, ti);
@@ -1724,7 +1729,17 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
len = min_t(sector_t, max_io_len(ti, ci->sector), ci->sector_count);
setup_split_accounting(ci, len);
- clone = alloc_tio(ci, ti, 0, &len, GFP_NOIO);
+
+ if (unlikely(ci->bio->bi_opf & REQ_NOWAIT)) {
+ if (unlikely(!dm_target_supports_nowait(ti->type)))
+ return BLK_STS_NOTSUPP;
+
+ clone = alloc_tio(ci, ti, 0, &len, GFP_NOWAIT);
+ if (unlikely(!clone))
+ return BLK_STS_AGAIN;
+ } else {
+ clone = alloc_tio(ci, ti, 0, &len, GFP_NOIO);
+ }
__map_bio(clone);
ci->sector += len;
@@ -1733,11 +1748,11 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
return BLK_STS_OK;
}
-static void init_clone_info(struct clone_info *ci, struct mapped_device *md,
+static void init_clone_info(struct clone_info *ci, struct dm_io *io,
struct dm_table *map, struct bio *bio, bool is_abnormal)
{
ci->map = map;
- ci->io = alloc_io(md, bio);
+ ci->io = io;
ci->bio = bio;
ci->is_abnormal_io = is_abnormal;
ci->submit_as_polled = false;
@@ -1772,8 +1787,18 @@ static void dm_split_and_process_bio(struct mapped_device *md,
return;
}
- init_clone_info(&ci, md, map, bio, is_abnormal);
- io = ci.io;
+ /* Only support nowait for normal IO */
+ if (unlikely(bio->bi_opf & REQ_NOWAIT) && !is_abnormal) {
+ io = alloc_io(md, bio, GFP_NOWAIT);
+ if (unlikely(!io)) {
+ /* Unable to do anything without dm_io. */
+ bio_wouldblock_error(bio);
+ return;
+ }
+ } else {
+ io = alloc_io(md, bio, GFP_NOIO);
+ }
+ init_clone_info(&ci, io, map, bio, is_abnormal);
if (bio->bi_opf & REQ_PREFLUSH) {
__send_empty_flush(&ci);
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index f682295af91f..7f1acbf6bd9e 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -188,9 +188,11 @@ void dm_kobject_release(struct kobject *kobj);
/*
* Targets for linear and striped mappings
*/
+int linear_map(struct dm_target *ti, struct bio *bio);
int dm_linear_init(void);
void dm_linear_exit(void);
+int stripe_map(struct dm_target *ti, struct bio *bio);
int dm_stripe_init(void);
void dm_stripe_exit(void);
diff --git a/drivers/md/md-autodetect.c b/drivers/md/md-autodetect.c
index 6eaa0eab40f9..4b80165afd23 100644
--- a/drivers/md/md-autodetect.c
+++ b/drivers/md/md-autodetect.c
@@ -175,7 +175,7 @@ static void __init md_setup_drive(struct md_setup_args *args)
return;
}
- err = mddev_lock(mddev);
+ err = mddev_suspend_and_lock(mddev);
if (err) {
pr_err("md: failed to lock array %s\n", name);
goto out_mddev_put;
@@ -221,7 +221,7 @@ static void __init md_setup_drive(struct md_setup_args *args)
if (err)
pr_warn("md: starting %s failed\n", name);
out_unlock:
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
out_mddev_put:
mddev_put(mddev);
}
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index 6f9ff14971f9..9672f75c3050 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -1861,7 +1861,7 @@ void md_bitmap_destroy(struct mddev *mddev)
md_bitmap_wait_behind_writes(mddev);
if (!mddev->serialize_policy)
- mddev_destroy_serial_pool(mddev, NULL, true);
+ mddev_destroy_serial_pool(mddev, NULL);
mutex_lock(&mddev->bitmap_info.mutex);
spin_lock(&mddev->lock);
@@ -1977,7 +1977,7 @@ int md_bitmap_load(struct mddev *mddev)
goto out;
rdev_for_each(rdev, mddev)
- mddev_create_serial_pool(mddev, rdev, true);
+ mddev_create_serial_pool(mddev, rdev);
if (mddev_is_clustered(mddev))
md_cluster_ops->load_bitmaps(mddev, mddev->bitmap_info.nodes);
@@ -2348,14 +2348,11 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
{
int rv;
- rv = mddev_lock(mddev);
+ rv = mddev_suspend_and_lock(mddev);
if (rv)
return rv;
+
if (mddev->pers) {
- if (!mddev->pers->quiesce) {
- rv = -EBUSY;
- goto out;
- }
if (mddev->recovery || mddev->sync_thread) {
rv = -EBUSY;
goto out;
@@ -2369,11 +2366,8 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
rv = -EBUSY;
goto out;
}
- if (mddev->pers) {
- mddev_suspend(mddev);
- md_bitmap_destroy(mddev);
- mddev_resume(mddev);
- }
+
+ md_bitmap_destroy(mddev);
mddev->bitmap_info.offset = 0;
if (mddev->bitmap_info.file) {
struct file *f = mddev->bitmap_info.file;
@@ -2383,6 +2377,8 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
} else {
/* No bitmap, OK to set a location */
long long offset;
+ struct bitmap *bitmap;
+
if (strncmp(buf, "none", 4) == 0)
/* nothing to be done */;
else if (strncmp(buf, "file:", 5) == 0) {
@@ -2406,25 +2402,20 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
rv = -EINVAL;
goto out;
}
+
mddev->bitmap_info.offset = offset;
- if (mddev->pers) {
- struct bitmap *bitmap;
- bitmap = md_bitmap_create(mddev, -1);
- mddev_suspend(mddev);
- if (IS_ERR(bitmap))
- rv = PTR_ERR(bitmap);
- else {
- mddev->bitmap = bitmap;
- rv = md_bitmap_load(mddev);
- if (rv)
- mddev->bitmap_info.offset = 0;
- }
- if (rv) {
- md_bitmap_destroy(mddev);
- mddev_resume(mddev);
- goto out;
- }
- mddev_resume(mddev);
+ bitmap = md_bitmap_create(mddev, -1);
+ if (IS_ERR(bitmap)) {
+ rv = PTR_ERR(bitmap);
+ goto out;
+ }
+
+ mddev->bitmap = bitmap;
+ rv = md_bitmap_load(mddev);
+ if (rv) {
+ mddev->bitmap_info.offset = 0;
+ md_bitmap_destroy(mddev);
+ goto out;
}
}
}
@@ -2437,7 +2428,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
}
rv = 0;
out:
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
if (rv)
return rv;
return len;
@@ -2546,7 +2537,7 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
if (backlog > COUNTER_MAX)
return -EINVAL;
- rv = mddev_lock(mddev);
+ rv = mddev_suspend_and_lock(mddev);
if (rv)
return rv;
@@ -2571,16 +2562,16 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
if (!backlog && mddev->serial_info_pool) {
/* serial_info_pool is not needed if backlog is zero */
if (!mddev->serialize_policy)
- mddev_destroy_serial_pool(mddev, NULL, false);
+ mddev_destroy_serial_pool(mddev, NULL);
} else if (backlog && !mddev->serial_info_pool) {
/* serial_info_pool is needed since backlog is not zero */
rdev_for_each(rdev, mddev)
- mddev_create_serial_pool(mddev, rdev, false);
+ mddev_create_serial_pool(mddev, rdev);
}
if (old_mwb != backlog)
md_bitmap_update_sb(mddev->bitmap);
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return len;
}
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
index 1e26eb223349..8e36a0feec09 100644
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -501,7 +501,7 @@ static void process_suspend_info(struct mddev *mddev,
mddev->pers->quiesce(mddev, 0);
}
-static void process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg)
+static int process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg)
{
char disk_uuid[64];
struct md_cluster_info *cinfo = mddev->cluster_info;
@@ -509,6 +509,7 @@ static void process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg)
char raid_slot[16];
char *envp[] = {event_name, disk_uuid, raid_slot, NULL};
int len;
+ int res = 0;
len = snprintf(disk_uuid, 64, "DEVICE_UUID=");
sprintf(disk_uuid + len, "%pU", cmsg->uuid);
@@ -517,9 +518,14 @@ static void process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg)
init_completion(&cinfo->newdisk_completion);
set_bit(MD_CLUSTER_WAITING_FOR_NEWDISK, &cinfo->state);
kobject_uevent_env(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE, envp);
- wait_for_completion_timeout(&cinfo->newdisk_completion,
- NEW_DEV_TIMEOUT);
+ if (!wait_for_completion_timeout(&cinfo->newdisk_completion,
+ NEW_DEV_TIMEOUT)) {
+ pr_err("md-cluster(%s:%d): timeout on a new disk adding\n",
+ __func__, __LINE__);
+ res = -1;
+ }
clear_bit(MD_CLUSTER_WAITING_FOR_NEWDISK, &cinfo->state);
+ return res;
}
@@ -594,7 +600,8 @@ static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
le64_to_cpu(msg->high));
break;
case NEWDISK:
- process_add_new_disk(mddev, msg);
+ if (process_add_new_disk(mddev, msg))
+ ret = -1;
break;
case REMOVE:
process_remove_disk(mddev, msg);
diff --git a/drivers/md/md-linear.c b/drivers/md/md-linear.c
index 71ac99646827..8eca7693b793 100644
--- a/drivers/md/md-linear.c
+++ b/drivers/md/md-linear.c
@@ -69,6 +69,19 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
if (!conf)
return NULL;
+ /*
+ * conf->raid_disks is copy of mddev->raid_disks. The reason to
+ * keep a copy of mddev->raid_disks in struct linear_conf is,
+ * mddev->raid_disks may not be consistent with pointers number of
+ * conf->disks[] when it is updated in linear_add() and used to
+ * iterate old conf->disks[] earray in linear_congested().
+ * Here conf->raid_disks is always consitent with number of
+ * pointers in conf->disks[] array, and mddev->private is updated
+ * with rcu_assign_pointer() in linear_addr(), such race can be
+ * avoided.
+ */
+ conf->raid_disks = raid_disks;
+
cnt = 0;
conf->array_sectors = 0;
@@ -112,19 +125,6 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
conf->disks[i-1].end_sector +
conf->disks[i].rdev->sectors;
- /*
- * conf->raid_disks is copy of mddev->raid_disks. The reason to
- * keep a copy of mddev->raid_disks in struct linear_conf is,
- * mddev->raid_disks may not be consistent with pointers number of
- * conf->disks[] when it is updated in linear_add() and used to
- * iterate old conf->disks[] earray in linear_congested().
- * Here conf->raid_disks is always consitent with number of
- * pointers in conf->disks[] array, and mddev->private is updated
- * with rcu_assign_pointer() in linear_addr(), such race can be
- * avoided.
- */
- conf->raid_disks = raid_disks;
-
return conf;
out:
@@ -183,7 +183,6 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
* in linear_congested(), therefore kfree_rcu() is used to free
* oldconf until no one uses it anymore.
*/
- mddev_suspend(mddev);
oldconf = rcu_dereference_protected(mddev->private,
lockdep_is_held(&mddev->reconfig_mutex));
mddev->raid_disks++;
@@ -192,7 +191,6 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
rcu_assign_pointer(mddev->private, newconf);
md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
set_capacity_and_notify(mddev->gendisk, mddev->array_sectors);
- mddev_resume(mddev);
kfree_rcu(oldconf, rcu);
return 0;
}
diff --git a/drivers/md/md-linear.h b/drivers/md/md-linear.h
index 24e97db50ebb..5587eeedb882 100644
--- a/drivers/md/md-linear.h
+++ b/drivers/md/md-linear.h
@@ -12,6 +12,6 @@ struct linear_conf
struct rcu_head rcu;
sector_t array_sectors;
int raid_disks; /* a copy of mddev->raid_disks */
- struct dev_info disks[];
+ struct dev_info disks[] __counted_by(raid_disks);
};
#endif
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 839e79e567ee..4ee4593c874a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -91,6 +91,18 @@ static void mddev_detach(struct mddev *mddev);
static void export_rdev(struct md_rdev *rdev, struct mddev *mddev);
static void md_wakeup_thread_directly(struct md_thread __rcu *thread);
+enum md_ro_state {
+ MD_RDWR,
+ MD_RDONLY,
+ MD_AUTO_READ,
+ MD_MAX_STATE
+};
+
+static bool md_is_rdwr(struct mddev *mddev)
+{
+ return (mddev->ro == MD_RDWR);
+}
+
/*
* Default number of read corrections we'll attempt on an rdev
* before ejecting it from the array. We divide the read error
@@ -206,8 +218,7 @@ static int rdev_need_serial(struct md_rdev *rdev)
* 1. rdev is the first device which return true from rdev_enable_serial.
* 2. rdev is NULL, means we want to enable serialization for all rdevs.
*/
-void mddev_create_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
- bool is_suspend)
+void mddev_create_serial_pool(struct mddev *mddev, struct md_rdev *rdev)
{
int ret = 0;
@@ -215,15 +226,12 @@ void mddev_create_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
!test_bit(CollisionCheck, &rdev->flags))
return;
- if (!is_suspend)
- mddev_suspend(mddev);
-
if (!rdev)
ret = rdevs_init_serial(mddev);
else
ret = rdev_init_serial(rdev);
if (ret)
- goto abort;
+ return;
if (mddev->serial_info_pool == NULL) {
/*
@@ -238,10 +246,6 @@ void mddev_create_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
pr_err("can't alloc memory pool for serialization\n");
}
}
-
-abort:
- if (!is_suspend)
- mddev_resume(mddev);
}
/*
@@ -250,8 +254,7 @@ abort:
* 2. when bitmap is destroyed while policy is not enabled.
* 3. for disable policy, the pool is destroyed only when no rdev needs it.
*/
-void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
- bool is_suspend)
+void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev)
{
if (rdev && !test_bit(CollisionCheck, &rdev->flags))
return;
@@ -260,8 +263,6 @@ void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
struct md_rdev *temp;
int num = 0; /* used to track if other rdevs need the pool */
- if (!is_suspend)
- mddev_suspend(mddev);
rdev_for_each(temp, mddev) {
if (!rdev) {
if (!mddev->serialize_policy ||
@@ -283,8 +284,6 @@ void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
mempool_destroy(mddev->serial_info_pool);
mddev->serial_info_pool = NULL;
}
- if (!is_suspend)
- mddev_resume(mddev);
}
}
@@ -305,7 +304,6 @@ static struct ctl_table raid_table[] = {
.mode = S_IRUGO|S_IWUSR,
.proc_handler = proc_dointvec,
},
- { }
};
static int start_readonly;
@@ -346,6 +344,10 @@ EXPORT_SYMBOL_GPL(md_new_event);
static LIST_HEAD(all_mddevs);
static DEFINE_SPINLOCK(all_mddevs_lock);
+static bool is_md_suspended(struct mddev *mddev)
+{
+ return percpu_ref_is_dying(&mddev->active_io);
+}
/* Rather than calling directly into the personality make_request function,
* IO requests come here first so that we can check if the device is
* being suspended pending a reconfiguration.
@@ -359,11 +361,11 @@ static bool is_suspended(struct mddev *mddev, struct bio *bio)
return true;
if (bio_data_dir(bio) != WRITE)
return false;
- if (mddev->suspend_lo >= mddev->suspend_hi)
+ if (READ_ONCE(mddev->suspend_lo) >= READ_ONCE(mddev->suspend_hi))
return false;
- if (bio->bi_iter.bi_sector >= mddev->suspend_hi)
+ if (bio->bi_iter.bi_sector >= READ_ONCE(mddev->suspend_hi))
return false;
- if (bio_end_sector(bio) < mddev->suspend_lo)
+ if (bio_end_sector(bio) < READ_ONCE(mddev->suspend_lo))
return false;
return true;
}
@@ -431,42 +433,73 @@ static void md_submit_bio(struct bio *bio)
md_handle_request(mddev, bio);
}
-/* mddev_suspend makes sure no new requests are submitted
- * to the device, and that any requests that have been submitted
- * are completely handled.
- * Once mddev_detach() is called and completes, the module will be
- * completely unused.
+/*
+ * Make sure no new requests are submitted to the device, and any requests that
+ * have been submitted are completely handled.
*/
-void mddev_suspend(struct mddev *mddev)
+int mddev_suspend(struct mddev *mddev, bool interruptible)
{
- struct md_thread *thread = rcu_dereference_protected(mddev->thread,
- lockdep_is_held(&mddev->reconfig_mutex));
+ int err = 0;
- WARN_ON_ONCE(thread && current == thread->tsk);
- if (mddev->suspended++)
- return;
- wake_up(&mddev->sb_wait);
- set_bit(MD_ALLOW_SB_UPDATE, &mddev->flags);
- percpu_ref_kill(&mddev->active_io);
+ /*
+ * hold reconfig_mutex to wait for normal io will deadlock, because
+ * other context can't update super_block, and normal io can rely on
+ * updating super_block.
+ */
+ lockdep_assert_not_held(&mddev->reconfig_mutex);
- if (mddev->pers->prepare_suspend)
- mddev->pers->prepare_suspend(mddev);
+ if (interruptible)
+ err = mutex_lock_interruptible(&mddev->suspend_mutex);
+ else
+ mutex_lock(&mddev->suspend_mutex);
+ if (err)
+ return err;
- wait_event(mddev->sb_wait, percpu_ref_is_zero(&mddev->active_io));
- clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags);
- wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags));
+ if (mddev->suspended) {
+ WRITE_ONCE(mddev->suspended, mddev->suspended + 1);
+ mutex_unlock(&mddev->suspend_mutex);
+ return 0;
+ }
+
+ percpu_ref_kill(&mddev->active_io);
+ if (interruptible)
+ err = wait_event_interruptible(mddev->sb_wait,
+ percpu_ref_is_zero(&mddev->active_io));
+ else
+ wait_event(mddev->sb_wait,
+ percpu_ref_is_zero(&mddev->active_io));
+ if (err) {
+ percpu_ref_resurrect(&mddev->active_io);
+ mutex_unlock(&mddev->suspend_mutex);
+ return err;
+ }
+
+ /*
+ * For raid456, io might be waiting for reshape to make progress,
+ * allow new reshape to start while waiting for io to be done to
+ * prevent deadlock.
+ */
+ WRITE_ONCE(mddev->suspended, mddev->suspended + 1);
del_timer_sync(&mddev->safemode_timer);
/* restrict memory reclaim I/O during raid array is suspend */
mddev->noio_flag = memalloc_noio_save();
+
+ mutex_unlock(&mddev->suspend_mutex);
+ return 0;
}
EXPORT_SYMBOL_GPL(mddev_suspend);
void mddev_resume(struct mddev *mddev)
{
- lockdep_assert_held(&mddev->reconfig_mutex);
- if (--mddev->suspended)
+ lockdep_assert_not_held(&mddev->reconfig_mutex);
+
+ mutex_lock(&mddev->suspend_mutex);
+ WRITE_ONCE(mddev->suspended, mddev->suspended - 1);
+ if (mddev->suspended) {
+ mutex_unlock(&mddev->suspend_mutex);
return;
+ }
/* entred the memalloc scope from mddev_suspend() */
memalloc_noio_restore(mddev->noio_flag);
@@ -477,6 +510,8 @@ void mddev_resume(struct mddev *mddev)
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread);
md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
+
+ mutex_unlock(&mddev->suspend_mutex);
}
EXPORT_SYMBOL_GPL(mddev_resume);
@@ -616,34 +651,63 @@ static inline struct mddev *mddev_get(struct mddev *mddev)
static void mddev_delayed_delete(struct work_struct *ws);
+static void __mddev_put(struct mddev *mddev)
+{
+ if (mddev->raid_disks || !list_empty(&mddev->disks) ||
+ mddev->ctime || mddev->hold_active)
+ return;
+
+ /* Array is not configured at all, and not held active, so destroy it */
+ set_bit(MD_DELETED, &mddev->flags);
+
+ /*
+ * Call queue_work inside the spinlock so that flush_workqueue() after
+ * mddev_find will succeed in waiting for the work to be done.
+ */
+ queue_work(md_misc_wq, &mddev->del_work);
+}
+
void mddev_put(struct mddev *mddev)
{
if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
return;
- if (!mddev->raid_disks && list_empty(&mddev->disks) &&
- mddev->ctime == 0 && !mddev->hold_active) {
- /* Array is not configured at all, and not held active,
- * so destroy it */
- set_bit(MD_DELETED, &mddev->flags);
- /*
- * Call queue_work inside the spinlock so that
- * flush_workqueue() after mddev_find will succeed in waiting
- * for the work to be done.
- */
- INIT_WORK(&mddev->del_work, mddev_delayed_delete);
- queue_work(md_misc_wq, &mddev->del_work);
- }
+ __mddev_put(mddev);
spin_unlock(&all_mddevs_lock);
}
static void md_safemode_timeout(struct timer_list *t);
+static void md_start_sync(struct work_struct *ws);
+
+static void active_io_release(struct percpu_ref *ref)
+{
+ struct mddev *mddev = container_of(ref, struct mddev, active_io);
+
+ wake_up(&mddev->sb_wait);
+}
+
+static void no_op(struct percpu_ref *r) {}
-void mddev_init(struct mddev *mddev)
+int mddev_init(struct mddev *mddev)
{
+
+ if (percpu_ref_init(&mddev->active_io, active_io_release,
+ PERCPU_REF_ALLOW_REINIT, GFP_KERNEL))
+ return -ENOMEM;
+
+ if (percpu_ref_init(&mddev->writes_pending, no_op,
+ PERCPU_REF_ALLOW_REINIT, GFP_KERNEL)) {
+ percpu_ref_exit(&mddev->active_io);
+ return -ENOMEM;
+ }
+
+ /* We want to start with the refcount at zero */
+ percpu_ref_put(&mddev->writes_pending);
+
mutex_init(&mddev->open_mutex);
mutex_init(&mddev->reconfig_mutex);
mutex_init(&mddev->sync_mutex);
+ mutex_init(&mddev->suspend_mutex);
mutex_init(&mddev->bitmap_info.mutex);
INIT_LIST_HEAD(&mddev->disks);
INIT_LIST_HEAD(&mddev->all_mddevs);
@@ -662,9 +726,21 @@ void mddev_init(struct mddev *mddev)
mddev->resync_min = 0;
mddev->resync_max = MaxSector;
mddev->level = LEVEL_NONE;
+
+ INIT_WORK(&mddev->sync_work, md_start_sync);
+ INIT_WORK(&mddev->del_work, mddev_delayed_delete);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(mddev_init);
+void mddev_destroy(struct mddev *mddev)
+{
+ percpu_ref_exit(&mddev->active_io);
+ percpu_ref_exit(&mddev->writes_pending);
+}
+EXPORT_SYMBOL_GPL(mddev_destroy);
+
static struct mddev *mddev_find_locked(dev_t unit)
{
struct mddev *mddev;
@@ -708,13 +784,16 @@ static struct mddev *mddev_alloc(dev_t unit)
new = kzalloc(sizeof(*new), GFP_KERNEL);
if (!new)
return ERR_PTR(-ENOMEM);
- mddev_init(new);
+
+ error = mddev_init(new);
+ if (error)
+ goto out_free_new;
spin_lock(&all_mddevs_lock);
if (unit) {
error = -EEXIST;
if (mddev_find_locked(unit))
- goto out_free_new;
+ goto out_destroy_new;
new->unit = unit;
if (MAJOR(unit) == MD_MAJOR)
new->md_minor = MINOR(unit);
@@ -725,7 +804,7 @@ static struct mddev *mddev_alloc(dev_t unit)
error = -ENODEV;
new->unit = mddev_alloc_unit();
if (!new->unit)
- goto out_free_new;
+ goto out_destroy_new;
new->md_minor = MINOR(new->unit);
new->hold_active = UNTIL_STOP;
}
@@ -733,8 +812,11 @@ static struct mddev *mddev_alloc(dev_t unit)
list_add(&new->all_mddevs, &all_mddevs);
spin_unlock(&all_mddevs_lock);
return new;
-out_free_new:
+
+out_destroy_new:
spin_unlock(&all_mddevs_lock);
+ mddev_destroy(new);
+out_free_new:
kfree(new);
return ERR_PTR(error);
}
@@ -745,6 +827,7 @@ static void mddev_free(struct mddev *mddev)
list_del(&mddev->all_mddevs);
spin_unlock(&all_mddevs_lock);
+ mddev_destroy(mddev);
kfree(mddev);
}
@@ -2412,7 +2495,7 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
pr_debug("md: bind<%s>\n", b);
if (mddev->raid_disks)
- mddev_create_serial_pool(mddev, rdev, false);
+ mddev_create_serial_pool(mddev, rdev);
if ((err = kobject_add(&rdev->kobj, &mddev->kobj, "dev-%s", b)))
goto fail;
@@ -2464,7 +2547,7 @@ static void md_kick_rdev_from_array(struct md_rdev *rdev)
bd_unlink_disk_holder(rdev->bdev, rdev->mddev->gendisk);
list_del_rcu(&rdev->same_set);
pr_debug("md: unbind<%pg>\n", rdev->bdev);
- mddev_destroy_serial_pool(rdev->mddev, rdev, false);
+ mddev_destroy_serial_pool(rdev->mddev, rdev);
rdev->mddev = NULL;
sysfs_remove_link(&rdev->kobj, "block");
sysfs_put(rdev->sysfs_state);
@@ -2794,11 +2877,7 @@ static int add_bound_rdev(struct md_rdev *rdev)
*/
super_types[mddev->major_version].
validate_super(mddev, rdev);
- if (add_journal)
- mddev_suspend(mddev);
err = mddev->pers->hot_add_disk(mddev, rdev);
- if (add_journal)
- mddev_resume(mddev);
if (err) {
md_kick_rdev_from_array(rdev);
return err;
@@ -2935,11 +3014,11 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len)
}
} else if (cmd_match(buf, "writemostly")) {
set_bit(WriteMostly, &rdev->flags);
- mddev_create_serial_pool(rdev->mddev, rdev, false);
+ mddev_create_serial_pool(rdev->mddev, rdev);
need_update_sb = true;
err = 0;
} else if (cmd_match(buf, "-writemostly")) {
- mddev_destroy_serial_pool(rdev->mddev, rdev, false);
+ mddev_destroy_serial_pool(rdev->mddev, rdev);
clear_bit(WriteMostly, &rdev->flags);
need_update_sb = true;
err = 0;
@@ -3551,6 +3630,7 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
struct md_rdev *rdev = container_of(kobj, struct md_rdev, kobj);
struct kernfs_node *kn = NULL;
+ bool suspend = false;
ssize_t rv;
struct mddev *mddev = rdev->mddev;
@@ -3558,17 +3638,25 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
return -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
+ if (!mddev)
+ return -ENODEV;
- if (entry->store == state_store && cmd_match(page, "remove"))
- kn = sysfs_break_active_protection(kobj, attr);
+ if (entry->store == state_store) {
+ if (cmd_match(page, "remove"))
+ kn = sysfs_break_active_protection(kobj, attr);
+ if (cmd_match(page, "remove") || cmd_match(page, "re-add") ||
+ cmd_match(page, "writemostly") ||
+ cmd_match(page, "-writemostly"))
+ suspend = true;
+ }
- rv = mddev ? mddev_lock(mddev) : -ENODEV;
+ rv = suspend ? mddev_suspend_and_lock(mddev) : mddev_lock(mddev);
if (!rv) {
if (rdev->mddev == NULL)
rv = -ENODEV;
else
rv = entry->store(rdev, page, length);
- mddev_unlock(mddev);
+ suspend ? mddev_unlock_and_resume(mddev) : mddev_unlock(mddev);
}
if (kn)
@@ -3867,12 +3955,12 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
if (slen == 0 || slen >= sizeof(clevel))
return -EINVAL;
- rv = mddev_lock(mddev);
+ rv = mddev_suspend_and_lock(mddev);
if (rv)
return rv;
if (mddev->pers == NULL) {
- strncpy(mddev->clevel, buf, slen);
+ memcpy(mddev->clevel, buf, slen);
if (mddev->clevel[slen-1] == '\n')
slen--;
mddev->clevel[slen] = 0;
@@ -3905,7 +3993,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
}
/* Now find the new personality */
- strncpy(clevel, buf, slen);
+ memcpy(clevel, buf, slen);
if (clevel[slen-1] == '\n')
slen--;
clevel[slen] = 0;
@@ -3960,7 +4048,6 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
}
/* Looks like we have a winner */
- mddev_suspend(mddev);
mddev_detach(mddev);
spin_lock(&mddev->lock);
@@ -4046,14 +4133,13 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
blk_set_stacking_limits(&mddev->queue->limits);
pers->run(mddev);
set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
- mddev_resume(mddev);
if (!mddev->thread)
md_update_sb(mddev, 1);
sysfs_notify_dirent_safe(mddev->sysfs_level);
md_new_event();
rv = len;
out_unlock:
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return rv;
}
@@ -4361,6 +4447,18 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
int err = 0;
enum array_state st = match_word(buf, array_states);
+ /* No lock dependent actions */
+ switch (st) {
+ case suspended: /* not supported yet */
+ case write_pending: /* cannot be set */
+ case active_idle: /* cannot be set */
+ case broken: /* cannot be set */
+ case bad_word:
+ return -EINVAL;
+ default:
+ break;
+ }
+
if (mddev->pers && (st == active || st == clean) &&
mddev->ro != MD_RDONLY) {
/* don't take reconfig_mutex when toggling between
@@ -4385,23 +4483,16 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
err = mddev_lock(mddev);
if (err)
return err;
- err = -EINVAL;
- switch(st) {
- case bad_word:
- break;
- case clear:
- /* stopping an active array */
- err = do_md_stop(mddev, 0, NULL);
- break;
+
+ switch (st) {
case inactive:
- /* stopping an active array */
+ /* stop an active array, return 0 otherwise */
if (mddev->pers)
err = do_md_stop(mddev, 2, NULL);
- else
- err = 0; /* already inactive */
break;
- case suspended:
- break; /* not supported yet */
+ case clear:
+ err = do_md_stop(mddev, 0, NULL);
+ break;
case readonly:
if (mddev->pers)
err = md_set_readonly(mddev, NULL);
@@ -4452,10 +4543,8 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
err = do_md_run(mddev);
}
break;
- case write_pending:
- case active_idle:
- case broken:
- /* these cannot be set */
+ default:
+ err = -EINVAL;
break;
}
@@ -4528,7 +4617,7 @@ new_dev_store(struct mddev *mddev, const char *buf, size_t len)
minor != MINOR(dev))
return -EOVERFLOW;
- err = mddev_lock(mddev);
+ err = mddev_suspend_and_lock(mddev);
if (err)
return err;
if (mddev->persistent) {
@@ -4549,14 +4638,14 @@ new_dev_store(struct mddev *mddev, const char *buf, size_t len)
rdev = md_import_device(dev, -1, -1);
if (IS_ERR(rdev)) {
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return PTR_ERR(rdev);
}
err = bind_rdev_to_array(rdev, mddev);
out:
if (err)
export_rdev(rdev, mddev);
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
if (!err)
md_new_event();
return err ? err : len;
@@ -4691,7 +4780,7 @@ metadata_store(struct mddev *mddev, const char *buf, size_t len)
size_t namelen = len-9;
if (namelen >= sizeof(mddev->metadata_type))
namelen = sizeof(mddev->metadata_type)-1;
- strncpy(mddev->metadata_type, buf+9, namelen);
+ memcpy(mddev->metadata_type, buf+9, namelen);
mddev->metadata_type[namelen] = 0;
if (namelen && mddev->metadata_type[namelen-1] == '\n')
mddev->metadata_type[--namelen] = 0;
@@ -4865,6 +4954,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
/* A write to sync_action is enough to justify
* canceling read-auto mode
*/
+ flush_work(&mddev->sync_work);
mddev->ro = MD_RDWR;
md_wakeup_thread(mddev->sync_thread);
}
@@ -5121,7 +5211,8 @@ __ATTR(sync_max, S_IRUGO|S_IWUSR, max_sync_show, max_sync_store);
static ssize_t
suspend_lo_show(struct mddev *mddev, char *page)
{
- return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_lo);
+ return sprintf(page, "%llu\n",
+ (unsigned long long)READ_ONCE(mddev->suspend_lo));
}
static ssize_t
@@ -5136,21 +5227,14 @@ suspend_lo_store(struct mddev *mddev, const char *buf, size_t len)
if (new != (sector_t)new)
return -EINVAL;
- err = mddev_lock(mddev);
+ err = mddev_suspend(mddev, true);
if (err)
return err;
- err = -EINVAL;
- if (mddev->pers == NULL ||
- mddev->pers->quiesce == NULL)
- goto unlock;
- mddev_suspend(mddev);
- mddev->suspend_lo = new;
+
+ WRITE_ONCE(mddev->suspend_lo, new);
mddev_resume(mddev);
- err = 0;
-unlock:
- mddev_unlock(mddev);
- return err ?: len;
+ return len;
}
static struct md_sysfs_entry md_suspend_lo =
__ATTR(suspend_lo, S_IRUGO|S_IWUSR, suspend_lo_show, suspend_lo_store);
@@ -5158,7 +5242,8 @@ __ATTR(suspend_lo, S_IRUGO|S_IWUSR, suspend_lo_show, suspend_lo_store);
static ssize_t
suspend_hi_show(struct mddev *mddev, char *page)
{
- return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_hi);
+ return sprintf(page, "%llu\n",
+ (unsigned long long)READ_ONCE(mddev->suspend_hi));
}
static ssize_t
@@ -5173,21 +5258,14 @@ suspend_hi_store(struct mddev *mddev, const char *buf, size_t len)
if (new != (sector_t)new)
return -EINVAL;
- err = mddev_lock(mddev);
+ err = mddev_suspend(mddev, true);
if (err)
return err;
- err = -EINVAL;
- if (mddev->pers == NULL)
- goto unlock;
- mddev_suspend(mddev);
- mddev->suspend_hi = new;
+ WRITE_ONCE(mddev->suspend_hi, new);
mddev_resume(mddev);
- err = 0;
-unlock:
- mddev_unlock(mddev);
- return err ?: len;
+ return len;
}
static struct md_sysfs_entry md_suspend_hi =
__ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store);
@@ -5434,7 +5512,7 @@ serialize_policy_store(struct mddev *mddev, const char *buf, size_t len)
if (value == mddev->serialize_policy)
return len;
- err = mddev_lock(mddev);
+ err = mddev_suspend_and_lock(mddev);
if (err)
return err;
if (mddev->pers == NULL || (mddev->pers->level != 1)) {
@@ -5443,15 +5521,13 @@ serialize_policy_store(struct mddev *mddev, const char *buf, size_t len)
goto unlock;
}
- mddev_suspend(mddev);
if (value)
- mddev_create_serial_pool(mddev, NULL, true);
+ mddev_create_serial_pool(mddev, NULL);
else
- mddev_destroy_serial_pool(mddev, NULL, true);
+ mddev_destroy_serial_pool(mddev, NULL);
mddev->serialize_policy = value;
- mddev_resume(mddev);
unlock:
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return err ?: len;
}
@@ -5590,21 +5666,6 @@ static void mddev_delayed_delete(struct work_struct *ws)
kobject_put(&mddev->kobj);
}
-static void no_op(struct percpu_ref *r) {}
-
-int mddev_init_writes_pending(struct mddev *mddev)
-{
- if (mddev->writes_pending.percpu_count_ptr)
- return 0;
- if (percpu_ref_init(&mddev->writes_pending, no_op,
- PERCPU_REF_ALLOW_REINIT, GFP_KERNEL) < 0)
- return -ENOMEM;
- /* We want to start with the refcount at zero */
- percpu_ref_put(&mddev->writes_pending);
- return 0;
-}
-EXPORT_SYMBOL_GPL(mddev_init_writes_pending);
-
struct mddev *md_alloc(dev_t dev, char *name)
{
/*
@@ -5776,12 +5837,6 @@ static void md_safemode_timeout(struct timer_list *t)
}
static int start_dirty_degraded;
-static void active_io_release(struct percpu_ref *ref)
-{
- struct mddev *mddev = container_of(ref, struct mddev, active_io);
-
- wake_up(&mddev->sb_wait);
-}
int md_run(struct mddev *mddev)
{
@@ -5862,15 +5917,10 @@ int md_run(struct mddev *mddev)
nowait = nowait && bdev_nowait(rdev->bdev);
}
- err = percpu_ref_init(&mddev->active_io, active_io_release,
- PERCPU_REF_ALLOW_REINIT, GFP_KERNEL);
- if (err)
- return err;
-
if (!bioset_initialized(&mddev->bio_set)) {
err = bioset_init(&mddev->bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS);
if (err)
- goto exit_active_io;
+ return err;
}
if (!bioset_initialized(&mddev->sync_set)) {
err = bioset_init(&mddev->sync_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS);
@@ -6067,8 +6117,6 @@ exit_sync_set:
bioset_exit(&mddev->sync_set);
exit_bio_set:
bioset_exit(&mddev->bio_set);
-exit_active_io:
- percpu_ref_exit(&mddev->active_io);
return err;
}
EXPORT_SYMBOL_GPL(md_run);
@@ -6242,7 +6290,7 @@ static void __md_stop_writes(struct mddev *mddev)
}
/* disable policy to guarantee rdevs free resources for serialization */
mddev->serialize_policy = 0;
- mddev_destroy_serial_pool(mddev, NULL, true);
+ mddev_destroy_serial_pool(mddev, NULL);
}
void md_stop_writes(struct mddev *mddev)
@@ -6284,7 +6332,6 @@ static void __md_stop(struct mddev *mddev)
module_put(pers->owner);
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
- percpu_ref_exit(&mddev->active_io);
bioset_exit(&mddev->bio_set);
bioset_exit(&mddev->sync_set);
bioset_exit(&mddev->io_clone_set);
@@ -6299,7 +6346,6 @@ void md_stop(struct mddev *mddev)
*/
__md_stop_writes(mddev);
__md_stop(mddev);
- percpu_ref_exit(&mddev->writes_pending);
}
EXPORT_SYMBOL_GPL(md_stop);
@@ -6536,13 +6582,13 @@ static void autorun_devices(int part)
if (IS_ERR(mddev))
break;
- if (mddev_lock(mddev))
+ if (mddev_suspend_and_lock(mddev))
pr_warn("md: %s locked, cannot run\n", mdname(mddev));
else if (mddev->raid_disks || mddev->major_version
|| !list_empty(&mddev->disks)) {
pr_warn("md: %s already running, cannot run %pg\n",
mdname(mddev), rdev0->bdev);
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
} else {
pr_debug("md: created %s\n", mdname(mddev));
mddev->persistent = 1;
@@ -6552,7 +6598,7 @@ static void autorun_devices(int part)
export_rdev(rdev, mddev);
}
autorun_array(mddev);
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
}
/* on success, candidates will be empty, on error
* it won't...
@@ -7102,7 +7148,6 @@ static int set_bitmap_file(struct mddev *mddev, int fd)
struct bitmap *bitmap;
bitmap = md_bitmap_create(mddev, -1);
- mddev_suspend(mddev);
if (!IS_ERR(bitmap)) {
mddev->bitmap = bitmap;
err = md_bitmap_load(mddev);
@@ -7112,11 +7157,8 @@ static int set_bitmap_file(struct mddev *mddev, int fd)
md_bitmap_destroy(mddev);
fd = -1;
}
- mddev_resume(mddev);
} else if (fd < 0) {
- mddev_suspend(mddev);
md_bitmap_destroy(mddev);
- mddev_resume(mddev);
}
}
if (fd < 0) {
@@ -7405,7 +7447,6 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
mddev->bitmap_info.space =
mddev->bitmap_info.default_space;
bitmap = md_bitmap_create(mddev, -1);
- mddev_suspend(mddev);
if (!IS_ERR(bitmap)) {
mddev->bitmap = bitmap;
rv = md_bitmap_load(mddev);
@@ -7413,7 +7454,6 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
rv = PTR_ERR(bitmap);
if (rv)
md_bitmap_destroy(mddev);
- mddev_resume(mddev);
} else {
/* remove the bitmap */
if (!mddev->bitmap) {
@@ -7438,9 +7478,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
module_put(md_cluster_mod);
mddev->safemode_delay = DEFAULT_SAFEMODE_DELAY;
}
- mddev_suspend(mddev);
md_bitmap_destroy(mddev);
- mddev_resume(mddev);
mddev->bitmap_info.offset = 0;
}
}
@@ -7511,6 +7549,20 @@ static inline bool md_ioctl_valid(unsigned int cmd)
}
}
+static bool md_ioctl_need_suspend(unsigned int cmd)
+{
+ switch (cmd) {
+ case ADD_NEW_DISK:
+ case HOT_ADD_DISK:
+ case HOT_REMOVE_DISK:
+ case SET_BITMAP_FILE:
+ case SET_ARRAY_INFO:
+ return true;
+ default:
+ return false;
+ }
+}
+
static int __md_set_array_info(struct mddev *mddev, void __user *argp)
{
mdu_array_info_t info;
@@ -7639,7 +7691,12 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
mutex_unlock(&mddev->open_mutex);
sync_blockdev(bdev);
}
- err = mddev_lock(mddev);
+
+ if (!md_is_rdwr(mddev))
+ flush_work(&mddev->sync_work);
+
+ err = md_ioctl_need_suspend(cmd) ? mddev_suspend_and_lock(mddev) :
+ mddev_lock(mddev);
if (err) {
pr_debug("md: ioctl lock interrupted, reason %d, cmd %d\n",
err, cmd);
@@ -7767,7 +7824,10 @@ unlock:
if (mddev->hold_active == UNTIL_IOCTL &&
err != -EINVAL)
mddev->hold_active = 0;
- mddev_unlock(mddev);
+
+ md_ioctl_need_suspend(cmd) ? mddev_unlock_and_resume(mddev) :
+ mddev_unlock(mddev);
+
out:
if(did_set_md_closing)
clear_bit(MD_CLOSING, &mddev->flags);
@@ -7879,7 +7939,6 @@ static void md_free_disk(struct gendisk *disk)
{
struct mddev *mddev = disk->private_data;
- percpu_ref_exit(&mddev->writes_pending);
mddev_free(mddev);
}
@@ -8195,105 +8254,46 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
}
static void *md_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(&all_mddevs_lock)
{
- struct list_head *tmp;
- loff_t l = *pos;
- struct mddev *mddev;
+ struct md_personality *pers;
- if (l == 0x10000) {
- ++*pos;
- return (void *)2;
- }
- if (l > 0x10000)
- return NULL;
- if (!l--)
- /* header */
- return (void*)1;
+ seq_puts(seq, "Personalities : ");
+ spin_lock(&pers_lock);
+ list_for_each_entry(pers, &pers_list, list)
+ seq_printf(seq, "[%s] ", pers->name);
+
+ spin_unlock(&pers_lock);
+ seq_puts(seq, "\n");
+ seq->poll_event = atomic_read(&md_event_count);
spin_lock(&all_mddevs_lock);
- list_for_each(tmp,&all_mddevs)
- if (!l--) {
- mddev = list_entry(tmp, struct mddev, all_mddevs);
- if (!mddev_get(mddev))
- continue;
- spin_unlock(&all_mddevs_lock);
- return mddev;
- }
- spin_unlock(&all_mddevs_lock);
- if (!l--)
- return (void*)2;/* tail */
- return NULL;
+
+ return seq_list_start(&all_mddevs, *pos);
}
static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct list_head *tmp;
- struct mddev *next_mddev, *mddev = v;
- struct mddev *to_put = NULL;
-
- ++*pos;
- if (v == (void*)2)
- return NULL;
-
- spin_lock(&all_mddevs_lock);
- if (v == (void*)1) {
- tmp = all_mddevs.next;
- } else {
- to_put = mddev;
- tmp = mddev->all_mddevs.next;
- }
-
- for (;;) {
- if (tmp == &all_mddevs) {
- next_mddev = (void*)2;
- *pos = 0x10000;
- break;
- }
- next_mddev = list_entry(tmp, struct mddev, all_mddevs);
- if (mddev_get(next_mddev))
- break;
- mddev = next_mddev;
- tmp = mddev->all_mddevs.next;
- }
- spin_unlock(&all_mddevs_lock);
-
- if (to_put)
- mddev_put(to_put);
- return next_mddev;
-
+ return seq_list_next(v, &all_mddevs, pos);
}
static void md_seq_stop(struct seq_file *seq, void *v)
+ __releases(&all_mddevs_lock)
{
- struct mddev *mddev = v;
-
- if (mddev && v != (void*)1 && v != (void*)2)
- mddev_put(mddev);
+ status_unused(seq);
+ spin_unlock(&all_mddevs_lock);
}
static int md_seq_show(struct seq_file *seq, void *v)
{
- struct mddev *mddev = v;
+ struct mddev *mddev = list_entry(v, struct mddev, all_mddevs);
sector_t sectors;
struct md_rdev *rdev;
- if (v == (void*)1) {
- struct md_personality *pers;
- seq_printf(seq, "Personalities : ");
- spin_lock(&pers_lock);
- list_for_each_entry(pers, &pers_list, list)
- seq_printf(seq, "[%s] ", pers->name);
-
- spin_unlock(&pers_lock);
- seq_printf(seq, "\n");
- seq->poll_event = atomic_read(&md_event_count);
+ if (!mddev_get(mddev))
return 0;
- }
- if (v == (void*)2) {
- status_unused(seq);
- return 0;
- }
+ spin_unlock(&all_mddevs_lock);
spin_lock(&mddev->lock);
if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
seq_printf(seq, "%s : %sactive", mdname(mddev),
@@ -8364,6 +8364,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "\n");
}
spin_unlock(&mddev->lock);
+ spin_lock(&all_mddevs_lock);
+ if (atomic_dec_and_test(&mddev->active))
+ __mddev_put(mddev);
return 0;
}
@@ -8563,6 +8566,7 @@ bool md_write_start(struct mddev *mddev, struct bio *bi)
BUG_ON(mddev->ro == MD_RDONLY);
if (mddev->ro == MD_AUTO_READ) {
/* need to switch to read/write */
+ flush_work(&mddev->sync_work);
mddev->ro = MD_RDWR;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread);
@@ -9148,12 +9152,90 @@ void md_do_sync(struct md_thread *thread)
spin_unlock(&mddev->lock);
wake_up(&resync_wait);
- wake_up(&mddev->sb_wait);
md_wakeup_thread(mddev->thread);
return;
}
EXPORT_SYMBOL_GPL(md_do_sync);
+static bool rdev_removeable(struct md_rdev *rdev)
+{
+ /* rdev is not used. */
+ if (rdev->raid_disk < 0)
+ return false;
+
+ /* There are still inflight io, don't remove this rdev. */
+ if (atomic_read(&rdev->nr_pending))
+ return false;
+
+ /*
+ * An error occurred but has not yet been acknowledged by the metadata
+ * handler, don't remove this rdev.
+ */
+ if (test_bit(Blocked, &rdev->flags))
+ return false;
+
+ /* Fautly rdev is not used, it's safe to remove it. */
+ if (test_bit(Faulty, &rdev->flags))
+ return true;
+
+ /* Journal disk can only be removed if it's faulty. */
+ if (test_bit(Journal, &rdev->flags))
+ return false;
+
+ /*
+ * 'In_sync' is cleared while 'raid_disk' is valid, which means
+ * replacement has just become active from pers->spare_active(), and
+ * then pers->hot_remove_disk() will replace this rdev with replacement.
+ */
+ if (!test_bit(In_sync, &rdev->flags))
+ return true;
+
+ return false;
+}
+
+static bool rdev_is_spare(struct md_rdev *rdev)
+{
+ return !test_bit(Candidate, &rdev->flags) && rdev->raid_disk >= 0 &&
+ !test_bit(In_sync, &rdev->flags) &&
+ !test_bit(Journal, &rdev->flags) &&
+ !test_bit(Faulty, &rdev->flags);
+}
+
+static bool rdev_addable(struct md_rdev *rdev)
+{
+ /* rdev is already used, don't add it again. */
+ if (test_bit(Candidate, &rdev->flags) || rdev->raid_disk >= 0 ||
+ test_bit(Faulty, &rdev->flags))
+ return false;
+
+ /* Allow to add journal disk. */
+ if (test_bit(Journal, &rdev->flags))
+ return true;
+
+ /* Allow to add if array is read-write. */
+ if (md_is_rdwr(rdev->mddev))
+ return true;
+
+ /*
+ * For read-only array, only allow to readd a rdev. And if bitmap is
+ * used, don't allow to readd a rdev that is too old.
+ */
+ if (rdev->saved_raid_disk >= 0 && !test_bit(Bitmap_sync, &rdev->flags))
+ return true;
+
+ return false;
+}
+
+static bool md_spares_need_change(struct mddev *mddev)
+{
+ struct md_rdev *rdev;
+
+ rdev_for_each(rdev, mddev)
+ if (rdev_removeable(rdev) || rdev_addable(rdev))
+ return true;
+ return false;
+}
+
static int remove_and_add_spares(struct mddev *mddev,
struct md_rdev *this)
{
@@ -9186,12 +9268,8 @@ static int remove_and_add_spares(struct mddev *mddev,
synchronize_rcu();
rdev_for_each(rdev, mddev) {
if ((this == NULL || rdev == this) &&
- rdev->raid_disk >= 0 &&
- !test_bit(Blocked, &rdev->flags) &&
- ((test_bit(RemoveSynchronized, &rdev->flags) ||
- (!test_bit(In_sync, &rdev->flags) &&
- !test_bit(Journal, &rdev->flags))) &&
- atomic_read(&rdev->nr_pending)==0)) {
+ (test_bit(RemoveSynchronized, &rdev->flags) ||
+ rdev_removeable(rdev))) {
if (mddev->pers->hot_remove_disk(
mddev, rdev) == 0) {
sysfs_unlink_rdev(mddev, rdev);
@@ -9213,25 +9291,12 @@ static int remove_and_add_spares(struct mddev *mddev,
rdev_for_each(rdev, mddev) {
if (this && this != rdev)
continue;
- if (test_bit(Candidate, &rdev->flags))
- continue;
- if (rdev->raid_disk >= 0 &&
- !test_bit(In_sync, &rdev->flags) &&
- !test_bit(Journal, &rdev->flags) &&
- !test_bit(Faulty, &rdev->flags))
+ if (rdev_is_spare(rdev))
spares++;
- if (rdev->raid_disk >= 0)
- continue;
- if (test_bit(Faulty, &rdev->flags))
+ if (!rdev_addable(rdev))
continue;
- if (!test_bit(Journal, &rdev->flags)) {
- if (!md_is_rdwr(mddev) &&
- !(rdev->saved_raid_disk >= 0 &&
- !test_bit(Bitmap_sync, &rdev->flags)))
- continue;
-
+ if (!test_bit(Journal, &rdev->flags))
rdev->recovery_offset = 0;
- }
if (mddev->pers->hot_add_disk(mddev, rdev) == 0) {
/* failure here is OK */
sysfs_link_rdev(mddev, rdev);
@@ -9247,9 +9312,86 @@ no_add:
return spares;
}
+static bool md_choose_sync_action(struct mddev *mddev, int *spares)
+{
+ /* Check if reshape is in progress first. */
+ if (mddev->reshape_position != MaxSector) {
+ if (mddev->pers->check_reshape == NULL ||
+ mddev->pers->check_reshape(mddev) != 0)
+ return false;
+
+ set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
+ clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
+ return true;
+ }
+
+ /*
+ * Remove any failed drives, then add spares if possible. Spares are
+ * also removed and re-added, to allow the personality to fail the
+ * re-add.
+ */
+ *spares = remove_and_add_spares(mddev, NULL);
+ if (*spares) {
+ clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
+ clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
+ clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
+
+ /* Start new recovery. */
+ set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
+ return true;
+ }
+
+ /* Check if recovery is in progress. */
+ if (mddev->recovery_cp < MaxSector) {
+ set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
+ clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
+ return true;
+ }
+
+ /* Delay to choose resync/check/repair in md_do_sync(). */
+ if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
+ return true;
+
+ /* Nothing to be done */
+ return false;
+}
+
static void md_start_sync(struct work_struct *ws)
{
- struct mddev *mddev = container_of(ws, struct mddev, del_work);
+ struct mddev *mddev = container_of(ws, struct mddev, sync_work);
+ int spares = 0;
+ bool suspend = false;
+
+ if (md_spares_need_change(mddev))
+ suspend = true;
+
+ suspend ? mddev_suspend_and_lock_nointr(mddev) :
+ mddev_lock_nointr(mddev);
+
+ if (!md_is_rdwr(mddev)) {
+ /*
+ * On a read-only array we can:
+ * - remove failed devices
+ * - add already-in_sync devices if the array itself is in-sync.
+ * As we only add devices that are already in-sync, we can
+ * activate the spares immediately.
+ */
+ remove_and_add_spares(mddev, NULL);
+ goto not_running;
+ }
+
+ if (!md_choose_sync_action(mddev, &spares))
+ goto not_running;
+
+ if (!mddev->pers->sync_request)
+ goto not_running;
+
+ /*
+ * We are adding a device or devices to an array which has the bitmap
+ * stored on all devices. So make sure all bitmap pages get written.
+ */
+ if (spares)
+ md_bitmap_write_all(mddev->bitmap);
rcu_assign_pointer(mddev->sync_thread,
md_register_thread(md_do_sync, mddev, "resync"));
@@ -9257,20 +9399,27 @@ static void md_start_sync(struct work_struct *ws)
pr_warn("%s: could not start resync thread...\n",
mdname(mddev));
/* leave the spares where they are, it shouldn't hurt */
- clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
- clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
- clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
- clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
- clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
- wake_up(&resync_wait);
- if (test_and_clear_bit(MD_RECOVERY_RECOVER,
- &mddev->recovery))
- if (mddev->sysfs_action)
- sysfs_notify_dirent_safe(mddev->sysfs_action);
- } else
- md_wakeup_thread(mddev->sync_thread);
+ goto not_running;
+ }
+
+ suspend ? mddev_unlock_and_resume(mddev) : mddev_unlock(mddev);
+ md_wakeup_thread(mddev->sync_thread);
sysfs_notify_dirent_safe(mddev->sysfs_action);
md_new_event();
+ return;
+
+not_running:
+ clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
+ clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
+ clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
+ clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
+ clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
+ suspend ? mddev_unlock_and_resume(mddev) : mddev_unlock(mddev);
+
+ wake_up(&resync_wait);
+ if (test_and_clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery) &&
+ mddev->sysfs_action)
+ sysfs_notify_dirent_safe(mddev->sysfs_action);
}
/*
@@ -9297,19 +9446,7 @@ static void md_start_sync(struct work_struct *ws)
*/
void md_check_recovery(struct mddev *mddev)
{
- if (test_bit(MD_ALLOW_SB_UPDATE, &mddev->flags) && mddev->sb_flags) {
- /* Write superblock - thread that called mddev_suspend()
- * holds reconfig_mutex for us.
- */
- set_bit(MD_UPDATING_SB, &mddev->flags);
- smp_mb__after_atomic();
- if (test_bit(MD_ALLOW_SB_UPDATE, &mddev->flags))
- md_update_sb(mddev, 0);
- clear_bit_unlock(MD_UPDATING_SB, &mddev->flags);
- wake_up(&mddev->sb_wait);
- }
-
- if (is_md_suspended(mddev))
+ if (READ_ONCE(mddev->suspended))
return;
if (mddev->bitmap)
@@ -9338,7 +9475,6 @@ void md_check_recovery(struct mddev *mddev)
return;
if (mddev_trylock(mddev)) {
- int spares = 0;
bool try_set_sync = mddev->safemode != 0;
if (!mddev->external && mddev->safemode == 1)
@@ -9346,30 +9482,43 @@ void md_check_recovery(struct mddev *mddev)
if (!md_is_rdwr(mddev)) {
struct md_rdev *rdev;
+
+ if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
+ /* sync_work already queued. */
+ clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ goto unlock;
+ }
+
if (!mddev->external && mddev->in_sync)
- /* 'Blocked' flag not needed as failed devices
+ /*
+ * 'Blocked' flag not needed as failed devices
* will be recorded if array switched to read/write.
* Leaving it set will prevent the device
* from being removed.
*/
rdev_for_each(rdev, mddev)
clear_bit(Blocked, &rdev->flags);
- /* On a read-only array we can:
- * - remove failed devices
- * - add already-in_sync devices if the array itself
- * is in-sync.
- * As we only add devices that are already in-sync,
- * we can activate the spares immediately.
- */
- remove_and_add_spares(mddev, NULL);
- /* There is no thread, but we need to call
+
+ /*
+ * There is no thread, but we need to call
* ->spare_active and clear saved_raid_disk
*/
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
md_reap_sync_thread(mddev);
+
+ /*
+ * Let md_start_sync() to remove and add rdevs to the
+ * array.
+ */
+ if (md_spares_need_change(mddev)) {
+ set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
+ queue_work(md_misc_wq, &mddev->sync_work);
+ }
+
clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
clear_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags);
+
goto unlock;
}
@@ -9425,56 +9574,14 @@ void md_check_recovery(struct mddev *mddev)
clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
- if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
- test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
- goto not_running;
- /* no recovery is running.
- * remove any failed drives, then
- * add spares if possible.
- * Spares are also removed and re-added, to allow
- * the personality to fail the re-add.
- */
-
- if (mddev->reshape_position != MaxSector) {
- if (mddev->pers->check_reshape == NULL ||
- mddev->pers->check_reshape(mddev) != 0)
- /* Cannot proceed */
- goto not_running;
- set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
- clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
- } else if ((spares = remove_and_add_spares(mddev, NULL))) {
- clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
- clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
- clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
- set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
- } else if (mddev->recovery_cp < MaxSector) {
- set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
- clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
- } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
- /* nothing to be done ... */
- goto not_running;
-
- if (mddev->pers->sync_request) {
- if (spares) {
- /* We are adding a device or devices to an array
- * which has the bitmap stored on all devices.
- * So make sure all bitmap pages get written
- */
- md_bitmap_write_all(mddev->bitmap);
- }
- INIT_WORK(&mddev->del_work, md_start_sync);
- queue_work(md_misc_wq, &mddev->del_work);
- goto unlock;
- }
- not_running:
- if (!mddev->sync_thread) {
+ if (test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) &&
+ !test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) {
+ queue_work(md_misc_wq, &mddev->sync_work);
+ } else {
clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
wake_up(&resync_wait);
- if (test_and_clear_bit(MD_RECOVERY_RECOVER,
- &mddev->recovery))
- if (mddev->sysfs_action)
- sysfs_notify_dirent_safe(mddev->sysfs_action);
}
+
unlock:
wake_up(&mddev->sb_wait);
mddev_unlock(mddev);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 274e7d61d19f..ade83af123a2 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -246,10 +246,6 @@ struct md_cluster_info;
* become failed.
* @MD_HAS_PPL: The raid array has PPL feature set.
* @MD_HAS_MULTIPLE_PPLS: The raid array has multiple PPLs feature set.
- * @MD_ALLOW_SB_UPDATE: md_check_recovery is allowed to update the metadata
- * without taking reconfig_mutex.
- * @MD_UPDATING_SB: md_check_recovery is updating the metadata without
- * explicitly holding reconfig_mutex.
* @MD_NOT_READY: do_md_run() is active, so 'array_state', ust not report that
* array is ready yet.
* @MD_BROKEN: This is used to stop writes and mark array as failed.
@@ -266,8 +262,6 @@ enum mddev_flags {
MD_FAILFAST_SUPPORTED,
MD_HAS_PPL,
MD_HAS_MULTIPLE_PPLS,
- MD_ALLOW_SB_UPDATE,
- MD_UPDATING_SB,
MD_NOT_READY,
MD_BROKEN,
MD_DELETED,
@@ -314,6 +308,7 @@ struct mddev {
unsigned long sb_flags;
int suspended;
+ struct mutex suspend_mutex;
struct percpu_ref active_io;
int ro;
int sysfs_active; /* set when sysfs deletes
@@ -451,7 +446,10 @@ struct mddev {
struct kernfs_node *sysfs_degraded; /*handle for 'degraded' */
struct kernfs_node *sysfs_level; /*handle for 'level' */
- struct work_struct del_work; /* used for delayed sysfs removal */
+ /* used for delayed sysfs removal */
+ struct work_struct del_work;
+ /* used for register new sync thread */
+ struct work_struct sync_work;
/* "lock" protects:
* flush_bio transition from NULL to !NULL
@@ -565,23 +563,6 @@ enum recovery_flags {
MD_RESYNCING_REMOTE, /* remote node is running resync thread */
};
-enum md_ro_state {
- MD_RDWR,
- MD_RDONLY,
- MD_AUTO_READ,
- MD_MAX_STATE
-};
-
-static inline bool md_is_rdwr(struct mddev *mddev)
-{
- return (mddev->ro == MD_RDWR);
-}
-
-static inline bool is_md_suspended(struct mddev *mddev)
-{
- return percpu_ref_is_dying(&mddev->active_io);
-}
-
static inline int __must_check mddev_lock(struct mddev *mddev)
{
return mutex_lock_interruptible(&mddev->reconfig_mutex);
@@ -641,7 +622,6 @@ struct md_personality
int (*start_reshape) (struct mddev *mddev);
void (*finish_reshape) (struct mddev *mddev);
void (*update_reshape_pos) (struct mddev *mddev);
- void (*prepare_suspend) (struct mddev *mddev);
/* quiesce suspends or resumes internal processing.
* 1 - stop new actions and wait for action io to complete
* 0 - return to normal behaviour
@@ -766,7 +746,6 @@ extern void md_unregister_thread(struct mddev *mddev, struct md_thread __rcu **t
extern void md_wakeup_thread(struct md_thread __rcu *thread);
extern void md_check_recovery(struct mddev *mddev);
extern void md_reap_sync_thread(struct mddev *mddev);
-extern int mddev_init_writes_pending(struct mddev *mddev);
extern bool md_write_start(struct mddev *mddev, struct bio *bi);
extern void md_write_inc(struct mddev *mddev, struct bio *bi);
extern void md_write_end(struct mddev *mddev);
@@ -793,7 +772,8 @@ extern int md_integrity_register(struct mddev *mddev);
extern int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev);
extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale);
-extern void mddev_init(struct mddev *mddev);
+extern int mddev_init(struct mddev *mddev);
+extern void mddev_destroy(struct mddev *mddev);
struct mddev *md_alloc(dev_t dev, char *name);
void mddev_put(struct mddev *mddev);
extern int md_run(struct mddev *mddev);
@@ -804,15 +784,14 @@ extern int md_rdev_init(struct md_rdev *rdev);
extern void md_rdev_clear(struct md_rdev *rdev);
extern void md_handle_request(struct mddev *mddev, struct bio *bio);
-extern void mddev_suspend(struct mddev *mddev);
+extern int mddev_suspend(struct mddev *mddev, bool interruptible);
extern void mddev_resume(struct mddev *mddev);
extern void md_reload_sb(struct mddev *mddev, int raid_disk);
extern void md_update_sb(struct mddev *mddev, int force);
-extern void mddev_create_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
- bool is_suspend);
-extern void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
- bool is_suspend);
+extern void mddev_create_serial_pool(struct mddev *mddev, struct md_rdev *rdev);
+extern void mddev_destroy_serial_pool(struct mddev *mddev,
+ struct md_rdev *rdev);
struct md_rdev *md_find_rdev_nr_rcu(struct mddev *mddev, int nr);
struct md_rdev *md_find_rdev_rcu(struct mddev *mddev, dev_t dev);
@@ -850,6 +829,33 @@ static inline void mddev_check_write_zeroes(struct mddev *mddev, struct bio *bio
mddev->queue->limits.max_write_zeroes_sectors = 0;
}
+static inline int mddev_suspend_and_lock(struct mddev *mddev)
+{
+ int ret;
+
+ ret = mddev_suspend(mddev, true);
+ if (ret)
+ return ret;
+
+ ret = mddev_lock(mddev);
+ if (ret)
+ mddev_resume(mddev);
+
+ return ret;
+}
+
+static inline void mddev_suspend_and_lock_nointr(struct mddev *mddev)
+{
+ mddev_suspend(mddev, false);
+ mutex_lock(&mddev->reconfig_mutex);
+}
+
+static inline void mddev_unlock_and_resume(struct mddev *mddev)
+{
+ mddev_unlock(mddev);
+ mddev_resume(mddev);
+}
+
struct mdu_array_info_s;
struct mdu_disk_info_s;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 2aabac773fe7..35d12948e0a9 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1345,6 +1345,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
int first_clone;
int max_sectors;
bool write_behind = false;
+ bool is_discard = (bio_op(bio) == REQ_OP_DISCARD);
if (mddev_is_clustered(mddev) &&
md_cluster_ops->area_resyncing(mddev, WRITE,
@@ -1405,7 +1406,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
* write-mostly, which means we could allocate write behind
* bio later.
*/
- if (rdev && test_bit(WriteMostly, &rdev->flags))
+ if (!is_discard && rdev && test_bit(WriteMostly, &rdev->flags))
write_behind = true;
if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
@@ -3122,8 +3123,7 @@ static int raid1_run(struct mddev *mddev)
mdname(mddev));
return -EIO;
}
- if (mddev_init_writes_pending(mddev) < 0)
- return -ENOMEM;
+
/*
* copy the already verified devices into our private RAID1
* bookkeeping area. [whatever we allocate in run(),
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 023413120851..a5927e98dc67 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -4154,9 +4154,6 @@ static int raid10_run(struct mddev *mddev)
sector_t min_offset_diff = 0;
int first = 1;
- if (mddev_init_writes_pending(mddev) < 0)
- return -ENOMEM;
-
if (mddev->private == NULL) {
conf = setup_conf(mddev);
if (IS_ERR(conf))
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 518b7cfa78b9..6157f5beb9fe 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -327,8 +327,9 @@ void r5l_wake_reclaim(struct r5l_log *log, sector_t space);
void r5c_check_stripe_cache_usage(struct r5conf *conf)
{
int total_cached;
+ struct r5l_log *log = READ_ONCE(conf->log);
- if (!r5c_is_writeback(conf->log))
+ if (!r5c_is_writeback(log))
return;
total_cached = atomic_read(&conf->r5c_cached_partial_stripes) +
@@ -344,7 +345,7 @@ void r5c_check_stripe_cache_usage(struct r5conf *conf)
*/
if (total_cached > conf->min_nr_stripes * 1 / 2 ||
atomic_read(&conf->empty_inactive_list_nr) > 0)
- r5l_wake_reclaim(conf->log, 0);
+ r5l_wake_reclaim(log, 0);
}
/*
@@ -353,7 +354,9 @@ void r5c_check_stripe_cache_usage(struct r5conf *conf)
*/
void r5c_check_cached_full_stripe(struct r5conf *conf)
{
- if (!r5c_is_writeback(conf->log))
+ struct r5l_log *log = READ_ONCE(conf->log);
+
+ if (!r5c_is_writeback(log))
return;
/*
@@ -363,7 +366,7 @@ void r5c_check_cached_full_stripe(struct r5conf *conf)
if (atomic_read(&conf->r5c_cached_full_stripes) >=
min(R5C_FULL_STRIPE_FLUSH_BATCH(conf),
conf->chunk_sectors >> RAID5_STRIPE_SHIFT(conf)))
- r5l_wake_reclaim(conf->log, 0);
+ r5l_wake_reclaim(log, 0);
}
/*
@@ -396,7 +399,7 @@ void r5c_check_cached_full_stripe(struct r5conf *conf)
*/
static sector_t r5c_log_required_to_flush_cache(struct r5conf *conf)
{
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
if (!r5c_is_writeback(log))
return 0;
@@ -449,7 +452,7 @@ static inline void r5c_update_log_state(struct r5l_log *log)
void r5c_make_stripe_write_out(struct stripe_head *sh)
{
struct r5conf *conf = sh->raid_conf;
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
BUG_ON(!r5c_is_writeback(log));
@@ -491,7 +494,7 @@ static void r5c_handle_parity_cached(struct stripe_head *sh)
*/
static void r5c_finish_cache_stripe(struct stripe_head *sh)
{
- struct r5l_log *log = sh->raid_conf->log;
+ struct r5l_log *log = READ_ONCE(sh->raid_conf->log);
if (log->r5c_journal_mode == R5C_JOURNAL_MODE_WRITE_THROUGH) {
BUG_ON(test_bit(STRIPE_R5C_CACHING, &sh->state));
@@ -683,7 +686,6 @@ static void r5c_disable_writeback_async(struct work_struct *work)
disable_writeback_work);
struct mddev *mddev = log->rdev->mddev;
struct r5conf *conf = mddev->private;
- int locked = 0;
if (log->r5c_journal_mode == R5C_JOURNAL_MODE_WRITE_THROUGH)
return;
@@ -692,14 +694,14 @@ static void r5c_disable_writeback_async(struct work_struct *work)
/* wait superblock change before suspend */
wait_event(mddev->sb_wait,
- conf->log == NULL ||
- (!test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) &&
- (locked = mddev_trylock(mddev))));
- if (locked) {
- mddev_suspend(mddev);
+ !READ_ONCE(conf->log) ||
+ !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags));
+
+ log = READ_ONCE(conf->log);
+ if (log) {
+ mddev_suspend(mddev, false);
log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_THROUGH;
mddev_resume(mddev);
- mddev_unlock(mddev);
}
}
@@ -1151,7 +1153,7 @@ static void r5l_run_no_space_stripes(struct r5l_log *log)
static sector_t r5c_calculate_new_cp(struct r5conf *conf)
{
struct stripe_head *sh;
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
sector_t new_cp;
unsigned long flags;
@@ -1159,12 +1161,12 @@ static sector_t r5c_calculate_new_cp(struct r5conf *conf)
return log->next_checkpoint;
spin_lock_irqsave(&log->stripe_in_journal_lock, flags);
- if (list_empty(&conf->log->stripe_in_journal_list)) {
+ if (list_empty(&log->stripe_in_journal_list)) {
/* all stripes flushed */
spin_unlock_irqrestore(&log->stripe_in_journal_lock, flags);
return log->next_checkpoint;
}
- sh = list_first_entry(&conf->log->stripe_in_journal_list,
+ sh = list_first_entry(&log->stripe_in_journal_list,
struct stripe_head, r5c);
new_cp = sh->log_start;
spin_unlock_irqrestore(&log->stripe_in_journal_lock, flags);
@@ -1399,7 +1401,7 @@ void r5c_flush_cache(struct r5conf *conf, int num)
struct stripe_head *sh, *next;
lockdep_assert_held(&conf->device_lock);
- if (!conf->log)
+ if (!READ_ONCE(conf->log))
return;
count = 0;
@@ -1420,7 +1422,7 @@ void r5c_flush_cache(struct r5conf *conf, int num)
static void r5c_do_reclaim(struct r5conf *conf)
{
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
struct stripe_head *sh;
int count = 0;
unsigned long flags;
@@ -1549,7 +1551,7 @@ static void r5l_reclaim_thread(struct md_thread *thread)
{
struct mddev *mddev = thread->mddev;
struct r5conf *conf = mddev->private;
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
if (!log)
return;
@@ -1591,7 +1593,7 @@ void r5l_quiesce(struct r5l_log *log, int quiesce)
bool r5l_log_disk_error(struct r5conf *conf)
{
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
/* don't allow write if journal disk is missing */
if (!log)
@@ -2583,9 +2585,7 @@ int r5c_journal_mode_set(struct mddev *mddev, int mode)
mode == R5C_JOURNAL_MODE_WRITE_BACK)
return -EINVAL;
- mddev_suspend(mddev);
conf->log->r5c_journal_mode = mode;
- mddev_resume(mddev);
pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n",
mdname(mddev), mode, r5c_journal_mode_str[mode]);
@@ -2610,11 +2610,11 @@ static ssize_t r5c_journal_mode_store(struct mddev *mddev,
if (strlen(r5c_journal_mode_str[mode]) == len &&
!strncmp(page, r5c_journal_mode_str[mode], len))
break;
- ret = mddev_lock(mddev);
+ ret = mddev_suspend_and_lock(mddev);
if (ret)
return ret;
ret = r5c_journal_mode_set(mddev, mode);
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return ret ?: length;
}
@@ -2635,7 +2635,7 @@ int r5c_try_caching_write(struct r5conf *conf,
struct stripe_head_state *s,
int disks)
{
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
int i;
struct r5dev *dev;
int to_cache = 0;
@@ -2802,7 +2802,7 @@ void r5c_finish_stripe_write_out(struct r5conf *conf,
struct stripe_head *sh,
struct stripe_head_state *s)
{
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
int i;
int do_wakeup = 0;
sector_t tree_index;
@@ -2941,7 +2941,7 @@ int r5c_cache_data(struct r5l_log *log, struct stripe_head *sh)
/* check whether this big stripe is in write back cache. */
bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect)
{
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
sector_t tree_index;
void *slot;
@@ -3049,14 +3049,14 @@ int r5l_start(struct r5l_log *log)
void r5c_update_on_rdev_error(struct mddev *mddev, struct md_rdev *rdev)
{
struct r5conf *conf = mddev->private;
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = READ_ONCE(conf->log);
if (!log)
return;
if ((raid5_calc_degraded(conf) > 0 ||
test_bit(Journal, &rdev->flags)) &&
- conf->log->r5c_journal_mode == R5C_JOURNAL_MODE_WRITE_BACK)
+ log->r5c_journal_mode == R5C_JOURNAL_MODE_WRITE_BACK)
schedule_work(&log->disable_writeback_work);
}
@@ -3145,7 +3145,7 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
spin_lock_init(&log->stripe_in_journal_lock);
atomic_set(&log->stripe_in_journal_count, 0);
- conf->log = log;
+ WRITE_ONCE(conf->log, log);
set_bit(MD_HAS_JOURNAL, &conf->mddev->flags);
return 0;
@@ -3173,7 +3173,7 @@ void r5l_exit_log(struct r5conf *conf)
* 'reconfig_mutex' is held by caller, set 'confg->log' to NULL to
* ensure disable_writeback_work wakes up and exits.
*/
- conf->log = NULL;
+ WRITE_ONCE(conf->log, NULL);
wake_up(&conf->mddev->sb_wait);
flush_work(&log->disable_writeback_work);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 284cd71bcc68..c84ccc97329b 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -70,6 +70,8 @@ MODULE_PARM_DESC(devices_handle_discard_safely,
"Set to Y if all devices in each array reliably return zeroes on reads from discarded regions");
static struct workqueue_struct *raid5_wq;
+static void raid5_quiesce(struct mddev *mddev, int quiesce);
+
static inline struct hlist_head *stripe_hash(struct r5conf *conf, sector_t sect)
{
int hash = (sect >> RAID5_STRIPE_SHIFT(conf)) & HASH_MASK;
@@ -2499,15 +2501,12 @@ static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
unsigned long cpu;
int err = 0;
- /*
- * Never shrink. And mddev_suspend() could deadlock if this is called
- * from raid5d. In that case, scribble_disks and scribble_sectors
- * should equal to new_disks and new_sectors
- */
+ /* Never shrink. */
if (conf->scribble_disks >= new_disks &&
conf->scribble_sectors >= new_sectors)
return 0;
- mddev_suspend(conf->mddev);
+
+ raid5_quiesce(conf->mddev, true);
cpus_read_lock();
for_each_present_cpu(cpu) {
@@ -2521,7 +2520,8 @@ static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
}
cpus_read_unlock();
- mddev_resume(conf->mddev);
+ raid5_quiesce(conf->mddev, false);
+
if (!err) {
conf->scribble_disks = new_disks;
conf->scribble_sectors = new_sectors;
@@ -5960,19 +5960,6 @@ out:
return ret;
}
-static bool reshape_inprogress(struct mddev *mddev)
-{
- return test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
- test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
- !test_bit(MD_RECOVERY_DONE, &mddev->recovery) &&
- !test_bit(MD_RECOVERY_INTR, &mddev->recovery);
-}
-
-static bool reshape_disabled(struct mddev *mddev)
-{
- return is_md_suspended(mddev) || !md_is_rdwr(mddev);
-}
-
static enum stripe_result make_stripe_request(struct mddev *mddev,
struct r5conf *conf, struct stripe_request_ctx *ctx,
sector_t logical_sector, struct bio *bi)
@@ -6004,8 +5991,7 @@ static enum stripe_result make_stripe_request(struct mddev *mddev,
if (ahead_of_reshape(mddev, logical_sector,
conf->reshape_safe)) {
spin_unlock_irq(&conf->device_lock);
- ret = STRIPE_SCHEDULE_AND_RETRY;
- goto out;
+ return STRIPE_SCHEDULE_AND_RETRY;
}
}
spin_unlock_irq(&conf->device_lock);
@@ -6084,15 +6070,6 @@ static enum stripe_result make_stripe_request(struct mddev *mddev,
out_release:
raid5_release_stripe(sh);
-out:
- if (ret == STRIPE_SCHEDULE_AND_RETRY && !reshape_inprogress(mddev) &&
- reshape_disabled(mddev)) {
- bi->bi_status = BLK_STS_IOERR;
- ret = STRIPE_FAIL;
- pr_err("md/raid456:%s: io failed across reshape position while reshape can't make progress.\n",
- mdname(mddev));
- }
-
return ret;
}
@@ -7032,7 +7009,7 @@ raid5_store_stripe_size(struct mddev *mddev, const char *page, size_t len)
new != roundup_pow_of_two(new))
return -EINVAL;
- err = mddev_lock(mddev);
+ err = mddev_suspend_and_lock(mddev);
if (err)
return err;
@@ -7056,7 +7033,6 @@ raid5_store_stripe_size(struct mddev *mddev, const char *page, size_t len)
goto out_unlock;
}
- mddev_suspend(mddev);
mutex_lock(&conf->cache_size_mutex);
size = conf->max_nr_stripes;
@@ -7071,10 +7047,9 @@ raid5_store_stripe_size(struct mddev *mddev, const char *page, size_t len)
err = -ENOMEM;
}
mutex_unlock(&conf->cache_size_mutex);
- mddev_resume(mddev);
out_unlock:
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return err ?: len;
}
@@ -7160,7 +7135,7 @@ raid5_store_skip_copy(struct mddev *mddev, const char *page, size_t len)
return -EINVAL;
new = !!new;
- err = mddev_lock(mddev);
+ err = mddev_suspend_and_lock(mddev);
if (err)
return err;
conf = mddev->private;
@@ -7169,15 +7144,13 @@ raid5_store_skip_copy(struct mddev *mddev, const char *page, size_t len)
else if (new != conf->skip_copy) {
struct request_queue *q = mddev->queue;
- mddev_suspend(mddev);
conf->skip_copy = new;
if (new)
blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, q);
else
blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, q);
- mddev_resume(mddev);
}
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return err ?: len;
}
@@ -7232,15 +7205,13 @@ raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)
if (new > 8192)
return -EINVAL;
- err = mddev_lock(mddev);
+ err = mddev_suspend_and_lock(mddev);
if (err)
return err;
conf = mddev->private;
if (!conf)
err = -ENODEV;
else if (new != conf->worker_cnt_per_group) {
- mddev_suspend(mddev);
-
old_groups = conf->worker_groups;
if (old_groups)
flush_workqueue(raid5_wq);
@@ -7257,9 +7228,8 @@ raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)
kfree(old_groups[0].workers);
kfree(old_groups);
}
- mddev_resume(mddev);
}
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return err ?: len;
}
@@ -7785,9 +7755,6 @@ static int raid5_run(struct mddev *mddev)
long long min_offset_diff = 0;
int first = 1;
- if (mddev_init_writes_pending(mddev) < 0)
- return -ENOMEM;
-
if (mddev->recovery_cp != MaxSector)
pr_notice("md/raid:%s: not clean -- starting background reconstruction\n",
mdname(mddev));
@@ -8568,8 +8535,8 @@ static int raid5_start_reshape(struct mddev *mddev)
* the reshape wasn't running - like Discard or Read - have
* completed.
*/
- mddev_suspend(mddev);
- mddev_resume(mddev);
+ raid5_quiesce(mddev, true);
+ raid5_quiesce(mddev, false);
/* Add some new drives, as many as will fit.
* We know there are enough to make the newly sized array work.
@@ -8984,12 +8951,12 @@ static int raid5_change_consistency_policy(struct mddev *mddev, const char *buf)
struct r5conf *conf;
int err;
- err = mddev_lock(mddev);
+ err = mddev_suspend_and_lock(mddev);
if (err)
return err;
conf = mddev->private;
if (!conf) {
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return -ENODEV;
}
@@ -8999,19 +8966,14 @@ static int raid5_change_consistency_policy(struct mddev *mddev, const char *buf)
err = log_init(conf, NULL, true);
if (!err) {
err = resize_stripes(conf, conf->pool_size);
- if (err) {
- mddev_suspend(mddev);
+ if (err)
log_exit(conf);
- mddev_resume(mddev);
- }
}
} else
err = -EINVAL;
} else if (strncmp(buf, "resync", 6) == 0) {
if (raid5_has_ppl(conf)) {
- mddev_suspend(mddev);
log_exit(conf);
- mddev_resume(mddev);
err = resize_stripes(conf, conf->pool_size);
} else if (test_bit(MD_HAS_JOURNAL, &conf->mddev->flags) &&
r5l_log_disk_error(conf)) {
@@ -9024,11 +8986,9 @@ static int raid5_change_consistency_policy(struct mddev *mddev, const char *buf)
break;
}
- if (!journal_dev_exists) {
- mddev_suspend(mddev);
+ if (!journal_dev_exists)
clear_bit(MD_HAS_JOURNAL, &mddev->flags);
- mddev_resume(mddev);
- } else /* need remove journal device first */
+ else /* need remove journal device first */
err = -EBUSY;
} else
err = -EINVAL;
@@ -9039,7 +8999,7 @@ static int raid5_change_consistency_policy(struct mddev *mddev, const char *buf)
if (!err)
md_update_sb(mddev, 1);
- mddev_unlock(mddev);
+ mddev_unlock_and_resume(mddev);
return err;
}
@@ -9051,22 +9011,6 @@ static int raid5_start(struct mddev *mddev)
return r5l_start(conf->log);
}
-static void raid5_prepare_suspend(struct mddev *mddev)
-{
- struct r5conf *conf = mddev->private;
-
- wait_event(mddev->sb_wait, !reshape_inprogress(mddev) ||
- percpu_ref_is_zero(&mddev->active_io));
- if (percpu_ref_is_zero(&mddev->active_io))
- return;
-
- /*
- * Reshape is not in progress, and array is suspended, io that is
- * waiting for reshpape can never be done.
- */
- wake_up(&conf->wait_for_overlap);
-}
-
static struct md_personality raid6_personality =
{
.name = "raid6",
@@ -9087,7 +9031,6 @@ static struct md_personality raid6_personality =
.check_reshape = raid6_check_reshape,
.start_reshape = raid5_start_reshape,
.finish_reshape = raid5_finish_reshape,
- .prepare_suspend = raid5_prepare_suspend,
.quiesce = raid5_quiesce,
.takeover = raid6_takeover,
.change_consistency_policy = raid5_change_consistency_policy,
@@ -9112,7 +9055,6 @@ static struct md_personality raid5_personality =
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
.finish_reshape = raid5_finish_reshape,
- .prepare_suspend = raid5_prepare_suspend,
.quiesce = raid5_quiesce,
.takeover = raid5_takeover,
.change_consistency_policy = raid5_change_consistency_policy,
@@ -9138,7 +9080,6 @@ static struct md_personality raid4_personality =
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
.finish_reshape = raid5_finish_reshape,
- .prepare_suspend = raid5_prepare_suspend,
.quiesce = raid5_quiesce,
.takeover = raid4_takeover,
.change_consistency_policy = raid5_change_consistency_policy,
diff --git a/drivers/media/cec/platform/Kconfig b/drivers/media/cec/platform/Kconfig
index b672d3142eb7..ede81fe331b0 100644
--- a/drivers/media/cec/platform/Kconfig
+++ b/drivers/media/cec/platform/Kconfig
@@ -99,7 +99,7 @@ config CEC_TEGRA
config CEC_SECO
tristate "SECO Boards HDMI CEC driver"
- depends on (X86 || IA64) || COMPILE_TEST
+ depends on X86 || COMPILE_TEST
depends on PCI && DMI
select CEC_CORE
select CEC_NOTIFIER
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c
index 635966d705cb..e8bb5f37f5cb 100644
--- a/drivers/memory/atmel-ebi.c
+++ b/drivers/memory/atmel-ebi.c
@@ -12,7 +12,10 @@
#include <linux/mfd/syscon/atmel-matrix.h>
#include <linux/mfd/syscon/atmel-smc.h>
#include <linux/init.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <soc/at91/atmel-sfr.h>
@@ -30,7 +33,7 @@ struct atmel_ebi_dev {
struct atmel_ebi *ebi;
u32 mode;
int numcs;
- struct atmel_ebi_dev_config configs[];
+ struct atmel_ebi_dev_config configs[] __counted_by(numcs);
};
struct atmel_ebi_caps {
@@ -515,16 +518,11 @@ static int atmel_ebi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *child, *np = dev->of_node, *smc_np;
- const struct of_device_id *match;
struct atmel_ebi *ebi;
int ret, reg_cells;
struct clk *clk;
u32 val;
- match = of_match_device(atmel_ebi_id_table, dev);
- if (!match || !match->data)
- return -EINVAL;
-
ebi = devm_kzalloc(dev, sizeof(*ebi), GFP_KERNEL);
if (!ebi)
return -ENOMEM;
@@ -532,7 +530,9 @@ static int atmel_ebi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ebi);
INIT_LIST_HEAD(&ebi->devs);
- ebi->caps = match->data;
+ ebi->caps = device_get_match_data(dev);
+ if (!ebi->caps)
+ return -EINVAL;
ebi->dev = dev;
clk = devm_clk_get(dev, NULL);
diff --git a/drivers/memory/brcmstb_memc.c b/drivers/memory/brcmstb_memc.c
index 233a53f5bce1..a6ea51996522 100644
--- a/drivers/memory/brcmstb_memc.c
+++ b/drivers/memory/brcmstb_memc.c
@@ -8,8 +8,9 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#define REG_MEMC_CNTRLR_CONFIG 0x00
#define CNTRLR_CONFIG_LPDDR4_SHIFT 5
@@ -121,12 +122,9 @@ static struct attribute_group dev_attr_group = {
.attrs = dev_attrs,
};
-static const struct of_device_id brcmstb_memc_of_match[];
-
static int brcmstb_memc_probe(struct platform_device *pdev)
{
const struct brcmstb_memc_data *memc_data;
- const struct of_device_id *of_id;
struct device *dev = &pdev->dev;
struct brcmstb_memc *memc;
int ret;
@@ -137,8 +135,7 @@ static int brcmstb_memc_probe(struct platform_device *pdev)
dev_set_drvdata(dev, memc);
- of_id = of_match_device(brcmstb_memc_of_match, dev);
- memc_data = of_id->data;
+ memc_data = device_get_match_data(dev);
memc->srpd_offset = memc_data->srpd_offset;
memc->ddr_ctrl = devm_platform_ioremap_resource(pdev, 0);
diff --git a/drivers/memory/fsl-corenet-cf.c b/drivers/memory/fsl-corenet-cf.c
index 7fc9f57ae278..8096c4f33303 100644
--- a/drivers/memory/fsl-corenet-cf.c
+++ b/drivers/memory/fsl-corenet-cf.c
@@ -10,10 +10,8 @@
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
enum ccf_version {
CCF1,
@@ -172,14 +170,9 @@ out:
static int ccf_probe(struct platform_device *pdev)
{
struct ccf_private *ccf;
- const struct of_device_id *match;
u32 errinten;
int ret, irq;
- match = of_match_device(ccf_matches, &pdev->dev);
- if (WARN_ON(!match))
- return -ENODEV;
-
ccf = devm_kzalloc(&pdev->dev, sizeof(*ccf), GFP_KERNEL);
if (!ccf)
return -ENOMEM;
@@ -189,7 +182,7 @@ static int ccf_probe(struct platform_device *pdev)
return PTR_ERR(ccf->regs);
ccf->dev = &pdev->dev;
- ccf->info = match->data;
+ ccf->info = device_get_match_data(&pdev->dev);
ccf->err_regs = ccf->regs + ccf->info->err_reg_offs;
if (ccf->info->has_brr) {
diff --git a/drivers/memory/tegra/tegra234.c b/drivers/memory/tegra/tegra234.c
index 9e5b5dbd9c8d..abff87f917cb 100644
--- a/drivers/memory/tegra/tegra234.c
+++ b/drivers/memory/tegra/tegra234.c
@@ -450,6 +450,18 @@ static const struct tegra_mc_client tegra234_mc_clients[] = {
},
},
}, {
+ .id = TEGRA234_MEMORY_CLIENT_VIW,
+ .name = "viw",
+ .bpmp_id = TEGRA_ICC_BPMP_VI,
+ .type = TEGRA_ICC_ISO_VI,
+ .sid = TEGRA234_SID_ISO_VI,
+ .regs = {
+ .sid = {
+ .override = 0x390,
+ .security = 0x394,
+ },
+ },
+ }, {
.id = TEGRA234_MEMORY_CLIENT_NVDECSRD,
.name = "nvdecsrd",
.bpmp_id = TEGRA_ICC_BPMP_NVDEC,
@@ -622,6 +634,30 @@ static const struct tegra_mc_client tegra234_mc_clients[] = {
},
},
}, {
+ .id = TEGRA234_MEMORY_CLIENT_VIFALR,
+ .name = "vifalr",
+ .bpmp_id = TEGRA_ICC_BPMP_VIFAL,
+ .type = TEGRA_ICC_ISO_VIFAL,
+ .sid = TEGRA234_SID_ISO_VIFALC,
+ .regs = {
+ .sid = {
+ .override = 0x5e0,
+ .security = 0x5e4,
+ },
+ },
+ }, {
+ .id = TEGRA234_MEMORY_CLIENT_VIFALW,
+ .name = "vifalw",
+ .bpmp_id = TEGRA_ICC_BPMP_VIFAL,
+ .type = TEGRA_ICC_ISO_VIFAL,
+ .sid = TEGRA234_SID_ISO_VIFALC,
+ .regs = {
+ .sid = {
+ .override = 0x5e8,
+ .security = 0x5ec,
+ },
+ },
+ }, {
.id = TEGRA234_MEMORY_CLIENT_DLA0RDA,
.name = "dla0rda",
.sid = TEGRA234_SID_NVDLA0,
@@ -702,6 +738,30 @@ static const struct tegra_mc_client tegra234_mc_clients[] = {
},
},
}, {
+ .id = TEGRA234_MEMORY_CLIENT_RCER,
+ .name = "rcer",
+ .bpmp_id = TEGRA_ICC_BPMP_RCE,
+ .type = TEGRA_ICC_NISO,
+ .sid = TEGRA234_SID_RCE,
+ .regs = {
+ .sid = {
+ .override = 0x690,
+ .security = 0x694,
+ },
+ },
+ }, {
+ .id = TEGRA234_MEMORY_CLIENT_RCEW,
+ .name = "rcew",
+ .bpmp_id = TEGRA_ICC_BPMP_RCE,
+ .type = TEGRA_ICC_NISO,
+ .sid = TEGRA234_SID_RCE,
+ .regs = {
+ .sid = {
+ .override = 0x698,
+ .security = 0x69c,
+ },
+ },
+ }, {
.id = TEGRA234_MEMORY_CLIENT_PCIE0R,
.name = "pcie0r",
.bpmp_id = TEGRA_ICC_BPMP_PCIE_0,
@@ -986,6 +1046,10 @@ static int tegra234_mc_icc_set(struct icc_node *src, struct icc_node *dst)
msg.rx.data = &bwmgr_resp;
msg.rx.size = sizeof(bwmgr_resp);
+ if (pclient->bpmp_id >= TEGRA_ICC_BPMP_CPU_CLUSTER0 &&
+ pclient->bpmp_id <= TEGRA_ICC_BPMP_CPU_CLUSTER2)
+ msg.flags = TEGRA_BPMP_MESSAGE_RESET;
+
ret = tegra_bpmp_transfer(mc->bpmp, &msg);
if (ret < 0) {
dev_err(mc->dev, "BPMP transfer failed: %d\n", ret);
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 21cb2a786058..e77eb8b0eb12 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -66,7 +66,7 @@ struct jmb38x_ms_host {
struct jmb38x_ms {
struct pci_dev *pdev;
int host_cnt;
- struct memstick_host *hosts[];
+ struct memstick_host *hosts[] __counted_by(host_cnt);
};
#define BLOCK_COUNT_MASK 0xffff0000
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index cadd4a820c03..f37c4b8380ae 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -166,7 +166,7 @@ config ENCLOSURE_SERVICES
config SGI_XP
tristate "Support communication between SGI SSIs"
depends on NET
- depends on (IA64_SGI_UV || X86_UV) && SMP
+ depends on X86_UV && SMP
depends on X86_64 || BROKEN
select SGI_GRU if X86_64 && SMP
help
diff --git a/drivers/misc/sgi-gru/gru.h b/drivers/misc/sgi-gru/gru.h
index 3ad76cd18b4b..6ae045037219 100644
--- a/drivers/misc/sgi-gru/gru.h
+++ b/drivers/misc/sgi-gru/gru.h
@@ -30,9 +30,7 @@
/*
* Size used to map GRU GSeg
*/
-#if defined(CONFIG_IA64)
-#define GRU_GSEG_PAGESIZE (256 * 1024UL)
-#elif defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_64)
#define GRU_GSEG_PAGESIZE (256 * 1024UL) /* ZZZ 2MB ??? */
#else
#error "Unsupported architecture"
diff --git a/drivers/misc/sgi-gru/gru_instructions.h b/drivers/misc/sgi-gru/gru_instructions.h
index 04d5170ac149..da5eb9edf9ec 100644
--- a/drivers/misc/sgi-gru/gru_instructions.h
+++ b/drivers/misc/sgi-gru/gru_instructions.h
@@ -29,17 +29,7 @@ extern void gru_wait_abort_proc(void *cb);
* Architecture dependent functions
*/
-#if defined(CONFIG_IA64)
-#include <linux/compiler.h>
-#include <asm/intrinsics.h>
-#define __flush_cache(p) ia64_fc((unsigned long)p)
-/* Use volatile on IA64 to ensure ordering via st4.rel */
-#define gru_ordered_store_ulong(p, v) \
- do { \
- barrier(); \
- *((volatile unsigned long *)(p)) = v; /* force st.rel */ \
- } while (0)
-#elif defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_64)
#include <asm/cacheflush.h>
#define __flush_cache(p) clflush(p)
#define gru_ordered_store_ulong(p, v) \
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index a3d659c11cc4..e755690c9805 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -337,72 +337,6 @@ static unsigned long gru_chiplet_cpu_to_mmr(int chiplet, int cpu, int *corep)
return mmr;
}
-#ifdef CONFIG_IA64
-
-static int gru_irq_count[GRU_CHIPLETS_PER_BLADE];
-
-static void gru_noop(struct irq_data *d)
-{
-}
-
-static struct irq_chip gru_chip[GRU_CHIPLETS_PER_BLADE] = {
- [0 ... GRU_CHIPLETS_PER_BLADE - 1] {
- .irq_mask = gru_noop,
- .irq_unmask = gru_noop,
- .irq_ack = gru_noop
- }
-};
-
-static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name,
- irq_handler_t irq_handler, int cpu, int blade)
-{
- unsigned long mmr;
- int irq = IRQ_GRU + chiplet;
- int ret, core;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr == 0)
- return 0;
-
- if (gru_irq_count[chiplet] == 0) {
- gru_chip[chiplet].name = irq_name;
- ret = irq_set_chip(irq, &gru_chip[chiplet]);
- if (ret) {
- printk(KERN_ERR "%s: set_irq_chip failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -ret);
- return ret;
- }
-
- ret = request_irq(irq, irq_handler, 0, irq_name, NULL);
- if (ret) {
- printk(KERN_ERR "%s: request_irq failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -ret);
- return ret;
- }
- }
- gru_irq_count[chiplet]++;
-
- return 0;
-}
-
-static void gru_chiplet_teardown_tlb_irq(int chiplet, int cpu, int blade)
-{
- unsigned long mmr;
- int core, irq = IRQ_GRU + chiplet;
-
- if (gru_irq_count[chiplet] == 0)
- return;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr == 0)
- return;
-
- if (--gru_irq_count[chiplet] == 0)
- free_irq(irq, NULL);
-}
-
-#elif defined CONFIG_X86_64
-
static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name,
irq_handler_t irq_handler, int cpu, int blade)
{
@@ -447,8 +381,6 @@ static void gru_chiplet_teardown_tlb_irq(int chiplet, int cpu, int blade)
}
}
-#endif
-
static void gru_teardown_tlb_irqs(void)
{
int blade;
@@ -514,12 +446,8 @@ static int __init gru_init(void)
if (!gru_supported())
return 0;
-#if defined CONFIG_IA64
- gru_start_paddr = 0xd000000000UL; /* ZZZZZZZZZZZZZZZZZZZ fixme */
-#else
gru_start_paddr = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG) &
0x7fffffffffffUL;
-#endif
gru_start_vaddr = __va(gru_start_paddr);
gru_end_paddr = gru_start_paddr + GRU_MAX_BLADES * GRU_SIZE;
printk(KERN_INFO "GRU space: 0x%lx - 0x%lx\n",
diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c
index 1d75d5e540bc..695316a83b01 100644
--- a/drivers/misc/sgi-gru/gruhandles.c
+++ b/drivers/misc/sgi-gru/gruhandles.c
@@ -11,16 +11,10 @@
#include "grutables.h"
/* 10 sec */
-#ifdef CONFIG_IA64
-#include <asm/processor.h>
-#define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
-#define CLKS2NSEC(c) ((c) *1000000000 / local_cpu_data->itc_freq)
-#else
#include <linux/sync_core.h>
#include <asm/tsc.h>
#define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
#define CLKS2NSEC(c) ((c) * 1000000 / tsc_khz)
-#endif
/* Extract the status field from a kernel handle */
#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index 4eb4b9455139..0f5b09e290c8 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -41,16 +41,12 @@ struct device *grudev = &gru_device;
*/
int gru_cpu_fault_map_id(void)
{
-#ifdef CONFIG_IA64
- return uv_blade_processor_id() % GRU_NUM_TFM;
-#else
int cpu = smp_processor_id();
int id, core;
core = uv_cpu_core_number(cpu);
id = core + UV_MAX_INT_CORES * uv_cpu_socket_number(cpu);
return id;
-#endif
}
/*--------- ASID Management -------------------------------------------
diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h
index f1336f43d3bd..3185711beb07 100644
--- a/drivers/misc/sgi-xp/xp.h
+++ b/drivers/misc/sgi-xp/xp.h
@@ -16,7 +16,7 @@
#include <linux/mutex.h>
-#if defined CONFIG_X86_UV || defined CONFIG_IA64_SGI_UV
+#if defined CONFIG_X86_UV
#include <asm/uv/uv.h>
#endif
diff --git a/drivers/misc/sgi-xp/xp_uv.c b/drivers/misc/sgi-xp/xp_uv.c
index 19fc7076af27..3faa7eadf679 100644
--- a/drivers/misc/sgi-xp/xp_uv.c
+++ b/drivers/misc/sgi-xp/xp_uv.c
@@ -18,8 +18,6 @@
#include <asm/uv/uv_hub.h>
#if defined CONFIG_X86_64
#include <asm/uv/bios.h>
-#elif defined CONFIG_IA64_SGI_UV
-#include <asm/sn/sn_sal.h>
#endif
#include "../sgi-gru/grukservices.h"
#include "xp.h"
@@ -99,17 +97,6 @@ xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
"UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
return xpBiosError;
}
-
-#elif defined CONFIG_IA64_SGI_UV
- u64 nasid_array;
-
- ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
- &nasid_array);
- if (ret != 0) {
- dev_err(xp, "sn_change_memprotect(,, "
- "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
- return xpSalError;
- }
#else
#error not a supported configuration
#endif
@@ -129,17 +116,6 @@ xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
"UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
return xpBiosError;
}
-
-#elif defined CONFIG_IA64_SGI_UV
- u64 nasid_array;
-
- ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
- &nasid_array);
- if (ret != 0) {
- dev_err(xp, "sn_change_memprotect(,, "
- "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
- return xpSalError;
- }
#else
#error not a supported configuration
#endif
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 6da509d692bb..61b66e318488 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -110,7 +110,6 @@ static struct ctl_table xpc_sys_xpc_hb[] = {
.proc_handler = proc_dointvec_minmax,
.extra1 = &xpc_hb_check_min_interval,
.extra2 = &xpc_hb_check_max_interval},
- {}
};
static struct ctl_table xpc_sys_xpc[] = {
{
@@ -121,7 +120,6 @@ static struct ctl_table xpc_sys_xpc[] = {
.proc_handler = proc_dointvec_minmax,
.extra1 = &xpc_disengage_min_timelimit,
.extra2 = &xpc_disengage_max_timelimit},
- {}
};
static struct ctl_table_header *xpc_sysctl;
@@ -1155,36 +1153,6 @@ xpc_die_deactivate(void)
static int
xpc_system_die(struct notifier_block *nb, unsigned long event, void *_die_args)
{
-#ifdef CONFIG_IA64 /* !!! temporary kludge */
- switch (event) {
- case DIE_MACHINE_RESTART:
- case DIE_MACHINE_HALT:
- xpc_die_deactivate();
- break;
-
- case DIE_KDEBUG_ENTER:
- /* Should lack of heartbeat be ignored by other partitions? */
- if (!xpc_kdebug_ignore)
- break;
-
- fallthrough;
- case DIE_MCA_MONARCH_ENTER:
- case DIE_INIT_MONARCH_ENTER:
- xpc_arch_ops.offline_heartbeat();
- break;
-
- case DIE_KDEBUG_LEAVE:
- /* Is lack of heartbeat being ignored by other partitions? */
- if (!xpc_kdebug_ignore)
- break;
-
- fallthrough;
- case DIE_MCA_MONARCH_LEAVE:
- case DIE_INIT_MONARCH_LEAVE:
- xpc_arch_ops.online_heartbeat();
- break;
- }
-#else
struct die_args *die_args = _die_args;
switch (event) {
@@ -1206,7 +1174,6 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *_die_args)
default:
xpc_die_deactivate();
}
-#endif
return NOTIFY_DONE;
}
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index fff522d347e3..2f03a7080d96 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -24,34 +24,12 @@
#include <linux/slab.h>
#include <linux/numa.h>
#include <asm/uv/uv_hub.h>
-#if defined CONFIG_X86_64
#include <asm/uv/bios.h>
#include <asm/uv/uv_irq.h>
-#elif defined CONFIG_IA64_SGI_UV
-#include <asm/sn/intr.h>
-#include <asm/sn/sn_sal.h>
-#endif
#include "../sgi-gru/gru.h"
#include "../sgi-gru/grukservices.h"
#include "xpc.h"
-#if defined CONFIG_IA64_SGI_UV
-struct uv_IO_APIC_route_entry {
- __u64 vector : 8,
- delivery_mode : 3,
- dest_mode : 1,
- delivery_status : 1,
- polarity : 1,
- __reserved_1 : 1,
- trigger : 1,
- mask : 1,
- __reserved_2 : 15,
- dest : 32;
-};
-
-#define sn_partition_id 0
-#endif
-
static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
#define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES)
@@ -113,7 +91,6 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
{
int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
-#if defined CONFIG_X86_64
mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset,
UV_AFFINITY_CPU);
if (mq->irq < 0)
@@ -121,40 +98,13 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
-#elif defined CONFIG_IA64_SGI_UV
- if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0)
- mq->irq = SGI_XPC_ACTIVATE;
- else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0)
- mq->irq = SGI_XPC_NOTIFY;
- else
- return -EINVAL;
-
- mq->mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
- uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mq->mmr_value);
-#else
- #error not a supported configuration
-#endif
-
return 0;
}
static void
xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq)
{
-#if defined CONFIG_X86_64
uv_teardown_irq(mq->irq);
-
-#elif defined CONFIG_IA64_SGI_UV
- int mmr_pnode;
- unsigned long mmr_value;
-
- mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
- mmr_value = 1UL << 16;
-
- uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
-#else
- #error not a supported configuration
-#endif
}
static int
@@ -162,17 +112,6 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
{
int ret;
-#if defined CONFIG_IA64_SGI_UV
- int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
-
- ret = sn_mq_watchlist_alloc(mmr_pnode, (void *)uv_gpa(mq->address),
- mq->order, &mq->mmr_offset);
- if (ret < 0) {
- dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
- ret);
- return -EBUSY;
- }
-#elif defined CONFIG_X86_64
ret = uv_bios_mq_watchlist_alloc(uv_gpa(mq->address),
mq->order, &mq->mmr_offset);
if (ret < 0) {
@@ -180,9 +119,6 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
"ret=%d\n", ret);
return ret;
}
-#else
- #error not a supported configuration
-#endif
mq->watchlist_num = ret;
return 0;
@@ -194,15 +130,8 @@ xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq)
int ret;
int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
-#if defined CONFIG_X86_64
ret = uv_bios_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
BUG_ON(ret != BIOS_STATUS_SUCCESS);
-#elif defined CONFIG_IA64_SGI_UV
- ret = sn_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
- BUG_ON(ret != SALRET_OK);
-#else
- #error not a supported configuration
-#endif
}
static struct xpc_gru_mq_uv *
@@ -786,7 +715,6 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
s64 status;
enum xp_retval ret;
-#if defined CONFIG_X86_64
status = uv_bios_reserved_page_pa((u64)buf, cookie, (u64 *)rp_pa,
(u64 *)len);
if (status == BIOS_STATUS_SUCCESS)
@@ -796,19 +724,6 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
else
ret = xpBiosError;
-#elif defined CONFIG_IA64_SGI_UV
- status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len);
- if (status == SALRET_OK)
- ret = xpSuccess;
- else if (status == SALRET_MORE_PASSES)
- ret = xpNeedMoreInfo;
- else
- ret = xpSalError;
-
-#else
- #error not a supported configuration
-#endif
-
return ret;
}
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 2c97b94aab23..1642ea72d22c 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -12,9 +12,12 @@
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/fault-inject.h>
+#include <linux/time.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
#include "core.h"
#include "card.h"
@@ -298,6 +301,49 @@ static const struct file_operations mmc_err_stats_fops = {
.release = single_release,
};
+static int mmc_caps_get(void *data, u64 *val)
+{
+ *val = *(u32 *)data;
+ return 0;
+}
+
+static int mmc_caps_set(void *data, u64 val)
+{
+ u32 *caps = data;
+ u32 diff = *caps ^ val;
+ u32 allowed = MMC_CAP_AGGRESSIVE_PM |
+ MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_MMC_HIGHSPEED |
+ MMC_CAP_UHS |
+ MMC_CAP_DDR;
+
+ if (diff & ~allowed)
+ return -EINVAL;
+
+ *caps = val;
+
+ return 0;
+}
+
+static int mmc_caps2_set(void *data, u64 val)
+{
+ u32 allowed = MMC_CAP2_HSX00_1_8V | MMC_CAP2_HSX00_1_2V;
+ u32 *caps = data;
+ u32 diff = *caps ^ val;
+
+ if (diff & ~allowed)
+ return -EINVAL;
+
+ *caps = val;
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(mmc_caps_fops, mmc_caps_get, mmc_caps_set,
+ "0x%08llx\n");
+DEFINE_DEBUGFS_ATTRIBUTE(mmc_caps2_fops, mmc_caps_get, mmc_caps2_set,
+ "0x%08llx\n");
+
void mmc_add_host_debugfs(struct mmc_host *host)
{
struct dentry *root;
@@ -306,8 +352,9 @@ void mmc_add_host_debugfs(struct mmc_host *host)
host->debugfs_root = root;
debugfs_create_file("ios", S_IRUSR, root, host, &mmc_ios_fops);
- debugfs_create_x32("caps", S_IRUSR, root, &host->caps);
- debugfs_create_x32("caps2", S_IRUSR, root, &host->caps2);
+ debugfs_create_file("caps", 0600, root, &host->caps, &mmc_caps_fops);
+ debugfs_create_file("caps2", 0600, root, &host->caps2,
+ &mmc_caps2_fops);
debugfs_create_file_unsafe("clock", S_IRUSR | S_IWUSR, root, host,
&mmc_clock_fops);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 4a4bab9aa726..8180983bd402 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -419,7 +419,6 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
card->ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT];
card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
- mmc_select_card_type(card);
card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT];
card->ext_csd.raw_erase_timeout_mult =
@@ -1732,6 +1731,12 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
mmc_set_erase_size(card);
}
+ /*
+ * Reselect the card type since host caps could have been changed when
+ * debugging even if the card is not new.
+ */
+ mmc_select_card_type(card);
+
/* Enable ERASE_GRP_DEF. This bit is lost after a reset or power off. */
if (card->ext_csd.rev >= 3) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
index b396e3900717..a0a2412f62a7 100644
--- a/drivers/mmc/core/queue.c
+++ b/drivers/mmc/core/queue.c
@@ -260,11 +260,7 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
}
break;
case MMC_ISSUE_ASYNC:
- /*
- * For MMC host software queue, we only allow 2 requests in
- * flight to avoid a long latency.
- */
- if (host->hsq_enabled && mq->in_flight[issue_type] > 2) {
+ if (host->hsq_enabled && mq->in_flight[issue_type] > host->hsq_depth) {
spin_unlock_irq(&mq->lock);
return BLK_STS_RESOURCE;
}
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 554e67103c1a..58bd5fe4cd25 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -429,6 +429,14 @@ config MMC_SDHCI_IPROC
If unsure, say N.
+config MMC_SDHCI_NPCM
+ tristate "Secure Digital Host Controller Interface support for NPCM"
+ depends on ARCH_NPCM || COMPILE_TEST
+ depends on MMC_SDHCI_PLTFM
+ help
+ This provides support for the SD/eMMC controller found in
+ NPCM BMC family SoCs.
+
config MMC_MESON_GX
tristate "Amlogic S905/GX*/AXG SD/MMC Host Controller support"
depends on ARCH_MESON|| COMPILE_TEST
@@ -677,9 +685,9 @@ config MMC_SDHI_SYS_DMAC
config MMC_SDHI_INTERNAL_DMAC
tristate "DMA for SDHI SD/SDIO controllers using on-chip bus mastering"
- depends on ARM64 || ARCH_R7S9210 || ARCH_R8A77470 || COMPILE_TEST
+ depends on ARCH_RENESAS || COMPILE_TEST
depends on MMC_SDHI
- default MMC_SDHI if (ARM64 || ARCH_R7S9210 || ARCH_R8A77470)
+ default MMC_SDHI if ARCH_RENESAS
help
This provides DMA support for SDHI SD/SDIO controllers
using on-chip bus mastering. This supports the controllers
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index a693fa3d3f1c..d0be4465f3ec 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -89,6 +89,7 @@ obj-$(CONFIG_MMC_SDHCI_OF_DWCMSHC) += sdhci-of-dwcmshc.o
obj-$(CONFIG_MMC_SDHCI_OF_SPARX5) += sdhci-of-sparx5.o
obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o
obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o
+obj-$(CONFIG_MMC_SDHCI_NPCM) += sdhci-npcm.o
obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o
obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o
obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 535783c43105..dba826db739a 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -227,6 +227,7 @@ struct mci_slot_pdata {
/**
* struct mci_platform_data - board-specific MMC/SDcard configuration
* @dma_slave: DMA slave interface to use in data transfers.
+ * @dma_filter: Filtering function to filter the DMA channel
* @slot: Per-slot configuration data.
*/
struct mci_platform_data {
@@ -674,8 +675,10 @@ atmci_of_init(struct platform_device *pdev)
"cd", GPIOD_IN, "cd-gpios");
err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].detect_pin);
if (err) {
- if (err != -ENOENT)
+ if (err != -ENOENT) {
+ of_node_put(cnp);
return ERR_PTR(err);
+ }
pdata->slot[slot_id].detect_pin = NULL;
}
@@ -687,8 +690,10 @@ atmci_of_init(struct platform_device *pdev)
"wp", GPIOD_IN, "wp-gpios");
err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].wp_pin);
if (err) {
- if (err != -ENOENT)
+ if (err != -ENOENT) {
+ of_node_put(cnp);
return ERR_PTR(err);
+ }
pdata->slot[slot_id].wp_pin = NULL;
}
}
diff --git a/drivers/mmc/host/dw_mmc-starfive.c b/drivers/mmc/host/dw_mmc-starfive.c
index fd05a648a8bb..b4d81ef0f3af 100644
--- a/drivers/mmc/host/dw_mmc-starfive.c
+++ b/drivers/mmc/host/dw_mmc-starfive.c
@@ -5,6 +5,7 @@
* Copyright (c) 2022 StarFive Technology Co., Ltd.
*/
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/mfd/syscon.h>
@@ -20,13 +21,7 @@
#define ALL_INT_CLR 0x1ffff
#define MAX_DELAY_CHAIN 32
-struct starfive_priv {
- struct device *dev;
- struct regmap *reg_syscon;
- u32 syscon_offset;
- u32 syscon_shift;
- u32 syscon_mask;
-};
+#define STARFIVE_SMPL_PHASE GENMASK(20, 16)
static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *ios)
{
@@ -44,117 +39,65 @@ static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *ios)
}
}
+static void dw_mci_starfive_set_sample_phase(struct dw_mci *host, u32 smpl_phase)
+{
+ /* change driver phase and sample phase */
+ u32 reg_value = mci_readl(host, UHS_REG_EXT);
+
+ /* In UHS_REG_EXT, only 5 bits valid in DRV_PHASE and SMPL_PHASE */
+ reg_value &= ~STARFIVE_SMPL_PHASE;
+ reg_value |= FIELD_PREP(STARFIVE_SMPL_PHASE, smpl_phase);
+ mci_writel(host, UHS_REG_EXT, reg_value);
+
+ /* We should delay 1ms wait for timing setting finished. */
+ mdelay(1);
+}
+
static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
u32 opcode)
{
static const int grade = MAX_DELAY_CHAIN;
struct dw_mci *host = slot->host;
- struct starfive_priv *priv = host->priv;
- int rise_point = -1, fall_point = -1;
- int err, prev_err = 0;
- int i;
- bool found = 0;
- u32 regval;
-
- /*
- * Use grade as the max delay chain, and use the rise_point and
- * fall_point to ensure the best sampling point of a data input
- * signals.
- */
- for (i = 0; i < grade; i++) {
- regval = i << priv->syscon_shift;
- err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
- priv->syscon_mask, regval);
- if (err)
- return err;
+ int smpl_phase, smpl_raise = -1, smpl_fall = -1;
+ int ret;
+
+ for (smpl_phase = 0; smpl_phase < grade; smpl_phase++) {
+ dw_mci_starfive_set_sample_phase(host, smpl_phase);
mci_writel(host, RINTSTS, ALL_INT_CLR);
- err = mmc_send_tuning(slot->mmc, opcode, NULL);
- if (!err)
- found = 1;
+ ret = mmc_send_tuning(slot->mmc, opcode, NULL);
- if (i > 0) {
- if (err && !prev_err)
- fall_point = i - 1;
- if (!err && prev_err)
- rise_point = i;
+ if (!ret && smpl_raise < 0) {
+ smpl_raise = smpl_phase;
+ } else if (ret && smpl_raise >= 0) {
+ smpl_fall = smpl_phase - 1;
+ break;
}
-
- if (rise_point != -1 && fall_point != -1)
- goto tuning_out;
-
- prev_err = err;
- err = 0;
}
-tuning_out:
- if (found) {
- if (rise_point == -1)
- rise_point = 0;
- if (fall_point == -1)
- fall_point = grade - 1;
- if (fall_point < rise_point) {
- if ((rise_point + fall_point) >
- (grade - 1))
- i = fall_point / 2;
- else
- i = (rise_point + grade - 1) / 2;
- } else {
- i = (rise_point + fall_point) / 2;
- }
-
- regval = i << priv->syscon_shift;
- err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
- priv->syscon_mask, regval);
- if (err)
- return err;
- mci_writel(host, RINTSTS, ALL_INT_CLR);
+ if (smpl_phase >= grade)
+ smpl_fall = grade - 1;
- dev_info(host->dev, "Found valid delay chain! use it [delay=%d]\n", i);
- } else {
+ if (smpl_raise < 0) {
+ smpl_phase = 0;
dev_err(host->dev, "No valid delay chain! use default\n");
- err = -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
- mci_writel(host, RINTSTS, ALL_INT_CLR);
- return err;
-}
-
-static int dw_mci_starfive_parse_dt(struct dw_mci *host)
-{
- struct of_phandle_args args;
- struct starfive_priv *priv;
- int ret;
-
- priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
+ smpl_phase = (smpl_raise + smpl_fall) / 2;
+ dev_dbg(host->dev, "Found valid delay chain! use it [delay=%d]\n", smpl_phase);
+ ret = 0;
- ret = of_parse_phandle_with_fixed_args(host->dev->of_node,
- "starfive,sysreg", 3, 0, &args);
- if (ret) {
- dev_err(host->dev, "Failed to parse starfive,sysreg\n");
- return -EINVAL;
- }
-
- priv->reg_syscon = syscon_node_to_regmap(args.np);
- of_node_put(args.np);
- if (IS_ERR(priv->reg_syscon))
- return PTR_ERR(priv->reg_syscon);
-
- priv->syscon_offset = args.args[0];
- priv->syscon_shift = args.args[1];
- priv->syscon_mask = args.args[2];
-
- host->priv = priv;
-
- return 0;
+out:
+ dw_mci_starfive_set_sample_phase(host, smpl_phase);
+ mci_writel(host, RINTSTS, ALL_INT_CLR);
+ return ret;
}
static const struct dw_mci_drv_data starfive_data = {
.common_caps = MMC_CAP_CMD23,
.set_ios = dw_mci_starfive_set_ios,
- .parse_dt = dw_mci_starfive_parse_dt,
.execute_tuning = dw_mci_starfive_execute_tuning,
};
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index f379ce5b582d..6a45991ca056 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -18,9 +18,10 @@
#include <linux/mmc/host.h>
#include <linux/mmc/slot-gpio.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/scatterlist.h>
@@ -1040,7 +1041,6 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
int ret;
struct mmc_host *mmc;
struct jz4740_mmc_host *host;
- const struct of_device_id *match;
mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev);
if (!mmc) {
@@ -1050,13 +1050,8 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
host = mmc_priv(mmc);
- match = of_match_device(jz4740_mmc_of_match, &pdev->dev);
- if (match) {
- host->version = (enum jz4740_mmc_version)match->data;
- } else {
- /* JZ4740 should be the only one using legacy probe */
- host->version = JZ_MMC_JZ4740;
- }
+ /* Default if no match is JZ4740 */
+ host->version = (enum jz4740_mmc_version)device_get_match_data(&pdev->dev);
ret = mmc_of_parse(mmc);
if (ret) {
@@ -1200,7 +1195,7 @@ static struct platform_driver jz4740_mmc_driver = {
.driver = {
.name = "jz4740-mmc",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
- .of_match_table = of_match_ptr(jz4740_mmc_of_match),
+ .of_match_table = jz4740_mmc_of_match,
.pm = pm_sleep_ptr(&jz4740_mmc_pm_ops),
},
};
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index 9837dab096e6..c7c067b9415a 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -801,7 +801,6 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
cmd_cfg |= FIELD_PREP(CMD_CFG_CMD_INDEX_MASK, cmd->opcode);
cmd_cfg |= CMD_CFG_OWNER; /* owned by CPU */
- cmd_cfg |= CMD_CFG_ERROR; /* stop in case of error */
meson_mmc_set_response_bits(cmd, &cmd_cfg);
diff --git a/drivers/mmc/host/mmc_hsq.c b/drivers/mmc/host/mmc_hsq.c
index 424dc7b07858..79836705c176 100644
--- a/drivers/mmc/host/mmc_hsq.c
+++ b/drivers/mmc/host/mmc_hsq.c
@@ -21,6 +21,25 @@ static void mmc_hsq_retry_handler(struct work_struct *work)
mmc->ops->request(mmc, hsq->mrq);
}
+static void mmc_hsq_modify_threshold(struct mmc_hsq *hsq)
+{
+ struct mmc_host *mmc = hsq->mmc;
+ struct mmc_request *mrq;
+ unsigned int tag, need_change = 0;
+
+ mmc->hsq_depth = HSQ_NORMAL_DEPTH;
+ for (tag = 0; tag < HSQ_NUM_SLOTS; tag++) {
+ mrq = hsq->slot[tag].mrq;
+ if (mrq && mrq->data &&
+ (mrq->data->blksz * mrq->data->blocks == 4096) &&
+ (mrq->data->flags & MMC_DATA_WRITE) &&
+ (++need_change == 2)) {
+ mmc->hsq_depth = HSQ_PERFORMANCE_DEPTH;
+ break;
+ }
+ }
+}
+
static void mmc_hsq_pump_requests(struct mmc_hsq *hsq)
{
struct mmc_host *mmc = hsq->mmc;
@@ -42,6 +61,8 @@ static void mmc_hsq_pump_requests(struct mmc_hsq *hsq)
return;
}
+ mmc_hsq_modify_threshold(hsq);
+
slot = &hsq->slot[hsq->next_tag];
hsq->mrq = slot->mrq;
hsq->qcnt--;
@@ -337,6 +358,7 @@ int mmc_hsq_init(struct mmc_hsq *hsq, struct mmc_host *mmc)
hsq->mmc = mmc;
hsq->mmc->cqe_private = hsq;
mmc->cqe_ops = &mmc_hsq_ops;
+ mmc->hsq_depth = HSQ_NORMAL_DEPTH;
for (i = 0; i < HSQ_NUM_SLOTS; i++)
hsq->tag_slot[i] = HSQ_INVALID_TAG;
diff --git a/drivers/mmc/host/mmc_hsq.h b/drivers/mmc/host/mmc_hsq.h
index 1808024fc6c5..dd352a6ac32a 100644
--- a/drivers/mmc/host/mmc_hsq.h
+++ b/drivers/mmc/host/mmc_hsq.h
@@ -5,6 +5,17 @@
#define HSQ_NUM_SLOTS 64
#define HSQ_INVALID_TAG HSQ_NUM_SLOTS
+/*
+ * For MMC host software queue, we only allow 2 requests in
+ * flight to avoid a long latency.
+ */
+#define HSQ_NORMAL_DEPTH 2
+/*
+ * For 4k random writes, we allow hsq_depth to increase to 5
+ * for better performance.
+ */
+#define HSQ_PERFORMANCE_DEPTH 5
+
struct hsq_slot {
struct mmc_request *mrq;
};
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index dda756a56379..e967cca7a16f 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -249,6 +249,7 @@ static struct variant_data variant_stm32 = {
.f_max = 48000000,
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
+ .dma_flow_controller = true,
.init = mmci_variant_init,
};
@@ -1015,7 +1016,7 @@ static int _mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data,
.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
.src_maxburst = variant->fifohalfsize >> 2, /* # of words */
.dst_maxburst = variant->fifohalfsize >> 2, /* # of words */
- .device_fc = false,
+ .device_fc = variant->dma_flow_controller,
};
struct dma_chan *chan;
struct dma_device *device;
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 253197f132fc..34d9897c289b 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -332,6 +332,7 @@ enum mmci_busy_state {
* @opendrain: bitmask identifying the OPENDRAIN bit inside MMCIPOWER register
* @dma_lli: true if variant has dma link list feature.
* @stm32_idmabsize_mask: stm32 sdmmc idma buffer size.
+ * @dma_flow_controller: use peripheral as flow controller for DMA.
*/
struct variant_data {
unsigned int clkreg;
@@ -378,6 +379,7 @@ struct variant_data {
u8 dma_lli:1;
u32 stm32_idmabsize_mask;
u32 stm32_idmabsize_align;
+ bool dma_flow_controller;
void (*init)(struct mmci_host *host);
};
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 3b8030f3552a..40a6e2f8145a 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1154,32 +1154,52 @@ static void esdhc_post_tuning(struct sdhci_host *host)
writel(reg, host->ioaddr + ESDHC_MIX_CTRL);
}
+/*
+ * find the largest pass window, and use the average delay of this
+ * largest window to get the best timing.
+ */
static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
{
int min, max, avg, ret;
+ int win_length, target_min, target_max, target_win_length;
- /* find the mininum delay first which can pass tuning */
min = ESDHC_TUNE_CTRL_MIN;
- while (min < ESDHC_TUNE_CTRL_MAX) {
- esdhc_prepare_tuning(host, min);
- if (!mmc_send_tuning(host->mmc, opcode, NULL))
- break;
- min += ESDHC_TUNE_CTRL_STEP;
- }
-
- /* find the maxinum delay which can not pass tuning */
- max = min + ESDHC_TUNE_CTRL_STEP;
+ max = ESDHC_TUNE_CTRL_MIN;
+ target_win_length = 0;
while (max < ESDHC_TUNE_CTRL_MAX) {
- esdhc_prepare_tuning(host, max);
- if (mmc_send_tuning(host->mmc, opcode, NULL)) {
- max -= ESDHC_TUNE_CTRL_STEP;
- break;
+ /* find the mininum delay first which can pass tuning */
+ while (min < ESDHC_TUNE_CTRL_MAX) {
+ esdhc_prepare_tuning(host, min);
+ if (!mmc_send_tuning(host->mmc, opcode, NULL))
+ break;
+ min += ESDHC_TUNE_CTRL_STEP;
}
- max += ESDHC_TUNE_CTRL_STEP;
+
+ /* find the maxinum delay which can not pass tuning */
+ max = min + ESDHC_TUNE_CTRL_STEP;
+ while (max < ESDHC_TUNE_CTRL_MAX) {
+ esdhc_prepare_tuning(host, max);
+ if (mmc_send_tuning(host->mmc, opcode, NULL)) {
+ max -= ESDHC_TUNE_CTRL_STEP;
+ break;
+ }
+ max += ESDHC_TUNE_CTRL_STEP;
+ }
+
+ win_length = max - min + 1;
+ /* get the largest pass window */
+ if (win_length > target_win_length) {
+ target_win_length = win_length;
+ target_min = min;
+ target_max = max;
+ }
+
+ /* continue to find the next pass window */
+ min = max + ESDHC_TUNE_CTRL_STEP;
}
/* use average delay to get the best timing */
- avg = (min + max) / 2;
+ avg = (target_min + target_max) / 2;
esdhc_prepare_tuning(host, avg);
ret = mmc_send_tuning(host->mmc, opcode, NULL);
esdhc_post_tuning(host);
diff --git a/drivers/mmc/host/sdhci-npcm.c b/drivers/mmc/host/sdhci-npcm.c
new file mode 100644
index 000000000000..5bf9d18f364e
--- /dev/null
+++ b/drivers/mmc/host/sdhci-npcm.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NPCM SDHC MMC host controller driver.
+ *
+ * Copyright (c) 2023 Nuvoton Technology corporation.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include "sdhci-pltfm.h"
+
+static const struct sdhci_pltfm_data npcm7xx_sdhci_pdata = {
+ .quirks = SDHCI_QUIRK_DELAY_AFTER_POWER,
+ .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC |
+ SDHCI_QUIRK2_NO_1_8_V,
+};
+
+static const struct sdhci_pltfm_data npcm8xx_sdhci_pdata = {
+ .quirks = SDHCI_QUIRK_DELAY_AFTER_POWER,
+ .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC,
+};
+
+static int npcm_sdhci_probe(struct platform_device *pdev)
+{
+ const struct sdhci_pltfm_data *data;
+ struct sdhci_pltfm_host *pltfm_host;
+ struct device *dev = &pdev->dev;
+ struct sdhci_host *host;
+ u32 caps;
+ int ret;
+
+ data = of_device_get_match_data(dev);
+ if (!data)
+ return -EINVAL;
+
+ host = sdhci_pltfm_init(pdev, data, 0);
+ if (IS_ERR(host))
+ return PTR_ERR(host);
+
+ pltfm_host = sdhci_priv(host);
+
+ pltfm_host->clk = devm_clk_get_optional_enabled(dev, NULL);
+ if (IS_ERR(pltfm_host->clk)) {
+ ret = PTR_ERR(pltfm_host->clk);
+ goto err_sdhci;
+ }
+
+ caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+ if (caps & SDHCI_CAN_DO_8BIT)
+ host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+
+ ret = mmc_of_parse(host->mmc);
+ if (ret)
+ goto err_sdhci;
+
+ ret = sdhci_add_host(host);
+ if (ret)
+ goto err_sdhci;
+
+ return 0;
+
+err_sdhci:
+ sdhci_pltfm_free(pdev);
+ return ret;
+}
+
+static const struct of_device_id npcm_sdhci_of_match[] = {
+ { .compatible = "nuvoton,npcm750-sdhci", .data = &npcm7xx_sdhci_pdata },
+ { .compatible = "nuvoton,npcm845-sdhci", .data = &npcm8xx_sdhci_pdata },
+ { }
+};
+MODULE_DEVICE_TABLE(of, npcm_sdhci_of_match);
+
+static struct platform_driver npcm_sdhci_driver = {
+ .driver = {
+ .name = "npcm-sdhci",
+ .of_match_table = npcm_sdhci_of_match,
+ .pm = &sdhci_pltfm_pmops,
+ },
+ .probe = npcm_sdhci_probe,
+ .remove_new = sdhci_pltfm_remove,
+};
+module_platform_driver(npcm_sdhci_driver);
+
+MODULE_DESCRIPTION("NPCM Secure Digital Host Controller Interface driver");
+MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
index 7c14feb5db77..025b31aa712c 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -483,11 +483,12 @@ static int __intel_dsm(struct intel_host *intel_host, struct device *dev,
int err = 0;
size_t len;
- obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &intel_dsm_guid, 0, fn, NULL);
+ obj = acpi_evaluate_dsm_typed(ACPI_HANDLE(dev), &intel_dsm_guid, 0, fn, NULL,
+ ACPI_TYPE_BUFFER);
if (!obj)
return -EOPNOTSUPP;
- if (obj->type != ACPI_TYPE_BUFFER || obj->buffer.length < 1) {
+ if (obj->buffer.length < 1) {
err = -EINVAL;
goto out;
}
diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c
index 109d4b010f97..d83261e857a5 100644
--- a/drivers/mmc/host/sdhci-pci-gli.c
+++ b/drivers/mmc/host/sdhci-pci-gli.c
@@ -25,6 +25,9 @@
#define GLI_9750_WT_EN_ON 0x1
#define GLI_9750_WT_EN_OFF 0x0
+#define PCI_GLI_9750_PM_CTRL 0xFC
+#define PCI_GLI_9750_PM_STATE GENMASK(1, 0)
+
#define SDHCI_GLI_9750_CFG2 0x848
#define SDHCI_GLI_9750_CFG2_L1DLY GENMASK(28, 24)
#define GLI_9750_CFG2_L1DLY_VALUE 0x1F
@@ -536,8 +539,12 @@ static void sdhci_gl9750_set_clock(struct sdhci_host *host, unsigned int clock)
static void gl9750_hw_setting(struct sdhci_host *host)
{
+ struct sdhci_pci_slot *slot = sdhci_priv(host);
+ struct pci_dev *pdev;
u32 value;
+ pdev = slot->chip->pdev;
+
gl9750_wt_on(host);
value = sdhci_readl(host, SDHCI_GLI_9750_CFG2);
@@ -547,6 +554,13 @@ static void gl9750_hw_setting(struct sdhci_host *host)
GLI_9750_CFG2_L1DLY_VALUE);
sdhci_writel(host, value, SDHCI_GLI_9750_CFG2);
+ /* toggle PM state to allow GL9750 to enter ASPM L1.2 */
+ pci_read_config_dword(pdev, PCI_GLI_9750_PM_CTRL, &value);
+ value |= PCI_GLI_9750_PM_STATE;
+ pci_write_config_dword(pdev, PCI_GLI_9750_PM_CTRL, value);
+ value &= ~PCI_GLI_9750_PM_STATE;
+ pci_write_config_dword(pdev, PCI_GLI_9750_PM_CTRL, value);
+
gl9750_wt_off(host);
}
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index a72e123a585d..62753d72198a 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -19,7 +19,6 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/property.h>
-#include <linux/of.h>
#ifdef CONFIG_PPC
#include <asm/machdep.h>
#endif
@@ -56,19 +55,16 @@ static bool sdhci_wp_inverted(struct device *dev)
static void sdhci_get_compatibility(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct sdhci_host *host = platform_get_drvdata(pdev);
- struct device_node *np = pdev->dev.of_node;
-
- if (!np)
- return;
- if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
+ if (device_is_compatible(dev, "fsl,p2020-rev1-esdhc"))
host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
- if (of_device_is_compatible(np, "fsl,p2020-esdhc") ||
- of_device_is_compatible(np, "fsl,p1010-esdhc") ||
- of_device_is_compatible(np, "fsl,t4240-esdhc") ||
- of_device_is_compatible(np, "fsl,mpc8536-esdhc"))
+ if (device_is_compatible(dev, "fsl,p2020-esdhc") ||
+ device_is_compatible(dev, "fsl,p1010-esdhc") ||
+ device_is_compatible(dev, "fsl,t4240-esdhc") ||
+ device_is_compatible(dev, "fsl,mpc8536-esdhc"))
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
}
@@ -115,26 +111,21 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
{
struct sdhci_host *host;
void __iomem *ioaddr;
- int irq, ret;
+ int irq;
ioaddr = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(ioaddr)) {
- ret = PTR_ERR(ioaddr);
- goto err;
- }
+ if (IS_ERR(ioaddr))
+ return ERR_CAST(ioaddr);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto err;
- }
+ if (irq < 0)
+ return ERR_PTR(irq);
host = sdhci_alloc_host(&pdev->dev,
sizeof(struct sdhci_pltfm_host) + priv_size);
-
if (IS_ERR(host)) {
- ret = PTR_ERR(host);
- goto err;
+ dev_err(&pdev->dev, "%s failed %pe\n", __func__, host);
+ return ERR_CAST(host);
}
host->ioaddr = ioaddr;
@@ -152,9 +143,6 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
platform_set_drvdata(pdev, host);
return host;
-err:
- dev_err(&pdev->dev, "%s failed %d\n", __func__, ret);
- return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(sdhci_pltfm_init);
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index 9ec593d52f0f..de3f443f5fdc 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -512,7 +512,7 @@ static void new_system_port_status(struct vub300_mmc_host *vub300)
vub300->card_present = 1;
vub300->bus_width = 0;
if (disable_offload_processing)
- strncpy(vub300->vub_name, "EMPTY Processing Disabled",
+ strscpy(vub300->vub_name, "EMPTY Processing Disabled",
sizeof(vub300->vub_name));
else
vub300->vub_name[0] = 0;
@@ -1216,7 +1216,7 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300,
dev_err(&vub300->udev->dev,
"corrupt offload pseudocode in firmware %s\n",
vub300->vub_name);
- strncpy(vub300->vub_name, "corrupt offload pseudocode",
+ strscpy(vub300->vub_name, "corrupt offload pseudocode",
sizeof(vub300->vub_name));
return;
}
@@ -1250,7 +1250,7 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300,
"not enough memory for xfer buffer to send"
" INTERRUPT_PSEUDOCODE for %s %s\n", fw->data,
vub300->vub_name);
- strncpy(vub300->vub_name,
+ strscpy(vub300->vub_name,
"SDIO interrupt pseudocode download failed",
sizeof(vub300->vub_name));
return;
@@ -1259,7 +1259,7 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300,
dev_err(&vub300->udev->dev,
"corrupt interrupt pseudocode in firmware %s %s\n",
fw->data, vub300->vub_name);
- strncpy(vub300->vub_name, "corrupt interrupt pseudocode",
+ strscpy(vub300->vub_name, "corrupt interrupt pseudocode",
sizeof(vub300->vub_name));
return;
}
@@ -1293,7 +1293,7 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300,
"not enough memory for xfer buffer to send"
" TRANSFER_PSEUDOCODE for %s %s\n", fw->data,
vub300->vub_name);
- strncpy(vub300->vub_name,
+ strscpy(vub300->vub_name,
"SDIO transfer pseudocode download failed",
sizeof(vub300->vub_name));
return;
@@ -1302,7 +1302,7 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300,
dev_err(&vub300->udev->dev,
"corrupt transfer pseudocode in firmware %s %s\n",
fw->data, vub300->vub_name);
- strncpy(vub300->vub_name, "corrupt transfer pseudocode",
+ strscpy(vub300->vub_name, "corrupt transfer pseudocode",
sizeof(vub300->vub_name));
return;
}
@@ -1336,13 +1336,13 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300,
dev_err(&vub300->udev->dev,
"corrupt dynamic registers in firmware %s\n",
vub300->vub_name);
- strncpy(vub300->vub_name, "corrupt dynamic registers",
+ strscpy(vub300->vub_name, "corrupt dynamic registers",
sizeof(vub300->vub_name));
return;
}
copy_error_message:
- strncpy(vub300->vub_name, "SDIO pseudocode download failed",
+ strscpy(vub300->vub_name, "SDIO pseudocode download failed",
sizeof(vub300->vub_name));
}
@@ -1370,11 +1370,11 @@ static void download_offload_pseudocode(struct vub300_mmc_host *vub300)
vub300->vub_name);
retval = request_firmware(&fw, vub300->vub_name, &card->dev);
if (retval < 0) {
- strncpy(vub300->vub_name, "vub_default.bin",
+ strscpy(vub300->vub_name, "vub_default.bin",
sizeof(vub300->vub_name));
retval = request_firmware(&fw, vub300->vub_name, &card->dev);
if (retval < 0) {
- strncpy(vub300->vub_name,
+ strscpy(vub300->vub_name,
"no SDIO offload firmware found",
sizeof(vub300->vub_name));
} else {
@@ -1758,7 +1758,7 @@ static void vub300_cmndwork_thread(struct work_struct *work)
* has been already downloaded to the VUB300 chip
*/
} else if (0 == vub300->mmc->card->sdio_funcs) {
- strncpy(vub300->vub_name, "SD memory device",
+ strscpy(vub300->vub_name, "SD memory device",
sizeof(vub300->vub_name));
} else {
download_offload_pseudocode(vub300);
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 2d20be6ffb7e..53415e83821c 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -3449,5 +3449,6 @@ static void __exit amt_fini(void)
module_exit(amt_fini);
MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Driver for Automatic Multicast Tunneling (AMT)");
MODULE_AUTHOR("Taehee Yoo <ap420073@gmail.com>");
MODULE_ALIAS_RTNL_LINK("amt");
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index c4b1b0aa438a..768454aa36d6 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -202,4 +202,5 @@ static void __exit dummy_cleanup_module(void)
module_init(dummy_init_module);
module_exit(dummy_cleanup_module);
MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Dummy netdevice driver which discards all packets sent to it");
MODULE_ALIAS_RTNL_LINK(DRV_NAME);
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index ca3e4700a813..3c2efda916f1 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -607,4 +607,5 @@ static void __exit eql_cleanup_module(void)
module_init(eql_init_module);
module_exit(eql_cleanup_module);
+MODULE_DESCRIPTION("Equalizer Load-balancer for serial network interfaces");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 59896bbf9e73..5665d0c3668f 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -17054,7 +17054,7 @@ static u32 tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
!tg3_flag(tp, PCI_EXPRESS))
goto out;
-#if defined(CONFIG_PPC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC)
+#if defined(CONFIG_PPC64) || defined(CONFIG_PARISC)
goal = BOUNDARY_MULTI_CACHELINE;
#else
#if defined(CONFIG_SPARC64) || defined(CONFIG_ALPHA)
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index 627a93ce38ab..10b1e534030e 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -19,7 +19,6 @@
#include <linux/firmware.h>
#include <linux/if_vlan.h>
-/* Fix for IA64 */
#include <asm/checksum.h>
#include <net/ip6_checksum.h>
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 032c15b541ff..c3b7694a7485 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -363,6 +363,70 @@ static void fec_dump(struct net_device *ndev)
} while (bdp != txq->bd.base);
}
+/*
+ * Coldfire does not support DMA coherent allocations, and has historically used
+ * a band-aid with a manual flush in fec_enet_rx_queue.
+ */
+#if defined(CONFIG_COLDFIRE) && !defined(CONFIG_COLDFIRE_COHERENT_DMA)
+static void *fec_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp)
+{
+ return dma_alloc_noncoherent(dev, size, handle, DMA_BIDIRECTIONAL, gfp);
+}
+
+static void fec_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle)
+{
+ dma_free_noncoherent(dev, size, cpu_addr, handle, DMA_BIDIRECTIONAL);
+}
+#else /* !CONFIG_COLDFIRE || CONFIG_COLDFIRE_COHERENT_DMA */
+static void *fec_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp)
+{
+ return dma_alloc_coherent(dev, size, handle, gfp);
+}
+
+static void fec_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle)
+{
+ dma_free_coherent(dev, size, cpu_addr, handle);
+}
+#endif /* !CONFIG_COLDFIRE || CONFIG_COLDFIRE_COHERENT_DMA */
+
+struct fec_dma_devres {
+ size_t size;
+ void *vaddr;
+ dma_addr_t dma_handle;
+};
+
+static void fec_dmam_release(struct device *dev, void *res)
+{
+ struct fec_dma_devres *this = res;
+
+ fec_dma_free(dev, this->size, this->vaddr, this->dma_handle);
+}
+
+static void *fec_dmam_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp)
+{
+ struct fec_dma_devres *dr;
+ void *vaddr;
+
+ dr = devres_alloc(fec_dmam_release, sizeof(*dr), gfp);
+ if (!dr)
+ return NULL;
+ vaddr = fec_dma_alloc(dev, size, handle, gfp);
+ if (!vaddr) {
+ devres_free(dr);
+ return NULL;
+ }
+ dr->vaddr = vaddr;
+ dr->dma_handle = *handle;
+ dr->size = size;
+ devres_add(dev, dr);
+ return vaddr;
+}
+
static inline bool is_ipv4_pkt(struct sk_buff *skb)
{
return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
@@ -1617,7 +1681,11 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
}
#endif
-#ifdef CONFIG_M532x
+#if defined(CONFIG_COLDFIRE) && !defined(CONFIG_COLDFIRE_COHERENT_DMA)
+ /*
+ * Hacky flush of all caches instead of using the DMA API for the TSO
+ * headers.
+ */
flush_cache_all();
#endif
rxq = fep->rx_queue[queue_id];
@@ -3243,10 +3311,9 @@ static void fec_enet_free_queue(struct net_device *ndev)
for (i = 0; i < fep->num_tx_queues; i++)
if (fep->tx_queue[i] && fep->tx_queue[i]->tso_hdrs) {
txq = fep->tx_queue[i];
- dma_free_coherent(&fep->pdev->dev,
- txq->bd.ring_size * TSO_HEADER_SIZE,
- txq->tso_hdrs,
- txq->tso_hdrs_dma);
+ fec_dma_free(&fep->pdev->dev,
+ txq->bd.ring_size * TSO_HEADER_SIZE,
+ txq->tso_hdrs, txq->tso_hdrs_dma);
}
for (i = 0; i < fep->num_rx_queues; i++)
@@ -3276,10 +3343,9 @@ static int fec_enet_alloc_queue(struct net_device *ndev)
txq->tx_stop_threshold = FEC_MAX_SKB_DESCS;
txq->tx_wake_threshold = FEC_MAX_SKB_DESCS + 2 * MAX_SKB_FRAGS;
- txq->tso_hdrs = dma_alloc_coherent(&fep->pdev->dev,
+ txq->tso_hdrs = fec_dma_alloc(&fep->pdev->dev,
txq->bd.ring_size * TSO_HEADER_SIZE,
- &txq->tso_hdrs_dma,
- GFP_KERNEL);
+ &txq->tso_hdrs_dma, GFP_KERNEL);
if (!txq->tso_hdrs) {
ret = -ENOMEM;
goto alloc_failed;
@@ -3998,8 +4064,8 @@ static int fec_enet_init(struct net_device *ndev)
bd_size = (fep->total_tx_ring_size + fep->total_rx_ring_size) * dsize;
/* Allocate memory for buffer descriptors. */
- cbd_base = dmam_alloc_coherent(&fep->pdev->dev, bd_size, &bd_dma,
- GFP_KERNEL);
+ cbd_base = fec_dmam_alloc(&fep->pdev->dev, bd_size, &bd_dma,
+ GFP_KERNEL);
if (!cbd_base) {
ret = -ENOMEM;
goto free_queue_mem;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 1d1e183d3a8b..ed24d6af7487 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -233,9 +233,7 @@ static int nx_set_dma_mask(struct netxen_adapter *adapter)
cmask = DMA_BIT_MASK(32);
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-#ifndef CONFIG_IA64
mask = DMA_BIT_MASK(35);
-#endif
} else {
mask = DMA_BIT_MASK(39);
cmask = mask;
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 78253ad57b2e..2c1b5def4a0b 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -454,5 +454,6 @@ static void __exit ifb_cleanup_module(void)
module_init(ifb_init_module);
module_exit(ifb_cleanup_module);
MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Intermediate Functional Block (ifb) netdevice driver for sharing of resources and ingress packet queuing");
MODULE_AUTHOR("Jamal Hadi Salim");
MODULE_ALIAS_RTNL_LINK("ifb");
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index bddcc127812e..29a5929d48e5 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -250,5 +250,6 @@ static void __exit macvtap_exit(void)
module_exit(macvtap_exit);
MODULE_ALIAS_RTNL_LINK("macvtap");
+MODULE_DESCRIPTION("MAC-VLAN based tap driver");
MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 2eac92f49631..aecaf5f44374 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -470,4 +470,5 @@ static void __exit nsim_module_exit(void)
module_init(nsim_module_init);
module_exit(nsim_module_exit);
MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Simulated networking device for testing");
MODULE_ALIAS_RTNL_LINK(DRV_NAME);
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 36803d932dff..d591e33268e5 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -1194,4 +1194,5 @@ fail:
}
EXPORT_SYMBOL(sungem_phy_probe);
+MODULE_DESCRIPTION("PHY drivers for the sungem Ethernet MAC driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 5c01cc7b9949..9f0495e8df4d 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -1399,6 +1399,7 @@ void tap_destroy_cdev(dev_t major, struct cdev *tap_cdev)
}
EXPORT_SYMBOL_GPL(tap_destroy_cdev);
+MODULE_DESCRIPTION("Common library for drivers implementing the TAP interface");
MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
MODULE_AUTHOR("Sainath Grandhi <sainath.grandhi@intel.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index a3408e4e1491..db766941b78f 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1963,7 +1963,6 @@ static const struct ctl_table vrf_table[] = {
/* set by the vrf_netns_init */
.extra1 = NULL,
},
- { },
};
static int vrf_netns_init_sysctl(struct net *net, struct netns_vrf *nn_vrf)
diff --git a/drivers/net/wireless/mediatek/mt7601u/usb.c b/drivers/net/wireless/mediatek/mt7601u/usb.c
index cc772045d526..c41ae251cb95 100644
--- a/drivers/net/wireless/mediatek/mt7601u/usb.c
+++ b/drivers/net/wireless/mediatek/mt7601u/usb.c
@@ -365,6 +365,7 @@ static int mt7601u_resume(struct usb_interface *usb_intf)
MODULE_DEVICE_TABLE(usb, mt7601u_device_table);
MODULE_FIRMWARE(MT7601U_FIRMWARE);
+MODULE_DESCRIPTION("MediaTek MT7601U USB Wireless LAN driver");
MODULE_LICENSE("GPL");
static struct usb_driver mt7601u_driver = {
diff --git a/drivers/nvme/common/Kconfig b/drivers/nvme/common/Kconfig
index 4514f44362dd..06c8df00d1e2 100644
--- a/drivers/nvme/common/Kconfig
+++ b/drivers/nvme/common/Kconfig
@@ -2,3 +2,16 @@
config NVME_COMMON
tristate
+
+config NVME_KEYRING
+ bool
+ select KEYS
+
+config NVME_AUTH
+ bool
+ select CRYPTO
+ select CRYPTO_HMAC
+ select CRYPTO_SHA256
+ select CRYPTO_SHA512
+ select CRYPTO_DH
+ select CRYPTO_DH_RFC7919_GROUPS
diff --git a/drivers/nvme/common/Makefile b/drivers/nvme/common/Makefile
index 720c625b8a52..0cbd0b0b8d49 100644
--- a/drivers/nvme/common/Makefile
+++ b/drivers/nvme/common/Makefile
@@ -4,4 +4,5 @@ ccflags-y += -I$(src)
obj-$(CONFIG_NVME_COMMON) += nvme-common.o
-nvme-common-y += auth.o
+nvme-common-$(CONFIG_NVME_AUTH) += auth.o
+nvme-common-$(CONFIG_NVME_KEYRING) += keyring.o
diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c
index d90e4f0c08b7..a8e87dfbeab2 100644
--- a/drivers/nvme/common/auth.c
+++ b/drivers/nvme/common/auth.c
@@ -150,6 +150,14 @@ size_t nvme_auth_hmac_hash_len(u8 hmac_id)
}
EXPORT_SYMBOL_GPL(nvme_auth_hmac_hash_len);
+u32 nvme_auth_key_struct_size(u32 key_len)
+{
+ struct nvme_dhchap_key key;
+
+ return struct_size(&key, key, key_len);
+}
+EXPORT_SYMBOL_GPL(nvme_auth_key_struct_size);
+
struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
u8 key_hash)
{
@@ -163,14 +171,9 @@ struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
p = strrchr(secret, ':');
if (p)
allocated_len = p - secret;
- key = kzalloc(sizeof(*key), GFP_KERNEL);
+ key = nvme_auth_alloc_key(allocated_len, 0);
if (!key)
return ERR_PTR(-ENOMEM);
- key->key = kzalloc(allocated_len, GFP_KERNEL);
- if (!key->key) {
- ret = -ENOMEM;
- goto out_free_key;
- }
key_len = base64_decode(secret, allocated_len, key->key);
if (key_len < 0) {
@@ -187,14 +190,6 @@ struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
goto out_free_secret;
}
- if (key_hash > 0 &&
- (key_len - 4) != nvme_auth_hmac_hash_len(key_hash)) {
- pr_err("Mismatched key len %d for %s\n", key_len,
- nvme_auth_hmac_name(key_hash));
- ret = -EINVAL;
- goto out_free_secret;
- }
-
/* The last four bytes is the CRC in little-endian format */
key_len -= 4;
/*
@@ -213,37 +208,51 @@ struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
key->hash = key_hash;
return key;
out_free_secret:
- kfree_sensitive(key->key);
-out_free_key:
- kfree(key);
+ nvme_auth_free_key(key);
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(nvme_auth_extract_key);
+struct nvme_dhchap_key *nvme_auth_alloc_key(u32 len, u8 hash)
+{
+ u32 num_bytes = nvme_auth_key_struct_size(len);
+ struct nvme_dhchap_key *key = kzalloc(num_bytes, GFP_KERNEL);
+
+ if (key) {
+ key->len = len;
+ key->hash = hash;
+ }
+ return key;
+}
+EXPORT_SYMBOL_GPL(nvme_auth_alloc_key);
+
void nvme_auth_free_key(struct nvme_dhchap_key *key)
{
if (!key)
return;
- kfree_sensitive(key->key);
- kfree(key);
+ kfree_sensitive(key);
}
EXPORT_SYMBOL_GPL(nvme_auth_free_key);
-u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn)
+struct nvme_dhchap_key *nvme_auth_transform_key(
+ struct nvme_dhchap_key *key, char *nqn)
{
const char *hmac_name;
struct crypto_shash *key_tfm;
struct shash_desc *shash;
- u8 *transformed_key;
- int ret;
+ struct nvme_dhchap_key *transformed_key;
+ int ret, key_len;
- if (!key || !key->key) {
+ if (!key) {
pr_warn("No key specified\n");
return ERR_PTR(-ENOKEY);
}
if (key->hash == 0) {
- transformed_key = kmemdup(key->key, key->len, GFP_KERNEL);
- return transformed_key ? transformed_key : ERR_PTR(-ENOMEM);
+ key_len = nvme_auth_key_struct_size(key->len);
+ transformed_key = kmemdup(key, key_len, GFP_KERNEL);
+ if (!transformed_key)
+ return ERR_PTR(-ENOMEM);
+ return transformed_key;
}
hmac_name = nvme_auth_hmac_name(key->hash);
if (!hmac_name) {
@@ -253,7 +262,7 @@ u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn)
key_tfm = crypto_alloc_shash(hmac_name, 0, 0);
if (IS_ERR(key_tfm))
- return (u8 *)key_tfm;
+ return ERR_CAST(key_tfm);
shash = kmalloc(sizeof(struct shash_desc) +
crypto_shash_descsize(key_tfm),
@@ -263,7 +272,8 @@ u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn)
goto out_free_key;
}
- transformed_key = kzalloc(crypto_shash_digestsize(key_tfm), GFP_KERNEL);
+ key_len = crypto_shash_digestsize(key_tfm);
+ transformed_key = nvme_auth_alloc_key(key_len, key->hash);
if (!transformed_key) {
ret = -ENOMEM;
goto out_free_shash;
@@ -282,7 +292,7 @@ u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn)
ret = crypto_shash_update(shash, "NVMe-over-Fabrics", 17);
if (ret < 0)
goto out_free_transformed_key;
- ret = crypto_shash_final(shash, transformed_key);
+ ret = crypto_shash_final(shash, transformed_key->key);
if (ret < 0)
goto out_free_transformed_key;
@@ -292,7 +302,7 @@ u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn)
return transformed_key;
out_free_transformed_key:
- kfree_sensitive(transformed_key);
+ nvme_auth_free_key(transformed_key);
out_free_shash:
kfree(shash);
out_free_key:
diff --git a/drivers/nvme/common/keyring.c b/drivers/nvme/common/keyring.c
new file mode 100644
index 000000000000..f8d9a208397b
--- /dev/null
+++ b/drivers/nvme/common/keyring.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Hannes Reinecke, SUSE Labs
+ */
+
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/key.h>
+#include <linux/key-type.h>
+#include <keys/user-type.h>
+#include <linux/nvme.h>
+#include <linux/nvme-tcp.h>
+#include <linux/nvme-keyring.h>
+
+static struct key *nvme_keyring;
+
+key_serial_t nvme_keyring_id(void)
+{
+ return nvme_keyring->serial;
+}
+EXPORT_SYMBOL_GPL(nvme_keyring_id);
+
+static void nvme_tls_psk_describe(const struct key *key, struct seq_file *m)
+{
+ seq_puts(m, key->description);
+ seq_printf(m, ": %u", key->datalen);
+}
+
+static bool nvme_tls_psk_match(const struct key *key,
+ const struct key_match_data *match_data)
+{
+ const char *match_id;
+ size_t match_len;
+
+ if (!key->description) {
+ pr_debug("%s: no key description\n", __func__);
+ return false;
+ }
+ match_len = strlen(key->description);
+ pr_debug("%s: id %s len %zd\n", __func__, key->description, match_len);
+
+ if (!match_data->raw_data) {
+ pr_debug("%s: no match data\n", __func__);
+ return false;
+ }
+ match_id = match_data->raw_data;
+ pr_debug("%s: match '%s' '%s' len %zd\n",
+ __func__, match_id, key->description, match_len);
+ return !memcmp(key->description, match_id, match_len);
+}
+
+static int nvme_tls_psk_match_preparse(struct key_match_data *match_data)
+{
+ match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE;
+ match_data->cmp = nvme_tls_psk_match;
+ return 0;
+}
+
+static struct key_type nvme_tls_psk_key_type = {
+ .name = "psk",
+ .flags = KEY_TYPE_NET_DOMAIN,
+ .preparse = user_preparse,
+ .free_preparse = user_free_preparse,
+ .match_preparse = nvme_tls_psk_match_preparse,
+ .instantiate = generic_key_instantiate,
+ .revoke = user_revoke,
+ .destroy = user_destroy,
+ .describe = nvme_tls_psk_describe,
+ .read = user_read,
+};
+
+static struct key *nvme_tls_psk_lookup(struct key *keyring,
+ const char *hostnqn, const char *subnqn,
+ int hmac, bool generated)
+{
+ char *identity;
+ size_t identity_len = (NVMF_NQN_SIZE) * 2 + 11;
+ key_ref_t keyref;
+ key_serial_t keyring_id;
+
+ identity = kzalloc(identity_len, GFP_KERNEL);
+ if (!identity)
+ return ERR_PTR(-ENOMEM);
+
+ snprintf(identity, identity_len, "NVMe0%c%02d %s %s",
+ generated ? 'G' : 'R', hmac, hostnqn, subnqn);
+
+ if (!keyring)
+ keyring = nvme_keyring;
+ keyring_id = key_serial(keyring);
+ pr_debug("keyring %x lookup tls psk '%s'\n",
+ keyring_id, identity);
+ keyref = keyring_search(make_key_ref(keyring, true),
+ &nvme_tls_psk_key_type,
+ identity, false);
+ if (IS_ERR(keyref)) {
+ pr_debug("lookup tls psk '%s' failed, error %ld\n",
+ identity, PTR_ERR(keyref));
+ kfree(identity);
+ return ERR_PTR(-ENOKEY);
+ }
+ kfree(identity);
+
+ return key_ref_to_ptr(keyref);
+}
+
+/*
+ * NVMe PSK priority list
+ *
+ * 'Retained' PSKs (ie 'generated == false')
+ * should be preferred to 'generated' PSKs,
+ * and SHA-384 should be preferred to SHA-256.
+ */
+struct nvme_tls_psk_priority_list {
+ bool generated;
+ enum nvme_tcp_tls_cipher cipher;
+} nvme_tls_psk_prio[] = {
+ { .generated = false,
+ .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
+ { .generated = false,
+ .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
+ { .generated = true,
+ .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
+ { .generated = true,
+ .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
+};
+
+/*
+ * nvme_tls_psk_default - Return the preferred PSK to use for TLS ClientHello
+ */
+key_serial_t nvme_tls_psk_default(struct key *keyring,
+ const char *hostnqn, const char *subnqn)
+{
+ struct key *tls_key;
+ key_serial_t tls_key_id;
+ int prio;
+
+ for (prio = 0; prio < ARRAY_SIZE(nvme_tls_psk_prio); prio++) {
+ bool generated = nvme_tls_psk_prio[prio].generated;
+ enum nvme_tcp_tls_cipher cipher = nvme_tls_psk_prio[prio].cipher;
+
+ tls_key = nvme_tls_psk_lookup(keyring, hostnqn, subnqn,
+ cipher, generated);
+ if (!IS_ERR(tls_key)) {
+ tls_key_id = tls_key->serial;
+ key_put(tls_key);
+ return tls_key_id;
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(nvme_tls_psk_default);
+
+int nvme_keyring_init(void)
+{
+ int err;
+
+ nvme_keyring = keyring_alloc(".nvme",
+ GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
+ current_cred(),
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ (KEY_USR_ALL & ~KEY_USR_SETATTR),
+ KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
+ if (IS_ERR(nvme_keyring))
+ return PTR_ERR(nvme_keyring);
+
+ err = register_key_type(&nvme_tls_psk_key_type);
+ if (err) {
+ key_put(nvme_keyring);
+ return err;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(nvme_keyring_init);
+
+void nvme_keyring_exit(void)
+{
+ unregister_key_type(&nvme_tls_psk_key_type);
+ key_revoke(nvme_keyring);
+ key_put(nvme_keyring);
+}
+EXPORT_SYMBOL_GPL(nvme_keyring_exit);
diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig
index 2f6a7f8c94e8..48f7d72de5e9 100644
--- a/drivers/nvme/host/Kconfig
+++ b/drivers/nvme/host/Kconfig
@@ -92,16 +92,26 @@ config NVME_TCP
If unsure, say N.
-config NVME_AUTH
+config NVME_TCP_TLS
+ bool "NVMe over Fabrics TCP TLS encryption support"
+ depends on NVME_TCP
+ select NVME_COMMON
+ select NVME_KEYRING
+ select NET_HANDSHAKE
+ select KEYS
+ help
+ Enables TLS encryption for NVMe TCP using the netlink handshake API.
+
+ The TLS handshake daemon is availble at
+ https://github.com/oracle/ktls-utils.
+
+ If unsure, say N.
+
+config NVME_HOST_AUTH
bool "NVM Express over Fabrics In-Band Authentication"
depends on NVME_CORE
select NVME_COMMON
- select CRYPTO
- select CRYPTO_HMAC
- select CRYPTO_SHA256
- select CRYPTO_SHA512
- select CRYPTO_DH
- select CRYPTO_DH_RFC7919_GROUPS
+ select NVME_AUTH
help
This provides support for NVMe over Fabrics In-Band Authentication.
diff --git a/drivers/nvme/host/Makefile b/drivers/nvme/host/Makefile
index c7c3cf202d12..6414ec968f99 100644
--- a/drivers/nvme/host/Makefile
+++ b/drivers/nvme/host/Makefile
@@ -17,7 +17,7 @@ nvme-core-$(CONFIG_NVME_MULTIPATH) += multipath.o
nvme-core-$(CONFIG_BLK_DEV_ZONED) += zns.o
nvme-core-$(CONFIG_FAULT_INJECTION_DEBUG_FS) += fault_inject.o
nvme-core-$(CONFIG_NVME_HWMON) += hwmon.o
-nvme-core-$(CONFIG_NVME_AUTH) += auth.o
+nvme-core-$(CONFIG_NVME_HOST_AUTH) += auth.o
nvme-y += pci.o
diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c
index 064592a5d546..eaefebb2a799 100644
--- a/drivers/nvme/host/auth.c
+++ b/drivers/nvme/host/auth.c
@@ -23,6 +23,7 @@ struct nvme_dhchap_queue_context {
struct nvme_ctrl *ctrl;
struct crypto_shash *shash_tfm;
struct crypto_kpp *dh_tfm;
+ struct nvme_dhchap_key *transformed_key;
void *buf;
int qid;
int error;
@@ -36,7 +37,6 @@ struct nvme_dhchap_queue_context {
u8 c1[64];
u8 c2[64];
u8 response[64];
- u8 *host_response;
u8 *ctrl_key;
u8 *host_key;
u8 *sess_key;
@@ -428,12 +428,12 @@ static int nvme_auth_dhchap_setup_host_response(struct nvme_ctrl *ctrl,
dev_dbg(ctrl->device, "%s: qid %d host response seq %u transaction %d\n",
__func__, chap->qid, chap->s1, chap->transaction);
- if (!chap->host_response) {
- chap->host_response = nvme_auth_transform_key(ctrl->host_key,
+ if (!chap->transformed_key) {
+ chap->transformed_key = nvme_auth_transform_key(ctrl->host_key,
ctrl->opts->host->nqn);
- if (IS_ERR(chap->host_response)) {
- ret = PTR_ERR(chap->host_response);
- chap->host_response = NULL;
+ if (IS_ERR(chap->transformed_key)) {
+ ret = PTR_ERR(chap->transformed_key);
+ chap->transformed_key = NULL;
return ret;
}
} else {
@@ -442,7 +442,7 @@ static int nvme_auth_dhchap_setup_host_response(struct nvme_ctrl *ctrl,
}
ret = crypto_shash_setkey(chap->shash_tfm,
- chap->host_response, ctrl->host_key->len);
+ chap->transformed_key->key, chap->transformed_key->len);
if (ret) {
dev_warn(ctrl->device, "qid %d: failed to set key, error %d\n",
chap->qid, ret);
@@ -508,19 +508,19 @@ static int nvme_auth_dhchap_setup_ctrl_response(struct nvme_ctrl *ctrl,
struct nvme_dhchap_queue_context *chap)
{
SHASH_DESC_ON_STACK(shash, chap->shash_tfm);
- u8 *ctrl_response;
+ struct nvme_dhchap_key *transformed_key;
u8 buf[4], *challenge = chap->c2;
int ret;
- ctrl_response = nvme_auth_transform_key(ctrl->ctrl_key,
+ transformed_key = nvme_auth_transform_key(ctrl->ctrl_key,
ctrl->opts->subsysnqn);
- if (IS_ERR(ctrl_response)) {
- ret = PTR_ERR(ctrl_response);
+ if (IS_ERR(transformed_key)) {
+ ret = PTR_ERR(transformed_key);
return ret;
}
ret = crypto_shash_setkey(chap->shash_tfm,
- ctrl_response, ctrl->ctrl_key->len);
+ transformed_key->key, transformed_key->len);
if (ret) {
dev_warn(ctrl->device, "qid %d: failed to set key, error %d\n",
chap->qid, ret);
@@ -586,7 +586,7 @@ static int nvme_auth_dhchap_setup_ctrl_response(struct nvme_ctrl *ctrl,
out:
if (challenge != chap->c2)
kfree(challenge);
- kfree(ctrl_response);
+ nvme_auth_free_key(transformed_key);
return ret;
}
@@ -648,8 +648,8 @@ gen_sesskey:
static void nvme_auth_reset_dhchap(struct nvme_dhchap_queue_context *chap)
{
- kfree_sensitive(chap->host_response);
- chap->host_response = NULL;
+ nvme_auth_free_key(chap->transformed_key);
+ chap->transformed_key = NULL;
kfree_sensitive(chap->host_key);
chap->host_key = NULL;
chap->host_key_len = 0;
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 21783aa2ee8e..62612f87aafa 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -25,6 +25,7 @@
#include "nvme.h"
#include "fabrics.h"
#include <linux/nvme-auth.h>
+#include <linux/nvme-keyring.h>
#define CREATE_TRACE_POINTS
#include "trace.h"
@@ -420,7 +421,7 @@ void nvme_complete_rq(struct request *req)
nvme_failover_req(req);
return;
case AUTHENTICATE:
-#ifdef CONFIG_NVME_AUTH
+#ifdef CONFIG_NVME_HOST_AUTH
queue_work(nvme_wq, &ctrl->dhchap_auth_work);
nvme_retry_req(req);
#else
@@ -4399,7 +4400,7 @@ static void nvme_free_ctrl(struct device *dev)
if (!subsys || ctrl->instance != subsys->instance)
ida_free(&nvme_instance_ida, ctrl->instance);
-
+ key_put(ctrl->tls_key);
nvme_free_cels(ctrl);
nvme_mpath_uninit(ctrl);
nvme_auth_stop(ctrl);
@@ -4723,12 +4724,16 @@ static int __init nvme_core_init(void)
result = PTR_ERR(nvme_ns_chr_class);
goto unregister_generic_ns;
}
-
- result = nvme_init_auth();
+ result = nvme_keyring_init();
if (result)
goto destroy_ns_chr;
+ result = nvme_init_auth();
+ if (result)
+ goto keyring_exit;
return 0;
+keyring_exit:
+ nvme_keyring_exit();
destroy_ns_chr:
class_destroy(nvme_ns_chr_class);
unregister_generic_ns:
@@ -4752,6 +4757,7 @@ out:
static void __exit nvme_core_exit(void)
{
nvme_exit_auth();
+ nvme_keyring_exit();
class_destroy(nvme_ns_chr_class);
class_destroy(nvme_subsys_class);
class_destroy(nvme_class);
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index 8175d49f2909..4673ead69c5f 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -12,6 +12,7 @@
#include <linux/seq_file.h>
#include "nvme.h"
#include "fabrics.h"
+#include <linux/nvme-keyring.h>
static LIST_HEAD(nvmf_transports);
static DECLARE_RWSEM(nvmf_transports_rwsem);
@@ -622,6 +623,23 @@ static struct nvmf_transport_ops *nvmf_lookup_transport(
return NULL;
}
+static struct key *nvmf_parse_key(int key_id)
+{
+ struct key *key;
+
+ if (!IS_ENABLED(CONFIG_NVME_TCP_TLS)) {
+ pr_err("TLS is not supported\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ key = key_lookup(key_id);
+ if (!IS_ERR(key))
+ pr_err("key id %08x not found\n", key_id);
+ else
+ pr_debug("Using key id %08x\n", key_id);
+ return key;
+}
+
static const match_table_t opt_tokens = {
{ NVMF_OPT_TRANSPORT, "transport=%s" },
{ NVMF_OPT_TRADDR, "traddr=%s" },
@@ -643,10 +661,17 @@ static const match_table_t opt_tokens = {
{ NVMF_OPT_NR_WRITE_QUEUES, "nr_write_queues=%d" },
{ NVMF_OPT_NR_POLL_QUEUES, "nr_poll_queues=%d" },
{ NVMF_OPT_TOS, "tos=%d" },
+#ifdef CONFIG_NVME_TCP_TLS
+ { NVMF_OPT_KEYRING, "keyring=%d" },
+ { NVMF_OPT_TLS_KEY, "tls_key=%d" },
+#endif
{ NVMF_OPT_FAIL_FAST_TMO, "fast_io_fail_tmo=%d" },
{ NVMF_OPT_DISCOVERY, "discovery" },
{ NVMF_OPT_DHCHAP_SECRET, "dhchap_secret=%s" },
{ NVMF_OPT_DHCHAP_CTRL_SECRET, "dhchap_ctrl_secret=%s" },
+#ifdef CONFIG_NVME_TCP_TLS
+ { NVMF_OPT_TLS, "tls" },
+#endif
{ NVMF_OPT_ERR, NULL }
};
@@ -657,9 +682,10 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
char *options, *o, *p;
int token, ret = 0;
size_t nqnlen = 0;
- int ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO;
+ int ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO, key_id;
uuid_t hostid;
char hostnqn[NVMF_NQN_SIZE];
+ struct key *key;
/* Set defaults */
opts->queue_size = NVMF_DEF_QUEUE_SIZE;
@@ -671,6 +697,9 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
opts->hdr_digest = false;
opts->data_digest = false;
opts->tos = -1; /* < 0 == use transport default */
+ opts->tls = false;
+ opts->tls_key = NULL;
+ opts->keyring = NULL;
options = o = kstrdup(buf, GFP_KERNEL);
if (!options)
@@ -924,6 +953,32 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
}
opts->tos = token;
break;
+ case NVMF_OPT_KEYRING:
+ if (match_int(args, &key_id) || key_id <= 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+ key = nvmf_parse_key(key_id);
+ if (IS_ERR(key)) {
+ ret = PTR_ERR(key);
+ goto out;
+ }
+ key_put(opts->keyring);
+ opts->keyring = key;
+ break;
+ case NVMF_OPT_TLS_KEY:
+ if (match_int(args, &key_id) || key_id <= 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+ key = nvmf_parse_key(key_id);
+ if (IS_ERR(key)) {
+ ret = PTR_ERR(key);
+ goto out;
+ }
+ key_put(opts->tls_key);
+ opts->tls_key = key;
+ break;
case NVMF_OPT_DISCOVERY:
opts->discovery_nqn = true;
break;
@@ -955,6 +1010,14 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
kfree(opts->dhchap_ctrl_secret);
opts->dhchap_ctrl_secret = p;
break;
+ case NVMF_OPT_TLS:
+ if (!IS_ENABLED(CONFIG_NVME_TCP_TLS)) {
+ pr_err("TLS is not supported\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ opts->tls = true;
+ break;
default:
pr_warn("unknown parameter or missing value '%s' in ctrl creation request\n",
p);
@@ -1156,6 +1219,8 @@ static int nvmf_check_allowed_opts(struct nvmf_ctrl_options *opts,
void nvmf_free_options(struct nvmf_ctrl_options *opts)
{
nvmf_host_put(opts->host);
+ key_put(opts->keyring);
+ key_put(opts->tls_key);
kfree(opts->transport);
kfree(opts->traddr);
kfree(opts->trsvcid);
diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h
index 82e7a27ffbde..fbaee5a7be19 100644
--- a/drivers/nvme/host/fabrics.h
+++ b/drivers/nvme/host/fabrics.h
@@ -70,6 +70,9 @@ enum {
NVMF_OPT_DISCOVERY = 1 << 22,
NVMF_OPT_DHCHAP_SECRET = 1 << 23,
NVMF_OPT_DHCHAP_CTRL_SECRET = 1 << 24,
+ NVMF_OPT_TLS = 1 << 25,
+ NVMF_OPT_KEYRING = 1 << 26,
+ NVMF_OPT_TLS_KEY = 1 << 27,
};
/**
@@ -102,6 +105,9 @@ enum {
* @dhchap_secret: DH-HMAC-CHAP secret
* @dhchap_ctrl_secret: DH-HMAC-CHAP controller secret for bi-directional
* authentication
+ * @keyring: Keyring to use for key lookups
+ * @tls_key: TLS key for encrypted connections (TCP)
+ * @tls: Start TLS encrypted connections (TCP)
* @disable_sqflow: disable controller sq flow control
* @hdr_digest: generate/verify header digest (TCP)
* @data_digest: generate/verify data digest (TCP)
@@ -128,6 +134,9 @@ struct nvmf_ctrl_options {
struct nvmf_host *host;
char *dhchap_secret;
char *dhchap_ctrl_secret;
+ struct key *keyring;
+ struct key *tls_key;
+ bool tls;
bool disable_sqflow;
bool hdr_digest;
bool data_digest;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index f35647c470af..39a90b7cb125 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -349,7 +349,7 @@ struct nvme_ctrl {
struct work_struct ana_work;
#endif
-#ifdef CONFIG_NVME_AUTH
+#ifdef CONFIG_NVME_HOST_AUTH
struct work_struct dhchap_auth_work;
struct mutex dhchap_auth_mutex;
struct nvme_dhchap_queue_context *dhchap_ctxs;
@@ -357,6 +357,7 @@ struct nvme_ctrl {
struct nvme_dhchap_key *ctrl_key;
u16 transaction;
#endif
+ struct key *tls_key;
/* Power saving configuration */
u64 ps_max_latency_us;
@@ -1048,7 +1049,7 @@ static inline bool nvme_ctrl_sgl_supported(struct nvme_ctrl *ctrl)
return ctrl->sgls & ((1 << 0) | (1 << 1));
}
-#ifdef CONFIG_NVME_AUTH
+#ifdef CONFIG_NVME_HOST_AUTH
int __init nvme_init_auth(void);
void __exit nvme_exit_auth(void);
int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl);
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 3f0c9ee09a12..507bc149046d 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -924,7 +924,6 @@ static bool nvme_prep_rq_batch(struct nvme_queue *nvmeq, struct request *req)
if (unlikely(!nvme_check_ready(&nvmeq->dev->ctrl, req, true)))
return false;
- req->mq_hctx->tags->rqs[req->tag] = req;
return nvme_prep_rq(nvmeq->dev, req) == BLK_STS_OK;
}
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index 212e1b05d298..c6b7fbd4d34d 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -409,7 +409,7 @@ static ssize_t dctype_show(struct device *dev,
}
static DEVICE_ATTR_RO(dctype);
-#ifdef CONFIG_NVME_AUTH
+#ifdef CONFIG_NVME_HOST_AUTH
static ssize_t nvme_ctrl_dhchap_secret_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -527,6 +527,19 @@ static DEVICE_ATTR(dhchap_ctrl_secret, S_IRUGO | S_IWUSR,
nvme_ctrl_dhchap_ctrl_secret_show, nvme_ctrl_dhchap_ctrl_secret_store);
#endif
+#ifdef CONFIG_NVME_TCP_TLS
+static ssize_t tls_key_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+
+ if (!ctrl->tls_key)
+ return 0;
+ return sysfs_emit(buf, "%08x", key_serial(ctrl->tls_key));
+}
+static DEVICE_ATTR_RO(tls_key);
+#endif
+
static struct attribute *nvme_dev_attrs[] = {
&dev_attr_reset_controller.attr,
&dev_attr_rescan_controller.attr,
@@ -550,10 +563,13 @@ static struct attribute *nvme_dev_attrs[] = {
&dev_attr_kato.attr,
&dev_attr_cntrltype.attr,
&dev_attr_dctype.attr,
-#ifdef CONFIG_NVME_AUTH
+#ifdef CONFIG_NVME_HOST_AUTH
&dev_attr_dhchap_secret.attr,
&dev_attr_dhchap_ctrl_secret.attr,
#endif
+#ifdef CONFIG_NVME_TCP_TLS
+ &dev_attr_tls_key.attr,
+#endif
NULL
};
@@ -577,12 +593,17 @@ static umode_t nvme_dev_attrs_are_visible(struct kobject *kobj,
return 0;
if (a == &dev_attr_fast_io_fail_tmo.attr && !ctrl->opts)
return 0;
-#ifdef CONFIG_NVME_AUTH
+#ifdef CONFIG_NVME_HOST_AUTH
if (a == &dev_attr_dhchap_secret.attr && !ctrl->opts)
return 0;
if (a == &dev_attr_dhchap_ctrl_secret.attr && !ctrl->opts)
return 0;
#endif
+#ifdef CONFIG_NVME_TCP_TLS
+ if (a == &dev_attr_tls_key.attr &&
+ (!ctrl->opts || strcmp(ctrl->opts->transport, "tcp")))
+ return 0;
+#endif
return a->mode;
}
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 5b332d9f87fc..4714a902f4ca 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -8,9 +8,14 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
+#include <linux/key.h>
#include <linux/nvme-tcp.h>
+#include <linux/nvme-keyring.h>
#include <net/sock.h>
#include <net/tcp.h>
+#include <net/tls.h>
+#include <net/tls_prot.h>
+#include <net/handshake.h>
#include <linux/blk-mq.h>
#include <crypto/hash.h>
#include <net/busy_poll.h>
@@ -31,6 +36,16 @@ static int so_priority;
module_param(so_priority, int, 0644);
MODULE_PARM_DESC(so_priority, "nvme tcp socket optimize priority");
+#ifdef CONFIG_NVME_TCP_TLS
+/*
+ * TLS handshake timeout
+ */
+static int tls_handshake_timeout = 10;
+module_param(tls_handshake_timeout, int, 0644);
+MODULE_PARM_DESC(tls_handshake_timeout,
+ "nvme TLS handshake timeout in seconds (default 10)");
+#endif
+
#ifdef CONFIG_DEBUG_LOCK_ALLOC
/* lockdep can detect a circular dependency of the form
* sk_lock -> mmap_lock (page fault) -> fs locks -> sk_lock
@@ -146,7 +161,10 @@ struct nvme_tcp_queue {
struct ahash_request *snd_hash;
__le32 exp_ddgst;
__le32 recv_ddgst;
-
+#ifdef CONFIG_NVME_TCP_TLS
+ struct completion tls_complete;
+ int tls_err;
+#endif
struct page_frag_cache pf_cache;
void (*state_change)(struct sock *);
@@ -1338,7 +1356,9 @@ static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
}
noreclaim_flag = memalloc_noreclaim_save();
- sock_release(queue->sock);
+ /* ->sock will be released by fput() */
+ fput(queue->sock->file);
+ queue->sock = NULL;
memalloc_noreclaim_restore(noreclaim_flag);
kfree(queue->pdu);
@@ -1350,6 +1370,8 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
{
struct nvme_tcp_icreq_pdu *icreq;
struct nvme_tcp_icresp_pdu *icresp;
+ char cbuf[CMSG_LEN(sizeof(char))] = {};
+ u8 ctype;
struct msghdr msg = {};
struct kvec iov;
bool ctrl_hdgst, ctrl_ddgst;
@@ -1381,17 +1403,35 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
iov.iov_base = icreq;
iov.iov_len = sizeof(*icreq);
ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
- if (ret < 0)
+ if (ret < 0) {
+ pr_warn("queue %d: failed to send icreq, error %d\n",
+ nvme_tcp_queue_id(queue), ret);
goto free_icresp;
+ }
memset(&msg, 0, sizeof(msg));
iov.iov_base = icresp;
iov.iov_len = sizeof(*icresp);
+ if (queue->ctrl->ctrl.opts->tls) {
+ msg.msg_control = cbuf;
+ msg.msg_controllen = sizeof(cbuf);
+ }
ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
iov.iov_len, msg.msg_flags);
- if (ret < 0)
+ if (ret < 0) {
+ pr_warn("queue %d: failed to receive icresp, error %d\n",
+ nvme_tcp_queue_id(queue), ret);
goto free_icresp;
-
+ }
+ if (queue->ctrl->ctrl.opts->tls) {
+ ctype = tls_get_record_type(queue->sock->sk,
+ (struct cmsghdr *)cbuf);
+ if (ctype != TLS_RECORD_TYPE_DATA) {
+ pr_err("queue %d: unhandled TLS record %d\n",
+ nvme_tcp_queue_id(queue), ctype);
+ return -ENOTCONN;
+ }
+ }
ret = -EINVAL;
if (icresp->hdr.type != nvme_tcp_icresp) {
pr_err("queue %d: bad type returned %d\n",
@@ -1507,11 +1547,99 @@ static void nvme_tcp_set_queue_io_cpu(struct nvme_tcp_queue *queue)
queue->io_cpu = cpumask_next_wrap(n - 1, cpu_online_mask, -1, false);
}
-static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid)
+#ifdef CONFIG_NVME_TCP_TLS
+static void nvme_tcp_tls_done(void *data, int status, key_serial_t pskid)
+{
+ struct nvme_tcp_queue *queue = data;
+ struct nvme_tcp_ctrl *ctrl = queue->ctrl;
+ int qid = nvme_tcp_queue_id(queue);
+ struct key *tls_key;
+
+ dev_dbg(ctrl->ctrl.device, "queue %d: TLS handshake done, key %x, status %d\n",
+ qid, pskid, status);
+
+ if (status) {
+ queue->tls_err = -status;
+ goto out_complete;
+ }
+
+ tls_key = key_lookup(pskid);
+ if (IS_ERR(tls_key)) {
+ dev_warn(ctrl->ctrl.device, "queue %d: Invalid key %x\n",
+ qid, pskid);
+ queue->tls_err = -ENOKEY;
+ } else {
+ ctrl->ctrl.tls_key = tls_key;
+ queue->tls_err = 0;
+ }
+
+out_complete:
+ complete(&queue->tls_complete);
+}
+
+static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl,
+ struct nvme_tcp_queue *queue,
+ key_serial_t pskid)
+{
+ int qid = nvme_tcp_queue_id(queue);
+ int ret;
+ struct tls_handshake_args args;
+ unsigned long tmo = tls_handshake_timeout * HZ;
+ key_serial_t keyring = nvme_keyring_id();
+
+ dev_dbg(nctrl->device, "queue %d: start TLS with key %x\n",
+ qid, pskid);
+ memset(&args, 0, sizeof(args));
+ args.ta_sock = queue->sock;
+ args.ta_done = nvme_tcp_tls_done;
+ args.ta_data = queue;
+ args.ta_my_peerids[0] = pskid;
+ args.ta_num_peerids = 1;
+ if (nctrl->opts->keyring)
+ keyring = key_serial(nctrl->opts->keyring);
+ args.ta_keyring = keyring;
+ args.ta_timeout_ms = tls_handshake_timeout * 1000;
+ queue->tls_err = -EOPNOTSUPP;
+ init_completion(&queue->tls_complete);
+ ret = tls_client_hello_psk(&args, GFP_KERNEL);
+ if (ret) {
+ dev_err(nctrl->device, "queue %d: failed to start TLS: %d\n",
+ qid, ret);
+ return ret;
+ }
+ ret = wait_for_completion_interruptible_timeout(&queue->tls_complete, tmo);
+ if (ret <= 0) {
+ if (ret == 0)
+ ret = -ETIMEDOUT;
+
+ dev_err(nctrl->device,
+ "queue %d: TLS handshake failed, error %d\n",
+ qid, ret);
+ tls_handshake_cancel(queue->sock->sk);
+ } else {
+ dev_dbg(nctrl->device,
+ "queue %d: TLS handshake complete, error %d\n",
+ qid, queue->tls_err);
+ ret = queue->tls_err;
+ }
+ return ret;
+}
+#else
+static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl,
+ struct nvme_tcp_queue *queue,
+ key_serial_t pskid)
+{
+ return -EPROTONOSUPPORT;
+}
+#endif
+
+static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid,
+ key_serial_t pskid)
{
struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
struct nvme_tcp_queue *queue = &ctrl->queues[qid];
int ret, rcv_pdu_size;
+ struct file *sock_file;
mutex_init(&queue->queue_lock);
queue->ctrl = ctrl;
@@ -1534,6 +1662,11 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid)
goto err_destroy_mutex;
}
+ sock_file = sock_alloc_file(queue->sock, O_CLOEXEC, NULL);
+ if (IS_ERR(sock_file)) {
+ ret = PTR_ERR(sock_file);
+ goto err_destroy_mutex;
+ }
nvme_tcp_reclassify_socket(queue->sock);
/* Single syn retry */
@@ -1624,6 +1757,13 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid)
goto err_rcv_pdu;
}
+ /* If PSKs are configured try to start TLS */
+ if (pskid) {
+ ret = nvme_tcp_start_tls(nctrl, queue, pskid);
+ if (ret)
+ goto err_init_connect;
+ }
+
ret = nvme_tcp_init_connection(queue);
if (ret)
goto err_init_connect;
@@ -1640,7 +1780,8 @@ err_crypto:
if (queue->hdr_digest || queue->data_digest)
nvme_tcp_free_crypto(queue);
err_sock:
- sock_release(queue->sock);
+ /* ->sock will be released by fput() */
+ fput(queue->sock->file);
queue->sock = NULL;
err_destroy_mutex:
mutex_destroy(&queue->send_mutex);
@@ -1772,10 +1913,25 @@ out_stop_queues:
static int nvme_tcp_alloc_admin_queue(struct nvme_ctrl *ctrl)
{
int ret;
+ key_serial_t pskid = 0;
- ret = nvme_tcp_alloc_queue(ctrl, 0);
+ if (ctrl->opts->tls) {
+ if (ctrl->opts->tls_key)
+ pskid = key_serial(ctrl->opts->tls_key);
+ else
+ pskid = nvme_tls_psk_default(ctrl->opts->keyring,
+ ctrl->opts->host->nqn,
+ ctrl->opts->subsysnqn);
+ if (!pskid) {
+ dev_err(ctrl->device, "no valid PSK found\n");
+ ret = -ENOKEY;
+ goto out_free_queue;
+ }
+ }
+
+ ret = nvme_tcp_alloc_queue(ctrl, 0, pskid);
if (ret)
- return ret;
+ goto out_free_queue;
ret = nvme_tcp_alloc_async_req(to_tcp_ctrl(ctrl));
if (ret)
@@ -1792,8 +1948,13 @@ static int __nvme_tcp_alloc_io_queues(struct nvme_ctrl *ctrl)
{
int i, ret;
+ if (ctrl->opts->tls && !ctrl->tls_key) {
+ dev_err(ctrl->device, "no PSK negotiated\n");
+ return -ENOKEY;
+ }
for (i = 1; i < ctrl->queue_count; i++) {
- ret = nvme_tcp_alloc_queue(ctrl, i);
+ ret = nvme_tcp_alloc_queue(ctrl, i,
+ key_serial(ctrl->tls_key));
if (ret)
goto out_free_queues;
}
@@ -2621,7 +2782,8 @@ static struct nvmf_transport_ops nvme_tcp_transport = {
NVMF_OPT_HOST_TRADDR | NVMF_OPT_CTRL_LOSS_TMO |
NVMF_OPT_HDR_DIGEST | NVMF_OPT_DATA_DIGEST |
NVMF_OPT_NR_WRITE_QUEUES | NVMF_OPT_NR_POLL_QUEUES |
- NVMF_OPT_TOS | NVMF_OPT_HOST_IFACE,
+ NVMF_OPT_TOS | NVMF_OPT_HOST_IFACE | NVMF_OPT_TLS |
+ NVMF_OPT_KEYRING | NVMF_OPT_TLS_KEY,
.create_ctrl = nvme_tcp_create_ctrl,
};
diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig
index 79fc64035ee3..fa479c9f5c3d 100644
--- a/drivers/nvme/target/Kconfig
+++ b/drivers/nvme/target/Kconfig
@@ -84,16 +84,26 @@ config NVME_TARGET_TCP
If unsure, say N.
+config NVME_TARGET_TCP_TLS
+ bool "NVMe over Fabrics TCP target TLS encryption support"
+ depends on NVME_TARGET_TCP
+ select NVME_COMMON
+ select NVME_KEYRING
+ select NET_HANDSHAKE
+ select KEYS
+ help
+ Enables TLS encryption for the NVMe TCP target using the netlink handshake API.
+
+ The TLS handshake daemon is available at
+ https://github.com/oracle/ktls-utils.
+
+ If unsure, say N.
+
config NVME_TARGET_AUTH
bool "NVMe over Fabrics In-band Authentication support"
depends on NVME_TARGET
select NVME_COMMON
- select CRYPTO
- select CRYPTO_HMAC
- select CRYPTO_SHA256
- select CRYPTO_SHA512
- select CRYPTO_DH
- select CRYPTO_DH_RFC7919_GROUPS
+ select NVME_AUTH
help
This enables support for NVMe over Fabrics In-band Authentication
diff --git a/drivers/nvme/target/auth.c b/drivers/nvme/target/auth.c
index 4dcddcf95279..3ddbc3880cac 100644
--- a/drivers/nvme/target/auth.c
+++ b/drivers/nvme/target/auth.c
@@ -267,7 +267,8 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response,
struct shash_desc *shash;
struct nvmet_ctrl *ctrl = req->sq->ctrl;
const char *hash_name;
- u8 *challenge = req->sq->dhchap_c1, *host_response;
+ u8 *challenge = req->sq->dhchap_c1;
+ struct nvme_dhchap_key *transformed_key;
u8 buf[4];
int ret;
@@ -291,14 +292,15 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response,
goto out_free_tfm;
}
- host_response = nvme_auth_transform_key(ctrl->host_key, ctrl->hostnqn);
- if (IS_ERR(host_response)) {
- ret = PTR_ERR(host_response);
+ transformed_key = nvme_auth_transform_key(ctrl->host_key,
+ ctrl->hostnqn);
+ if (IS_ERR(transformed_key)) {
+ ret = PTR_ERR(transformed_key);
goto out_free_tfm;
}
- ret = crypto_shash_setkey(shash_tfm, host_response,
- ctrl->host_key->len);
+ ret = crypto_shash_setkey(shash_tfm, transformed_key->key,
+ transformed_key->len);
if (ret)
goto out_free_response;
@@ -365,7 +367,7 @@ out:
kfree(challenge);
kfree(shash);
out_free_response:
- kfree_sensitive(host_response);
+ nvme_auth_free_key(transformed_key);
out_free_tfm:
crypto_free_shash(shash_tfm);
return 0;
@@ -378,7 +380,8 @@ int nvmet_auth_ctrl_hash(struct nvmet_req *req, u8 *response,
struct shash_desc *shash;
struct nvmet_ctrl *ctrl = req->sq->ctrl;
const char *hash_name;
- u8 *challenge = req->sq->dhchap_c2, *ctrl_response;
+ u8 *challenge = req->sq->dhchap_c2;
+ struct nvme_dhchap_key *transformed_key;
u8 buf[4];
int ret;
@@ -402,15 +405,15 @@ int nvmet_auth_ctrl_hash(struct nvmet_req *req, u8 *response,
goto out_free_tfm;
}
- ctrl_response = nvme_auth_transform_key(ctrl->ctrl_key,
+ transformed_key = nvme_auth_transform_key(ctrl->ctrl_key,
ctrl->subsysnqn);
- if (IS_ERR(ctrl_response)) {
- ret = PTR_ERR(ctrl_response);
+ if (IS_ERR(transformed_key)) {
+ ret = PTR_ERR(transformed_key);
goto out_free_tfm;
}
- ret = crypto_shash_setkey(shash_tfm, ctrl_response,
- ctrl->ctrl_key->len);
+ ret = crypto_shash_setkey(shash_tfm, transformed_key->key,
+ transformed_key->len);
if (ret)
goto out_free_response;
@@ -474,7 +477,7 @@ out:
kfree(challenge);
kfree(shash);
out_free_response:
- kfree_sensitive(ctrl_response);
+ nvme_auth_free_key(transformed_key);
out_free_tfm:
crypto_free_shash(shash_tfm);
return 0;
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index 907143870da5..9eed6e6765ea 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -15,6 +15,7 @@
#ifdef CONFIG_NVME_TARGET_AUTH
#include <linux/nvme-auth.h>
#endif
+#include <linux/nvme-keyring.h>
#include <crypto/hash.h>
#include <crypto/kpp.h>
@@ -159,10 +160,14 @@ static const struct nvmet_type_name_map nvmet_addr_treq[] = {
{ NVMF_TREQ_NOT_REQUIRED, "not required" },
};
+static inline u8 nvmet_port_disc_addr_treq_mask(struct nvmet_port *port)
+{
+ return (port->disc_addr.treq & ~NVME_TREQ_SECURE_CHANNEL_MASK);
+}
+
static ssize_t nvmet_addr_treq_show(struct config_item *item, char *page)
{
- u8 treq = to_nvmet_port(item)->disc_addr.treq &
- NVME_TREQ_SECURE_CHANNEL_MASK;
+ u8 treq = nvmet_port_disc_addr_treq_secure_channel(to_nvmet_port(item));
int i;
for (i = 0; i < ARRAY_SIZE(nvmet_addr_treq); i++) {
@@ -178,7 +183,7 @@ static ssize_t nvmet_addr_treq_store(struct config_item *item,
const char *page, size_t count)
{
struct nvmet_port *port = to_nvmet_port(item);
- u8 treq = port->disc_addr.treq & ~NVME_TREQ_SECURE_CHANNEL_MASK;
+ u8 treq = nvmet_port_disc_addr_treq_mask(port);
int i;
if (nvmet_is_port_enabled(port, __func__))
@@ -193,6 +198,20 @@ static ssize_t nvmet_addr_treq_store(struct config_item *item,
return -EINVAL;
found:
+ if (port->disc_addr.trtype == NVMF_TRTYPE_TCP &&
+ port->disc_addr.tsas.tcp.sectype == NVMF_TCP_SECTYPE_TLS13) {
+ switch (nvmet_addr_treq[i].type) {
+ case NVMF_TREQ_NOT_SPECIFIED:
+ pr_debug("treq '%s' not allowed for TLS1.3\n",
+ nvmet_addr_treq[i].name);
+ return -EINVAL;
+ case NVMF_TREQ_NOT_REQUIRED:
+ pr_warn("Allow non-TLS connections while TLS1.3 is enabled\n");
+ break;
+ default:
+ break;
+ }
+ }
treq |= nvmet_addr_treq[i].type;
port->disc_addr.treq = treq;
return count;
@@ -303,6 +322,11 @@ static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
port->disc_addr.tsas.rdma.cms = NVMF_RDMA_CMS_RDMA_CM;
}
+static void nvmet_port_init_tsas_tcp(struct nvmet_port *port, int sectype)
+{
+ port->disc_addr.tsas.tcp.sectype = sectype;
+}
+
static ssize_t nvmet_addr_trtype_store(struct config_item *item,
const char *page, size_t count)
{
@@ -325,11 +349,99 @@ found:
port->disc_addr.trtype = nvmet_transport[i].type;
if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA)
nvmet_port_init_tsas_rdma(port);
+ else if (port->disc_addr.trtype == NVMF_TRTYPE_TCP)
+ nvmet_port_init_tsas_tcp(port, NVMF_TCP_SECTYPE_NONE);
return count;
}
CONFIGFS_ATTR(nvmet_, addr_trtype);
+static const struct nvmet_type_name_map nvmet_addr_tsas_tcp[] = {
+ { NVMF_TCP_SECTYPE_NONE, "none" },
+ { NVMF_TCP_SECTYPE_TLS13, "tls1.3" },
+};
+
+static const struct nvmet_type_name_map nvmet_addr_tsas_rdma[] = {
+ { NVMF_RDMA_QPTYPE_CONNECTED, "connected" },
+ { NVMF_RDMA_QPTYPE_DATAGRAM, "datagram" },
+};
+
+static ssize_t nvmet_addr_tsas_show(struct config_item *item,
+ char *page)
+{
+ struct nvmet_port *port = to_nvmet_port(item);
+ int i;
+
+ if (port->disc_addr.trtype == NVMF_TRTYPE_TCP) {
+ for (i = 0; i < ARRAY_SIZE(nvmet_addr_tsas_tcp); i++) {
+ if (port->disc_addr.tsas.tcp.sectype == nvmet_addr_tsas_tcp[i].type)
+ return sprintf(page, "%s\n", nvmet_addr_tsas_tcp[i].name);
+ }
+ } else if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA) {
+ for (i = 0; i < ARRAY_SIZE(nvmet_addr_tsas_rdma); i++) {
+ if (port->disc_addr.tsas.rdma.qptype == nvmet_addr_tsas_rdma[i].type)
+ return sprintf(page, "%s\n", nvmet_addr_tsas_rdma[i].name);
+ }
+ }
+ return sprintf(page, "reserved\n");
+}
+
+static ssize_t nvmet_addr_tsas_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct nvmet_port *port = to_nvmet_port(item);
+ u8 treq = nvmet_port_disc_addr_treq_mask(port);
+ u8 sectype;
+ int i;
+
+ if (nvmet_is_port_enabled(port, __func__))
+ return -EACCES;
+
+ if (port->disc_addr.trtype != NVMF_TRTYPE_TCP)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(nvmet_addr_tsas_tcp); i++) {
+ if (sysfs_streq(page, nvmet_addr_tsas_tcp[i].name)) {
+ sectype = nvmet_addr_tsas_tcp[i].type;
+ goto found;
+ }
+ }
+
+ pr_err("Invalid value '%s' for tsas\n", page);
+ return -EINVAL;
+
+found:
+ if (sectype == NVMF_TCP_SECTYPE_TLS13) {
+ if (!IS_ENABLED(CONFIG_NVME_TARGET_TCP_TLS)) {
+ pr_err("TLS is not supported\n");
+ return -EINVAL;
+ }
+ if (!port->keyring) {
+ pr_err("TLS keyring not configured\n");
+ return -EINVAL;
+ }
+ }
+
+ nvmet_port_init_tsas_tcp(port, sectype);
+ /*
+ * If TLS is enabled TREQ should be set to 'required' per default
+ */
+ if (sectype == NVMF_TCP_SECTYPE_TLS13) {
+ u8 sc = nvmet_port_disc_addr_treq_secure_channel(port);
+
+ if (sc == NVMF_TREQ_NOT_SPECIFIED)
+ treq |= NVMF_TREQ_REQUIRED;
+ else
+ treq |= sc;
+ } else {
+ treq |= NVMF_TREQ_NOT_SPECIFIED;
+ }
+ port->disc_addr.treq = treq;
+ return count;
+}
+
+CONFIGFS_ATTR(nvmet_, addr_tsas);
+
/*
* Namespace structures & file operation functions below
*/
@@ -1731,6 +1843,7 @@ static void nvmet_port_release(struct config_item *item)
flush_workqueue(nvmet_wq);
list_del(&port->global_entry);
+ key_put(port->keyring);
kfree(port->ana_state);
kfree(port);
}
@@ -1741,6 +1854,7 @@ static struct configfs_attribute *nvmet_port_attrs[] = {
&nvmet_attr_addr_traddr,
&nvmet_attr_addr_trsvcid,
&nvmet_attr_addr_trtype,
+ &nvmet_attr_addr_tsas,
&nvmet_attr_param_inline_data_size,
#ifdef CONFIG_BLK_DEV_INTEGRITY
&nvmet_attr_param_pi_enable,
@@ -1779,6 +1893,14 @@ static struct config_group *nvmet_ports_make(struct config_group *group,
return ERR_PTR(-ENOMEM);
}
+ if (nvme_keyring_id()) {
+ port->keyring = key_lookup(nvme_keyring_id());
+ if (IS_ERR(port->keyring)) {
+ pr_warn("NVMe keyring not available, disabling TLS\n");
+ port->keyring = NULL;
+ }
+ }
+
for (i = 1; i <= NVMET_MAX_ANAGRPS; i++) {
if (i == NVMET_DEFAULT_ANA_GRPID)
port->ana_state[1] = NVME_ANA_OPTIMIZED;
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
index 1ab6601fdd5c..bd59990b5250 100644
--- a/drivers/nvme/target/fc.c
+++ b/drivers/nvme/target/fc.c
@@ -146,7 +146,8 @@ struct nvmet_fc_tgt_queue {
struct workqueue_struct *work_q;
struct kref ref;
struct rcu_head rcu;
- struct nvmet_fc_fcp_iod fod[]; /* array of fcp_iods */
+ /* array of fcp_iods */
+ struct nvmet_fc_fcp_iod fod[] __counted_by(sqsize);
} __aligned(sizeof(unsigned long long));
struct nvmet_fc_hostport {
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 360e385be33b..6c8acebe1a1a 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -159,6 +159,7 @@ struct nvmet_port {
struct config_group ana_groups_group;
struct nvmet_ana_group ana_default_group;
enum nvme_ana_state *ana_state;
+ struct key *keyring;
void *priv;
bool enabled;
int inline_data_size;
@@ -179,6 +180,16 @@ static inline struct nvmet_port *ana_groups_to_port(
ana_groups_group);
}
+static inline u8 nvmet_port_disc_addr_treq_secure_channel(struct nvmet_port *port)
+{
+ return (port->disc_addr.treq & NVME_TREQ_SECURE_CHANNEL_MASK);
+}
+
+static inline bool nvmet_port_secure_channel_required(struct nvmet_port *port)
+{
+ return nvmet_port_disc_addr_treq_secure_channel(port) == NVMF_TREQ_REQUIRED;
+}
+
struct nvmet_ctrl {
struct nvmet_subsys *subsys;
struct nvmet_sq **sqs;
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 197fc2ecb164..92b74d0b8686 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -8,9 +8,14 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
+#include <linux/key.h>
#include <linux/nvme-tcp.h>
+#include <linux/nvme-keyring.h>
#include <net/sock.h>
#include <net/tcp.h>
+#include <net/tls.h>
+#include <net/tls_prot.h>
+#include <net/handshake.h>
#include <linux/inet.h>
#include <linux/llist.h>
#include <crypto/hash.h>
@@ -66,6 +71,16 @@ device_param_cb(idle_poll_period_usecs, &set_param_ops,
MODULE_PARM_DESC(idle_poll_period_usecs,
"nvmet tcp io_work poll till idle time period in usecs: Default 0");
+#ifdef CONFIG_NVME_TARGET_TCP_TLS
+/*
+ * TLS handshake timeout
+ */
+static int tls_handshake_timeout = 10;
+module_param(tls_handshake_timeout, int, 0644);
+MODULE_PARM_DESC(tls_handshake_timeout,
+ "nvme TLS handshake timeout in seconds (default 10)");
+#endif
+
#define NVMET_TCP_RECV_BUDGET 8
#define NVMET_TCP_SEND_BUDGET 8
#define NVMET_TCP_IO_WORK_BUDGET 64
@@ -104,6 +119,7 @@ struct nvmet_tcp_cmd {
u32 pdu_len;
u32 pdu_recv;
int sg_idx;
+ char recv_cbuf[CMSG_LEN(sizeof(char))];
struct msghdr recv_msg;
struct bio_vec *iov;
u32 flags;
@@ -122,8 +138,10 @@ struct nvmet_tcp_cmd {
enum nvmet_tcp_queue_state {
NVMET_TCP_Q_CONNECTING,
+ NVMET_TCP_Q_TLS_HANDSHAKE,
NVMET_TCP_Q_LIVE,
NVMET_TCP_Q_DISCONNECTING,
+ NVMET_TCP_Q_FAILED,
};
struct nvmet_tcp_queue {
@@ -132,6 +150,7 @@ struct nvmet_tcp_queue {
struct work_struct io_work;
struct nvmet_cq nvme_cq;
struct nvmet_sq nvme_sq;
+ struct kref kref;
/* send state */
struct nvmet_tcp_cmd *cmds;
@@ -155,6 +174,10 @@ struct nvmet_tcp_queue {
struct ahash_request *snd_hash;
struct ahash_request *rcv_hash;
+ /* TLS state */
+ key_serial_t tls_pskid;
+ struct delayed_work tls_handshake_tmo_work;
+
unsigned long poll_end;
spinlock_t state_lock;
@@ -910,8 +933,10 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
iov.iov_base = icresp;
iov.iov_len = sizeof(*icresp);
ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
- if (ret < 0)
+ if (ret < 0) {
+ queue->state = NVMET_TCP_Q_FAILED;
return ret; /* queue removal will cleanup */
+ }
queue->state = NVMET_TCP_Q_LIVE;
nvmet_prepare_receive_pdu(queue);
@@ -1096,20 +1121,65 @@ static inline bool nvmet_tcp_pdu_valid(u8 type)
return false;
}
+static int nvmet_tcp_tls_record_ok(struct nvmet_tcp_queue *queue,
+ struct msghdr *msg, char *cbuf)
+{
+ struct cmsghdr *cmsg = (struct cmsghdr *)cbuf;
+ u8 ctype, level, description;
+ int ret = 0;
+
+ ctype = tls_get_record_type(queue->sock->sk, cmsg);
+ switch (ctype) {
+ case 0:
+ break;
+ case TLS_RECORD_TYPE_DATA:
+ break;
+ case TLS_RECORD_TYPE_ALERT:
+ tls_alert_recv(queue->sock->sk, msg, &level, &description);
+ if (level == TLS_ALERT_LEVEL_FATAL) {
+ pr_err("queue %d: TLS Alert desc %u\n",
+ queue->idx, description);
+ ret = -ENOTCONN;
+ } else {
+ pr_warn("queue %d: TLS Alert desc %u\n",
+ queue->idx, description);
+ ret = -EAGAIN;
+ }
+ break;
+ default:
+ /* discard this record type */
+ pr_err("queue %d: TLS record %d unhandled\n",
+ queue->idx, ctype);
+ ret = -EAGAIN;
+ break;
+ }
+ return ret;
+}
+
static int nvmet_tcp_try_recv_pdu(struct nvmet_tcp_queue *queue)
{
struct nvme_tcp_hdr *hdr = &queue->pdu.cmd.hdr;
- int len;
+ int len, ret;
struct kvec iov;
+ char cbuf[CMSG_LEN(sizeof(char))] = {};
struct msghdr msg = { .msg_flags = MSG_DONTWAIT };
recv:
iov.iov_base = (void *)&queue->pdu + queue->offset;
iov.iov_len = queue->left;
+ if (queue->tls_pskid) {
+ msg.msg_control = cbuf;
+ msg.msg_controllen = sizeof(cbuf);
+ }
len = kernel_recvmsg(queue->sock, &msg, &iov, 1,
iov.iov_len, msg.msg_flags);
if (unlikely(len < 0))
return len;
+ if (queue->tls_pskid) {
+ ret = nvmet_tcp_tls_record_ok(queue, &msg, cbuf);
+ if (ret < 0)
+ return ret;
+ }
queue->offset += len;
queue->left -= len;
@@ -1162,16 +1232,22 @@ static void nvmet_tcp_prep_recv_ddgst(struct nvmet_tcp_cmd *cmd)
static int nvmet_tcp_try_recv_data(struct nvmet_tcp_queue *queue)
{
struct nvmet_tcp_cmd *cmd = queue->cmd;
- int ret;
+ int len, ret;
while (msg_data_left(&cmd->recv_msg)) {
- ret = sock_recvmsg(cmd->queue->sock, &cmd->recv_msg,
+ len = sock_recvmsg(cmd->queue->sock, &cmd->recv_msg,
cmd->recv_msg.msg_flags);
- if (ret <= 0)
- return ret;
+ if (len <= 0)
+ return len;
+ if (queue->tls_pskid) {
+ ret = nvmet_tcp_tls_record_ok(cmd->queue,
+ &cmd->recv_msg, cmd->recv_cbuf);
+ if (ret < 0)
+ return ret;
+ }
- cmd->pdu_recv += ret;
- cmd->rbytes_done += ret;
+ cmd->pdu_recv += len;
+ cmd->rbytes_done += len;
}
if (queue->data_digest) {
@@ -1189,20 +1265,30 @@ static int nvmet_tcp_try_recv_data(struct nvmet_tcp_queue *queue)
static int nvmet_tcp_try_recv_ddgst(struct nvmet_tcp_queue *queue)
{
struct nvmet_tcp_cmd *cmd = queue->cmd;
- int ret;
+ int ret, len;
+ char cbuf[CMSG_LEN(sizeof(char))] = {};
struct msghdr msg = { .msg_flags = MSG_DONTWAIT };
struct kvec iov = {
.iov_base = (void *)&cmd->recv_ddgst + queue->offset,
.iov_len = queue->left
};
- ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
+ if (queue->tls_pskid) {
+ msg.msg_control = cbuf;
+ msg.msg_controllen = sizeof(cbuf);
+ }
+ len = kernel_recvmsg(queue->sock, &msg, &iov, 1,
iov.iov_len, msg.msg_flags);
- if (unlikely(ret < 0))
- return ret;
+ if (unlikely(len < 0))
+ return len;
+ if (queue->tls_pskid) {
+ ret = nvmet_tcp_tls_record_ok(queue, &msg, cbuf);
+ if (ret < 0)
+ return ret;
+ }
- queue->offset += ret;
- queue->left -= ret;
+ queue->offset += len;
+ queue->left -= len;
if (queue->left)
return -EAGAIN;
@@ -1280,14 +1366,27 @@ done:
return ret;
}
+static void nvmet_tcp_release_queue(struct kref *kref)
+{
+ struct nvmet_tcp_queue *queue =
+ container_of(kref, struct nvmet_tcp_queue, kref);
+
+ WARN_ON(queue->state != NVMET_TCP_Q_DISCONNECTING);
+ queue_work(nvmet_wq, &queue->release_work);
+}
+
static void nvmet_tcp_schedule_release_queue(struct nvmet_tcp_queue *queue)
{
- spin_lock(&queue->state_lock);
+ spin_lock_bh(&queue->state_lock);
+ if (queue->state == NVMET_TCP_Q_TLS_HANDSHAKE) {
+ /* Socket closed during handshake */
+ tls_handshake_cancel(queue->sock->sk);
+ }
if (queue->state != NVMET_TCP_Q_DISCONNECTING) {
queue->state = NVMET_TCP_Q_DISCONNECTING;
- queue_work(nvmet_wq, &queue->release_work);
+ kref_put(&queue->kref, nvmet_tcp_release_queue);
}
- spin_unlock(&queue->state_lock);
+ spin_unlock_bh(&queue->state_lock);
}
static inline void nvmet_tcp_arm_queue_deadline(struct nvmet_tcp_queue *queue)
@@ -1369,6 +1468,10 @@ static int nvmet_tcp_alloc_cmd(struct nvmet_tcp_queue *queue,
if (!c->r2t_pdu)
goto out_free_data;
+ if (queue->state == NVMET_TCP_Q_TLS_HANDSHAKE) {
+ c->recv_msg.msg_control = c->recv_cbuf;
+ c->recv_msg.msg_controllen = sizeof(c->recv_cbuf);
+ }
c->recv_msg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
list_add_tail(&c->entry, &queue->free_list);
@@ -1482,6 +1585,7 @@ static void nvmet_tcp_release_queue_work(struct work_struct *w)
mutex_unlock(&nvmet_tcp_queue_mutex);
nvmet_tcp_restore_socket_callbacks(queue);
+ cancel_delayed_work_sync(&queue->tls_handshake_tmo_work);
cancel_work_sync(&queue->io_work);
/* stop accepting incoming data */
queue->rcv_state = NVMET_TCP_RECV_ERR;
@@ -1490,12 +1594,12 @@ static void nvmet_tcp_release_queue_work(struct work_struct *w)
nvmet_sq_destroy(&queue->nvme_sq);
cancel_work_sync(&queue->io_work);
nvmet_tcp_free_cmd_data_in_buffers(queue);
- sock_release(queue->sock);
+ /* ->sock will be released by fput() */
+ fput(queue->sock->file);
nvmet_tcp_free_cmds(queue);
if (queue->hdr_digest || queue->data_digest)
nvmet_tcp_free_crypto(queue);
ida_free(&nvmet_tcp_queue_ida, queue->idx);
-
page = virt_to_head_page(queue->pf_cache.va);
__page_frag_cache_drain(page, queue->pf_cache.pagecnt_bias);
kfree(queue);
@@ -1509,8 +1613,13 @@ static void nvmet_tcp_data_ready(struct sock *sk)
read_lock_bh(&sk->sk_callback_lock);
queue = sk->sk_user_data;
- if (likely(queue))
- queue_work_on(queue_cpu(queue), nvmet_tcp_wq, &queue->io_work);
+ if (likely(queue)) {
+ if (queue->data_ready)
+ queue->data_ready(sk);
+ if (queue->state != NVMET_TCP_Q_TLS_HANDSHAKE)
+ queue_work_on(queue_cpu(queue), nvmet_tcp_wq,
+ &queue->io_work);
+ }
read_unlock_bh(&sk->sk_callback_lock);
}
@@ -1618,31 +1727,174 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue)
return ret;
}
-static int nvmet_tcp_alloc_queue(struct nvmet_tcp_port *port,
+#ifdef CONFIG_NVME_TARGET_TCP_TLS
+static int nvmet_tcp_try_peek_pdu(struct nvmet_tcp_queue *queue)
+{
+ struct nvme_tcp_hdr *hdr = &queue->pdu.cmd.hdr;
+ int len, ret;
+ struct kvec iov = {
+ .iov_base = (u8 *)&queue->pdu + queue->offset,
+ .iov_len = sizeof(struct nvme_tcp_hdr),
+ };
+ char cbuf[CMSG_LEN(sizeof(char))] = {};
+ struct msghdr msg = {
+ .msg_control = cbuf,
+ .msg_controllen = sizeof(cbuf),
+ .msg_flags = MSG_PEEK,
+ };
+
+ if (nvmet_port_secure_channel_required(queue->port->nport))
+ return 0;
+
+ len = kernel_recvmsg(queue->sock, &msg, &iov, 1,
+ iov.iov_len, msg.msg_flags);
+ if (unlikely(len < 0)) {
+ pr_debug("queue %d: peek error %d\n",
+ queue->idx, len);
+ return len;
+ }
+
+ ret = nvmet_tcp_tls_record_ok(queue, &msg, cbuf);
+ if (ret < 0)
+ return ret;
+
+ if (len < sizeof(struct nvme_tcp_hdr)) {
+ pr_debug("queue %d: short read, %d bytes missing\n",
+ queue->idx, (int)iov.iov_len - len);
+ return -EAGAIN;
+ }
+ pr_debug("queue %d: hdr type %d hlen %d plen %d size %d\n",
+ queue->idx, hdr->type, hdr->hlen, hdr->plen,
+ (int)sizeof(struct nvme_tcp_icreq_pdu));
+ if (hdr->type == nvme_tcp_icreq &&
+ hdr->hlen == sizeof(struct nvme_tcp_icreq_pdu) &&
+ hdr->plen == (__le32)sizeof(struct nvme_tcp_icreq_pdu)) {
+ pr_debug("queue %d: icreq detected\n",
+ queue->idx);
+ return len;
+ }
+ return 0;
+}
+
+static void nvmet_tcp_tls_handshake_done(void *data, int status,
+ key_serial_t peerid)
+{
+ struct nvmet_tcp_queue *queue = data;
+
+ pr_debug("queue %d: TLS handshake done, key %x, status %d\n",
+ queue->idx, peerid, status);
+ spin_lock_bh(&queue->state_lock);
+ if (WARN_ON(queue->state != NVMET_TCP_Q_TLS_HANDSHAKE)) {
+ spin_unlock_bh(&queue->state_lock);
+ return;
+ }
+ if (!status) {
+ queue->tls_pskid = peerid;
+ queue->state = NVMET_TCP_Q_CONNECTING;
+ } else
+ queue->state = NVMET_TCP_Q_FAILED;
+ spin_unlock_bh(&queue->state_lock);
+
+ cancel_delayed_work_sync(&queue->tls_handshake_tmo_work);
+ if (status)
+ nvmet_tcp_schedule_release_queue(queue);
+ else
+ nvmet_tcp_set_queue_sock(queue);
+ kref_put(&queue->kref, nvmet_tcp_release_queue);
+}
+
+static void nvmet_tcp_tls_handshake_timeout(struct work_struct *w)
+{
+ struct nvmet_tcp_queue *queue = container_of(to_delayed_work(w),
+ struct nvmet_tcp_queue, tls_handshake_tmo_work);
+
+ pr_warn("queue %d: TLS handshake timeout\n", queue->idx);
+ /*
+ * If tls_handshake_cancel() fails we've lost the race with
+ * nvmet_tcp_tls_handshake_done() */
+ if (!tls_handshake_cancel(queue->sock->sk))
+ return;
+ spin_lock_bh(&queue->state_lock);
+ if (WARN_ON(queue->state != NVMET_TCP_Q_TLS_HANDSHAKE)) {
+ spin_unlock_bh(&queue->state_lock);
+ return;
+ }
+ queue->state = NVMET_TCP_Q_FAILED;
+ spin_unlock_bh(&queue->state_lock);
+ nvmet_tcp_schedule_release_queue(queue);
+ kref_put(&queue->kref, nvmet_tcp_release_queue);
+}
+
+static int nvmet_tcp_tls_handshake(struct nvmet_tcp_queue *queue)
+{
+ int ret = -EOPNOTSUPP;
+ struct tls_handshake_args args;
+
+ if (queue->state != NVMET_TCP_Q_TLS_HANDSHAKE) {
+ pr_warn("cannot start TLS in state %d\n", queue->state);
+ return -EINVAL;
+ }
+
+ kref_get(&queue->kref);
+ pr_debug("queue %d: TLS ServerHello\n", queue->idx);
+ memset(&args, 0, sizeof(args));
+ args.ta_sock = queue->sock;
+ args.ta_done = nvmet_tcp_tls_handshake_done;
+ args.ta_data = queue;
+ args.ta_keyring = key_serial(queue->port->nport->keyring);
+ args.ta_timeout_ms = tls_handshake_timeout * 1000;
+
+ ret = tls_server_hello_psk(&args, GFP_KERNEL);
+ if (ret) {
+ kref_put(&queue->kref, nvmet_tcp_release_queue);
+ pr_err("failed to start TLS, err=%d\n", ret);
+ } else {
+ queue_delayed_work(nvmet_wq, &queue->tls_handshake_tmo_work,
+ tls_handshake_timeout * HZ);
+ }
+ return ret;
+}
+#endif
+
+static void nvmet_tcp_alloc_queue(struct nvmet_tcp_port *port,
struct socket *newsock)
{
struct nvmet_tcp_queue *queue;
+ struct file *sock_file = NULL;
int ret;
queue = kzalloc(sizeof(*queue), GFP_KERNEL);
- if (!queue)
- return -ENOMEM;
+ if (!queue) {
+ ret = -ENOMEM;
+ goto out_release;
+ }
INIT_WORK(&queue->release_work, nvmet_tcp_release_queue_work);
INIT_WORK(&queue->io_work, nvmet_tcp_io_work);
+ kref_init(&queue->kref);
queue->sock = newsock;
queue->port = port;
queue->nr_cmds = 0;
spin_lock_init(&queue->state_lock);
- queue->state = NVMET_TCP_Q_CONNECTING;
+ if (queue->port->nport->disc_addr.tsas.tcp.sectype ==
+ NVMF_TCP_SECTYPE_TLS13)
+ queue->state = NVMET_TCP_Q_TLS_HANDSHAKE;
+ else
+ queue->state = NVMET_TCP_Q_CONNECTING;
INIT_LIST_HEAD(&queue->free_list);
init_llist_head(&queue->resp_list);
INIT_LIST_HEAD(&queue->resp_send_list);
+ sock_file = sock_alloc_file(queue->sock, O_CLOEXEC, NULL);
+ if (IS_ERR(sock_file)) {
+ ret = PTR_ERR(sock_file);
+ goto out_free_queue;
+ }
+
queue->idx = ida_alloc(&nvmet_tcp_queue_ida, GFP_KERNEL);
if (queue->idx < 0) {
ret = queue->idx;
- goto out_free_queue;
+ goto out_sock;
}
ret = nvmet_tcp_alloc_cmd(queue, &queue->connect);
@@ -1659,11 +1911,33 @@ static int nvmet_tcp_alloc_queue(struct nvmet_tcp_port *port,
list_add_tail(&queue->queue_list, &nvmet_tcp_queue_list);
mutex_unlock(&nvmet_tcp_queue_mutex);
+#ifdef CONFIG_NVME_TARGET_TCP_TLS
+ INIT_DELAYED_WORK(&queue->tls_handshake_tmo_work,
+ nvmet_tcp_tls_handshake_timeout);
+ if (queue->state == NVMET_TCP_Q_TLS_HANDSHAKE) {
+ struct sock *sk = queue->sock->sk;
+
+ /* Restore the default callbacks before starting upcall */
+ read_lock_bh(&sk->sk_callback_lock);
+ sk->sk_user_data = NULL;
+ sk->sk_data_ready = port->data_ready;
+ read_unlock_bh(&sk->sk_callback_lock);
+ if (!nvmet_tcp_try_peek_pdu(queue)) {
+ if (!nvmet_tcp_tls_handshake(queue))
+ return;
+ /* TLS handshake failed, terminate the connection */
+ goto out_destroy_sq;
+ }
+ /* Not a TLS connection, continue with normal processing */
+ queue->state = NVMET_TCP_Q_CONNECTING;
+ }
+#endif
+
ret = nvmet_tcp_set_queue_sock(queue);
if (ret)
goto out_destroy_sq;
- return 0;
+ return;
out_destroy_sq:
mutex_lock(&nvmet_tcp_queue_mutex);
list_del_init(&queue->queue_list);
@@ -1673,9 +1947,14 @@ out_free_connect:
nvmet_tcp_free_cmd(&queue->connect);
out_ida_remove:
ida_free(&nvmet_tcp_queue_ida, queue->idx);
+out_sock:
+ fput(queue->sock->file);
out_free_queue:
kfree(queue);
- return ret;
+out_release:
+ pr_err("failed to allocate queue, error %d\n", ret);
+ if (!sock_file)
+ sock_release(newsock);
}
static void nvmet_tcp_accept_work(struct work_struct *w)
@@ -1692,11 +1971,7 @@ static void nvmet_tcp_accept_work(struct work_struct *w)
pr_warn("failed to accept err=%d\n", ret);
return;
}
- ret = nvmet_tcp_alloc_queue(port, newsock);
- if (ret) {
- pr_err("failed to allocate queue\n");
- sock_release(newsock);
- }
+ nvmet_tcp_alloc_queue(port, newsock);
}
}
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c
index 6f5e5f0230d3..539d8920c202 100644
--- a/drivers/parisc/power.c
+++ b/drivers/parisc/power.c
@@ -1,38 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
- * linux/drivers/parisc/power.c
- * HP PARISC soft power switch support driver
- *
- * Copyright (c) 2001-2007 Helge Deller <deller@gmx.de>
- * All rights reserved.
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL").
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * HP PARISC soft power switch driver
*
+ * Copyright (c) 2001-2023 Helge Deller <deller@gmx.de>
*
* HINT:
* Support of the soft power switch button may be enabled or disabled at
* runtime through the "/proc/sys/kernel/power" procfs entry.
- */
+ */
#include <linux/module.h>
#include <linux/init.h>
@@ -62,12 +37,12 @@
#define MFCPU_X(rDiagReg, t_ch, t_th, code) \
(DIAG_CODE(code) + ((rDiagReg)<<21) + ((t_ch)<<16) + ((t_th)<<0) )
-
+
#define MTCPU(dr, gr) MFCPU_X(dr, gr, 0, 0x12) /* move value of gr to dr[dr] */
#define MFCPU_C(dr, gr) MFCPU_X(dr, gr, 0, 0x30) /* for dr0 and dr8 only ! */
#define MFCPU_T(dr, gr) MFCPU_X(dr, 0, gr, 0xa0) /* all dr except dr0 and dr8 */
-
-#define __getDIAG(dr) ( { \
+
+#define __getDIAG(dr) ( { \
register unsigned long __res asm("r28");\
__asm__ __volatile__ ( \
".word %1" : "=&r" (__res) : "i" (MFCPU_T(dr,28) ) \
@@ -85,7 +60,7 @@ static void process_shutdown(void)
printk(KERN_ALERT KTHREAD_NAME ": Shutdown requested...\n");
shutdown_timer++;
-
+
/* wait until the button was pressed for 1 second */
if (shutdown_timer == (POWERSWITCH_DOWN_SEC*POWERSWITCH_POLL_PER_SEC)) {
static const char msg[] = "Shutting down...";
@@ -135,7 +110,7 @@ static int kpowerswd(void *param)
button_not_pressed = (gsc_readl(soft_power_reg) & 0x1);
} else {
/*
- * On gecko style machines (e.g. 712/xx and 715/xx)
+ * On gecko style machines (e.g. 712/xx and 715/xx)
* the power switch status is stored in Bit 0 ("the highest bit")
* of CPU diagnose register 25.
* Warning: Some machines never reset the DIAG flag, even if
@@ -161,7 +136,7 @@ static int kpowerswd(void *param)
/*
- * powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2)
+ * powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2)
*/
#if 0
static void powerfail_interrupt(int code, void *x)
@@ -197,6 +172,14 @@ static struct notifier_block parisc_panic_block = {
.priority = INT_MAX,
};
+/* qemu soft power-off function */
+static int qemu_power_off(struct sys_off_data *data)
+{
+ /* this turns the system off via SeaBIOS */
+ *(int *)data->cb_data = 0;
+ pdc_soft_power_button(1);
+ return NOTIFY_DONE;
+}
static int __init power_init(void)
{
@@ -214,19 +197,25 @@ static int __init power_init(void)
ret = pdc_soft_power_button(1);
if (ret != PDC_OK)
soft_power_reg = -1UL;
-
+
switch (soft_power_reg) {
case 0: printk(KERN_INFO DRIVER_NAME ": Gecko-style soft power switch enabled.\n");
break;
-
+
case -1UL: printk(KERN_INFO DRIVER_NAME ": Soft power switch support not available.\n");
return -ENODEV;
-
+
default: printk(KERN_INFO DRIVER_NAME ": Soft power switch at 0x%08lx enabled.\n",
soft_power_reg);
}
- power_task = kthread_run(kpowerswd, (void*)soft_power_reg, KTHREAD_NAME);
+ power_task = NULL;
+ if (running_on_qemu && soft_power_reg)
+ register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT,
+ qemu_power_off, (void *)soft_power_reg);
+ else
+ power_task = kthread_run(kpowerswd, (void*)soft_power_reg,
+ KTHREAD_NAME);
if (IS_ERR(power_task)) {
printk(KERN_ERR DRIVER_NAME ": thread creation failed. Driver not loaded.\n");
pdc_soft_power_button(0);
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 05e7103d1d40..784037837f65 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -2007,7 +2007,7 @@ void * sba_get_iommu(struct parisc_device *pci_hba)
struct parisc_device *sba_dev = parisc_parent(pci_hba);
struct sba_device *sba = dev_get_drvdata(&sba_dev->dev);
char t = sba_dev->id.hw_type;
- int iocnum = (pci_hba->hw_path >> 3); /* rope # */
+ int iocnum = (pci_hba->hw_path >> 3); /* IOC # */
WARN_ON((t != HPHW_IOA) && (t != HPHW_BCPORT));
diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
index 4e5b972c3e26..532d5cbbd344 100644
--- a/drivers/parport/procfs.c
+++ b/drivers/parport/procfs.c
@@ -259,8 +259,12 @@ PARPORT_MAX_SPINTIME_VALUE;
struct parport_sysctl_table {
struct ctl_table_header *port_header;
struct ctl_table_header *devices_header;
- struct ctl_table vars[12];
- struct ctl_table device_dir[2];
+#ifdef CONFIG_PARPORT_1284
+ struct ctl_table vars[10];
+#else
+ struct ctl_table vars[5];
+#endif /* IEEE 1284 support */
+ struct ctl_table device_dir[1];
};
static const struct parport_sysctl_table parport_sysctl_template = {
@@ -341,7 +345,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.proc_handler = do_autoprobe
},
#endif /* IEEE 1284 support */
- {}
},
{
{
@@ -351,19 +354,14 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.mode = 0444,
.proc_handler = do_active_device
},
- {}
},
};
struct parport_device_sysctl_table
{
struct ctl_table_header *sysctl_header;
- struct ctl_table vars[2];
- struct ctl_table device_dir[2];
- struct ctl_table devices_root_dir[2];
- struct ctl_table port_dir[2];
- struct ctl_table parport_dir[2];
- struct ctl_table dev_dir[2];
+ struct ctl_table vars[1];
+ struct ctl_table device_dir[1];
};
static const struct parport_device_sysctl_table
@@ -379,7 +377,6 @@ parport_device_sysctl_template = {
.extra1 = (void*) &parport_min_timeslice_value,
.extra2 = (void*) &parport_max_timeslice_value
},
- {}
},
{
{
@@ -388,17 +385,13 @@ parport_device_sysctl_template = {
.maxlen = 0,
.mode = 0555,
},
- {}
}
};
struct parport_default_sysctl_table
{
struct ctl_table_header *sysctl_header;
- struct ctl_table vars[3];
- struct ctl_table default_dir[2];
- struct ctl_table parport_dir[2];
- struct ctl_table dev_dir[2];
+ struct ctl_table vars[2];
};
static struct parport_default_sysctl_table
@@ -423,7 +416,6 @@ parport_default_sysctl_table = {
.extra1 = (void*) &parport_min_spintime_value,
.extra2 = (void*) &parport_max_spintime_value
},
- {}
}
};
@@ -443,7 +435,9 @@ int parport_proc_register(struct parport *port)
t->vars[0].data = &port->spintime;
for (i = 0; i < 5; i++) {
t->vars[i].extra1 = port;
+#ifdef CONFIG_PARPORT_1284
t->vars[5 + i].extra2 = &port->probe_info[i];
+#endif /* IEEE 1284 support */
}
port_name_len = strnlen(port->name, PARPORT_NAME_MAX_LEN);
diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 5e6b1eb54c64..a771b2259f21 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -556,7 +556,7 @@ EXPORT_SYMBOL(vga_put);
static bool vga_is_firmware_default(struct pci_dev *pdev)
{
-#if defined(CONFIG_X86) || defined(CONFIG_IA64)
+#if defined(CONFIG_X86)
u64 base = screen_info.lfb_base;
u64 size = screen_info.lfb_size;
struct resource *r;
diff --git a/drivers/perf/amlogic/meson_g12_ddr_pmu.c b/drivers/perf/amlogic/meson_g12_ddr_pmu.c
index 8b643888d503..15d52ab3276a 100644
--- a/drivers/perf/amlogic/meson_g12_ddr_pmu.c
+++ b/drivers/perf/amlogic/meson_g12_ddr_pmu.c
@@ -377,6 +377,7 @@ static const struct of_device_id meson_ddr_pmu_dt_match[] = {
},
{}
};
+MODULE_DEVICE_TABLE(of, meson_ddr_pmu_dt_match);
static struct platform_driver g12_ddr_pmu_driver = {
.probe = g12_ddr_pmu_probe,
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index 6b50bc551984..014010d03588 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -112,7 +112,9 @@
#define CMN_DTM_PMEVCNTSR 0x240
-#define CMN_DTM_UNIT_INFO 0x0910
+#define CMN650_DTM_UNIT_INFO 0x0910
+#define CMN_DTM_UNIT_INFO 0x0960
+#define CMN_DTM_UNIT_INFO_DTC_DOMAIN GENMASK_ULL(1, 0)
#define CMN_DTM_NUM_COUNTERS 4
/* Want more local counters? Why not replicate the whole DTM! Ugh... */
@@ -279,16 +281,13 @@ struct arm_cmn_node {
u16 id, logid;
enum cmn_node_type type;
- int dtm;
- union {
- /* DN/HN-F/CXHA */
- struct {
- u8 val : 4;
- u8 count : 4;
- } occupid[SEL_MAX];
- /* XP */
- u8 dtc;
- };
+ u8 dtm;
+ s8 dtc;
+ /* DN/HN-F/CXHA */
+ struct {
+ u8 val : 4;
+ u8 count : 4;
+ } occupid[SEL_MAX];
union {
u8 event[4];
__le32 event_sel;
@@ -538,12 +537,12 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
seq_puts(s, "\n |");
for (x = 0; x < cmn->mesh_x; x++) {
- u8 dtc = cmn->xps[xp_base + x].dtc;
+ s8 dtc = cmn->xps[xp_base + x].dtc;
- if (dtc & (dtc - 1))
+ if (dtc < 0)
seq_puts(s, " DTC ?? |");
else
- seq_printf(s, " DTC %ld |", __ffs(dtc));
+ seq_printf(s, " DTC %d |", dtc);
}
seq_puts(s, "\n |");
for (x = 0; x < cmn->mesh_x; x++)
@@ -587,8 +586,7 @@ static void arm_cmn_debugfs_init(struct arm_cmn *cmn, int id) {}
struct arm_cmn_hw_event {
struct arm_cmn_node *dn;
u64 dtm_idx[4];
- unsigned int dtc_idx;
- u8 dtcs_used;
+ s8 dtc_idx[CMN_MAX_DTCS];
u8 num_dns;
u8 dtm_offset;
bool wide_sel;
@@ -598,6 +596,10 @@ struct arm_cmn_hw_event {
#define for_each_hw_dn(hw, dn, i) \
for (i = 0, dn = hw->dn; i < hw->num_dns; i++, dn++)
+/* @i is the DTC number, @idx is the counter index on that DTC */
+#define for_each_hw_dtc_idx(hw, i, idx) \
+ for (int i = 0, idx; i < CMN_MAX_DTCS; i++) if ((idx = hw->dtc_idx[i]) >= 0)
+
static struct arm_cmn_hw_event *to_cmn_hw(struct perf_event *event)
{
BUILD_BUG_ON(sizeof(struct arm_cmn_hw_event) > offsetof(struct hw_perf_event, target));
@@ -1427,12 +1429,11 @@ static void arm_cmn_init_counter(struct perf_event *event)
{
struct arm_cmn *cmn = to_cmn(event->pmu);
struct arm_cmn_hw_event *hw = to_cmn_hw(event);
- unsigned int i, pmevcnt = CMN_DT_PMEVCNT(hw->dtc_idx);
u64 count;
- for (i = 0; hw->dtcs_used & (1U << i); i++) {
- writel_relaxed(CMN_COUNTER_INIT, cmn->dtc[i].base + pmevcnt);
- cmn->dtc[i].counters[hw->dtc_idx] = event;
+ for_each_hw_dtc_idx(hw, i, idx) {
+ writel_relaxed(CMN_COUNTER_INIT, cmn->dtc[i].base + CMN_DT_PMEVCNT(idx));
+ cmn->dtc[i].counters[idx] = event;
}
count = arm_cmn_read_dtm(cmn, hw, false);
@@ -1445,11 +1446,9 @@ static void arm_cmn_event_read(struct perf_event *event)
struct arm_cmn_hw_event *hw = to_cmn_hw(event);
u64 delta, new, prev;
unsigned long flags;
- unsigned int i;
- if (hw->dtc_idx == CMN_DT_NUM_COUNTERS) {
- i = __ffs(hw->dtcs_used);
- delta = arm_cmn_read_cc(cmn->dtc + i);
+ if (CMN_EVENT_TYPE(event) == CMN_TYPE_DTC) {
+ delta = arm_cmn_read_cc(cmn->dtc + hw->dtc_idx[0]);
local64_add(delta, &event->count);
return;
}
@@ -1459,8 +1458,8 @@ static void arm_cmn_event_read(struct perf_event *event)
delta = new - prev;
local_irq_save(flags);
- for (i = 0; hw->dtcs_used & (1U << i); i++) {
- new = arm_cmn_read_counter(cmn->dtc + i, hw->dtc_idx);
+ for_each_hw_dtc_idx(hw, i, idx) {
+ new = arm_cmn_read_counter(cmn->dtc + i, idx);
delta += new << 16;
}
local_irq_restore(flags);
@@ -1516,7 +1515,7 @@ static void arm_cmn_event_start(struct perf_event *event, int flags)
int i;
if (type == CMN_TYPE_DTC) {
- i = __ffs(hw->dtcs_used);
+ i = hw->dtc_idx[0];
writeq_relaxed(CMN_CC_INIT, cmn->dtc[i].base + CMN_DT_PMCCNTR);
cmn->dtc[i].cc_active = true;
} else if (type == CMN_TYPE_WP) {
@@ -1547,7 +1546,7 @@ static void arm_cmn_event_stop(struct perf_event *event, int flags)
int i;
if (type == CMN_TYPE_DTC) {
- i = __ffs(hw->dtcs_used);
+ i = hw->dtc_idx[0];
cmn->dtc[i].cc_active = false;
} else if (type == CMN_TYPE_WP) {
int wp_idx = arm_cmn_wp_idx(event);
@@ -1571,7 +1570,7 @@ struct arm_cmn_val {
u8 dtm_count[CMN_MAX_DTMS];
u8 occupid[CMN_MAX_DTMS][SEL_MAX];
u8 wp[CMN_MAX_DTMS][4];
- int dtc_count;
+ int dtc_count[CMN_MAX_DTCS];
bool cycles;
};
@@ -1592,7 +1591,8 @@ static void arm_cmn_val_add_event(struct arm_cmn *cmn, struct arm_cmn_val *val,
return;
}
- val->dtc_count++;
+ for_each_hw_dtc_idx(hw, dtc, idx)
+ val->dtc_count[dtc]++;
for_each_hw_dn(hw, dn, i) {
int wp_idx, dtm = dn->dtm, sel = hw->filter_sel;
@@ -1639,8 +1639,9 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event)
goto done;
}
- if (val->dtc_count == CMN_DT_NUM_COUNTERS)
- goto done;
+ for (i = 0; i < CMN_MAX_DTCS; i++)
+ if (val->dtc_count[i] == CMN_DT_NUM_COUNTERS)
+ goto done;
for_each_hw_dn(hw, dn, i) {
int wp_idx, wp_cmb, dtm = dn->dtm, sel = hw->filter_sel;
@@ -1733,12 +1734,19 @@ static int arm_cmn_event_init(struct perf_event *event)
hw->dn = arm_cmn_node(cmn, type);
if (!hw->dn)
return -EINVAL;
+
+ memset(hw->dtc_idx, -1, sizeof(hw->dtc_idx));
for (dn = hw->dn; dn->type == type; dn++) {
if (bynodeid && dn->id != nodeid) {
hw->dn++;
continue;
}
hw->num_dns++;
+ if (dn->dtc < 0)
+ memset(hw->dtc_idx, 0, cmn->num_dtcs);
+ else
+ hw->dtc_idx[dn->dtc] = 0;
+
if (bynodeid)
break;
}
@@ -1750,12 +1758,6 @@ static int arm_cmn_event_init(struct perf_event *event)
nodeid, nid.x, nid.y, nid.port, nid.dev, type);
return -EINVAL;
}
- /*
- * Keep assuming non-cycles events count in all DTC domains; turns out
- * it's hard to make a worthwhile optimisation around this, short of
- * going all-in with domain-local counter allocation as well.
- */
- hw->dtcs_used = (1U << cmn->num_dtcs) - 1;
return arm_cmn_validate_group(cmn, event);
}
@@ -1781,46 +1783,48 @@ static void arm_cmn_event_clear(struct arm_cmn *cmn, struct perf_event *event,
}
memset(hw->dtm_idx, 0, sizeof(hw->dtm_idx));
- for (i = 0; hw->dtcs_used & (1U << i); i++)
- cmn->dtc[i].counters[hw->dtc_idx] = NULL;
+ for_each_hw_dtc_idx(hw, j, idx)
+ cmn->dtc[j].counters[idx] = NULL;
}
static int arm_cmn_event_add(struct perf_event *event, int flags)
{
struct arm_cmn *cmn = to_cmn(event->pmu);
struct arm_cmn_hw_event *hw = to_cmn_hw(event);
- struct arm_cmn_dtc *dtc = &cmn->dtc[0];
struct arm_cmn_node *dn;
enum cmn_node_type type = CMN_EVENT_TYPE(event);
- unsigned int i, dtc_idx, input_sel;
+ unsigned int input_sel, i = 0;
if (type == CMN_TYPE_DTC) {
- i = 0;
while (cmn->dtc[i].cycles)
if (++i == cmn->num_dtcs)
return -ENOSPC;
cmn->dtc[i].cycles = event;
- hw->dtc_idx = CMN_DT_NUM_COUNTERS;
- hw->dtcs_used = 1U << i;
+ hw->dtc_idx[0] = i;
if (flags & PERF_EF_START)
arm_cmn_event_start(event, 0);
return 0;
}
- /* Grab a free global counter first... */
- dtc_idx = 0;
- while (dtc->counters[dtc_idx])
- if (++dtc_idx == CMN_DT_NUM_COUNTERS)
- return -ENOSPC;
-
- hw->dtc_idx = dtc_idx;
+ /* Grab the global counters first... */
+ for_each_hw_dtc_idx(hw, j, idx) {
+ if (cmn->part == PART_CMN600 && j > 0) {
+ idx = hw->dtc_idx[0];
+ } else {
+ idx = 0;
+ while (cmn->dtc[j].counters[idx])
+ if (++idx == CMN_DT_NUM_COUNTERS)
+ goto free_dtms;
+ }
+ hw->dtc_idx[j] = idx;
+ }
- /* ...then the local counters to feed it. */
+ /* ...then the local counters to feed them */
for_each_hw_dn(hw, dn, i) {
struct arm_cmn_dtm *dtm = &cmn->dtms[dn->dtm] + hw->dtm_offset;
- unsigned int dtm_idx, shift;
+ unsigned int dtm_idx, shift, d = max_t(int, dn->dtc, 0);
u64 reg;
dtm_idx = 0;
@@ -1839,11 +1843,11 @@ static int arm_cmn_event_add(struct perf_event *event, int flags)
tmp = dtm->wp_event[wp_idx ^ 1];
if (tmp >= 0 && CMN_EVENT_WP_COMBINE(event) !=
- CMN_EVENT_WP_COMBINE(dtc->counters[tmp]))
+ CMN_EVENT_WP_COMBINE(cmn->dtc[d].counters[tmp]))
goto free_dtms;
input_sel = CMN__PMEVCNT0_INPUT_SEL_WP + wp_idx;
- dtm->wp_event[wp_idx] = dtc_idx;
+ dtm->wp_event[wp_idx] = hw->dtc_idx[d];
writel_relaxed(cfg, dtm->base + CMN_DTM_WPn_CONFIG(wp_idx));
} else {
struct arm_cmn_nodeid nid = arm_cmn_nid(cmn, dn->id);
@@ -1863,7 +1867,7 @@ static int arm_cmn_event_add(struct perf_event *event, int flags)
dtm->input_sel[dtm_idx] = input_sel;
shift = CMN__PMEVCNTn_GLOBAL_NUM_SHIFT(dtm_idx);
dtm->pmu_config_low &= ~(CMN__PMEVCNT0_GLOBAL_NUM << shift);
- dtm->pmu_config_low |= FIELD_PREP(CMN__PMEVCNT0_GLOBAL_NUM, dtc_idx) << shift;
+ dtm->pmu_config_low |= FIELD_PREP(CMN__PMEVCNT0_GLOBAL_NUM, hw->dtc_idx[d]) << shift;
dtm->pmu_config_low |= CMN__PMEVCNT_PAIRED(dtm_idx);
reg = (u64)le32_to_cpu(dtm->pmu_config_high) << 32 | dtm->pmu_config_low;
writeq_relaxed(reg, dtm->base + CMN_DTM_PMU_CONFIG);
@@ -1891,7 +1895,7 @@ static void arm_cmn_event_del(struct perf_event *event, int flags)
arm_cmn_event_stop(event, PERF_EF_UPDATE);
if (type == CMN_TYPE_DTC)
- cmn->dtc[__ffs(hw->dtcs_used)].cycles = NULL;
+ cmn->dtc[hw->dtc_idx[0]].cycles = NULL;
else
arm_cmn_event_clear(cmn, event, hw->num_dns);
}
@@ -2072,7 +2076,6 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
{
struct arm_cmn_node *dn, *xp;
int dtc_idx = 0;
- u8 dtcs_present = (1 << cmn->num_dtcs) - 1;
cmn->dtc = devm_kcalloc(cmn->dev, cmn->num_dtcs, sizeof(cmn->dtc[0]), GFP_KERNEL);
if (!cmn->dtc)
@@ -2082,23 +2085,26 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
cmn->xps = arm_cmn_node(cmn, CMN_TYPE_XP);
+ if (cmn->part == PART_CMN600 && cmn->num_dtcs > 1) {
+ /* We do at least know that a DTC's XP must be in that DTC's domain */
+ dn = arm_cmn_node(cmn, CMN_TYPE_DTC);
+ for (int i = 0; i < cmn->num_dtcs; i++)
+ arm_cmn_node_to_xp(cmn, dn + i)->dtc = i;
+ }
+
for (dn = cmn->dns; dn->type; dn++) {
- if (dn->type == CMN_TYPE_XP) {
- dn->dtc &= dtcs_present;
+ if (dn->type == CMN_TYPE_XP)
continue;
- }
xp = arm_cmn_node_to_xp(cmn, dn);
+ dn->dtc = xp->dtc;
dn->dtm = xp->dtm;
if (cmn->multi_dtm)
dn->dtm += arm_cmn_nid(cmn, dn->id).port / 2;
if (dn->type == CMN_TYPE_DTC) {
- int err;
- /* We do at least know that a DTC's XP must be in that DTC's domain */
- if (xp->dtc == 0xf)
- xp->dtc = 1 << dtc_idx;
- err = arm_cmn_init_dtc(cmn, dn, dtc_idx++);
+ int err = arm_cmn_init_dtc(cmn, dn, dtc_idx++);
+
if (err)
return err;
}
@@ -2117,6 +2123,16 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
return 0;
}
+static unsigned int arm_cmn_dtc_domain(struct arm_cmn *cmn, void __iomem *xp_region)
+{
+ int offset = CMN_DTM_UNIT_INFO;
+
+ if (cmn->part == PART_CMN650 || cmn->part == PART_CI700)
+ offset = CMN650_DTM_UNIT_INFO;
+
+ return FIELD_GET(CMN_DTM_UNIT_INFO_DTC_DOMAIN, readl_relaxed(xp_region + offset));
+}
+
static void arm_cmn_init_node_info(struct arm_cmn *cmn, u32 offset, struct arm_cmn_node *node)
{
int level;
@@ -2246,9 +2262,9 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
cmn->mesh_x = xp->logid;
if (cmn->part == PART_CMN600)
- xp->dtc = 0xf;
+ xp->dtc = -1;
else
- xp->dtc = 1 << readl_relaxed(xp_region + CMN_DTM_UNIT_INFO);
+ xp->dtc = arm_cmn_dtc_domain(cmn, xp_region);
xp->dtm = dtm - cmn->dtms;
arm_cmn_init_dtm(dtm++, xp, 0);
diff --git a/drivers/perf/arm_cspmu/Kconfig b/drivers/perf/arm_cspmu/Kconfig
index 25d25ded0983..6f4e28fc84a2 100644
--- a/drivers/perf/arm_cspmu/Kconfig
+++ b/drivers/perf/arm_cspmu/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
#
-# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
config ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU
tristate "ARM Coresight Architecture PMU"
@@ -10,3 +10,20 @@ config ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU
based on ARM CoreSight PMU architecture. Note that this PMU
architecture does not have relationship with the ARM CoreSight
Self-Hosted Tracing.
+
+config NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU
+ tristate "NVIDIA Coresight Architecture PMU"
+ depends on ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU
+ help
+ Provides NVIDIA specific attributes for performance monitoring unit
+ (PMU) devices based on ARM CoreSight PMU architecture.
+
+config AMPERE_CORESIGHT_PMU_ARCH_SYSTEM_PMU
+ tristate "Ampere Coresight Architecture PMU"
+ depends on ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU
+ help
+ Provides Ampere specific attributes for performance monitoring unit
+ (PMU) devices based on ARM CoreSight PMU architecture.
+
+ In the first phase, the driver enables support on MCU PMU used in
+ AmpereOne SoC family.
diff --git a/drivers/perf/arm_cspmu/Makefile b/drivers/perf/arm_cspmu/Makefile
index fedb17df982d..220a734efd54 100644
--- a/drivers/perf/arm_cspmu/Makefile
+++ b/drivers/perf/arm_cspmu/Makefile
@@ -1,6 +1,10 @@
-# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU) += arm_cspmu_module.o
-arm_cspmu_module-y := arm_cspmu.o nvidia_cspmu.o
+
+arm_cspmu_module-y := arm_cspmu.o
+
+obj-$(CONFIG_NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU) += nvidia_cspmu.o
+obj-$(CONFIG_AMPERE_CORESIGHT_PMU_ARCH_SYSTEM_PMU) += ampere_cspmu.o
diff --git a/drivers/perf/arm_cspmu/ampere_cspmu.c b/drivers/perf/arm_cspmu/ampere_cspmu.c
new file mode 100644
index 000000000000..f146a455e838
--- /dev/null
+++ b/drivers/perf/arm_cspmu/ampere_cspmu.c
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Ampere SoC PMU (Performance Monitor Unit)
+ *
+ * Copyright (c) 2023, Ampere Computing LLC
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+
+#include "arm_cspmu.h"
+
+#define PMAUXR0 0xD80
+#define PMAUXR1 0xD84
+#define PMAUXR2 0xD88
+#define PMAUXR3 0xD8C
+
+#define to_ampere_cspmu_ctx(cspmu) ((struct ampere_cspmu_ctx *)(cspmu->impl.ctx))
+
+struct ampere_cspmu_ctx {
+ const char *name;
+ struct attribute **event_attr;
+ struct attribute **format_attr;
+};
+
+static DEFINE_IDA(mcu_pmu_ida);
+
+#define SOC_PMU_EVENT_ATTR_EXTRACTOR(_name, _config, _start, _end) \
+ static inline u32 get_##_name(const struct perf_event *event) \
+ { \
+ return FIELD_GET(GENMASK_ULL(_end, _start), \
+ event->attr._config); \
+ } \
+
+SOC_PMU_EVENT_ATTR_EXTRACTOR(event, config, 0, 8);
+SOC_PMU_EVENT_ATTR_EXTRACTOR(threshold, config1, 0, 7);
+SOC_PMU_EVENT_ATTR_EXTRACTOR(rank, config1, 8, 23);
+SOC_PMU_EVENT_ATTR_EXTRACTOR(bank, config1, 24, 55);
+
+static struct attribute *ampereone_mcu_pmu_event_attrs[] = {
+ ARM_CSPMU_EVENT_ATTR(cycle_count, 0x00),
+ ARM_CSPMU_EVENT_ATTR(act_sent, 0x01),
+ ARM_CSPMU_EVENT_ATTR(pre_sent, 0x02),
+ ARM_CSPMU_EVENT_ATTR(rd_sent, 0x03),
+ ARM_CSPMU_EVENT_ATTR(rda_sent, 0x04),
+ ARM_CSPMU_EVENT_ATTR(wr_sent, 0x05),
+ ARM_CSPMU_EVENT_ATTR(wra_sent, 0x06),
+ ARM_CSPMU_EVENT_ATTR(pd_entry_vld, 0x07),
+ ARM_CSPMU_EVENT_ATTR(sref_entry_vld, 0x08),
+ ARM_CSPMU_EVENT_ATTR(prea_sent, 0x09),
+ ARM_CSPMU_EVENT_ATTR(pre_sb_sent, 0x0a),
+ ARM_CSPMU_EVENT_ATTR(ref_sent, 0x0b),
+ ARM_CSPMU_EVENT_ATTR(rfm_sent, 0x0c),
+ ARM_CSPMU_EVENT_ATTR(ref_sb_sent, 0x0d),
+ ARM_CSPMU_EVENT_ATTR(rfm_sb_sent, 0x0e),
+ ARM_CSPMU_EVENT_ATTR(rd_rda_sent, 0x0f),
+ ARM_CSPMU_EVENT_ATTR(wr_wra_sent, 0x10),
+ ARM_CSPMU_EVENT_ATTR(raw_hazard, 0x11),
+ ARM_CSPMU_EVENT_ATTR(war_hazard, 0x12),
+ ARM_CSPMU_EVENT_ATTR(waw_hazard, 0x13),
+ ARM_CSPMU_EVENT_ATTR(rar_hazard, 0x14),
+ ARM_CSPMU_EVENT_ATTR(raw_war_waw_hazard, 0x15),
+ ARM_CSPMU_EVENT_ATTR(hprd_lprd_wr_req_vld, 0x16),
+ ARM_CSPMU_EVENT_ATTR(lprd_req_vld, 0x17),
+ ARM_CSPMU_EVENT_ATTR(hprd_req_vld, 0x18),
+ ARM_CSPMU_EVENT_ATTR(hprd_lprd_req_vld, 0x19),
+ ARM_CSPMU_EVENT_ATTR(prefetch_tgt, 0x1a),
+ ARM_CSPMU_EVENT_ATTR(wr_req_vld, 0x1b),
+ ARM_CSPMU_EVENT_ATTR(partial_wr_req_vld, 0x1c),
+ ARM_CSPMU_EVENT_ATTR(rd_retry, 0x1d),
+ ARM_CSPMU_EVENT_ATTR(wr_retry, 0x1e),
+ ARM_CSPMU_EVENT_ATTR(retry_gnt, 0x1f),
+ ARM_CSPMU_EVENT_ATTR(rank_change, 0x20),
+ ARM_CSPMU_EVENT_ATTR(dir_change, 0x21),
+ ARM_CSPMU_EVENT_ATTR(rank_dir_change, 0x22),
+ ARM_CSPMU_EVENT_ATTR(rank_active, 0x23),
+ ARM_CSPMU_EVENT_ATTR(rank_idle, 0x24),
+ ARM_CSPMU_EVENT_ATTR(rank_pd, 0x25),
+ ARM_CSPMU_EVENT_ATTR(rank_sref, 0x26),
+ ARM_CSPMU_EVENT_ATTR(queue_fill_gt_thresh, 0x27),
+ ARM_CSPMU_EVENT_ATTR(queue_rds_gt_thresh, 0x28),
+ ARM_CSPMU_EVENT_ATTR(queue_wrs_gt_thresh, 0x29),
+ ARM_CSPMU_EVENT_ATTR(phy_updt_complt, 0x2a),
+ ARM_CSPMU_EVENT_ATTR(tz_fail, 0x2b),
+ ARM_CSPMU_EVENT_ATTR(dram_errc, 0x2c),
+ ARM_CSPMU_EVENT_ATTR(dram_errd, 0x2d),
+ ARM_CSPMU_EVENT_ATTR(read_data_return, 0x32),
+ ARM_CSPMU_EVENT_ATTR(chi_wr_data_delta, 0x33),
+ ARM_CSPMU_EVENT_ATTR(zq_start, 0x34),
+ ARM_CSPMU_EVENT_ATTR(zq_latch, 0x35),
+ ARM_CSPMU_EVENT_ATTR(wr_fifo_full, 0x36),
+ ARM_CSPMU_EVENT_ATTR(info_fifo_full, 0x37),
+ ARM_CSPMU_EVENT_ATTR(cmd_fifo_full, 0x38),
+ ARM_CSPMU_EVENT_ATTR(dfi_nop, 0x39),
+ ARM_CSPMU_EVENT_ATTR(dfi_cmd, 0x3a),
+ ARM_CSPMU_EVENT_ATTR(rd_run_len, 0x3b),
+ ARM_CSPMU_EVENT_ATTR(wr_run_len, 0x3c),
+
+ ARM_CSPMU_EVENT_ATTR(cycles, ARM_CSPMU_EVT_CYCLES_DEFAULT),
+ NULL,
+};
+
+static struct attribute *ampereone_mcu_format_attrs[] = {
+ ARM_CSPMU_FORMAT_EVENT_ATTR,
+ ARM_CSPMU_FORMAT_ATTR(threshold, "config1:0-7"),
+ ARM_CSPMU_FORMAT_ATTR(rank, "config1:8-23"),
+ ARM_CSPMU_FORMAT_ATTR(bank, "config1:24-55"),
+ NULL,
+};
+
+static struct attribute **
+ampere_cspmu_get_event_attrs(const struct arm_cspmu *cspmu)
+{
+ const struct ampere_cspmu_ctx *ctx = to_ampere_cspmu_ctx(cspmu);
+
+ return ctx->event_attr;
+}
+
+static struct attribute **
+ampere_cspmu_get_format_attrs(const struct arm_cspmu *cspmu)
+{
+ const struct ampere_cspmu_ctx *ctx = to_ampere_cspmu_ctx(cspmu);
+
+ return ctx->format_attr;
+}
+
+static const char *
+ampere_cspmu_get_name(const struct arm_cspmu *cspmu)
+{
+ const struct ampere_cspmu_ctx *ctx = to_ampere_cspmu_ctx(cspmu);
+
+ return ctx->name;
+}
+
+static u32 ampere_cspmu_event_filter(const struct perf_event *event)
+{
+ /*
+ * PMEVFILTR or PMCCFILTR aren't used in Ampere SoC PMU but are marked
+ * as RES0. Make sure, PMCCFILTR is written zero.
+ */
+ return 0;
+}
+
+static void ampere_cspmu_set_ev_filter(struct arm_cspmu *cspmu,
+ struct hw_perf_event *hwc,
+ u32 filter)
+{
+ struct perf_event *event;
+ unsigned int idx;
+ u32 threshold, rank, bank;
+
+ /*
+ * At this point, all the events have the same filter settings.
+ * Therefore, take the first event and use its configuration.
+ */
+ idx = find_first_bit(cspmu->hw_events.used_ctrs,
+ cspmu->cycle_counter_logical_idx);
+
+ event = cspmu->hw_events.events[idx];
+
+ threshold = get_threshold(event);
+ rank = get_rank(event);
+ bank = get_bank(event);
+
+ writel(threshold, cspmu->base0 + PMAUXR0);
+ writel(rank, cspmu->base0 + PMAUXR1);
+ writel(bank, cspmu->base0 + PMAUXR2);
+}
+
+static int ampere_cspmu_validate_configs(struct perf_event *event,
+ struct perf_event *event2)
+{
+ if (get_threshold(event) != get_threshold(event2) ||
+ get_rank(event) != get_rank(event2) ||
+ get_bank(event) != get_bank(event2))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ampere_cspmu_validate_event(struct arm_cspmu *cspmu,
+ struct perf_event *new)
+{
+ struct perf_event *curr, *leader = new->group_leader;
+ unsigned int idx;
+ int ret;
+
+ ret = ampere_cspmu_validate_configs(new, leader);
+ if (ret)
+ return ret;
+
+ /* We compare the global filter settings to the existing events */
+ idx = find_first_bit(cspmu->hw_events.used_ctrs,
+ cspmu->cycle_counter_logical_idx);
+
+ /* This is the first event, thus any configuration is fine */
+ if (idx == cspmu->cycle_counter_logical_idx)
+ return 0;
+
+ curr = cspmu->hw_events.events[idx];
+
+ return ampere_cspmu_validate_configs(curr, new);
+}
+
+static char *ampere_cspmu_format_name(const struct arm_cspmu *cspmu,
+ const char *name_pattern)
+{
+ struct device *dev = cspmu->dev;
+ int id;
+
+ id = ida_alloc(&mcu_pmu_ida, GFP_KERNEL);
+ if (id < 0)
+ return ERR_PTR(id);
+
+ return devm_kasprintf(dev, GFP_KERNEL, name_pattern, id);
+}
+
+static int ampere_cspmu_init_ops(struct arm_cspmu *cspmu)
+{
+ struct device *dev = cspmu->dev;
+ struct ampere_cspmu_ctx *ctx;
+ struct arm_cspmu_impl_ops *impl_ops = &cspmu->impl.ops;
+
+ ctx = devm_kzalloc(dev, sizeof(struct ampere_cspmu_ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->event_attr = ampereone_mcu_pmu_event_attrs;
+ ctx->format_attr = ampereone_mcu_format_attrs;
+ ctx->name = ampere_cspmu_format_name(cspmu, "ampere_mcu_pmu_%d");
+ if (IS_ERR_OR_NULL(ctx->name))
+ return ctx->name ? PTR_ERR(ctx->name) : -ENOMEM;
+
+ cspmu->impl.ctx = ctx;
+
+ impl_ops->event_filter = ampere_cspmu_event_filter;
+ impl_ops->set_ev_filter = ampere_cspmu_set_ev_filter;
+ impl_ops->validate_event = ampere_cspmu_validate_event;
+ impl_ops->get_name = ampere_cspmu_get_name;
+ impl_ops->get_event_attrs = ampere_cspmu_get_event_attrs;
+ impl_ops->get_format_attrs = ampere_cspmu_get_format_attrs;
+
+ return 0;
+}
+
+/* Match all Ampere Coresight PMU devices */
+static const struct arm_cspmu_impl_match ampere_cspmu_param = {
+ .pmiidr_val = ARM_CSPMU_IMPL_ID_AMPERE,
+ .module = THIS_MODULE,
+ .impl_init_ops = ampere_cspmu_init_ops
+};
+
+static int __init ampere_cspmu_init(void)
+{
+ int ret;
+
+ ret = arm_cspmu_impl_register(&ampere_cspmu_param);
+ if (ret)
+ pr_err("ampere_cspmu backend registration error: %d\n", ret);
+
+ return ret;
+}
+
+static void __exit ampere_cspmu_exit(void)
+{
+ arm_cspmu_impl_unregister(&ampere_cspmu_param);
+}
+
+module_init(ampere_cspmu_init);
+module_exit(ampere_cspmu_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index f0e6d14281d6..42b72042f6b3 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -16,7 +16,7 @@
* The user should refer to the vendor technical documentation to get details
* about the supported events.
*
- * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ * Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
*/
@@ -26,11 +26,11 @@
#include <linux/interrupt.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include "arm_cspmu.h"
-#include "nvidia_cspmu.h"
#define PMUNAME "arm_cspmu"
#define DRVNAME "arm-cs-arch-pmu"
@@ -112,11 +112,13 @@
*/
#define HILOHI_MAX_POLL 1000
-/* JEDEC-assigned JEP106 identification code */
-#define ARM_CSPMU_IMPL_ID_NVIDIA 0x36B
-
static unsigned long arm_cspmu_cpuhp_state;
+static DEFINE_MUTEX(arm_cspmu_lock);
+
+static void arm_cspmu_set_ev_filter(struct arm_cspmu *cspmu,
+ struct hw_perf_event *hwc, u32 filter);
+
static struct acpi_apmt_node *arm_cspmu_apmt_node(struct device *dev)
{
return *(struct acpi_apmt_node **)dev_get_platdata(dev);
@@ -373,27 +375,45 @@ static struct attribute_group arm_cspmu_cpumask_attr_group = {
.attrs = arm_cspmu_cpumask_attrs,
};
-struct impl_match {
- u32 pmiidr;
- u32 mask;
- int (*impl_init_ops)(struct arm_cspmu *cspmu);
-};
-
-static const struct impl_match impl_match[] = {
+static struct arm_cspmu_impl_match impl_match[] = {
{
- .pmiidr = ARM_CSPMU_IMPL_ID_NVIDIA,
- .mask = ARM_CSPMU_PMIIDR_IMPLEMENTER,
- .impl_init_ops = nv_cspmu_init_ops
+ .module_name = "nvidia_cspmu",
+ .pmiidr_val = ARM_CSPMU_IMPL_ID_NVIDIA,
+ .pmiidr_mask = ARM_CSPMU_PMIIDR_IMPLEMENTER,
+ .module = NULL,
+ .impl_init_ops = NULL,
},
- {}
+ {
+ .module_name = "ampere_cspmu",
+ .pmiidr_val = ARM_CSPMU_IMPL_ID_AMPERE,
+ .pmiidr_mask = ARM_CSPMU_PMIIDR_IMPLEMENTER,
+ .module = NULL,
+ .impl_init_ops = NULL,
+ },
+
+ {0}
};
+static struct arm_cspmu_impl_match *arm_cspmu_impl_match_get(u32 pmiidr)
+{
+ struct arm_cspmu_impl_match *match = impl_match;
+
+ for (; match->pmiidr_val; match++) {
+ u32 mask = match->pmiidr_mask;
+
+ if ((match->pmiidr_val & mask) == (pmiidr & mask))
+ return match;
+ }
+
+ return NULL;
+}
+
static int arm_cspmu_init_impl_ops(struct arm_cspmu *cspmu)
{
- int ret;
+ int ret = 0;
struct arm_cspmu_impl_ops *impl_ops = &cspmu->impl.ops;
struct acpi_apmt_node *apmt_node = arm_cspmu_apmt_node(cspmu->dev);
- const struct impl_match *match = impl_match;
+ struct arm_cspmu_impl_match *match;
/*
* Get PMU implementer and product id from APMT node.
@@ -405,17 +425,36 @@ static int arm_cspmu_init_impl_ops(struct arm_cspmu *cspmu)
readl(cspmu->base0 + PMIIDR);
/* Find implementer specific attribute ops. */
- for (; match->pmiidr; match++) {
- const u32 mask = match->mask;
+ match = arm_cspmu_impl_match_get(cspmu->impl.pmiidr);
+
+ /* Load implementer module and initialize the callbacks. */
+ if (match) {
+ mutex_lock(&arm_cspmu_lock);
+
+ if (match->impl_init_ops) {
+ /* Prevent unload until PMU registration is done. */
+ if (try_module_get(match->module)) {
+ cspmu->impl.module = match->module;
+ cspmu->impl.match = match;
+ ret = match->impl_init_ops(cspmu);
+ if (ret)
+ module_put(match->module);
+ } else {
+ WARN(1, "arm_cspmu failed to get module: %s\n",
+ match->module_name);
+ ret = -EINVAL;
+ }
+ } else {
+ request_module_nowait(match->module_name);
+ ret = -EPROBE_DEFER;
+ }
- if ((match->pmiidr & mask) == (cspmu->impl.pmiidr & mask)) {
- ret = match->impl_init_ops(cspmu);
- if (ret)
- return ret;
+ mutex_unlock(&arm_cspmu_lock);
- break;
- }
- }
+ if (ret)
+ return ret;
+ } else
+ cspmu->impl.module = THIS_MODULE;
/* Use default callbacks if implementer doesn't provide one. */
CHECK_DEFAULT_IMPL_OPS(impl_ops, get_event_attrs);
@@ -426,6 +465,7 @@ static int arm_cspmu_init_impl_ops(struct arm_cspmu *cspmu)
CHECK_DEFAULT_IMPL_OPS(impl_ops, event_type);
CHECK_DEFAULT_IMPL_OPS(impl_ops, event_filter);
CHECK_DEFAULT_IMPL_OPS(impl_ops, event_attr_is_visible);
+ CHECK_DEFAULT_IMPL_OPS(impl_ops, set_ev_filter);
return 0;
}
@@ -478,11 +518,6 @@ arm_cspmu_alloc_attr_group(struct arm_cspmu *cspmu)
struct attribute_group **attr_groups = NULL;
struct device *dev = cspmu->dev;
const struct arm_cspmu_impl_ops *impl_ops = &cspmu->impl.ops;
- int ret;
-
- ret = arm_cspmu_init_impl_ops(cspmu);
- if (ret)
- return NULL;
cspmu->identifier = impl_ops->get_identifier(cspmu);
cspmu->name = impl_ops->get_name(cspmu);
@@ -549,7 +584,7 @@ static void arm_cspmu_disable(struct pmu *pmu)
static int arm_cspmu_get_event_idx(struct arm_cspmu_hw_events *hw_events,
struct perf_event *event)
{
- int idx;
+ int idx, ret;
struct arm_cspmu *cspmu = to_arm_cspmu(event->pmu);
if (supports_cycle_counter(cspmu)) {
@@ -583,6 +618,12 @@ static int arm_cspmu_get_event_idx(struct arm_cspmu_hw_events *hw_events,
if (idx >= cspmu->num_logical_ctrs)
return -EAGAIN;
+ if (cspmu->impl.ops.validate_event) {
+ ret = cspmu->impl.ops.validate_event(cspmu, event);
+ if (ret)
+ return ret;
+ }
+
set_bit(idx, hw_events->used_ctrs);
return idx;
@@ -696,7 +737,10 @@ static void arm_cspmu_write_counter(struct perf_event *event, u64 val)
if (use_64b_counter_reg(cspmu)) {
offset = counter_offset(sizeof(u64), event->hw.idx);
- writeq(val, cspmu->base1 + offset);
+ if (cspmu->has_atomic_dword)
+ writeq(val, cspmu->base1 + offset);
+ else
+ lo_hi_writeq(val, cspmu->base1 + offset);
} else {
offset = counter_offset(sizeof(u32), event->hw.idx);
@@ -789,9 +833,9 @@ static inline void arm_cspmu_set_event(struct arm_cspmu *cspmu,
writel(hwc->config, cspmu->base0 + offset);
}
-static inline void arm_cspmu_set_ev_filter(struct arm_cspmu *cspmu,
- struct hw_perf_event *hwc,
- u32 filter)
+static void arm_cspmu_set_ev_filter(struct arm_cspmu *cspmu,
+ struct hw_perf_event *hwc,
+ u32 filter)
{
u32 offset = PMEVFILTR + (4 * hwc->idx);
@@ -823,7 +867,7 @@ static void arm_cspmu_start(struct perf_event *event, int pmu_flags)
arm_cspmu_set_cc_filter(cspmu, filter);
} else {
arm_cspmu_set_event(cspmu, hwc);
- arm_cspmu_set_ev_filter(cspmu, hwc, filter);
+ cspmu->impl.ops.set_ev_filter(cspmu, hwc, filter);
}
hwc->state = 0;
@@ -1147,7 +1191,7 @@ static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
cspmu->pmu = (struct pmu){
.task_ctx_nr = perf_invalid_context,
- .module = THIS_MODULE,
+ .module = cspmu->impl.module,
.pmu_enable = arm_cspmu_enable,
.pmu_disable = arm_cspmu_disable,
.event_init = arm_cspmu_event_init,
@@ -1194,11 +1238,17 @@ static int arm_cspmu_device_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = arm_cspmu_register_pmu(cspmu);
+ ret = arm_cspmu_init_impl_ops(cspmu);
if (ret)
return ret;
- return 0;
+ ret = arm_cspmu_register_pmu(cspmu);
+
+ /* Matches arm_cspmu_init_impl_ops() above. */
+ if (cspmu->impl.module != THIS_MODULE)
+ module_put(cspmu->impl.module);
+
+ return ret;
}
static int arm_cspmu_device_remove(struct platform_device *pdev)
@@ -1298,6 +1348,75 @@ static void __exit arm_cspmu_exit(void)
cpuhp_remove_multi_state(arm_cspmu_cpuhp_state);
}
+int arm_cspmu_impl_register(const struct arm_cspmu_impl_match *impl_match)
+{
+ struct arm_cspmu_impl_match *match;
+ int ret = 0;
+
+ match = arm_cspmu_impl_match_get(impl_match->pmiidr_val);
+
+ if (match) {
+ mutex_lock(&arm_cspmu_lock);
+
+ if (!match->impl_init_ops) {
+ match->module = impl_match->module;
+ match->impl_init_ops = impl_match->impl_init_ops;
+ } else {
+ /* Broken match table may contain non-unique entries */
+ WARN(1, "arm_cspmu backend already registered for module: %s, pmiidr: 0x%x, mask: 0x%x\n",
+ match->module_name,
+ match->pmiidr_val,
+ match->pmiidr_mask);
+
+ ret = -EINVAL;
+ }
+
+ mutex_unlock(&arm_cspmu_lock);
+
+ if (!ret)
+ ret = driver_attach(&arm_cspmu_driver.driver);
+ } else {
+ pr_err("arm_cspmu reg failed, unable to find a match for pmiidr: 0x%x\n",
+ impl_match->pmiidr_val);
+
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(arm_cspmu_impl_register);
+
+static int arm_cspmu_match_device(struct device *dev, const void *match)
+{
+ struct arm_cspmu *cspmu = platform_get_drvdata(to_platform_device(dev));
+
+ return (cspmu && cspmu->impl.match == match) ? 1 : 0;
+}
+
+void arm_cspmu_impl_unregister(const struct arm_cspmu_impl_match *impl_match)
+{
+ struct device *dev;
+ struct arm_cspmu_impl_match *match;
+
+ match = arm_cspmu_impl_match_get(impl_match->pmiidr_val);
+
+ if (WARN_ON(!match))
+ return;
+
+ /* Unbind the driver from all matching backend devices. */
+ while ((dev = driver_find_device(&arm_cspmu_driver.driver, NULL,
+ match, arm_cspmu_match_device)))
+ device_release_driver(dev);
+
+ mutex_lock(&arm_cspmu_lock);
+
+ match->module = NULL;
+ match->impl_init_ops = NULL;
+
+ mutex_unlock(&arm_cspmu_lock);
+}
+EXPORT_SYMBOL_GPL(arm_cspmu_impl_unregister);
+
module_init(arm_cspmu_init);
module_exit(arm_cspmu_exit);
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.h b/drivers/perf/arm_cspmu/arm_cspmu.h
index 83df53d1c132..2fe723555a6b 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.h
+++ b/drivers/perf/arm_cspmu/arm_cspmu.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0
*
* ARM CoreSight Architecture PMU driver.
- * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ * Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
*/
@@ -69,6 +69,10 @@
#define ARM_CSPMU_PMIIDR_IMPLEMENTER GENMASK(11, 0)
#define ARM_CSPMU_PMIIDR_PRODUCTID GENMASK(31, 20)
+/* JEDEC-assigned JEP106 identification code */
+#define ARM_CSPMU_IMPL_ID_NVIDIA 0x36B
+#define ARM_CSPMU_IMPL_ID_AMPERE 0xA16
+
struct arm_cspmu;
/* This tracks the events assigned to each counter in the PMU. */
@@ -101,14 +105,34 @@ struct arm_cspmu_impl_ops {
u32 (*event_type)(const struct perf_event *event);
/* Decode filter value from configs */
u32 (*event_filter)(const struct perf_event *event);
+ /* Set event filter */
+ void (*set_ev_filter)(struct arm_cspmu *cspmu,
+ struct hw_perf_event *hwc, u32 filter);
+ /* Implementation specific event validation */
+ int (*validate_event)(struct arm_cspmu *cspmu,
+ struct perf_event *event);
/* Hide/show unsupported events */
umode_t (*event_attr_is_visible)(struct kobject *kobj,
struct attribute *attr, int unused);
};
+/* Vendor/implementer registration parameter. */
+struct arm_cspmu_impl_match {
+ /* Backend module. */
+ struct module *module;
+ const char *module_name;
+ /* PMIIDR value/mask. */
+ u32 pmiidr_val;
+ u32 pmiidr_mask;
+ /* Callback to vendor backend to init arm_cspmu_impl::ops. */
+ int (*impl_init_ops)(struct arm_cspmu *cspmu);
+};
+
/* Vendor/implementer descriptor. */
struct arm_cspmu_impl {
u32 pmiidr;
+ struct module *module;
+ struct arm_cspmu_impl_match *match;
struct arm_cspmu_impl_ops ops;
void *ctx;
};
@@ -147,4 +171,10 @@ ssize_t arm_cspmu_sysfs_format_show(struct device *dev,
struct device_attribute *attr,
char *buf);
+/* Register vendor backend. */
+int arm_cspmu_impl_register(const struct arm_cspmu_impl_match *impl_match);
+
+/* Unregister vendor backend. */
+void arm_cspmu_impl_unregister(const struct arm_cspmu_impl_match *impl_match);
+
#endif /* __ARM_CSPMU_H__ */
diff --git a/drivers/perf/arm_cspmu/nvidia_cspmu.c b/drivers/perf/arm_cspmu/nvidia_cspmu.c
index 72ef80caa3c8..0382b702f092 100644
--- a/drivers/perf/arm_cspmu/nvidia_cspmu.c
+++ b/drivers/perf/arm_cspmu/nvidia_cspmu.c
@@ -1,14 +1,15 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ * Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
*/
/* Support for NVIDIA specific attributes. */
+#include <linux/module.h>
#include <linux/topology.h>
-#include "nvidia_cspmu.h"
+#include "arm_cspmu.h"
#define NV_PCIE_PORT_COUNT 10ULL
#define NV_PCIE_FILTER_ID_MASK GENMASK_ULL(NV_PCIE_PORT_COUNT - 1, 0)
@@ -351,7 +352,7 @@ static char *nv_cspmu_format_name(const struct arm_cspmu *cspmu,
return name;
}
-int nv_cspmu_init_ops(struct arm_cspmu *cspmu)
+static int nv_cspmu_init_ops(struct arm_cspmu *cspmu)
{
u32 prodid;
struct nv_cspmu_ctx *ctx;
@@ -395,6 +396,31 @@ int nv_cspmu_init_ops(struct arm_cspmu *cspmu)
return 0;
}
-EXPORT_SYMBOL_GPL(nv_cspmu_init_ops);
+
+/* Match all NVIDIA Coresight PMU devices */
+static const struct arm_cspmu_impl_match nv_cspmu_param = {
+ .pmiidr_val = ARM_CSPMU_IMPL_ID_NVIDIA,
+ .module = THIS_MODULE,
+ .impl_init_ops = nv_cspmu_init_ops
+};
+
+static int __init nvidia_cspmu_init(void)
+{
+ int ret;
+
+ ret = arm_cspmu_impl_register(&nv_cspmu_param);
+ if (ret)
+ pr_err("nvidia_cspmu backend registration error: %d\n", ret);
+
+ return ret;
+}
+
+static void __exit nvidia_cspmu_exit(void)
+{
+ arm_cspmu_impl_unregister(&nv_cspmu_param);
+}
+
+module_init(nvidia_cspmu_init);
+module_exit(nvidia_cspmu_exit);
MODULE_LICENSE("GPL v2");
diff --git a/drivers/perf/arm_cspmu/nvidia_cspmu.h b/drivers/perf/arm_cspmu/nvidia_cspmu.h
deleted file mode 100644
index 71e18f0dc50b..000000000000
--- a/drivers/perf/arm_cspmu/nvidia_cspmu.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0
- *
- * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
- *
- */
-
-/* Support for NVIDIA specific attributes. */
-
-#ifndef __NVIDIA_CSPMU_H__
-#define __NVIDIA_CSPMU_H__
-
-#include "arm_cspmu.h"
-
-/* Allocate NVIDIA descriptor. */
-int nv_cspmu_init_ops(struct arm_cspmu *cspmu);
-
-#endif /* __NVIDIA_CSPMU_H__ */
diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c
index 8fcaa26f0f8a..18b91b56af1d 100644
--- a/drivers/perf/arm_pmuv3.c
+++ b/drivers/perf/arm_pmuv3.c
@@ -1126,7 +1126,7 @@ static void __armv8pmu_probe_pmu(void *info)
pmceid, ARMV8_PMUV3_MAX_COMMON_EVENTS);
/* store PMMIR register for sysfs */
- if (is_pmuv3p4(pmuver) && (pmceid_raw[1] & BIT(31)))
+ if (is_pmuv3p4(pmuver))
cpu_pmu->reg_pmmir = read_pmmir();
else
cpu_pmu->reg_pmmir = 0;
@@ -1175,7 +1175,6 @@ static struct ctl_table armv8_pmu_sysctl_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
- { }
};
static void armv8_pmu_register_sysctl_table(void)
@@ -1187,10 +1186,7 @@ static void armv8_pmu_register_sysctl_table(void)
}
static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
- int (*map_event)(struct perf_event *event),
- const struct attribute_group *events,
- const struct attribute_group *format,
- const struct attribute_group *caps)
+ int (*map_event)(struct perf_event *event))
{
int ret = armv8pmu_probe_pmu(cpu_pmu);
if (ret)
@@ -1212,27 +1208,17 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
cpu_pmu->name = name;
cpu_pmu->map_event = map_event;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = events ?
- events : &armv8_pmuv3_events_attr_group;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = format ?
- format : &armv8_pmuv3_format_attr_group;
- cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_CAPS] = caps ?
- caps : &armv8_pmuv3_caps_attr_group;
-
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &armv8_pmuv3_events_attr_group;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &armv8_pmuv3_format_attr_group;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_CAPS] = &armv8_pmuv3_caps_attr_group;
armv8_pmu_register_sysctl_table();
return 0;
}
-static int armv8_pmu_init_nogroups(struct arm_pmu *cpu_pmu, char *name,
- int (*map_event)(struct perf_event *event))
-{
- return armv8_pmu_init(cpu_pmu, name, map_event, NULL, NULL, NULL);
-}
-
#define PMUV3_INIT_SIMPLE(name) \
static int name##_pmu_init(struct arm_pmu *cpu_pmu) \
{ \
- return armv8_pmu_init_nogroups(cpu_pmu, #name, armv8_pmuv3_map_event);\
+ return armv8_pmu_init(cpu_pmu, #name, armv8_pmuv3_map_event); \
}
PMUV3_INIT_SIMPLE(armv8_pmuv3)
@@ -1263,44 +1249,37 @@ PMUV3_INIT_SIMPLE(armv8_nvidia_denver)
static int armv8_a35_pmu_init(struct arm_pmu *cpu_pmu)
{
- return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a35",
- armv8_a53_map_event);
+ return armv8_pmu_init(cpu_pmu, "armv8_cortex_a35", armv8_a53_map_event);
}
static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu)
{
- return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a53",
- armv8_a53_map_event);
+ return armv8_pmu_init(cpu_pmu, "armv8_cortex_a53", armv8_a53_map_event);
}
static int armv8_a57_pmu_init(struct arm_pmu *cpu_pmu)
{
- return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a57",
- armv8_a57_map_event);
+ return armv8_pmu_init(cpu_pmu, "armv8_cortex_a57", armv8_a57_map_event);
}
static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu)
{
- return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a72",
- armv8_a57_map_event);
+ return armv8_pmu_init(cpu_pmu, "armv8_cortex_a72", armv8_a57_map_event);
}
static int armv8_a73_pmu_init(struct arm_pmu *cpu_pmu)
{
- return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a73",
- armv8_a73_map_event);
+ return armv8_pmu_init(cpu_pmu, "armv8_cortex_a73", armv8_a73_map_event);
}
static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu)
{
- return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cavium_thunder",
- armv8_thunder_map_event);
+ return armv8_pmu_init(cpu_pmu, "armv8_cavium_thunder", armv8_thunder_map_event);
}
static int armv8_vulcan_pmu_init(struct arm_pmu *cpu_pmu)
{
- return armv8_pmu_init_nogroups(cpu_pmu, "armv8_brcm_vulcan",
- armv8_vulcan_map_event);
+ return armv8_pmu_init(cpu_pmu, "armv8_brcm_vulcan", armv8_vulcan_map_event);
}
static const struct of_device_id armv8_pmu_of_device_ids[] = {
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 5a00adb2de8c..b90ba8aca3fa 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -353,16 +353,15 @@ static int hisi_pcie_pmu_event_init(struct perf_event *event)
struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
struct hw_perf_event *hwc = &event->hw;
- event->cpu = pcie_pmu->on_cpu;
+ /* Check the type first before going on, otherwise it's not our event */
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event)))
hwc->event_base = HISI_PCIE_EXT_CNT;
else
hwc->event_base = HISI_PCIE_CNT;
- if (event->attr.type != event->pmu->type)
- return -ENOENT;
-
/* Sampling is not supported. */
if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
return -EOPNOTSUPP;
@@ -373,6 +372,8 @@ static int hisi_pcie_pmu_event_init(struct perf_event *event)
if (!hisi_pcie_pmu_validate_event_group(event))
return -EINVAL;
+ event->cpu = pcie_pmu->on_cpu;
+
return 0;
}
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
index d941e746b424..797cf201996a 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
@@ -505,8 +505,8 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
if (ret) {
dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
- &pa_pmu->node);
+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
+ &pa_pmu->node);
return ret;
}
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
index 6fe534a665ed..e706ca567676 100644
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
@@ -450,8 +450,8 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
ret = perf_pmu_register(&sllc_pmu->pmu, name, -1);
if (ret) {
dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret);
- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
- &sllc_pmu->node);
+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
+ &sllc_pmu->node);
return ret;
}
diff --git a/drivers/perf/hisilicon/hns3_pmu.c b/drivers/perf/hisilicon/hns3_pmu.c
index e0457d84af6b..16869bf5bf4c 100644
--- a/drivers/perf/hisilicon/hns3_pmu.c
+++ b/drivers/perf/hisilicon/hns3_pmu.c
@@ -1556,8 +1556,8 @@ static int hns3_pmu_init_pmu(struct pci_dev *pdev, struct hns3_pmu *hns3_pmu)
ret = perf_pmu_register(&hns3_pmu->pmu, hns3_pmu->pmu.name, -1);
if (ret) {
pci_err(pdev, "failed to register perf PMU, ret = %d.\n", ret);
- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
- &hns3_pmu->node);
+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
+ &hns3_pmu->node);
}
return ret;
@@ -1568,8 +1568,8 @@ static void hns3_pmu_uninit_pmu(struct pci_dev *pdev)
struct hns3_pmu *hns3_pmu = pci_get_drvdata(pdev);
perf_pmu_unregister(&hns3_pmu->pmu);
- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
- &hns3_pmu->node);
+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
+ &hns3_pmu->node);
}
static int hns3_pmu_init_dev(struct pci_dev *pdev)
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index 9972bfc11a5c..7ce344248dda 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -16,11 +16,9 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -1731,6 +1729,12 @@ static const struct xgene_pmu_data xgene_pmu_v2_data = {
.id = PCP_PMU_V2,
};
+#ifdef CONFIG_ACPI
+static const struct xgene_pmu_data xgene_pmu_v3_data = {
+ .id = PCP_PMU_V3,
+};
+#endif
+
static const struct xgene_pmu_ops xgene_pmu_ops = {
.mask_int = xgene_pmu_mask_int,
.unmask_int = xgene_pmu_unmask_int,
@@ -1773,9 +1777,9 @@ static const struct of_device_id xgene_pmu_of_match[] = {
MODULE_DEVICE_TABLE(of, xgene_pmu_of_match);
#ifdef CONFIG_ACPI
static const struct acpi_device_id xgene_pmu_acpi_match[] = {
- {"APMC0D5B", PCP_PMU_V1},
- {"APMC0D5C", PCP_PMU_V2},
- {"APMC0D83", PCP_PMU_V3},
+ {"APMC0D5B", (kernel_ulong_t)&xgene_pmu_data},
+ {"APMC0D5C", (kernel_ulong_t)&xgene_pmu_v2_data},
+ {"APMC0D83", (kernel_ulong_t)&xgene_pmu_v3_data},
{},
};
MODULE_DEVICE_TABLE(acpi, xgene_pmu_acpi_match);
@@ -1831,7 +1835,6 @@ static int xgene_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
static int xgene_pmu_probe(struct platform_device *pdev)
{
const struct xgene_pmu_data *dev_data;
- const struct of_device_id *of_id;
struct xgene_pmu *xgene_pmu;
int irq, rc;
int version;
@@ -1850,24 +1853,10 @@ static int xgene_pmu_probe(struct platform_device *pdev)
xgene_pmu->dev = &pdev->dev;
platform_set_drvdata(pdev, xgene_pmu);
- version = -EINVAL;
- of_id = of_match_device(xgene_pmu_of_match, &pdev->dev);
- if (of_id) {
- dev_data = (const struct xgene_pmu_data *) of_id->data;
- version = dev_data->id;
- }
-
-#ifdef CONFIG_ACPI
- if (ACPI_COMPANION(&pdev->dev)) {
- const struct acpi_device_id *acpi_id;
-
- acpi_id = acpi_match_device(xgene_pmu_acpi_match, &pdev->dev);
- if (acpi_id)
- version = (int) acpi_id->driver_data;
- }
-#endif
- if (version < 0)
+ dev_data = device_get_match_data(&pdev->dev);
+ if (!dev_data)
return -ENODEV;
+ version = dev_data->id;
if (version == PCP_PMU_V3)
xgene_pmu->ops = &xgene_pmu_v3_ops;
diff --git a/drivers/pmdomain/Kconfig b/drivers/pmdomain/Kconfig
new file mode 100644
index 000000000000..c98c5bf75a14
--- /dev/null
+++ b/drivers/pmdomain/Kconfig
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "PM Domains"
+
+source "drivers/pmdomain/actions/Kconfig"
+source "drivers/pmdomain/amlogic/Kconfig"
+source "drivers/pmdomain/apple/Kconfig"
+source "drivers/pmdomain/bcm/Kconfig"
+source "drivers/pmdomain/imx/Kconfig"
+source "drivers/pmdomain/mediatek/Kconfig"
+source "drivers/pmdomain/qcom/Kconfig"
+source "drivers/pmdomain/renesas/Kconfig"
+source "drivers/pmdomain/rockchip/Kconfig"
+source "drivers/pmdomain/samsung/Kconfig"
+source "drivers/pmdomain/st/Kconfig"
+source "drivers/pmdomain/starfive/Kconfig"
+source "drivers/pmdomain/sunxi/Kconfig"
+source "drivers/pmdomain/tegra/Kconfig"
+source "drivers/pmdomain/ti/Kconfig"
+source "drivers/pmdomain/xilinx/Kconfig"
+
+endmenu
diff --git a/drivers/pmdomain/Makefile b/drivers/pmdomain/Makefile
index 666753676e5c..f0326b27b30b 100644
--- a/drivers/pmdomain/Makefile
+++ b/drivers/pmdomain/Makefile
@@ -2,6 +2,7 @@
obj-y += actions/
obj-y += amlogic/
obj-y += apple/
+obj-y += arm/
obj-y += bcm/
obj-y += imx/
obj-y += mediatek/
diff --git a/drivers/soc/actions/Kconfig b/drivers/pmdomain/actions/Kconfig
index 1aca2058a40c..1aca2058a40c 100644
--- a/drivers/soc/actions/Kconfig
+++ b/drivers/pmdomain/actions/Kconfig
diff --git a/drivers/pmdomain/actions/owl-sps.c b/drivers/pmdomain/actions/owl-sps.c
index 73a9e0bb7e8e..3a586d1f3256 100644
--- a/drivers/pmdomain/actions/owl-sps.c
+++ b/drivers/pmdomain/actions/owl-sps.c
@@ -8,8 +8,10 @@
* Copyright (c) 2017 Andreas Färber
*/
+#include <linux/mod_devicetable.h>
#include <linux/of_address.h>
-#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/pm_domain.h>
#include <linux/soc/actions/owl-sps.h>
#include <dt-bindings/power/owl-s500-powergate.h>
@@ -96,24 +98,16 @@ static int owl_sps_init_domain(struct owl_sps *sps, int index)
static int owl_sps_probe(struct platform_device *pdev)
{
- const struct of_device_id *match;
const struct owl_sps_info *sps_info;
struct owl_sps *sps;
int i, ret;
- if (!pdev->dev.of_node) {
- dev_err(&pdev->dev, "no device node\n");
- return -ENODEV;
- }
-
- match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
- if (!match || !match->data) {
+ sps_info = device_get_match_data(&pdev->dev);
+ if (!sps_info) {
dev_err(&pdev->dev, "unknown compatible or missing data\n");
return -EINVAL;
}
- sps_info = match->data;
-
sps = devm_kzalloc(&pdev->dev,
struct_size(sps, domains, sps_info->num_domains),
GFP_KERNEL);
diff --git a/drivers/pmdomain/amlogic/Kconfig b/drivers/pmdomain/amlogic/Kconfig
new file mode 100644
index 000000000000..2108729909b5
--- /dev/null
+++ b/drivers/pmdomain/amlogic/Kconfig
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "Amlogic PM Domains"
+
+config MESON_GX_PM_DOMAINS
+ tristate "Amlogic Meson GX Power Domains driver"
+ depends on ARCH_MESON || COMPILE_TEST
+ depends on PM && OF
+ default ARCH_MESON
+ select PM_GENERIC_DOMAINS
+ select PM_GENERIC_DOMAINS_OF
+ help
+ Say yes to expose Amlogic Meson GX Power Domains as
+ Generic Power Domains.
+
+config MESON_EE_PM_DOMAINS
+ tristate "Amlogic Meson Everything-Else Power Domains driver"
+ depends on ARCH_MESON || COMPILE_TEST
+ depends on PM && OF
+ default ARCH_MESON
+ select PM_GENERIC_DOMAINS
+ select PM_GENERIC_DOMAINS_OF
+ help
+ Say yes to expose Amlogic Meson Everything-Else Power Domains as
+ Generic Power Domains.
+
+config MESON_SECURE_PM_DOMAINS
+ tristate "Amlogic Meson Secure Power Domains driver"
+ depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM
+ depends on PM && OF
+ depends on HAVE_ARM_SMCCC
+ default ARCH_MESON
+ select PM_GENERIC_DOMAINS
+ select PM_GENERIC_DOMAINS_OF
+ help
+ Support for the power controller on Amlogic A1/C1 series.
+ Say yes to expose Amlogic Meson Secure Power Domains as Generic
+ Power Domains.
+
+endmenu
diff --git a/drivers/pmdomain/amlogic/meson-ee-pwrc.c b/drivers/pmdomain/amlogic/meson-ee-pwrc.c
index cfb796d40d9d..0dd71cd814c5 100644
--- a/drivers/pmdomain/amlogic/meson-ee-pwrc.c
+++ b/drivers/pmdomain/amlogic/meson-ee-pwrc.c
@@ -228,7 +228,7 @@ static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_audio[] = {
static struct meson_ee_pwrc_mem_domain g12a_pwrc_mem_nna[] = {
{ G12A_HHI_NANOQ_MEM_PD_REG0, GENMASK(31, 0) },
- { G12A_HHI_NANOQ_MEM_PD_REG1, GENMASK(23, 0) },
+ { G12A_HHI_NANOQ_MEM_PD_REG1, GENMASK(31, 0) },
};
#define VPU_PD(__name, __top_pd, __mem, __is_pwr_off, __resets, __clks) \
diff --git a/drivers/pmdomain/amlogic/meson-secure-pwrc.c b/drivers/pmdomain/amlogic/meson-secure-pwrc.c
index 89c881c56cd7..4d5bda0d60fc 100644
--- a/drivers/pmdomain/amlogic/meson-secure-pwrc.c
+++ b/drivers/pmdomain/amlogic/meson-secure-pwrc.c
@@ -13,16 +13,19 @@
#include <dt-bindings/power/meson-a1-power.h>
#include <dt-bindings/power/amlogic,c3-pwrc.h>
#include <dt-bindings/power/meson-s4-power.h>
+#include <dt-bindings/power/amlogic,t7-pwrc.h>
#include <linux/arm-smccc.h>
#include <linux/firmware/meson/meson_sm.h>
#include <linux/module.h>
#define PWRC_ON 1
#define PWRC_OFF 0
+#define PWRC_NO_PARENT UINT_MAX
struct meson_secure_pwrc_domain {
struct generic_pm_domain base;
unsigned int index;
+ unsigned int parent;
struct meson_secure_pwrc *pwrc;
};
@@ -34,6 +37,7 @@ struct meson_secure_pwrc {
struct meson_secure_pwrc_domain_desc {
unsigned int index;
+ unsigned int parent;
unsigned int flags;
char *name;
bool (*is_off)(struct meson_secure_pwrc_domain *pwrc_domain);
@@ -90,8 +94,19 @@ static int meson_secure_pwrc_on(struct generic_pm_domain *domain)
{ \
.name = #__name, \
.index = PWRC_##__name##_ID, \
- .is_off = pwrc_secure_is_off, \
+ .is_off = pwrc_secure_is_off, \
.flags = __flag, \
+ .parent = PWRC_NO_PARENT, \
+}
+
+#define TOP_PD(__name, __flag, __parent) \
+[PWRC_##__name##_ID] = \
+{ \
+ .name = #__name, \
+ .index = PWRC_##__name##_ID, \
+ .is_off = pwrc_secure_is_off, \
+ .flags = __flag, \
+ .parent = __parent, \
}
static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
@@ -122,18 +137,19 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
};
static struct meson_secure_pwrc_domain_desc c3_pwrc_domains[] = {
- SEC_PD(C3_NNA, 0),
- SEC_PD(C3_AUDIO, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_SDIOA, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_EMMC, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_USB_COMB, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_SDCARD, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_ETH, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_GE2D, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_CVE, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_GDC_WRAP, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_ISP_TOP, GENPD_FLAG_ALWAYS_ON),
- SEC_PD(C3_MIPI_ISP_WRAP, GENPD_FLAG_ALWAYS_ON),
+ SEC_PD(C3_NNA, 0),
+ SEC_PD(C3_AUDIO, 0),
+ SEC_PD(C3_SDIOA, 0),
+ SEC_PD(C3_EMMC, 0),
+ SEC_PD(C3_USB_COMB, 0),
+ SEC_PD(C3_SDCARD, 0),
+ /* ETH is for ethernet online wakeup, and should be always on */
+ SEC_PD(C3_ETH, GENPD_FLAG_ALWAYS_ON),
+ SEC_PD(C3_GE2D, 0),
+ SEC_PD(C3_CVE, 0),
+ SEC_PD(C3_GDC_WRAP, 0),
+ SEC_PD(C3_ISP_TOP, 0),
+ SEC_PD(C3_MIPI_ISP_WRAP, 0),
SEC_PD(C3_VCODEC, 0),
};
@@ -149,6 +165,69 @@ static struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = {
SEC_PD(S4_AUDIO, 0),
};
+static struct meson_secure_pwrc_domain_desc t7_pwrc_domains[] = {
+ SEC_PD(T7_DSPA, 0),
+ SEC_PD(T7_DSPB, 0),
+ TOP_PD(T7_DOS_HCODEC, 0, PWRC_T7_NIC3_ID),
+ TOP_PD(T7_DOS_HEVC, 0, PWRC_T7_NIC3_ID),
+ TOP_PD(T7_DOS_VDEC, 0, PWRC_T7_NIC3_ID),
+ TOP_PD(T7_DOS_WAVE, 0, PWRC_T7_NIC3_ID),
+ SEC_PD(T7_VPU_HDMI, 0),
+ SEC_PD(T7_USB_COMB, 0),
+ SEC_PD(T7_PCIE, 0),
+ TOP_PD(T7_GE2D, 0, PWRC_T7_NIC3_ID),
+ /* SRAMA is used as ATF runtime memory, and should be always on */
+ SEC_PD(T7_SRAMA, GENPD_FLAG_ALWAYS_ON),
+ /* SRAMB is used as ATF runtime memory, and should be always on */
+ SEC_PD(T7_SRAMB, GENPD_FLAG_ALWAYS_ON),
+ SEC_PD(T7_HDMIRX, 0),
+ SEC_PD(T7_VI_CLK1, 0),
+ SEC_PD(T7_VI_CLK2, 0),
+ /* ETH is for ethernet online wakeup, and should be always on */
+ SEC_PD(T7_ETH, GENPD_FLAG_ALWAYS_ON),
+ SEC_PD(T7_ISP, 0),
+ SEC_PD(T7_MIPI_ISP, 0),
+ TOP_PD(T7_GDC, 0, PWRC_T7_NIC3_ID),
+ TOP_PD(T7_DEWARP, 0, PWRC_T7_NIC3_ID),
+ SEC_PD(T7_SDIO_A, 0),
+ SEC_PD(T7_SDIO_B, 0),
+ SEC_PD(T7_EMMC, 0),
+ TOP_PD(T7_MALI_SC0, 0, PWRC_T7_NNA_TOP_ID),
+ TOP_PD(T7_MALI_SC1, 0, PWRC_T7_NNA_TOP_ID),
+ TOP_PD(T7_MALI_SC2, 0, PWRC_T7_NNA_TOP_ID),
+ TOP_PD(T7_MALI_SC3, 0, PWRC_T7_NNA_TOP_ID),
+ SEC_PD(T7_MALI_TOP, 0),
+ TOP_PD(T7_NNA_CORE0, 0, PWRC_T7_NNA_TOP_ID),
+ TOP_PD(T7_NNA_CORE1, 0, PWRC_T7_NNA_TOP_ID),
+ TOP_PD(T7_NNA_CORE2, 0, PWRC_T7_NNA_TOP_ID),
+ TOP_PD(T7_NNA_CORE3, 0, PWRC_T7_NNA_TOP_ID),
+ SEC_PD(T7_NNA_TOP, 0),
+ SEC_PD(T7_DDR0, GENPD_FLAG_ALWAYS_ON),
+ SEC_PD(T7_DDR1, GENPD_FLAG_ALWAYS_ON),
+ /* DMC0 is for DDR PHY ana/dig and DMC, and should be always on */
+ SEC_PD(T7_DMC0, GENPD_FLAG_ALWAYS_ON),
+ /* DMC1 is for DDR PHY ana/dig and DMC, and should be always on */
+ SEC_PD(T7_DMC1, GENPD_FLAG_ALWAYS_ON),
+ /* NOC is related to clk bus, and should be always on */
+ SEC_PD(T7_NOC, GENPD_FLAG_ALWAYS_ON),
+ /* NIC is for the Arm NIC-400 interconnect, and should be always on */
+ SEC_PD(T7_NIC2, GENPD_FLAG_ALWAYS_ON),
+ SEC_PD(T7_NIC3, 0),
+ /* CPU accesses the interleave data to the ddr need cci, and should be always on */
+ SEC_PD(T7_CCI, GENPD_FLAG_ALWAYS_ON),
+ SEC_PD(T7_MIPI_DSI0, 0),
+ SEC_PD(T7_SPICC0, 0),
+ SEC_PD(T7_SPICC1, 0),
+ SEC_PD(T7_SPICC2, 0),
+ SEC_PD(T7_SPICC3, 0),
+ SEC_PD(T7_SPICC4, 0),
+ SEC_PD(T7_SPICC5, 0),
+ SEC_PD(T7_EDP0, 0),
+ SEC_PD(T7_EDP1, 0),
+ SEC_PD(T7_MIPI_DSI1, 0),
+ SEC_PD(T7_AUDIO, 0),
+};
+
static int meson_secure_pwrc_probe(struct platform_device *pdev)
{
int i;
@@ -201,16 +280,29 @@ static int meson_secure_pwrc_probe(struct platform_device *pdev)
dom->pwrc = pwrc;
dom->index = match->domains[i].index;
+ dom->parent = match->domains[i].parent;
dom->base.name = match->domains[i].name;
dom->base.flags = match->domains[i].flags;
dom->base.power_on = meson_secure_pwrc_on;
dom->base.power_off = meson_secure_pwrc_off;
+ if (match->domains[i].is_off(dom) && (dom->base.flags & GENPD_FLAG_ALWAYS_ON))
+ meson_secure_pwrc_on(&dom->base);
+
pm_genpd_init(&dom->base, NULL, match->domains[i].is_off(dom));
pwrc->xlate.domains[i] = &dom->base;
}
+ for (i = 0; i < match->count; i++) {
+ struct meson_secure_pwrc_domain *dom = pwrc->domains;
+
+ if (!match->domains[i].name || match->domains[i].parent == PWRC_NO_PARENT)
+ continue;
+
+ pm_genpd_add_subdomain(&dom[dom[i].parent].base, &dom[i].base);
+ }
+
return of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate);
}
@@ -229,6 +321,11 @@ static struct meson_secure_pwrc_domain_data meson_secure_s4_pwrc_data = {
.count = ARRAY_SIZE(s4_pwrc_domains),
};
+static struct meson_secure_pwrc_domain_data amlogic_secure_t7_pwrc_data = {
+ .domains = t7_pwrc_domains,
+ .count = ARRAY_SIZE(t7_pwrc_domains),
+};
+
static const struct of_device_id meson_secure_pwrc_match_table[] = {
{
.compatible = "amlogic,meson-a1-pwrc",
@@ -242,6 +339,10 @@ static const struct of_device_id meson_secure_pwrc_match_table[] = {
.compatible = "amlogic,meson-s4-pwrc",
.data = &meson_secure_s4_pwrc_data,
},
+ {
+ .compatible = "amlogic,t7-pwrc",
+ .data = &amlogic_secure_t7_pwrc_data,
+ },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, meson_secure_pwrc_match_table);
diff --git a/drivers/pmdomain/apple/Kconfig b/drivers/pmdomain/apple/Kconfig
new file mode 100644
index 000000000000..12237cbcfaa9
--- /dev/null
+++ b/drivers/pmdomain/apple/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+if ARCH_APPLE || COMPILE_TEST
+
+config APPLE_PMGR_PWRSTATE
+ bool "Apple SoC PMGR power state control"
+ depends on PM
+ select REGMAP
+ select MFD_SYSCON
+ select PM_GENERIC_DOMAINS
+ select RESET_CONTROLLER
+ default ARCH_APPLE
+ help
+ The PMGR block in Apple SoCs provides high-level power state
+ controls for SoC devices. This driver manages them through the
+ generic power domain framework, and also provides reset support.
+
+endif
diff --git a/drivers/pmdomain/arm/Makefile b/drivers/pmdomain/arm/Makefile
new file mode 100644
index 000000000000..cfcb1f6cdd90
--- /dev/null
+++ b/drivers/pmdomain/arm/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_ARM_SCMI_PERF_DOMAIN) += scmi_perf_domain.o
+obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
diff --git a/drivers/pmdomain/arm/scmi_perf_domain.c b/drivers/pmdomain/arm/scmi_perf_domain.c
new file mode 100644
index 000000000000..bc3f78abb6da
--- /dev/null
+++ b/drivers/pmdomain/arm/scmi_perf_domain.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SCMI performance domain support.
+ *
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/scmi_protocol.h>
+#include <linux/slab.h>
+
+struct scmi_perf_domain {
+ struct generic_pm_domain genpd;
+ const struct scmi_perf_proto_ops *perf_ops;
+ const struct scmi_protocol_handle *ph;
+ const struct scmi_perf_domain_info *info;
+ u32 domain_id;
+};
+
+#define to_scmi_pd(pd) container_of(pd, struct scmi_perf_domain, genpd)
+
+static int
+scmi_pd_set_perf_state(struct generic_pm_domain *genpd, unsigned int state)
+{
+ struct scmi_perf_domain *pd = to_scmi_pd(genpd);
+ int ret;
+
+ if (!pd->info->set_perf)
+ return 0;
+
+ if (!state)
+ return -EINVAL;
+
+ ret = pd->perf_ops->level_set(pd->ph, pd->domain_id, state, true);
+ if (ret)
+ dev_warn(&genpd->dev, "Failed with %d when trying to set %d perf level",
+ ret, state);
+
+ return ret;
+}
+
+static int
+scmi_pd_attach_dev(struct generic_pm_domain *genpd, struct device *dev)
+{
+ struct scmi_perf_domain *pd = to_scmi_pd(genpd);
+ int ret;
+
+ /*
+ * Allow the device to be attached, but don't add the OPP table unless
+ * the performance level can be changed.
+ */
+ if (!pd->info->set_perf)
+ return 0;
+
+ ret = pd->perf_ops->device_opps_add(pd->ph, dev, pd->domain_id);
+ if (ret)
+ dev_warn(dev, "failed to add OPPs for the device\n");
+
+ return ret;
+}
+
+static void
+scmi_pd_detach_dev(struct generic_pm_domain *genpd, struct device *dev)
+{
+ struct scmi_perf_domain *pd = to_scmi_pd(genpd);
+
+ if (!pd->info->set_perf)
+ return;
+
+ dev_pm_opp_remove_all_dynamic(dev);
+}
+
+static int scmi_perf_domain_probe(struct scmi_device *sdev)
+{
+ struct device *dev = &sdev->dev;
+ const struct scmi_handle *handle = sdev->handle;
+ const struct scmi_perf_proto_ops *perf_ops;
+ struct scmi_protocol_handle *ph;
+ struct scmi_perf_domain *scmi_pd;
+ struct genpd_onecell_data *scmi_pd_data;
+ struct generic_pm_domain **domains;
+ int num_domains, i, ret = 0;
+
+ if (!handle)
+ return -ENODEV;
+
+ /* The OF node must specify us as a power-domain provider. */
+ if (!of_find_property(dev->of_node, "#power-domain-cells", NULL))
+ return 0;
+
+ perf_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PERF, &ph);
+ if (IS_ERR(perf_ops))
+ return PTR_ERR(perf_ops);
+
+ num_domains = perf_ops->num_domains_get(ph);
+ if (num_domains < 0) {
+ dev_warn(dev, "Failed with %d when getting num perf domains\n",
+ num_domains);
+ return num_domains;
+ } else if (!num_domains) {
+ return 0;
+ }
+
+ scmi_pd = devm_kcalloc(dev, num_domains, sizeof(*scmi_pd), GFP_KERNEL);
+ if (!scmi_pd)
+ return -ENOMEM;
+
+ scmi_pd_data = devm_kzalloc(dev, sizeof(*scmi_pd_data), GFP_KERNEL);
+ if (!scmi_pd_data)
+ return -ENOMEM;
+
+ domains = devm_kcalloc(dev, num_domains, sizeof(*domains), GFP_KERNEL);
+ if (!domains)
+ return -ENOMEM;
+
+ for (i = 0; i < num_domains; i++, scmi_pd++) {
+ scmi_pd->info = perf_ops->info_get(ph, i);
+
+ scmi_pd->domain_id = i;
+ scmi_pd->perf_ops = perf_ops;
+ scmi_pd->ph = ph;
+ scmi_pd->genpd.name = scmi_pd->info->name;
+ scmi_pd->genpd.flags = GENPD_FLAG_ALWAYS_ON |
+ GENPD_FLAG_OPP_TABLE_FW;
+ scmi_pd->genpd.set_performance_state = scmi_pd_set_perf_state;
+ scmi_pd->genpd.attach_dev = scmi_pd_attach_dev;
+ scmi_pd->genpd.detach_dev = scmi_pd_detach_dev;
+
+ ret = pm_genpd_init(&scmi_pd->genpd, NULL, false);
+ if (ret)
+ goto err;
+
+ domains[i] = &scmi_pd->genpd;
+ }
+
+ scmi_pd_data->domains = domains;
+ scmi_pd_data->num_domains = num_domains;
+
+ ret = of_genpd_add_provider_onecell(dev->of_node, scmi_pd_data);
+ if (ret)
+ goto err;
+
+ dev_set_drvdata(dev, scmi_pd_data);
+ dev_info(dev, "Initialized %d performance domains", num_domains);
+ return 0;
+err:
+ for (i--; i >= 0; i--)
+ pm_genpd_remove(domains[i]);
+ return ret;
+}
+
+static void scmi_perf_domain_remove(struct scmi_device *sdev)
+{
+ struct device *dev = &sdev->dev;
+ struct genpd_onecell_data *scmi_pd_data = dev_get_drvdata(dev);
+ int i;
+
+ of_genpd_del_provider(dev->of_node);
+
+ for (i = 0; i < scmi_pd_data->num_domains; i++)
+ pm_genpd_remove(scmi_pd_data->domains[i]);
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+ { SCMI_PROTOCOL_PERF, "perf" },
+ { },
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_perf_domain_driver = {
+ .name = "scmi-perf-domain",
+ .probe = scmi_perf_domain_probe,
+ .remove = scmi_perf_domain_remove,
+ .id_table = scmi_id_table,
+};
+module_scmi_driver(scmi_perf_domain_driver);
+
+MODULE_AUTHOR("Ulf Hansson <ulf.hansson@linaro.org>");
+MODULE_DESCRIPTION("ARM SCMI perf domain driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/firmware/arm_scmi/scmi_pm_domain.c b/drivers/pmdomain/arm/scmi_pm_domain.c
index 0e05a79de82d..0e05a79de82d 100644
--- a/drivers/firmware/arm_scmi/scmi_pm_domain.c
+++ b/drivers/pmdomain/arm/scmi_pm_domain.c
diff --git a/drivers/pmdomain/bcm/Kconfig b/drivers/pmdomain/bcm/Kconfig
new file mode 100644
index 000000000000..b28c9f6d256b
--- /dev/null
+++ b/drivers/pmdomain/bcm/Kconfig
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "Broadcom PM Domains"
+
+config BCM2835_POWER
+ bool "BCM2835 power domain driver"
+ depends on ARCH_BCM2835 || (COMPILE_TEST && OF)
+ default y if ARCH_BCM2835
+ select PM_GENERIC_DOMAINS if PM
+ select RESET_CONTROLLER
+ help
+ This enables support for the BCM2835 power domains and reset
+ controller. Any usage of power domains by the Raspberry Pi
+ firmware means that Linux usage of the same power domain
+ must be accessed using the RASPBERRYPI_POWER driver
+
+config RASPBERRYPI_POWER
+ bool "Raspberry Pi power domain driver"
+ depends on ARCH_BCM2835 || (COMPILE_TEST && OF)
+ depends on RASPBERRYPI_FIRMWARE=y
+ select PM_GENERIC_DOMAINS if PM
+ help
+ This enables support for the RPi power domains which can be enabled
+ or disabled via the RPi firmware.
+
+config BCM_PMB
+ bool "Broadcom PMB (Power Management Bus) driver"
+ depends on ARCH_BCMBCA || (COMPILE_TEST && OF)
+ default ARCH_BCMBCA
+ select PM_GENERIC_DOMAINS if PM
+ help
+ This enables support for the Broadcom's PMB (Power Management Bus) that
+ is used for disabling and enabling SoC devices.
+
+config BCM63XX_POWER
+ bool "BCM63xx power domain driver"
+ depends on BMIPS_GENERIC || (COMPILE_TEST && OF)
+ select PM_GENERIC_DOMAINS if PM
+ help
+ This enables support for the BCM63xx power domains controller on
+ BCM6318, BCM6328, BCM6362 and BCM63268 SoCs.
+
+endmenu
diff --git a/drivers/pmdomain/bcm/bcm2835-power.c b/drivers/pmdomain/bcm/bcm2835-power.c
index 1a179d4e011c..d2f0233cb620 100644
--- a/drivers/pmdomain/bcm/bcm2835-power.c
+++ b/drivers/pmdomain/bcm/bcm2835-power.c
@@ -175,7 +175,7 @@ static int bcm2835_asb_control(struct bcm2835_power *power, u32 reg, bool enable
}
writel(PM_PASSWORD | val, base + reg);
- while (readl(base + reg) & ASB_ACK) {
+ while (!!(readl(base + reg) & ASB_ACK) == enable) {
cpu_relax();
if (ktime_get_ns() - start >= 1000)
return -ETIMEDOUT;
diff --git a/drivers/pmdomain/imx/Kconfig b/drivers/pmdomain/imx/Kconfig
new file mode 100644
index 000000000000..00203615c65e
--- /dev/null
+++ b/drivers/pmdomain/imx/Kconfig
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "i.MX PM Domains"
+
+config IMX_GPCV2_PM_DOMAINS
+ bool "i.MX GPCv2 PM domains"
+ depends on ARCH_MXC || (COMPILE_TEST && OF)
+ depends on PM
+ select PM_GENERIC_DOMAINS
+ select REGMAP_MMIO
+ default y if SOC_IMX7D
+
+config IMX8M_BLK_CTRL
+ bool
+ default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
+ depends on PM_GENERIC_DOMAINS
+ depends on COMMON_CLK
+
+config IMX9_BLK_CTRL
+ bool
+ default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
+ depends on PM_GENERIC_DOMAINS
+
+config IMX_SCU_PD
+ bool "IMX SCU Power Domain driver"
+ depends on IMX_SCU
+ help
+ The System Controller Firmware (SCFW) based power domain driver.
+
+endmenu
diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c
index 90a8b2c0676f..7d81e3171d39 100644
--- a/drivers/pmdomain/imx/gpc.c
+++ b/drivers/pmdomain/imx/gpc.c
@@ -7,9 +7,10 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
@@ -403,9 +404,7 @@ clk_err:
static int imx_gpc_probe(struct platform_device *pdev)
{
- const struct of_device_id *of_id =
- of_match_device(imx_gpc_dt_ids, &pdev->dev);
- const struct imx_gpc_dt_data *of_id_data = of_id->data;
+ const struct imx_gpc_dt_data *of_id_data = device_get_match_data(&pdev->dev);
struct device_node *pgc_node;
struct regmap *regmap;
void __iomem *base;
@@ -498,6 +497,7 @@ static int imx_gpc_probe(struct platform_device *pdev)
pd_pdev->dev.parent = &pdev->dev;
pd_pdev->dev.of_node = np;
+ pd_pdev->dev.fwnode = of_fwnode_handle(np);
ret = platform_device_add(pd_pdev);
if (ret) {
diff --git a/drivers/pmdomain/mediatek/Kconfig b/drivers/pmdomain/mediatek/Kconfig
new file mode 100644
index 000000000000..21305c4f17fe
--- /dev/null
+++ b/drivers/pmdomain/mediatek/Kconfig
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menu "MediaTek PM Domains"
+ depends on ARCH_MEDIATEK || COMPILE_TEST
+
+config MTK_SCPSYS
+ bool "MediaTek SCPSYS Support"
+ default ARCH_MEDIATEK
+ depends on OF
+ select REGMAP
+ select MTK_INFRACFG
+ select PM_GENERIC_DOMAINS if PM
+ help
+ Say yes here to add support for the MediaTek SCPSYS power domain
+ driver.
+
+config MTK_SCPSYS_PM_DOMAINS
+ bool "MediaTek SCPSYS generic power domain"
+ default ARCH_MEDIATEK
+ depends on PM
+ select PM_GENERIC_DOMAINS
+ select REGMAP
+ help
+ Say y here to enable power domain support.
+ In order to meet high performance and low power requirements, the System
+ Control Processor System (SCPSYS) has several power management related
+ tasks in the system.
+
+endmenu
diff --git a/drivers/pmdomain/mediatek/mt6795-pm-domains.h b/drivers/pmdomain/mediatek/mt6795-pm-domains.h
index ef07c9dfdd9b..a3f7785b04bd 100644
--- a/drivers/pmdomain/mediatek/mt6795-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt6795-pm-domains.h
@@ -46,9 +46,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt6795[] = {
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
.sram_pdn_bits = GENMASK(11, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MM_M0 |
- MT8173_TOP_AXI_PROT_EN_MM_M1),
+ .bp_cfg = {
+ BUS_PROT_INFRA_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MM_M0 |
+ MT8173_TOP_AXI_PROT_EN_MM_M1),
},
},
[MT6795_POWER_DOMAIN_MJC] = {
@@ -95,11 +95,11 @@ static const struct scpsys_domain_data scpsys_domain_data_mt6795[] = {
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
.sram_pdn_bits = GENMASK(13, 8),
.sram_pdn_ack_bits = GENMASK(21, 16),
- .bp_infracfg = {
- BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MFG_S |
- MT8173_TOP_AXI_PROT_EN_MFG_M0 |
- MT8173_TOP_AXI_PROT_EN_MFG_M1 |
- MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT),
+ .bp_cfg = {
+ BUS_PROT_INFRA_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MFG_S |
+ MT8173_TOP_AXI_PROT_EN_MFG_M0 |
+ MT8173_TOP_AXI_PROT_EN_MFG_M1 |
+ MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT),
},
},
};
diff --git a/drivers/pmdomain/mediatek/mt8167-pm-domains.h b/drivers/pmdomain/mediatek/mt8167-pm-domains.h
index 4d6c32759606..8a0e898b79ab 100644
--- a/drivers/pmdomain/mediatek/mt8167-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8167-pm-domains.h
@@ -22,9 +22,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
.sram_pdn_bits = GENMASK(11, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_MM_EMI |
- MT8167_TOP_AXI_PROT_EN_MCU_MM),
+ .bp_cfg = {
+ BUS_PROT_INFRA_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_MM_EMI |
+ MT8167_TOP_AXI_PROT_EN_MCU_MM),
},
.caps = MTK_SCPD_ACTIVE_WAKEUP,
},
@@ -56,9 +56,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
.sram_pdn_bits = 0,
.sram_pdn_ack_bits = 0,
- .bp_infracfg = {
- BUS_PROT_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_MCU_MFG |
- MT8167_TOP_AXI_PROT_EN_MFG_EMI),
+ .bp_cfg = {
+ BUS_PROT_INFRA_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_MCU_MFG |
+ MT8167_TOP_AXI_PROT_EN_MFG_EMI),
},
},
[MT8167_POWER_DOMAIN_MFG_2D] = {
@@ -88,10 +88,10 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = 0,
.caps = MTK_SCPD_ACTIVE_WAKEUP,
- .bp_infracfg = {
- BUS_PROT_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_CONN_EMI |
- MT8167_TOP_AXI_PROT_EN_CONN_MCU |
- MT8167_TOP_AXI_PROT_EN_MCU_CONN),
+ .bp_cfg = {
+ BUS_PROT_INFRA_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_CONN_EMI |
+ MT8167_TOP_AXI_PROT_EN_CONN_MCU |
+ MT8167_TOP_AXI_PROT_EN_MCU_CONN),
},
},
};
diff --git a/drivers/pmdomain/mediatek/mt8173-pm-domains.h b/drivers/pmdomain/mediatek/mt8173-pm-domains.h
index 1a5dc63b7357..7be0f47f5214 100644
--- a/drivers/pmdomain/mediatek/mt8173-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8173-pm-domains.h
@@ -46,9 +46,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
.sram_pdn_bits = GENMASK(11, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MM_M0 |
- MT8173_TOP_AXI_PROT_EN_MM_M1),
+ .bp_cfg = {
+ BUS_PROT_INFRA_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MM_M0 |
+ MT8173_TOP_AXI_PROT_EN_MM_M1),
},
},
[MT8173_POWER_DOMAIN_VENC_LT] = {
@@ -106,11 +106,11 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
.sram_pdn_bits = GENMASK(13, 8),
.sram_pdn_ack_bits = GENMASK(21, 16),
- .bp_infracfg = {
- BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MFG_S |
- MT8173_TOP_AXI_PROT_EN_MFG_M0 |
- MT8173_TOP_AXI_PROT_EN_MFG_M1 |
- MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT),
+ .bp_cfg = {
+ BUS_PROT_INFRA_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MFG_S |
+ MT8173_TOP_AXI_PROT_EN_MFG_M0 |
+ MT8173_TOP_AXI_PROT_EN_MFG_M1 |
+ MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT),
},
},
};
diff --git a/drivers/pmdomain/mediatek/mt8183-pm-domains.h b/drivers/pmdomain/mediatek/mt8183-pm-domains.h
index 99de67fe5de8..c4c1b63d85b1 100644
--- a/drivers/pmdomain/mediatek/mt8183-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8183-pm-domains.h
@@ -28,9 +28,12 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = 0,
.sram_pdn_ack_bits = 0,
- .bp_infracfg = {
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_CONN, MT8183_TOP_AXI_PROT_EN_SET,
- MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1),
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_CONN,
+ MT8183_TOP_AXI_PROT_EN_SET,
+ MT8183_TOP_AXI_PROT_EN_CLR,
+ MT8183_TOP_AXI_PROT_EN_STA1),
},
},
[MT8183_POWER_DOMAIN_MFG_ASYNC] = {
@@ -79,11 +82,17 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_1_MFG, MT8183_TOP_AXI_PROT_EN_1_SET,
- MT8183_TOP_AXI_PROT_EN_1_CLR, MT8183_TOP_AXI_PROT_EN_STA1_1),
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MFG, MT8183_TOP_AXI_PROT_EN_SET,
- MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1),
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_1_MFG,
+ MT8183_TOP_AXI_PROT_EN_1_SET,
+ MT8183_TOP_AXI_PROT_EN_1_CLR,
+ MT8183_TOP_AXI_PROT_EN_STA1_1),
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MFG,
+ MT8183_TOP_AXI_PROT_EN_SET,
+ MT8183_TOP_AXI_PROT_EN_CLR,
+ MT8183_TOP_AXI_PROT_EN_STA1),
},
},
[MT8183_POWER_DOMAIN_DISP] = {
@@ -94,14 +103,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_1_DISP, MT8183_TOP_AXI_PROT_EN_1_SET,
- MT8183_TOP_AXI_PROT_EN_1_CLR, MT8183_TOP_AXI_PROT_EN_STA1_1),
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_DISP, MT8183_TOP_AXI_PROT_EN_SET,
- MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1),
- },
- .bp_smi = {
- BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_DISP,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_1_DISP,
+ MT8183_TOP_AXI_PROT_EN_1_SET,
+ MT8183_TOP_AXI_PROT_EN_1_CLR,
+ MT8183_TOP_AXI_PROT_EN_STA1_1),
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_DISP,
+ MT8183_TOP_AXI_PROT_EN_SET,
+ MT8183_TOP_AXI_PROT_EN_CLR,
+ MT8183_TOP_AXI_PROT_EN_STA1),
+ BUS_PROT_WR(SMI,
+ MT8183_SMI_COMMON_SMI_CLAMP_DISP,
MT8183_SMI_COMMON_CLAMP_EN_SET,
MT8183_SMI_COMMON_CLAMP_EN_CLR,
MT8183_SMI_COMMON_CLAMP_EN),
@@ -115,18 +129,24 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = GENMASK(9, 8),
.sram_pdn_ack_bits = GENMASK(13, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_CAM, MT8183_TOP_AXI_PROT_EN_MM_SET,
- MT8183_TOP_AXI_PROT_EN_MM_CLR, MT8183_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_CAM, MT8183_TOP_AXI_PROT_EN_SET,
- MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR_IGN(MT8183_TOP_AXI_PROT_EN_MM_CAM_2ND,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MM_CAM,
+ MT8183_TOP_AXI_PROT_EN_MM_SET,
+ MT8183_TOP_AXI_PROT_EN_MM_CLR,
+ MT8183_TOP_AXI_PROT_EN_MM_STA1),
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_CAM,
+ MT8183_TOP_AXI_PROT_EN_SET,
+ MT8183_TOP_AXI_PROT_EN_CLR,
+ MT8183_TOP_AXI_PROT_EN_STA1),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MM_CAM_2ND,
MT8183_TOP_AXI_PROT_EN_MM_SET,
MT8183_TOP_AXI_PROT_EN_MM_CLR,
MT8183_TOP_AXI_PROT_EN_MM_STA1),
- },
- .bp_smi = {
- BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_CAM,
+ BUS_PROT_WR(SMI,
+ MT8183_SMI_COMMON_SMI_CLAMP_CAM,
MT8183_SMI_COMMON_CLAMP_EN_SET,
MT8183_SMI_COMMON_CLAMP_EN_CLR,
MT8183_SMI_COMMON_CLAMP_EN),
@@ -140,18 +160,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = GENMASK(9, 8),
.sram_pdn_ack_bits = GENMASK(13, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_ISP,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MM_ISP,
MT8183_TOP_AXI_PROT_EN_MM_SET,
MT8183_TOP_AXI_PROT_EN_MM_CLR,
MT8183_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR_IGN(MT8183_TOP_AXI_PROT_EN_MM_ISP_2ND,
+ BUS_PROT_WR_IGN(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MM_ISP_2ND,
MT8183_TOP_AXI_PROT_EN_MM_SET,
MT8183_TOP_AXI_PROT_EN_MM_CLR,
MT8183_TOP_AXI_PROT_EN_MM_STA1),
- },
- .bp_smi = {
- BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_ISP,
+ BUS_PROT_WR(SMI,
+ MT8183_SMI_COMMON_SMI_CLAMP_ISP,
MT8183_SMI_COMMON_CLAMP_EN_SET,
MT8183_SMI_COMMON_CLAMP_EN_CLR,
MT8183_SMI_COMMON_CLAMP_EN),
@@ -165,8 +186,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_smi = {
- BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_VDEC,
+ .bp_cfg = {
+ BUS_PROT_WR(SMI,
+ MT8183_SMI_COMMON_SMI_CLAMP_VDEC,
MT8183_SMI_COMMON_CLAMP_EN_SET,
MT8183_SMI_COMMON_CLAMP_EN_CLR,
MT8183_SMI_COMMON_CLAMP_EN),
@@ -180,8 +202,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = GENMASK(11, 8),
.sram_pdn_ack_bits = GENMASK(15, 12),
- .bp_smi = {
- BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_VENC,
+ .bp_cfg = {
+ BUS_PROT_WR(SMI,
+ MT8183_SMI_COMMON_SMI_CLAMP_VENC,
MT8183_SMI_COMMON_CLAMP_EN_SET,
MT8183_SMI_COMMON_CLAMP_EN_CLR,
MT8183_SMI_COMMON_CLAMP_EN),
@@ -195,22 +218,24 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP,
MT8183_TOP_AXI_PROT_EN_MM_SET,
MT8183_TOP_AXI_PROT_EN_MM_CLR,
MT8183_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_VPU_TOP,
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_VPU_TOP,
MT8183_TOP_AXI_PROT_EN_SET,
MT8183_TOP_AXI_PROT_EN_CLR,
MT8183_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP_2ND,
MT8183_TOP_AXI_PROT_EN_MM_SET,
MT8183_TOP_AXI_PROT_EN_MM_CLR,
MT8183_TOP_AXI_PROT_EN_MM_STA1),
- },
- .bp_smi = {
- BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_VPU_TOP,
+ BUS_PROT_WR(SMI,
+ MT8183_SMI_COMMON_SMI_CLAMP_VPU_TOP,
MT8183_SMI_COMMON_CLAMP_EN_SET,
MT8183_SMI_COMMON_CLAMP_EN_CLR,
MT8183_SMI_COMMON_CLAMP_EN),
@@ -224,12 +249,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = GENMASK(11, 8),
.sram_pdn_ack_bits = GENMASK(13, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0,
MT8183_TOP_AXI_PROT_EN_MCU_SET,
MT8183_TOP_AXI_PROT_EN_MCU_CLR,
MT8183_TOP_AXI_PROT_EN_MCU_STA1),
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0_2ND,
MT8183_TOP_AXI_PROT_EN_MCU_SET,
MT8183_TOP_AXI_PROT_EN_MCU_CLR,
MT8183_TOP_AXI_PROT_EN_MCU_STA1),
@@ -244,12 +271,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
.pwr_sta2nd_offs = 0x0184,
.sram_pdn_bits = GENMASK(11, 8),
.sram_pdn_ack_bits = GENMASK(13, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1,
MT8183_TOP_AXI_PROT_EN_MCU_SET,
MT8183_TOP_AXI_PROT_EN_MCU_CLR,
MT8183_TOP_AXI_PROT_EN_MCU_STA1),
- BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1_2ND,
MT8183_TOP_AXI_PROT_EN_MCU_SET,
MT8183_TOP_AXI_PROT_EN_MCU_CLR,
MT8183_TOP_AXI_PROT_EN_MCU_STA1),
diff --git a/drivers/pmdomain/mediatek/mt8186-pm-domains.h b/drivers/pmdomain/mediatek/mt8186-pm-domains.h
index fce86f79c505..cbac715c38fa 100644
--- a/drivers/pmdomain/mediatek/mt8186-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8186-pm-domains.h
@@ -33,23 +33,27 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP1,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_MFG1_STEP2,
- MT8186_TOP_AXI_PROT_EN_SET,
- MT8186_TOP_AXI_PROT_EN_CLR,
- MT8186_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_MFG1_STEP3,
- MT8186_TOP_AXI_PROT_EN_SET,
- MT8186_TOP_AXI_PROT_EN_CLR,
- MT8186_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP4,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP1,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_MFG1_STEP2,
+ MT8186_TOP_AXI_PROT_EN_SET,
+ MT8186_TOP_AXI_PROT_EN_CLR,
+ MT8186_TOP_AXI_PROT_EN_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_MFG1_STEP3,
+ MT8186_TOP_AXI_PROT_EN_SET,
+ MT8186_TOP_AXI_PROT_EN_CLR,
+ MT8186_TOP_AXI_PROT_EN_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP4,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
},
.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY,
},
@@ -101,15 +105,17 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_DIS_STEP2,
- MT8186_TOP_AXI_PROT_EN_SET,
- MT8186_TOP_AXI_PROT_EN_CLR,
- MT8186_TOP_AXI_PROT_EN_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_DIS_STEP2,
+ MT8186_TOP_AXI_PROT_EN_SET,
+ MT8186_TOP_AXI_PROT_EN_CLR,
+ MT8186_TOP_AXI_PROT_EN_STA),
},
},
[MT8186_POWER_DOMAIN_IMG] = {
@@ -120,15 +126,17 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IMG_STEP1,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IMG_STEP2,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_IMG_STEP1,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_IMG_STEP2,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
},
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
},
@@ -150,15 +158,17 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IPE_STEP1,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IPE_STEP2,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_IPE_STEP1,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_IPE_STEP2,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
},
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
},
@@ -170,15 +180,17 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CAM_STEP1,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CAM_STEP2,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_CAM_STEP1,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_CAM_STEP2,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
},
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
},
@@ -210,15 +222,17 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VENC_STEP1,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VENC_STEP2,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_VENC_STEP1,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_VENC_STEP2,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
},
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
},
@@ -230,15 +244,17 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP1,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP2,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP1,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP2,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
},
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
},
@@ -250,15 +266,17 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_2_WPE_STEP1,
- MT8186_TOP_AXI_PROT_EN_2_SET,
- MT8186_TOP_AXI_PROT_EN_2_CLR,
- MT8186_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_2_WPE_STEP2,
- MT8186_TOP_AXI_PROT_EN_2_SET,
- MT8186_TOP_AXI_PROT_EN_2_CLR,
- MT8186_TOP_AXI_PROT_EN_2_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_2_WPE_STEP1,
+ MT8186_TOP_AXI_PROT_EN_2_SET,
+ MT8186_TOP_AXI_PROT_EN_2_CLR,
+ MT8186_TOP_AXI_PROT_EN_2_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_2_WPE_STEP2,
+ MT8186_TOP_AXI_PROT_EN_2_SET,
+ MT8186_TOP_AXI_PROT_EN_2_CLR,
+ MT8186_TOP_AXI_PROT_EN_2_STA),
},
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
},
@@ -268,23 +286,27 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.ctl_offs = 0x304,
.pwr_sta_offs = 0x16C,
.pwr_sta2nd_offs = 0x170,
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CONN_ON_STEP1,
- MT8186_TOP_AXI_PROT_EN_1_SET,
- MT8186_TOP_AXI_PROT_EN_1_CLR,
- MT8186_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP2,
- MT8186_TOP_AXI_PROT_EN_SET,
- MT8186_TOP_AXI_PROT_EN_CLR,
- MT8186_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP3,
- MT8186_TOP_AXI_PROT_EN_SET,
- MT8186_TOP_AXI_PROT_EN_CLR,
- MT8186_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP4,
- MT8186_TOP_AXI_PROT_EN_SET,
- MT8186_TOP_AXI_PROT_EN_CLR,
- MT8186_TOP_AXI_PROT_EN_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_1_CONN_ON_STEP1,
+ MT8186_TOP_AXI_PROT_EN_1_SET,
+ MT8186_TOP_AXI_PROT_EN_1_CLR,
+ MT8186_TOP_AXI_PROT_EN_1_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP2,
+ MT8186_TOP_AXI_PROT_EN_SET,
+ MT8186_TOP_AXI_PROT_EN_CLR,
+ MT8186_TOP_AXI_PROT_EN_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP3,
+ MT8186_TOP_AXI_PROT_EN_SET,
+ MT8186_TOP_AXI_PROT_EN_CLR,
+ MT8186_TOP_AXI_PROT_EN_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP4,
+ MT8186_TOP_AXI_PROT_EN_SET,
+ MT8186_TOP_AXI_PROT_EN_CLR,
+ MT8186_TOP_AXI_PROT_EN_STA),
},
.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP,
},
@@ -320,15 +342,17 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP1,
- MT8186_TOP_AXI_PROT_EN_3_SET,
- MT8186_TOP_AXI_PROT_EN_3_CLR,
- MT8186_TOP_AXI_PROT_EN_3_STA),
- BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP2,
- MT8186_TOP_AXI_PROT_EN_3_SET,
- MT8186_TOP_AXI_PROT_EN_3_CLR,
- MT8186_TOP_AXI_PROT_EN_3_STA),
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP1,
+ MT8186_TOP_AXI_PROT_EN_3_SET,
+ MT8186_TOP_AXI_PROT_EN_3_CLR,
+ MT8186_TOP_AXI_PROT_EN_3_STA),
+ BUS_PROT_WR_IGN(INFRA,
+ MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP2,
+ MT8186_TOP_AXI_PROT_EN_3_SET,
+ MT8186_TOP_AXI_PROT_EN_3_CLR,
+ MT8186_TOP_AXI_PROT_EN_3_STA),
},
.caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_ACTIVE_WAKEUP,
},
diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
index 0692cb444ed0..06834ab6597c 100644
--- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
@@ -33,28 +33,34 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x178,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MFG1_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MFG1_STEP1,
MT8188_TOP_AXI_PROT_EN_SET,
MT8188_TOP_AXI_PROT_EN_CLR,
MT8188_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_MFG1_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_MFG1_STEP2,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_1_MFG1_STEP3,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_1_MFG1_STEP3,
MT8188_TOP_AXI_PROT_EN_1_SET,
MT8188_TOP_AXI_PROT_EN_1_CLR,
MT8188_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_MFG1_STEP4,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_MFG1_STEP4,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MFG1_STEP5,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MFG1_STEP5,
MT8188_TOP_AXI_PROT_EN_SET,
MT8188_TOP_AXI_PROT_EN_CLR,
MT8188_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1_STEP6,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1_STEP6,
MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA),
@@ -99,12 +105,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x178,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_PEXTP_MAC_P0_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_PEXTP_MAC_P0_STEP1,
MT8188_TOP_AXI_PROT_EN_SET,
MT8188_TOP_AXI_PROT_EN_CLR,
MT8188_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_PEXTP_MAC_P0_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_PEXTP_MAC_P0_STEP2,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA),
@@ -135,8 +143,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_ETHER_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_ETHER_STEP1,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA),
@@ -151,8 +160,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_HDMI_TX_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_HDMI_TX_STEP1,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA),
@@ -165,12 +175,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.ctl_offs = 0x35C,
.pwr_sta_offs = 0x16C,
.pwr_sta2nd_offs = 0x170,
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP1,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP2,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
@@ -185,12 +197,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_INFRA_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_ADSP_INFRA_STEP1,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_INFRA_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_ADSP_INFRA_STEP2,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
@@ -205,12 +219,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_ADSP_STEP1,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_ADSP_STEP2,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
@@ -225,12 +241,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
@@ -245,12 +263,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_AUDIO_ASRC_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_AUDIO_ASRC_STEP1,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_AUDIO_ASRC_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_AUDIO_ASRC_STEP2,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
@@ -265,24 +285,29 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_VPPSYS0_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_VPPSYS0_STEP1,
MT8188_TOP_AXI_PROT_EN_SET,
MT8188_TOP_AXI_PROT_EN_CLR,
MT8188_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS0_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS0_STEP2,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_VPPSYS0_STEP3,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_VPPSYS0_STEP3,
MT8188_TOP_AXI_PROT_EN_SET,
MT8188_TOP_AXI_PROT_EN_CLR,
MT8188_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS0_STEP4,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS0_STEP4,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0_STEP5,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0_STEP5,
MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA),
@@ -296,16 +321,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDOSYS0_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VDOSYS0_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_VDOSYS0_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_VDOSYS0_STEP2,
MT8188_TOP_AXI_PROT_EN_SET,
MT8188_TOP_AXI_PROT_EN_CLR,
MT8188_TOP_AXI_PROT_EN_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0_STEP3,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0_STEP3,
MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA),
@@ -319,16 +347,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDOSYS1_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VDOSYS1_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDOSYS1_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VDOSYS1_STEP2,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VDOSYS1_STEP3,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_VDOSYS1_STEP3,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
@@ -342,8 +373,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_DP_TX_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_DP_TX_STEP1,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA),
@@ -358,8 +390,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_EDP_TX_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_EDP_TX_STEP1,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR,
MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA),
@@ -374,16 +407,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VPPSYS1_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VPPSYS1_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VPPSYS1_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VPPSYS1_STEP2,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS1_STEP3,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS1_STEP3,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
@@ -397,12 +433,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_WPE_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_WPE_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_WPE_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_WPE_STEP2,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
@@ -417,12 +455,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDEC0_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VDEC0_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VDEC0_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_VDEC0_STEP2,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
@@ -437,12 +477,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDEC1_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VDEC1_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDEC1_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VDEC1_STEP2,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
@@ -457,16 +499,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VENC_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VENC_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VENC_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_VENC_STEP2,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VENC_STEP3,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_VENC_STEP3,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
@@ -479,16 +524,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.ctl_offs = 0x3A4,
.pwr_sta_offs = 0x16C,
.pwr_sta2nd_offs = 0x170,
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP2,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_IMG_VCORE_STEP3,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_IMG_VCORE_STEP3,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
@@ -503,12 +551,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_IMG_MAIN_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_IMG_MAIN_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_IMG_MAIN_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_IMG_MAIN_STEP2,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
@@ -541,24 +591,29 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.ctl_offs = 0x3A0,
.pwr_sta_offs = 0x16C,
.pwr_sta2nd_offs = 0x170,
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_CAM_VCORE_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_CAM_VCORE_STEP2,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_1_CAM_VCORE_STEP3,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_1_CAM_VCORE_STEP3,
MT8188_TOP_AXI_PROT_EN_1_SET,
MT8188_TOP_AXI_PROT_EN_1_CLR,
MT8188_TOP_AXI_PROT_EN_1_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP4,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP4,
MT8188_TOP_AXI_PROT_EN_MM_SET,
MT8188_TOP_AXI_PROT_EN_MM_CLR,
MT8188_TOP_AXI_PROT_EN_MM_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_CAM_VCORE_STEP5,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_CAM_VCORE_STEP5,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
@@ -573,20 +628,24 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = BIT(8),
.sram_pdn_ack_bits = BIT(12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_CAM_MAIN_STEP1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_CAM_MAIN_STEP1,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_CAM_MAIN_STEP2,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_CAM_MAIN_STEP2,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_CAM_MAIN_STEP3,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_MM_2_CAM_MAIN_STEP3,
MT8188_TOP_AXI_PROT_EN_MM_2_SET,
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
- BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_CAM_MAIN_STEP4,
+ BUS_PROT_WR(INFRA,
+ MT8188_TOP_AXI_PROT_EN_2_CAM_MAIN_STEP4,
MT8188_TOP_AXI_PROT_EN_2_SET,
MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA),
diff --git a/drivers/pmdomain/mediatek/mt8192-pm-domains.h b/drivers/pmdomain/mediatek/mt8192-pm-domains.h
index b97b2051920f..6f139eed3769 100644
--- a/drivers/pmdomain/mediatek/mt8192-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8192-pm-domains.h
@@ -19,8 +19,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_AUDIO,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_2_AUDIO,
MT8192_TOP_AXI_PROT_EN_2_SET,
MT8192_TOP_AXI_PROT_EN_2_CLR,
MT8192_TOP_AXI_PROT_EN_2_STA1),
@@ -34,16 +35,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = 0,
.sram_pdn_ack_bits = 0,
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_CONN,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_CONN,
MT8192_TOP_AXI_PROT_EN_SET,
MT8192_TOP_AXI_PROT_EN_CLR,
MT8192_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_CONN_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_CONN_2ND,
MT8192_TOP_AXI_PROT_EN_SET,
MT8192_TOP_AXI_PROT_EN_CLR,
MT8192_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_1_CONN,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_1_CONN,
MT8192_TOP_AXI_PROT_EN_1_SET,
MT8192_TOP_AXI_PROT_EN_1_CLR,
MT8192_TOP_AXI_PROT_EN_1_STA1),
@@ -68,20 +72,24 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_1_MFG1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_1_MFG1,
MT8192_TOP_AXI_PROT_EN_1_SET,
MT8192_TOP_AXI_PROT_EN_1_CLR,
MT8192_TOP_AXI_PROT_EN_1_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_MFG1,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_2_MFG1,
MT8192_TOP_AXI_PROT_EN_2_SET,
MT8192_TOP_AXI_PROT_EN_2_CLR,
MT8192_TOP_AXI_PROT_EN_2_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MFG1,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MFG1,
MT8192_TOP_AXI_PROT_EN_SET,
MT8192_TOP_AXI_PROT_EN_CLR,
MT8192_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_MFG1_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_2_MFG1_2ND,
MT8192_TOP_AXI_PROT_EN_2_SET,
MT8192_TOP_AXI_PROT_EN_2_CLR,
MT8192_TOP_AXI_PROT_EN_2_STA1),
@@ -141,24 +149,29 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR_IGN(MT8192_TOP_AXI_PROT_EN_MM_DISP,
+ .bp_cfg = {
+ BUS_PROT_WR_IGN(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_DISP,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR_IGN(MT8192_TOP_AXI_PROT_EN_MM_2_DISP,
+ BUS_PROT_WR_IGN(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_2_DISP,
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_DISP,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_DISP,
MT8192_TOP_AXI_PROT_EN_SET,
MT8192_TOP_AXI_PROT_EN_CLR,
MT8192_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_DISP_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_DISP_2ND,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_DISP_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_2_DISP_2ND,
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -172,12 +185,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_IPE,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_IPE,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_IPE_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_IPE_2ND,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
@@ -191,12 +206,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_ISP,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_2_ISP,
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_ISP_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_2_ISP_2ND,
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -210,12 +227,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_ISP2,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_ISP2,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_ISP2_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_ISP2_2ND,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
@@ -229,12 +248,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_MDP,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_2_MDP,
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND,
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -248,12 +269,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VENC,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_VENC,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VENC_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_VENC_2ND,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
@@ -267,12 +290,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VDEC,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_VDEC,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VDEC_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_VDEC_2ND,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
@@ -295,24 +320,29 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
.pwr_sta2nd_offs = 0x0170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_CAM,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_2_CAM,
MT8192_TOP_AXI_PROT_EN_2_SET,
MT8192_TOP_AXI_PROT_EN_2_CLR,
MT8192_TOP_AXI_PROT_EN_2_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_CAM,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_CAM,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_1_CAM,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_1_CAM,
MT8192_TOP_AXI_PROT_EN_1_SET,
MT8192_TOP_AXI_PROT_EN_1_CLR,
MT8192_TOP_AXI_PROT_EN_1_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_CAM_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_MM_CAM_2ND,
MT8192_TOP_AXI_PROT_EN_MM_SET,
MT8192_TOP_AXI_PROT_EN_MM_CLR,
MT8192_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_VDNR_CAM,
+ BUS_PROT_WR(INFRA,
+ MT8192_TOP_AXI_PROT_EN_VDNR_CAM,
MT8192_TOP_AXI_PROT_EN_VDNR_SET,
MT8192_TOP_AXI_PROT_EN_VDNR_CLR,
MT8192_TOP_AXI_PROT_EN_VDNR_STA1),
diff --git a/drivers/pmdomain/mediatek/mt8195-pm-domains.h b/drivers/pmdomain/mediatek/mt8195-pm-domains.h
index d7387ea1b9c9..59aa031ae632 100644
--- a/drivers/pmdomain/mediatek/mt8195-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8195-pm-domains.h
@@ -23,12 +23,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x178,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0,
MT8195_TOP_AXI_PROT_EN_VDNR_SET,
MT8195_TOP_AXI_PROT_EN_VDNR_CLR,
MT8195_TOP_AXI_PROT_EN_VDNR_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0,
MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
@@ -42,12 +44,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x178,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1,
MT8195_TOP_AXI_PROT_EN_VDNR_SET,
MT8195_TOP_AXI_PROT_EN_VDNR_CLR,
MT8195_TOP_AXI_PROT_EN_VDNR_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1,
MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
@@ -95,8 +99,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_ADSP,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_2_ADSP,
MT8195_TOP_AXI_PROT_EN_2_SET,
MT8195_TOP_AXI_PROT_EN_2_CLR,
MT8195_TOP_AXI_PROT_EN_2_STA1),
@@ -111,8 +116,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_AUDIO,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_2_AUDIO,
MT8195_TOP_AXI_PROT_EN_2_SET,
MT8195_TOP_AXI_PROT_EN_2_CLR,
MT8195_TOP_AXI_PROT_EN_2_STA1),
@@ -136,28 +142,34 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x178,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MFG1,
MT8195_TOP_AXI_PROT_EN_SET,
MT8195_TOP_AXI_PROT_EN_CLR,
MT8195_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_2_MFG1,
MT8195_TOP_AXI_PROT_EN_2_SET,
MT8195_TOP_AXI_PROT_EN_2_CLR,
MT8195_TOP_AXI_PROT_EN_2_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_MFG1,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_1_MFG1,
MT8195_TOP_AXI_PROT_EN_1_SET,
MT8195_TOP_AXI_PROT_EN_1_CLR,
MT8195_TOP_AXI_PROT_EN_1_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND,
MT8195_TOP_AXI_PROT_EN_2_SET,
MT8195_TOP_AXI_PROT_EN_2_CLR,
MT8195_TOP_AXI_PROT_EN_2_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MFG1_2ND,
MT8195_TOP_AXI_PROT_EN_SET,
MT8195_TOP_AXI_PROT_EN_CLR,
MT8195_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1,
MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
@@ -222,24 +234,29 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_VPPSYS0,
MT8195_TOP_AXI_PROT_EN_SET,
MT8195_TOP_AXI_PROT_EN_CLR,
MT8195_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND,
MT8195_TOP_AXI_PROT_EN_SET,
MT8195_TOP_AXI_PROT_EN_CLR,
MT8195_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0,
MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
@@ -253,16 +270,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDOSYS0,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_VDOSYS0,
MT8195_TOP_AXI_PROT_EN_SET,
MT8195_TOP_AXI_PROT_EN_CLR,
MT8195_TOP_AXI_PROT_EN_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0,
MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
@@ -276,16 +296,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -299,16 +322,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -322,8 +348,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX,
MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
@@ -338,8 +365,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX,
MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
@@ -364,16 +392,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_WPESYS,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_WPESYS,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -387,20 +418,24 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VDEC0,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -415,12 +450,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VDEC1,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
@@ -435,12 +472,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -455,16 +494,19 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VENC,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VENC,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -479,12 +521,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -499,12 +543,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_IMG,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
@@ -529,12 +575,14 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IPE,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_IPE,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_IPE,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_IPE,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
@@ -549,24 +597,29 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
.pwr_sta2nd_offs = 0x170,
.sram_pdn_bits = GENMASK(8, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
- .bp_infracfg = {
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_CAM,
+ .bp_cfg = {
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_2_CAM,
MT8195_TOP_AXI_PROT_EN_2_SET,
MT8195_TOP_AXI_PROT_EN_2_CLR,
MT8195_TOP_AXI_PROT_EN_2_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_CAM,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_CAM,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_1_CAM,
MT8195_TOP_AXI_PROT_EN_1_SET,
MT8195_TOP_AXI_PROT_EN_1_CLR,
MT8195_TOP_AXI_PROT_EN_1_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND,
MT8195_TOP_AXI_PROT_EN_MM_SET,
MT8195_TOP_AXI_PROT_EN_MM_CLR,
MT8195_TOP_AXI_PROT_EN_MM_STA1),
- BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_CAM,
+ BUS_PROT_WR(INFRA,
+ MT8195_TOP_AXI_PROT_EN_MM_2_CAM,
MT8195_TOP_AXI_PROT_EN_MM_2_SET,
MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
diff --git a/drivers/pmdomain/mediatek/mt8365-pm-domains.h b/drivers/pmdomain/mediatek/mt8365-pm-domains.h
new file mode 100644
index 000000000000..3d83d49eaa7c
--- /dev/null
+++ b/drivers/pmdomain/mediatek/mt8365-pm-domains.h
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8365_PM_DOMAINS_H
+#define __SOC_MEDIATEK_MT8365_PM_DOMAINS_H
+
+#include "mtk-pm-domains.h"
+#include <dt-bindings/power/mediatek,mt8365-power.h>
+
+/*
+ * MT8365 power domain support
+ */
+
+#define MT8365_BUS_PROT_INFRA_WR_TOPAXI(_mask) \
+ BUS_PROT_WR(INFRA, _mask, \
+ MT8365_INFRA_TOPAXI_PROTECTEN_SET, \
+ MT8365_INFRA_TOPAXI_PROTECTEN_CLR, \
+ MT8365_INFRA_TOPAXI_PROTECTEN_STA1)
+
+#define MT8365_BUS_PROT_INFRA_WR_TOPAXI_1(_mask) \
+ BUS_PROT_WR(INFRA, _mask, \
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_SET, \
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_CLR, \
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_STA1)
+
+#define MT8365_BUS_PROT_SMI_WR_CLAMP_EN_PORT(port) \
+ BUS_PROT_WR(SMI, BIT(port), \
+ MT8365_SMI_COMMON_CLAMP_EN_SET, \
+ MT8365_SMI_COMMON_CLAMP_EN_CLR, \
+ MT8365_SMI_COMMON_CLAMP_EN)
+
+#define MT8365_BUS_PROT_WAY_EN(_set_mask, _set, _sta_mask, _sta) \
+ _BUS_PROT(_set_mask, _set, _set, _sta_mask, _sta, \
+ BUS_PROT_COMPONENT_INFRA | \
+ BUS_PROT_STA_COMPONENT_INFRA_NAO | \
+ BUS_PROT_INVERTED | \
+ BUS_PROT_REG_UPDATE)
+
+static const struct scpsys_domain_data scpsys_domain_data_mt8365[] = {
+ [MT8365_POWER_DOMAIN_MM] = {
+ .name = "mm",
+ .sta_mask = PWR_STATUS_DISP,
+ .ctl_offs = 0x30c,
+ .pwr_sta_offs = 0x0180,
+ .pwr_sta2nd_offs = 0x0184,
+ .sram_pdn_bits = GENMASK(8, 8),
+ .sram_pdn_ack_bits = GENMASK(12, 12),
+ .bp_cfg = {
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI_1(
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_MM2INFRA_AXI_GALS_MST_0 |
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_MM2INFRA_AXI_GALS_MST_1),
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI(
+ MT8365_INFRA_TOPAXI_PROTECTEN_MM_M0 |
+ MT8365_INFRA_TOPAXI_PROTECTEN_MDMCU_M1 |
+ MT8365_INFRA_TOPAXI_PROTECTEN_MM2INFRA_AXI_GALS_SLV_0 |
+ MT8365_INFRA_TOPAXI_PROTECTEN_MM2INFRA_AXI_GALS_SLV_1),
+ MT8365_BUS_PROT_WAY_EN(
+ MT8365_INFRA_TOPAXI_SI0_WAY_EN_MMAPB_S,
+ MT8365_INFRA_TOPAXI_SI0_CTL,
+ MT8365_INFRA_NAO_TOPAXI_SI0_CTRL_UPDATED,
+ MT8365_INFRA_NAO_TOPAXI_SI0_STA),
+ MT8365_BUS_PROT_WAY_EN(
+ MT8365_INFRA_TOPAXI_SI2_WAY_EN_PERI_M1,
+ MT8365_INFRA_TOPAXI_SI2_CTL,
+ MT8365_INFRA_NAO_TOPAXI_SI2_CTRL_UPDATED,
+ MT8365_INFRA_NAO_TOPAXI_SI2_STA),
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI(
+ MT8365_INFRA_TOPAXI_PROTECTEN_MMAPB_S),
+ },
+ .caps = MTK_SCPD_STRICT_BUS_PROTECTION | MTK_SCPD_HAS_INFRA_NAO,
+ },
+ [MT8365_POWER_DOMAIN_VENC] = {
+ .name = "venc",
+ .sta_mask = PWR_STATUS_VENC,
+ .ctl_offs = 0x0304,
+ .pwr_sta_offs = 0x0180,
+ .pwr_sta2nd_offs = 0x0184,
+ .sram_pdn_bits = GENMASK(8, 8),
+ .sram_pdn_ack_bits = GENMASK(12, 12),
+ .bp_cfg = {
+ MT8365_BUS_PROT_SMI_WR_CLAMP_EN_PORT(1),
+ },
+ },
+ [MT8365_POWER_DOMAIN_AUDIO] = {
+ .name = "audio",
+ .sta_mask = PWR_STATUS_AUDIO,
+ .ctl_offs = 0x0314,
+ .pwr_sta_offs = 0x0180,
+ .pwr_sta2nd_offs = 0x0184,
+ .sram_pdn_bits = GENMASK(12, 8),
+ .sram_pdn_ack_bits = GENMASK(17, 13),
+ .bp_cfg = {
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI_1(
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_PWRDNREQ_MP1_L2C_AFIFO |
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_AUDIO_BUS_AUDIO_M),
+ },
+ .caps = MTK_SCPD_ACTIVE_WAKEUP,
+ },
+ [MT8365_POWER_DOMAIN_CONN] = {
+ .name = "conn",
+ .sta_mask = PWR_STATUS_CONN,
+ .ctl_offs = 0x032c,
+ .pwr_sta_offs = 0x0180,
+ .pwr_sta2nd_offs = 0x0184,
+ .sram_pdn_bits = 0,
+ .sram_pdn_ack_bits = 0,
+ .bp_cfg = {
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI(
+ MT8365_INFRA_TOPAXI_PROTECTEN_AP2CONN_AHB),
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI_1(
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_CONN2INFRA_AXI_GALS_MST),
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI(
+ MT8365_INFRA_TOPAXI_PROTECTEN_CONN2INFRA_AHB),
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI_1(
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_INFRA2CONN_AHB_GALS_SLV),
+ },
+ .caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_KEEP_DEFAULT_OFF,
+ },
+ [MT8365_POWER_DOMAIN_MFG] = {
+ .name = "mfg",
+ .sta_mask = PWR_STATUS_MFG,
+ .ctl_offs = 0x0338,
+ .pwr_sta_offs = 0x0180,
+ .pwr_sta2nd_offs = 0x0184,
+ .sram_pdn_bits = GENMASK(9, 8),
+ .sram_pdn_ack_bits = GENMASK(13, 12),
+ .bp_cfg = {
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI(BIT(25)),
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI(
+ MT8365_INFRA_TOPAXI_PROTECTEN_MFG_M0 |
+ MT8365_INFRA_TOPAXI_PROTECTEN_INFRA2MFG),
+ },
+ },
+ [MT8365_POWER_DOMAIN_CAM] = {
+ .name = "cam",
+ .sta_mask = BIT(25),
+ .ctl_offs = 0x0344,
+ .pwr_sta_offs = 0x0180,
+ .pwr_sta2nd_offs = 0x0184,
+ .sram_pdn_bits = GENMASK(9, 8),
+ .sram_pdn_ack_bits = GENMASK(13, 12),
+ .bp_cfg = {
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI_1(
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_CAM2MM_AXI_GALS_MST),
+ MT8365_BUS_PROT_SMI_WR_CLAMP_EN_PORT(2),
+ },
+ },
+ [MT8365_POWER_DOMAIN_VDEC] = {
+ .name = "vdec",
+ .sta_mask = BIT(31),
+ .ctl_offs = 0x0370,
+ .pwr_sta_offs = 0x0180,
+ .pwr_sta2nd_offs = 0x0184,
+ .sram_pdn_bits = GENMASK(8, 8),
+ .sram_pdn_ack_bits = GENMASK(12, 12),
+ .bp_cfg = {
+ MT8365_BUS_PROT_SMI_WR_CLAMP_EN_PORT(3),
+ },
+ },
+ [MT8365_POWER_DOMAIN_APU] = {
+ .name = "apu",
+ .sta_mask = BIT(16),
+ .ctl_offs = 0x0378,
+ .pwr_sta_offs = 0x0180,
+ .pwr_sta2nd_offs = 0x0184,
+ .sram_pdn_bits = GENMASK(14, 8),
+ .sram_pdn_ack_bits = GENMASK(21, 15),
+ .bp_cfg = {
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI_1(
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_APU2AP |
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_APU_CBIP_GALS_MST),
+ MT8365_BUS_PROT_SMI_WR_CLAMP_EN_PORT(4),
+ },
+ },
+ [MT8365_POWER_DOMAIN_DSP] = {
+ .name = "dsp",
+ .sta_mask = BIT(17),
+ .ctl_offs = 0x037C,
+ .pwr_sta_offs = 0x0180,
+ .pwr_sta2nd_offs = 0x0184,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .bp_cfg = {
+ MT8365_BUS_PROT_INFRA_WR_TOPAXI_1(
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_PWRDNREQ_INFRA_GALS_ADB |
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_AUDIO_BUS_DSP_M |
+ MT8365_INFRA_TOPAXI_PROTECTEN_1_AUDIO_BUS_DSP_S),
+ },
+ .caps = MTK_SCPD_ACTIVE_WAKEUP,
+ },
+};
+
+static const struct scpsys_soc_data mt8365_scpsys_data = {
+ .domains_data = scpsys_domain_data_mt8365,
+ .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8365),
+};
+
+#endif /* __SOC_MEDIATEK_MT8365_PM_DOMAINS_H */
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
index ee962804b830..e26dc17d07ad 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
@@ -24,6 +24,7 @@
#include "mt8188-pm-domains.h"
#include "mt8192-pm-domains.h"
#include "mt8195-pm-domains.h"
+#include "mt8365-pm-domains.h"
#define MTK_POLL_DELAY_US 10
#define MTK_POLL_TIMEOUT USEC_PER_SEC
@@ -44,6 +45,7 @@ struct scpsys_domain {
struct clk_bulk_data *clks;
int num_subsys_clks;
struct clk_bulk_data *subsys_clks;
+ struct regmap *infracfg_nao;
struct regmap *infracfg;
struct regmap *smi;
struct regulator *supply;
@@ -118,64 +120,79 @@ static int scpsys_sram_disable(struct scpsys_domain *pd)
MTK_POLL_TIMEOUT);
}
-static int _scpsys_bus_protect_enable(const struct scpsys_bus_prot_data *bpd, struct regmap *regmap)
+static struct regmap *scpsys_bus_protect_get_regmap(struct scpsys_domain *pd,
+ const struct scpsys_bus_prot_data *bpd)
{
- int i, ret;
+ if (bpd->flags & BUS_PROT_COMPONENT_SMI)
+ return pd->smi;
+ else
+ return pd->infracfg;
+}
- for (i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
- u32 val, mask = bpd[i].bus_prot_mask;
+static struct regmap *scpsys_bus_protect_get_sta_regmap(struct scpsys_domain *pd,
+ const struct scpsys_bus_prot_data *bpd)
+{
+ if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
+ return pd->infracfg_nao;
+ else
+ return scpsys_bus_protect_get_regmap(pd, bpd);
+}
- if (!mask)
- break;
+static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
+ const struct scpsys_bus_prot_data *bpd)
+{
+ struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
+ struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
+ u32 sta_mask = bpd->bus_prot_sta_mask;
+ u32 expected_ack;
+ u32 val;
- if (bpd[i].bus_prot_reg_update)
- regmap_set_bits(regmap, bpd[i].bus_prot_set, mask);
- else
- regmap_write(regmap, bpd[i].bus_prot_set, mask);
+ expected_ack = (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO ? sta_mask : 0);
- ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta,
- val, (val & mask) == mask,
- MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
- if (ret)
- return ret;
- }
+ if (bpd->flags & BUS_PROT_REG_UPDATE)
+ regmap_clear_bits(regmap, bpd->bus_prot_clr, bpd->bus_prot_set_clr_mask);
+ else
+ regmap_write(regmap, bpd->bus_prot_clr, bpd->bus_prot_set_clr_mask);
- return 0;
+ if (bpd->flags & BUS_PROT_IGNORE_CLR_ACK)
+ return 0;
+
+ return regmap_read_poll_timeout(sta_regmap, bpd->bus_prot_sta,
+ val, (val & sta_mask) == expected_ack,
+ MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
}
-static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
+static int scpsys_bus_protect_set(struct scpsys_domain *pd,
+ const struct scpsys_bus_prot_data *bpd)
{
- int ret;
+ struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
+ struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
+ u32 sta_mask = bpd->bus_prot_sta_mask;
+ u32 val;
- ret = _scpsys_bus_protect_enable(pd->data->bp_infracfg, pd->infracfg);
- if (ret)
- return ret;
+ if (bpd->flags & BUS_PROT_REG_UPDATE)
+ regmap_set_bits(regmap, bpd->bus_prot_set, bpd->bus_prot_set_clr_mask);
+ else
+ regmap_write(regmap, bpd->bus_prot_set, bpd->bus_prot_set_clr_mask);
- return _scpsys_bus_protect_enable(pd->data->bp_smi, pd->smi);
+ return regmap_read_poll_timeout(sta_regmap, bpd->bus_prot_sta,
+ val, (val & sta_mask) == sta_mask,
+ MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
}
-static int _scpsys_bus_protect_disable(const struct scpsys_bus_prot_data *bpd,
- struct regmap *regmap)
+static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
{
- int i, ret;
+ for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
+ const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
+ int ret;
- for (i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
- u32 val, mask = bpd[i].bus_prot_mask;
-
- if (!mask)
- continue;
+ if (!bpd->bus_prot_set_clr_mask)
+ break;
- if (bpd[i].bus_prot_reg_update)
- regmap_clear_bits(regmap, bpd[i].bus_prot_clr, mask);
+ if (bpd->flags & BUS_PROT_INVERTED)
+ ret = scpsys_bus_protect_clear(pd, bpd);
else
- regmap_write(regmap, bpd[i].bus_prot_clr, mask);
-
- if (bpd[i].ignore_clr_ack)
- continue;
-
- ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta,
- val, !(val & mask),
- MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+ ret = scpsys_bus_protect_set(pd, bpd);
if (ret)
return ret;
}
@@ -185,13 +202,22 @@ static int _scpsys_bus_protect_disable(const struct scpsys_bus_prot_data *bpd,
static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
{
- int ret;
+ for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
+ const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
+ int ret;
- ret = _scpsys_bus_protect_disable(pd->data->bp_smi, pd->smi);
- if (ret)
- return ret;
+ if (!bpd->bus_prot_set_clr_mask)
+ continue;
- return _scpsys_bus_protect_disable(pd->data->bp_infracfg, pd->infracfg);
+ if (bpd->flags & BUS_PROT_INVERTED)
+ ret = scpsys_bus_protect_set(pd, bpd);
+ else
+ ret = scpsys_bus_protect_clear(pd, bpd);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static int scpsys_regulator_enable(struct regulator *supply)
@@ -237,9 +263,17 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT);
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
- ret = clk_bulk_prepare_enable(pd->num_subsys_clks, pd->subsys_clks);
- if (ret)
- goto err_pwr_ack;
+ /*
+ * In few Mediatek platforms(e.g. MT6779), the bus protect policy is
+ * stricter, which leads to bus protect release must be prior to bus
+ * access.
+ */
+ if (!MTK_SCPD_CAPS(pd, MTK_SCPD_STRICT_BUS_PROTECTION)) {
+ ret = clk_bulk_prepare_enable(pd->num_subsys_clks,
+ pd->subsys_clks);
+ if (ret)
+ goto err_pwr_ack;
+ }
ret = scpsys_sram_enable(pd);
if (ret < 0)
@@ -249,12 +283,23 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
if (ret < 0)
goto err_disable_sram;
+ if (MTK_SCPD_CAPS(pd, MTK_SCPD_STRICT_BUS_PROTECTION)) {
+ ret = clk_bulk_prepare_enable(pd->num_subsys_clks,
+ pd->subsys_clks);
+ if (ret)
+ goto err_enable_bus_protect;
+ }
+
return 0;
+err_enable_bus_protect:
+ scpsys_bus_protect_enable(pd);
err_disable_sram:
scpsys_sram_disable(pd);
err_disable_subsys_clks:
- clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
+ if (!MTK_SCPD_CAPS(pd, MTK_SCPD_STRICT_BUS_PROTECTION))
+ clk_bulk_disable_unprepare(pd->num_subsys_clks,
+ pd->subsys_clks);
err_pwr_ack:
clk_bulk_disable_unprepare(pd->num_clks, pd->clks);
err_reg:
@@ -373,6 +418,14 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
return ERR_CAST(pd->smi);
}
+ if (MTK_SCPD_CAPS(pd, MTK_SCPD_HAS_INFRA_NAO)) {
+ pd->infracfg_nao = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg-nao");
+ if (IS_ERR(pd->infracfg_nao))
+ return ERR_CAST(pd->infracfg_nao);
+ } else {
+ pd->infracfg_nao = NULL;
+ }
+
num_clks = of_clk_get_parent_count(node);
if (num_clks > 0) {
/* Calculate number of subsys_clks */
@@ -600,6 +653,10 @@ static const struct of_device_id scpsys_of_match[] = {
.compatible = "mediatek,mt8195-power-controller",
.data = &mt8195_scpsys_data,
},
+ {
+ .compatible = "mediatek,mt8365-power-controller",
+ .data = &mt8365_scpsys_data,
+ },
{ }
};
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/mediatek/mtk-pm-domains.h
index 5ec53ee073c4..aaba5e6b0536 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h
@@ -11,6 +11,8 @@
/* can't set MTK_SCPD_KEEP_DEFAULT_OFF at the same time */
#define MTK_SCPD_ALWAYS_ON BIT(5)
#define MTK_SCPD_EXT_BUCK_ISO BIT(6)
+#define MTK_SCPD_HAS_INFRA_NAO BIT(7)
+#define MTK_SCPD_STRICT_BUS_PROTECTION BIT(8)
#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x))
#define SPM_VDE_PWR_CON 0x0210
@@ -42,37 +44,48 @@
#define SPM_MAX_BUS_PROT_DATA 6
-#define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) { \
- .bus_prot_mask = (_mask), \
+enum scpsys_bus_prot_flags {
+ BUS_PROT_REG_UPDATE = BIT(1),
+ BUS_PROT_IGNORE_CLR_ACK = BIT(2),
+ BUS_PROT_INVERTED = BIT(3),
+ BUS_PROT_COMPONENT_INFRA = BIT(4),
+ BUS_PROT_COMPONENT_SMI = BIT(5),
+ BUS_PROT_STA_COMPONENT_INFRA_NAO = BIT(6),
+};
+
+#define _BUS_PROT(_set_clr_mask, _set, _clr, _sta_mask, _sta, _flags) { \
+ .bus_prot_set_clr_mask = (_set_clr_mask), \
.bus_prot_set = _set, \
.bus_prot_clr = _clr, \
+ .bus_prot_sta_mask = (_sta_mask), \
.bus_prot_sta = _sta, \
- .bus_prot_reg_update = _update, \
- .ignore_clr_ack = _ignore, \
+ .flags = _flags \
}
-#define BUS_PROT_WR(_mask, _set, _clr, _sta) \
- _BUS_PROT(_mask, _set, _clr, _sta, false, false)
+#define BUS_PROT_WR(_hwip, _mask, _set, _clr, _sta) \
+ _BUS_PROT(_mask, _set, _clr, _mask, _sta, BUS_PROT_COMPONENT_##_hwip)
-#define BUS_PROT_WR_IGN(_mask, _set, _clr, _sta) \
- _BUS_PROT(_mask, _set, _clr, _sta, false, true)
+#define BUS_PROT_WR_IGN(_hwip, _mask, _set, _clr, _sta) \
+ _BUS_PROT(_mask, _set, _clr, _mask, _sta, \
+ BUS_PROT_COMPONENT_##_hwip | BUS_PROT_IGNORE_CLR_ACK)
-#define BUS_PROT_UPDATE(_mask, _set, _clr, _sta) \
- _BUS_PROT(_mask, _set, _clr, _sta, true, false)
+#define BUS_PROT_UPDATE(_hwip, _mask, _set, _clr, _sta) \
+ _BUS_PROT(_mask, _set, _clr, _mask, _sta, \
+ BUS_PROT_COMPONENT_##_hwip | BUS_PROT_REG_UPDATE)
-#define BUS_PROT_UPDATE_TOPAXI(_mask) \
- BUS_PROT_UPDATE(_mask, \
+#define BUS_PROT_INFRA_UPDATE_TOPAXI(_mask) \
+ BUS_PROT_UPDATE(INFRA, _mask, \
INFRA_TOPAXI_PROTECTEN, \
INFRA_TOPAXI_PROTECTEN, \
INFRA_TOPAXI_PROTECTSTA1)
struct scpsys_bus_prot_data {
- u32 bus_prot_mask;
+ u32 bus_prot_set_clr_mask;
u32 bus_prot_set;
u32 bus_prot_clr;
+ u32 bus_prot_sta_mask;
u32 bus_prot_sta;
- bool bus_prot_reg_update;
- bool ignore_clr_ack;
+ u8 flags;
};
/**
@@ -85,8 +98,7 @@ struct scpsys_bus_prot_data {
* @ext_buck_iso_offs: The offset for external buck isolation
* @ext_buck_iso_mask: The mask for external buck isolation
* @caps: The flag for active wake-up action.
- * @bp_infracfg: bus protection for infracfg subsystem
- * @bp_smi: bus protection for smi subsystem
+ * @bp_cfg: bus protection configuration for any subsystem
*/
struct scpsys_domain_data {
const char *name;
@@ -96,9 +108,8 @@ struct scpsys_domain_data {
u32 sram_pdn_ack_bits;
int ext_buck_iso_offs;
u32 ext_buck_iso_mask;
- u8 caps;
- const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA];
- const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA];
+ u16 caps;
+ const struct scpsys_bus_prot_data bp_cfg[SPM_MAX_BUS_PROT_DATA];
int pwr_sta_offs;
int pwr_sta2nd_offs;
};
diff --git a/drivers/pmdomain/qcom/Kconfig b/drivers/pmdomain/qcom/Kconfig
new file mode 100644
index 000000000000..3d3948eabef0
--- /dev/null
+++ b/drivers/pmdomain/qcom/Kconfig
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "Qualcomm PM Domains"
+
+config QCOM_CPR
+ tristate "QCOM Core Power Reduction (CPR) support"
+ depends on ARCH_QCOM && HAS_IOMEM
+ select PM_OPP
+ select REGMAP
+ help
+ Say Y here to enable support for the CPR hardware found on Qualcomm
+ SoCs like QCS404.
+
+ This driver populates CPU OPPs tables and makes adjustments to the
+ tables based on feedback from the CPR hardware. If you want to do
+ CPUfrequency scaling say Y here.
+
+ To compile this driver as a module, choose M here: the module will
+ be called qcom-cpr
+
+config QCOM_RPMHPD
+ tristate "Qualcomm RPMh Power domain driver"
+ depends on QCOM_RPMH && QCOM_COMMAND_DB
+ help
+ QCOM RPMh Power domain driver to support power-domains with
+ performance states. The driver communicates a performance state
+ value to RPMh which then translates it into corresponding voltage
+ for the voltage rail.
+
+config QCOM_RPMPD
+ tristate "Qualcomm RPM Power domain driver"
+ depends on PM && OF
+ depends on QCOM_SMD_RPM
+ select PM_GENERIC_DOMAINS
+ select PM_GENERIC_DOMAINS_OF
+ help
+ QCOM RPM Power domain driver to support power-domains with
+ performance states. The driver communicates a performance state
+ value to RPM which then translates it into corresponding voltage
+ for the voltage rail.
+
+endmenu
diff --git a/drivers/pmdomain/qcom/cpr.c b/drivers/pmdomain/qcom/cpr.c
index 94a3f0977212..e9dd42bded6f 100644
--- a/drivers/pmdomain/qcom/cpr.c
+++ b/drivers/pmdomain/qcom/cpr.c
@@ -1424,12 +1424,6 @@ static const struct cpr_acc_desc qcs404_cpr_acc_desc = {
.acc_desc = &qcs404_acc_desc,
};
-static unsigned int cpr_get_performance_state(struct generic_pm_domain *genpd,
- struct dev_pm_opp *opp)
-{
- return dev_pm_opp_get_level(opp);
-}
-
static int cpr_power_off(struct generic_pm_domain *domain)
{
struct cpr_drv *drv = container_of(domain, struct cpr_drv, pd);
@@ -1698,7 +1692,6 @@ static int cpr_probe(struct platform_device *pdev)
drv->pd.power_off = cpr_power_off;
drv->pd.power_on = cpr_power_on;
drv->pd.set_performance_state = cpr_set_performance_state;
- drv->pd.opp_to_performance_state = cpr_get_performance_state;
drv->pd.attach_dev = cpr_pd_attach_dev;
ret = pm_genpd_init(&drv->pd, NULL, true);
diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c
index a87e336d5e33..f2e64324deb8 100644
--- a/drivers/pmdomain/qcom/rpmhpd.c
+++ b/drivers/pmdomain/qcom/rpmhpd.c
@@ -197,11 +197,21 @@ static struct rpmhpd nsp1 = {
.res_name = "nsp1.lvl",
};
+static struct rpmhpd nsp2 = {
+ .pd = { .name = "nsp2", },
+ .res_name = "nsp2.lvl",
+};
+
static struct rpmhpd qphy = {
.pd = { .name = "qphy", },
.res_name = "qphy.lvl",
};
+static struct rpmhpd gmxc = {
+ .pd = { .name = "gmxc", },
+ .res_name = "gmxc.lvl",
+};
+
/* SA8540P RPMH powerdomains */
static struct rpmhpd *sa8540p_rpmhpds[] = {
[SC8280XP_CX] = &cx,
@@ -337,6 +347,23 @@ static const struct rpmhpd_desc sm6350_desc = {
.num_pds = ARRAY_SIZE(sm6350_rpmhpds),
};
+/* SM7150 RPMH powerdomains */
+static struct rpmhpd *sm7150_rpmhpds[] = {
+ [RPMHPD_CX] = &cx_w_mx_parent,
+ [RPMHPD_CX_AO] = &cx_ao_w_mx_parent,
+ [RPMHPD_GFX] = &gfx,
+ [RPMHPD_LCX] = &lcx,
+ [RPMHPD_LMX] = &lmx,
+ [RPMHPD_MX] = &mx,
+ [RPMHPD_MX_AO] = &mx_ao,
+ [RPMHPD_MSS] = &mss,
+};
+
+static const struct rpmhpd_desc sm7150_desc = {
+ .rpmhpds = sm7150_rpmhpds,
+ .num_pds = ARRAY_SIZE(sm7150_rpmhpds),
+};
+
/* SM8150 RPMH powerdomains */
static struct rpmhpd *sm8150_rpmhpds[] = {
[SM8150_CX] = &cx_w_mx_parent,
@@ -458,6 +485,30 @@ static const struct rpmhpd_desc sm8550_desc = {
.num_pds = ARRAY_SIZE(sm8550_rpmhpds),
};
+/* SM8650 RPMH powerdomains */
+static struct rpmhpd *sm8650_rpmhpds[] = {
+ [RPMHPD_CX] = &cx,
+ [RPMHPD_CX_AO] = &cx_ao,
+ [RPMHPD_EBI] = &ebi,
+ [RPMHPD_GFX] = &gfx,
+ [RPMHPD_LCX] = &lcx,
+ [RPMHPD_LMX] = &lmx,
+ [RPMHPD_MMCX] = &mmcx_w_cx_parent,
+ [RPMHPD_MMCX_AO] = &mmcx_ao_w_cx_parent,
+ [RPMHPD_MSS] = &mss,
+ [RPMHPD_MX] = &mx,
+ [RPMHPD_MX_AO] = &mx_ao,
+ [RPMHPD_MXC] = &mxc,
+ [RPMHPD_MXC_AO] = &mxc_ao,
+ [RPMHPD_NSP] = &nsp,
+ [RPMHPD_NSP2] = &nsp2,
+};
+
+static const struct rpmhpd_desc sm8650_desc = {
+ .rpmhpds = sm8650_rpmhpds,
+ .num_pds = ARRAY_SIZE(sm8650_rpmhpds),
+};
+
/* QDU1000/QRU1000 RPMH powerdomains */
static struct rpmhpd *qdu1000_rpmhpds[] = {
[QDU1000_CX] = &cx,
@@ -547,6 +598,28 @@ static const struct rpmhpd_desc sc8280xp_desc = {
.num_pds = ARRAY_SIZE(sc8280xp_rpmhpds),
};
+/* SC8380xp RPMH powerdomains */
+static struct rpmhpd *sc8380xp_rpmhpds[] = {
+ [RPMHPD_CX] = &cx,
+ [RPMHPD_CX_AO] = &cx_ao,
+ [RPMHPD_EBI] = &ebi,
+ [RPMHPD_GFX] = &gfx,
+ [RPMHPD_LCX] = &lcx,
+ [RPMHPD_LMX] = &lmx,
+ [RPMHPD_MMCX] = &mmcx,
+ [RPMHPD_MMCX_AO] = &mmcx_ao,
+ [RPMHPD_MX] = &mx,
+ [RPMHPD_MX_AO] = &mx_ao,
+ [RPMHPD_NSP] = &nsp,
+ [RPMHPD_MXC] = &mxc,
+ [RPMHPD_GMXC] = &gmxc,
+};
+
+static const struct rpmhpd_desc sc8380xp_desc = {
+ .rpmhpds = sc8380xp_rpmhpds,
+ .num_pds = ARRAY_SIZE(sc8380xp_rpmhpds),
+};
+
static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,qdu1000-rpmhpd", .data = &qdu1000_desc },
{ .compatible = "qcom,sa8155p-rpmhpd", .data = &sa8155p_desc },
@@ -556,17 +629,20 @@ static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,sc7280-rpmhpd", .data = &sc7280_desc },
{ .compatible = "qcom,sc8180x-rpmhpd", .data = &sc8180x_desc },
{ .compatible = "qcom,sc8280xp-rpmhpd", .data = &sc8280xp_desc },
+ { .compatible = "qcom,sc8380xp-rpmhpd", .data = &sc8380xp_desc },
{ .compatible = "qcom,sdm670-rpmhpd", .data = &sdm670_desc },
{ .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc },
{ .compatible = "qcom,sdx55-rpmhpd", .data = &sdx55_desc},
{ .compatible = "qcom,sdx65-rpmhpd", .data = &sdx65_desc},
{ .compatible = "qcom,sdx75-rpmhpd", .data = &sdx75_desc},
{ .compatible = "qcom,sm6350-rpmhpd", .data = &sm6350_desc },
+ { .compatible = "qcom,sm7150-rpmhpd", .data = &sm7150_desc },
{ .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc },
{ .compatible = "qcom,sm8250-rpmhpd", .data = &sm8250_desc },
{ .compatible = "qcom,sm8350-rpmhpd", .data = &sm8350_desc },
{ .compatible = "qcom,sm8450-rpmhpd", .data = &sm8450_desc },
{ .compatible = "qcom,sm8550-rpmhpd", .data = &sm8550_desc },
+ { .compatible = "qcom,sm8650-rpmhpd", .data = &sm8650_desc },
{ }
};
MODULE_DEVICE_TABLE(of, rpmhpd_match_table);
@@ -725,12 +801,6 @@ out:
return ret;
}
-static unsigned int rpmhpd_get_performance_state(struct generic_pm_domain *genpd,
- struct dev_pm_opp *opp)
-{
- return dev_pm_opp_get_level(opp);
-}
-
static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
{
int i;
@@ -820,7 +890,6 @@ static int rpmhpd_probe(struct platform_device *pdev)
rpmhpds[i]->pd.power_off = rpmhpd_power_off;
rpmhpds[i]->pd.power_on = rpmhpd_power_on;
rpmhpds[i]->pd.set_performance_state = rpmhpd_set_performance_state;
- rpmhpds[i]->pd.opp_to_performance_state = rpmhpd_get_performance_state;
pm_genpd_init(&rpmhpds[i]->pd, NULL, true);
data->domains[i] = &rpmhpds[i]->pd;
diff --git a/drivers/pmdomain/qcom/rpmpd.c b/drivers/pmdomain/qcom/rpmpd.c
index 3135dd1dafe0..07590a3ef19c 100644
--- a/drivers/pmdomain/qcom/rpmpd.c
+++ b/drivers/pmdomain/qcom/rpmpd.c
@@ -105,6 +105,24 @@ static struct rpmpd cx_s1a_corner_ao = {
.key = KEY_CORNER,
};
+static struct rpmpd cx_s1a_lvl_ao;
+static struct rpmpd cx_s1a_lvl = {
+ .pd = { .name = "cx", },
+ .peer = &cx_s1a_lvl_ao,
+ .res_type = RPMPD_SMPA,
+ .res_id = 1,
+ .key = KEY_LEVEL,
+};
+
+static struct rpmpd cx_s1a_lvl_ao = {
+ .pd = { .name = "cx_ao", },
+ .peer = &cx_s1a_lvl,
+ .active_only = true,
+ .res_type = RPMPD_SMPA,
+ .res_id = 1,
+ .key = KEY_LEVEL,
+};
+
static struct rpmpd cx_s2a_corner_ao;
static struct rpmpd cx_s2a_corner = {
.pd = { .name = "cx", },
@@ -180,6 +198,13 @@ static struct rpmpd cx_s1a_vfc = {
.key = KEY_FLOOR_CORNER,
};
+static struct rpmpd cx_s1a_vfl = {
+ .pd = { .name = "cx_vfl", },
+ .res_type = RPMPD_SMPA,
+ .res_id = 1,
+ .key = KEY_FLOOR_LEVEL,
+};
+
static struct rpmpd cx_s2a_vfc = {
.pd = { .name = "cx_vfc", },
.res_type = RPMPD_SMPA,
@@ -239,6 +264,24 @@ static struct rpmpd gx_rwgx0_lvl_ao = {
};
/* MX */
+static struct rpmpd mx_l2a_lvl_ao;
+static struct rpmpd mx_l2a_lvl = {
+ .pd = { .name = "mx", },
+ .peer = &mx_l2a_lvl_ao,
+ .res_type = RPMPD_LDOA,
+ .res_id = 2,
+ .key = KEY_LEVEL,
+};
+
+static struct rpmpd mx_l2a_lvl_ao = {
+ .pd = { .name = "mx_ao", },
+ .peer = &mx_l2a_lvl,
+ .active_only = true,
+ .res_type = RPMPD_LDOA,
+ .res_id = 2,
+ .key = KEY_LEVEL,
+};
+
static struct rpmpd mx_l3a_corner_ao;
static struct rpmpd mx_l3a_corner = {
.pd = { .name = "mx", },
@@ -257,6 +300,24 @@ static struct rpmpd mx_l3a_corner_ao = {
.key = KEY_CORNER,
};
+static struct rpmpd mx_l3a_lvl_ao;
+static struct rpmpd mx_l3a_lvl = {
+ .pd = { .name = "mx", },
+ .peer = &mx_l3a_lvl_ao,
+ .res_type = RPMPD_LDOA,
+ .res_id = 3,
+ .key = KEY_LEVEL,
+};
+
+static struct rpmpd mx_l3a_lvl_ao = {
+ .pd = { .name = "mx_ao", },
+ .peer = &mx_l3a_lvl,
+ .active_only = true,
+ .res_type = RPMPD_LDOA,
+ .res_id = 3,
+ .key = KEY_LEVEL,
+};
+
static struct rpmpd mx_l12a_lvl_ao;
static struct rpmpd mx_l12a_lvl = {
.pd = { .name = "mx", },
@@ -572,6 +633,20 @@ static const struct rpmpd_desc msm8916_desc = {
.max_state = MAX_CORNER_RPMPD_STATE,
};
+static struct rpmpd *msm8917_rpmpds[] = {
+ [MSM8917_VDDCX] = &cx_s2a_lvl,
+ [MSM8917_VDDCX_AO] = &cx_s2a_lvl_ao,
+ [MSM8917_VDDCX_VFL] = &cx_s2a_vfl,
+ [MSM8917_VDDMX] = &mx_l3a_lvl,
+ [MSM8917_VDDMX_AO] = &mx_l3a_lvl_ao,
+};
+
+static const struct rpmpd_desc msm8917_desc = {
+ .rpmpds = msm8917_rpmpds,
+ .num_pds = ARRAY_SIZE(msm8917_rpmpds),
+ .max_state = RPM_SMD_LEVEL_TURBO,
+};
+
static struct rpmpd *msm8953_rpmpds[] = {
[MSM8953_VDDMD] = &md_s1a_lvl,
[MSM8953_VDDMD_AO] = &md_s1a_lvl_ao,
@@ -672,6 +747,20 @@ static const struct rpmpd_desc qcs404_desc = {
.max_state = RPM_SMD_LEVEL_BINNING,
};
+static struct rpmpd *qm215_rpmpds[] = {
+ [QM215_VDDCX] = &cx_s1a_lvl,
+ [QM215_VDDCX_AO] = &cx_s1a_lvl_ao,
+ [QM215_VDDCX_VFL] = &cx_s1a_vfl,
+ [QM215_VDDMX] = &mx_l2a_lvl,
+ [QM215_VDDMX_AO] = &mx_l2a_lvl_ao,
+};
+
+static const struct rpmpd_desc qm215_desc = {
+ .rpmpds = qm215_rpmpds,
+ .num_pds = ARRAY_SIZE(qm215_rpmpds),
+ .max_state = RPM_SMD_LEVEL_TURBO,
+};
+
static struct rpmpd *sdm660_rpmpds[] = {
[SDM660_VDDCX] = &cx_rwcx0_lvl,
[SDM660_VDDCX_AO] = &cx_rwcx0_lvl_ao,
@@ -764,6 +853,7 @@ static const struct of_device_id rpmpd_match_table[] = {
{ .compatible = "qcom,msm8226-rpmpd", .data = &msm8226_desc },
{ .compatible = "qcom,msm8909-rpmpd", .data = &msm8916_desc },
{ .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc },
+ { .compatible = "qcom,msm8917-rpmpd", .data = &msm8917_desc },
{ .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc },
{ .compatible = "qcom,msm8953-rpmpd", .data = &msm8953_desc },
{ .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc },
@@ -772,6 +862,7 @@ static const struct of_device_id rpmpd_match_table[] = {
{ .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc },
{ .compatible = "qcom,qcm2290-rpmpd", .data = &qcm2290_desc },
{ .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc },
+ { .compatible = "qcom,qm215-rpmpd", .data = &qm215_desc },
{ .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc },
{ .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc },
{ .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc },
@@ -908,12 +999,6 @@ out:
return ret;
}
-static unsigned int rpmpd_get_performance(struct generic_pm_domain *genpd,
- struct dev_pm_opp *opp)
-{
- return dev_pm_opp_get_level(opp);
-}
-
static int rpmpd_probe(struct platform_device *pdev)
{
int i;
@@ -959,7 +1044,6 @@ static int rpmpd_probe(struct platform_device *pdev)
rpmpds[i]->pd.power_off = rpmpd_power_off;
rpmpds[i]->pd.power_on = rpmpd_power_on;
rpmpds[i]->pd.set_performance_state = rpmpd_set_performance;
- rpmpds[i]->pd.opp_to_performance_state = rpmpd_get_performance;
pm_genpd_init(&rpmpds[i]->pd, NULL, true);
data->domains[i] = &rpmpds[i]->pd;
diff --git a/drivers/pmdomain/renesas/Kconfig b/drivers/pmdomain/renesas/Kconfig
new file mode 100644
index 000000000000..80bf2cf8b60e
--- /dev/null
+++ b/drivers/pmdomain/renesas/Kconfig
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: GPL-2.0
+if SOC_RENESAS
+
+config SYSC_RCAR
+ bool "System Controller support for R-Car" if COMPILE_TEST
+
+config SYSC_RCAR_GEN4
+ bool "System Controller support for R-Car Gen4" if COMPILE_TEST
+
+config SYSC_R8A77995
+ bool "System Controller support for R-Car D3" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A7794
+ bool "System Controller support for R-Car E2" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A77990
+ bool "System Controller support for R-Car E3" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A7779
+ bool "System Controller support for R-Car H1" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A7790
+ bool "System Controller support for R-Car H2" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A7795
+ bool "System Controller support for R-Car H3" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A7791
+ bool "System Controller support for R-Car M2-W/N" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A77965
+ bool "System Controller support for R-Car M3-N" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A77960
+ bool "System Controller support for R-Car M3-W" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A77961
+ bool "System Controller support for R-Car M3-W+" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A779F0
+ bool "System Controller support for R-Car S4-8" if COMPILE_TEST
+ select SYSC_RCAR_GEN4
+
+config SYSC_R8A7792
+ bool "System Controller support for R-Car V2H" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A77980
+ bool "System Controller support for R-Car V3H" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A77970
+ bool "System Controller support for R-Car V3M" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A779A0
+ bool "System Controller support for R-Car V3U" if COMPILE_TEST
+ select SYSC_RCAR_GEN4
+
+config SYSC_R8A779G0
+ bool "System Controller support for R-Car V4H" if COMPILE_TEST
+ select SYSC_RCAR_GEN4
+
+config SYSC_RMOBILE
+ bool "System Controller support for R-Mobile" if COMPILE_TEST
+
+config SYSC_R8A77470
+ bool "System Controller support for RZ/G1C" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A7745
+ bool "System Controller support for RZ/G1E" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A7742
+ bool "System Controller support for RZ/G1H" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A7743
+ bool "System Controller support for RZ/G1M" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A774C0
+ bool "System Controller support for RZ/G2E" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A774E1
+ bool "System Controller support for RZ/G2H" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A774A1
+ bool "System Controller support for RZ/G2M" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A774B1
+ bool "System Controller support for RZ/G2N" if COMPILE_TEST
+ select SYSC_RCAR
+
+endif
diff --git a/drivers/pmdomain/renesas/rmobile-sysc.c b/drivers/pmdomain/renesas/rmobile-sysc.c
index 912daadaa10d..0b77f37787d5 100644
--- a/drivers/pmdomain/renesas/rmobile-sysc.c
+++ b/drivers/pmdomain/renesas/rmobile-sysc.c
@@ -190,7 +190,7 @@ static void __init get_special_pds(void)
/* PM domains containing other special devices */
for_each_matching_node_and_match(np, special_ids, &id)
- add_special_pd(np, (enum pd_types)id->data);
+ add_special_pd(np, (uintptr_t)id->data);
}
static void __init put_special_pds(void)
diff --git a/drivers/pmdomain/rockchip/Kconfig b/drivers/pmdomain/rockchip/Kconfig
new file mode 100644
index 000000000000..b0d70f1a8439
--- /dev/null
+++ b/drivers/pmdomain/rockchip/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+if ARCH_ROCKCHIP || COMPILE_TEST
+
+config ROCKCHIP_PM_DOMAINS
+ bool "Rockchip generic power domain"
+ depends on PM
+ select PM_GENERIC_DOMAINS
+ help
+ Say y here to enable power domain support.
+ In order to meet high performance and low power requirements, a power
+ management unit is designed or saving power when RK3288 in low power
+ mode. The RK3288 PMU is dedicated for managing the power of the whole chip.
+
+ If unsure, say N.
+
+endif
diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
index d5d3ecb38283..9b76b62869d0 100644
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -9,11 +9,13 @@
#include <linux/iopoll.h>
#include <linux/err.h>
#include <linux/mutex.h>
+#include <linux/platform_device.h>
#include <linux/pm_clock.h>
#include <linux/pm_domain.h>
+#include <linux/property.h>
+#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_clk.h>
-#include <linux/of_platform.h>
#include <linux/clk.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
@@ -857,7 +859,6 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
struct device_node *node;
struct device *parent;
struct rockchip_pmu *pmu;
- const struct of_device_id *match;
const struct rockchip_pmu_info *pmu_info;
int error;
@@ -866,13 +867,7 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
return -ENODEV;
}
- match = of_match_device(dev->driver->of_match_table, dev);
- if (!match || !match->data) {
- dev_err(dev, "missing pmu data\n");
- return -EINVAL;
- }
-
- pmu_info = match->data;
+ pmu_info = device_get_match_data(dev);
pmu = devm_kzalloc(dev,
struct_size(pmu, domains, pmu_info->num_domains),
diff --git a/drivers/pmdomain/samsung/Kconfig b/drivers/pmdomain/samsung/Kconfig
new file mode 100644
index 000000000000..0debfe36b00a
--- /dev/null
+++ b/drivers/pmdomain/samsung/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+if SOC_SAMSUNG
+
+config EXYNOS_PM_DOMAINS
+ bool "Exynos PM domains" if COMPILE_TEST
+ depends on (ARCH_EXYNOS && PM_GENERIC_DOMAINS) || COMPILE_TEST
+
+endif
diff --git a/drivers/pmdomain/st/Kconfig b/drivers/pmdomain/st/Kconfig
new file mode 100644
index 000000000000..a77a70211f61
--- /dev/null
+++ b/drivers/pmdomain/st/Kconfig
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config UX500_PM_DOMAIN
+ bool "ST-Ericsson ux500 Power Domain"
+ depends on ARCH_U8500 || COMPILE_TEST
+ default ARCH_U8500
diff --git a/drivers/pmdomain/st/Makefile b/drivers/pmdomain/st/Makefile
index 8fa5f9855460..6d8b617eb834 100644
--- a/drivers/pmdomain/st/Makefile
+++ b/drivers/pmdomain/st/Makefile
@@ -1,2 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_ARCH_U8500) += ste-ux500-pm-domain.o
+obj-$(CONFIG_UX500_PM_DOMAIN) += ste-ux500-pm-domain.o
diff --git a/drivers/soc/starfive/Kconfig b/drivers/pmdomain/starfive/Kconfig
index bdb96dc4c989..1e9b0c414fec 100644
--- a/drivers/soc/starfive/Kconfig
+++ b/drivers/pmdomain/starfive/Kconfig
@@ -3,8 +3,8 @@
config JH71XX_PMU
bool "Support PMU for StarFive JH71XX Soc"
depends on PM
- depends on SOC_STARFIVE || COMPILE_TEST
- default SOC_STARFIVE
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ default ARCH_STARFIVE
select PM_GENERIC_DOMAINS
help
Say 'y' here to enable support power domain support.
diff --git a/drivers/pmdomain/starfive/jh71xx-pmu.c b/drivers/pmdomain/starfive/jh71xx-pmu.c
index 7d5f50d71c0d..74720c09a6e3 100644
--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
+++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
@@ -2,7 +2,7 @@
/*
* StarFive JH71XX PMU (Power Management Unit) Controller Driver
*
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
*/
#include <linux/interrupt.h>
@@ -10,7 +10,6 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <dt-bindings/power/starfive,jh7110-pmu.h>
@@ -24,6 +23,9 @@
#define JH71XX_PMU_EVENT_STATUS 0x88
#define JH71XX_PMU_INT_STATUS 0x8C
+/* aon pmu register offset */
+#define JH71XX_AON_PMU_SWITCH 0x00
+
/* sw encourage cfg */
#define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
#define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
@@ -51,9 +53,17 @@ struct jh71xx_domain_info {
u8 bit;
};
+struct jh71xx_pmu;
+struct jh71xx_pmu_dev;
+
struct jh71xx_pmu_match_data {
const struct jh71xx_domain_info *domain_info;
int num_domains;
+ unsigned int pmu_status;
+ int (*pmu_parse_irq)(struct platform_device *pdev,
+ struct jh71xx_pmu *pmu);
+ int (*pmu_set_state)(struct jh71xx_pmu_dev *pmd,
+ u32 mask, bool on);
};
struct jh71xx_pmu {
@@ -79,12 +89,12 @@ static int jh71xx_pmu_get_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool *is_o
if (!mask)
return -EINVAL;
- *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
+ *is_on = readl(pmu->base + pmu->match_data->pmu_status) & mask;
return 0;
}
-static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
+static int jh7110_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
{
struct jh71xx_pmu *pmu = pmd->pmu;
unsigned long flags;
@@ -92,22 +102,8 @@ static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
u32 mode;
u32 encourage_lo;
u32 encourage_hi;
- bool is_on;
int ret;
- ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
- if (ret) {
- dev_dbg(pmu->dev, "unable to get current state for %s\n",
- pmd->genpd.name);
- return ret;
- }
-
- if (is_on == on) {
- dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
- pmd->genpd.name, on ? "en" : "dis");
- return 0;
- }
-
spin_lock_irqsave(&pmu->lock, flags);
/*
@@ -166,6 +162,49 @@ static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
return 0;
}
+static int jh7110_aon_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
+{
+ struct jh71xx_pmu *pmu = pmd->pmu;
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&pmu->lock, flags);
+ val = readl(pmu->base + JH71XX_AON_PMU_SWITCH);
+
+ if (on)
+ val |= mask;
+ else
+ val &= ~mask;
+
+ writel(val, pmu->base + JH71XX_AON_PMU_SWITCH);
+ spin_unlock_irqrestore(&pmu->lock, flags);
+
+ return 0;
+}
+
+static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
+{
+ struct jh71xx_pmu *pmu = pmd->pmu;
+ const struct jh71xx_pmu_match_data *match_data = pmu->match_data;
+ bool is_on;
+ int ret;
+
+ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
+ if (ret) {
+ dev_dbg(pmu->dev, "unable to get current state for %s\n",
+ pmd->genpd.name);
+ return ret;
+ }
+
+ if (is_on == on) {
+ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
+ pmd->genpd.name, on ? "en" : "dis");
+ return 0;
+ }
+
+ return match_data->pmu_set_state(pmd, mask, on);
+}
+
static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
{
struct jh71xx_pmu_dev *pmd = container_of(genpd,
@@ -226,6 +265,25 @@ static irqreturn_t jh71xx_pmu_interrupt(int irq, void *data)
return IRQ_HANDLED;
}
+static int jh7110_pmu_parse_irq(struct platform_device *pdev, struct jh71xx_pmu *pmu)
+{
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ pmu->irq = platform_get_irq(pdev, 0);
+ if (pmu->irq < 0)
+ return pmu->irq;
+
+ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
+ 0, pdev->name, pmu);
+ if (ret)
+ dev_err(dev, "failed to request irq\n");
+
+ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
+
+ return 0;
+}
+
static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
{
struct jh71xx_pmu_dev *pmd;
@@ -275,19 +333,20 @@ static int jh71xx_pmu_probe(struct platform_device *pdev)
if (IS_ERR(pmu->base))
return PTR_ERR(pmu->base);
- pmu->irq = platform_get_irq(pdev, 0);
- if (pmu->irq < 0)
- return pmu->irq;
-
- ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
- 0, pdev->name, pmu);
- if (ret)
- dev_err(dev, "failed to request irq\n");
+ spin_lock_init(&pmu->lock);
match_data = of_device_get_match_data(dev);
if (!match_data)
return -EINVAL;
+ if (match_data->pmu_parse_irq) {
+ ret = match_data->pmu_parse_irq(pdev, pmu);
+ if (ret) {
+ dev_err(dev, "failed to parse irq\n");
+ return ret;
+ }
+ }
+
pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
sizeof(struct generic_pm_domain *),
GFP_KERNEL);
@@ -307,9 +366,6 @@ static int jh71xx_pmu_probe(struct platform_device *pdev)
}
}
- spin_lock_init(&pmu->lock);
- jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
-
ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
if (ret) {
dev_err(dev, "failed to register genpd driver: %d\n", ret);
@@ -357,6 +413,27 @@ static const struct jh71xx_domain_info jh7110_power_domains[] = {
static const struct jh71xx_pmu_match_data jh7110_pmu = {
.num_domains = ARRAY_SIZE(jh7110_power_domains),
.domain_info = jh7110_power_domains,
+ .pmu_status = JH71XX_PMU_CURR_POWER_MODE,
+ .pmu_parse_irq = jh7110_pmu_parse_irq,
+ .pmu_set_state = jh7110_pmu_set_state,
+};
+
+static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
+ [JH7110_AON_PD_DPHY_TX] = {
+ .name = "DPHY-TX",
+ .bit = 30,
+ },
+ [JH7110_AON_PD_DPHY_RX] = {
+ .name = "DPHY-RX",
+ .bit = 31,
+ },
+};
+
+static const struct jh71xx_pmu_match_data jh7110_aon_pmu = {
+ .num_domains = ARRAY_SIZE(jh7110_aon_power_domains),
+ .domain_info = jh7110_aon_power_domains,
+ .pmu_status = JH71XX_AON_PMU_SWITCH,
+ .pmu_set_state = jh7110_aon_pmu_set_state,
};
static const struct of_device_id jh71xx_pmu_of_match[] = {
@@ -364,6 +441,9 @@ static const struct of_device_id jh71xx_pmu_of_match[] = {
.compatible = "starfive,jh7110-pmu",
.data = (void *)&jh7110_pmu,
}, {
+ .compatible = "starfive,jh7110-aon-syscon",
+ .data = (void *)&jh7110_aon_pmu,
+ }, {
/* sentinel */
}
};
@@ -379,5 +459,6 @@ static struct platform_driver jh71xx_pmu_driver = {
builtin_platform_driver(jh71xx_pmu_driver);
MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/pmdomain/sunxi/Kconfig b/drivers/pmdomain/sunxi/Kconfig
new file mode 100644
index 000000000000..17781bf8d86d
--- /dev/null
+++ b/drivers/pmdomain/sunxi/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config SUN20I_PPU
+ bool "Allwinner D1 PPU power domain driver"
+ depends on ARCH_SUNXI || COMPILE_TEST
+ depends on PM
+ select PM_GENERIC_DOMAINS
+ help
+ Say y to enable the PPU power domain driver. This saves power
+ when certain peripherals, such as the video engine, are idle.
diff --git a/drivers/pmdomain/tegra/Kconfig b/drivers/pmdomain/tegra/Kconfig
new file mode 100644
index 000000000000..13ade6d84696
--- /dev/null
+++ b/drivers/pmdomain/tegra/Kconfig
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config SOC_TEGRA_POWERGATE_BPMP
+ def_bool y
+ depends on PM_GENERIC_DOMAINS
+ depends on TEGRA_BPMP
diff --git a/drivers/pmdomain/ti/Kconfig b/drivers/pmdomain/ti/Kconfig
new file mode 100644
index 000000000000..67c608bf7ed0
--- /dev/null
+++ b/drivers/pmdomain/ti/Kconfig
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config OMAP2PLUS_PRM
+ bool
+ depends on ARCH_OMAP2PLUS
+ default ARCH_OMAP2PLUS
+
+if SOC_TI
+
+config TI_SCI_PM_DOMAINS
+ tristate "TI SCI PM Domains Driver"
+ depends on TI_SCI_PROTOCOL
+ depends on PM_GENERIC_DOMAINS
+ help
+ Generic power domain implementation for TI device implementing
+ the TI SCI protocol.
+
+ To compile this as a module, choose M here. The module will be
+ called ti_sci_pm_domains. Note this is needed early in boot before
+ rootfs may be available.
+
+endif
diff --git a/drivers/pmdomain/ti/Makefile b/drivers/pmdomain/ti/Makefile
index 69580afbb436..af6cd056c158 100644
--- a/drivers/pmdomain/ti/Makefile
+++ b/drivers/pmdomain/ti/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_ARCH_OMAP2PLUS) += omap_prm.o
+obj-$(CONFIG_OMAP2PLUS_PRM) += omap_prm.o
obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o
diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
index 34645104fe45..c091d569ecd5 100644
--- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
+++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
@@ -153,14 +153,18 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
max_id = args.args[0];
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
- if (!pd)
+ if (!pd) {
+ of_node_put(np);
return -ENOMEM;
+ }
pd->pd.name = devm_kasprintf(dev, GFP_KERNEL,
"pd:%d",
args.args[0]);
- if (!pd->pd.name)
+ if (!pd->pd.name) {
+ of_node_put(np);
return -ENOMEM;
+ }
pd->pd.power_off = ti_sci_pd_power_off;
pd->pd.power_on = ti_sci_pd_power_on;
diff --git a/drivers/pmdomain/xilinx/Kconfig b/drivers/pmdomain/xilinx/Kconfig
new file mode 100644
index 000000000000..5242753d848a
--- /dev/null
+++ b/drivers/pmdomain/xilinx/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config ZYNQMP_PM_DOMAINS
+ bool "Enable Zynq MPSoC generic PM domains"
+ default y
+ depends on PM && ZYNQMP_FIRMWARE
+ select PM_GENERIC_DOMAINS
+ help
+ Say yes to enable device power management through PM domains
+ If in doubt, say N.
diff --git a/drivers/scsi/scsi_sysctl.c b/drivers/scsi/scsi_sysctl.c
index 7f0914ea168f..093774d77534 100644
--- a/drivers/scsi/scsi_sysctl.c
+++ b/drivers/scsi/scsi_sysctl.c
@@ -18,7 +18,6 @@ static struct ctl_table scsi_table[] = {
.maxlen = sizeof(scsi_logging_level),
.mode = 0644,
.proc_handler = proc_dointvec },
- { }
};
static struct ctl_table_header *scsi_table_header;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 6effa13039f3..f4a49623ee3b 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -3928,7 +3928,7 @@ static int sd_suspend_runtime(struct device *dev)
static int sd_resume(struct device *dev, bool runtime)
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
- int ret = 0;
+ int ret;
if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
return 0;
@@ -3938,11 +3938,8 @@ static int sd_resume(struct device *dev, bool runtime)
return 0;
}
- if (!sdkp->device->no_start_on_resume) {
- sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
- ret = sd_start_stop_device(sdkp, 1);
- }
-
+ sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
+ ret = sd_start_stop_device(sdkp, 1);
if (!ret) {
opal_unlock_from_suspend(sdkp->opal_dev);
sdkp->suspended = false;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 0d8afffd1683..86210e4dd0d3 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1650,7 +1650,6 @@ static struct ctl_table sg_sysctls[] = {
.mode = 0444,
.proc_handler = proc_dointvec,
},
- {}
};
static struct ctl_table_header *hdr;
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index d21e75d69294..10a9ff84ff41 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
menu "SOC (System On Chip) specific Drivers"
-source "drivers/soc/actions/Kconfig"
source "drivers/soc/amlogic/Kconfig"
source "drivers/soc/apple/Kconfig"
source "drivers/soc/aspeed/Kconfig"
@@ -24,7 +23,6 @@ source "drivers/soc/renesas/Kconfig"
source "drivers/soc/rockchip/Kconfig"
source "drivers/soc/samsung/Kconfig"
source "drivers/soc/sifive/Kconfig"
-source "drivers/soc/starfive/Kconfig"
source "drivers/soc/sunxi/Kconfig"
source "drivers/soc/tegra/Kconfig"
source "drivers/soc/ti/Kconfig"
diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig
index 174a9b011461..d08e398bdad4 100644
--- a/drivers/soc/amlogic/Kconfig
+++ b/drivers/soc/amlogic/Kconfig
@@ -26,41 +26,6 @@ config MESON_GX_SOCINFO
Say yes to support decoding of Amlogic Meson GX SoC family
information about the type, package and version.
-config MESON_GX_PM_DOMAINS
- tristate "Amlogic Meson GX Power Domains driver"
- depends on ARCH_MESON || COMPILE_TEST
- depends on PM && OF
- default ARCH_MESON
- select PM_GENERIC_DOMAINS
- select PM_GENERIC_DOMAINS_OF
- help
- Say yes to expose Amlogic Meson GX Power Domains as
- Generic Power Domains.
-
-config MESON_EE_PM_DOMAINS
- tristate "Amlogic Meson Everything-Else Power Domains driver"
- depends on ARCH_MESON || COMPILE_TEST
- depends on PM && OF
- default ARCH_MESON
- select PM_GENERIC_DOMAINS
- select PM_GENERIC_DOMAINS_OF
- help
- Say yes to expose Amlogic Meson Everything-Else Power Domains as
- Generic Power Domains.
-
-config MESON_SECURE_PM_DOMAINS
- tristate "Amlogic Meson Secure Power Domains driver"
- depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM
- depends on PM && OF
- depends on HAVE_ARM_SMCCC
- default ARCH_MESON
- select PM_GENERIC_DOMAINS
- select PM_GENERIC_DOMAINS_OF
- help
- Support for the power controller on Amlogic A1/C1 series.
- Say yes to expose Amlogic Meson Secure Power Domains as Generic
- Power Domains.
-
config MESON_MX_SOCINFO
bool "Amlogic Meson MX SoC Information driver"
depends on (ARM && ARCH_MESON) || COMPILE_TEST
diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig
index a1596fefacff..eff486a77337 100644
--- a/drivers/soc/apple/Kconfig
+++ b/drivers/soc/apple/Kconfig
@@ -4,19 +4,6 @@ if ARCH_APPLE || COMPILE_TEST
menu "Apple SoC drivers"
-config APPLE_PMGR_PWRSTATE
- bool "Apple SoC PMGR power state control"
- depends on PM
- select REGMAP
- select MFD_SYSCON
- select PM_GENERIC_DOMAINS
- select RESET_CONTROLLER
- default ARCH_APPLE
- help
- The PMGR block in Apple SoCs provides high-level power state
- controls for SoC devices. This driver manages them through the
- generic power domain framework, and also provides reset support.
-
config APPLE_RTKIT
tristate "Apple RTKit co-processor IPC protocol"
depends on MAILBOX
diff --git a/drivers/soc/aspeed/aspeed-lpc-ctrl.c b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
index 258894ed234b..e87038009d1b 100644
--- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c
+++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c
@@ -332,14 +332,12 @@ err:
return rc;
}
-static int aspeed_lpc_ctrl_remove(struct platform_device *pdev)
+static void aspeed_lpc_ctrl_remove(struct platform_device *pdev)
{
struct aspeed_lpc_ctrl *lpc_ctrl = dev_get_drvdata(&pdev->dev);
misc_deregister(&lpc_ctrl->miscdev);
clk_disable_unprepare(lpc_ctrl->clk);
-
- return 0;
}
static const struct of_device_id aspeed_lpc_ctrl_match[] = {
@@ -355,7 +353,7 @@ static struct platform_driver aspeed_lpc_ctrl_driver = {
.of_match_table = aspeed_lpc_ctrl_match,
},
.probe = aspeed_lpc_ctrl_probe,
- .remove = aspeed_lpc_ctrl_remove,
+ .remove_new = aspeed_lpc_ctrl_remove,
};
module_platform_driver(aspeed_lpc_ctrl_driver);
diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c
index 773dbcbc03a6..888b5840c015 100644
--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c
+++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c
@@ -331,7 +331,7 @@ err:
return rc;
}
-static int aspeed_lpc_snoop_remove(struct platform_device *pdev)
+static void aspeed_lpc_snoop_remove(struct platform_device *pdev)
{
struct aspeed_lpc_snoop *lpc_snoop = dev_get_drvdata(&pdev->dev);
@@ -340,8 +340,6 @@ static int aspeed_lpc_snoop_remove(struct platform_device *pdev)
aspeed_lpc_disable_snoop(lpc_snoop, 1);
clk_disable_unprepare(lpc_snoop->clk);
-
- return 0;
}
static const struct aspeed_lpc_snoop_model_data ast2400_model_data = {
@@ -368,7 +366,7 @@ static struct platform_driver aspeed_lpc_snoop_driver = {
.of_match_table = aspeed_lpc_snoop_match,
},
.probe = aspeed_lpc_snoop_probe,
- .remove = aspeed_lpc_snoop_remove,
+ .remove_new = aspeed_lpc_snoop_remove,
};
module_platform_driver(aspeed_lpc_snoop_driver);
diff --git a/drivers/soc/aspeed/aspeed-p2a-ctrl.c b/drivers/soc/aspeed/aspeed-p2a-ctrl.c
index 548f44da28a9..8610ddacc7bc 100644
--- a/drivers/soc/aspeed/aspeed-p2a-ctrl.c
+++ b/drivers/soc/aspeed/aspeed-p2a-ctrl.c
@@ -383,13 +383,11 @@ static int aspeed_p2a_ctrl_probe(struct platform_device *pdev)
return rc;
}
-static int aspeed_p2a_ctrl_remove(struct platform_device *pdev)
+static void aspeed_p2a_ctrl_remove(struct platform_device *pdev)
{
struct aspeed_p2a_ctrl *p2a_ctrl = dev_get_drvdata(&pdev->dev);
misc_deregister(&p2a_ctrl->miscdev);
-
- return 0;
}
#define SCU2C_DRAM BIT(25)
@@ -433,7 +431,7 @@ static struct platform_driver aspeed_p2a_ctrl_driver = {
.of_match_table = aspeed_p2a_ctrl_match,
},
.probe = aspeed_p2a_ctrl_probe,
- .remove = aspeed_p2a_ctrl_remove,
+ .remove_new = aspeed_p2a_ctrl_remove,
};
module_platform_driver(aspeed_p2a_ctrl_driver);
diff --git a/drivers/soc/aspeed/aspeed-uart-routing.c b/drivers/soc/aspeed/aspeed-uart-routing.c
index 3a4c1f28cb34..a2195f062e01 100644
--- a/drivers/soc/aspeed/aspeed-uart-routing.c
+++ b/drivers/soc/aspeed/aspeed-uart-routing.c
@@ -565,14 +565,12 @@ static int aspeed_uart_routing_probe(struct platform_device *pdev)
return 0;
}
-static int aspeed_uart_routing_remove(struct platform_device *pdev)
+static void aspeed_uart_routing_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct aspeed_uart_routing *uart_routing = platform_get_drvdata(pdev);
sysfs_remove_group(&dev->kobj, uart_routing->attr_grp);
-
- return 0;
}
static const struct of_device_id aspeed_uart_routing_table[] = {
@@ -591,7 +589,7 @@ static struct platform_driver aspeed_uart_routing_driver = {
.of_match_table = aspeed_uart_routing_table,
},
.probe = aspeed_uart_routing_probe,
- .remove = aspeed_uart_routing_remove,
+ .remove_new = aspeed_uart_routing_remove,
};
module_platform_driver(aspeed_uart_routing_driver);
diff --git a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig
index f96906795fa6..c921a22f6c11 100644
--- a/drivers/soc/bcm/Kconfig
+++ b/drivers/soc/bcm/Kconfig
@@ -1,39 +1,9 @@
# SPDX-License-Identifier: GPL-2.0-only
menu "Broadcom SoC drivers"
-config BCM2835_POWER
- bool "BCM2835 power domain driver"
- depends on ARCH_BCM2835 || (COMPILE_TEST && OF)
- default y if ARCH_BCM2835
- select PM_GENERIC_DOMAINS if PM
- select RESET_CONTROLLER
- help
- This enables support for the BCM2835 power domains and reset
- controller. Any usage of power domains by the Raspberry Pi
- firmware means that Linux usage of the same power domain
- must be accessed using the RASPBERRYPI_POWER driver
-
-config RASPBERRYPI_POWER
- bool "Raspberry Pi power domain driver"
- depends on ARCH_BCM2835 || (COMPILE_TEST && OF)
- depends on RASPBERRYPI_FIRMWARE=y
- select PM_GENERIC_DOMAINS if PM
- help
- This enables support for the RPi power domains which can be enabled
- or disabled via the RPi firmware.
-
-config SOC_BCM63XX
- bool "Broadcom 63xx SoC drivers"
- depends on BMIPS_GENERIC || COMPILE_TEST
- help
- Enables drivers for the Broadcom 63xx series of chips.
- Drivers can be enabled individually within this menu.
-
- If unsure, say N.
-
config SOC_BRCMSTB
bool "Broadcom STB SoC drivers"
- depends on ARM || ARM64 || BMIPS_GENERIC || COMPILE_TEST
+ depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
select SOC_BUS
help
Enables drivers for the Broadcom Set-Top Box (STB) series of chips.
@@ -42,27 +12,6 @@ config SOC_BRCMSTB
If unsure, say N.
-config BCM_PMB
- bool "Broadcom PMB (Power Management Bus) driver"
- depends on ARCH_BCMBCA || (COMPILE_TEST && OF)
- default ARCH_BCMBCA
- select PM_GENERIC_DOMAINS if PM
- help
- This enables support for the Broadcom's PMB (Power Management Bus) that
- is used for disabling and enabling SoC devices.
-
-if SOC_BCM63XX
-
-config BCM63XX_POWER
- bool "BCM63xx power domain driver"
- depends on BMIPS_GENERIC || (COMPILE_TEST && OF)
- select PM_GENERIC_DOMAINS if PM
- help
- This enables support for the BCM63xx power domains controller on
- BCM6318, BCM6328, BCM6362 and BCM63268 SoCs.
-
-endif # SOC_BCM63XX
-
source "drivers/soc/bcm/brcmstb/Kconfig"
endmenu
diff --git a/drivers/soc/dove/pmu.c b/drivers/soc/dove/pmu.c
index ffc5311c0ed8..6202dbcd20a8 100644
--- a/drivers/soc/dove/pmu.c
+++ b/drivers/soc/dove/pmu.c
@@ -410,13 +410,16 @@ int __init dove_init_pmu(void)
struct pmu_domain *domain;
domain = kzalloc(sizeof(*domain), GFP_KERNEL);
- if (!domain)
+ if (!domain) {
+ of_node_put(np);
break;
+ }
domain->pmu = pmu;
domain->base.name = kasprintf(GFP_KERNEL, "%pOFn", np);
if (!domain->base.name) {
kfree(domain);
+ of_node_put(np);
break;
}
diff --git a/drivers/soc/fsl/dpaa2-console.c b/drivers/soc/fsl/dpaa2-console.c
index 1dca693b6b38..6dbc77db7718 100644
--- a/drivers/soc/fsl/dpaa2-console.c
+++ b/drivers/soc/fsl/dpaa2-console.c
@@ -300,12 +300,10 @@ err_register_mc:
return error;
}
-static int dpaa2_console_remove(struct platform_device *pdev)
+static void dpaa2_console_remove(struct platform_device *pdev)
{
misc_deregister(&dpaa2_mc_console_dev);
misc_deregister(&dpaa2_aiop_console_dev);
-
- return 0;
}
static const struct of_device_id dpaa2_console_match_table[] = {
@@ -322,7 +320,7 @@ static struct platform_driver dpaa2_console_driver = {
.of_match_table = dpaa2_console_match_table,
},
.probe = dpaa2_console_probe,
- .remove = dpaa2_console_remove,
+ .remove_new = dpaa2_console_remove,
};
module_platform_driver(dpaa2_console_driver);
diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 3ee0c7c1e9a4..70b6eddb867b 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -430,7 +430,7 @@ static void qe_upload_microcode(const void *base,
/*
* Upload a microcode to the I-RAM at a specific address.
*
- * See Documentation/powerpc/qe_firmware.rst for information on QE microcode
+ * See Documentation/arch/powerpc/qe_firmware.rst for information on QE microcode
* uploading.
*
* Currently, only version 1 is supported, so the 'version' field must be
diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index b3c292c9a14e..92ec76c03965 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -1415,7 +1415,7 @@ err_tsa_serial_disconnect:
return ret;
}
-static int qmc_remove(struct platform_device *pdev)
+static void qmc_remove(struct platform_device *pdev)
{
struct qmc *qmc = platform_get_drvdata(pdev);
@@ -1427,8 +1427,6 @@ static int qmc_remove(struct platform_device *pdev)
/* Disconnect the serial from TSA */
tsa_serial_disconnect(qmc->tsa_serial);
-
- return 0;
}
static const struct of_device_id qmc_id_table[] = {
@@ -1443,7 +1441,7 @@ static struct platform_driver qmc_driver = {
.of_match_table = of_match_ptr(qmc_id_table),
},
.probe = qmc_probe,
- .remove = qmc_remove,
+ .remove_new = qmc_remove,
};
module_platform_driver(qmc_driver);
diff --git a/drivers/soc/fsl/qe/tsa.c b/drivers/soc/fsl/qe/tsa.c
index 3646153117b3..3f9981335590 100644
--- a/drivers/soc/fsl/qe/tsa.c
+++ b/drivers/soc/fsl/qe/tsa.c
@@ -706,7 +706,7 @@ static int tsa_probe(struct platform_device *pdev)
return 0;
}
-static int tsa_remove(struct platform_device *pdev)
+static void tsa_remove(struct platform_device *pdev)
{
struct tsa *tsa = platform_get_drvdata(pdev);
int i;
@@ -729,7 +729,6 @@ static int tsa_remove(struct platform_device *pdev)
clk_put(tsa->tdm[i].l1rclk_clk);
}
}
- return 0;
}
static const struct of_device_id tsa_id_table[] = {
@@ -744,7 +743,7 @@ static struct platform_driver tsa_driver = {
.of_match_table = of_match_ptr(tsa_id_table),
},
.probe = tsa_probe,
- .remove = tsa_remove,
+ .remove_new = tsa_remove,
};
module_platform_driver(tsa_driver);
diff --git a/drivers/soc/fujitsu/a64fx-diag.c b/drivers/soc/fujitsu/a64fx-diag.c
index 524fbfeb94e3..330901893577 100644
--- a/drivers/soc/fujitsu/a64fx-diag.c
+++ b/drivers/soc/fujitsu/a64fx-diag.c
@@ -116,7 +116,7 @@ static int a64fx_diag_probe(struct platform_device *pdev)
return 0;
}
-static int a64fx_diag_remove(struct platform_device *pdev)
+static void a64fx_diag_remove(struct platform_device *pdev)
{
struct a64fx_diag_priv *priv = platform_get_drvdata(pdev);
@@ -127,8 +127,6 @@ static int a64fx_diag_remove(struct platform_device *pdev)
free_nmi(priv->irq, NULL);
else
free_irq(priv->irq, NULL);
-
- return 0;
}
static const struct acpi_device_id a64fx_diag_acpi_match[] = {
@@ -144,7 +142,7 @@ static struct platform_driver a64fx_diag_driver = {
.acpi_match_table = ACPI_PTR(a64fx_diag_acpi_match),
},
.probe = a64fx_diag_probe,
- .remove = a64fx_diag_remove,
+ .remove_new = a64fx_diag_remove,
};
module_platform_driver(a64fx_diag_driver);
diff --git a/drivers/soc/hisilicon/kunpeng_hccs.c b/drivers/soc/hisilicon/kunpeng_hccs.c
index 27a96cafd1ea..e31791659560 100644
--- a/drivers/soc/hisilicon/kunpeng_hccs.c
+++ b/drivers/soc/hisilicon/kunpeng_hccs.c
@@ -1240,14 +1240,12 @@ unregister_pcc_chan:
return rc;
}
-static int hccs_remove(struct platform_device *pdev)
+static void hccs_remove(struct platform_device *pdev)
{
struct hccs_dev *hdev = platform_get_drvdata(pdev);
hccs_remove_topo_dirs(hdev);
hccs_unregister_pcc_channel(hdev);
-
- return 0;
}
static const struct acpi_device_id hccs_acpi_match[] = {
@@ -1258,7 +1256,7 @@ MODULE_DEVICE_TABLE(acpi, hccs_acpi_match);
static struct platform_driver hccs_driver = {
.probe = hccs_probe,
- .remove = hccs_remove,
+ .remove_new = hccs_remove,
.driver = {
.name = "kunpeng_hccs",
.acpi_match_table = hccs_acpi_match,
diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig
index 76a4593baf0a..2a90ddd20104 100644
--- a/drivers/soc/imx/Kconfig
+++ b/drivers/soc/imx/Kconfig
@@ -1,14 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
menu "i.MX SoC drivers"
-config IMX_GPCV2_PM_DOMAINS
- bool "i.MX GPCv2 PM domains"
- depends on ARCH_MXC || (COMPILE_TEST && OF)
- depends on PM
- select PM_GENERIC_DOMAINS
- select REGMAP_MMIO
- default y if SOC_IMX7D
-
config SOC_IMX8M
tristate "i.MX8M SoC family support"
depends on ARCH_MXC || COMPILE_TEST
@@ -28,15 +20,4 @@ config SOC_IMX9
help
If you say yes here, you get support for the NXP i.MX9 family
-config IMX8M_BLK_CTRL
- bool
- default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
- depends on PM_GENERIC_DOMAINS
- depends on COMMON_CLK
-
-config IMX9_BLK_CTRL
- bool
- default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
- depends on PM_GENERIC_DOMAINS
-
endmenu
diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c
index 5be9988f30ce..35825ee95dff 100644
--- a/drivers/soc/ixp4xx/ixp4xx-npe.c
+++ b/drivers/soc/ixp4xx/ixp4xx-npe.c
@@ -736,7 +736,7 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
return 0;
}
-static int ixp4xx_npe_remove(struct platform_device *pdev)
+static void ixp4xx_npe_remove(struct platform_device *pdev)
{
int i;
@@ -744,8 +744,6 @@ static int ixp4xx_npe_remove(struct platform_device *pdev)
if (npe_tab[i].regs) {
npe_reset(&npe_tab[i]);
}
-
- return 0;
}
static const struct of_device_id ixp4xx_npe_of_match[] = {
@@ -761,7 +759,7 @@ static struct platform_driver ixp4xx_npe_driver = {
.of_match_table = ixp4xx_npe_of_match,
},
.probe = ixp4xx_npe_probe,
- .remove = ixp4xx_npe_remove,
+ .remove_new = ixp4xx_npe_remove,
};
module_platform_driver(ixp4xx_npe_driver);
diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
index 291086bb9313..244ad8d7e80b 100644
--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -442,11 +442,10 @@ static int ixp4xx_qmgr_probe(struct platform_device *pdev)
return 0;
}
-static int ixp4xx_qmgr_remove(struct platform_device *pdev)
+static void ixp4xx_qmgr_remove(struct platform_device *pdev)
{
synchronize_irq(qmgr_irq_1);
synchronize_irq(qmgr_irq_2);
- return 0;
}
static const struct of_device_id ixp4xx_qmgr_of_match[] = {
@@ -462,7 +461,7 @@ static struct platform_driver ixp4xx_qmgr_driver = {
.of_match_table = ixp4xx_qmgr_of_match,
},
.probe = ixp4xx_qmgr_probe,
- .remove = ixp4xx_qmgr_remove,
+ .remove_new = ixp4xx_qmgr_remove,
};
module_platform_driver(ixp4xx_qmgr_driver);
diff --git a/drivers/soc/litex/litex_soc_ctrl.c b/drivers/soc/litex/litex_soc_ctrl.c
index f75790091d38..10813299aa10 100644
--- a/drivers/soc/litex/litex_soc_ctrl.c
+++ b/drivers/soc/litex/litex_soc_ctrl.c
@@ -120,12 +120,11 @@ static int litex_soc_ctrl_probe(struct platform_device *pdev)
return 0;
}
-static int litex_soc_ctrl_remove(struct platform_device *pdev)
+static void litex_soc_ctrl_remove(struct platform_device *pdev)
{
struct litex_soc_ctrl_device *soc_ctrl_dev = platform_get_drvdata(pdev);
unregister_restart_handler(&soc_ctrl_dev->reset_nb);
- return 0;
}
static struct platform_driver litex_soc_ctrl_driver = {
@@ -134,7 +133,7 @@ static struct platform_driver litex_soc_ctrl_driver = {
.of_match_table = of_match_ptr(litex_soc_ctrl_of_match)
},
.probe = litex_soc_ctrl_probe,
- .remove = litex_soc_ctrl_remove,
+ .remove_new = litex_soc_ctrl_remove,
};
module_platform_driver(litex_soc_ctrl_driver);
diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c
index 9a469779eea7..ef352a0f5022 100644
--- a/drivers/soc/loongson/loongson2_guts.c
+++ b/drivers/soc/loongson/loongson2_guts.c
@@ -148,11 +148,9 @@ static int loongson2_guts_probe(struct platform_device *pdev)
return 0;
}
-static int loongson2_guts_remove(struct platform_device *dev)
+static void loongson2_guts_remove(struct platform_device *dev)
{
soc_device_unregister(soc_dev);
-
- return 0;
}
/*
@@ -171,7 +169,7 @@ static struct platform_driver loongson2_guts_driver = {
.of_match_table = loongson2_guts_of_match,
},
.probe = loongson2_guts_probe,
- .remove = loongson2_guts_remove,
+ .remove_new = loongson2_guts_remove,
};
static int __init loongson2_guts_init(void)
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a88cf04fc803..0810b5b0c688 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -49,29 +49,6 @@ config MTK_REGULATOR_COUPLER
default ARCH_MEDIATEK
depends on REGULATOR
-config MTK_SCPSYS
- bool "MediaTek SCPSYS Support"
- default ARCH_MEDIATEK
- depends on OF
- select REGMAP
- select MTK_INFRACFG
- select PM_GENERIC_DOMAINS if PM
- help
- Say yes here to add support for the MediaTek SCPSYS power domain
- driver.
-
-config MTK_SCPSYS_PM_DOMAINS
- bool "MediaTek SCPSYS generic power domain"
- default ARCH_MEDIATEK
- depends on PM
- select PM_GENERIC_DOMAINS
- select REGMAP
- help
- Say y here to enable power domain support.
- In order to meet high performance and low power requirements, the System
- Control Processor System (SCPSYS) has several power management related
- tasks in the system.
-
config MTK_MMSYS
tristate "MediaTek MMSYS Support"
default ARCH_MEDIATEK
diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index b28feb967540..56cc345552a4 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -292,18 +292,16 @@ static int mtk_devapc_probe(struct platform_device *pdev)
return 0;
}
-static int mtk_devapc_remove(struct platform_device *pdev)
+static void mtk_devapc_remove(struct platform_device *pdev)
{
struct mtk_devapc_context *ctx = platform_get_drvdata(pdev);
stop_devapc(ctx);
-
- return 0;
}
static struct platform_driver mtk_devapc_driver = {
.probe = mtk_devapc_probe,
- .remove = mtk_devapc_remove,
+ .remove_new = mtk_devapc_remove,
.driver = {
.name = "mtk-devapc",
.of_match_table = mtk_devapc_dt_match,
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index ffb75711a1da..88209102ff3b 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -410,14 +410,12 @@ out_probe_done:
return 0;
}
-static int mtk_mmsys_remove(struct platform_device *pdev)
+static void mtk_mmsys_remove(struct platform_device *pdev)
{
struct mtk_mmsys *mmsys = platform_get_drvdata(pdev);
platform_device_unregister(mmsys->drm_pdev);
platform_device_unregister(mmsys->clks_pdev);
-
- return 0;
}
static const struct of_device_id of_match_mtk_mmsys[] = {
@@ -449,7 +447,7 @@ static struct platform_driver mtk_mmsys_drv = {
.of_match_table = of_match_mtk_mmsys,
},
.probe = mtk_mmsys_probe,
- .remove = mtk_mmsys_remove,
+ .remove_new = mtk_mmsys_remove,
};
module_platform_driver(mtk_mmsys_drv);
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 3a2f97cd5272..f31e3bedff50 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -407,6 +407,7 @@ struct svs_platform_data {
* @dcbdet: svs efuse data
* @dcmdet: svs efuse data
* @turn_pt: 2-line turn point tells which opp_volt calculated by high/low bank
+ * @vbin_turn_pt: voltage bin turn point helps know which svsb_volt should be overridden
* @type: bank type to represent it is 2-line (high/low) bank or 1-line bank
*
* Svs bank will generate suitalbe voltages by below general math equation
@@ -469,6 +470,7 @@ struct svs_bank {
u32 dcbdet;
u32 dcmdet;
u32 turn_pt;
+ u32 vbin_turn_pt;
u32 type;
};
@@ -751,11 +753,12 @@ static int svs_status_debug_show(struct seq_file *m, void *v)
ret = thermal_zone_get_temp(svsb->tzd, &tzone_temp);
if (ret)
- seq_printf(m, "%s: temperature ignore, turn_pt = %u\n",
- svsb->name, svsb->turn_pt);
+ seq_printf(m, "%s: temperature ignore, vbin_turn_pt = %u, turn_pt = %u\n",
+ svsb->name, svsb->vbin_turn_pt, svsb->turn_pt);
else
- seq_printf(m, "%s: temperature = %d, turn_pt = %u\n",
- svsb->name, tzone_temp, svsb->turn_pt);
+ seq_printf(m, "%s: temperature = %d, vbin_turn_pt = %u, turn_pt = %u\n",
+ svsb->name, tzone_temp, svsb->vbin_turn_pt,
+ svsb->turn_pt);
for (i = 0; i < svsb->opp_count; i++) {
opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
@@ -952,6 +955,29 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp)
for (i = opp_start; i < opp_stop; i++)
if (svsb->volt_flags & SVSB_REMOVE_DVTFIXED_VOLT)
svsb->volt[i] -= svsb->dvt_fixed;
+
+ /* For voltage bin support */
+ if (svsb->opp_dfreq[0] > svsb->freq_base) {
+ svsb->volt[0] = svs_opp_volt_to_bank_volt(svsb->opp_dvolt[0],
+ svsb->volt_step,
+ svsb->volt_base);
+
+ /* Find voltage bin turn point */
+ for (i = 0; i < svsb->opp_count; i++) {
+ if (svsb->opp_dfreq[i] <= svsb->freq_base) {
+ svsb->vbin_turn_pt = i;
+ break;
+ }
+ }
+
+ /* Override svs bank voltages */
+ for (i = 1; i < svsb->vbin_turn_pt; i++)
+ svsb->volt[i] = interpolate(svsb->freq_pct[0],
+ svsb->freq_pct[svsb->vbin_turn_pt],
+ svsb->volt[0],
+ svsb->volt[svsb->vbin_turn_pt],
+ svsb->freq_pct[i]);
+ }
}
static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
@@ -1069,6 +1095,29 @@ static void svs_get_bank_volts_v2(struct svs_platform *svsp)
for (i = 0; i < svsb->opp_count; i++)
svsb->volt[i] += svsb->volt_od;
+
+ /* For voltage bin support */
+ if (svsb->opp_dfreq[0] > svsb->freq_base) {
+ svsb->volt[0] = svs_opp_volt_to_bank_volt(svsb->opp_dvolt[0],
+ svsb->volt_step,
+ svsb->volt_base);
+
+ /* Find voltage bin turn point */
+ for (i = 0; i < svsb->opp_count; i++) {
+ if (svsb->opp_dfreq[i] <= svsb->freq_base) {
+ svsb->vbin_turn_pt = i;
+ break;
+ }
+ }
+
+ /* Override svs bank voltages */
+ for (i = 1; i < svsb->vbin_turn_pt; i++)
+ svsb->volt[i] = interpolate(svsb->freq_pct[0],
+ svsb->freq_pct[svsb->vbin_turn_pt],
+ svsb->volt[0],
+ svsb->volt[svsb->vbin_turn_pt],
+ svsb->freq_pct[i]);
+ }
}
static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp)
@@ -1808,6 +1857,66 @@ static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp)
return true;
}
+static bool svs_mt8188_efuse_parsing(struct svs_platform *svsp)
+{
+ struct svs_bank *svsb;
+ u32 idx, i, golden_temp;
+ int ret;
+
+ for (i = 0; i < svsp->efuse_max; i++)
+ if (svsp->efuse[i])
+ dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
+ i, svsp->efuse[i]);
+
+ if (!svsp->efuse[5]) {
+ dev_notice(svsp->dev, "svs_efuse[5] = 0x0?\n");
+ return false;
+ }
+
+ /* Svs efuse parsing */
+ for (idx = 0; idx < svsp->bank_max; idx++) {
+ svsb = &svsp->banks[idx];
+
+ if (svsb->type == SVSB_LOW) {
+ svsb->mtdes = svsp->efuse[5] & GENMASK(7, 0);
+ svsb->bdes = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
+ svsb->mdes = (svsp->efuse[5] >> 24) & GENMASK(7, 0);
+ svsb->dcbdet = (svsp->efuse[15] >> 16) & GENMASK(7, 0);
+ svsb->dcmdet = (svsp->efuse[15] >> 24) & GENMASK(7, 0);
+ } else if (svsb->type == SVSB_HIGH) {
+ svsb->mtdes = svsp->efuse[4] & GENMASK(7, 0);
+ svsb->bdes = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
+ svsb->mdes = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
+ svsb->dcbdet = svsp->efuse[14] & GENMASK(7, 0);
+ svsb->dcmdet = (svsp->efuse[14] >> 8) & GENMASK(7, 0);
+ }
+
+ svsb->vmax += svsb->dvt_fixed;
+ }
+
+ ret = svs_get_efuse_data(svsp, "t-calibration-data",
+ &svsp->tefuse, &svsp->tefuse_max);
+ if (ret)
+ return false;
+
+ for (i = 0; i < svsp->tefuse_max; i++)
+ if (svsp->tefuse[i] != 0)
+ break;
+
+ if (i == svsp->tefuse_max)
+ golden_temp = 50; /* All thermal efuse data are 0 */
+ else
+ golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0);
+
+ for (idx = 0; idx < svsp->bank_max; idx++) {
+ svsb = &svsp->banks[idx];
+ svsb->mts = 500;
+ svsb->bts = (((500 * golden_temp + 250460) / 1000) - 25) * 4;
+ }
+
+ return true;
+}
+
static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
{
struct svs_bank *svsb;
@@ -2173,6 +2282,61 @@ static struct svs_bank svs_mt8192_banks[] = {
},
};
+static struct svs_bank svs_mt8188_banks[] = {
+ {
+ .sw_id = SVSB_GPU,
+ .type = SVSB_LOW,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
+ .mode_support = SVSB_MODE_INIT02,
+ .opp_count = MAX_OPP_ENTRIES,
+ .freq_base = 640000000,
+ .turn_freq_base = 640000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .vmax = 0x38,
+ .vmin = 0x1c,
+ .age_config = 0x555555,
+ .dc_config = 0x555555,
+ .dvt_fixed = 0x1,
+ .vco = 0x10,
+ .chk_shift = 0x87,
+ .core_sel = 0x0fff0000,
+ .int_st = BIT(0),
+ .ctl0 = 0x00100003,
+ },
+ {
+ .sw_id = SVSB_GPU,
+ .type = SVSB_HIGH,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .tzone_name = "gpu1",
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT |
+ SVSB_MON_VOLT_IGNORE,
+ .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
+ .opp_count = MAX_OPP_ENTRIES,
+ .freq_base = 880000000,
+ .turn_freq_base = 640000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .vmax = 0x38,
+ .vmin = 0x1c,
+ .age_config = 0x555555,
+ .dc_config = 0x555555,
+ .dvt_fixed = 0x4,
+ .vco = 0x10,
+ .chk_shift = 0x87,
+ .core_sel = 0x0fff0001,
+ .int_st = BIT(1),
+ .ctl0 = 0x00100003,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 0,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 7,
+ },
+};
+
static struct svs_bank svs_mt8183_banks[] = {
{
.sw_id = SVSB_CPU_LITTLE,
@@ -2286,6 +2450,15 @@ static const struct svs_platform_data svs_mt8192_platform_data = {
.bank_max = ARRAY_SIZE(svs_mt8192_banks),
};
+static const struct svs_platform_data svs_mt8188_platform_data = {
+ .name = "mt8188-svs",
+ .banks = svs_mt8188_banks,
+ .efuse_parsing = svs_mt8188_efuse_parsing,
+ .probe = svs_mt8192_platform_probe,
+ .regs = svs_regs_v2,
+ .bank_max = ARRAY_SIZE(svs_mt8188_banks),
+};
+
static const struct svs_platform_data svs_mt8183_platform_data = {
.name = "mt8183-svs",
.banks = svs_mt8183_banks,
@@ -2300,6 +2473,9 @@ static const struct of_device_id svs_of_match[] = {
.compatible = "mediatek,mt8192-svs",
.data = &svs_mt8192_platform_data,
}, {
+ .compatible = "mediatek,mt8188-svs",
+ .data = &svs_mt8188_platform_data,
+ }, {
.compatible = "mediatek,mt8183-svs",
.data = &svs_mt8183_platform_data,
}, {
diff --git a/drivers/soc/microchip/mpfs-sys-controller.c b/drivers/soc/microchip/mpfs-sys-controller.c
index fbcd5fd24d7c..0935e9e94172 100644
--- a/drivers/soc/microchip/mpfs-sys-controller.c
+++ b/drivers/soc/microchip/mpfs-sys-controller.c
@@ -149,13 +149,11 @@ static int mpfs_sys_controller_probe(struct platform_device *pdev)
return 0;
}
-static int mpfs_sys_controller_remove(struct platform_device *pdev)
+static void mpfs_sys_controller_remove(struct platform_device *pdev)
{
struct mpfs_sys_controller *sys_controller = platform_get_drvdata(pdev);
mpfs_sys_controller_put(sys_controller);
-
- return 0;
}
static const struct of_device_id mpfs_sys_controller_of_match[] = {
@@ -207,7 +205,7 @@ static struct platform_driver mpfs_sys_controller_driver = {
.of_match_table = mpfs_sys_controller_of_match,
},
.probe = mpfs_sys_controller_probe,
- .remove = mpfs_sys_controller_remove,
+ .remove_new = mpfs_sys_controller_remove,
};
module_platform_driver(mpfs_sys_controller_driver);
diff --git a/drivers/soc/pxa/ssp.c b/drivers/soc/pxa/ssp.c
index bd029e838241..a1e8a07f7275 100644
--- a/drivers/soc/pxa/ssp.c
+++ b/drivers/soc/pxa/ssp.c
@@ -176,15 +176,13 @@ static int pxa_ssp_probe(struct platform_device *pdev)
return 0;
}
-static int pxa_ssp_remove(struct platform_device *pdev)
+static void pxa_ssp_remove(struct platform_device *pdev)
{
struct ssp_device *ssp = platform_get_drvdata(pdev);
mutex_lock(&ssp_lock);
list_del(&ssp->node);
mutex_unlock(&ssp_lock);
-
- return 0;
}
static const struct platform_device_id ssp_id_table[] = {
@@ -199,7 +197,7 @@ static const struct platform_device_id ssp_id_table[] = {
static struct platform_driver pxa_ssp_driver = {
.probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
+ .remove_new = pxa_ssp_remove,
.driver = {
.name = "pxa2xx-ssp",
.of_match_table = of_match_ptr(pxa_ssp_of_ids),
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 715348869d04..b3634e10f6f5 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -26,22 +26,6 @@ config QCOM_COMMAND_DB
resource on a RPM-hardened platform must use this database to get
SoC specific identifier and information for the shared resources.
-config QCOM_CPR
- tristate "QCOM Core Power Reduction (CPR) support"
- depends on ARCH_QCOM && HAS_IOMEM
- select PM_OPP
- select REGMAP
- help
- Say Y here to enable support for the CPR hardware found on Qualcomm
- SoCs like QCS404.
-
- This driver populates CPU OPPs tables and makes adjustments to the
- tables based on feedback from the CPR hardware. If you want to do
- CPUfrequency scaling say Y here.
-
- To compile this driver as a module, choose M here: the module will
- be called qcom-cpr
-
config QCOM_GENI_SE
tristate "QCOM GENI Serial Engine Driver"
depends on ARCH_QCOM || COMPILE_TEST
@@ -157,27 +141,6 @@ config QCOM_RPMH
of hardware components aggregate requests for these resources and
help apply the aggregated state on the resource.
-config QCOM_RPMHPD
- tristate "Qualcomm RPMh Power domain driver"
- depends on QCOM_RPMH && QCOM_COMMAND_DB
- help
- QCOM RPMh Power domain driver to support power-domains with
- performance states. The driver communicates a performance state
- value to RPMh which then translates it into corresponding voltage
- for the voltage rail.
-
-config QCOM_RPMPD
- tristate "Qualcomm RPM Power domain driver"
- depends on PM && OF
- depends on QCOM_SMD_RPM
- select PM_GENERIC_DOMAINS
- select PM_GENERIC_DOMAINS_OF
- help
- QCOM RPM Power domain driver to support power-domains with
- performance states. The driver communicates a performance state
- value to RPM which then translates it into corresponding voltage
- for the voltage rail.
-
config QCOM_SMEM
tristate "Qualcomm Shared Memory Manager (SMEM)"
depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
index 30f81d6d9d9d..1f8b315576a4 100644
--- a/drivers/soc/qcom/apr.c
+++ b/drivers/soc/qcom/apr.c
@@ -41,7 +41,7 @@ struct packet_router {
struct apr_rx_buf {
struct list_head node;
int len;
- uint8_t buf[];
+ uint8_t buf[] __counted_by(len);
};
/**
@@ -171,7 +171,7 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf,
return -EINVAL;
}
- abuf = kzalloc(sizeof(*abuf) + len, GFP_ATOMIC);
+ abuf = kzalloc(struct_size(abuf, buf, len), GFP_ATOMIC);
if (!abuf)
return -ENOMEM;
diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
index 34c40368d5b5..a5fd68411bed 100644
--- a/drivers/soc/qcom/cmd-db.c
+++ b/drivers/soc/qcom/cmd-db.c
@@ -133,7 +133,7 @@ int cmd_db_ready(void)
return 0;
}
-EXPORT_SYMBOL(cmd_db_ready);
+EXPORT_SYMBOL_GPL(cmd_db_ready);
static int cmd_db_get_header(const char *id, const struct entry_header **eh,
const struct rsc_hdr **rh)
@@ -193,7 +193,7 @@ u32 cmd_db_read_addr(const char *id)
return ret < 0 ? 0 : le32_to_cpu(ent->addr);
}
-EXPORT_SYMBOL(cmd_db_read_addr);
+EXPORT_SYMBOL_GPL(cmd_db_read_addr);
/**
* cmd_db_read_aux_data() - Query command db for aux data.
@@ -218,7 +218,7 @@ const void *cmd_db_read_aux_data(const char *id, size_t *len)
return rsc_offset(rsc_hdr, ent);
}
-EXPORT_SYMBOL(cmd_db_read_aux_data);
+EXPORT_SYMBOL_GPL(cmd_db_read_aux_data);
/**
* cmd_db_read_slave_id - Get the slave ID for a given resource address
@@ -240,7 +240,7 @@ enum cmd_db_hw_type cmd_db_read_slave_id(const char *id)
addr = le32_to_cpu(ent->addr);
return (addr >> SLAVE_ID_SHIFT) & SLAVE_ID_MASK;
}
-EXPORT_SYMBOL(cmd_db_read_slave_id);
+EXPORT_SYMBOL_GPL(cmd_db_read_slave_id);
#ifdef CONFIG_DEBUG_FS
static int cmd_db_debugfs_dump(struct seq_file *seq, void *p)
diff --git a/drivers/soc/qcom/icc-bwmon.c b/drivers/soc/qcom/icc-bwmon.c
index adf2d523f103..656706259353 100644
--- a/drivers/soc/qcom/icc-bwmon.c
+++ b/drivers/soc/qcom/icc-bwmon.c
@@ -793,13 +793,11 @@ static int bwmon_probe(struct platform_device *pdev)
return 0;
}
-static int bwmon_remove(struct platform_device *pdev)
+static void bwmon_remove(struct platform_device *pdev)
{
struct icc_bwmon *bwmon = platform_get_drvdata(pdev);
bwmon_disable(bwmon);
-
- return 0;
}
static const struct icc_bwmon_data msm8998_bwmon_data = {
@@ -862,7 +860,7 @@ MODULE_DEVICE_TABLE(of, bwmon_of_match);
static struct platform_driver bwmon_driver = {
.probe = bwmon_probe,
- .remove = bwmon_remove,
+ .remove_new = bwmon_remove,
.driver = {
.name = "qcom-bwmon",
.of_match_table = bwmon_of_match,
diff --git a/drivers/soc/qcom/kryo-l2-accessors.c b/drivers/soc/qcom/kryo-l2-accessors.c
index 7886af4fd726..50cd710c5e82 100644
--- a/drivers/soc/qcom/kryo-l2-accessors.c
+++ b/drivers/soc/qcom/kryo-l2-accessors.c
@@ -32,7 +32,7 @@ void kryo_l2_set_indirect_reg(u64 reg, u64 val)
isb();
raw_spin_unlock_irqrestore(&l2_access_lock, flags);
}
-EXPORT_SYMBOL(kryo_l2_set_indirect_reg);
+EXPORT_SYMBOL_GPL(kryo_l2_set_indirect_reg);
/**
* kryo_l2_get_indirect_reg() - read an L2 register value
@@ -54,4 +54,4 @@ u64 kryo_l2_get_indirect_reg(u64 reg)
return val;
}
-EXPORT_SYMBOL(kryo_l2_get_indirect_reg);
+EXPORT_SYMBOL_GPL(kryo_l2_get_indirect_reg);
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index e32a4161a8d0..674abd0d6700 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/sizes.h>
@@ -126,6 +127,11 @@ struct qcom_llcc_config {
bool no_edac;
};
+struct qcom_sct_config {
+ const struct qcom_llcc_config *llcc_config;
+ int num_config;
+};
+
enum llcc_reg_offset {
LLCC_COMMON_HW_INFO,
LLCC_COMMON_STATUS0,
@@ -185,7 +191,7 @@ static const struct llcc_slice_config sc8280xp_data[] = {
{ LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },
{ LLCC_DISP, 16, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_AUDHW, 22, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
- { LLCC_DRE, 26, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
+ { LLCC_ECC, 26, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_CVP, 28, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0, 0 },
{ LLCC_WRCACHE, 31, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },
@@ -356,6 +362,36 @@ static const struct llcc_slice_config sm8550_data[] = {
{LLCC_VIDVSP, 28, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
};
+static const struct llcc_slice_config qdu1000_data_2ch[] = {
+ { LLCC_MDMHPGRW, 7, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_MODHW, 9, 256, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_MDMPNG, 21, 256, 0, 1, 0x3, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_ECC, 26, 512, 3, 1, 0xffc, 0x0, 0, 0, 0, 0, 1, 0, 0 },
+ { LLCC_MODPE, 29, 256, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_APTCM, 30, 256, 3, 1, 0x0, 0xc, 1, 0, 0, 1, 0, 0, 0 },
+ { LLCC_WRCACHE, 31, 128, 1, 1, 0x3, 0x0, 0, 0, 0, 0, 1, 0, 0 },
+};
+
+static const struct llcc_slice_config qdu1000_data_4ch[] = {
+ { LLCC_MDMHPGRW, 7, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_MODHW, 9, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_MDMPNG, 21, 512, 0, 1, 0x3, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_ECC, 26, 1024, 3, 1, 0xffc, 0x0, 0, 0, 0, 0, 1, 0, 0 },
+ { LLCC_MODPE, 29, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_APTCM, 30, 512, 3, 1, 0x0, 0xc, 1, 0, 0, 1, 0, 0, 0 },
+ { LLCC_WRCACHE, 31, 256, 1, 1, 0x3, 0x0, 0, 0, 0, 0, 1, 0, 0 },
+};
+
+static const struct llcc_slice_config qdu1000_data_8ch[] = {
+ { LLCC_MDMHPGRW, 7, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_MODHW, 9, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_MDMPNG, 21, 1024, 0, 1, 0x3, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_ECC, 26, 2048, 3, 1, 0xffc, 0x0, 0, 0, 0, 0, 1, 0, 0 },
+ { LLCC_MODPE, 29, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },
+ { LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0xc, 1, 0, 0, 1, 0, 0, 0 },
+ { LLCC_WRCACHE, 31, 512, 1, 1, 0x3, 0x0, 0, 0, 0, 0, 1, 0, 0 },
+};
+
static const struct llcc_edac_reg_offset llcc_v1_edac_reg_offset = {
.trp_ecc_error_status0 = 0x20344,
.trp_ecc_error_status1 = 0x20348,
@@ -422,101 +458,221 @@ static const u32 llcc_v2_1_reg_offset[] = {
[LLCC_COMMON_STATUS0] = 0x0003400c,
};
-static const struct qcom_llcc_config sc7180_cfg = {
- .sct_data = sc7180_data,
- .size = ARRAY_SIZE(sc7180_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
+static const struct qcom_llcc_config qdu1000_cfg[] = {
+ {
+ .sct_data = qdu1000_data_8ch,
+ .size = ARRAY_SIZE(qdu1000_data_8ch),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v2_1_reg_offset,
+ .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
+ },
+ {
+ .sct_data = qdu1000_data_4ch,
+ .size = ARRAY_SIZE(qdu1000_data_4ch),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v2_1_reg_offset,
+ .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
+ },
+ {
+ .sct_data = qdu1000_data_4ch,
+ .size = ARRAY_SIZE(qdu1000_data_4ch),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v2_1_reg_offset,
+ .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
+ },
+ {
+ .sct_data = qdu1000_data_2ch,
+ .size = ARRAY_SIZE(qdu1000_data_2ch),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v2_1_reg_offset,
+ .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sc7180_cfg[] = {
+ {
+ .sct_data = sc7180_data,
+ .size = ARRAY_SIZE(sc7180_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sc7280_cfg[] = {
+ {
+ .sct_data = sc7280_data,
+ .size = ARRAY_SIZE(sc7280_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sc8180x_cfg[] = {
+ {
+ .sct_data = sc8180x_data,
+ .size = ARRAY_SIZE(sc8180x_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sc8280xp_cfg[] = {
+ {
+ .sct_data = sc8280xp_data,
+ .size = ARRAY_SIZE(sc8280xp_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sdm845_cfg[] = {
+ {
+ .sct_data = sdm845_data,
+ .size = ARRAY_SIZE(sdm845_data),
+ .need_llcc_cfg = false,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ .no_edac = true,
+ },
+};
+
+static const struct qcom_llcc_config sm6350_cfg[] = {
+ {
+ .sct_data = sm6350_data,
+ .size = ARRAY_SIZE(sm6350_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sm7150_cfg[] = {
+ {
+ .sct_data = sm7150_data,
+ .size = ARRAY_SIZE(sm7150_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sm8150_cfg[] = {
+ {
+ .sct_data = sm8150_data,
+ .size = ARRAY_SIZE(sm8150_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sm8250_cfg[] = {
+ {
+ .sct_data = sm8250_data,
+ .size = ARRAY_SIZE(sm8250_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sm8350_cfg[] = {
+ {
+ .sct_data = sm8350_data,
+ .size = ARRAY_SIZE(sm8350_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sm8450_cfg[] = {
+ {
+ .sct_data = sm8450_data,
+ .size = ARRAY_SIZE(sm8450_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v2_1_reg_offset,
+ .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_llcc_config sm8550_cfg[] = {
+ {
+ .sct_data = sm8550_data,
+ .size = ARRAY_SIZE(sm8550_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v2_1_reg_offset,
+ .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
+ },
+};
+
+static const struct qcom_sct_config qdu1000_cfgs = {
+ .llcc_config = qdu1000_cfg,
+ .num_config = ARRAY_SIZE(qdu1000_cfg),
+};
+
+static const struct qcom_sct_config sc7180_cfgs = {
+ .llcc_config = sc7180_cfg,
+ .num_config = ARRAY_SIZE(sc7180_cfg),
};
-static const struct qcom_llcc_config sc7280_cfg = {
- .sct_data = sc7280_data,
- .size = ARRAY_SIZE(sc7280_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
+static const struct qcom_sct_config sc7280_cfgs = {
+ .llcc_config = sc7280_cfg,
+ .num_config = ARRAY_SIZE(sc7280_cfg),
};
-static const struct qcom_llcc_config sc8180x_cfg = {
- .sct_data = sc8180x_data,
- .size = ARRAY_SIZE(sc8180x_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
+static const struct qcom_sct_config sc8180x_cfgs = {
+ .llcc_config = sc8180x_cfg,
+ .num_config = ARRAY_SIZE(sc8180x_cfg),
};
-static const struct qcom_llcc_config sc8280xp_cfg = {
- .sct_data = sc8280xp_data,
- .size = ARRAY_SIZE(sc8280xp_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
+static const struct qcom_sct_config sc8280xp_cfgs = {
+ .llcc_config = sc8280xp_cfg,
+ .num_config = ARRAY_SIZE(sc8280xp_cfg),
};
-static const struct qcom_llcc_config sdm845_cfg = {
- .sct_data = sdm845_data,
- .size = ARRAY_SIZE(sdm845_data),
- .need_llcc_cfg = false,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
- .no_edac = true,
+static const struct qcom_sct_config sdm845_cfgs = {
+ .llcc_config = sdm845_cfg,
+ .num_config = ARRAY_SIZE(sdm845_cfg),
};
-static const struct qcom_llcc_config sm6350_cfg = {
- .sct_data = sm6350_data,
- .size = ARRAY_SIZE(sm6350_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
+static const struct qcom_sct_config sm6350_cfgs = {
+ .llcc_config = sm6350_cfg,
+ .num_config = ARRAY_SIZE(sm6350_cfg),
};
-static const struct qcom_llcc_config sm7150_cfg = {
- .sct_data = sm7150_data,
- .size = ARRAY_SIZE(sm7150_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
+static const struct qcom_sct_config sm7150_cfgs = {
+ .llcc_config = sm7150_cfg,
+ .num_config = ARRAY_SIZE(sm7150_cfg),
};
-static const struct qcom_llcc_config sm8150_cfg = {
- .sct_data = sm8150_data,
- .size = ARRAY_SIZE(sm8150_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
+static const struct qcom_sct_config sm8150_cfgs = {
+ .llcc_config = sm8150_cfg,
+ .num_config = ARRAY_SIZE(sm8150_cfg),
};
-static const struct qcom_llcc_config sm8250_cfg = {
- .sct_data = sm8250_data,
- .size = ARRAY_SIZE(sm8250_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
+static const struct qcom_sct_config sm8250_cfgs = {
+ .llcc_config = sm8250_cfg,
+ .num_config = ARRAY_SIZE(sm8250_cfg),
};
-static const struct qcom_llcc_config sm8350_cfg = {
- .sct_data = sm8350_data,
- .size = ARRAY_SIZE(sm8350_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v1_reg_offset,
- .edac_reg_offset = &llcc_v1_edac_reg_offset,
+static const struct qcom_sct_config sm8350_cfgs = {
+ .llcc_config = sm8350_cfg,
+ .num_config = ARRAY_SIZE(sm8350_cfg),
};
-static const struct qcom_llcc_config sm8450_cfg = {
- .sct_data = sm8450_data,
- .size = ARRAY_SIZE(sm8450_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v2_1_reg_offset,
- .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
+static const struct qcom_sct_config sm8450_cfgs = {
+ .llcc_config = sm8450_cfg,
+ .num_config = ARRAY_SIZE(sm8450_cfg),
};
-static const struct qcom_llcc_config sm8550_cfg = {
- .sct_data = sm8550_data,
- .size = ARRAY_SIZE(sm8550_data),
- .need_llcc_cfg = true,
- .reg_offset = llcc_v2_1_reg_offset,
- .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
+static const struct qcom_sct_config sm8550_cfgs = {
+ .llcc_config = sm8550_cfg,
+ .num_config = ARRAY_SIZE(sm8550_cfg),
};
static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
@@ -906,11 +1062,28 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev,
return ret;
}
-static int qcom_llcc_remove(struct platform_device *pdev)
+static int qcom_llcc_get_cfg_index(struct platform_device *pdev, u8 *cfg_index, int num_config)
+{
+ int ret;
+
+ ret = nvmem_cell_read_u8(&pdev->dev, "multi-chan-ddr", cfg_index);
+ if (ret == -ENOENT || ret == -EOPNOTSUPP) {
+ if (num_config > 1)
+ return -EINVAL;
+ *cfg_index = 0;
+ return 0;
+ }
+
+ if (!ret && *cfg_index >= num_config)
+ ret = -EINVAL;
+
+ return ret;
+}
+
+static void qcom_llcc_remove(struct platform_device *pdev)
{
/* Set the global pointer to a error code to avoid referencing it */
drv_data = ERR_PTR(-ENODEV);
- return 0;
}
static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, u8 index,
@@ -938,12 +1111,17 @@ static int qcom_llcc_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
int ret, i;
struct platform_device *llcc_edac;
+ const struct qcom_sct_config *cfgs;
const struct qcom_llcc_config *cfg;
const struct llcc_slice_config *llcc_cfg;
u32 sz;
+ u8 cfg_index;
u32 version;
struct regmap *regmap;
+ if (!IS_ERR(drv_data))
+ return -EBUSY;
+
drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
if (!drv_data) {
ret = -ENOMEM;
@@ -957,7 +1135,15 @@ static int qcom_llcc_probe(struct platform_device *pdev)
goto err;
}
- cfg = of_device_get_match_data(&pdev->dev);
+ cfgs = of_device_get_match_data(&pdev->dev);
+ if (!cfgs) {
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = qcom_llcc_get_cfg_index(pdev, &cfg_index, cfgs->num_config);
+ if (ret)
+ goto err;
+ cfg = &cfgs->llcc_config[cfg_index];
ret = regmap_read(regmap, cfg->reg_offset[LLCC_COMMON_STATUS0], &num_banks);
if (ret)
@@ -1050,18 +1236,19 @@ err:
}
static const struct of_device_id qcom_llcc_of_match[] = {
- { .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfg },
- { .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfg },
- { .compatible = "qcom,sc8180x-llcc", .data = &sc8180x_cfg },
- { .compatible = "qcom,sc8280xp-llcc", .data = &sc8280xp_cfg },
- { .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfg },
- { .compatible = "qcom,sm6350-llcc", .data = &sm6350_cfg },
- { .compatible = "qcom,sm7150-llcc", .data = &sm7150_cfg },
- { .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg },
- { .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg },
- { .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfg },
- { .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfg },
- { .compatible = "qcom,sm8550-llcc", .data = &sm8550_cfg },
+ { .compatible = "qcom,qdu1000-llcc", .data = &qdu1000_cfgs},
+ { .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfgs },
+ { .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfgs },
+ { .compatible = "qcom,sc8180x-llcc", .data = &sc8180x_cfgs },
+ { .compatible = "qcom,sc8280xp-llcc", .data = &sc8280xp_cfgs },
+ { .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfgs },
+ { .compatible = "qcom,sm6350-llcc", .data = &sm6350_cfgs },
+ { .compatible = "qcom,sm7150-llcc", .data = &sm7150_cfgs },
+ { .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfgs },
+ { .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfgs },
+ { .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfgs },
+ { .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfgs },
+ { .compatible = "qcom,sm8550-llcc", .data = &sm8550_cfgs },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_llcc_of_match);
@@ -1072,7 +1259,7 @@ static struct platform_driver qcom_llcc_driver = {
.of_match_table = qcom_llcc_of_match,
},
.probe = qcom_llcc_probe,
- .remove = qcom_llcc_remove,
+ .remove_new = qcom_llcc_remove,
};
module_platform_driver(qcom_llcc_driver);
diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c
index 20f5461d46b9..e8841d247953 100644
--- a/drivers/soc/qcom/ocmem.c
+++ b/drivers/soc/qcom/ocmem.c
@@ -211,7 +211,7 @@ struct ocmem *of_get_ocmem(struct device *dev)
}
return ocmem;
}
-EXPORT_SYMBOL(of_get_ocmem);
+EXPORT_SYMBOL_GPL(of_get_ocmem);
struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem, enum ocmem_client client,
unsigned long size)
@@ -267,7 +267,7 @@ err_unlock:
return ERR_PTR(ret);
}
-EXPORT_SYMBOL(ocmem_allocate);
+EXPORT_SYMBOL_GPL(ocmem_allocate);
void ocmem_free(struct ocmem *ocmem, enum ocmem_client client,
struct ocmem_buf *buf)
@@ -294,7 +294,7 @@ void ocmem_free(struct ocmem *ocmem, enum ocmem_client client,
clear_bit_unlock(BIT(client), &ocmem->active_allocations);
}
-EXPORT_SYMBOL(ocmem_free);
+EXPORT_SYMBOL_GPL(ocmem_free);
static int ocmem_dev_probe(struct platform_device *pdev)
{
@@ -416,14 +416,12 @@ err_clk_disable:
return ret;
}
-static int ocmem_dev_remove(struct platform_device *pdev)
+static void ocmem_dev_remove(struct platform_device *pdev)
{
struct ocmem *ocmem = platform_get_drvdata(pdev);
clk_disable_unprepare(ocmem->core_clk);
clk_disable_unprepare(ocmem->iface_clk);
-
- return 0;
}
static const struct ocmem_config ocmem_8226_config = {
@@ -446,7 +444,7 @@ MODULE_DEVICE_TABLE(of, ocmem_of_match);
static struct platform_driver ocmem_driver = {
.probe = ocmem_dev_probe,
- .remove = ocmem_dev_remove,
+ .remove_new = ocmem_dev_remove,
.driver = {
.name = "ocmem",
.of_match_table = ocmem_of_match,
diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c
index 0034af927b48..a1b6a4081dea 100644
--- a/drivers/soc/qcom/pdr_interface.c
+++ b/drivers/soc/qcom/pdr_interface.c
@@ -554,7 +554,7 @@ err:
kfree(pds);
return ERR_PTR(ret);
}
-EXPORT_SYMBOL(pdr_add_lookup);
+EXPORT_SYMBOL_GPL(pdr_add_lookup);
/**
* pdr_restart_pd() - restart PD
@@ -634,7 +634,7 @@ int pdr_restart_pd(struct pdr_handle *pdr, struct pdr_service *pds)
return 0;
}
-EXPORT_SYMBOL(pdr_restart_pd);
+EXPORT_SYMBOL_GPL(pdr_restart_pd);
/**
* pdr_handle_alloc() - initialize the PDR client handle
@@ -715,7 +715,7 @@ free_pdr_handle:
return ERR_PTR(ret);
}
-EXPORT_SYMBOL(pdr_handle_alloc);
+EXPORT_SYMBOL_GPL(pdr_handle_alloc);
/**
* pdr_handle_release() - release the PDR client handle
@@ -749,7 +749,7 @@ void pdr_handle_release(struct pdr_handle *pdr)
kfree(pdr);
}
-EXPORT_SYMBOL(pdr_handle_release);
+EXPORT_SYMBOL_GPL(pdr_handle_release);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Qualcomm Protection Domain Restart helpers");
diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c
index 61c89ddfc75b..914057331afd 100644
--- a/drivers/soc/qcom/pmic_glink.c
+++ b/drivers/soc/qcom/pmic_glink.c
@@ -318,7 +318,7 @@ out_release_ucsi_aux:
return ret;
}
-static int pmic_glink_remove(struct platform_device *pdev)
+static void pmic_glink_remove(struct platform_device *pdev)
{
struct pmic_glink *pg = dev_get_drvdata(&pdev->dev);
@@ -334,8 +334,6 @@ static int pmic_glink_remove(struct platform_device *pdev)
mutex_lock(&__pmic_glink_lock);
__pmic_glink = NULL;
mutex_unlock(&__pmic_glink_lock);
-
- return 0;
}
static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) |
@@ -352,7 +350,7 @@ MODULE_DEVICE_TABLE(of, pmic_glink_of_match);
static struct platform_driver pmic_glink_driver = {
.probe = pmic_glink_probe,
- .remove = pmic_glink_remove,
+ .remove_new = pmic_glink_remove,
.driver = {
.name = "qcom_pmic_glink",
.of_match_table = pmic_glink_of_match,
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
index d05e0d6edf49..b78279e2f54c 100644
--- a/drivers/soc/qcom/pmic_glink_altmode.c
+++ b/drivers/soc/qcom/pmic_glink_altmode.c
@@ -160,7 +160,7 @@ static void pmic_glink_altmode_enable_dp(struct pmic_glink_altmode *altmode,
ret = typec_mux_set(port->typec_mux, &port->state);
if (ret)
- dev_err(altmode->dev, "failed to switch mux to DP\n");
+ dev_err(altmode->dev, "failed to switch mux to DP: %d\n", ret);
port->retimer_state.alt = &port->dp_alt;
port->retimer_state.data = &dp_data;
@@ -168,7 +168,7 @@ static void pmic_glink_altmode_enable_dp(struct pmic_glink_altmode *altmode,
ret = typec_retimer_set(port->typec_retimer, &port->retimer_state);
if (ret)
- dev_err(altmode->dev, "failed to setup retimer to DP\n");
+ dev_err(altmode->dev, "failed to setup retimer to DP: %d\n", ret);
}
static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode,
@@ -182,7 +182,7 @@ static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode,
ret = typec_mux_set(port->typec_mux, &port->state);
if (ret)
- dev_err(altmode->dev, "failed to switch mux to USB\n");
+ dev_err(altmode->dev, "failed to switch mux to USB: %d\n", ret);
port->retimer_state.alt = NULL;
port->retimer_state.data = NULL;
@@ -190,7 +190,7 @@ static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode,
ret = typec_retimer_set(port->typec_retimer, &port->retimer_state);
if (ret)
- dev_err(altmode->dev, "failed to setup retimer to USB\n");
+ dev_err(altmode->dev, "failed to setup retimer to USB: %d\n", ret);
}
static void pmic_glink_altmode_safe(struct pmic_glink_altmode *altmode,
@@ -204,7 +204,7 @@ static void pmic_glink_altmode_safe(struct pmic_glink_altmode *altmode,
ret = typec_mux_set(port->typec_mux, &port->state);
if (ret)
- dev_err(altmode->dev, "failed to switch mux to safe mode\n");
+ dev_err(altmode->dev, "failed to switch mux to safe mode: %d\n", ret);
port->retimer_state.alt = NULL;
port->retimer_state.data = NULL;
@@ -212,7 +212,7 @@ static void pmic_glink_altmode_safe(struct pmic_glink_altmode *altmode,
ret = typec_retimer_set(port->typec_retimer, &port->retimer_state);
if (ret)
- dev_err(altmode->dev, "failed to setup retimer to USB\n");
+ dev_err(altmode->dev, "failed to setup retimer to USB: %d\n", ret);
}
static void pmic_glink_altmode_worker(struct work_struct *work)
@@ -397,7 +397,7 @@ static void pmic_glink_altmode_enable_worker(struct work_struct *work)
ret = pmic_glink_altmode_request(altmode, ALTMODE_PAN_EN, 0);
if (ret)
- dev_err(altmode->dev, "failed to request altmode notifications\n");
+ dev_err(altmode->dev, "failed to request altmode notifications: %d\n", ret);
}
static void pmic_glink_altmode_pdr_notify(void *priv, int state)
@@ -444,6 +444,7 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
ret = fwnode_property_read_u32(fwnode, "reg", &port);
if (ret < 0) {
dev_err(dev, "missing reg property of %pOFn\n", fwnode);
+ fwnode_handle_put(fwnode);
return ret;
}
@@ -454,6 +455,7 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
if (altmode->ports[port].altmode) {
dev_err(dev, "multiple connector definition for port %u\n", port);
+ fwnode_handle_put(fwnode);
return -EINVAL;
}
@@ -465,48 +467,62 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
alt_port->bridge.funcs = &pmic_glink_altmode_bridge_funcs;
alt_port->bridge.of_node = to_of_node(fwnode);
alt_port->bridge.ops = DRM_BRIDGE_OP_HPD;
- alt_port->bridge.type = DRM_MODE_CONNECTOR_USB;
+ alt_port->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
ret = devm_drm_bridge_add(dev, &alt_port->bridge);
- if (ret)
+ if (ret) {
+ fwnode_handle_put(fwnode);
return ret;
+ }
alt_port->dp_alt.svid = USB_TYPEC_DP_SID;
alt_port->dp_alt.mode = USB_TYPEC_DP_MODE;
alt_port->dp_alt.active = 1;
alt_port->typec_mux = fwnode_typec_mux_get(fwnode);
- if (IS_ERR(alt_port->typec_mux))
+ if (IS_ERR(alt_port->typec_mux)) {
+ fwnode_handle_put(fwnode);
return dev_err_probe(dev, PTR_ERR(alt_port->typec_mux),
"failed to acquire mode-switch for port: %d\n",
port);
+ }
ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_mux,
alt_port->typec_mux);
- if (ret)
+ if (ret) {
+ fwnode_handle_put(fwnode);
return ret;
+ }
alt_port->typec_retimer = fwnode_typec_retimer_get(fwnode);
- if (IS_ERR(alt_port->typec_retimer))
+ if (IS_ERR(alt_port->typec_retimer)) {
+ fwnode_handle_put(fwnode);
return dev_err_probe(dev, PTR_ERR(alt_port->typec_retimer),
"failed to acquire retimer-switch for port: %d\n",
port);
+ }
ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_retimer,
alt_port->typec_retimer);
- if (ret)
+ if (ret) {
+ fwnode_handle_put(fwnode);
return ret;
+ }
alt_port->typec_switch = fwnode_typec_switch_get(fwnode);
- if (IS_ERR(alt_port->typec_switch))
+ if (IS_ERR(alt_port->typec_switch)) {
+ fwnode_handle_put(fwnode);
return dev_err_probe(dev, PTR_ERR(alt_port->typec_switch),
"failed to acquire orientation-switch for port: %d\n",
port);
+ }
ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_switch,
alt_port->typec_switch);
- if (ret)
+ if (ret) {
+ fwnode_handle_put(fwnode);
return ret;
+ }
}
altmode->client = devm_pmic_glink_register_client(dev,
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index ba788762835f..bdcf44b85b2f 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -199,7 +199,7 @@ u32 geni_se_get_qup_hw_version(struct geni_se *se)
return readl_relaxed(wrapper->base + QUP_HW_VER_REG);
}
-EXPORT_SYMBOL(geni_se_get_qup_hw_version);
+EXPORT_SYMBOL_GPL(geni_se_get_qup_hw_version);
static void geni_se_io_set_mode(void __iomem *base)
{
@@ -272,7 +272,7 @@ void geni_se_init(struct geni_se *se, u32 rx_wm, u32 rx_rfr)
val |= S_COMMON_GENI_S_IRQ_EN;
writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
}
-EXPORT_SYMBOL(geni_se_init);
+EXPORT_SYMBOL_GPL(geni_se_init);
static void geni_se_select_fifo_mode(struct geni_se *se)
{
@@ -364,7 +364,7 @@ void geni_se_select_mode(struct geni_se *se, enum geni_se_xfer_mode mode)
break;
}
}
-EXPORT_SYMBOL(geni_se_select_mode);
+EXPORT_SYMBOL_GPL(geni_se_select_mode);
/**
* DOC: Overview
@@ -481,7 +481,7 @@ void geni_se_config_packing(struct geni_se *se, int bpw, int pack_words,
if (pack_words || bpw == 32)
writel_relaxed(bpw / 16, se->base + SE_GENI_BYTE_GRAN);
}
-EXPORT_SYMBOL(geni_se_config_packing);
+EXPORT_SYMBOL_GPL(geni_se_config_packing);
static void geni_se_clks_off(struct geni_se *se)
{
@@ -512,7 +512,7 @@ int geni_se_resources_off(struct geni_se *se)
geni_se_clks_off(se);
return 0;
}
-EXPORT_SYMBOL(geni_se_resources_off);
+EXPORT_SYMBOL_GPL(geni_se_resources_off);
static int geni_se_clks_on(struct geni_se *se)
{
@@ -553,7 +553,7 @@ int geni_se_resources_on(struct geni_se *se)
return ret;
}
-EXPORT_SYMBOL(geni_se_resources_on);
+EXPORT_SYMBOL_GPL(geni_se_resources_on);
/**
* geni_se_clk_tbl_get() - Get the clock table to program DFS
@@ -594,7 +594,7 @@ int geni_se_clk_tbl_get(struct geni_se *se, unsigned long **tbl)
*tbl = se->clk_perf_tbl;
return se->num_clk_levels;
}
-EXPORT_SYMBOL(geni_se_clk_tbl_get);
+EXPORT_SYMBOL_GPL(geni_se_clk_tbl_get);
/**
* geni_se_clk_freq_match() - Get the matching or closest SE clock frequency
@@ -656,7 +656,7 @@ int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq,
return 0;
}
-EXPORT_SYMBOL(geni_se_clk_freq_match);
+EXPORT_SYMBOL_GPL(geni_se_clk_freq_match);
#define GENI_SE_DMA_DONE_EN BIT(0)
#define GENI_SE_DMA_EOT_EN BIT(1)
@@ -684,7 +684,7 @@ void geni_se_tx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len)
writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
writel(len, se->base + SE_DMA_TX_LEN);
}
-EXPORT_SYMBOL(geni_se_tx_init_dma);
+EXPORT_SYMBOL_GPL(geni_se_tx_init_dma);
/**
* geni_se_tx_dma_prep() - Prepare the serial engine for TX DMA transfer
@@ -712,7 +712,7 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
geni_se_tx_init_dma(se, *iova, len);
return 0;
}
-EXPORT_SYMBOL(geni_se_tx_dma_prep);
+EXPORT_SYMBOL_GPL(geni_se_tx_dma_prep);
/**
* geni_se_rx_init_dma() - Initiate RX DMA transfer on the serial engine
@@ -736,7 +736,7 @@ void geni_se_rx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len)
writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
writel(len, se->base + SE_DMA_RX_LEN);
}
-EXPORT_SYMBOL(geni_se_rx_init_dma);
+EXPORT_SYMBOL_GPL(geni_se_rx_init_dma);
/**
* geni_se_rx_dma_prep() - Prepare the serial engine for RX DMA transfer
@@ -764,7 +764,7 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
geni_se_rx_init_dma(se, *iova, len);
return 0;
}
-EXPORT_SYMBOL(geni_se_rx_dma_prep);
+EXPORT_SYMBOL_GPL(geni_se_rx_dma_prep);
/**
* geni_se_tx_dma_unprep() - Unprepare the serial engine after TX DMA transfer
@@ -781,7 +781,7 @@ void geni_se_tx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
if (!dma_mapping_error(wrapper->dev, iova))
dma_unmap_single(wrapper->dev, iova, len, DMA_TO_DEVICE);
}
-EXPORT_SYMBOL(geni_se_tx_dma_unprep);
+EXPORT_SYMBOL_GPL(geni_se_tx_dma_unprep);
/**
* geni_se_rx_dma_unprep() - Unprepare the serial engine after RX DMA transfer
@@ -798,7 +798,7 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
if (!dma_mapping_error(wrapper->dev, iova))
dma_unmap_single(wrapper->dev, iova, len, DMA_FROM_DEVICE);
}
-EXPORT_SYMBOL(geni_se_rx_dma_unprep);
+EXPORT_SYMBOL_GPL(geni_se_rx_dma_unprep);
int geni_icc_get(struct geni_se *se, const char *icc_ddr)
{
@@ -827,7 +827,7 @@ err:
return err;
}
-EXPORT_SYMBOL(geni_icc_get);
+EXPORT_SYMBOL_GPL(geni_icc_get);
int geni_icc_set_bw(struct geni_se *se)
{
@@ -845,7 +845,7 @@ int geni_icc_set_bw(struct geni_se *se)
return 0;
}
-EXPORT_SYMBOL(geni_icc_set_bw);
+EXPORT_SYMBOL_GPL(geni_icc_set_bw);
void geni_icc_set_tag(struct geni_se *se, u32 tag)
{
@@ -854,7 +854,7 @@ void geni_icc_set_tag(struct geni_se *se, u32 tag)
for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++)
icc_set_tag(se->icc_paths[i].path, tag);
}
-EXPORT_SYMBOL(geni_icc_set_tag);
+EXPORT_SYMBOL_GPL(geni_icc_set_tag);
/* To do: Replace this by icc_bulk_enable once it's implemented in ICC core */
int geni_icc_enable(struct geni_se *se)
@@ -872,7 +872,7 @@ int geni_icc_enable(struct geni_se *se)
return 0;
}
-EXPORT_SYMBOL(geni_icc_enable);
+EXPORT_SYMBOL_GPL(geni_icc_enable);
int geni_icc_disable(struct geni_se *se)
{
@@ -889,7 +889,7 @@ int geni_icc_disable(struct geni_se *se)
return 0;
}
-EXPORT_SYMBOL(geni_icc_disable);
+EXPORT_SYMBOL_GPL(geni_icc_disable);
static int geni_se_probe(struct platform_device *pdev)
{
diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
index 77f0cf126629..aff0cfb71482 100644
--- a/drivers/soc/qcom/qcom_aoss.c
+++ b/drivers/soc/qcom/qcom_aoss.c
@@ -260,7 +260,7 @@ int qmp_send(struct qmp *qmp, const char *fmt, ...)
return ret;
}
-EXPORT_SYMBOL(qmp_send);
+EXPORT_SYMBOL_GPL(qmp_send);
static int qmp_qdss_clk_prepare(struct clk_hw *hw)
{
@@ -458,7 +458,7 @@ struct qmp *qmp_get(struct device *dev)
}
return qmp;
}
-EXPORT_SYMBOL(qmp_get);
+EXPORT_SYMBOL_GPL(qmp_get);
/**
* qmp_put() - release a qmp handle
@@ -473,7 +473,7 @@ void qmp_put(struct qmp *qmp)
if (!IS_ERR_OR_NULL(qmp))
put_device(qmp->dev);
}
-EXPORT_SYMBOL(qmp_put);
+EXPORT_SYMBOL_GPL(qmp_put);
static int qmp_probe(struct platform_device *pdev)
{
@@ -533,7 +533,7 @@ err_free_mbox:
return ret;
}
-static int qmp_remove(struct platform_device *pdev)
+static void qmp_remove(struct platform_device *pdev)
{
struct qmp *qmp = platform_get_drvdata(pdev);
@@ -542,8 +542,6 @@ static int qmp_remove(struct platform_device *pdev)
qmp_close(qmp);
mbox_free_channel(qmp->mbox_chan);
-
- return 0;
}
static const struct of_device_id qmp_dt_match[] = {
@@ -565,7 +563,7 @@ static struct platform_driver qmp_driver = {
.suppress_bind_attrs = true,
},
.probe = qmp_probe,
- .remove = qmp_remove,
+ .remove_new = qmp_remove,
};
module_platform_driver(qmp_driver);
diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c
index df7907a83aa8..f04b9a324ea9 100644
--- a/drivers/soc/qcom/qcom_gsbi.c
+++ b/drivers/soc/qcom/qcom_gsbi.c
@@ -212,13 +212,11 @@ static int gsbi_probe(struct platform_device *pdev)
return of_platform_populate(node, NULL, NULL, &pdev->dev);
}
-static int gsbi_remove(struct platform_device *pdev)
+static void gsbi_remove(struct platform_device *pdev)
{
struct gsbi_info *gsbi = platform_get_drvdata(pdev);
clk_disable_unprepare(gsbi->hclk);
-
- return 0;
}
static const struct of_device_id gsbi_dt_match[] = {
@@ -234,7 +232,7 @@ static struct platform_driver gsbi_driver = {
.of_match_table = gsbi_dt_match,
},
.probe = gsbi_probe,
- .remove = gsbi_remove,
+ .remove_new = gsbi_remove,
};
module_platform_driver(gsbi_driver);
diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c
index c207bb96c523..0216fc24f2ca 100644
--- a/drivers/soc/qcom/qcom_stats.c
+++ b/drivers/soc/qcom/qcom_stats.c
@@ -216,13 +216,11 @@ static int qcom_stats_probe(struct platform_device *pdev)
return 0;
}
-static int qcom_stats_remove(struct platform_device *pdev)
+static void qcom_stats_remove(struct platform_device *pdev)
{
struct dentry *root = platform_get_drvdata(pdev);
debugfs_remove_recursive(root);
-
- return 0;
}
static const struct stats_config rpm_data = {
@@ -272,7 +270,7 @@ MODULE_DEVICE_TABLE(of, qcom_stats_table);
static struct platform_driver qcom_stats = {
.probe = qcom_stats_probe,
- .remove = qcom_stats_remove,
+ .remove_new = qcom_stats_remove,
.driver = {
.name = "qcom_stats",
.of_match_table = qcom_stats_table,
diff --git a/drivers/soc/qcom/qmi_encdec.c b/drivers/soc/qcom/qmi_encdec.c
index 5c7161b18b72..bb09eff85cff 100644
--- a/drivers/soc/qcom/qmi_encdec.c
+++ b/drivers/soc/qcom/qmi_encdec.c
@@ -754,7 +754,7 @@ void *qmi_encode_message(int type, unsigned int msg_id, size_t *len,
return msg;
}
-EXPORT_SYMBOL(qmi_encode_message);
+EXPORT_SYMBOL_GPL(qmi_encode_message);
/**
* qmi_decode_message() - Decode QMI encoded message to C structure
@@ -778,7 +778,7 @@ int qmi_decode_message(const void *buf, size_t len,
return qmi_decode(ei, c_struct, buf + sizeof(struct qmi_header),
len - sizeof(struct qmi_header), 1);
}
-EXPORT_SYMBOL(qmi_decode_message);
+EXPORT_SYMBOL_GPL(qmi_decode_message);
/* Common header in all QMI responses */
const struct qmi_elem_info qmi_response_type_v01_ei[] = {
@@ -810,7 +810,7 @@ const struct qmi_elem_info qmi_response_type_v01_ei[] = {
.ei_array = NULL,
},
};
-EXPORT_SYMBOL(qmi_response_type_v01_ei);
+EXPORT_SYMBOL_GPL(qmi_response_type_v01_ei);
MODULE_DESCRIPTION("QMI encoder/decoder helper");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/qmi_interface.c b/drivers/soc/qcom/qmi_interface.c
index 78d7361fdcf2..bb98b06e87f8 100644
--- a/drivers/soc/qcom/qmi_interface.c
+++ b/drivers/soc/qcom/qmi_interface.c
@@ -223,7 +223,7 @@ int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service,
return 0;
}
-EXPORT_SYMBOL(qmi_add_lookup);
+EXPORT_SYMBOL_GPL(qmi_add_lookup);
static void qmi_send_new_server(struct qmi_handle *qmi, struct qmi_service *svc)
{
@@ -287,7 +287,7 @@ int qmi_add_server(struct qmi_handle *qmi, unsigned int service,
return 0;
}
-EXPORT_SYMBOL(qmi_add_server);
+EXPORT_SYMBOL_GPL(qmi_add_server);
/**
* qmi_txn_init() - allocate transaction id within the given QMI handle
@@ -328,7 +328,7 @@ int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn,
return ret;
}
-EXPORT_SYMBOL(qmi_txn_init);
+EXPORT_SYMBOL_GPL(qmi_txn_init);
/**
* qmi_txn_wait() - wait for a response on a transaction
@@ -359,7 +359,7 @@ int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout)
else
return txn->result;
}
-EXPORT_SYMBOL(qmi_txn_wait);
+EXPORT_SYMBOL_GPL(qmi_txn_wait);
/**
* qmi_txn_cancel() - cancel an ongoing transaction
@@ -375,7 +375,7 @@ void qmi_txn_cancel(struct qmi_txn *txn)
mutex_unlock(&txn->lock);
mutex_unlock(&qmi->txn_lock);
}
-EXPORT_SYMBOL(qmi_txn_cancel);
+EXPORT_SYMBOL_GPL(qmi_txn_cancel);
/**
* qmi_invoke_handler() - find and invoke a handler for a message
@@ -676,7 +676,7 @@ err_free_recv_buf:
return ret;
}
-EXPORT_SYMBOL(qmi_handle_init);
+EXPORT_SYMBOL_GPL(qmi_handle_init);
/**
* qmi_handle_release() - release the QMI client handle
@@ -717,7 +717,7 @@ void qmi_handle_release(struct qmi_handle *qmi)
kfree(svc);
}
}
-EXPORT_SYMBOL(qmi_handle_release);
+EXPORT_SYMBOL_GPL(qmi_handle_release);
/**
* qmi_send_message() - send a QMI message
@@ -796,7 +796,7 @@ ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
return qmi_send_message(qmi, sq, txn, QMI_REQUEST, msg_id, len, ei,
c_struct);
}
-EXPORT_SYMBOL(qmi_send_request);
+EXPORT_SYMBOL_GPL(qmi_send_request);
/**
* qmi_send_response() - send a response QMI message
@@ -817,7 +817,7 @@ ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
return qmi_send_message(qmi, sq, txn, QMI_RESPONSE, msg_id, len, ei,
c_struct);
}
-EXPORT_SYMBOL(qmi_send_response);
+EXPORT_SYMBOL_GPL(qmi_send_response);
/**
* qmi_send_indication() - send an indication QMI message
@@ -851,4 +851,4 @@ ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
return rval;
}
-EXPORT_SYMBOL(qmi_send_indication);
+EXPORT_SYMBOL_GPL(qmi_send_indication);
diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c
index f83811f51175..df850d073102 100644
--- a/drivers/soc/qcom/rmtfs_mem.c
+++ b/drivers/soc/qcom/rmtfs_mem.c
@@ -200,6 +200,15 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
rmtfs_mem->client_id = client_id;
rmtfs_mem->size = rmem->size;
+ /*
+ * If requested, discard the first and last 4k block in order to ensure
+ * that the rmtfs region isn't adjacent to other protected regions.
+ */
+ if (of_property_read_bool(node, "qcom,use-guard-pages")) {
+ rmtfs_mem->addr += SZ_4K;
+ rmtfs_mem->size -= 2 * SZ_4K;
+ }
+
device_initialize(&rmtfs_mem->dev);
rmtfs_mem->dev.parent = &pdev->dev;
rmtfs_mem->dev.groups = qcom_rmtfs_mem_groups;
@@ -281,7 +290,7 @@ put_device:
return ret;
}
-static int qcom_rmtfs_mem_remove(struct platform_device *pdev)
+static void qcom_rmtfs_mem_remove(struct platform_device *pdev)
{
struct qcom_rmtfs_mem *rmtfs_mem = dev_get_drvdata(&pdev->dev);
struct qcom_scm_vmperm perm;
@@ -296,8 +305,6 @@ static int qcom_rmtfs_mem_remove(struct platform_device *pdev)
cdev_device_del(&rmtfs_mem->cdev, &rmtfs_mem->dev);
put_device(&rmtfs_mem->dev);
-
- return 0;
}
static const struct of_device_id qcom_rmtfs_mem_of_match[] = {
@@ -308,7 +315,7 @@ MODULE_DEVICE_TABLE(of, qcom_rmtfs_mem_of_match);
static struct platform_driver qcom_rmtfs_mem_driver = {
.probe = qcom_rmtfs_mem_probe,
- .remove = qcom_rmtfs_mem_remove,
+ .remove_new = qcom_rmtfs_mem_remove,
.driver = {
.name = "qcom_rmtfs_mem",
.of_match_table = qcom_rmtfs_mem_of_match,
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index 08e09642d7f5..9f26d7f9b9dc 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -239,7 +239,7 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state,
return __rpmh_write(dev, state, rpm_msg);
}
-EXPORT_SYMBOL(rpmh_write_async);
+EXPORT_SYMBOL_GPL(rpmh_write_async);
/**
* rpmh_write: Write a set of RPMH commands and block until response
@@ -270,7 +270,7 @@ int rpmh_write(const struct device *dev, enum rpmh_state state,
WARN_ON(!ret);
return (ret > 0) ? 0 : -ETIMEDOUT;
}
-EXPORT_SYMBOL(rpmh_write);
+EXPORT_SYMBOL_GPL(rpmh_write);
static void cache_batch(struct rpmh_ctrlr *ctrlr, struct batch_cache_req *req)
{
@@ -395,7 +395,7 @@ exit:
return ret;
}
-EXPORT_SYMBOL(rpmh_write_batch);
+EXPORT_SYMBOL_GPL(rpmh_write_batch);
static int is_req_valid(struct cache_req *req)
{
@@ -500,4 +500,4 @@ void rpmh_invalidate(const struct device *dev)
ctrlr->dirty = true;
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
}
-EXPORT_SYMBOL(rpmh_invalidate);
+EXPORT_SYMBOL_GPL(rpmh_invalidate);
diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c
index f9fd6177118c..b7056aed4c7d 100644
--- a/drivers/soc/qcom/smd-rpm.c
+++ b/drivers/soc/qcom/smd-rpm.c
@@ -142,7 +142,7 @@ out:
mutex_unlock(&rpm->lock);
return ret;
}
-EXPORT_SYMBOL(qcom_rpm_smd_write);
+EXPORT_SYMBOL_GPL(qcom_rpm_smd_write);
static int qcom_smd_rpm_callback(struct rpmsg_device *rpdev,
void *data,
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index d4a89d2bb43b..690afc9a12f4 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -285,7 +285,7 @@ struct qcom_smem {
struct smem_partition partitions[SMEM_HOST_COUNT];
unsigned num_regions;
- struct smem_region regions[];
+ struct smem_region regions[] __counted_by(num_regions);
};
static void *
@@ -368,7 +368,7 @@ bool qcom_smem_is_available(void)
{
return !!__smem;
}
-EXPORT_SYMBOL(qcom_smem_is_available);
+EXPORT_SYMBOL_GPL(qcom_smem_is_available);
static int qcom_smem_alloc_private(struct qcom_smem *smem,
struct smem_partition *part,
@@ -1187,14 +1187,12 @@ static int qcom_smem_probe(struct platform_device *pdev)
return 0;
}
-static int qcom_smem_remove(struct platform_device *pdev)
+static void qcom_smem_remove(struct platform_device *pdev)
{
platform_device_unregister(__smem->socinfo);
hwspin_lock_free(__smem->hwlock);
__smem = NULL;
-
- return 0;
}
static const struct of_device_id qcom_smem_of_match[] = {
@@ -1205,7 +1203,7 @@ MODULE_DEVICE_TABLE(of, qcom_smem_of_match);
static struct platform_driver qcom_smem_driver = {
.probe = qcom_smem_probe,
- .remove = qcom_smem_remove,
+ .remove_new = qcom_smem_remove,
.driver = {
.name = "qcom-smem",
.of_match_table = qcom_smem_of_match,
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c
index e9c8030d50ee..914b2246148f 100644
--- a/drivers/soc/qcom/smp2p.c
+++ b/drivers/soc/qcom/smp2p.c
@@ -660,7 +660,7 @@ report_read_failure:
return -EINVAL;
}
-static int qcom_smp2p_remove(struct platform_device *pdev)
+static void qcom_smp2p_remove(struct platform_device *pdev)
{
struct qcom_smp2p *smp2p = platform_get_drvdata(pdev);
struct smp2p_entry *entry;
@@ -676,8 +676,6 @@ static int qcom_smp2p_remove(struct platform_device *pdev)
mbox_free_channel(smp2p->mbox_chan);
smp2p->out->valid_entries = 0;
-
- return 0;
}
static const struct of_device_id qcom_smp2p_of_match[] = {
@@ -688,7 +686,7 @@ MODULE_DEVICE_TABLE(of, qcom_smp2p_of_match);
static struct platform_driver qcom_smp2p_driver = {
.probe = qcom_smp2p_probe,
- .remove = qcom_smp2p_remove,
+ .remove_new = qcom_smp2p_remove,
.driver = {
.name = "qcom_smp2p",
.of_match_table = qcom_smp2p_of_match,
diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c
index c58cfff64856..e7c7e9a640a6 100644
--- a/drivers/soc/qcom/smsm.c
+++ b/drivers/soc/qcom/smsm.c
@@ -613,7 +613,7 @@ out_put:
return ret;
}
-static int qcom_smsm_remove(struct platform_device *pdev)
+static void qcom_smsm_remove(struct platform_device *pdev)
{
struct qcom_smsm *smsm = platform_get_drvdata(pdev);
unsigned id;
@@ -623,8 +623,6 @@ static int qcom_smsm_remove(struct platform_device *pdev)
irq_domain_remove(smsm->entries[id].domain);
qcom_smem_state_unregister(smsm->state);
-
- return 0;
}
static const struct of_device_id qcom_smsm_of_match[] = {
@@ -635,7 +633,7 @@ MODULE_DEVICE_TABLE(of, qcom_smsm_of_match);
static struct platform_driver qcom_smsm_driver = {
.probe = qcom_smsm_probe,
- .remove = qcom_smsm_remove,
+ .remove_new = qcom_smsm_remove,
.driver = {
.name = "qcom-smsm",
.of_match_table = qcom_smsm_of_match,
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 497cfb720fcb..51e05bec5bfc 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -117,6 +117,12 @@ static const char *const pmic_models[] = {
[55] = "PM2250",
[58] = "PM8450",
[65] = "PM8010",
+ [69] = "PM8550VS",
+ [70] = "PM8550VE",
+ [71] = "PM8550B",
+ [72] = "PMR735D",
+ [73] = "PM8550",
+ [74] = "PMK8550",
};
struct socinfo_params {
@@ -349,6 +355,7 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(SDA439) },
{ qcom_board_id(SDA429) },
{ qcom_board_id(SM7150) },
+ { qcom_board_id(SM7150P) },
{ qcom_board_id(IPQ8070) },
{ qcom_board_id(IPQ8071) },
{ qcom_board_id(QM215) },
@@ -359,6 +366,9 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(SM6125) },
{ qcom_board_id(IPQ8070A) },
{ qcom_board_id(IPQ8071A) },
+ { qcom_board_id(IPQ8172) },
+ { qcom_board_id(IPQ8173) },
+ { qcom_board_id(IPQ8174) },
{ qcom_board_id(IPQ6018) },
{ qcom_board_id(IPQ6028) },
{ qcom_board_id(SDM429W) },
@@ -389,6 +399,7 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id_named(SM8450_3, "SM8450") },
{ qcom_board_id(SC7280) },
{ qcom_board_id(SC7180P) },
+ { qcom_board_id(QCM6490) },
{ qcom_board_id(IPQ5000) },
{ qcom_board_id(IPQ0509) },
{ qcom_board_id(IPQ0518) },
@@ -776,20 +787,18 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
return 0;
}
-static int qcom_socinfo_remove(struct platform_device *pdev)
+static void qcom_socinfo_remove(struct platform_device *pdev)
{
struct qcom_socinfo *qs = platform_get_drvdata(pdev);
soc_device_unregister(qs->soc_dev);
socinfo_debugfs_exit(qs);
-
- return 0;
}
static struct platform_driver qcom_socinfo_driver = {
.probe = qcom_socinfo_probe,
- .remove = qcom_socinfo_remove,
+ .remove_new = qcom_socinfo_remove,
.driver = {
.name = "qcom-socinfo",
},
diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c
index ad9942412c58..148bcbac332d 100644
--- a/drivers/soc/qcom/wcnss_ctrl.c
+++ b/drivers/soc/qcom/wcnss_ctrl.c
@@ -287,7 +287,7 @@ struct rpmsg_endpoint *qcom_wcnss_open_channel(void *wcnss, const char *name, rp
return rpmsg_create_ept(_wcnss->channel->rpdev, cb, priv, chinfo);
}
-EXPORT_SYMBOL(qcom_wcnss_open_channel);
+EXPORT_SYMBOL_GPL(qcom_wcnss_open_channel);
static void wcnss_async_probe(struct work_struct *work)
{
@@ -355,7 +355,6 @@ static struct rpmsg_driver wcnss_ctrl_driver = {
.callback = wcnss_ctrl_smd_callback,
.drv = {
.name = "qcom_wcnss_ctrl",
- .owner = THIS_MODULE,
.of_match_table = wcnss_ctrl_of_match,
},
};
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index acc812e490d0..0071864c2111 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -319,6 +319,12 @@ config ARCH_R9A07G054
help
This enables support for the Renesas RZ/V2L SoC variants.
+config ARCH_R9A08G045
+ bool "ARM64 Platform support for RZ/G3S"
+ select ARCH_RZG2L
+ help
+ This enables support for the Renesas RZ/G3S SoC variants.
+
config ARCH_R9A09G011
bool "ARM64 Platform support for RZ/V2M"
select PM
@@ -353,109 +359,4 @@ config PWC_RZV2M
config RST_RCAR
bool "Reset Controller support for R-Car" if COMPILE_TEST
-config SYSC_RCAR
- bool "System Controller support for R-Car" if COMPILE_TEST
-
-config SYSC_RCAR_GEN4
- bool "System Controller support for R-Car Gen4" if COMPILE_TEST
-
-config SYSC_R8A77995
- bool "System Controller support for R-Car D3" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A7794
- bool "System Controller support for R-Car E2" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A77990
- bool "System Controller support for R-Car E3" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A7779
- bool "System Controller support for R-Car H1" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A7790
- bool "System Controller support for R-Car H2" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A7795
- bool "System Controller support for R-Car H3" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A7791
- bool "System Controller support for R-Car M2-W/N" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A77965
- bool "System Controller support for R-Car M3-N" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A77960
- bool "System Controller support for R-Car M3-W" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A77961
- bool "System Controller support for R-Car M3-W+" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A779F0
- bool "System Controller support for R-Car S4-8" if COMPILE_TEST
- select SYSC_RCAR_GEN4
-
-config SYSC_R8A7792
- bool "System Controller support for R-Car V2H" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A77980
- bool "System Controller support for R-Car V3H" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A77970
- bool "System Controller support for R-Car V3M" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A779A0
- bool "System Controller support for R-Car V3U" if COMPILE_TEST
- select SYSC_RCAR_GEN4
-
-config SYSC_R8A779G0
- bool "System Controller support for R-Car V4H" if COMPILE_TEST
- select SYSC_RCAR_GEN4
-
-config SYSC_RMOBILE
- bool "System Controller support for R-Mobile" if COMPILE_TEST
-
-config SYSC_R8A77470
- bool "System Controller support for RZ/G1C" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A7745
- bool "System Controller support for RZ/G1E" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A7742
- bool "System Controller support for RZ/G1H" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A7743
- bool "System Controller support for RZ/G1M" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A774C0
- bool "System Controller support for RZ/G2E" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A774E1
- bool "System Controller support for RZ/G2H" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A774A1
- bool "System Controller support for RZ/G2M" if COMPILE_TEST
- select SYSC_RCAR
-
-config SYSC_R8A774B1
- bool "System Controller support for RZ/G2N" if COMPILE_TEST
- select SYSC_RCAR
-
endif # SOC_RENESAS
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
index 42af7c09f743..c732d4a5b26a 100644
--- a/drivers/soc/renesas/renesas-soc.c
+++ b/drivers/soc/renesas/renesas-soc.c
@@ -12,7 +12,6 @@
#include <linux/string.h>
#include <linux/sys_soc.h>
-
struct renesas_family {
const char name[16];
u32 reg; /* CCCR or PRR, if not in DT */
@@ -72,6 +71,10 @@ static const struct renesas_family fam_rzg2ul __initconst __maybe_unused = {
.name = "RZ/G2UL",
};
+static const struct renesas_family fam_rzg3s __initconst __maybe_unused = {
+ .name = "RZ/G3S",
+};
+
static const struct renesas_family fam_rzv2l __initconst __maybe_unused = {
.name = "RZ/V2L",
};
@@ -85,7 +88,6 @@ static const struct renesas_family fam_shmobile __initconst __maybe_unused = {
.reg = 0xe600101c, /* CCCR (Common Chip Code Register) */
};
-
struct renesas_soc {
const struct renesas_family *family;
u32 id;
@@ -170,6 +172,11 @@ static const struct renesas_soc soc_rz_g2ul __initconst __maybe_unused = {
.id = 0x8450447,
};
+static const struct renesas_soc soc_rz_g3s __initconst __maybe_unused = {
+ .family = &fam_rzg3s,
+ .id = 0x85e0447,
+};
+
static const struct renesas_soc soc_rz_v2l __initconst __maybe_unused = {
.family = &fam_rzv2l,
.id = 0x8447447,
@@ -386,6 +393,9 @@ static const struct of_device_id renesas_socs[] __initconst __maybe_unused = {
#ifdef CONFIG_ARCH_R9A07G054
{ .compatible = "renesas,r9a07g054", .data = &soc_rz_v2l },
#endif
+#ifdef CONFIG_ARCH_R9A08G045
+ { .compatible = "renesas,r9a08g045", .data = &soc_rz_g3s },
+#endif
#ifdef CONFIG_ARCH_R9A09G011
{ .compatible = "renesas,r9a09g011", .data = &soc_rz_v2m },
#endif
@@ -429,6 +439,7 @@ static const struct of_device_id renesas_ids[] __initconst = {
{ .compatible = "renesas,r9a07g043-sysc", .data = &id_rzg2l },
{ .compatible = "renesas,r9a07g044-sysc", .data = &id_rzg2l },
{ .compatible = "renesas,r9a07g054-sysc", .data = &id_rzg2l },
+ { .compatible = "renesas,r9a08g045-sysc", .data = &id_rzg2l },
{ .compatible = "renesas,r9a09g011-sys", .data = &id_rzv2m },
{ .compatible = "renesas,prr", .data = &id_prr },
{ /* sentinel */ }
diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
index aff2f7e95237..785f60c6f3ad 100644
--- a/drivers/soc/rockchip/Kconfig
+++ b/drivers/soc/rockchip/Kconfig
@@ -22,18 +22,6 @@ config ROCKCHIP_IODOMAIN
necessary for the io domain setting of the SoC to match the
voltage supplied by the regulators.
-config ROCKCHIP_PM_DOMAINS
- bool "Rockchip generic power domain"
- depends on PM
- select PM_GENERIC_DOMAINS
- help
- Say y here to enable power domain support.
- In order to meet high performance and low power requirements, a power
- management unit is designed or saving power when RK3288 in low power
- mode. The RK3288 PMU is dedicated for managing the power of the whole chip.
-
- If unsure, say N.
-
config ROCKCHIP_DTPM
tristate "Rockchip DTPM hierarchy"
depends on DTPM && m
diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
index 6619256c2d11..18f809c160a7 100644
--- a/drivers/soc/rockchip/io-domain.c
+++ b/drivers/soc/rockchip/io-domain.c
@@ -687,7 +687,7 @@ unreg_notify:
return ret;
}
-static int rockchip_iodomain_remove(struct platform_device *pdev)
+static void rockchip_iodomain_remove(struct platform_device *pdev)
{
struct rockchip_iodomain *iod = platform_get_drvdata(pdev);
int i;
@@ -699,13 +699,11 @@ static int rockchip_iodomain_remove(struct platform_device *pdev)
regulator_unregister_notifier(io_supply->reg,
&io_supply->nb);
}
-
- return 0;
}
static struct platform_driver rockchip_iodomain_driver = {
.probe = rockchip_iodomain_probe,
- .remove = rockchip_iodomain_remove,
+ .remove_new = rockchip_iodomain_remove,
.driver = {
.name = "rockchip-iodomain",
.of_match_table = rockchip_iodomain_match,
diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 7a8f291e7704..27ec99af77e3 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -48,10 +48,6 @@ config EXYNOS_PMU_ARM_DRIVERS
bool "Exynos PMU ARMv7-specific driver extensions" if COMPILE_TEST
depends on EXYNOS_PMU
-config EXYNOS_PM_DOMAINS
- bool "Exynos PM domains" if COMPILE_TEST
- depends on (ARCH_EXYNOS && PM_GENERIC_DOMAINS) || COMPILE_TEST
-
config SAMSUNG_PM_CHECK
bool "S3C2410 PM Suspend Memory CRC"
depends on PM && (ARCH_S3C64XX || ARCH_S5PV210)
diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
index 7ba45c4aff97..3fd0f2b84dd3 100644
--- a/drivers/soc/samsung/exynos-chipid.c
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -158,13 +158,11 @@ err:
return ret;
}
-static int exynos_chipid_remove(struct platform_device *pdev)
+static void exynos_chipid_remove(struct platform_device *pdev)
{
struct soc_device *soc_dev = platform_get_drvdata(pdev);
soc_device_unregister(soc_dev);
-
- return 0;
}
static const struct exynos_chipid_variant exynos4210_chipid_drv_data = {
@@ -197,7 +195,7 @@ static struct platform_driver exynos_chipid_driver = {
.of_match_table = exynos_chipid_of_device_ids,
},
.probe = exynos_chipid_probe,
- .remove = exynos_chipid_remove,
+ .remove_new = exynos_chipid_remove,
};
module_platform_driver(exynos_chipid_driver);
diff --git a/drivers/soc/sifive/Kconfig b/drivers/soc/sifive/Kconfig
index e86870be34c9..139884addc41 100644
--- a/drivers/soc/sifive/Kconfig
+++ b/drivers/soc/sifive/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-if SOC_SIFIVE || SOC_STARFIVE
+if ARCH_SIFIVE || ARCH_STARFIVE
config SIFIVE_CCACHE
bool "Sifive Composable Cache controller"
diff --git a/drivers/soc/sunxi/Kconfig b/drivers/soc/sunxi/Kconfig
index c5070914fc6a..8aecbc9b1976 100644
--- a/drivers/soc/sunxi/Kconfig
+++ b/drivers/soc/sunxi/Kconfig
@@ -19,12 +19,3 @@ config SUNXI_SRAM
Say y here to enable the SRAM controller support. This
device is responsible on mapping the SRAM in the sunXi SoCs
whether to the CPU/DMA, or to the devices.
-
-config SUN20I_PPU
- bool "Allwinner D1 PPU power domain driver"
- depends on ARCH_SUNXI || COMPILE_TEST
- depends on PM
- select PM_GENERIC_DOMAINS
- help
- Say y to enable the PPU power domain driver. This saves power
- when certain peripherals, such as the video engine, are idle.
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index 6f3098822969..f16beeabaa92 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -152,11 +152,6 @@ config SOC_TEGRA_PMC
select PM_GENERIC_DOMAINS
select REGMAP
-config SOC_TEGRA_POWERGATE_BPMP
- def_bool y
- depends on PM_GENERIC_DOMAINS
- depends on TEGRA_BPMP
-
config SOC_TEGRA20_VOLTAGE_COUPLER
bool "Voltage scaling support for Tegra20 SoCs"
depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c
index cf6886f362d3..9cbc562ae7d3 100644
--- a/drivers/soc/tegra/cbb/tegra194-cbb.c
+++ b/drivers/soc/tegra/cbb/tegra194-cbb.c
@@ -2293,7 +2293,7 @@ static int tegra194_cbb_probe(struct platform_device *pdev)
return tegra_cbb_register(&cbb->base);
}
-static int tegra194_cbb_remove(struct platform_device *pdev)
+static void tegra194_cbb_remove(struct platform_device *pdev)
{
struct tegra194_cbb *cbb = platform_get_drvdata(pdev);
struct tegra_cbb *noc, *tmp;
@@ -2311,8 +2311,6 @@ static int tegra194_cbb_remove(struct platform_device *pdev)
}
spin_unlock_irqrestore(&cbb_lock, flags);
-
- return 0;
}
static int __maybe_unused tegra194_cbb_resume_noirq(struct device *dev)
@@ -2332,7 +2330,7 @@ static const struct dev_pm_ops tegra194_cbb_pm = {
static struct platform_driver tegra194_cbb_driver = {
.probe = tegra194_cbb_probe,
- .remove = tegra194_cbb_remove,
+ .remove_new = tegra194_cbb_remove,
.driver = {
.name = "tegra194-cbb",
.of_match_table = of_match_ptr(tegra194_cbb_match),
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 162f52456f65..f432aa022ace 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -1393,13 +1393,6 @@ tegra_pmc_core_pd_set_performance_state(struct generic_pm_domain *genpd,
return 0;
}
-static unsigned int
-tegra_pmc_core_pd_opp_to_performance_state(struct generic_pm_domain *genpd,
- struct dev_pm_opp *opp)
-{
- return dev_pm_opp_get_level(opp);
-}
-
static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
{
struct generic_pm_domain *genpd;
@@ -1412,7 +1405,6 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
genpd->name = "core";
genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state;
- genpd->opp_to_performance_state = tegra_pmc_core_pd_opp_to_performance_state;
err = devm_pm_opp_set_regulators(pmc->dev, rname);
if (err)
diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index 2cae17b65fd9..1a93001c9e36 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -50,18 +50,6 @@ config WKUP_M3_IPC
to communicate and use the Wakeup M3 for PM features like suspend
resume and boots it using wkup_m3_rproc driver.
-config TI_SCI_PM_DOMAINS
- tristate "TI SCI PM Domains Driver"
- depends on TI_SCI_PROTOCOL
- depends on PM_GENERIC_DOMAINS
- help
- Generic power domain implementation for TI device implementing
- the TI SCI protocol.
-
- To compile this as a module, choose M here. The module will be
- called ti_sci_pm_domains. Note this is needed early in boot before
- rootfs may be available.
-
config TI_K3_RINGACC
tristate "K3 Ring accelerator Sub System"
depends on ARCH_K3 || COMPILE_TEST
diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c
index 148f54d9691d..fd4251d75935 100644
--- a/drivers/soc/ti/k3-ringacc.c
+++ b/drivers/soc/ti/k3-ringacc.c
@@ -1551,19 +1551,18 @@ static int k3_ringacc_probe(struct platform_device *pdev)
return 0;
}
-static int k3_ringacc_remove(struct platform_device *pdev)
+static void k3_ringacc_remove(struct platform_device *pdev)
{
struct k3_ringacc *ringacc = dev_get_drvdata(&pdev->dev);
mutex_lock(&k3_ringacc_list_lock);
list_del(&ringacc->list);
mutex_unlock(&k3_ringacc_list_lock);
- return 0;
}
static struct platform_driver k3_ringacc_driver = {
.probe = k3_ringacc_probe,
- .remove = k3_ringacc_remove,
+ .remove_new = k3_ringacc_remove,
.driver = {
.name = "k3-ringacc",
.of_match_table = k3_ringacc_of_match,
diff --git a/drivers/soc/ti/k3-socinfo.c b/drivers/soc/ti/k3-socinfo.c
index 6ea9b8c7d335..7fc3548e084c 100644
--- a/drivers/soc/ti/k3-socinfo.c
+++ b/drivers/soc/ti/k3-socinfo.c
@@ -20,7 +20,7 @@
* 31-28 VARIANT Device variant
* 27-12 PARTNO Part number
* 11-1 MFG Indicates TI as manufacturer (0x17)
- * 1 Always 1
+ * 0 Always 1
*/
#define CTRLMMR_WKUP_JTAGID_VARIANT_SHIFT (28)
#define CTRLMMR_WKUP_JTAGID_VARIANT_MASK GENMASK(31, 28)
@@ -60,7 +60,7 @@ k3_chipinfo_partno_to_names(unsigned int partno,
return 0;
}
- return -EINVAL;
+ return -ENODEV;
}
static int k3_chipinfo_probe(struct platform_device *pdev)
@@ -111,8 +111,7 @@ static int k3_chipinfo_probe(struct platform_device *pdev)
ret = k3_chipinfo_partno_to_names(partno_id, soc_dev_attr);
if (ret) {
- dev_err(dev, "Unknown SoC JTAGID[0x%08X]\n", jtag_id);
- ret = -ENODEV;
+ dev_err(dev, "Unknown SoC JTAGID[0x%08X]: %d\n", jtag_id, ret);
goto err_free_rev;
}
diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c
index 0fbc37cd5123..6023006685fc 100644
--- a/drivers/soc/ti/knav_dma.c
+++ b/drivers/soc/ti/knav_dma.c
@@ -773,7 +773,7 @@ err_pm_disable:
return ret;
}
-static int knav_dma_remove(struct platform_device *pdev)
+static void knav_dma_remove(struct platform_device *pdev)
{
struct knav_dma_device *dma;
@@ -784,8 +784,6 @@ static int knav_dma_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static struct of_device_id of_match[] = {
@@ -797,7 +795,7 @@ MODULE_DEVICE_TABLE(of, of_match);
static struct platform_driver knav_dma_driver = {
.probe = knav_dma_probe,
- .remove = knav_dma_remove,
+ .remove_new = knav_dma_remove,
.driver = {
.name = "keystone-navigator-dma",
.of_match_table = of_match,
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index 0f252c2549ba..06fb5505c22c 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -14,10 +14,12 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/of_device.h>
#include <linux/of_irq.h>
+#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/slab.h>
#include <linux/soc/ti/knav_qmss.h>
@@ -1754,7 +1756,6 @@ static int knav_queue_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct device_node *qmgrs, *queue_pools, *regions, *pdsps;
- const struct of_device_id *match;
struct device *dev = &pdev->dev;
u32 temp[2];
int ret;
@@ -1770,8 +1771,7 @@ static int knav_queue_probe(struct platform_device *pdev)
return -ENOMEM;
}
- match = of_match_device(of_match_ptr(keystone_qmss_of_match), dev);
- if (match && match->data)
+ if (device_get_match_data(dev))
kdev->version = QMSS_66AK2G;
platform_set_drvdata(pdev, kdev);
@@ -1884,17 +1884,16 @@ err:
return ret;
}
-static int knav_queue_remove(struct platform_device *pdev)
+static void knav_queue_remove(struct platform_device *pdev)
{
/* TODO: Free resources */
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- return 0;
}
static struct platform_driver keystone_qmss_driver = {
.probe = knav_queue_probe,
- .remove = knav_queue_remove,
+ .remove_new = knav_queue_remove,
.driver = {
.name = "keystone-navigator-qmss",
.of_match_table = keystone_qmss_of_match,
diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c
index f04c21157904..8e983c3c4e03 100644
--- a/drivers/soc/ti/pm33xx.c
+++ b/drivers/soc/ti/pm33xx.c
@@ -583,7 +583,7 @@ err_wkup_m3_ipc_put:
return ret;
}
-static int am33xx_pm_remove(struct platform_device *pdev)
+static void am33xx_pm_remove(struct platform_device *pdev)
{
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
@@ -594,7 +594,6 @@ static int am33xx_pm_remove(struct platform_device *pdev)
am33xx_pm_free_sram();
iounmap(rtc_base_virt);
clk_put(rtc_fck);
- return 0;
}
static struct platform_driver am33xx_pm_driver = {
@@ -602,7 +601,7 @@ static struct platform_driver am33xx_pm_driver = {
.name = "pm33xx",
},
.probe = am33xx_pm_probe,
- .remove = am33xx_pm_remove,
+ .remove_new = am33xx_pm_remove,
};
module_platform_driver(am33xx_pm_driver);
diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
index f49f8492dde5..24a42e0b645c 100644
--- a/drivers/soc/ti/pruss.c
+++ b/drivers/soc/ti/pruss.c
@@ -565,7 +565,7 @@ rpm_disable:
return ret;
}
-static int pruss_remove(struct platform_device *pdev)
+static void pruss_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -573,8 +573,6 @@ static int pruss_remove(struct platform_device *pdev)
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
-
- return 0;
}
/* instance-specific driver private data */
@@ -610,7 +608,7 @@ static struct platform_driver pruss_driver = {
.of_match_table = pruss_of_match,
},
.probe = pruss_probe,
- .remove = pruss_remove,
+ .remove_new = pruss_remove,
};
module_platform_driver(pruss_driver);
diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
index 62b2f1464e46..d6219060b616 100644
--- a/drivers/soc/ti/smartreflex.c
+++ b/drivers/soc/ti/smartreflex.c
@@ -933,7 +933,7 @@ err_list_del:
return ret;
}
-static int omap_sr_remove(struct platform_device *pdev)
+static void omap_sr_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct omap_sr *sr_info = platform_get_drvdata(pdev);
@@ -945,7 +945,6 @@ static int omap_sr_remove(struct platform_device *pdev)
pm_runtime_disable(dev);
clk_unprepare(sr_info->fck);
list_del(&sr_info->node);
- return 0;
}
static void omap_sr_shutdown(struct platform_device *pdev)
@@ -970,7 +969,7 @@ MODULE_DEVICE_TABLE(of, omap_sr_match);
static struct platform_driver smartreflex_driver = {
.probe = omap_sr_probe,
- .remove = omap_sr_remove,
+ .remove_new = omap_sr_remove,
.shutdown = omap_sr_shutdown,
.driver = {
.name = DRIVER_NAME,
diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c
index 3aff106fc11a..6a1c6b34c414 100644
--- a/drivers/soc/ti/wkup_m3_ipc.c
+++ b/drivers/soc/ti/wkup_m3_ipc.c
@@ -713,7 +713,7 @@ err_free_mbox:
return ret;
}
-static int wkup_m3_ipc_remove(struct platform_device *pdev)
+static void wkup_m3_ipc_remove(struct platform_device *pdev)
{
wkup_m3_ipc_dbg_destroy(m3_ipc_state);
@@ -723,8 +723,6 @@ static int wkup_m3_ipc_remove(struct platform_device *pdev)
rproc_put(m3_ipc_state->rproc);
m3_ipc_state = NULL;
-
- return 0;
}
static int __maybe_unused wkup_m3_ipc_suspend(struct device *dev)
@@ -760,7 +758,7 @@ MODULE_DEVICE_TABLE(of, wkup_m3_ipc_of_match);
static struct platform_driver wkup_m3_ipc_driver = {
.probe = wkup_m3_ipc_probe,
- .remove = wkup_m3_ipc_remove,
+ .remove_new = wkup_m3_ipc_remove,
.driver = {
.name = "wkup_m3_ipc",
.of_match_table = wkup_m3_ipc_of_match,
diff --git a/drivers/soc/xilinx/Kconfig b/drivers/soc/xilinx/Kconfig
index 8a755a5c8836..49d69d6e18fe 100644
--- a/drivers/soc/xilinx/Kconfig
+++ b/drivers/soc/xilinx/Kconfig
@@ -16,15 +16,6 @@ config ZYNQMP_POWER
If in doubt, say N.
-config ZYNQMP_PM_DOMAINS
- bool "Enable Zynq MPSoC generic PM domains"
- default y
- depends on PM && ZYNQMP_FIRMWARE
- select PM_GENERIC_DOMAINS
- help
- Say yes to enable device power management through PM domains
- If in doubt, say N.
-
config XLNX_EVENT_MANAGER
bool "Enable Xilinx Event Management Driver"
depends on ZYNQMP_FIRMWARE
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index d29fdfe9d93d..98433a53bae1 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -47,7 +47,7 @@
* using the 2.6 Linux kernel kref construct.
*
* For direction on installation and usage of this driver please reference
- * Documentation/powerpc/hvcs.rst.
+ * Documentation/arch/powerpc/hvcs.rst.
*/
#include <linux/device.h>
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index ee17cf5c44c6..c12978311a09 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -222,7 +222,7 @@ config SERIAL_8250_EXTENDED
config SERIAL_8250_MANY_PORTS
bool "Support more than 4 legacy serial ports"
- depends on SERIAL_8250_EXTENDED && !IA64
+ depends on SERIAL_8250_EXTENDED
help
Say Y here if you have dumb serial boards other than the four
standard COM 1/2/3/4 ports. This may happen if you have an AST
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index d13d2f2e76c7..0216a468b438 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3612,7 +3612,6 @@ static struct ctl_table tty_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
- { }
};
/*
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 358f216c6cd6..1fe6107b539b 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -1273,7 +1273,7 @@ static void kbd_bh(struct tasklet_struct *unused)
}
}
-#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
+#if defined(CONFIG_X86) || defined(CONFIG_ALPHA) ||\
defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
(defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile
index c82ea032d352..68c05705200f 100644
--- a/drivers/vfio/Makefile
+++ b/drivers/vfio/Makefile
@@ -1,8 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_VFIO) += vfio.o
-vfio-y += vfio_main.o \
- iova_bitmap.o
+vfio-y += vfio_main.o
vfio-$(CONFIG_VFIO_DEVICE_CDEV) += device_cdev.o
vfio-$(CONFIG_VFIO_GROUP) += group.o
vfio-$(CONFIG_IOMMUFD) += iommufd.o
diff --git a/drivers/vfio/cdx/main.c b/drivers/vfio/cdx/main.c
index de56686581ae..a63744302b5e 100644
--- a/drivers/vfio/cdx/main.c
+++ b/drivers/vfio/cdx/main.c
@@ -14,7 +14,7 @@ static int vfio_cdx_open_device(struct vfio_device *core_vdev)
container_of(core_vdev, struct vfio_cdx_device, vdev);
struct cdx_device *cdx_dev = to_cdx_device(core_vdev->dev);
int count = cdx_dev->res_count;
- int i;
+ int i, ret;
vdev->regions = kcalloc(count, sizeof(struct vfio_cdx_region),
GFP_KERNEL_ACCOUNT);
@@ -39,6 +39,17 @@ static int vfio_cdx_open_device(struct vfio_device *core_vdev)
if (!(cdx_dev->res[i].flags & IORESOURCE_READONLY))
vdev->regions[i].flags |= VFIO_REGION_INFO_FLAG_WRITE;
}
+ ret = cdx_dev_reset(core_vdev->dev);
+ if (ret) {
+ kfree(vdev->regions);
+ vdev->regions = NULL;
+ return ret;
+ }
+ ret = cdx_clear_master(cdx_dev);
+ if (ret)
+ vdev->flags &= ~BME_SUPPORT;
+ else
+ vdev->flags |= BME_SUPPORT;
return 0;
}
@@ -52,6 +63,49 @@ static void vfio_cdx_close_device(struct vfio_device *core_vdev)
cdx_dev_reset(core_vdev->dev);
}
+static int vfio_cdx_bm_ctrl(struct vfio_device *core_vdev, u32 flags,
+ void __user *arg, size_t argsz)
+{
+ size_t minsz =
+ offsetofend(struct vfio_device_feature_bus_master, op);
+ struct vfio_cdx_device *vdev =
+ container_of(core_vdev, struct vfio_cdx_device, vdev);
+ struct cdx_device *cdx_dev = to_cdx_device(core_vdev->dev);
+ struct vfio_device_feature_bus_master ops;
+ int ret;
+
+ if (!(vdev->flags & BME_SUPPORT))
+ return -ENOTTY;
+
+ ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_SET,
+ sizeof(ops));
+ if (ret != 1)
+ return ret;
+
+ if (copy_from_user(&ops, arg, minsz))
+ return -EFAULT;
+
+ switch (ops.op) {
+ case VFIO_DEVICE_FEATURE_CLEAR_MASTER:
+ return cdx_clear_master(cdx_dev);
+ case VFIO_DEVICE_FEATURE_SET_MASTER:
+ return cdx_set_master(cdx_dev);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int vfio_cdx_ioctl_feature(struct vfio_device *device, u32 flags,
+ void __user *arg, size_t argsz)
+{
+ switch (flags & VFIO_DEVICE_FEATURE_MASK) {
+ case VFIO_DEVICE_FEATURE_BUS_MASTER:
+ return vfio_cdx_bm_ctrl(device, flags, arg, argsz);
+ default:
+ return -ENOTTY;
+ }
+}
+
static int vfio_cdx_ioctl_get_info(struct vfio_cdx_device *vdev,
struct vfio_device_info __user *arg)
{
@@ -169,6 +223,7 @@ static const struct vfio_device_ops vfio_cdx_ops = {
.open_device = vfio_cdx_open_device,
.close_device = vfio_cdx_close_device,
.ioctl = vfio_cdx_ioctl,
+ .device_feature = vfio_cdx_ioctl_feature,
.mmap = vfio_cdx_mmap,
.bind_iommufd = vfio_iommufd_physical_bind,
.unbind_iommufd = vfio_iommufd_physical_unbind,
diff --git a/drivers/vfio/cdx/private.h b/drivers/vfio/cdx/private.h
index 8bdc117ea88e..8e9d25913728 100644
--- a/drivers/vfio/cdx/private.h
+++ b/drivers/vfio/cdx/private.h
@@ -23,6 +23,8 @@ struct vfio_cdx_region {
struct vfio_cdx_device {
struct vfio_device vdev;
struct vfio_cdx_region *regions;
+ u32 flags;
+#define BME_SUPPORT BIT(0)
};
#endif /* VFIO_CDX_PRIVATE_H */
diff --git a/drivers/vfio/pci/mlx5/Kconfig b/drivers/vfio/pci/mlx5/Kconfig
index 7088edc4fb28..c3ced56b7787 100644
--- a/drivers/vfio/pci/mlx5/Kconfig
+++ b/drivers/vfio/pci/mlx5/Kconfig
@@ -3,6 +3,7 @@ config MLX5_VFIO_PCI
tristate "VFIO support for MLX5 PCI devices"
depends on MLX5_CORE
select VFIO_PCI_CORE
+ select IOMMUFD_DRIVER
help
This provides migration support for MLX5 devices using the VFIO
framework.
diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c
index 33574b04477d..efd1d252cdc9 100644
--- a/drivers/vfio/pci/mlx5/cmd.c
+++ b/drivers/vfio/pci/mlx5/cmd.c
@@ -86,7 +86,8 @@ int mlx5vf_cmd_resume_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod)
}
int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev,
- size_t *state_size, u8 query_flags)
+ size_t *state_size, u64 *total_size,
+ u8 query_flags)
{
u32 out[MLX5_ST_SZ_DW(query_vhca_migration_state_out)] = {};
u32 in[MLX5_ST_SZ_DW(query_vhca_migration_state_in)] = {};
@@ -128,6 +129,7 @@ int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev,
MLX5_SET(query_vhca_migration_state_in, in, op_mod, 0);
MLX5_SET(query_vhca_migration_state_in, in, incremental,
query_flags & MLX5VF_QUERY_INC);
+ MLX5_SET(query_vhca_migration_state_in, in, chunk, mvdev->chunk_mode);
ret = mlx5_cmd_exec_inout(mvdev->mdev, query_vhca_migration_state, in,
out);
@@ -139,6 +141,11 @@ int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev,
*state_size = MLX5_GET(query_vhca_migration_state_out, out,
required_umem_size);
+ if (total_size)
+ *total_size = mvdev->chunk_mode ?
+ MLX5_GET64(query_vhca_migration_state_out, out,
+ remaining_total_size) : *state_size;
+
return 0;
}
@@ -254,6 +261,9 @@ void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev,
mvdev->core_device.vdev.migration_flags |=
VFIO_MIGRATION_PRE_COPY;
+ if (MLX5_CAP_GEN_2(mvdev->mdev, migration_in_chunks))
+ mvdev->chunk_mode = 1;
+
end:
mlx5_vf_put_core_dev(mvdev->mdev);
}
@@ -428,6 +438,7 @@ end:
void mlx5vf_put_data_buffer(struct mlx5_vhca_data_buffer *buf)
{
spin_lock_irq(&buf->migf->list_lock);
+ buf->stop_copy_chunk_num = 0;
list_add_tail(&buf->buf_elm, &buf->migf->avail_list);
spin_unlock_irq(&buf->migf->list_lock);
}
@@ -475,6 +486,15 @@ found:
return buf;
}
+static void
+mlx5vf_save_callback_complete(struct mlx5_vf_migration_file *migf,
+ struct mlx5vf_async_data *async_data)
+{
+ kvfree(async_data->out);
+ complete(&migf->save_comp);
+ fput(migf->filp);
+}
+
void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work)
{
struct mlx5vf_async_data *async_data = container_of(_work,
@@ -487,16 +507,15 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work)
mlx5vf_put_data_buffer(async_data->buf);
if (async_data->header_buf)
mlx5vf_put_data_buffer(async_data->header_buf);
- if (async_data->status == MLX5_CMD_STAT_BAD_RES_STATE_ERR)
+ if (!async_data->stop_copy_chunk &&
+ async_data->status == MLX5_CMD_STAT_BAD_RES_STATE_ERR)
migf->state = MLX5_MIGF_STATE_PRE_COPY_ERROR;
else
migf->state = MLX5_MIGF_STATE_ERROR;
wake_up_interruptible(&migf->poll_wait);
}
mutex_unlock(&migf->lock);
- kvfree(async_data->out);
- complete(&migf->save_comp);
- fput(migf->filp);
+ mlx5vf_save_callback_complete(migf, async_data);
}
static int add_buf_header(struct mlx5_vhca_data_buffer *header_buf,
@@ -536,13 +555,20 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context)
struct mlx5_vf_migration_file, async_data);
if (!status) {
+ size_t next_required_umem_size = 0;
+ bool stop_copy_last_chunk;
size_t image_size;
unsigned long flags;
bool initial_pre_copy = migf->state != MLX5_MIGF_STATE_PRE_COPY &&
- !async_data->last_chunk;
+ !async_data->stop_copy_chunk;
image_size = MLX5_GET(save_vhca_state_out, async_data->out,
actual_image_size);
+ if (async_data->buf->stop_copy_chunk_num)
+ next_required_umem_size = MLX5_GET(save_vhca_state_out,
+ async_data->out, next_required_umem_size);
+ stop_copy_last_chunk = async_data->stop_copy_chunk &&
+ !next_required_umem_size;
if (async_data->header_buf) {
status = add_buf_header(async_data->header_buf, image_size,
initial_pre_copy);
@@ -554,19 +580,34 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context)
migf->max_pos += async_data->buf->length;
spin_lock_irqsave(&migf->list_lock, flags);
list_add_tail(&async_data->buf->buf_elm, &migf->buf_list);
+ if (async_data->buf->stop_copy_chunk_num) {
+ migf->num_ready_chunks++;
+ if (next_required_umem_size &&
+ migf->num_ready_chunks >= MAX_NUM_CHUNKS) {
+ /* Delay the next SAVE till one chunk be consumed */
+ migf->next_required_umem_size = next_required_umem_size;
+ next_required_umem_size = 0;
+ }
+ }
spin_unlock_irqrestore(&migf->list_lock, flags);
- if (initial_pre_copy)
+ if (initial_pre_copy) {
migf->pre_copy_initial_bytes += image_size;
- migf->state = async_data->last_chunk ?
- MLX5_MIGF_STATE_COMPLETE : MLX5_MIGF_STATE_PRE_COPY;
+ migf->state = MLX5_MIGF_STATE_PRE_COPY;
+ }
+ if (stop_copy_last_chunk)
+ migf->state = MLX5_MIGF_STATE_COMPLETE;
wake_up_interruptible(&migf->poll_wait);
+ if (next_required_umem_size)
+ mlx5vf_mig_file_set_save_work(migf,
+ /* Picking up the next chunk num */
+ (async_data->buf->stop_copy_chunk_num % MAX_NUM_CHUNKS) + 1,
+ next_required_umem_size);
+ mlx5vf_save_callback_complete(migf, async_data);
+ return;
}
err:
- /*
- * The error and the cleanup flows can't run from an
- * interrupt context
- */
+ /* The error flow can't run from an interrupt context */
if (status == -EREMOTEIO)
status = MLX5_GET(save_vhca_state_out, async_data->out, status);
async_data->status = status;
@@ -610,7 +651,7 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
async_data = &migf->async_data;
async_data->buf = buf;
- async_data->last_chunk = !track;
+ async_data->stop_copy_chunk = !track;
async_data->out = kvzalloc(out_size, GFP_KERNEL);
if (!async_data->out) {
err = -ENOMEM;
@@ -618,10 +659,15 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
}
if (MLX5VF_PRE_COPY_SUPP(mvdev)) {
- if (async_data->last_chunk && migf->buf_header) {
- header_buf = migf->buf_header;
- migf->buf_header = NULL;
- } else {
+ if (async_data->stop_copy_chunk) {
+ u8 header_idx = buf->stop_copy_chunk_num ?
+ buf->stop_copy_chunk_num - 1 : 0;
+
+ header_buf = migf->buf_header[header_idx];
+ migf->buf_header[header_idx] = NULL;
+ }
+
+ if (!header_buf) {
header_buf = mlx5vf_get_data_buffer(migf,
sizeof(struct mlx5_vf_migration_header), DMA_NONE);
if (IS_ERR(header_buf)) {
@@ -631,8 +677,8 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
}
}
- if (async_data->last_chunk)
- migf->state = MLX5_MIGF_STATE_SAVE_LAST;
+ if (async_data->stop_copy_chunk)
+ migf->state = MLX5_MIGF_STATE_SAVE_STOP_COPY_CHUNK;
async_data->header_buf = header_buf;
get_file(migf->filp);
@@ -707,18 +753,21 @@ void mlx5vf_cmd_dealloc_pd(struct mlx5_vf_migration_file *migf)
void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf)
{
struct mlx5_vhca_data_buffer *entry;
+ int i;
lockdep_assert_held(&migf->mvdev->state_mutex);
WARN_ON(migf->mvdev->mdev_detach);
- if (migf->buf) {
- mlx5vf_free_data_buffer(migf->buf);
- migf->buf = NULL;
- }
+ for (i = 0; i < MAX_NUM_CHUNKS; i++) {
+ if (migf->buf[i]) {
+ mlx5vf_free_data_buffer(migf->buf[i]);
+ migf->buf[i] = NULL;
+ }
- if (migf->buf_header) {
- mlx5vf_free_data_buffer(migf->buf_header);
- migf->buf_header = NULL;
+ if (migf->buf_header[i]) {
+ mlx5vf_free_data_buffer(migf->buf_header[i]);
+ migf->buf_header[i] = NULL;
+ }
}
list_splice(&migf->avail_list, &migf->buf_list);
diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h
index aec4c69dd6c1..f2c7227fa683 100644
--- a/drivers/vfio/pci/mlx5/cmd.h
+++ b/drivers/vfio/pci/mlx5/cmd.h
@@ -20,7 +20,7 @@ enum mlx5_vf_migf_state {
MLX5_MIGF_STATE_ERROR = 1,
MLX5_MIGF_STATE_PRE_COPY_ERROR,
MLX5_MIGF_STATE_PRE_COPY,
- MLX5_MIGF_STATE_SAVE_LAST,
+ MLX5_MIGF_STATE_SAVE_STOP_COPY_CHUNK,
MLX5_MIGF_STATE_COMPLETE,
};
@@ -64,6 +64,7 @@ struct mlx5_vhca_data_buffer {
u32 mkey;
enum dma_data_direction dma_dir;
u8 dmaed:1;
+ u8 stop_copy_chunk_num;
struct list_head buf_elm;
struct mlx5_vf_migration_file *migf;
/* Optimize mlx5vf_get_migration_page() for sequential access */
@@ -78,10 +79,19 @@ struct mlx5vf_async_data {
struct mlx5_vhca_data_buffer *buf;
struct mlx5_vhca_data_buffer *header_buf;
int status;
- u8 last_chunk:1;
+ u8 stop_copy_chunk:1;
void *out;
};
+struct mlx5vf_save_work_data {
+ struct mlx5_vf_migration_file *migf;
+ size_t next_required_umem_size;
+ struct work_struct work;
+ u8 chunk_num;
+};
+
+#define MAX_NUM_CHUNKS 2
+
struct mlx5_vf_migration_file {
struct file *filp;
struct mutex lock;
@@ -94,8 +104,12 @@ struct mlx5_vf_migration_file {
u32 record_tag;
u64 stop_copy_prep_size;
u64 pre_copy_initial_bytes;
- struct mlx5_vhca_data_buffer *buf;
- struct mlx5_vhca_data_buffer *buf_header;
+ size_t next_required_umem_size;
+ u8 num_ready_chunks;
+ /* Upon chunk mode preserve another set of buffers for stop_copy phase */
+ struct mlx5_vhca_data_buffer *buf[MAX_NUM_CHUNKS];
+ struct mlx5_vhca_data_buffer *buf_header[MAX_NUM_CHUNKS];
+ struct mlx5vf_save_work_data save_data[MAX_NUM_CHUNKS];
spinlock_t list_lock;
struct list_head buf_list;
struct list_head avail_list;
@@ -164,6 +178,7 @@ struct mlx5vf_pci_core_device {
u8 deferred_reset:1;
u8 mdev_detach:1;
u8 log_active:1;
+ u8 chunk_mode:1;
struct completion tracker_comp;
/* protect migration state */
struct mutex state_mutex;
@@ -186,7 +201,8 @@ enum {
int mlx5vf_cmd_suspend_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod);
int mlx5vf_cmd_resume_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod);
int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev,
- size_t *state_size, u8 query_flags);
+ size_t *state_size, u64 *total_size,
+ u8 query_flags);
void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev,
const struct vfio_migration_ops *mig_ops,
const struct vfio_log_ops *log_ops);
@@ -217,6 +233,8 @@ struct page *mlx5vf_get_migration_page(struct mlx5_vhca_data_buffer *buf,
void mlx5vf_state_mutex_unlock(struct mlx5vf_pci_core_device *mvdev);
void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev);
void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work);
+void mlx5vf_mig_file_set_save_work(struct mlx5_vf_migration_file *migf,
+ u8 chunk_num, size_t next_required_umem_size);
int mlx5vf_start_page_tracker(struct vfio_device *vdev,
struct rb_root_cached *ranges, u32 nnodes, u64 *page_size);
int mlx5vf_stop_page_tracker(struct vfio_device *vdev);
diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c
index 42ec574a8622..fe09a8c8af95 100644
--- a/drivers/vfio/pci/mlx5/main.c
+++ b/drivers/vfio/pci/mlx5/main.c
@@ -24,6 +24,8 @@
/* Device specification max LOAD size */
#define MAX_LOAD_SIZE (BIT_ULL(__mlx5_bit_sz(load_vhca_state_in, size)) - 1)
+#define MAX_CHUNK_SIZE SZ_8M
+
static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev)
{
struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
@@ -158,6 +160,41 @@ end:
return found ? buf : NULL;
}
+static void mlx5vf_buf_read_done(struct mlx5_vhca_data_buffer *vhca_buf)
+{
+ struct mlx5_vf_migration_file *migf = vhca_buf->migf;
+
+ if (vhca_buf->stop_copy_chunk_num) {
+ bool is_header = vhca_buf->dma_dir == DMA_NONE;
+ u8 chunk_num = vhca_buf->stop_copy_chunk_num;
+ size_t next_required_umem_size = 0;
+
+ if (is_header)
+ migf->buf_header[chunk_num - 1] = vhca_buf;
+ else
+ migf->buf[chunk_num - 1] = vhca_buf;
+
+ spin_lock_irq(&migf->list_lock);
+ list_del_init(&vhca_buf->buf_elm);
+ if (!is_header) {
+ next_required_umem_size =
+ migf->next_required_umem_size;
+ migf->next_required_umem_size = 0;
+ migf->num_ready_chunks--;
+ }
+ spin_unlock_irq(&migf->list_lock);
+ if (next_required_umem_size)
+ mlx5vf_mig_file_set_save_work(migf, chunk_num,
+ next_required_umem_size);
+ return;
+ }
+
+ spin_lock_irq(&migf->list_lock);
+ list_del_init(&vhca_buf->buf_elm);
+ list_add_tail(&vhca_buf->buf_elm, &vhca_buf->migf->avail_list);
+ spin_unlock_irq(&migf->list_lock);
+}
+
static ssize_t mlx5vf_buf_read(struct mlx5_vhca_data_buffer *vhca_buf,
char __user **buf, size_t *len, loff_t *pos)
{
@@ -193,12 +230,8 @@ static ssize_t mlx5vf_buf_read(struct mlx5_vhca_data_buffer *vhca_buf,
copy_len -= page_len;
}
- if (*pos >= vhca_buf->start_pos + vhca_buf->length) {
- spin_lock_irq(&vhca_buf->migf->list_lock);
- list_del_init(&vhca_buf->buf_elm);
- list_add_tail(&vhca_buf->buf_elm, &vhca_buf->migf->avail_list);
- spin_unlock_irq(&vhca_buf->migf->list_lock);
- }
+ if (*pos >= vhca_buf->start_pos + vhca_buf->length)
+ mlx5vf_buf_read_done(vhca_buf);
return done;
}
@@ -304,7 +337,75 @@ static void mlx5vf_mark_err(struct mlx5_vf_migration_file *migf)
wake_up_interruptible(&migf->poll_wait);
}
-static int mlx5vf_add_stop_copy_header(struct mlx5_vf_migration_file *migf)
+void mlx5vf_mig_file_set_save_work(struct mlx5_vf_migration_file *migf,
+ u8 chunk_num, size_t next_required_umem_size)
+{
+ migf->save_data[chunk_num - 1].next_required_umem_size =
+ next_required_umem_size;
+ migf->save_data[chunk_num - 1].migf = migf;
+ get_file(migf->filp);
+ queue_work(migf->mvdev->cb_wq,
+ &migf->save_data[chunk_num - 1].work);
+}
+
+static struct mlx5_vhca_data_buffer *
+mlx5vf_mig_file_get_stop_copy_buf(struct mlx5_vf_migration_file *migf,
+ u8 index, size_t required_length)
+{
+ struct mlx5_vhca_data_buffer *buf = migf->buf[index];
+ u8 chunk_num;
+
+ WARN_ON(!buf);
+ chunk_num = buf->stop_copy_chunk_num;
+ buf->migf->buf[index] = NULL;
+ /* Checking whether the pre-allocated buffer can fit */
+ if (buf->allocated_length >= required_length)
+ return buf;
+
+ mlx5vf_put_data_buffer(buf);
+ buf = mlx5vf_get_data_buffer(buf->migf, required_length,
+ DMA_FROM_DEVICE);
+ if (IS_ERR(buf))
+ return buf;
+
+ buf->stop_copy_chunk_num = chunk_num;
+ return buf;
+}
+
+static void mlx5vf_mig_file_save_work(struct work_struct *_work)
+{
+ struct mlx5vf_save_work_data *save_data = container_of(_work,
+ struct mlx5vf_save_work_data, work);
+ struct mlx5_vf_migration_file *migf = save_data->migf;
+ struct mlx5vf_pci_core_device *mvdev = migf->mvdev;
+ struct mlx5_vhca_data_buffer *buf;
+
+ mutex_lock(&mvdev->state_mutex);
+ if (migf->state == MLX5_MIGF_STATE_ERROR)
+ goto end;
+
+ buf = mlx5vf_mig_file_get_stop_copy_buf(migf,
+ save_data->chunk_num - 1,
+ save_data->next_required_umem_size);
+ if (IS_ERR(buf))
+ goto err;
+
+ if (mlx5vf_cmd_save_vhca_state(mvdev, migf, buf, true, false))
+ goto err_save;
+
+ goto end;
+
+err_save:
+ mlx5vf_put_data_buffer(buf);
+err:
+ mlx5vf_mark_err(migf);
+end:
+ mlx5vf_state_mutex_unlock(mvdev);
+ fput(migf->filp);
+}
+
+static int mlx5vf_add_stop_copy_header(struct mlx5_vf_migration_file *migf,
+ bool track)
{
size_t size = sizeof(struct mlx5_vf_migration_header) +
sizeof(struct mlx5_vf_migration_tag_stop_copy_data);
@@ -331,7 +432,7 @@ static int mlx5vf_add_stop_copy_header(struct mlx5_vf_migration_file *migf)
to_buff = kmap_local_page(page);
memcpy(to_buff, &header, sizeof(header));
header_buf->length = sizeof(header);
- data.stop_copy_size = cpu_to_le64(migf->buf->allocated_length);
+ data.stop_copy_size = cpu_to_le64(migf->buf[0]->allocated_length);
memcpy(to_buff + sizeof(header), &data, sizeof(data));
header_buf->length += sizeof(data);
kunmap_local(to_buff);
@@ -340,48 +441,86 @@ static int mlx5vf_add_stop_copy_header(struct mlx5_vf_migration_file *migf)
spin_lock_irqsave(&migf->list_lock, flags);
list_add_tail(&header_buf->buf_elm, &migf->buf_list);
spin_unlock_irqrestore(&migf->list_lock, flags);
- migf->pre_copy_initial_bytes = size;
+ if (track)
+ migf->pre_copy_initial_bytes = size;
return 0;
err:
mlx5vf_put_data_buffer(header_buf);
return ret;
}
-static int mlx5vf_prep_stop_copy(struct mlx5_vf_migration_file *migf,
- size_t state_size)
+static int mlx5vf_prep_stop_copy(struct mlx5vf_pci_core_device *mvdev,
+ struct mlx5_vf_migration_file *migf,
+ size_t state_size, u64 full_size,
+ bool track)
{
struct mlx5_vhca_data_buffer *buf;
size_t inc_state_size;
+ int num_chunks;
int ret;
+ int i;
- /* let's be ready for stop_copy size that might grow by 10 percents */
- if (check_add_overflow(state_size, state_size / 10, &inc_state_size))
- inc_state_size = state_size;
+ if (mvdev->chunk_mode) {
+ size_t chunk_size = min_t(size_t, MAX_CHUNK_SIZE, full_size);
- buf = mlx5vf_get_data_buffer(migf, inc_state_size, DMA_FROM_DEVICE);
- if (IS_ERR(buf))
- return PTR_ERR(buf);
+ /* from firmware perspective at least 'state_size' buffer should be set */
+ inc_state_size = max(state_size, chunk_size);
+ } else {
+ if (track) {
+ /* let's be ready for stop_copy size that might grow by 10 percents */
+ if (check_add_overflow(state_size, state_size / 10, &inc_state_size))
+ inc_state_size = state_size;
+ } else {
+ inc_state_size = state_size;
+ }
+ }
- migf->buf = buf;
- buf = mlx5vf_get_data_buffer(migf,
- sizeof(struct mlx5_vf_migration_header), DMA_NONE);
- if (IS_ERR(buf)) {
- ret = PTR_ERR(buf);
- goto err;
+ /* let's not overflow the device specification max SAVE size */
+ inc_state_size = min_t(size_t, inc_state_size,
+ (BIT_ULL(__mlx5_bit_sz(save_vhca_state_in, size)) - PAGE_SIZE));
+
+ num_chunks = mvdev->chunk_mode ? MAX_NUM_CHUNKS : 1;
+ for (i = 0; i < num_chunks; i++) {
+ buf = mlx5vf_get_data_buffer(migf, inc_state_size, DMA_FROM_DEVICE);
+ if (IS_ERR(buf)) {
+ ret = PTR_ERR(buf);
+ goto err;
+ }
+
+ migf->buf[i] = buf;
+ buf = mlx5vf_get_data_buffer(migf,
+ sizeof(struct mlx5_vf_migration_header), DMA_NONE);
+ if (IS_ERR(buf)) {
+ ret = PTR_ERR(buf);
+ goto err;
+ }
+ migf->buf_header[i] = buf;
+ if (mvdev->chunk_mode) {
+ migf->buf[i]->stop_copy_chunk_num = i + 1;
+ migf->buf_header[i]->stop_copy_chunk_num = i + 1;
+ INIT_WORK(&migf->save_data[i].work,
+ mlx5vf_mig_file_save_work);
+ migf->save_data[i].chunk_num = i + 1;
+ }
}
- migf->buf_header = buf;
- ret = mlx5vf_add_stop_copy_header(migf);
+ ret = mlx5vf_add_stop_copy_header(migf, track);
if (ret)
- goto err_header;
+ goto err;
return 0;
-err_header:
- mlx5vf_put_data_buffer(migf->buf_header);
- migf->buf_header = NULL;
err:
- mlx5vf_put_data_buffer(migf->buf);
- migf->buf = NULL;
+ for (i = 0; i < num_chunks; i++) {
+ if (migf->buf[i]) {
+ mlx5vf_put_data_buffer(migf->buf[i]);
+ migf->buf[i] = NULL;
+ }
+ if (migf->buf_header[i]) {
+ mlx5vf_put_data_buffer(migf->buf_header[i]);
+ migf->buf_header[i] = NULL;
+ }
+ }
+
return ret;
}
@@ -428,7 +567,7 @@ static long mlx5vf_precopy_ioctl(struct file *filp, unsigned int cmd,
* As so, the other code below is safe with the proper locks.
*/
ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &inc_length,
- MLX5VF_QUERY_INC);
+ NULL, MLX5VF_QUERY_INC);
if (ret)
goto err_state_unlock;
}
@@ -505,21 +644,15 @@ static int mlx5vf_pci_save_device_inc_data(struct mlx5vf_pci_core_device *mvdev)
if (migf->state == MLX5_MIGF_STATE_ERROR)
return -ENODEV;
- ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length,
+ ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length, NULL,
MLX5VF_QUERY_INC | MLX5VF_QUERY_FINAL);
if (ret)
goto err;
- /* Checking whether we have a matching pre-allocated buffer that can fit */
- if (migf->buf && migf->buf->allocated_length >= length) {
- buf = migf->buf;
- migf->buf = NULL;
- } else {
- buf = mlx5vf_get_data_buffer(migf, length, DMA_FROM_DEVICE);
- if (IS_ERR(buf)) {
- ret = PTR_ERR(buf);
- goto err;
- }
+ buf = mlx5vf_mig_file_get_stop_copy_buf(migf, 0, length);
+ if (IS_ERR(buf)) {
+ ret = PTR_ERR(buf);
+ goto err;
}
ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf, true, false);
@@ -541,6 +674,7 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev, bool track)
struct mlx5_vf_migration_file *migf;
struct mlx5_vhca_data_buffer *buf;
size_t length;
+ u64 full_size;
int ret;
migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT);
@@ -574,20 +708,25 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev, bool track)
INIT_LIST_HEAD(&migf->buf_list);
INIT_LIST_HEAD(&migf->avail_list);
spin_lock_init(&migf->list_lock);
- ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length, 0);
+ ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length, &full_size, 0);
+ if (ret)
+ goto out_pd;
+
+ ret = mlx5vf_prep_stop_copy(mvdev, migf, length, full_size, track);
if (ret)
goto out_pd;
if (track) {
- ret = mlx5vf_prep_stop_copy(migf, length);
- if (ret)
+ /* leave the allocated buffer ready for the stop-copy phase */
+ buf = mlx5vf_alloc_data_buffer(migf,
+ migf->buf[0]->allocated_length, DMA_FROM_DEVICE);
+ if (IS_ERR(buf)) {
+ ret = PTR_ERR(buf);
goto out_pd;
- }
-
- buf = mlx5vf_alloc_data_buffer(migf, length, DMA_FROM_DEVICE);
- if (IS_ERR(buf)) {
- ret = PTR_ERR(buf);
- goto out_pd;
+ }
+ } else {
+ buf = migf->buf[0];
+ migf->buf[0] = NULL;
}
ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf, false, track);
@@ -820,8 +959,8 @@ static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf,
size_t len, loff_t *pos)
{
struct mlx5_vf_migration_file *migf = filp->private_data;
- struct mlx5_vhca_data_buffer *vhca_buf = migf->buf;
- struct mlx5_vhca_data_buffer *vhca_buf_header = migf->buf_header;
+ struct mlx5_vhca_data_buffer *vhca_buf = migf->buf[0];
+ struct mlx5_vhca_data_buffer *vhca_buf_header = migf->buf_header[0];
loff_t requested_length;
bool has_work = false;
ssize_t done = 0;
@@ -856,15 +995,15 @@ static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf,
if (vhca_buf_header->allocated_length < migf->record_size) {
mlx5vf_free_data_buffer(vhca_buf_header);
- migf->buf_header = mlx5vf_alloc_data_buffer(migf,
+ migf->buf_header[0] = mlx5vf_alloc_data_buffer(migf,
migf->record_size, DMA_NONE);
- if (IS_ERR(migf->buf_header)) {
- ret = PTR_ERR(migf->buf_header);
- migf->buf_header = NULL;
+ if (IS_ERR(migf->buf_header[0])) {
+ ret = PTR_ERR(migf->buf_header[0]);
+ migf->buf_header[0] = NULL;
goto out_unlock;
}
- vhca_buf_header = migf->buf_header;
+ vhca_buf_header = migf->buf_header[0];
}
vhca_buf_header->start_pos = migf->max_pos;
@@ -884,15 +1023,15 @@ static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf,
if (vhca_buf->allocated_length < size) {
mlx5vf_free_data_buffer(vhca_buf);
- migf->buf = mlx5vf_alloc_data_buffer(migf,
+ migf->buf[0] = mlx5vf_alloc_data_buffer(migf,
size, DMA_TO_DEVICE);
- if (IS_ERR(migf->buf)) {
- ret = PTR_ERR(migf->buf);
- migf->buf = NULL;
+ if (IS_ERR(migf->buf[0])) {
+ ret = PTR_ERR(migf->buf[0]);
+ migf->buf[0] = NULL;
goto out_unlock;
}
- vhca_buf = migf->buf;
+ vhca_buf = migf->buf[0];
}
vhca_buf->start_pos = migf->max_pos;
@@ -974,7 +1113,7 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev)
goto out_pd;
}
- migf->buf = buf;
+ migf->buf[0] = buf;
if (MLX5VF_PRE_COPY_SUPP(mvdev)) {
buf = mlx5vf_alloc_data_buffer(migf,
sizeof(struct mlx5_vf_migration_header), DMA_NONE);
@@ -983,7 +1122,7 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev)
goto out_buf;
}
- migf->buf_header = buf;
+ migf->buf_header[0] = buf;
migf->load_state = MLX5_VF_LOAD_STATE_READ_HEADER;
} else {
/* Initial state will be to read the image */
@@ -997,7 +1136,7 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev)
spin_lock_init(&migf->list_lock);
return migf;
out_buf:
- mlx5vf_free_data_buffer(migf->buf);
+ mlx5vf_free_data_buffer(migf->buf[0]);
out_pd:
mlx5vf_cmd_dealloc_pd(migf);
out_free:
@@ -1019,6 +1158,7 @@ void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev)
mlx5_cmd_cleanup_async_ctx(&mvdev->saving_migf->async_ctx);
cancel_work_sync(&mvdev->saving_migf->async_data.work);
mlx5vf_disable_fd(mvdev->saving_migf);
+ wake_up_interruptible(&mvdev->saving_migf->poll_wait);
mlx5fv_cmd_clean_migf_resources(mvdev->saving_migf);
fput(mvdev->saving_migf->filp);
mvdev->saving_migf = NULL;
@@ -1100,7 +1240,7 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev,
if (!MLX5VF_PRE_COPY_SUPP(mvdev)) {
ret = mlx5vf_cmd_load_vhca_state(mvdev,
mvdev->resuming_migf,
- mvdev->resuming_migf->buf);
+ mvdev->resuming_migf->buf[0]);
if (ret)
return ERR_PTR(ret);
}
@@ -1194,13 +1334,14 @@ static int mlx5vf_pci_get_data_size(struct vfio_device *vdev,
struct mlx5vf_pci_core_device *mvdev = container_of(
vdev, struct mlx5vf_pci_core_device, core_device.vdev);
size_t state_size;
+ u64 total_size;
int ret;
mutex_lock(&mvdev->state_mutex);
- ret = mlx5vf_cmd_query_vhca_migration_state(mvdev,
- &state_size, 0);
+ ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &state_size,
+ &total_size, 0);
if (!ret)
- *stop_copy_length = state_size;
+ *stop_copy_length = total_size;
mlx5vf_state_mutex_unlock(mvdev);
return ret;
}
@@ -1376,6 +1517,7 @@ static struct pci_driver mlx5vf_pci_driver = {
module_pci_driver(mlx5vf_pci_driver);
+MODULE_IMPORT_NS(IOMMUFD);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Max Gurtovoy <mgurtovoy@nvidia.com>");
MODULE_AUTHOR("Yishai Hadas <yishaih@nvidia.com>");
diff --git a/drivers/vfio/pci/pds/Kconfig b/drivers/vfio/pci/pds/Kconfig
index 6eceef7b028a..fec9b167c7b9 100644
--- a/drivers/vfio/pci/pds/Kconfig
+++ b/drivers/vfio/pci/pds/Kconfig
@@ -5,6 +5,7 @@ config PDS_VFIO_PCI
tristate "VFIO support for PDS PCI devices"
depends on PDS_CORE && PCI_IOV
select VFIO_PCI_CORE
+ select IOMMUFD_DRIVER
help
This provides generic PCI support for PDS devices using the VFIO
framework.
diff --git a/drivers/vfio/pci/pds/pci_drv.c b/drivers/vfio/pci/pds/pci_drv.c
index ab4b5958e413..dd8c00c895a2 100644
--- a/drivers/vfio/pci/pds/pci_drv.c
+++ b/drivers/vfio/pci/pds/pci_drv.c
@@ -204,6 +204,7 @@ static struct pci_driver pds_vfio_pci_driver = {
module_pci_driver(pds_vfio_pci_driver);
+MODULE_IMPORT_NS(IOMMUFD);
MODULE_DESCRIPTION(PDS_VFIO_DRV_DESCRIPTION);
MODULE_AUTHOR("Brett Creeley <brett.creeley@amd.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 40732e8ed4c6..8d4995ada74a 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -946,6 +946,11 @@ void vfio_combine_iova_ranges(struct rb_root_cached *root, u32 cur_nodes,
unsigned long last;
comb_start = interval_tree_iter_first(root, 0, ULONG_MAX);
+
+ /* Empty list */
+ if (WARN_ON_ONCE(!comb_start))
+ return;
+
curr = comb_start;
while (curr) {
last = curr->last;
@@ -975,6 +980,11 @@ void vfio_combine_iova_ranges(struct rb_root_cached *root, u32 cur_nodes,
prev = curr;
curr = interval_tree_iter_next(curr, 0, ULONG_MAX);
}
+
+ /* Empty list or no nodes to combine */
+ if (WARN_ON_ONCE(min_gap == ULONG_MAX))
+ break;
+
comb_start->last = comb_end->last;
interval_tree_remove(comb_end, root);
cur_nodes--;
@@ -1693,6 +1703,7 @@ static void __exit vfio_cleanup(void)
module_init(vfio_init);
module_exit(vfio_cleanup);
+MODULE_IMPORT_NS(IOMMUFD);
MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 20e0167bf20c..96fdc7301481 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -468,7 +468,7 @@ config FB_VESA
config FB_EFI
bool "EFI-based Framebuffer Support"
- depends on (FB = y) && !IA64 && EFI
+ depends on (FB = y) && EFI
select APERTURE_HELPERS
select DRM_PANEL_ORIENTATION_QUIRKS
select FB_IOMEM_HELPERS
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 751458959411..8cb6fa45d599 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1287,7 +1287,7 @@ config INTEL_MID_WATCHDOG
config ITCO_WDT
tristate "Intel TCO Timer/Watchdog"
- depends on (X86 || IA64) && PCI
+ depends on X86 && PCI
select WATCHDOG_CORE
depends on I2C || I2C=n
depends on MFD_INTEL_PMC_BXT || !MFD_INTEL_PMC_BXT
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index d43153fec18e..d5989871dd5d 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -269,12 +269,12 @@ config XEN_PRIVCMD
disaggregated Xen setups this driver might be needed for other
domains, too.
-config XEN_PRIVCMD_IRQFD
- bool "Xen irqfd support"
+config XEN_PRIVCMD_EVENTFD
+ bool "Xen Ioeventfd and irqfd support"
depends on XEN_PRIVCMD && XEN_VIRTIO && EVENTFD
help
- Using the irqfd mechanism a virtio backend running in a daemon can
- speed up interrupt injection into a guest.
+ Using the ioeventfd / irqfd mechanism a virtio backend running in a
+ daemon can speed up interrupt delivery from / to a guest.
config XEN_ACPI_PROCESSOR
tristate "Xen ACPI processor"
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 586a1673459e..976c6cdf9ee6 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -94,7 +94,6 @@ static struct ctl_table balloon_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
- { }
};
#else
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 1b2136fe0fa5..6de6b084ea60 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -1229,7 +1229,8 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip,
bind_evtchn_to_cpu(evtchn, 0, false);
} else {
struct irq_info *info = info_for_irq(irq);
- WARN_ON(info == NULL || info->type != IRQT_EVTCHN);
+ if (!WARN_ON(!info || info->type != IRQT_EVTCHN))
+ info->refcnt++;
}
out:
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index 9139a7364df5..59717628ca42 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -397,7 +397,7 @@ static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port,
if (rc < 0)
goto err;
- rc = bind_evtchn_to_irqhandler_lateeoi(port, evtchn_interrupt, 0,
+ rc = bind_evtchn_to_irqhandler_lateeoi(port, evtchn_interrupt, IRQF_SHARED,
u->name, evtchn);
if (rc < 0)
goto err;
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index f00ad5f5f1d4..1ce7f3c7a950 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -29,15 +29,18 @@
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
#include <linux/moduleparam.h>
+#include <linux/virtio_mmio.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
#include <xen/xen.h>
+#include <xen/events.h>
#include <xen/privcmd.h>
#include <xen/interface/xen.h>
#include <xen/interface/memory.h>
#include <xen/interface/hvm/dm_op.h>
+#include <xen/interface/hvm/ioreq.h>
#include <xen/features.h>
#include <xen/page.h>
#include <xen/xen-ops.h>
@@ -782,6 +785,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
goto out;
pages = vma->vm_private_data;
+
for (i = 0; i < kdata.num; i++) {
xen_pfn_t pfn =
page_to_xen_pfn(pages[i / XEN_PFN_PER_PAGE]);
@@ -838,7 +842,7 @@ out:
return rc;
}
-#ifdef CONFIG_XEN_PRIVCMD_IRQFD
+#ifdef CONFIG_XEN_PRIVCMD_EVENTFD
/* Irqfd support */
static struct workqueue_struct *irqfd_cleanup_wq;
static DEFINE_MUTEX(irqfds_lock);
@@ -935,7 +939,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
return -ENOMEM;
dm_op = kirqfd + 1;
- if (copy_from_user(dm_op, irqfd->dm_op, irqfd->size)) {
+ if (copy_from_user(dm_op, u64_to_user_ptr(irqfd->dm_op), irqfd->size)) {
ret = -EFAULT;
goto error_kfree;
}
@@ -1079,6 +1083,389 @@ static void privcmd_irqfd_exit(void)
destroy_workqueue(irqfd_cleanup_wq);
}
+
+/* Ioeventfd Support */
+#define QUEUE_NOTIFY_VQ_MASK 0xFFFF
+
+static DEFINE_MUTEX(ioreq_lock);
+static LIST_HEAD(ioreq_list);
+
+/* per-eventfd structure */
+struct privcmd_kernel_ioeventfd {
+ struct eventfd_ctx *eventfd;
+ struct list_head list;
+ u64 addr;
+ unsigned int addr_len;
+ unsigned int vq;
+};
+
+/* per-guest CPU / port structure */
+struct ioreq_port {
+ int vcpu;
+ unsigned int port;
+ struct privcmd_kernel_ioreq *kioreq;
+};
+
+/* per-guest structure */
+struct privcmd_kernel_ioreq {
+ domid_t dom;
+ unsigned int vcpus;
+ u64 uioreq;
+ struct ioreq *ioreq;
+ spinlock_t lock; /* Protects ioeventfds list */
+ struct list_head ioeventfds;
+ struct list_head list;
+ struct ioreq_port ports[0];
+};
+
+static irqreturn_t ioeventfd_interrupt(int irq, void *dev_id)
+{
+ struct ioreq_port *port = dev_id;
+ struct privcmd_kernel_ioreq *kioreq = port->kioreq;
+ struct ioreq *ioreq = &kioreq->ioreq[port->vcpu];
+ struct privcmd_kernel_ioeventfd *kioeventfd;
+ unsigned int state = STATE_IOREQ_READY;
+
+ if (ioreq->state != STATE_IOREQ_READY ||
+ ioreq->type != IOREQ_TYPE_COPY || ioreq->dir != IOREQ_WRITE)
+ return IRQ_NONE;
+
+ /*
+ * We need a barrier, smp_mb(), here to ensure reads are finished before
+ * `state` is updated. Since the lock implementation ensures that
+ * appropriate barrier will be added anyway, we can avoid adding
+ * explicit barrier here.
+ *
+ * Ideally we don't need to update `state` within the locks, but we do
+ * that here to avoid adding explicit barrier.
+ */
+
+ spin_lock(&kioreq->lock);
+ ioreq->state = STATE_IOREQ_INPROCESS;
+
+ list_for_each_entry(kioeventfd, &kioreq->ioeventfds, list) {
+ if (ioreq->addr == kioeventfd->addr + VIRTIO_MMIO_QUEUE_NOTIFY &&
+ ioreq->size == kioeventfd->addr_len &&
+ (ioreq->data & QUEUE_NOTIFY_VQ_MASK) == kioeventfd->vq) {
+ eventfd_signal(kioeventfd->eventfd, 1);
+ state = STATE_IORESP_READY;
+ break;
+ }
+ }
+ spin_unlock(&kioreq->lock);
+
+ /*
+ * We need a barrier, smp_mb(), here to ensure writes are finished
+ * before `state` is updated. Since the lock implementation ensures that
+ * appropriate barrier will be added anyway, we can avoid adding
+ * explicit barrier here.
+ */
+
+ ioreq->state = state;
+
+ if (state == STATE_IORESP_READY) {
+ notify_remote_via_evtchn(port->port);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static void ioreq_free(struct privcmd_kernel_ioreq *kioreq)
+{
+ struct ioreq_port *ports = kioreq->ports;
+ int i;
+
+ lockdep_assert_held(&ioreq_lock);
+
+ list_del(&kioreq->list);
+
+ for (i = kioreq->vcpus - 1; i >= 0; i--)
+ unbind_from_irqhandler(irq_from_evtchn(ports[i].port), &ports[i]);
+
+ kfree(kioreq);
+}
+
+static
+struct privcmd_kernel_ioreq *alloc_ioreq(struct privcmd_ioeventfd *ioeventfd)
+{
+ struct privcmd_kernel_ioreq *kioreq;
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ struct page **pages;
+ unsigned int *ports;
+ int ret, size, i;
+
+ lockdep_assert_held(&ioreq_lock);
+
+ size = struct_size(kioreq, ports, ioeventfd->vcpus);
+ kioreq = kzalloc(size, GFP_KERNEL);
+ if (!kioreq)
+ return ERR_PTR(-ENOMEM);
+
+ kioreq->dom = ioeventfd->dom;
+ kioreq->vcpus = ioeventfd->vcpus;
+ kioreq->uioreq = ioeventfd->ioreq;
+ spin_lock_init(&kioreq->lock);
+ INIT_LIST_HEAD(&kioreq->ioeventfds);
+
+ /* The memory for ioreq server must have been mapped earlier */
+ mmap_write_lock(mm);
+ vma = find_vma(mm, (unsigned long)ioeventfd->ioreq);
+ if (!vma) {
+ pr_err("Failed to find vma for ioreq page!\n");
+ mmap_write_unlock(mm);
+ ret = -EFAULT;
+ goto error_kfree;
+ }
+
+ pages = vma->vm_private_data;
+ kioreq->ioreq = (struct ioreq *)(page_to_virt(pages[0]));
+ mmap_write_unlock(mm);
+
+ size = sizeof(*ports) * kioreq->vcpus;
+ ports = kzalloc(size, GFP_KERNEL);
+ if (!ports) {
+ ret = -ENOMEM;
+ goto error_kfree;
+ }
+
+ if (copy_from_user(ports, u64_to_user_ptr(ioeventfd->ports), size)) {
+ ret = -EFAULT;
+ goto error_kfree_ports;
+ }
+
+ for (i = 0; i < kioreq->vcpus; i++) {
+ kioreq->ports[i].vcpu = i;
+ kioreq->ports[i].port = ports[i];
+ kioreq->ports[i].kioreq = kioreq;
+
+ ret = bind_evtchn_to_irqhandler_lateeoi(ports[i],
+ ioeventfd_interrupt, IRQF_SHARED, "ioeventfd",
+ &kioreq->ports[i]);
+ if (ret < 0)
+ goto error_unbind;
+ }
+
+ kfree(ports);
+
+ list_add_tail(&kioreq->list, &ioreq_list);
+
+ return kioreq;
+
+error_unbind:
+ while (--i >= 0)
+ unbind_from_irqhandler(irq_from_evtchn(ports[i]), &kioreq->ports[i]);
+error_kfree_ports:
+ kfree(ports);
+error_kfree:
+ kfree(kioreq);
+ return ERR_PTR(ret);
+}
+
+static struct privcmd_kernel_ioreq *
+get_ioreq(struct privcmd_ioeventfd *ioeventfd, struct eventfd_ctx *eventfd)
+{
+ struct privcmd_kernel_ioreq *kioreq;
+ unsigned long flags;
+
+ list_for_each_entry(kioreq, &ioreq_list, list) {
+ struct privcmd_kernel_ioeventfd *kioeventfd;
+
+ /*
+ * kioreq fields can be accessed here without a lock as they are
+ * never updated after being added to the ioreq_list.
+ */
+ if (kioreq->uioreq != ioeventfd->ioreq) {
+ continue;
+ } else if (kioreq->dom != ioeventfd->dom ||
+ kioreq->vcpus != ioeventfd->vcpus) {
+ pr_err("Invalid ioeventfd configuration mismatch, dom (%u vs %u), vcpus (%u vs %u)\n",
+ kioreq->dom, ioeventfd->dom, kioreq->vcpus,
+ ioeventfd->vcpus);
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* Look for a duplicate eventfd for the same guest */
+ spin_lock_irqsave(&kioreq->lock, flags);
+ list_for_each_entry(kioeventfd, &kioreq->ioeventfds, list) {
+ if (eventfd == kioeventfd->eventfd) {
+ spin_unlock_irqrestore(&kioreq->lock, flags);
+ return ERR_PTR(-EBUSY);
+ }
+ }
+ spin_unlock_irqrestore(&kioreq->lock, flags);
+
+ return kioreq;
+ }
+
+ /* Matching kioreq isn't found, allocate a new one */
+ return alloc_ioreq(ioeventfd);
+}
+
+static void ioeventfd_free(struct privcmd_kernel_ioeventfd *kioeventfd)
+{
+ list_del(&kioeventfd->list);
+ eventfd_ctx_put(kioeventfd->eventfd);
+ kfree(kioeventfd);
+}
+
+static int privcmd_ioeventfd_assign(struct privcmd_ioeventfd *ioeventfd)
+{
+ struct privcmd_kernel_ioeventfd *kioeventfd;
+ struct privcmd_kernel_ioreq *kioreq;
+ unsigned long flags;
+ struct fd f;
+ int ret;
+
+ /* Check for range overflow */
+ if (ioeventfd->addr + ioeventfd->addr_len < ioeventfd->addr)
+ return -EINVAL;
+
+ /* Vhost requires us to support length 1, 2, 4, and 8 */
+ if (!(ioeventfd->addr_len == 1 || ioeventfd->addr_len == 2 ||
+ ioeventfd->addr_len == 4 || ioeventfd->addr_len == 8))
+ return -EINVAL;
+
+ /* 4096 vcpus limit enough ? */
+ if (!ioeventfd->vcpus || ioeventfd->vcpus > 4096)
+ return -EINVAL;
+
+ kioeventfd = kzalloc(sizeof(*kioeventfd), GFP_KERNEL);
+ if (!kioeventfd)
+ return -ENOMEM;
+
+ f = fdget(ioeventfd->event_fd);
+ if (!f.file) {
+ ret = -EBADF;
+ goto error_kfree;
+ }
+
+ kioeventfd->eventfd = eventfd_ctx_fileget(f.file);
+ fdput(f);
+
+ if (IS_ERR(kioeventfd->eventfd)) {
+ ret = PTR_ERR(kioeventfd->eventfd);
+ goto error_kfree;
+ }
+
+ kioeventfd->addr = ioeventfd->addr;
+ kioeventfd->addr_len = ioeventfd->addr_len;
+ kioeventfd->vq = ioeventfd->vq;
+
+ mutex_lock(&ioreq_lock);
+ kioreq = get_ioreq(ioeventfd, kioeventfd->eventfd);
+ if (IS_ERR(kioreq)) {
+ mutex_unlock(&ioreq_lock);
+ ret = PTR_ERR(kioreq);
+ goto error_eventfd;
+ }
+
+ spin_lock_irqsave(&kioreq->lock, flags);
+ list_add_tail(&kioeventfd->list, &kioreq->ioeventfds);
+ spin_unlock_irqrestore(&kioreq->lock, flags);
+
+ mutex_unlock(&ioreq_lock);
+
+ return 0;
+
+error_eventfd:
+ eventfd_ctx_put(kioeventfd->eventfd);
+
+error_kfree:
+ kfree(kioeventfd);
+ return ret;
+}
+
+static int privcmd_ioeventfd_deassign(struct privcmd_ioeventfd *ioeventfd)
+{
+ struct privcmd_kernel_ioreq *kioreq, *tkioreq;
+ struct eventfd_ctx *eventfd;
+ unsigned long flags;
+ int ret = 0;
+
+ eventfd = eventfd_ctx_fdget(ioeventfd->event_fd);
+ if (IS_ERR(eventfd))
+ return PTR_ERR(eventfd);
+
+ mutex_lock(&ioreq_lock);
+ list_for_each_entry_safe(kioreq, tkioreq, &ioreq_list, list) {
+ struct privcmd_kernel_ioeventfd *kioeventfd, *tmp;
+ /*
+ * kioreq fields can be accessed here without a lock as they are
+ * never updated after being added to the ioreq_list.
+ */
+ if (kioreq->dom != ioeventfd->dom ||
+ kioreq->uioreq != ioeventfd->ioreq ||
+ kioreq->vcpus != ioeventfd->vcpus)
+ continue;
+
+ spin_lock_irqsave(&kioreq->lock, flags);
+ list_for_each_entry_safe(kioeventfd, tmp, &kioreq->ioeventfds, list) {
+ if (eventfd == kioeventfd->eventfd) {
+ ioeventfd_free(kioeventfd);
+ spin_unlock_irqrestore(&kioreq->lock, flags);
+
+ if (list_empty(&kioreq->ioeventfds))
+ ioreq_free(kioreq);
+ goto unlock;
+ }
+ }
+ spin_unlock_irqrestore(&kioreq->lock, flags);
+ break;
+ }
+
+ pr_err("Ioeventfd isn't already assigned, dom: %u, addr: %llu\n",
+ ioeventfd->dom, ioeventfd->addr);
+ ret = -ENODEV;
+
+unlock:
+ mutex_unlock(&ioreq_lock);
+ eventfd_ctx_put(eventfd);
+
+ return ret;
+}
+
+static long privcmd_ioctl_ioeventfd(struct file *file, void __user *udata)
+{
+ struct privcmd_data *data = file->private_data;
+ struct privcmd_ioeventfd ioeventfd;
+
+ if (copy_from_user(&ioeventfd, udata, sizeof(ioeventfd)))
+ return -EFAULT;
+
+ /* No other flags should be set */
+ if (ioeventfd.flags & ~PRIVCMD_IOEVENTFD_FLAG_DEASSIGN)
+ return -EINVAL;
+
+ /* If restriction is in place, check the domid matches */
+ if (data->domid != DOMID_INVALID && data->domid != ioeventfd.dom)
+ return -EPERM;
+
+ if (ioeventfd.flags & PRIVCMD_IOEVENTFD_FLAG_DEASSIGN)
+ return privcmd_ioeventfd_deassign(&ioeventfd);
+
+ return privcmd_ioeventfd_assign(&ioeventfd);
+}
+
+static void privcmd_ioeventfd_exit(void)
+{
+ struct privcmd_kernel_ioreq *kioreq, *tmp;
+ unsigned long flags;
+
+ mutex_lock(&ioreq_lock);
+ list_for_each_entry_safe(kioreq, tmp, &ioreq_list, list) {
+ struct privcmd_kernel_ioeventfd *kioeventfd, *tmp;
+
+ spin_lock_irqsave(&kioreq->lock, flags);
+ list_for_each_entry_safe(kioeventfd, tmp, &kioreq->ioeventfds, list)
+ ioeventfd_free(kioeventfd);
+ spin_unlock_irqrestore(&kioreq->lock, flags);
+
+ ioreq_free(kioreq);
+ }
+ mutex_unlock(&ioreq_lock);
+}
#else
static inline long privcmd_ioctl_irqfd(struct file *file, void __user *udata)
{
@@ -1093,7 +1480,16 @@ static inline int privcmd_irqfd_init(void)
static inline void privcmd_irqfd_exit(void)
{
}
-#endif /* CONFIG_XEN_PRIVCMD_IRQFD */
+
+static inline long privcmd_ioctl_ioeventfd(struct file *file, void __user *udata)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void privcmd_ioeventfd_exit(void)
+{
+}
+#endif /* CONFIG_XEN_PRIVCMD_EVENTFD */
static long privcmd_ioctl(struct file *file,
unsigned int cmd, unsigned long data)
@@ -1134,6 +1530,10 @@ static long privcmd_ioctl(struct file *file,
ret = privcmd_ioctl_irqfd(file, udata);
break;
+ case IOCTL_PRIVCMD_IOEVENTFD:
+ ret = privcmd_ioctl_ioeventfd(file, udata);
+ break;
+
default:
break;
}
@@ -1278,6 +1678,7 @@ err_privcmdbuf:
static void __exit privcmd_exit(void)
{
+ privcmd_ioeventfd_exit();
privcmd_irqfd_exit();
misc_deregister(&privcmd_dev);
misc_deregister(&xen_privcmdbuf_dev);
diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c
index 059de92aea7d..d47eee6c5143 100644
--- a/drivers/xen/xen-pciback/conf_space.c
+++ b/drivers/xen/xen-pciback/conf_space.c
@@ -288,12 +288,6 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev)
u16 val;
int ret = 0;
- err = pci_read_config_word(dev, PCI_COMMAND, &val);
- if (err)
- return err;
- if (!(val & PCI_COMMAND_INTX_DISABLE))
- ret |= INTERRUPT_TYPE_INTX;
-
/*
* Do not trust dev->msi(x)_enabled here, as enabling could be done
* bypassing the pci_*msi* functions, by the qemu.
@@ -316,6 +310,19 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev)
if (val & PCI_MSIX_FLAGS_ENABLE)
ret |= INTERRUPT_TYPE_MSIX;
}
+
+ /*
+ * PCIe spec says device cannot use INTx if MSI/MSI-X is enabled,
+ * so check for INTx only when both are disabled.
+ */
+ if (!ret) {
+ err = pci_read_config_word(dev, PCI_COMMAND, &val);
+ if (err)
+ return err;
+ if (!(val & PCI_COMMAND_INTX_DISABLE))
+ ret |= INTERRUPT_TYPE_INTX;
+ }
+
return ret ?: INTERRUPT_TYPE_NONE;
}
diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c
index 097316a74126..1948a9700c8f 100644
--- a/drivers/xen/xen-pciback/conf_space_capability.c
+++ b/drivers/xen/xen-pciback/conf_space_capability.c
@@ -236,10 +236,16 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
return PCIBIOS_SET_FAILED;
if (new_value & field_config->enable_bit) {
- /* don't allow enabling together with other interrupt types */
+ /*
+ * Don't allow enabling together with other interrupt type, but do
+ * allow enabling MSI(-X) while INTx is still active to please Linuxes
+ * MSI(-X) startup sequence. It is safe to do, as according to PCI
+ * spec, device with enabled MSI(-X) shouldn't use INTx.
+ */
int int_type = xen_pcibk_get_interrupt_type(dev);
if (int_type == INTERRUPT_TYPE_NONE ||
+ int_type == INTERRUPT_TYPE_INTX ||
int_type == field_config->int_type)
goto write;
return PCIBIOS_SET_FAILED;
diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c
index 981435103af1..fc0332645966 100644
--- a/drivers/xen/xen-pciback/conf_space_header.c
+++ b/drivers/xen/xen-pciback/conf_space_header.c
@@ -104,24 +104,9 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
pci_clear_mwi(dev);
}
- if (dev_data && dev_data->allow_interrupt_control) {
- if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) {
- if (value & PCI_COMMAND_INTX_DISABLE) {
- pci_intx(dev, 0);
- } else {
- /* Do not allow enabling INTx together with MSI or MSI-X. */
- switch (xen_pcibk_get_interrupt_type(dev)) {
- case INTERRUPT_TYPE_NONE:
- pci_intx(dev, 1);
- break;
- case INTERRUPT_TYPE_INTX:
- break;
- default:
- return PCIBIOS_SET_FAILED;
- }
- }
- }
- }
+ if (dev_data && dev_data->allow_interrupt_control &&
+ ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE))
+ pci_intx(dev, !(value & PCI_COMMAND_INTX_DISABLE));
cmd->val = value;
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
index 0792fda49a15..6f56640092a9 100644
--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -82,7 +82,7 @@ struct read_buffer {
struct list_head list;
unsigned int cons;
unsigned int len;
- char msg[];
+ char msg[] __counted_by(len);
};
struct xenbus_file_priv {
@@ -195,7 +195,7 @@ static int queue_reply(struct list_head *queue, const void *data, size_t len)
if (len > XENSTORE_PAYLOAD_MAX)
return -EINVAL;
- rb = kmalloc(sizeof(*rb) + len, GFP_KERNEL);
+ rb = kmalloc(struct_size(rb, msg, len), GFP_KERNEL);
if (rb == NULL)
return -ENOMEM;
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 639bf628389b..3205e5d724c8 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -1025,7 +1025,7 @@ static int __init xenbus_init(void)
if (err < 0) {
pr_err("xenstore_late_init couldn't bind irq err=%d\n",
err);
- return err;
+ goto out_error;
}
xs_init_irq = err;
diff --git a/fs/Kconfig b/fs/Kconfig
index 0d6cb927872a..fd1f655b4f1f 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -256,7 +256,7 @@ config ARCH_SUPPORTS_HUGETLBFS
config HUGETLBFS
bool "HugeTLB file system support"
- depends on X86 || IA64 || SPARC64 || ARCH_SUPPORTS_HUGETLBFS || BROKEN
+ depends on X86 || SPARC64 || ARCH_SUPPORTS_HUGETLBFS || BROKEN
depends on (SYSFS || SYSCTL)
select MEMFD_CREATE
help
diff --git a/fs/afs/main.c b/fs/afs/main.c
index eae288c8d40a..6425c81d07de 100644
--- a/fs/afs/main.c
+++ b/fs/afs/main.c
@@ -41,8 +41,6 @@ const char afs_init_sysname[] = "arm_linux26";
const char afs_init_sysname[] = "aarch64_linux26";
#elif defined(CONFIG_X86_32)
const char afs_init_sysname[] = "i386_linux26";
-#elif defined(CONFIG_IA64)
-const char afs_init_sysname[] = "ia64_linux26";
#elif defined(CONFIG_PPC64)
const char afs_init_sysname[] = "ppc64_linux26";
#elif defined(CONFIG_PPC32)
diff --git a/fs/proc/bootconfig.c b/fs/proc/bootconfig.c
index 2e244ada1f97..902b326e1e56 100644
--- a/fs/proc/bootconfig.c
+++ b/fs/proc/bootconfig.c
@@ -62,6 +62,12 @@ static int __init copy_xbc_key_value_list(char *dst, size_t size)
break;
dst += ret;
}
+ if (ret >= 0 && boot_command_line[0]) {
+ ret = snprintf(dst, rest(dst, end), "# Parameters from bootloader:\n# %s\n",
+ boot_command_line);
+ if (ret > 0)
+ dst += ret;
+ }
}
out:
kfree(key);
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index bc9a2db89cfa..8064ea76f80b 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -1576,7 +1576,6 @@ static const struct sysctl_alias sysctl_aliases[] = {
{"hung_task_panic", "kernel.hung_task_panic" },
{"numa_zonelist_order", "vm.numa_zonelist_order" },
{"softlockup_all_cpu_backtrace", "kernel.softlockup_all_cpu_backtrace" },
- {"softlockup_panic", "kernel.softlockup_panic" },
{ }
};
@@ -1592,6 +1591,13 @@ static const char *sysctl_find_alias(char *param)
return NULL;
}
+bool sysctl_is_alias(char *param)
+{
+ const char *alias = sysctl_find_alias(param);
+
+ return alias != NULL;
+}
+
/* Set sysctl value passed on kernel command line. */
static int process_sysctl_arg(char *param, char *val,
const char *unused, void *arg)
diff --git a/fs/xfs/xfs_ioctl32.h b/fs/xfs/xfs_ioctl32.h
index c14852362fce..052d0e888c27 100644
--- a/fs/xfs/xfs_ioctl32.h
+++ b/fs/xfs/xfs_ioctl32.h
@@ -22,7 +22,7 @@
/*
* On intel, even if sizes match, alignment and/or padding may differ.
*/
-#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_64)
#define BROKEN_X86_ALIGNMENT
#define __compat_packed __attribute__((packed))
#else
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index 941be574bbe0..def242528b1d 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -2,7 +2,7 @@
#
# asm headers that all architectures except um should have
# (This file is not included when SRCARCH=um since UML borrows several
-# asm headers from the host architecutre.)
+# asm headers from the host architecture.)
mandatory-y += atomic.h
mandatory-y += archrandom.h
diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h
index be12e1dd1f38..f7248348a459 100644
--- a/include/dt-bindings/arm/qcom,ids.h
+++ b/include/dt-bindings/arm/qcom,ids.h
@@ -193,6 +193,7 @@
#define QCOM_ID_SDA439 363
#define QCOM_ID_SDA429 364
#define QCOM_ID_SM7150 365
+#define QCOM_ID_SM7150P 366
#define QCOM_ID_IPQ8070 375
#define QCOM_ID_IPQ8071 376
#define QCOM_ID_QM215 386
@@ -203,6 +204,9 @@
#define QCOM_ID_SM6125 394
#define QCOM_ID_IPQ8070A 395
#define QCOM_ID_IPQ8071A 396
+#define QCOM_ID_IPQ8172 397
+#define QCOM_ID_IPQ8173 398
+#define QCOM_ID_IPQ8174 399
#define QCOM_ID_IPQ6018 402
#define QCOM_ID_IPQ6028 403
#define QCOM_ID_SDM429W 416
@@ -233,6 +237,7 @@
#define QCOM_ID_SM8450_3 482
#define QCOM_ID_SC7280 487
#define QCOM_ID_SC7180P 495
+#define QCOM_ID_QCM6490 497
#define QCOM_ID_IPQ5000 503
#define QCOM_ID_IPQ0509 504
#define QCOM_ID_IPQ0518 505
diff --git a/include/dt-bindings/power/amlogic,t7-pwrc.h b/include/dt-bindings/power/amlogic,t7-pwrc.h
new file mode 100644
index 000000000000..1f1f2739cc26
--- /dev/null
+++ b/include/dt-bindings/power/amlogic,t7-pwrc.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2023 Amlogic, Inc.
+ * Author: Hongyu Chen <hongyu.chen1@amlogic.com>
+ */
+#ifndef _DT_BINDINGS_AMLOGIC_T7_POWER_H
+#define _DT_BINDINGS_AMLOGIC_T7_POWER_H
+
+#define PWRC_T7_DSPA_ID 0
+#define PWRC_T7_DSPB_ID 1
+#define PWRC_T7_DOS_HCODEC_ID 2
+#define PWRC_T7_DOS_HEVC_ID 3
+#define PWRC_T7_DOS_VDEC_ID 4
+#define PWRC_T7_DOS_WAVE_ID 5
+#define PWRC_T7_VPU_HDMI_ID 6
+#define PWRC_T7_USB_COMB_ID 7
+#define PWRC_T7_PCIE_ID 8
+#define PWRC_T7_GE2D_ID 9
+#define PWRC_T7_SRAMA_ID 10
+#define PWRC_T7_SRAMB_ID 11
+#define PWRC_T7_HDMIRX_ID 12
+#define PWRC_T7_VI_CLK1_ID 13
+#define PWRC_T7_VI_CLK2_ID 14
+#define PWRC_T7_ETH_ID 15
+#define PWRC_T7_ISP_ID 16
+#define PWRC_T7_MIPI_ISP_ID 17
+#define PWRC_T7_GDC_ID 18
+#define PWRC_T7_CVE_ID 18
+#define PWRC_T7_DEWARP_ID 19
+#define PWRC_T7_SDIO_A_ID 20
+#define PWRC_T7_SDIO_B_ID 21
+#define PWRC_T7_EMMC_ID 22
+#define PWRC_T7_MALI_SC0_ID 23
+#define PWRC_T7_MALI_SC1_ID 24
+#define PWRC_T7_MALI_SC2_ID 25
+#define PWRC_T7_MALI_SC3_ID 26
+#define PWRC_T7_MALI_TOP_ID 27
+#define PWRC_T7_NNA_CORE0_ID 28
+#define PWRC_T7_NNA_CORE1_ID 29
+#define PWRC_T7_NNA_CORE2_ID 30
+#define PWRC_T7_NNA_CORE3_ID 31
+#define PWRC_T7_NNA_TOP_ID 32
+#define PWRC_T7_DDR0_ID 33
+#define PWRC_T7_DDR1_ID 34
+#define PWRC_T7_DMC0_ID 35
+#define PWRC_T7_DMC1_ID 36
+#define PWRC_T7_NOC_ID 37
+#define PWRC_T7_NIC2_ID 38
+#define PWRC_T7_NIC3_ID 39
+#define PWRC_T7_CCI_ID 40
+#define PWRC_T7_MIPI_DSI0_ID 41
+#define PWRC_T7_SPICC0_ID 42
+#define PWRC_T7_SPICC1_ID 43
+#define PWRC_T7_SPICC2_ID 44
+#define PWRC_T7_SPICC3_ID 45
+#define PWRC_T7_SPICC4_ID 46
+#define PWRC_T7_SPICC5_ID 47
+#define PWRC_T7_EDP0_ID 48
+#define PWRC_T7_EDP1_ID 49
+#define PWRC_T7_MIPI_DSI1_ID 50
+#define PWRC_T7_AUDIO_ID 51
+
+#endif
diff --git a/include/dt-bindings/power/mediatek,mt8365-power.h b/include/dt-bindings/power/mediatek,mt8365-power.h
new file mode 100644
index 000000000000..e6cfd0ec7871
--- /dev/null
+++ b/include/dt-bindings/power/mediatek,mt8365-power.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_POWER_MT8365_POWER_H
+#define _DT_BINDINGS_POWER_MT8365_POWER_H
+
+#define MT8365_POWER_DOMAIN_MM 0
+#define MT8365_POWER_DOMAIN_CONN 1
+#define MT8365_POWER_DOMAIN_MFG 2
+#define MT8365_POWER_DOMAIN_AUDIO 3
+#define MT8365_POWER_DOMAIN_CAM 4
+#define MT8365_POWER_DOMAIN_DSP 5
+#define MT8365_POWER_DOMAIN_VDEC 6
+#define MT8365_POWER_DOMAIN_VENC 7
+#define MT8365_POWER_DOMAIN_APU 8
+
+#endif /* _DT_BINDINGS_POWER_MT8365_POWER_H */
diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h
index 7c201a66bc69..e54ffa361451 100644
--- a/include/dt-bindings/power/qcom,rpmhpd.h
+++ b/include/dt-bindings/power/qcom,rpmhpd.h
@@ -26,5 +26,7 @@
#define RPMHPD_QPHY 16
#define RPMHPD_DDR 17
#define RPMHPD_XO 18
+#define RPMHPD_NSP2 19
+#define RPMHPD_GMXC 20
#endif
diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
index 83be996cb5eb..7f4e2983a4c5 100644
--- a/include/dt-bindings/power/qcom-rpmpd.h
+++ b/include/dt-bindings/power/qcom-rpmpd.h
@@ -278,6 +278,27 @@
#define MSM8909_VDDMX MSM8916_VDDMX
#define MSM8909_VDDMX_AO MSM8916_VDDMX_AO
+/* MSM8917 Power Domain Indexes */
+#define MSM8917_VDDCX 0
+#define MSM8917_VDDCX_AO 1
+#define MSM8917_VDDCX_VFL 2
+#define MSM8917_VDDMX 3
+#define MSM8917_VDDMX_AO 4
+
+/* MSM8937 Power Domain Indexes */
+#define MSM8937_VDDCX MSM8917_VDDCX
+#define MSM8937_VDDCX_AO MSM8917_VDDCX_AO
+#define MSM8937_VDDCX_VFL MSM8917_VDDCX_VFL
+#define MSM8937_VDDMX MSM8917_VDDMX
+#define MSM8937_VDDMX_AO MSM8917_VDDMX_AO
+
+/* QM215 Power Domain Indexes */
+#define QM215_VDDCX MSM8917_VDDCX
+#define QM215_VDDCX_AO MSM8917_VDDCX_AO
+#define QM215_VDDCX_VFL MSM8917_VDDCX_VFL
+#define QM215_VDDMX MSM8917_VDDMX
+#define QM215_VDDMX_AO MSM8917_VDDMX_AO
+
/* MSM8953 Power Domain Indexes */
#define MSM8953_VDDMD 0
#define MSM8953_VDDMD_AO 1
diff --git a/include/dt-bindings/power/starfive,jh7110-pmu.h b/include/dt-bindings/power/starfive,jh7110-pmu.h
index 132bfe401fc8..7b4f24927dee 100644
--- a/include/dt-bindings/power/starfive,jh7110-pmu.h
+++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
* Author: Walker Chen <walker.chen@starfivetech.com>
*/
#ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
@@ -14,4 +14,8 @@
#define JH7110_PD_ISP 5
#define JH7110_PD_VENC 6
+/* AON Power Domain */
+#define JH7110_AON_PD_DPHY_TX 0
+#define JH7110_AON_PD_DPHY_RX 1
+
#endif
diff --git a/include/kunit/test.h b/include/kunit/test.h
index 68ff01aee244..20ed9f9275c9 100644
--- a/include/kunit/test.h
+++ b/include/kunit/test.h
@@ -33,9 +33,7 @@
DECLARE_STATIC_KEY_FALSE(kunit_running);
struct kunit;
-
-/* Size of log associated with test. */
-#define KUNIT_LOG_SIZE 2048
+struct string_stream;
/* Maximum size of parameter description string. */
#define KUNIT_PARAM_DESC_SIZE 128
@@ -133,7 +131,7 @@ struct kunit_case {
/* private: internal use only. */
enum kunit_status status;
char *module_name;
- char *log;
+ struct string_stream *log;
};
static inline char *kunit_status_to_ok_not_ok(enum kunit_status status)
@@ -253,7 +251,7 @@ struct kunit_suite {
/* private: internal use only */
char status_comment[KUNIT_STATUS_COMMENT_SIZE];
struct dentry *debugfs;
- char *log;
+ struct string_stream *log;
int suite_init_err;
};
@@ -279,7 +277,7 @@ struct kunit {
/* private: internal use only. */
const char *name; /* Read only after initialization! */
- char *log; /* Points at case log after initialization */
+ struct string_stream *log; /* Points at case log after initialization */
struct kunit_try_catch try_catch;
/* param_value is the current parameter value for a test case. */
const void *param_value;
@@ -315,7 +313,7 @@ const char *kunit_filter_glob(void);
char *kunit_filter(void);
char *kunit_filter_action(void);
-void kunit_init_test(struct kunit *test, const char *name, char *log);
+void kunit_init_test(struct kunit *test, const char *name, struct string_stream *log);
int kunit_run_tests(struct kunit_suite *suite);
@@ -473,7 +471,7 @@ static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp
void kunit_cleanup(struct kunit *test);
-void __printf(2, 3) kunit_log_append(char *log, const char *fmt, ...);
+void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, ...);
/**
* kunit_mark_skipped() - Marks @test_or_suite as skipped
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index db3a33e19c97..24e014760328 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -256,10 +256,15 @@ acpi_table_parse_cedt(enum acpi_cedt_type id,
int acpi_parse_mcfg (struct acpi_table_header *header);
void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
+static inline bool acpi_gicc_is_usable(struct acpi_madt_generic_interrupt *gicc)
+{
+ return gicc->flags & ACPI_MADT_ENABLED;
+}
+
/* the following numa functions are architecture-dependent */
void acpi_numa_slit_init (struct acpi_table_slit *slit);
-#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_LOONGARCH)
+#if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH)
void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
#else
static inline void
@@ -1119,15 +1124,8 @@ static inline int acpi_get_lps0_constraint(struct device *dev)
return ACPI_STATE_UNKNOWN;
}
#endif /* CONFIG_SUSPEND && CONFIG_X86 */
-#ifndef CONFIG_IA64
void arch_reserve_mem_area(acpi_physical_address addr, size_t size);
#else
-static inline void arch_reserve_mem_area(acpi_physical_address addr,
- size_t size)
-{
-}
-#endif /* CONFIG_X86 */
-#else
#define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
#endif
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index cc060da51bec..1abedb5b2e48 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -6,6 +6,7 @@
#ifndef _LINUX_ARM_FFA_H
#define _LINUX_ARM_FFA_H
+#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -20,6 +21,7 @@
#define FFA_ERROR FFA_SMC_32(0x60)
#define FFA_SUCCESS FFA_SMC_32(0x61)
+#define FFA_FN64_SUCCESS FFA_SMC_64(0x61)
#define FFA_INTERRUPT FFA_SMC_32(0x62)
#define FFA_VERSION FFA_SMC_32(0x63)
#define FFA_FEATURES FFA_SMC_32(0x64)
@@ -54,6 +56,23 @@
#define FFA_MEM_FRAG_RX FFA_SMC_32(0x7A)
#define FFA_MEM_FRAG_TX FFA_SMC_32(0x7B)
#define FFA_NORMAL_WORLD_RESUME FFA_SMC_32(0x7C)
+#define FFA_NOTIFICATION_BITMAP_CREATE FFA_SMC_32(0x7D)
+#define FFA_NOTIFICATION_BITMAP_DESTROY FFA_SMC_32(0x7E)
+#define FFA_NOTIFICATION_BIND FFA_SMC_32(0x7F)
+#define FFA_NOTIFICATION_UNBIND FFA_SMC_32(0x80)
+#define FFA_NOTIFICATION_SET FFA_SMC_32(0x81)
+#define FFA_NOTIFICATION_GET FFA_SMC_32(0x82)
+#define FFA_NOTIFICATION_INFO_GET FFA_SMC_32(0x83)
+#define FFA_FN64_NOTIFICATION_INFO_GET FFA_SMC_64(0x83)
+#define FFA_RX_ACQUIRE FFA_SMC_32(0x84)
+#define FFA_SPM_ID_GET FFA_SMC_32(0x85)
+#define FFA_MSG_SEND2 FFA_SMC_32(0x86)
+#define FFA_SECONDARY_EP_REGISTER FFA_SMC_32(0x87)
+#define FFA_FN64_SECONDARY_EP_REGISTER FFA_SMC_64(0x87)
+#define FFA_MEM_PERM_GET FFA_SMC_32(0x88)
+#define FFA_FN64_MEM_PERM_GET FFA_SMC_64(0x88)
+#define FFA_MEM_PERM_SET FFA_SMC_32(0x89)
+#define FFA_FN64_MEM_PERM_SET FFA_SMC_64(0x89)
/*
* For some calls it is necessary to use SMC64 to pass or return 64-bit values.
@@ -76,6 +95,7 @@
#define FFA_RET_DENIED (-6)
#define FFA_RET_RETRY (-7)
#define FFA_RET_ABORTED (-8)
+#define FFA_RET_NO_DATA (-9)
/* FFA version encoding */
#define FFA_MAJOR_VERSION_MASK GENMASK(30, 16)
@@ -86,6 +106,7 @@
(FIELD_PREP(FFA_MAJOR_VERSION_MASK, (major)) | \
FIELD_PREP(FFA_MINOR_VERSION_MASK, (minor)))
#define FFA_VERSION_1_0 FFA_PACK_VERSION_INFO(1, 0)
+#define FFA_VERSION_1_1 FFA_PACK_VERSION_INFO(1, 1)
/**
* FF-A specification mentions explicitly about '4K pages'. This should
@@ -278,8 +299,8 @@ struct ffa_mem_region {
#define FFA_MEM_NON_SHAREABLE (0)
#define FFA_MEM_OUTER_SHAREABLE (2)
#define FFA_MEM_INNER_SHAREABLE (3)
- u8 attributes;
- u8 reserved_0;
+ /* Memory region attributes, upper byte MBZ pre v1.1 */
+ u16 attributes;
/*
* Clear memory region contents after unmapping it from the sender and
* before mapping it for any receiver.
@@ -317,27 +338,41 @@ struct ffa_mem_region {
* memory region.
*/
u64 tag;
- u32 reserved_1;
+ /* Size of each endpoint memory access descriptor, MBZ pre v1.1 */
+ u32 ep_mem_size;
/*
* The number of `ffa_mem_region_attributes` entries included in this
* transaction.
*/
u32 ep_count;
/*
- * An array of endpoint memory access descriptors.
- * Each one specifies a memory region offset, an endpoint and the
- * attributes with which this memory region should be mapped in that
- * endpoint's page table.
+ * 16-byte aligned offset from the base address of this descriptor
+ * to the first element of the endpoint memory access descriptor array
+ * Valid only from v1.1
*/
- struct ffa_mem_region_attributes ep_mem_access[];
+ u32 ep_mem_offset;
+ /* MBZ, valid only from v1.1 */
+ u32 reserved[3];
};
-#define COMPOSITE_OFFSET(x) \
- (offsetof(struct ffa_mem_region, ep_mem_access[x]))
#define CONSTITUENTS_OFFSET(x) \
(offsetof(struct ffa_composite_mem_region, constituents[x]))
-#define COMPOSITE_CONSTITUENTS_OFFSET(x, y) \
- (COMPOSITE_OFFSET(x) + CONSTITUENTS_OFFSET(y))
+
+static inline u32
+ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)
+{
+ u32 offset = count * sizeof(struct ffa_mem_region_attributes);
+ /*
+ * Earlier to v1.1, the endpoint memory descriptor array started at
+ * offset 32(i.e. offset of ep_mem_offset in the current structure)
+ */
+ if (ffa_version <= FFA_VERSION_1_0)
+ offset += offsetof(struct ffa_mem_region, ep_mem_offset);
+ else
+ offset += sizeof(struct ffa_mem_region);
+
+ return offset;
+}
struct ffa_mem_ops_args {
bool use_txbuf;
@@ -367,10 +402,30 @@ struct ffa_mem_ops {
int (*memory_lend)(struct ffa_mem_ops_args *args);
};
+struct ffa_cpu_ops {
+ int (*run)(struct ffa_device *dev, u16 vcpu);
+};
+
+typedef void (*ffa_sched_recv_cb)(u16 vcpu, bool is_per_vcpu, void *cb_data);
+typedef void (*ffa_notifier_cb)(int notify_id, void *cb_data);
+
+struct ffa_notifier_ops {
+ int (*sched_recv_cb_register)(struct ffa_device *dev,
+ ffa_sched_recv_cb cb, void *cb_data);
+ int (*sched_recv_cb_unregister)(struct ffa_device *dev);
+ int (*notify_request)(struct ffa_device *dev, bool per_vcpu,
+ ffa_notifier_cb cb, void *cb_data, int notify_id);
+ int (*notify_relinquish)(struct ffa_device *dev, int notify_id);
+ int (*notify_send)(struct ffa_device *dev, int notify_id, bool per_vcpu,
+ u16 vcpu);
+};
+
struct ffa_ops {
const struct ffa_info_ops *info_ops;
const struct ffa_msg_ops *msg_ops;
const struct ffa_mem_ops *mem_ops;
+ const struct ffa_cpu_ops *cpu_ops;
+ const struct ffa_notifier_ops *notifier_ops;
};
#endif /* _LINUX_ARM_FFA_H */
diff --git a/include/linux/badblocks.h b/include/linux/badblocks.h
index 2426276b9bd3..670f2dae692f 100644
--- a/include/linux/badblocks.h
+++ b/include/linux/badblocks.h
@@ -15,6 +15,7 @@
#define BB_OFFSET(x) (((x) & BB_OFFSET_MASK) >> 9)
#define BB_LEN(x) (((x) & BB_LEN_MASK) + 1)
#define BB_ACK(x) (!!((x) & BB_ACK_MASK))
+#define BB_END(x) (BB_OFFSET(x) + BB_LEN(x))
#define BB_MAKE(a, l, ack) (((a)<<9) | ((l)-1) | ((u64)(!!(ack)) << 63))
/* Bad block numbers are stored sorted in a single page.
@@ -41,6 +42,12 @@ struct badblocks {
sector_t size; /* in sectors */
};
+struct badblocks_context {
+ sector_t start;
+ sector_t len;
+ int ack;
+};
+
int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
sector_t *first_bad, int *bad_sectors);
int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
@@ -63,4 +70,27 @@ static inline void devm_exit_badblocks(struct device *dev, struct badblocks *bb)
}
badblocks_exit(bb);
}
+
+static inline int badblocks_full(struct badblocks *bb)
+{
+ return (bb->count >= MAX_BADBLOCKS);
+}
+
+static inline int badblocks_empty(struct badblocks *bb)
+{
+ return (bb->count == 0);
+}
+
+static inline void set_changed(struct badblocks *bb)
+{
+ if (bb->changed != 1)
+ bb->changed = 1;
+}
+
+static inline void clear_changed(struct badblocks *bb)
+{
+ if (bb->changed != 0)
+ bb->changed = 0;
+}
+
#endif
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 958ed7e89b30..1ab3081c82ed 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -32,8 +32,6 @@ typedef __u32 __bitwise req_flags_t;
#define RQF_FLUSH_SEQ ((__force req_flags_t)(1 << 4))
/* merge of different types, fail separately */
#define RQF_MIXED_MERGE ((__force req_flags_t)(1 << 5))
-/* track inflight for MQ */
-#define RQF_MQ_INFLIGHT ((__force req_flags_t)(1 << 6))
/* don't call prep for this one */
#define RQF_DONTPREP ((__force req_flags_t)(1 << 7))
/* use hctx->sched_tags */
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 98b8cea904fe..a789266feac3 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -143,11 +143,12 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
enum cgroup_bpf_attach_type atype);
int __cgroup_bpf_run_filter_setsockopt(struct sock *sock, int *level,
- int *optname, char __user *optval,
+ int *optname, sockptr_t optval,
int *optlen, char **kernel_optval);
+
int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
- int optname, char __user *optval,
- int __user *optlen, int max_optlen,
+ int optname, sockptr_t optval,
+ sockptr_t optlen, int max_optlen,
int retval);
int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level,
@@ -392,7 +393,7 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
({ \
int __ret = 0; \
if (cgroup_bpf_enabled(CGROUP_GETSOCKOPT)) \
- get_user(__ret, optlen); \
+ copy_from_sockptr(&__ret, optlen, sizeof(int)); \
__ret; \
})
diff --git a/include/linux/cdx/cdx_bus.h b/include/linux/cdx/cdx_bus.h
index bead71b7bc73..8320ec3b9e37 100644
--- a/include/linux/cdx/cdx_bus.h
+++ b/include/linux/cdx/cdx_bus.h
@@ -21,11 +21,13 @@
struct cdx_controller;
enum {
+ CDX_DEV_BUS_MASTER_CONF,
CDX_DEV_RESET_CONF,
};
struct cdx_device_config {
u8 type;
+ bool bus_master_enable;
};
typedef int (*cdx_scan_cb)(struct cdx_controller *cdx);
@@ -170,4 +172,20 @@ extern struct bus_type cdx_bus_type;
*/
int cdx_dev_reset(struct device *dev);
+/**
+ * cdx_set_master - enables bus-mastering for CDX device
+ * @cdx_dev: the CDX device to enable
+ *
+ * Return: 0 for success, -errno on failure
+ */
+int cdx_set_master(struct cdx_device *cdx_dev);
+
+/**
+ * cdx_clear_master - disables bus-mastering for CDX device
+ * @cdx_dev: the CDX device to disable
+ *
+ * Return: 0 for success, -errno on failure
+ */
+int cdx_clear_master(struct cdx_device *cdx_dev);
+
#endif /* _CDX_BUS_H_ */
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 1cfa4f0f490a..233f61ec8afc 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -581,7 +581,6 @@ asmlinkage long compat_sys_io_pgetevents_time64(compat_aio_context_t ctx_id,
struct io_event __user *events,
struct __kernel_timespec __user *timeout,
const struct __compat_aio_sigset __user *usig);
-asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t);
asmlinkage long compat_sys_epoll_pwait(int epfd,
struct epoll_event __user *events,
int maxevents, int timeout,
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index d246d325918a..d305db70674b 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -172,6 +172,7 @@ enum cpuhp_state {
CPUHP_AP_ARM_L2X0_STARTING,
CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING,
CPUHP_AP_ARM_ARCH_TIMER_STARTING,
+ CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING,
CPUHP_AP_ARM_GLOBAL_TIMER_STARTING,
CPUHP_AP_JCORE_TIMER_STARTING,
CPUHP_AP_ARM_TWD_STARTING,
@@ -189,6 +190,7 @@ enum cpuhp_state {
/* Must be the last timer callback */
CPUHP_AP_DUMMY_TIMER_STARTING,
CPUHP_AP_ARM_XEN_STARTING,
+ CPUHP_AP_ARM_XEN_RUNSTATE_STARTING,
CPUHP_AP_ARM_CORESIGHT_STARTING,
CPUHP_AP_ARM_CORESIGHT_CTI_STARTING,
CPUHP_AP_ARM64_ISNDEP_STARTING,
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 80b21d1c6eaf..9cc5bf32f6f2 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -358,13 +358,10 @@ void efi_native_runtime_setup(void);
* where the UEFI SPEC breaks the line.
*/
#define NULL_GUID EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
-#define MPS_TABLE_GUID EFI_GUID(0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
#define ACPI_TABLE_GUID EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
#define ACPI_20_TABLE_GUID EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
#define SMBIOS_TABLE_GUID EFI_GUID(0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
#define SMBIOS3_TABLE_GUID EFI_GUID(0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94)
-#define SAL_SYSTEM_TABLE_GUID EFI_GUID(0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
-#define HCDP_TABLE_GUID EFI_GUID(0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98)
#define UGA_IO_PROTOCOL_GUID EFI_GUID(0x61a4d49e, 0x6f68, 0x4f1b, 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0x0b, 0x07, 0xa2)
#define EFI_GLOBAL_VARIABLE_GUID EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
#define UV_SYSTEM_TABLE_GUID EFI_GUID(0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93)
@@ -851,10 +848,6 @@ static inline int efi_range_is_wc(unsigned long start, unsigned long len)
return 1;
}
-#ifdef CONFIG_EFI_PCDP
-extern int __init efi_setup_pcdp_console(char *);
-#endif
-
/*
* We play games with efi_enabled so that the compiler will, if
* possible, remove EFI-related code altogether.
diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h
index 95b0da2326a9..8eaf8922ab02 100644
--- a/include/linux/firmware/meson/meson_sm.h
+++ b/include/linux/firmware/meson/meson_sm.h
@@ -19,7 +19,7 @@ enum {
struct meson_sm_firmware;
int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
- u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+ s32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
unsigned int b_size, unsigned int cmd_index, u32 arg0,
u32 arg1, u32 arg2, u32 arg3, u32 arg4);
diff --git a/include/linux/firmware/qcom/qcom_qseecom.h b/include/linux/firmware/qcom/qcom_qseecom.h
new file mode 100644
index 000000000000..5c28298a98be
--- /dev/null
+++ b/include/linux/firmware/qcom/qcom_qseecom.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Driver for Qualcomm Secure Execution Environment (SEE) interface (QSEECOM).
+ * Responsible for setting up and managing QSEECOM client devices.
+ *
+ * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
+ */
+
+#ifndef __QCOM_QSEECOM_H
+#define __QCOM_QSEECOM_H
+
+#include <linux/auxiliary_bus.h>
+#include <linux/types.h>
+
+#include <linux/firmware/qcom/qcom_scm.h>
+
+/**
+ * struct qseecom_client - QSEECOM client device.
+ * @aux_dev: Underlying auxiliary device.
+ * @app_id: ID of the loaded application.
+ */
+struct qseecom_client {
+ struct auxiliary_device aux_dev;
+ u32 app_id;
+};
+
+/**
+ * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app.
+ * @client: The QSEECOM client associated with the target app.
+ * @req: Request buffer sent to the app (must be DMA-mappable).
+ * @req_size: Size of the request buffer.
+ * @rsp: Response buffer, written to by the app (must be DMA-mappable).
+ * @rsp_size: Size of the response buffer.
+ *
+ * Sends a request to the QSEE app associated with the given client and read
+ * back its response. The caller must provide two DMA memory regions, one for
+ * the request and one for the response, and fill out the @req region with the
+ * respective (app-specific) request data. The QSEE app reads this and returns
+ * its response in the @rsp region.
+ *
+ * Note: This is a convenience wrapper around qcom_scm_qseecom_app_send().
+ * Clients should prefer to use this wrapper.
+ *
+ * Return: Zero on success, nonzero on failure.
+ */
+static inline int qcom_qseecom_app_send(struct qseecom_client *client, void *req, size_t req_size,
+ void *rsp, size_t rsp_size)
+{
+ return qcom_scm_qseecom_app_send(client->app_id, req, req_size, rsp, rsp_size);
+}
+
+#endif /* __QCOM_QSEECOM_H */
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 0c091a3f6d49..ccaf28846054 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -59,12 +59,12 @@ enum qcom_scm_ice_cipher {
#define QCOM_SCM_PERM_RW (QCOM_SCM_PERM_READ | QCOM_SCM_PERM_WRITE)
#define QCOM_SCM_PERM_RWX (QCOM_SCM_PERM_RW | QCOM_SCM_PERM_EXEC)
-extern bool qcom_scm_is_available(void);
+bool qcom_scm_is_available(void);
-extern int qcom_scm_set_cold_boot_addr(void *entry);
-extern int qcom_scm_set_warm_boot_addr(void *entry);
-extern void qcom_scm_cpu_power_down(u32 flags);
-extern int qcom_scm_set_remote_state(u32 state, u32 id);
+int qcom_scm_set_cold_boot_addr(void *entry);
+int qcom_scm_set_warm_boot_addr(void *entry);
+void qcom_scm_cpu_power_down(u32 flags);
+int qcom_scm_set_remote_state(u32 state, u32 id);
struct qcom_scm_pas_metadata {
void *ptr;
@@ -72,54 +72,69 @@ struct qcom_scm_pas_metadata {
ssize_t size;
};
-extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
- size_t size,
- struct qcom_scm_pas_metadata *ctx);
-extern void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
-extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
- phys_addr_t size);
-extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
-extern int qcom_scm_pas_shutdown(u32 peripheral);
-extern bool qcom_scm_pas_supported(u32 peripheral);
-
-extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
-extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
-
-extern bool qcom_scm_restore_sec_cfg_available(void);
-extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
-extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
-extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
-extern int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size);
-extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
- u32 cp_nonpixel_start,
- u32 cp_nonpixel_size);
-extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
- u64 *src,
- const struct qcom_scm_vmperm *newvm,
- unsigned int dest_cnt);
-
-extern bool qcom_scm_ocmem_lock_available(void);
-extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
- u32 size, u32 mode);
-extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset,
- u32 size);
-
-extern bool qcom_scm_ice_available(void);
-extern int qcom_scm_ice_invalidate_key(u32 index);
-extern int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
- enum qcom_scm_ice_cipher cipher,
- u32 data_unit_size);
-
-extern bool qcom_scm_hdcp_available(void);
-extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
- u32 *resp);
-
-extern int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt);
-extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en);
-
-extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
- u64 limit_node, u32 node_id, u64 version);
-extern int qcom_scm_lmh_profile_change(u32 profile_id);
-extern bool qcom_scm_lmh_dcvsh_available(void);
+int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
+ struct qcom_scm_pas_metadata *ctx);
+void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
+int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
+int qcom_scm_pas_auth_and_reset(u32 peripheral);
+int qcom_scm_pas_shutdown(u32 peripheral);
+bool qcom_scm_pas_supported(u32 peripheral);
+
+int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
+int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
+
+bool qcom_scm_restore_sec_cfg_available(void);
+int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
+int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
+int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
+int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size);
+int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
+ u32 cp_nonpixel_start, u32 cp_nonpixel_size);
+int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, u64 *src,
+ const struct qcom_scm_vmperm *newvm,
+ unsigned int dest_cnt);
+
+bool qcom_scm_ocmem_lock_available(void);
+int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size,
+ u32 mode);
+int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size);
+
+bool qcom_scm_ice_available(void);
+int qcom_scm_ice_invalidate_key(u32 index);
+int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
+ enum qcom_scm_ice_cipher cipher, u32 data_unit_size);
+
+bool qcom_scm_hdcp_available(void);
+int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp);
+
+int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt);
+int qcom_scm_qsmmu500_wait_safe_toggle(bool en);
+
+int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
+ u64 limit_node, u32 node_id, u64 version);
+int qcom_scm_lmh_profile_change(u32 profile_id);
+bool qcom_scm_lmh_dcvsh_available(void);
+
+#ifdef CONFIG_QCOM_QSEECOM
+
+int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id);
+int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
+ size_t rsp_size);
+
+#else /* CONFIG_QCOM_QSEECOM */
+
+static inline int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id)
+{
+ return -EINVAL;
+}
+
+static inline int qcom_scm_qseecom_app_send(u32 app_id, void *req,
+ size_t req_size, void *rsp,
+ size_t rsp_size)
+{
+ return -EINVAL;
+}
+
+#endif /* CONFIG_QCOM_QSEECOM */
#endif
diff --git a/include/linux/freelist.h b/include/linux/freelist.h
deleted file mode 100644
index fc1842b96469..000000000000
--- a/include/linux/freelist.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
-#ifndef FREELIST_H
-#define FREELIST_H
-
-#include <linux/atomic.h>
-
-/*
- * Copyright: cameron@moodycamel.com
- *
- * A simple CAS-based lock-free free list. Not the fastest thing in the world
- * under heavy contention, but simple and correct (assuming nodes are never
- * freed until after the free list is destroyed), and fairly speedy under low
- * contention.
- *
- * Adapted from: https://moodycamel.com/blog/2014/solving-the-aba-problem-for-lock-free-free-lists
- */
-
-struct freelist_node {
- atomic_t refs;
- struct freelist_node *next;
-};
-
-struct freelist_head {
- struct freelist_node *head;
-};
-
-#define REFS_ON_FREELIST 0x80000000
-#define REFS_MASK 0x7FFFFFFF
-
-static inline void __freelist_add(struct freelist_node *node, struct freelist_head *list)
-{
- /*
- * Since the refcount is zero, and nobody can increase it once it's
- * zero (except us, and we run only one copy of this method per node at
- * a time, i.e. the single thread case), then we know we can safely
- * change the next pointer of the node; however, once the refcount is
- * back above zero, then other threads could increase it (happens under
- * heavy contention, when the refcount goes to zero in between a load
- * and a refcount increment of a node in try_get, then back up to
- * something non-zero, then the refcount increment is done by the other
- * thread) -- so if the CAS to add the node to the actual list fails,
- * decrese the refcount and leave the add operation to the next thread
- * who puts the refcount back to zero (which could be us, hence the
- * loop).
- */
- struct freelist_node *head = READ_ONCE(list->head);
-
- for (;;) {
- WRITE_ONCE(node->next, head);
- atomic_set_release(&node->refs, 1);
-
- if (!try_cmpxchg_release(&list->head, &head, node)) {
- /*
- * Hmm, the add failed, but we can only try again when
- * the refcount goes back to zero.
- */
- if (atomic_fetch_add_release(REFS_ON_FREELIST - 1, &node->refs) == 1)
- continue;
- }
- return;
- }
-}
-
-static inline void freelist_add(struct freelist_node *node, struct freelist_head *list)
-{
- /*
- * We know that the should-be-on-freelist bit is 0 at this point, so
- * it's safe to set it using a fetch_add.
- */
- if (!atomic_fetch_add_release(REFS_ON_FREELIST, &node->refs)) {
- /*
- * Oh look! We were the last ones referencing this node, and we
- * know we want to add it to the free list, so let's do it!
- */
- __freelist_add(node, list);
- }
-}
-
-static inline struct freelist_node *freelist_try_get(struct freelist_head *list)
-{
- struct freelist_node *prev, *next, *head = smp_load_acquire(&list->head);
- unsigned int refs;
-
- while (head) {
- prev = head;
- refs = atomic_read(&head->refs);
- if ((refs & REFS_MASK) == 0 ||
- !atomic_try_cmpxchg_acquire(&head->refs, &refs, refs+1)) {
- head = smp_load_acquire(&list->head);
- continue;
- }
-
- /*
- * Good, reference count has been incremented (it wasn't at
- * zero), which means we can read the next and not worry about
- * it changing between now and the time we do the CAS.
- */
- next = READ_ONCE(head->next);
- if (try_cmpxchg_acquire(&list->head, &head, next)) {
- /*
- * Yay, got the node. This means it was on the list,
- * which means should-be-on-freelist must be false no
- * matter the refcount (because nobody else knows it's
- * been taken off yet, it can't have been put back on).
- */
- WARN_ON_ONCE(atomic_read(&head->refs) & REFS_ON_FREELIST);
-
- /*
- * Decrease refcount twice, once for our ref, and once
- * for the list's ref.
- */
- atomic_fetch_add(-2, &head->refs);
-
- return head;
- }
-
- /*
- * OK, the head must have changed on us, but we still need to decrement
- * the refcount we increased.
- */
- refs = atomic_fetch_add(-1, &prev->refs);
- if (refs == REFS_ON_FREELIST + 1)
- __freelist_add(prev, list);
- }
-
- return NULL;
-}
-
-#endif /* FREELIST_H */
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index 1b7a44b35616..25142a0e2fc2 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -166,6 +166,10 @@ struct io_pgtable_ops {
struct iommu_iotlb_gather *gather);
phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops,
unsigned long iova);
+ int (*read_and_clear_dirty)(struct io_pgtable_ops *ops,
+ unsigned long iova, size_t size,
+ unsigned long flags,
+ struct iommu_dirty_bitmap *dirty);
};
/**
diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h
index 106cdc55ff3b..aefb73eeeebf 100644
--- a/include/linux/io_uring.h
+++ b/include/linux/io_uring.h
@@ -20,8 +20,16 @@ enum io_uring_cmd_flags {
IO_URING_F_SQE128 = (1 << 8),
IO_URING_F_CQE32 = (1 << 9),
IO_URING_F_IOPOLL = (1 << 10),
+
+ /* set when uring wants to cancel a previously issued command */
+ IO_URING_F_CANCEL = (1 << 11),
+ IO_URING_F_COMPAT = (1 << 12),
};
+/* only top 8 bits of sqe->uring_cmd_flags for kernel internal use */
+#define IORING_URING_CMD_CANCELABLE (1U << 30)
+#define IORING_URING_CMD_POLLED (1U << 31)
+
struct io_uring_cmd {
struct file *file;
const struct io_uring_sqe *sqe;
@@ -82,6 +90,9 @@ static inline void io_uring_free(struct task_struct *tsk)
__io_uring_free(tsk);
}
int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags);
+void io_uring_cmd_mark_cancelable(struct io_uring_cmd *cmd,
+ unsigned int issue_flags);
+struct task_struct *io_uring_cmd_get_task(struct io_uring_cmd *cmd);
#else
static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
struct iov_iter *iter, void *ioucmd)
@@ -122,6 +133,14 @@ static inline int io_uring_cmd_sock(struct io_uring_cmd *cmd,
{
return -EOPNOTSUPP;
}
+static inline void io_uring_cmd_mark_cancelable(struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
+{
+}
+static inline struct task_struct *io_uring_cmd_get_task(struct io_uring_cmd *cmd)
+{
+ return NULL;
+}
#endif
#endif
diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h
index 13d19b9be9f4..d3009d56af0b 100644
--- a/include/linux/io_uring_types.h
+++ b/include/linux/io_uring_types.h
@@ -265,6 +265,12 @@ struct io_ring_ctx {
*/
struct io_wq_work_list iopoll_list;
bool poll_multi_queue;
+
+ /*
+ * Any cancelable uring_cmd is added to this list in
+ * ->uring_cmd() by io_uring_cmd_insert_cancelable()
+ */
+ struct hlist_head cancelable_uring_cmd;
} ____cacheline_aligned_in_smp;
struct {
@@ -313,6 +319,13 @@ struct io_ring_ctx {
struct list_head cq_overflow_list;
struct io_hash_table cancel_table;
+ struct hlist_head waitid_list;
+
+#ifdef CONFIG_FUTEX
+ struct hlist_head futex_list;
+ struct io_alloc_cache futex_cache;
+#endif
+
const struct cred *sq_creds; /* cred used for __io_sq_thread() */
struct io_sq_data *sq_data; /* if using sq thread polling */
@@ -342,8 +355,6 @@ struct io_ring_ctx {
struct wait_queue_head rsrc_quiesce_wq;
unsigned rsrc_quiesce;
- struct list_head io_buffers_pages;
-
#if defined(CONFIG_UNIX)
struct socket *ring_sock;
#endif
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c50a769d569a..8fb1b41b4d15 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -13,6 +13,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/of.h>
+#include <linux/iova_bitmap.h>
#include <uapi/linux/iommu.h>
#define IOMMU_READ (1 << 0)
@@ -37,6 +38,7 @@ struct bus_type;
struct device;
struct iommu_domain;
struct iommu_domain_ops;
+struct iommu_dirty_ops;
struct notifier_block;
struct iommu_sva;
struct iommu_fault_event;
@@ -65,6 +67,9 @@ struct iommu_domain_geometry {
#define __IOMMU_DOMAIN_SVA (1U << 4) /* Shared process address space */
+#define __IOMMU_DOMAIN_NESTED (1U << 6) /* User-managed address space nested
+ on a stage-2 translation */
+
#define IOMMU_DOMAIN_ALLOC_FLAGS ~__IOMMU_DOMAIN_DMA_FQ
/*
* This are the possible domain-types
@@ -91,10 +96,13 @@ struct iommu_domain_geometry {
__IOMMU_DOMAIN_DMA_API | \
__IOMMU_DOMAIN_DMA_FQ)
#define IOMMU_DOMAIN_SVA (__IOMMU_DOMAIN_SVA)
+#define IOMMU_DOMAIN_NESTED (__IOMMU_DOMAIN_NESTED)
struct iommu_domain {
unsigned type;
const struct iommu_domain_ops *ops;
+ const struct iommu_dirty_ops *dirty_ops;
+
unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */
struct iommu_domain_geometry geometry;
struct iommu_dma_cookie *iova_cookie;
@@ -133,6 +141,7 @@ enum iommu_cap {
* usefully support the non-strict DMA flush queue.
*/
IOMMU_CAP_DEFERRED_FLUSH,
+ IOMMU_CAP_DIRTY_TRACKING, /* IOMMU supports dirty tracking */
};
/* These are the possible reserved region types */
@@ -228,13 +237,109 @@ struct iommu_iotlb_gather {
};
/**
+ * struct iommu_dirty_bitmap - Dirty IOVA bitmap state
+ * @bitmap: IOVA bitmap
+ * @gather: Range information for a pending IOTLB flush
+ */
+struct iommu_dirty_bitmap {
+ struct iova_bitmap *bitmap;
+ struct iommu_iotlb_gather *gather;
+};
+
+/* Read but do not clear any dirty bits */
+#define IOMMU_DIRTY_NO_CLEAR (1 << 0)
+
+/**
+ * struct iommu_dirty_ops - domain specific dirty tracking operations
+ * @set_dirty_tracking: Enable or Disable dirty tracking on the iommu domain
+ * @read_and_clear_dirty: Walk IOMMU page tables for dirtied PTEs marshalled
+ * into a bitmap, with a bit represented as a page.
+ * Reads the dirty PTE bits and clears it from IO
+ * pagetables.
+ */
+struct iommu_dirty_ops {
+ int (*set_dirty_tracking)(struct iommu_domain *domain, bool enabled);
+ int (*read_and_clear_dirty)(struct iommu_domain *domain,
+ unsigned long iova, size_t size,
+ unsigned long flags,
+ struct iommu_dirty_bitmap *dirty);
+};
+
+/**
+ * struct iommu_user_data - iommu driver specific user space data info
+ * @type: The data type of the user buffer
+ * @uptr: Pointer to the user buffer for copy_from_user()
+ * @len: The length of the user buffer in bytes
+ *
+ * A user space data is an uAPI that is defined in include/uapi/linux/iommufd.h
+ * @type, @uptr and @len should be just copied from an iommufd core uAPI struct.
+ */
+struct iommu_user_data {
+ unsigned int type;
+ void __user *uptr;
+ size_t len;
+};
+
+/**
+ * __iommu_copy_struct_from_user - Copy iommu driver specific user space data
+ * @dst_data: Pointer to an iommu driver specific user data that is defined in
+ * include/uapi/linux/iommufd.h
+ * @src_data: Pointer to a struct iommu_user_data for user space data info
+ * @data_type: The data type of the @dst_data. Must match with @src_data.type
+ * @data_len: Length of current user data structure, i.e. sizeof(struct _dst)
+ * @min_len: Initial length of user data structure for backward compatibility.
+ * This should be offsetofend using the last member in the user data
+ * struct that was initially added to include/uapi/linux/iommufd.h
+ */
+static inline int __iommu_copy_struct_from_user(
+ void *dst_data, const struct iommu_user_data *src_data,
+ unsigned int data_type, size_t data_len, size_t min_len)
+{
+ if (src_data->type != data_type)
+ return -EINVAL;
+ if (WARN_ON(!dst_data || !src_data))
+ return -EINVAL;
+ if (src_data->len < min_len || data_len < src_data->len)
+ return -EINVAL;
+ return copy_struct_from_user(dst_data, data_len, src_data->uptr,
+ src_data->len);
+}
+
+/**
+ * iommu_copy_struct_from_user - Copy iommu driver specific user space data
+ * @kdst: Pointer to an iommu driver specific user data that is defined in
+ * include/uapi/linux/iommufd.h
+ * @user_data: Pointer to a struct iommu_user_data for user space data info
+ * @data_type: The data type of the @kdst. Must match with @user_data->type
+ * @min_last: The last memember of the data structure @kdst points in the
+ * initial version.
+ * Return 0 for success, otherwise -error.
+ */
+#define iommu_copy_struct_from_user(kdst, user_data, data_type, min_last) \
+ __iommu_copy_struct_from_user(kdst, user_data, data_type, \
+ sizeof(*kdst), \
+ offsetofend(typeof(*kdst), min_last))
+
+/**
* struct iommu_ops - iommu ops and capabilities
* @capable: check capability
* @hw_info: report iommu hardware information. The data buffer returned by this
* op is allocated in the iommu driver and freed by the caller after
* use. The information type is one of enum iommu_hw_info_type defined
* in include/uapi/linux/iommufd.h.
- * @domain_alloc: allocate iommu domain
+ * @domain_alloc: allocate and return an iommu domain if success. Otherwise
+ * NULL is returned. The domain is not fully initialized until
+ * the caller iommu_domain_alloc() returns.
+ * @domain_alloc_user: Allocate an iommu domain corresponding to the input
+ * parameters as defined in include/uapi/linux/iommufd.h.
+ * Unlike @domain_alloc, it is called only by IOMMUFD and
+ * must fully initialize the new domain before return.
+ * Upon success, if the @user_data is valid and the @parent
+ * points to a kernel-managed domain, the new domain must be
+ * IOMMU_DOMAIN_NESTED type; otherwise, the @parent must be
+ * NULL while the @user_data can be optionally provided, the
+ * new domain must support __IOMMU_DOMAIN_PAGING.
+ * Upon failure, ERR_PTR must be returned.
* @probe_device: Add device to iommu driver handling
* @release_device: Remove device from iommu driver handling
* @probe_finalize: Do final setup work after the device is added to an IOMMU
@@ -267,6 +372,9 @@ struct iommu_ops {
/* Domain allocation and freeing by the iommu driver */
struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
+ struct iommu_domain *(*domain_alloc_user)(
+ struct device *dev, u32 flags, struct iommu_domain *parent,
+ const struct iommu_user_data *user_data);
struct iommu_device *(*probe_device)(struct device *dev);
void (*release_device)(struct device *dev);
@@ -632,6 +740,28 @@ static inline bool iommu_iotlb_gather_queued(struct iommu_iotlb_gather *gather)
return gather && gather->queued;
}
+static inline void iommu_dirty_bitmap_init(struct iommu_dirty_bitmap *dirty,
+ struct iova_bitmap *bitmap,
+ struct iommu_iotlb_gather *gather)
+{
+ if (gather)
+ iommu_iotlb_gather_init(gather);
+
+ dirty->bitmap = bitmap;
+ dirty->gather = gather;
+}
+
+static inline void iommu_dirty_bitmap_record(struct iommu_dirty_bitmap *dirty,
+ unsigned long iova,
+ unsigned long length)
+{
+ if (dirty->bitmap)
+ iova_bitmap_set(dirty->bitmap, iova, length);
+
+ if (dirty->gather)
+ iommu_iotlb_gather_add_range(dirty->gather, iova, length);
+}
+
/* PCI device grouping function */
extern struct iommu_group *pci_device_group(struct device *dev);
/* Generic device grouping function */
@@ -737,6 +867,8 @@ struct iommu_fwspec {};
struct iommu_device {};
struct iommu_fault_param {};
struct iommu_iotlb_gather {};
+struct iommu_dirty_bitmap {};
+struct iommu_dirty_ops {};
static inline bool iommu_present(const struct bus_type *bus)
{
@@ -969,6 +1101,18 @@ static inline bool iommu_iotlb_gather_queued(struct iommu_iotlb_gather *gather)
return false;
}
+static inline void iommu_dirty_bitmap_init(struct iommu_dirty_bitmap *dirty,
+ struct iova_bitmap *bitmap,
+ struct iommu_iotlb_gather *gather)
+{
+}
+
+static inline void iommu_dirty_bitmap_record(struct iommu_dirty_bitmap *dirty,
+ unsigned long iova,
+ unsigned long length)
+{
+}
+
static inline void iommu_device_unregister(struct iommu_device *iommu)
{
}
diff --git a/include/linux/iova_bitmap.h b/include/linux/iova_bitmap.h
index c006cf0a25f3..1c338f5e5b7a 100644
--- a/include/linux/iova_bitmap.h
+++ b/include/linux/iova_bitmap.h
@@ -7,6 +7,7 @@
#define _IOVA_BITMAP_H_
#include <linux/types.h>
+#include <linux/errno.h>
struct iova_bitmap;
@@ -14,6 +15,7 @@ typedef int (*iova_bitmap_fn_t)(struct iova_bitmap *bitmap,
unsigned long iova, size_t length,
void *opaque);
+#if IS_ENABLED(CONFIG_IOMMUFD_DRIVER)
struct iova_bitmap *iova_bitmap_alloc(unsigned long iova, size_t length,
unsigned long page_size,
u64 __user *data);
@@ -22,5 +24,29 @@ int iova_bitmap_for_each(struct iova_bitmap *bitmap, void *opaque,
iova_bitmap_fn_t fn);
void iova_bitmap_set(struct iova_bitmap *bitmap,
unsigned long iova, size_t length);
+#else
+static inline struct iova_bitmap *iova_bitmap_alloc(unsigned long iova,
+ size_t length,
+ unsigned long page_size,
+ u64 __user *data)
+{
+ return NULL;
+}
+
+static inline void iova_bitmap_free(struct iova_bitmap *bitmap)
+{
+}
+
+static inline int iova_bitmap_for_each(struct iova_bitmap *bitmap, void *opaque,
+ iova_bitmap_fn_t fn)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void iova_bitmap_set(struct iova_bitmap *bitmap,
+ unsigned long iova, size_t length)
+{
+}
+#endif
#endif
diff --git a/include/linux/key.h b/include/linux/key.h
index 938d7ecfb495..943a432da3ae 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -515,6 +515,7 @@ extern void key_init(void);
#define key_init() do { } while(0)
#define key_free_user_ns(ns) do { } while(0)
#define key_remove_domain(d) do { } while(0)
+#define key_lookup(k) NULL
#endif /* CONFIG_KEYS */
#endif /* __KERNEL__ */
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 85a64cb95d75..365eb092e9c4 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -26,8 +26,7 @@
#include <linux/rcupdate.h>
#include <linux/mutex.h>
#include <linux/ftrace.h>
-#include <linux/refcount.h>
-#include <linux/freelist.h>
+#include <linux/objpool.h>
#include <linux/rethook.h>
#include <asm/kprobes.h>
@@ -141,7 +140,7 @@ static inline bool kprobe_ftrace(struct kprobe *p)
*/
struct kretprobe_holder {
struct kretprobe *rp;
- refcount_t ref;
+ struct objpool_head pool;
};
struct kretprobe {
@@ -154,7 +153,6 @@ struct kretprobe {
#ifdef CONFIG_KRETPROBE_ON_RETHOOK
struct rethook *rh;
#else
- struct freelist_head freelist;
struct kretprobe_holder *rph;
#endif
};
@@ -165,10 +163,7 @@ struct kretprobe_instance {
#ifdef CONFIG_KRETPROBE_ON_RETHOOK
struct rethook_node node;
#else
- union {
- struct freelist_node freelist;
- struct rcu_head rcu;
- };
+ struct rcu_head rcu;
struct llist_node llist;
struct kretprobe_holder *rph;
kprobe_opcode_t *ret_addr;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 2a7d2af0ed80..1dbb14daccfa 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -656,7 +656,7 @@ struct ata_cpr {
struct ata_cpr_log {
u8 nr_cpr;
- struct ata_cpr cpr[];
+ struct ata_cpr cpr[] __counted_by(nr_cpr);
};
struct ata_device {
@@ -1561,6 +1561,11 @@ void ata_port_desc(struct ata_port *ap, const char *fmt, ...);
extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
const char *name);
#endif
+static inline void ata_port_desc_misc(struct ata_port *ap, int irq)
+{
+ ata_port_desc(ap, "irq %d", irq);
+ ata_port_desc(ap, "lpm-pol %d", ap->target_lpm_policy);
+}
static inline bool ata_tag_internal(unsigned int tag)
{
@@ -1881,23 +1886,21 @@ static inline unsigned long ata_deadline(unsigned long from_jiffies,
change in future hardware and specs, secondly 0xFF means 'no DMA' but is
> UDMA_0. Dyma ddreigiau */
-static inline int ata_using_mwdma(struct ata_device *adev)
+static inline bool ata_using_mwdma(struct ata_device *adev)
{
- if (adev->dma_mode >= XFER_MW_DMA_0 && adev->dma_mode <= XFER_MW_DMA_4)
- return 1;
- return 0;
+ return adev->dma_mode >= XFER_MW_DMA_0 &&
+ adev->dma_mode <= XFER_MW_DMA_4;
}
-static inline int ata_using_udma(struct ata_device *adev)
+static inline bool ata_using_udma(struct ata_device *adev)
{
- if (adev->dma_mode >= XFER_UDMA_0 && adev->dma_mode <= XFER_UDMA_7)
- return 1;
- return 0;
+ return adev->dma_mode >= XFER_UDMA_0 &&
+ adev->dma_mode <= XFER_UDMA_7;
}
-static inline int ata_dma_enabled(struct ata_device *adev)
+static inline bool ata_dma_enabled(struct ata_device *adev)
{
- return (adev->dma_mode == 0xFF ? 0 : 1);
+ return adev->dma_mode != 0xFF;
}
/**************************************************************************
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 116c28c51468..ba896e946651 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -362,8 +362,6 @@ extern unsigned int kobjsize(const void *objp);
# define VM_SAO VM_ARCH_1 /* Strong Access Ordering (powerpc) */
#elif defined(CONFIG_PARISC)
# define VM_GROWSUP VM_ARCH_1
-#elif defined(CONFIG_IA64)
-# define VM_GROWSUP VM_ARCH_1
#elif defined(CONFIG_SPARC64)
# define VM_SPARC_ADI VM_ARCH_1 /* Uses ADI tag for access control */
# define VM_ARCH_CLEAR VM_SPARC_ADI
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 62a6847a3b6f..2f445c651742 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -526,6 +526,7 @@ struct mmc_host {
/* Host Software Queue support */
bool hsq_enabled;
+ int hsq_depth;
u32 err_stats[MMC_ERR_MAX];
unsigned long private[] ____cacheline_aligned;
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index d4452f93d060..4fa9726bc328 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -276,7 +276,7 @@ struct kparam_array
read-only sections (which is part of respective UNIX ABI on these
platforms). So 'const' makes no sense and even causes compile failures
with some compilers. */
-#if defined(CONFIG_ALPHA) || defined(CONFIG_IA64) || defined(CONFIG_PPC64)
+#if defined(CONFIG_ALPHA) || defined(CONFIG_PPC64)
#define __moduleparam_const
#else
#define __moduleparam_const const
diff --git a/include/linux/nvme-auth.h b/include/linux/nvme-auth.h
index dcb8030062dd..c1d0bc5d9624 100644
--- a/include/linux/nvme-auth.h
+++ b/include/linux/nvme-auth.h
@@ -9,9 +9,9 @@
#include <crypto/kpp.h>
struct nvme_dhchap_key {
- u8 *key;
size_t len;
u8 hash;
+ u8 key[];
};
u32 nvme_auth_get_seqnum(void);
@@ -24,10 +24,13 @@ const char *nvme_auth_digest_name(u8 hmac_id);
size_t nvme_auth_hmac_hash_len(u8 hmac_id);
u8 nvme_auth_hmac_id(const char *hmac_name);
+u32 nvme_auth_key_struct_size(u32 key_len);
struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
u8 key_hash);
void nvme_auth_free_key(struct nvme_dhchap_key *key);
-u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn);
+struct nvme_dhchap_key *nvme_auth_alloc_key(u32 len, u8 hash);
+struct nvme_dhchap_key *nvme_auth_transform_key(
+ struct nvme_dhchap_key *key, char *nqn);
int nvme_auth_generate_key(u8 *secret, struct nvme_dhchap_key **ret_key);
int nvme_auth_augmented_challenge(u8 hmac_id, u8 *skey, size_t skey_len,
u8 *challenge, u8 *aug, size_t hlen);
diff --git a/include/linux/nvme-keyring.h b/include/linux/nvme-keyring.h
new file mode 100644
index 000000000000..4efea9dd967c
--- /dev/null
+++ b/include/linux/nvme-keyring.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Hannes Reinecke, SUSE Labs
+ */
+
+#ifndef _NVME_KEYRING_H
+#define _NVME_KEYRING_H
+
+#ifdef CONFIG_NVME_KEYRING
+
+key_serial_t nvme_tls_psk_default(struct key *keyring,
+ const char *hostnqn, const char *subnqn);
+
+key_serial_t nvme_keyring_id(void);
+int nvme_keyring_init(void);
+void nvme_keyring_exit(void);
+
+#else
+
+static inline key_serial_t nvme_tls_psk_default(struct key *keyring,
+ const char *hostnqn, const char *subnqn)
+{
+ return 0;
+}
+static inline key_serial_t nvme_keyring_id(void)
+{
+ return 0;
+}
+static inline int nvme_keyring_init(void)
+{
+ return 0;
+}
+static inline void nvme_keyring_exit(void) {}
+
+#endif /* !CONFIG_NVME_KEYRING */
+#endif /* _NVME_KEYRING_H */
diff --git a/include/linux/nvme-tcp.h b/include/linux/nvme-tcp.h
index 57ebe1267f7f..e07e8978d691 100644
--- a/include/linux/nvme-tcp.h
+++ b/include/linux/nvme-tcp.h
@@ -18,6 +18,12 @@ enum nvme_tcp_pfv {
NVME_TCP_PFV_1_0 = 0x0,
};
+enum nvme_tcp_tls_cipher {
+ NVME_TCP_TLS_CIPHER_INVALID = 0,
+ NVME_TCP_TLS_CIPHER_SHA256 = 1,
+ NVME_TCP_TLS_CIPHER_SHA384 = 2,
+};
+
enum nvme_tcp_fatal_error_status {
NVME_TCP_FES_INVALID_PDU_HDR = 0x01,
NVME_TCP_FES_PDU_SEQ_ERR = 0x02,
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 26dd3f859d9d..a7ba74babad7 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -108,6 +108,13 @@ enum {
NVMF_RDMA_CMS_RDMA_CM = 1, /* Sockets based endpoint addressing */
};
+/* TSAS SECTYPE for TCP transport */
+enum {
+ NVMF_TCP_SECTYPE_NONE = 0, /* No Security */
+ NVMF_TCP_SECTYPE_TLS12 = 1, /* TLSv1.2, NVMe-oF 1.1 and NVMe-TCP 3.6.1.1 */
+ NVMF_TCP_SECTYPE_TLS13 = 2, /* TLSv1.3, NVMe-oF 1.1 and NVMe-TCP 3.6.1.1 */
+};
+
#define NVME_AQ_DEPTH 32
#define NVME_NR_AEN_COMMANDS 1
#define NVME_AQ_BLK_MQ_DEPTH (NVME_AQ_DEPTH - NVME_NR_AEN_COMMANDS)
@@ -1493,6 +1500,9 @@ struct nvmf_disc_rsp_page_entry {
__u16 pkey;
__u8 resv10[246];
} rdma;
+ struct tcp {
+ __u8 sectype;
+ } tcp;
} tsas;
};
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 4523e4e83319..6ec4b9743e25 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -127,6 +127,12 @@ static inline int nvmem_cell_write(struct nvmem_cell *cell,
return -EOPNOTSUPP;
}
+static inline int nvmem_cell_read_u8(struct device *dev,
+ const char *cell_id, u8 *val)
+{
+ return -EOPNOTSUPP;
+}
+
static inline int nvmem_cell_read_u16(struct device *dev,
const char *cell_id, u16 *val)
{
diff --git a/include/linux/objpool.h b/include/linux/objpool.h
new file mode 100644
index 000000000000..15aff4a17f0c
--- /dev/null
+++ b/include/linux/objpool.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _LINUX_OBJPOOL_H
+#define _LINUX_OBJPOOL_H
+
+#include <linux/types.h>
+#include <linux/refcount.h>
+
+/*
+ * objpool: ring-array based lockless MPMC queue
+ *
+ * Copyright: wuqiang.matt@bytedance.com,mhiramat@kernel.org
+ *
+ * objpool is a scalable implementation of high performance queue for
+ * object allocation and reclamation, such as kretprobe instances.
+ *
+ * With leveraging percpu ring-array to mitigate hot spots of memory
+ * contention, it delivers near-linear scalability for high parallel
+ * scenarios. The objpool is best suited for the following cases:
+ * 1) Memory allocation or reclamation are prohibited or too expensive
+ * 2) Consumers are of different priorities, such as irqs and threads
+ *
+ * Limitations:
+ * 1) Maximum objects (capacity) is fixed after objpool creation
+ * 2) All pre-allocated objects are managed in percpu ring array,
+ * which consumes more memory than linked lists
+ */
+
+/**
+ * struct objpool_slot - percpu ring array of objpool
+ * @head: head sequence of the local ring array (to retrieve at)
+ * @tail: tail sequence of the local ring array (to append at)
+ * @last: the last sequence number marked as ready for retrieve
+ * @mask: bits mask for modulo capacity to compute array indexes
+ * @entries: object entries on this slot
+ *
+ * Represents a cpu-local array-based ring buffer, its size is specialized
+ * during initialization of object pool. The percpu objpool node is to be
+ * allocated from local memory for NUMA system, and to be kept compact in
+ * continuous memory: CPU assigned number of objects are stored just after
+ * the body of objpool_node.
+ *
+ * Real size of the ring array is far too smaller than the value range of
+ * head and tail, typed as uint32_t: [0, 2^32), so only lower bits (mask)
+ * of head and tail are used as the actual position in the ring array. In
+ * general the ring array is acting like a small sliding window, which is
+ * always moving forward in the loop of [0, 2^32).
+ */
+struct objpool_slot {
+ uint32_t head;
+ uint32_t tail;
+ uint32_t last;
+ uint32_t mask;
+ void *entries[];
+} __packed;
+
+struct objpool_head;
+
+/*
+ * caller-specified callback for object initial setup, it's only called
+ * once for each object (just after the memory allocation of the object)
+ */
+typedef int (*objpool_init_obj_cb)(void *obj, void *context);
+
+/* caller-specified cleanup callback for objpool destruction */
+typedef int (*objpool_fini_cb)(struct objpool_head *head, void *context);
+
+/**
+ * struct objpool_head - object pooling metadata
+ * @obj_size: object size, aligned to sizeof(void *)
+ * @nr_objs: total objs (to be pre-allocated with objpool)
+ * @nr_cpus: local copy of nr_cpu_ids
+ * @capacity: max objs can be managed by one objpool_slot
+ * @gfp: gfp flags for kmalloc & vmalloc
+ * @ref: refcount of objpool
+ * @flags: flags for objpool management
+ * @cpu_slots: pointer to the array of objpool_slot
+ * @release: resource cleanup callback
+ * @context: caller-provided context
+ */
+struct objpool_head {
+ int obj_size;
+ int nr_objs;
+ int nr_cpus;
+ int capacity;
+ gfp_t gfp;
+ refcount_t ref;
+ unsigned long flags;
+ struct objpool_slot **cpu_slots;
+ objpool_fini_cb release;
+ void *context;
+};
+
+#define OBJPOOL_NR_OBJECT_MAX (1UL << 24) /* maximum numbers of total objects */
+#define OBJPOOL_OBJECT_SIZE_MAX (1UL << 16) /* maximum size of an object */
+
+/**
+ * objpool_init() - initialize objpool and pre-allocated objects
+ * @pool: the object pool to be initialized, declared by caller
+ * @nr_objs: total objects to be pre-allocated by this object pool
+ * @object_size: size of an object (should be > 0)
+ * @gfp: flags for memory allocation (via kmalloc or vmalloc)
+ * @context: user context for object initialization callback
+ * @objinit: object initialization callback for extra setup
+ * @release: cleanup callback for extra cleanup task
+ *
+ * return value: 0 for success, otherwise error code
+ *
+ * All pre-allocated objects are to be zeroed after memory allocation.
+ * Caller could do extra initialization in objinit callback. objinit()
+ * will be called just after slot allocation and called only once for
+ * each object. After that the objpool won't touch any content of the
+ * objects. It's caller's duty to perform reinitialization after each
+ * pop (object allocation) or do clearance before each push (object
+ * reclamation).
+ */
+int objpool_init(struct objpool_head *pool, int nr_objs, int object_size,
+ gfp_t gfp, void *context, objpool_init_obj_cb objinit,
+ objpool_fini_cb release);
+
+/**
+ * objpool_pop() - allocate an object from objpool
+ * @pool: object pool
+ *
+ * return value: object ptr or NULL if failed
+ */
+void *objpool_pop(struct objpool_head *pool);
+
+/**
+ * objpool_push() - reclaim the object and return back to objpool
+ * @obj: object ptr to be pushed to objpool
+ * @pool: object pool
+ *
+ * return: 0 or error code (it fails only when user tries to push
+ * the same object multiple times or wrong "objects" into objpool)
+ */
+int objpool_push(void *obj, struct objpool_head *pool);
+
+/**
+ * objpool_drop() - discard the object and deref objpool
+ * @obj: object ptr to be discarded
+ * @pool: object pool
+ *
+ * return: 0 if objpool was released; -EAGAIN if there are still
+ * outstanding objects
+ *
+ * objpool_drop is normally for the release of outstanding objects
+ * after objpool cleanup (objpool_fini). Thinking of this example:
+ * kretprobe is unregistered and objpool_fini() is called to release
+ * all remained objects, but there are still objects being used by
+ * unfinished kretprobes (like blockable function: sys_accept). So
+ * only when the last outstanding object is dropped could the whole
+ * objpool be released along with the call of objpool_drop()
+ */
+int objpool_drop(void *obj, struct objpool_head *pool);
+
+/**
+ * objpool_free() - release objpool forcely (all objects to be freed)
+ * @pool: object pool to be released
+ */
+void objpool_free(struct objpool_head *pool);
+
+/**
+ * objpool_fini() - deref object pool (also releasing unused objects)
+ * @pool: object pool to be dereferenced
+ *
+ * objpool_fini() will try to release all remained free objects and
+ * then drop an extra reference of the objpool. If all objects are
+ * already returned to objpool (so called synchronous use cases),
+ * the objpool itself will be freed together. But if there are still
+ * outstanding objects (so called asynchronous use cases, such like
+ * blockable kretprobe), the objpool won't be released until all
+ * the outstanding objects are dropped, but the caller must assure
+ * there are no concurrent objpool_push() on the fly. Normally RCU
+ * is being required to make sure all ongoing objpool_push() must
+ * be finished before calling objpool_fini(), so does test_objpool,
+ * kretprobe or rethook
+ */
+void objpool_fini(struct objpool_head *pool);
+
+#endif /* _LINUX_OBJPOOL_H */
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index bda2964a0a56..34663d0d5c55 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -61,6 +61,10 @@
* GENPD_FLAG_MIN_RESIDENCY: Enable the genpd governor to consider its
* components' next wakeup when determining the
* optimal idle state.
+ *
+ * GENPD_FLAG_OPP_TABLE_FW: The genpd provider supports performance states,
+ * but its corresponding OPP tables are not
+ * described in DT, but are given directly by FW.
*/
#define GENPD_FLAG_PM_CLK (1U << 0)
#define GENPD_FLAG_IRQ_SAFE (1U << 1)
@@ -69,6 +73,7 @@
#define GENPD_FLAG_CPU_DOMAIN (1U << 4)
#define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5)
#define GENPD_FLAG_MIN_RESIDENCY (1U << 6)
+#define GENPD_FLAG_OPP_TABLE_FW (1U << 7)
enum gpd_status {
GENPD_STATE_ON = 0, /* PM domain is on */
diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h
index 006e18decfad..98030accf641 100644
--- a/include/linux/raid/pq.h
+++ b/include/linux/raid/pq.h
@@ -84,8 +84,6 @@ extern const struct raid6_calls raid6_intx1;
extern const struct raid6_calls raid6_intx2;
extern const struct raid6_calls raid6_intx4;
extern const struct raid6_calls raid6_intx8;
-extern const struct raid6_calls raid6_intx16;
-extern const struct raid6_calls raid6_intx32;
extern const struct raid6_calls raid6_mmxx1;
extern const struct raid6_calls raid6_mmxx2;
extern const struct raid6_calls raid6_sse1x1;
diff --git a/include/linux/rethook.h b/include/linux/rethook.h
index 26b6f3c81a76..ce69b2b7bc35 100644
--- a/include/linux/rethook.h
+++ b/include/linux/rethook.h
@@ -6,11 +6,10 @@
#define _LINUX_RETHOOK_H
#include <linux/compiler.h>
-#include <linux/freelist.h>
+#include <linux/objpool.h>
#include <linux/kallsyms.h>
#include <linux/llist.h>
#include <linux/rcupdate.h>
-#include <linux/refcount.h>
struct rethook_node;
@@ -30,14 +29,12 @@ typedef void (*rethook_handler_t) (struct rethook_node *, void *, unsigned long,
struct rethook {
void *data;
rethook_handler_t handler;
- struct freelist_head pool;
- refcount_t ref;
+ struct objpool_head pool;
struct rcu_head rcu;
};
/**
* struct rethook_node - The rethook shadow-stack entry node.
- * @freelist: The freelist, linked to struct rethook::pool.
* @rcu: The rcu_head for deferred freeing.
* @llist: The llist, linked to a struct task_struct::rethooks.
* @rethook: The pointer to the struct rethook.
@@ -48,20 +45,16 @@ struct rethook {
* on each entry of the shadow stack.
*/
struct rethook_node {
- union {
- struct freelist_node freelist;
- struct rcu_head rcu;
- };
+ struct rcu_head rcu;
struct llist_node llist;
struct rethook *rethook;
unsigned long ret_addr;
unsigned long frame;
};
-struct rethook *rethook_alloc(void *data, rethook_handler_t handler);
+struct rethook *rethook_alloc(void *data, rethook_handler_t handler, int size, int num);
void rethook_stop(struct rethook *rh);
void rethook_free(struct rethook *rh);
-void rethook_add_node(struct rethook *rh, struct rethook_node *node);
struct rethook_node *rethook_try_get(struct rethook *rh);
void rethook_recycle(struct rethook_node *node);
void rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount);
@@ -98,4 +91,3 @@ void rethook_flush_task(struct task_struct *tk);
#endif
#endif
-
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index 9610bad018a3..3b28cff24cc1 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -303,20 +303,11 @@ static inline void kernel_signal_stop(void)
schedule();
}
-#ifdef __ia64__
-# define ___ARCH_SI_IA64(_a1, _a2, _a3) , _a1, _a2, _a3
-#else
-# define ___ARCH_SI_IA64(_a1, _a2, _a3)
-#endif
-int force_sig_fault_to_task(int sig, int code, void __user *addr
- ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
- , struct task_struct *t);
-int force_sig_fault(int sig, int code, void __user *addr
- ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr));
-int send_sig_fault(int sig, int code, void __user *addr
- ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
- , struct task_struct *t);
+int force_sig_fault_to_task(int sig, int code, void __user *addr,
+ struct task_struct *t);
+int force_sig_fault(int sig, int code, void __user *addr);
+int send_sig_fault(int sig, int code, void __user *addr, struct task_struct *t);
int force_sig_mceerr(int code, void __user *, short);
int send_sig_mceerr(int code, void __user *, short, struct task_struct *);
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index e6fe4f73ffe6..f2f05fb42d28 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -58,6 +58,8 @@ struct scmi_clock_info {
u64 step_size;
} range;
};
+ int num_parents;
+ u32 *parents;
};
enum scmi_power_scale {
@@ -80,6 +82,11 @@ struct scmi_protocol_handle;
* @rate_set: set the clock rate of a clock
* @enable: enables the specified clock
* @disable: disables the specified clock
+ * @state_get: get the status of the specified clock
+ * @config_oem_get: get the value of an OEM specific clock config
+ * @config_oem_set: set the value of an OEM specific clock config
+ * @parent_get: get the parent id of a clk
+ * @parent_set: set the parent of a clock
*/
struct scmi_clk_proto_ops {
int (*count_get)(const struct scmi_protocol_handle *ph);
@@ -90,22 +97,36 @@ struct scmi_clk_proto_ops {
u64 *rate);
int (*rate_set)(const struct scmi_protocol_handle *ph, u32 clk_id,
u64 rate);
- int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id);
- int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id);
- int (*enable_atomic)(const struct scmi_protocol_handle *ph, u32 clk_id);
- int (*disable_atomic)(const struct scmi_protocol_handle *ph,
- u32 clk_id);
+ int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id,
+ bool atomic);
+ int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id,
+ bool atomic);
+ int (*state_get)(const struct scmi_protocol_handle *ph, u32 clk_id,
+ bool *enabled, bool atomic);
+ int (*config_oem_get)(const struct scmi_protocol_handle *ph, u32 clk_id,
+ u8 oem_type, u32 *oem_val, u32 *attributes,
+ bool atomic);
+ int (*config_oem_set)(const struct scmi_protocol_handle *ph, u32 clk_id,
+ u8 oem_type, u32 oem_val, bool atomic);
+ int (*parent_get)(const struct scmi_protocol_handle *ph, u32 clk_id, u32 *parent_id);
+ int (*parent_set)(const struct scmi_protocol_handle *ph, u32 clk_id, u32 parent_id);
+};
+
+struct scmi_perf_domain_info {
+ char name[SCMI_MAX_STR_SIZE];
+ bool set_perf;
};
/**
* struct scmi_perf_proto_ops - represents the various operations provided
* by SCMI Performance Protocol
*
+ * @num_domains_get: gets the number of supported performance domains
+ * @info_get: get the information of a performance domain
* @limits_set: sets limits on the performance level of a domain
* @limits_get: gets limits on the performance level of a domain
* @level_set: sets the performance level of a domain
* @level_get: gets the performance level of a domain
- * @device_domain_id: gets the scmi domain id for a given device
* @transition_latency_get: gets the DVFS transition latency for a given device
* @device_opps_add: adds all the OPPs for a given device
* @freq_set: sets the frequency for a given device using sustained frequency
@@ -120,6 +141,9 @@ struct scmi_clk_proto_ops {
* or in some other (abstract) scale
*/
struct scmi_perf_proto_ops {
+ int (*num_domains_get)(const struct scmi_protocol_handle *ph);
+ const struct scmi_perf_domain_info __must_check *(*info_get)
+ (const struct scmi_protocol_handle *ph, u32 domain);
int (*limits_set)(const struct scmi_protocol_handle *ph, u32 domain,
u32 max_perf, u32 min_perf);
int (*limits_get)(const struct scmi_protocol_handle *ph, u32 domain,
@@ -128,11 +152,10 @@ struct scmi_perf_proto_ops {
u32 level, bool poll);
int (*level_get)(const struct scmi_protocol_handle *ph, u32 domain,
u32 *level, bool poll);
- int (*device_domain_id)(struct device *dev);
int (*transition_latency_get)(const struct scmi_protocol_handle *ph,
- struct device *dev);
+ u32 domain);
int (*device_opps_add)(const struct scmi_protocol_handle *ph,
- struct device *dev);
+ struct device *dev, u32 domain);
int (*freq_set)(const struct scmi_protocol_handle *ph, u32 domain,
unsigned long rate, bool poll);
int (*freq_get)(const struct scmi_protocol_handle *ph, u32 domain,
@@ -140,7 +163,7 @@ struct scmi_perf_proto_ops {
int (*est_power_get)(const struct scmi_protocol_handle *ph, u32 domain,
unsigned long *rate, unsigned long *power);
bool (*fast_switch_possible)(const struct scmi_protocol_handle *ph,
- struct device *dev);
+ u32 domain);
enum scmi_power_scale (*power_scale_get)(const struct scmi_protocol_handle *ph);
};
diff --git a/include/linux/sed-opal-key.h b/include/linux/sed-opal-key.h
new file mode 100644
index 000000000000..0ca03054e8f6
--- /dev/null
+++ b/include/linux/sed-opal-key.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * SED key operations.
+ *
+ * Copyright (C) 2023 IBM Corporation
+ *
+ * These are the accessor functions (read/write) for SED Opal
+ * keys. Specific keystores can provide overrides.
+ *
+ */
+
+#include <linux/kernel.h>
+
+#ifdef CONFIG_PSERIES_PLPKS_SED
+int sed_read_key(char *keyname, char *key, u_int *keylen);
+int sed_write_key(char *keyname, char *key, u_int keylen);
+#else
+static inline
+int sed_read_key(char *keyname, char *key, u_int *keylen) {
+ return -EOPNOTSUPP;
+}
+static inline
+int sed_write_key(char *keyname, char *key, u_int keylen) {
+ return -EOPNOTSUPP;
+}
+#endif
diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
index 07f67b3d8e97..6c6cccc848f4 100644
--- a/include/linux/soc/mediatek/infracfg.h
+++ b/include/linux/soc/mediatek/infracfg.h
@@ -2,6 +2,47 @@
#ifndef __SOC_MEDIATEK_INFRACFG_H
#define __SOC_MEDIATEK_INFRACFG_H
+#define MT8365_INFRA_TOPAXI_PROTECTEN_STA1 0x228
+#define MT8365_INFRA_TOPAXI_PROTECTEN_SET 0x2a0
+#define MT8365_INFRA_TOPAXI_PROTECTEN_CLR 0x2a4
+#define MT8365_INFRA_TOPAXI_PROTECTEN_MM_M0 BIT(1)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_MDMCU_M1 BIT(2)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_MMAPB_S BIT(6)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_MM2INFRA_AXI_GALS_SLV_0 BIT(10)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_MM2INFRA_AXI_GALS_SLV_1 BIT(11)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_AP2CONN_AHB BIT(13)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_CONN2INFRA_AHB BIT(14)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_MFG_M0 BIT(21)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_INFRA2MFG BIT(22)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_STA1 0x258
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_SET 0x2a8
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_CLR 0x2ac
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_APU2AP BIT(2)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_MM2INFRA_AXI_GALS_MST_0 BIT(16)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_MM2INFRA_AXI_GALS_MST_1 BIT(17)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_CONN2INFRA_AXI_GALS_MST BIT(18)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_CAM2MM_AXI_GALS_MST BIT(19)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_APU_CBIP_GALS_MST BIT(20)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_INFRA2CONN_AHB_GALS_SLV BIT(21)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_PWRDNREQ_INFRA_GALS_ADB BIT(24)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_PWRDNREQ_MP1_L2C_AFIFO BIT(27)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_AUDIO_BUS_AUDIO_M BIT(28)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_AUDIO_BUS_DSP_M BIT(30)
+#define MT8365_INFRA_TOPAXI_PROTECTEN_1_AUDIO_BUS_DSP_S BIT(31)
+
+#define MT8365_INFRA_NAO_TOPAXI_SI0_STA 0x0
+#define MT8365_INFRA_NAO_TOPAXI_SI0_CTRL_UPDATED BIT(24)
+#define MT8365_INFRA_NAO_TOPAXI_SI2_STA 0x28
+#define MT8365_INFRA_NAO_TOPAXI_SI2_CTRL_UPDATED BIT(14)
+#define MT8365_INFRA_TOPAXI_SI0_CTL 0x200
+#define MT8365_INFRA_TOPAXI_SI0_WAY_EN_MMAPB_S BIT(6)
+#define MT8365_INFRA_TOPAXI_SI2_CTL 0x234
+#define MT8365_INFRA_TOPAXI_SI2_WAY_EN_PERI_M1 BIT(5)
+
+#define MT8365_SMI_COMMON_CLAMP_EN 0x3c0
+#define MT8365_SMI_COMMON_CLAMP_EN_SET 0x3c4
+#define MT8365_SMI_COMMON_CLAMP_EN_CLR 0x3c8
+
#define MT8195_TOP_AXI_PROT_EN_STA1 0x228
#define MT8195_TOP_AXI_PROT_EN_1_STA1 0x258
#define MT8195_TOP_AXI_PROT_EN_SET 0x2a0
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index 93417ba1ead4..1a886666bbb6 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -30,7 +30,7 @@
#define LLCC_NPU 23
#define LLCC_WLHW 24
#define LLCC_PIMEM 25
-#define LLCC_DRE 26
+#define LLCC_ECC 26
#define LLCC_CVP 28
#define LLCC_MODPE 29
#define LLCC_APTCM 30
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 0901af60d971..fd9d12de7e92 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -355,7 +355,6 @@ asmlinkage long sys_lremovexattr(const char __user *path,
const char __user *name);
asmlinkage long sys_fremovexattr(int fd, const char __user *name);
asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
-asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user *buf, size_t len);
asmlinkage long sys_eventfd2(unsigned int count, int flags);
asmlinkage long sys_epoll_create1(int flags);
asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 09d7429d67c0..61b40ea81f4d 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -242,6 +242,7 @@ extern void __register_sysctl_init(const char *path, struct ctl_table *table,
extern struct ctl_table_header *register_sysctl_mount_point(const char *path);
void do_sysctl_args(void);
+bool sysctl_is_alias(char *param);
int do_proc_douintvec(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos,
int (*conv)(unsigned long *lvalp,
@@ -287,6 +288,11 @@ static inline void setup_sysctl_set(struct ctl_table_set *p,
static inline void do_sysctl_args(void)
{
}
+
+static inline bool sysctl_is_alias(char *param)
+{
+ return false;
+}
#endif /* CONFIG_SYSCTL */
int sysctl_max_threads(struct ctl_table *table, int write, void *buffer,
diff --git a/include/linux/ucs2_string.h b/include/linux/ucs2_string.h
index cf3ada3e820e..c499ae809c7d 100644
--- a/include/linux/ucs2_string.h
+++ b/include/linux/ucs2_string.h
@@ -10,6 +10,7 @@ typedef u16 ucs2_char_t;
unsigned long ucs2_strnlen(const ucs2_char_t *s, size_t maxlength);
unsigned long ucs2_strlen(const ucs2_char_t *s);
unsigned long ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength);
+ssize_t ucs2_strscpy(ucs2_char_t *dst, const ucs2_char_t *src, size_t count);
int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len);
unsigned long ucs2_utf8size(const ucs2_char_t *src);
diff --git a/include/net/gro.h b/include/net/gro.h
index 88644b3ca660..b435f0ddbf64 100644
--- a/include/net/gro.h
+++ b/include/net/gro.h
@@ -41,7 +41,7 @@ struct napi_gro_cb {
/* Number of segments aggregated. */
u16 count;
- /* Used in ipv6_gro_receive() and foo-over-udp */
+ /* Used in ipv6_gro_receive() and foo-over-udp and esp-in-udp */
u16 proto;
/* Used in napi_gro_cb::free */
diff --git a/include/net/ipv6_stubs.h b/include/net/ipv6_stubs.h
index 21da31e1dff5..485c39a89866 100644
--- a/include/net/ipv6_stubs.h
+++ b/include/net/ipv6_stubs.h
@@ -60,6 +60,9 @@ struct ipv6_stub {
#if IS_ENABLED(CONFIG_XFRM)
void (*xfrm6_local_rxpmtu)(struct sk_buff *skb, u32 mtu);
int (*xfrm6_udp_encap_rcv)(struct sock *sk, struct sk_buff *skb);
+ struct sk_buff *(*xfrm6_gro_udp_encap_rcv)(struct sock *sk,
+ struct list_head *head,
+ struct sk_buff *skb);
int (*xfrm6_rcv_encap)(struct sk_buff *skb, int nexthdr, __be32 spi,
int encap_type);
#endif
diff --git a/include/net/sock.h b/include/net/sock.h
index 242590308d64..1d6931caf0c3 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1864,11 +1864,13 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
sockptr_t optval, unsigned int optlen);
int sock_setsockopt(struct socket *sock, int level, int op,
sockptr_t optval, unsigned int optlen);
+int do_sock_setsockopt(struct socket *sock, bool compat, int level,
+ int optname, sockptr_t optval, int optlen);
+int do_sock_getsockopt(struct socket *sock, bool compat, int level,
+ int optname, sockptr_t optval, sockptr_t optlen);
int sk_getsockopt(struct sock *sk, int level, int optname,
sockptr_t optval, sockptr_t optlen);
-int sock_getsockopt(struct socket *sock, int level, int op,
- char __user *optval, int __user *optlen);
int sock_gettstamp(struct socket *sock, void __user *userstamp,
bool timeval, bool time32);
struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 98d7aa78adda..c9bb0f892f55 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1207,20 +1207,20 @@ static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
}
-int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+int __xfrm_decode_session(struct net *net, struct sk_buff *skb, struct flowi *fl,
unsigned int family, int reverse);
-static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+static inline int xfrm_decode_session(struct net *net, struct sk_buff *skb, struct flowi *fl,
unsigned int family)
{
- return __xfrm_decode_session(skb, fl, family, 0);
+ return __xfrm_decode_session(net, skb, fl, family, 0);
}
-static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
+static inline int xfrm_decode_session_reverse(struct net *net, struct sk_buff *skb,
struct flowi *fl,
unsigned int family)
{
- return __xfrm_decode_session(skb, fl, family, 1);
+ return __xfrm_decode_session(net, skb, fl, family, 1);
}
int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
@@ -1296,7 +1296,7 @@ static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *sk
{
return 1;
}
-static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
+static inline int xfrm_decode_session_reverse(struct net *net, struct sk_buff *skb,
struct flowi *fl,
unsigned int family)
{
@@ -1669,7 +1669,6 @@ int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
#endif
void xfrm_local_error(struct sk_buff *skb, int mtu);
-int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
int encap_type);
int xfrm4_transport_finish(struct sk_buff *skb, int async);
@@ -1689,7 +1688,6 @@ int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char prot
int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
-int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
struct ip6_tnl *t);
int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
@@ -1712,6 +1710,10 @@ int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
+struct sk_buff *xfrm4_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
+ struct sk_buff *skb);
+struct sk_buff *xfrm6_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
+ struct sk_buff *skb);
int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
int optlen);
#else
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 65e49fae8da7..10480eb582b2 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -213,7 +213,6 @@ struct scsi_device {
unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */
unsigned no_start_on_add:1; /* do not issue start on add */
unsigned allow_restart:1; /* issue START_UNIT in error handler */
- unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */
unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */
unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
unsigned select_no_atn:1;
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
index eb5079904cc8..af793f2a0ec4 100644
--- a/include/soc/fsl/qe/qe.h
+++ b/include/soc/fsl/qe/qe.h
@@ -258,7 +258,7 @@ static inline int qe_alive_during_sleep(void)
/* Structure that defines QE firmware binary files.
*
- * See Documentation/powerpc/qe_firmware.rst for a description of these
+ * See Documentation/arch/powerpc/qe_firmware.rst for a description of these
* fields.
*/
struct qe_firmware {
diff --git a/include/soc/tegra/bpmp-abi.h b/include/soc/tegra/bpmp-abi.h
index ecefcaec7e66..6b995a8f0f6d 100644
--- a/include/soc/tegra/bpmp-abi.h
+++ b/include/soc/tegra/bpmp-abi.h
@@ -1194,7 +1194,7 @@ struct cmd_clk_is_enabled_request {
*/
struct cmd_clk_is_enabled_response {
/**
- * @brief The state of the clock that has been succesfully
+ * @brief The state of the clock that has been successfully
* requested with CMD_CLK_ENABLE or CMD_CLK_DISABLE by the
* master invoking the command earlier.
*
diff --git a/include/soc/tegra/bpmp.h b/include/soc/tegra/bpmp.h
index 5842e38bb288..f5e4ac5b8cce 100644
--- a/include/soc/tegra/bpmp.h
+++ b/include/soc/tegra/bpmp.h
@@ -102,8 +102,12 @@ struct tegra_bpmp {
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_mirror;
#endif
+
+ bool suspended;
};
+#define TEGRA_BPMP_MESSAGE_RESET BIT(0)
+
struct tegra_bpmp_message {
unsigned int mrq;
@@ -117,6 +121,8 @@ struct tegra_bpmp_message {
size_t size;
int ret;
} rx;
+
+ unsigned long flags;
};
#if IS_ENABLED(CONFIG_TEGRA_BPMP)
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index 1478b9dd05fa..d801409b33cf 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -144,7 +144,7 @@ IF_HAVE_PG_ARCH_X(arch_3)
#define __VM_ARCH_SPECIFIC_1 {VM_PAT, "pat" }
#elif defined(CONFIG_PPC)
#define __VM_ARCH_SPECIFIC_1 {VM_SAO, "sao" }
-#elif defined(CONFIG_PARISC) || defined(CONFIG_IA64)
+#elif defined(CONFIG_PARISC)
#define __VM_ARCH_SPECIFIC_1 {VM_GROWSUP, "growsup" }
#elif !defined(CONFIG_MMU)
#define __VM_ARCH_SPECIFIC_1 {VM_MAPPED_COPY,"mappedcopy" }
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index 0f52d0ac47c5..b7bc545ec3b2 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -68,11 +68,6 @@ union __sifields {
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
struct {
void __user *_addr; /* faulting insn/memory ref. */
-#ifdef __ia64__
- int _imm; /* immediate value for "break" */
- unsigned int _flags; /* see ia64 si_flags */
- unsigned long _isr; /* isr */
-#endif
#define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? \
sizeof(short) : __alignof__(void *))
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index d9e9cd13e577..756b013fb832 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -71,7 +71,7 @@ __SYSCALL(__NR_fremovexattr, sys_fremovexattr)
#define __NR_getcwd 17
__SYSCALL(__NR_getcwd, sys_getcwd)
#define __NR_lookup_dcookie 18
-__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
+__SYSCALL(__NR_lookup_dcookie, sys_ni_syscall)
#define __NR_eventfd2 19
__SYSCALL(__NR_eventfd2, sys_eventfd2)
#define __NR_epoll_create1 20
@@ -816,12 +816,12 @@ __SYSCALL(__NR_process_mrelease, sys_process_mrelease)
__SYSCALL(__NR_futex_waitv, sys_futex_waitv)
#define __NR_set_mempolicy_home_node 450
__SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node)
-
#define __NR_cachestat 451
__SYSCALL(__NR_cachestat, sys_cachestat)
-
#define __NR_fchmodat2 452
__SYSCALL(__NR_fchmodat2, sys_fchmodat2)
+#define __NR_map_shadow_stack 453
+__SYSCALL(__NR_map_shadow_stack, sys_map_shadow_stack)
#define __NR_futex_wake 454
__SYSCALL(__NR_futex_wake, sys_futex_wake)
#define __NR_futex_wait 455
diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index 8e61f8b7c2ce..f1c16f817742 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -43,6 +43,10 @@ struct io_uring_sqe {
union {
__u64 addr; /* pointer to buffer or iovecs */
__u64 splice_off_in;
+ struct {
+ __u32 level;
+ __u32 optname;
+ };
};
__u32 len; /* buffer size or number of iovecs */
union {
@@ -65,6 +69,8 @@ struct io_uring_sqe {
__u32 xattr_flags;
__u32 msg_ring_flags;
__u32 uring_cmd_flags;
+ __u32 waitid_flags;
+ __u32 futex_flags;
};
__u64 user_data; /* data to be passed back at completion time */
/* pack this to avoid bogus arm OABI complaints */
@@ -79,6 +85,7 @@ struct io_uring_sqe {
union {
__s32 splice_fd_in;
__u32 file_index;
+ __u32 optlen;
struct {
__u16 addr_len;
__u16 __pad3[1];
@@ -89,6 +96,7 @@ struct io_uring_sqe {
__u64 addr3;
__u64 __pad2[1];
};
+ __u64 optval;
/*
* If the ring is initialized with IORING_SETUP_SQE128, then
* this field is used for 80 bytes of arbitrary command data
@@ -240,19 +248,23 @@ enum io_uring_op {
IORING_OP_URING_CMD,
IORING_OP_SEND_ZC,
IORING_OP_SENDMSG_ZC,
+ IORING_OP_READ_MULTISHOT,
+ IORING_OP_WAITID,
+ IORING_OP_FUTEX_WAIT,
+ IORING_OP_FUTEX_WAKE,
+ IORING_OP_FUTEX_WAITV,
/* this goes last, obviously */
IORING_OP_LAST,
};
/*
- * sqe->uring_cmd_flags
+ * sqe->uring_cmd_flags top 8bits aren't available for userspace
* IORING_URING_CMD_FIXED use registered buffer; pass this flag
* along with setting sqe->buf_index.
- * IORING_URING_CMD_POLLED driver use only
*/
#define IORING_URING_CMD_FIXED (1U << 0)
-#define IORING_URING_CMD_POLLED (1U << 31)
+#define IORING_URING_CMD_MASK IORING_URING_CMD_FIXED
/*
@@ -734,6 +746,8 @@ struct io_uring_recvmsg_out {
enum {
SOCKET_URING_OP_SIOCINQ = 0,
SOCKET_URING_OP_SIOCOUTQ,
+ SOCKET_URING_OP_GETSOCKOPT,
+ SOCKET_URING_OP_SETSOCKOPT,
};
#ifdef __cplusplus
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index b4ba0c0cbab6..0b2bc6252e2c 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -47,6 +47,8 @@ enum {
IOMMUFD_CMD_VFIO_IOAS,
IOMMUFD_CMD_HWPT_ALLOC,
IOMMUFD_CMD_GET_HW_INFO,
+ IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING,
+ IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP,
};
/**
@@ -348,19 +350,85 @@ struct iommu_vfio_ioas {
#define IOMMU_VFIO_IOAS _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VFIO_IOAS)
/**
+ * enum iommufd_hwpt_alloc_flags - Flags for HWPT allocation
+ * @IOMMU_HWPT_ALLOC_NEST_PARENT: If set, allocate a HWPT that can serve as
+ * the parent HWPT in a nesting configuration.
+ * @IOMMU_HWPT_ALLOC_DIRTY_TRACKING: Dirty tracking support for device IOMMU is
+ * enforced on device attachment
+ */
+enum iommufd_hwpt_alloc_flags {
+ IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0,
+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1,
+};
+
+/**
+ * enum iommu_hwpt_vtd_s1_flags - Intel VT-d stage-1 page table
+ * entry attributes
+ * @IOMMU_VTD_S1_SRE: Supervisor request
+ * @IOMMU_VTD_S1_EAFE: Extended access enable
+ * @IOMMU_VTD_S1_WPE: Write protect enable
+ */
+enum iommu_hwpt_vtd_s1_flags {
+ IOMMU_VTD_S1_SRE = 1 << 0,
+ IOMMU_VTD_S1_EAFE = 1 << 1,
+ IOMMU_VTD_S1_WPE = 1 << 2,
+};
+
+/**
+ * struct iommu_hwpt_vtd_s1 - Intel VT-d stage-1 page table
+ * info (IOMMU_HWPT_DATA_VTD_S1)
+ * @flags: Combination of enum iommu_hwpt_vtd_s1_flags
+ * @pgtbl_addr: The base address of the stage-1 page table.
+ * @addr_width: The address width of the stage-1 page table
+ * @__reserved: Must be 0
+ */
+struct iommu_hwpt_vtd_s1 {
+ __aligned_u64 flags;
+ __aligned_u64 pgtbl_addr;
+ __u32 addr_width;
+ __u32 __reserved;
+};
+
+/**
+ * enum iommu_hwpt_data_type - IOMMU HWPT Data Type
+ * @IOMMU_HWPT_DATA_NONE: no data
+ * @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table
+ */
+enum iommu_hwpt_data_type {
+ IOMMU_HWPT_DATA_NONE,
+ IOMMU_HWPT_DATA_VTD_S1,
+};
+
+/**
* struct iommu_hwpt_alloc - ioctl(IOMMU_HWPT_ALLOC)
* @size: sizeof(struct iommu_hwpt_alloc)
- * @flags: Must be 0
+ * @flags: Combination of enum iommufd_hwpt_alloc_flags
* @dev_id: The device to allocate this HWPT for
- * @pt_id: The IOAS to connect this HWPT to
+ * @pt_id: The IOAS or HWPT to connect this HWPT to
* @out_hwpt_id: The ID of the new HWPT
* @__reserved: Must be 0
+ * @data_type: One of enum iommu_hwpt_data_type
+ * @data_len: Length of the type specific data
+ * @data_uptr: User pointer to the type specific data
*
* Explicitly allocate a hardware page table object. This is the same object
* type that is returned by iommufd_device_attach() and represents the
* underlying iommu driver's iommu_domain kernel object.
*
- * A HWPT will be created with the IOVA mappings from the given IOAS.
+ * A kernel-managed HWPT will be created with the mappings from the given
+ * IOAS via the @pt_id. The @data_type for this allocation must be set to
+ * IOMMU_HWPT_DATA_NONE. The HWPT can be allocated as a parent HWPT for a
+ * nesting configuration by passing IOMMU_HWPT_ALLOC_NEST_PARENT via @flags.
+ *
+ * A user-managed nested HWPT will be created from a given parent HWPT via
+ * @pt_id, in which the parent HWPT must be allocated previously via the
+ * same ioctl from a given IOAS (@pt_id). In this case, the @data_type
+ * must be set to a pre-defined type corresponding to an I/O page table
+ * type supported by the underlying IOMMU hardware.
+ *
+ * If the @data_type is set to IOMMU_HWPT_DATA_NONE, @data_len and
+ * @data_uptr should be zero. Otherwise, both @data_len and @data_uptr
+ * must be given.
*/
struct iommu_hwpt_alloc {
__u32 size;
@@ -369,13 +437,26 @@ struct iommu_hwpt_alloc {
__u32 pt_id;
__u32 out_hwpt_id;
__u32 __reserved;
+ __u32 data_type;
+ __u32 data_len;
+ __aligned_u64 data_uptr;
};
#define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC)
/**
+ * enum iommu_hw_info_vtd_flags - Flags for VT-d hw_info
+ * @IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17: If set, disallow read-only mappings
+ * on a nested_parent domain.
+ * https://www.intel.com/content/www/us/en/content-details/772415/content-details.html
+ */
+enum iommu_hw_info_vtd_flags {
+ IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17 = 1 << 0,
+};
+
+/**
* struct iommu_hw_info_vtd - Intel VT-d hardware information
*
- * @flags: Must be 0
+ * @flags: Combination of enum iommu_hw_info_vtd_flags
* @__reserved: Must be 0
*
* @cap_reg: Value of Intel VT-d capability register defined in VT-d spec
@@ -405,6 +486,20 @@ enum iommu_hw_info_type {
};
/**
+ * enum iommufd_hw_capabilities
+ * @IOMMU_HW_CAP_DIRTY_TRACKING: IOMMU hardware support for dirty tracking
+ * If available, it means the following APIs
+ * are supported:
+ *
+ * IOMMU_HWPT_GET_DIRTY_BITMAP
+ * IOMMU_HWPT_SET_DIRTY_TRACKING
+ *
+ */
+enum iommufd_hw_capabilities {
+ IOMMU_HW_CAP_DIRTY_TRACKING = 1 << 0,
+};
+
+/**
* struct iommu_hw_info - ioctl(IOMMU_GET_HW_INFO)
* @size: sizeof(struct iommu_hw_info)
* @flags: Must be 0
@@ -415,6 +510,8 @@ enum iommu_hw_info_type {
* the iommu type specific hardware information data
* @out_data_type: Output the iommu hardware info type as defined in the enum
* iommu_hw_info_type.
+ * @out_capabilities: Output the generic iommu capability info type as defined
+ * in the enum iommu_hw_capabilities.
* @__reserved: Must be 0
*
* Query an iommu type specific hardware information data from an iommu behind
@@ -439,6 +536,81 @@ struct iommu_hw_info {
__aligned_u64 data_uptr;
__u32 out_data_type;
__u32 __reserved;
+ __aligned_u64 out_capabilities;
};
#define IOMMU_GET_HW_INFO _IO(IOMMUFD_TYPE, IOMMUFD_CMD_GET_HW_INFO)
+
+/*
+ * enum iommufd_hwpt_set_dirty_tracking_flags - Flags for steering dirty
+ * tracking
+ * @IOMMU_HWPT_DIRTY_TRACKING_ENABLE: Enable dirty tracking
+ */
+enum iommufd_hwpt_set_dirty_tracking_flags {
+ IOMMU_HWPT_DIRTY_TRACKING_ENABLE = 1,
+};
+
+/**
+ * struct iommu_hwpt_set_dirty_tracking - ioctl(IOMMU_HWPT_SET_DIRTY_TRACKING)
+ * @size: sizeof(struct iommu_hwpt_set_dirty_tracking)
+ * @flags: Combination of enum iommufd_hwpt_set_dirty_tracking_flags
+ * @hwpt_id: HW pagetable ID that represents the IOMMU domain
+ * @__reserved: Must be 0
+ *
+ * Toggle dirty tracking on an HW pagetable.
+ */
+struct iommu_hwpt_set_dirty_tracking {
+ __u32 size;
+ __u32 flags;
+ __u32 hwpt_id;
+ __u32 __reserved;
+};
+#define IOMMU_HWPT_SET_DIRTY_TRACKING _IO(IOMMUFD_TYPE, \
+ IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING)
+
+/**
+ * enum iommufd_hwpt_get_dirty_bitmap_flags - Flags for getting dirty bits
+ * @IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR: Just read the PTEs without clearing
+ * any dirty bits metadata. This flag
+ * can be passed in the expectation
+ * where the next operation is an unmap
+ * of the same IOVA range.
+ *
+ */
+enum iommufd_hwpt_get_dirty_bitmap_flags {
+ IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR = 1,
+};
+
+/**
+ * struct iommu_hwpt_get_dirty_bitmap - ioctl(IOMMU_HWPT_GET_DIRTY_BITMAP)
+ * @size: sizeof(struct iommu_hwpt_get_dirty_bitmap)
+ * @hwpt_id: HW pagetable ID that represents the IOMMU domain
+ * @flags: Combination of enum iommufd_hwpt_get_dirty_bitmap_flags
+ * @__reserved: Must be 0
+ * @iova: base IOVA of the bitmap first bit
+ * @length: IOVA range size
+ * @page_size: page size granularity of each bit in the bitmap
+ * @data: bitmap where to set the dirty bits. The bitmap bits each
+ * represent a page_size which you deviate from an arbitrary iova.
+ *
+ * Checking a given IOVA is dirty:
+ *
+ * data[(iova / page_size) / 64] & (1ULL << ((iova / page_size) % 64))
+ *
+ * Walk the IOMMU pagetables for a given IOVA range to return a bitmap
+ * with the dirty IOVAs. In doing so it will also by default clear any
+ * dirty bit metadata set in the IOPTE.
+ */
+struct iommu_hwpt_get_dirty_bitmap {
+ __u32 size;
+ __u32 hwpt_id;
+ __u32 flags;
+ __u32 __reserved;
+ __aligned_u64 iova;
+ __aligned_u64 length;
+ __aligned_u64 page_size;
+ __aligned_u64 data;
+};
+#define IOMMU_HWPT_GET_DIRTY_BITMAP _IO(IOMMUFD_TYPE, \
+ IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP)
+
#endif
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index afc1369216d9..7f5fb010226d 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -277,8 +277,8 @@ struct vfio_region_info {
#define VFIO_REGION_INFO_FLAG_CAPS (1 << 3) /* Info supports caps */
__u32 index; /* Region index */
__u32 cap_offset; /* Offset within info struct of first cap */
- __u64 size; /* Region size (bytes) */
- __u64 offset; /* Region offset from start of device fd */
+ __aligned_u64 size; /* Region size (bytes) */
+ __aligned_u64 offset; /* Region offset from start of device fd */
};
#define VFIO_DEVICE_GET_REGION_INFO _IO(VFIO_TYPE, VFIO_BASE + 8)
@@ -294,8 +294,8 @@ struct vfio_region_info {
#define VFIO_REGION_INFO_CAP_SPARSE_MMAP 1
struct vfio_region_sparse_mmap_area {
- __u64 offset; /* Offset of mmap'able area within region */
- __u64 size; /* Size of mmap'able area */
+ __aligned_u64 offset; /* Offset of mmap'able area within region */
+ __aligned_u64 size; /* Size of mmap'able area */
};
struct vfio_region_info_cap_sparse_mmap {
@@ -450,9 +450,9 @@ struct vfio_device_migration_info {
VFIO_DEVICE_STATE_V1_RESUMING)
__u32 reserved;
- __u64 pending_bytes;
- __u64 data_offset;
- __u64 data_size;
+ __aligned_u64 pending_bytes;
+ __aligned_u64 data_offset;
+ __aligned_u64 data_size;
};
/*
@@ -476,7 +476,7 @@ struct vfio_device_migration_info {
struct vfio_region_info_cap_nvlink2_ssatgt {
struct vfio_info_cap_header header;
- __u64 tgt;
+ __aligned_u64 tgt;
};
/*
@@ -816,7 +816,7 @@ struct vfio_device_gfx_plane_info {
__u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */
/* out */
__u32 drm_format; /* drm format of plane */
- __u64 drm_format_mod; /* tiled mode */
+ __aligned_u64 drm_format_mod; /* tiled mode */
__u32 width; /* width of plane */
__u32 height; /* height of plane */
__u32 stride; /* stride of plane */
@@ -829,6 +829,7 @@ struct vfio_device_gfx_plane_info {
__u32 region_index; /* region index */
__u32 dmabuf_id; /* dma-buf id */
};
+ __u32 reserved;
};
#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14)
@@ -863,9 +864,10 @@ struct vfio_device_ioeventfd {
#define VFIO_DEVICE_IOEVENTFD_32 (1 << 2) /* 4-byte write */
#define VFIO_DEVICE_IOEVENTFD_64 (1 << 3) /* 8-byte write */
#define VFIO_DEVICE_IOEVENTFD_SIZE_MASK (0xf)
- __u64 offset; /* device fd offset of write */
- __u64 data; /* data to be written */
+ __aligned_u64 offset; /* device fd offset of write */
+ __aligned_u64 data; /* data to be written */
__s32 fd; /* -1 for de-assignment */
+ __u32 reserved;
};
#define VFIO_DEVICE_IOEVENTFD _IO(VFIO_TYPE, VFIO_BASE + 16)
@@ -1434,6 +1436,27 @@ struct vfio_device_feature_mig_data_size {
#define VFIO_DEVICE_FEATURE_MIG_DATA_SIZE 9
+/**
+ * Upon VFIO_DEVICE_FEATURE_SET, set or clear the BUS mastering for the device
+ * based on the operation specified in op flag.
+ *
+ * The functionality is incorporated for devices that needs bus master control,
+ * but the in-band device interface lacks the support. Consequently, it is not
+ * applicable to PCI devices, as bus master control for PCI devices is managed
+ * in-band through the configuration space. At present, this feature is supported
+ * only for CDX devices.
+ * When the device's BUS MASTER setting is configured as CLEAR, it will result in
+ * blocking all incoming DMA requests from the device. On the other hand, configuring
+ * the device's BUS MASTER setting as SET (enable) will grant the device the
+ * capability to perform DMA to the host memory.
+ */
+struct vfio_device_feature_bus_master {
+ __u32 op;
+#define VFIO_DEVICE_FEATURE_CLEAR_MASTER 0 /* Clear Bus Master */
+#define VFIO_DEVICE_FEATURE_SET_MASTER 1 /* Set Bus Master */
+};
+#define VFIO_DEVICE_FEATURE_BUS_MASTER 10
+
/* -------- API for Type1 VFIO IOMMU -------- */
/**
@@ -1449,7 +1472,7 @@ struct vfio_iommu_type1_info {
__u32 flags;
#define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */
#define VFIO_IOMMU_INFO_CAPS (1 << 1) /* Info supports caps */
- __u64 iova_pgsizes; /* Bitmap of supported page sizes */
+ __aligned_u64 iova_pgsizes; /* Bitmap of supported page sizes */
__u32 cap_offset; /* Offset within info struct of first cap */
__u32 pad;
};
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 23543c33fee8..6a77328be114 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -4,6 +4,7 @@
#include <linux/in6.h>
#include <linux/types.h>
+#include <linux/stddef.h>
/* All of the structures in this file may not change size as they are
* passed into the kernel from userspace via netlink sockets.
@@ -33,7 +34,7 @@ struct xfrm_sec_ctx {
__u8 ctx_alg;
__u16 ctx_len;
__u32 ctx_sid;
- char ctx_str[];
+ char ctx_str[] __counted_by(ctx_len);
};
/* Security Context Domains of Interpretation */
diff --git a/include/uapi/xen/privcmd.h b/include/uapi/xen/privcmd.h
index 375718ba4ab6..8b8c5d1420fe 100644
--- a/include/uapi/xen/privcmd.h
+++ b/include/uapi/xen/privcmd.h
@@ -102,7 +102,7 @@ struct privcmd_mmap_resource {
#define PRIVCMD_IRQFD_FLAG_DEASSIGN (1 << 0)
struct privcmd_irqfd {
- void __user *dm_op;
+ __u64 dm_op;
__u32 size; /* Size of structure pointed by dm_op */
__u32 fd;
__u32 flags;
@@ -110,6 +110,22 @@ struct privcmd_irqfd {
__u8 pad[2];
};
+/* For privcmd_ioeventfd::flags */
+#define PRIVCMD_IOEVENTFD_FLAG_DEASSIGN (1 << 0)
+
+struct privcmd_ioeventfd {
+ __u64 ioreq;
+ __u64 ports;
+ __u64 addr;
+ __u32 addr_len;
+ __u32 event_fd;
+ __u32 vcpus;
+ __u32 vq;
+ __u32 flags;
+ domid_t dom;
+ __u8 pad[2];
+};
+
/*
* @cmd: IOCTL_PRIVCMD_HYPERCALL
* @arg: &privcmd_hypercall_t
@@ -138,6 +154,8 @@ struct privcmd_irqfd {
#define IOCTL_PRIVCMD_MMAP_RESOURCE \
_IOC(_IOC_NONE, 'P', 7, sizeof(struct privcmd_mmap_resource))
#define IOCTL_PRIVCMD_IRQFD \
- _IOC(_IOC_NONE, 'P', 8, sizeof(struct privcmd_irqfd))
+ _IOW('P', 8, struct privcmd_irqfd)
+#define IOCTL_PRIVCMD_IOEVENTFD \
+ _IOW('P', 9, struct privcmd_ioeventfd)
#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
diff --git a/include/video/sticore.h b/include/video/sticore.h
index 945ad60463a1..012b5b46ad7d 100644
--- a/include/video/sticore.h
+++ b/include/video/sticore.h
@@ -232,7 +232,7 @@ struct sti_rom_font {
u8 height;
u8 font_type; /* language type */
u8 bytes_per_char;
- u32 next_font;
+ s32 next_font; /* note: signed int */
u8 underline_height;
u8 underline_pos;
u8 res008[2];
diff --git a/include/xen/interface/hvm/ioreq.h b/include/xen/interface/hvm/ioreq.h
new file mode 100644
index 000000000000..b02cfeae7eb5
--- /dev/null
+++ b/include/xen/interface/hvm/ioreq.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * ioreq.h: I/O request definitions for device models
+ * Copyright (c) 2004, Intel Corporation.
+ */
+
+#ifndef __XEN_PUBLIC_HVM_IOREQ_H__
+#define __XEN_PUBLIC_HVM_IOREQ_H__
+
+#define IOREQ_READ 1
+#define IOREQ_WRITE 0
+
+#define STATE_IOREQ_NONE 0
+#define STATE_IOREQ_READY 1
+#define STATE_IOREQ_INPROCESS 2
+#define STATE_IORESP_READY 3
+
+#define IOREQ_TYPE_PIO 0 /* pio */
+#define IOREQ_TYPE_COPY 1 /* mmio ops */
+#define IOREQ_TYPE_PCI_CONFIG 2
+#define IOREQ_TYPE_TIMEOFFSET 7
+#define IOREQ_TYPE_INVALIDATE 8 /* mapcache */
+
+/*
+ * VMExit dispatcher should cooperate with instruction decoder to
+ * prepare this structure and notify service OS and DM by sending
+ * virq.
+ *
+ * For I/O type IOREQ_TYPE_PCI_CONFIG, the physical address is formatted
+ * as follows:
+ *
+ * 63....48|47..40|39..35|34..32|31........0
+ * SEGMENT |BUS |DEV |FN |OFFSET
+ */
+struct ioreq {
+ uint64_t addr; /* physical address */
+ uint64_t data; /* data (or paddr of data) */
+ uint32_t count; /* for rep prefixes */
+ uint32_t size; /* size in bytes */
+ uint32_t vp_eport; /* evtchn for notifications to/from device model */
+ uint16_t _pad0;
+ uint8_t state:4;
+ uint8_t data_is_ptr:1; /* if 1, data above is the guest paddr
+ * of the real data to use. */
+ uint8_t dir:1; /* 1=read, 0=write */
+ uint8_t df:1;
+ uint8_t _pad1:1;
+ uint8_t type; /* I/O type */
+};
+
+#endif /* __XEN_PUBLIC_HVM_IOREQ_H__ */
diff --git a/init/Kconfig b/init/Kconfig
index 6d35728b94b2..9ffb103fc927 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1723,7 +1723,7 @@ config KALLSYMS_ABSOLUTE_PERCPU
config KALLSYMS_BASE_RELATIVE
bool
depends on KALLSYMS
- default !IA64
+ default y
help
Instead of emitting them as absolute values in the native word size,
emit the symbol references in the kallsyms table as 32-bit entries,
diff --git a/init/main.c b/init/main.c
index 436d73261810..e24b0780fdff 100644
--- a/init/main.c
+++ b/init/main.c
@@ -530,6 +530,10 @@ static int __init unknown_bootoption(char *param, char *val,
{
size_t len = strlen(param);
+ /* Handle params aliased to sysctls */
+ if (sysctl_is_alias(param))
+ return 0;
+
repair_env_string(param, val);
/* Handle obsolete-style parameters */
diff --git a/io_uring/Makefile b/io_uring/Makefile
index 8cc8e5387a75..e5be47e4fc3b 100644
--- a/io_uring/Makefile
+++ b/io_uring/Makefile
@@ -7,5 +7,7 @@ obj-$(CONFIG_IO_URING) += io_uring.o xattr.o nop.o fs.o splice.o \
openclose.o uring_cmd.o epoll.o \
statx.o net.o msg_ring.o timeout.o \
sqpoll.o fdinfo.o tctx.o poll.o \
- cancel.o kbuf.o rsrc.o rw.o opdef.o notif.o
+ cancel.o kbuf.o rsrc.o rw.o opdef.o \
+ notif.o waitid.o
obj-$(CONFIG_IO_WQ) += io-wq.o
+obj-$(CONFIG_FUTEX) += futex.o
diff --git a/io_uring/cancel.c b/io_uring/cancel.c
index 7b23607cf4af..3c19cccb1aec 100644
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -15,6 +15,8 @@
#include "tctx.h"
#include "poll.h"
#include "timeout.h"
+#include "waitid.h"
+#include "futex.h"
#include "cancel.h"
struct io_cancel {
@@ -119,6 +121,14 @@ int io_try_cancel(struct io_uring_task *tctx, struct io_cancel_data *cd,
if (ret != -ENOENT)
return ret;
+ ret = io_waitid_cancel(ctx, cd, issue_flags);
+ if (ret != -ENOENT)
+ return ret;
+
+ ret = io_futex_cancel(ctx, cd, issue_flags);
+ if (ret != -ENOENT)
+ return ret;
+
spin_lock(&ctx->completion_lock);
if (!(cd->flags & IORING_ASYNC_CANCEL_FD))
ret = io_timeout_cancel(ctx, cd);
diff --git a/io_uring/cancel.h b/io_uring/cancel.h
index fc98622e6166..c0a8e7c520b6 100644
--- a/io_uring/cancel.h
+++ b/io_uring/cancel.h
@@ -1,4 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
+#ifndef IORING_CANCEL_H
+#define IORING_CANCEL_H
#include <linux/io_uring_types.h>
@@ -22,3 +24,5 @@ void init_hash_table(struct io_hash_table *table, unsigned size);
int io_sync_cancel(struct io_ring_ctx *ctx, void __user *arg);
bool io_cancel_req_match(struct io_kiocb *req, struct io_cancel_data *cd);
+
+#endif
diff --git a/io_uring/futex.c b/io_uring/futex.c
new file mode 100644
index 000000000000..3c3575303c3d
--- /dev/null
+++ b/io_uring/futex.c
@@ -0,0 +1,386 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/io_uring.h>
+
+#include <uapi/linux/io_uring.h>
+
+#include "../kernel/futex/futex.h"
+#include "io_uring.h"
+#include "rsrc.h"
+#include "futex.h"
+
+struct io_futex {
+ struct file *file;
+ union {
+ u32 __user *uaddr;
+ struct futex_waitv __user *uwaitv;
+ };
+ unsigned long futex_val;
+ unsigned long futex_mask;
+ unsigned long futexv_owned;
+ u32 futex_flags;
+ unsigned int futex_nr;
+ bool futexv_unqueued;
+};
+
+struct io_futex_data {
+ union {
+ struct futex_q q;
+ struct io_cache_entry cache;
+ };
+ struct io_kiocb *req;
+};
+
+void io_futex_cache_init(struct io_ring_ctx *ctx)
+{
+ io_alloc_cache_init(&ctx->futex_cache, IO_NODE_ALLOC_CACHE_MAX,
+ sizeof(struct io_futex_data));
+}
+
+static void io_futex_cache_entry_free(struct io_cache_entry *entry)
+{
+ kfree(container_of(entry, struct io_futex_data, cache));
+}
+
+void io_futex_cache_free(struct io_ring_ctx *ctx)
+{
+ io_alloc_cache_free(&ctx->futex_cache, io_futex_cache_entry_free);
+}
+
+static void __io_futex_complete(struct io_kiocb *req, struct io_tw_state *ts)
+{
+ req->async_data = NULL;
+ hlist_del_init(&req->hash_node);
+ io_req_task_complete(req, ts);
+}
+
+static void io_futex_complete(struct io_kiocb *req, struct io_tw_state *ts)
+{
+ struct io_futex_data *ifd = req->async_data;
+ struct io_ring_ctx *ctx = req->ctx;
+
+ io_tw_lock(ctx, ts);
+ if (!io_alloc_cache_put(&ctx->futex_cache, &ifd->cache))
+ kfree(ifd);
+ __io_futex_complete(req, ts);
+}
+
+static void io_futexv_complete(struct io_kiocb *req, struct io_tw_state *ts)
+{
+ struct io_futex *iof = io_kiocb_to_cmd(req, struct io_futex);
+ struct futex_vector *futexv = req->async_data;
+
+ io_tw_lock(req->ctx, ts);
+
+ if (!iof->futexv_unqueued) {
+ int res;
+
+ res = futex_unqueue_multiple(futexv, iof->futex_nr);
+ if (res != -1)
+ io_req_set_res(req, res, 0);
+ }
+
+ kfree(req->async_data);
+ req->flags &= ~REQ_F_ASYNC_DATA;
+ __io_futex_complete(req, ts);
+}
+
+static bool io_futexv_claim(struct io_futex *iof)
+{
+ if (test_bit(0, &iof->futexv_owned) ||
+ test_and_set_bit_lock(0, &iof->futexv_owned))
+ return false;
+ return true;
+}
+
+static bool __io_futex_cancel(struct io_ring_ctx *ctx, struct io_kiocb *req)
+{
+ /* futex wake already done or in progress */
+ if (req->opcode == IORING_OP_FUTEX_WAIT) {
+ struct io_futex_data *ifd = req->async_data;
+
+ if (!futex_unqueue(&ifd->q))
+ return false;
+ req->io_task_work.func = io_futex_complete;
+ } else {
+ struct io_futex *iof = io_kiocb_to_cmd(req, struct io_futex);
+
+ if (!io_futexv_claim(iof))
+ return false;
+ req->io_task_work.func = io_futexv_complete;
+ }
+
+ hlist_del_init(&req->hash_node);
+ io_req_set_res(req, -ECANCELED, 0);
+ io_req_task_work_add(req);
+ return true;
+}
+
+int io_futex_cancel(struct io_ring_ctx *ctx, struct io_cancel_data *cd,
+ unsigned int issue_flags)
+{
+ struct hlist_node *tmp;
+ struct io_kiocb *req;
+ int nr = 0;
+
+ if (cd->flags & (IORING_ASYNC_CANCEL_FD|IORING_ASYNC_CANCEL_FD_FIXED))
+ return -ENOENT;
+
+ io_ring_submit_lock(ctx, issue_flags);
+ hlist_for_each_entry_safe(req, tmp, &ctx->futex_list, hash_node) {
+ if (req->cqe.user_data != cd->data &&
+ !(cd->flags & IORING_ASYNC_CANCEL_ANY))
+ continue;
+ if (__io_futex_cancel(ctx, req))
+ nr++;
+ if (!(cd->flags & IORING_ASYNC_CANCEL_ALL))
+ break;
+ }
+ io_ring_submit_unlock(ctx, issue_flags);
+
+ if (nr)
+ return nr;
+
+ return -ENOENT;
+}
+
+bool io_futex_remove_all(struct io_ring_ctx *ctx, struct task_struct *task,
+ bool cancel_all)
+{
+ struct hlist_node *tmp;
+ struct io_kiocb *req;
+ bool found = false;
+
+ lockdep_assert_held(&ctx->uring_lock);
+
+ hlist_for_each_entry_safe(req, tmp, &ctx->futex_list, hash_node) {
+ if (!io_match_task_safe(req, task, cancel_all))
+ continue;
+ __io_futex_cancel(ctx, req);
+ found = true;
+ }
+
+ return found;
+}
+
+int io_futex_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+{
+ struct io_futex *iof = io_kiocb_to_cmd(req, struct io_futex);
+ u32 flags;
+
+ if (unlikely(sqe->len || sqe->futex_flags || sqe->buf_index ||
+ sqe->file_index))
+ return -EINVAL;
+
+ iof->uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr));
+ iof->futex_val = READ_ONCE(sqe->addr2);
+ iof->futex_mask = READ_ONCE(sqe->addr3);
+ flags = READ_ONCE(sqe->fd);
+
+ if (flags & ~FUTEX2_VALID_MASK)
+ return -EINVAL;
+
+ iof->futex_flags = futex2_to_flags(flags);
+ if (!futex_flags_valid(iof->futex_flags))
+ return -EINVAL;
+
+ if (!futex_validate_input(iof->futex_flags, iof->futex_val) ||
+ !futex_validate_input(iof->futex_flags, iof->futex_mask))
+ return -EINVAL;
+
+ return 0;
+}
+
+static void io_futex_wakev_fn(struct wake_q_head *wake_q, struct futex_q *q)
+{
+ struct io_kiocb *req = q->wake_data;
+ struct io_futex *iof = io_kiocb_to_cmd(req, struct io_futex);
+
+ if (!io_futexv_claim(iof))
+ return;
+ if (unlikely(!__futex_wake_mark(q)))
+ return;
+
+ io_req_set_res(req, 0, 0);
+ req->io_task_work.func = io_futexv_complete;
+ io_req_task_work_add(req);
+}
+
+int io_futexv_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+{
+ struct io_futex *iof = io_kiocb_to_cmd(req, struct io_futex);
+ struct futex_vector *futexv;
+ int ret;
+
+ /* No flags or mask supported for waitv */
+ if (unlikely(sqe->fd || sqe->buf_index || sqe->file_index ||
+ sqe->addr2 || sqe->futex_flags || sqe->addr3))
+ return -EINVAL;
+
+ iof->uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr));
+ iof->futex_nr = READ_ONCE(sqe->len);
+ if (!iof->futex_nr || iof->futex_nr > FUTEX_WAITV_MAX)
+ return -EINVAL;
+
+ futexv = kcalloc(iof->futex_nr, sizeof(*futexv), GFP_KERNEL);
+ if (!futexv)
+ return -ENOMEM;
+
+ ret = futex_parse_waitv(futexv, iof->uwaitv, iof->futex_nr,
+ io_futex_wakev_fn, req);
+ if (ret) {
+ kfree(futexv);
+ return ret;
+ }
+
+ iof->futexv_owned = 0;
+ iof->futexv_unqueued = 0;
+ req->flags |= REQ_F_ASYNC_DATA;
+ req->async_data = futexv;
+ return 0;
+}
+
+static void io_futex_wake_fn(struct wake_q_head *wake_q, struct futex_q *q)
+{
+ struct io_futex_data *ifd = container_of(q, struct io_futex_data, q);
+ struct io_kiocb *req = ifd->req;
+
+ if (unlikely(!__futex_wake_mark(q)))
+ return;
+
+ io_req_set_res(req, 0, 0);
+ req->io_task_work.func = io_futex_complete;
+ io_req_task_work_add(req);
+}
+
+static struct io_futex_data *io_alloc_ifd(struct io_ring_ctx *ctx)
+{
+ struct io_cache_entry *entry;
+
+ entry = io_alloc_cache_get(&ctx->futex_cache);
+ if (entry)
+ return container_of(entry, struct io_futex_data, cache);
+
+ return kmalloc(sizeof(struct io_futex_data), GFP_NOWAIT);
+}
+
+int io_futexv_wait(struct io_kiocb *req, unsigned int issue_flags)
+{
+ struct io_futex *iof = io_kiocb_to_cmd(req, struct io_futex);
+ struct futex_vector *futexv = req->async_data;
+ struct io_ring_ctx *ctx = req->ctx;
+ int ret, woken = -1;
+
+ io_ring_submit_lock(ctx, issue_flags);
+
+ ret = futex_wait_multiple_setup(futexv, iof->futex_nr, &woken);
+
+ /*
+ * Error case, ret is < 0. Mark the request as failed.
+ */
+ if (unlikely(ret < 0)) {
+ io_ring_submit_unlock(ctx, issue_flags);
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+ kfree(futexv);
+ req->async_data = NULL;
+ req->flags &= ~REQ_F_ASYNC_DATA;
+ return IOU_OK;
+ }
+
+ /*
+ * 0 return means that we successfully setup the waiters, and that
+ * nobody triggered a wakeup while we were doing so. If the wakeup
+ * happened post setup, the task_work will be run post this issue and
+ * under the submission lock. 1 means We got woken while setting up,
+ * let that side do the completion. Note that
+ * futex_wait_multiple_setup() will have unqueued all the futexes in
+ * this case. Mark us as having done that already, since this is
+ * different from normal wakeup.
+ */
+ if (!ret) {
+ /*
+ * If futex_wait_multiple_setup() returns 0 for a
+ * successful setup, then the task state will not be
+ * runnable. This is fine for the sync syscall, as
+ * it'll be blocking unless we already got one of the
+ * futexes woken, but it obviously won't work for an
+ * async invocation. Mark us runnable again.
+ */
+ __set_current_state(TASK_RUNNING);
+ hlist_add_head(&req->hash_node, &ctx->futex_list);
+ } else {
+ iof->futexv_unqueued = 1;
+ if (woken != -1)
+ io_req_set_res(req, woken, 0);
+ }
+
+ io_ring_submit_unlock(ctx, issue_flags);
+ return IOU_ISSUE_SKIP_COMPLETE;
+}
+
+int io_futex_wait(struct io_kiocb *req, unsigned int issue_flags)
+{
+ struct io_futex *iof = io_kiocb_to_cmd(req, struct io_futex);
+ struct io_ring_ctx *ctx = req->ctx;
+ struct io_futex_data *ifd = NULL;
+ struct futex_hash_bucket *hb;
+ int ret;
+
+ if (!iof->futex_mask) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ io_ring_submit_lock(ctx, issue_flags);
+ ifd = io_alloc_ifd(ctx);
+ if (!ifd) {
+ ret = -ENOMEM;
+ goto done_unlock;
+ }
+
+ req->async_data = ifd;
+ ifd->q = futex_q_init;
+ ifd->q.bitset = iof->futex_mask;
+ ifd->q.wake = io_futex_wake_fn;
+ ifd->req = req;
+
+ ret = futex_wait_setup(iof->uaddr, iof->futex_val, iof->futex_flags,
+ &ifd->q, &hb);
+ if (!ret) {
+ hlist_add_head(&req->hash_node, &ctx->futex_list);
+ io_ring_submit_unlock(ctx, issue_flags);
+
+ futex_queue(&ifd->q, hb);
+ return IOU_ISSUE_SKIP_COMPLETE;
+ }
+
+done_unlock:
+ io_ring_submit_unlock(ctx, issue_flags);
+done:
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+ kfree(ifd);
+ return IOU_OK;
+}
+
+int io_futex_wake(struct io_kiocb *req, unsigned int issue_flags)
+{
+ struct io_futex *iof = io_kiocb_to_cmd(req, struct io_futex);
+ int ret;
+
+ /*
+ * Strict flags - ensure that waking 0 futexes yields a 0 result.
+ * See commit 43adf8449510 ("futex: FLAGS_STRICT") for details.
+ */
+ ret = futex_wake(iof->uaddr, FLAGS_STRICT | iof->futex_flags,
+ iof->futex_val, iof->futex_mask);
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+ return IOU_OK;
+}
diff --git a/io_uring/futex.h b/io_uring/futex.h
new file mode 100644
index 000000000000..0847e9e8a127
--- /dev/null
+++ b/io_uring/futex.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "cancel.h"
+
+int io_futex_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+int io_futexv_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+int io_futex_wait(struct io_kiocb *req, unsigned int issue_flags);
+int io_futexv_wait(struct io_kiocb *req, unsigned int issue_flags);
+int io_futex_wake(struct io_kiocb *req, unsigned int issue_flags);
+
+#if defined(CONFIG_FUTEX)
+int io_futex_cancel(struct io_ring_ctx *ctx, struct io_cancel_data *cd,
+ unsigned int issue_flags);
+bool io_futex_remove_all(struct io_ring_ctx *ctx, struct task_struct *task,
+ bool cancel_all);
+void io_futex_cache_init(struct io_ring_ctx *ctx);
+void io_futex_cache_free(struct io_ring_ctx *ctx);
+#else
+static inline int io_futex_cancel(struct io_ring_ctx *ctx,
+ struct io_cancel_data *cd,
+ unsigned int issue_flags)
+{
+ return 0;
+}
+static inline bool io_futex_remove_all(struct io_ring_ctx *ctx,
+ struct task_struct *task, bool cancel_all)
+{
+ return false;
+}
+static inline void io_futex_cache_init(struct io_ring_ctx *ctx)
+{
+}
+static inline void io_futex_cache_free(struct io_ring_ctx *ctx)
+{
+}
+#endif
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index 8d1bc6cdfe71..ed254076c723 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -92,6 +92,8 @@
#include "cancel.h"
#include "net.h"
#include "notif.h"
+#include "waitid.h"
+#include "futex.h"
#include "timeout.h"
#include "poll.h"
@@ -329,6 +331,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
sizeof(struct async_poll));
io_alloc_cache_init(&ctx->netmsg_cache, IO_ALLOC_CACHE_MAX,
sizeof(struct io_async_msghdr));
+ io_futex_cache_init(ctx);
init_completion(&ctx->ref_comp);
xa_init_flags(&ctx->personalities, XA_FLAGS_ALLOC1);
mutex_init(&ctx->uring_lock);
@@ -338,7 +341,6 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
spin_lock_init(&ctx->completion_lock);
spin_lock_init(&ctx->timeout_lock);
INIT_WQ_LIST(&ctx->iopoll_list);
- INIT_LIST_HEAD(&ctx->io_buffers_pages);
INIT_LIST_HEAD(&ctx->io_buffers_comp);
INIT_LIST_HEAD(&ctx->defer_list);
INIT_LIST_HEAD(&ctx->timeout_list);
@@ -348,8 +350,13 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
INIT_LIST_HEAD(&ctx->tctx_list);
ctx->submit_state.free_list.next = NULL;
INIT_WQ_LIST(&ctx->locked_free_list);
+ INIT_HLIST_HEAD(&ctx->waitid_list);
+#ifdef CONFIG_FUTEX
+ INIT_HLIST_HEAD(&ctx->futex_list);
+#endif
INIT_DELAYED_WORK(&ctx->fallback_work, io_fallback_req_func);
INIT_WQ_LIST(&ctx->submit_state.compl_reqs);
+ INIT_HLIST_HEAD(&ctx->cancelable_uring_cmd);
return ctx;
err:
kfree(ctx->cancel_table.hbs);
@@ -2912,6 +2919,7 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
io_eventfd_unregister(ctx);
io_alloc_cache_free(&ctx->apoll_cache, io_apoll_cache_free);
io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free);
+ io_futex_cache_free(ctx);
io_destroy_buffers(ctx);
mutex_unlock(&ctx->uring_lock);
if (ctx->sq_creds)
@@ -3276,6 +3284,37 @@ static __cold bool io_uring_try_cancel_iowq(struct io_ring_ctx *ctx)
return ret;
}
+static bool io_uring_try_cancel_uring_cmd(struct io_ring_ctx *ctx,
+ struct task_struct *task, bool cancel_all)
+{
+ struct hlist_node *tmp;
+ struct io_kiocb *req;
+ bool ret = false;
+
+ lockdep_assert_held(&ctx->uring_lock);
+
+ hlist_for_each_entry_safe(req, tmp, &ctx->cancelable_uring_cmd,
+ hash_node) {
+ struct io_uring_cmd *cmd = io_kiocb_to_cmd(req,
+ struct io_uring_cmd);
+ struct file *file = req->file;
+
+ if (!cancel_all && req->task != task)
+ continue;
+
+ if (cmd->flags & IORING_URING_CMD_CANCELABLE) {
+ /* ->sqe isn't available if no async data */
+ if (!req_has_async_data(req))
+ cmd->sqe = NULL;
+ file->f_op->uring_cmd(cmd, IO_URING_F_CANCEL);
+ ret = true;
+ }
+ }
+ io_submit_flush_completions(ctx);
+
+ return ret;
+}
+
static __cold bool io_uring_try_cancel_requests(struct io_ring_ctx *ctx,
struct task_struct *task,
bool cancel_all)
@@ -3323,6 +3362,9 @@ static __cold bool io_uring_try_cancel_requests(struct io_ring_ctx *ctx,
ret |= io_cancel_defer_files(ctx, task, cancel_all);
mutex_lock(&ctx->uring_lock);
ret |= io_poll_remove_all(ctx, task, cancel_all);
+ ret |= io_waitid_remove_all(ctx, task, cancel_all);
+ ret |= io_futex_remove_all(ctx, task, cancel_all);
+ ret |= io_uring_try_cancel_uring_cmd(ctx, task, cancel_all);
mutex_unlock(&ctx->uring_lock);
ret |= io_kill_timeouts(ctx, task, cancel_all);
if (task)
@@ -4686,6 +4728,9 @@ static int __init io_uring_init(void)
BUILD_BUG_ON(sizeof(atomic_t) != sizeof(u32));
+ /* top 8bits are for internal use */
+ BUILD_BUG_ON((IORING_URING_CMD_MASK & 0xff000000) != 0);
+
io_uring_optable_init();
/*
@@ -4701,6 +4746,9 @@ static int __init io_uring_init(void)
SLAB_ACCOUNT | SLAB_TYPESAFE_BY_RCU,
offsetof(struct io_kiocb, cmd.data),
sizeof_field(struct io_kiocb, cmd.data), NULL);
+ io_buf_cachep = kmem_cache_create("io_buffer", sizeof(struct io_buffer), 0,
+ SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT,
+ NULL);
#ifdef CONFIG_SYSCTL
register_sysctl_init("kernel", kernel_io_uring_disabled_table);
diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
index 0bc145614a6e..dc6d779b452b 100644
--- a/io_uring/io_uring.h
+++ b/io_uring/io_uring.h
@@ -343,6 +343,7 @@ static inline bool io_req_cache_empty(struct io_ring_ctx *ctx)
}
extern struct kmem_cache *req_cachep;
+extern struct kmem_cache *io_buf_cachep;
static inline struct io_kiocb *io_extract_req(struct io_ring_ctx *ctx)
{
diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
index 9123138aa9f4..fea06810b43d 100644
--- a/io_uring/kbuf.c
+++ b/io_uring/kbuf.c
@@ -19,12 +19,17 @@
#define BGID_ARRAY 64
+/* BIDs are addressed by a 16-bit field in a CQE */
+#define MAX_BIDS_PER_BGID (1 << 16)
+
+struct kmem_cache *io_buf_cachep;
+
struct io_provide_buf {
struct file *file;
__u64 addr;
__u32 len;
__u32 bgid;
- __u16 nbufs;
+ __u32 nbufs;
__u16 bid;
};
@@ -255,6 +260,8 @@ static int __io_remove_buffers(struct io_ring_ctx *ctx,
void io_destroy_buffers(struct io_ring_ctx *ctx)
{
struct io_buffer_list *bl;
+ struct list_head *item, *tmp;
+ struct io_buffer *buf;
unsigned long index;
int i;
@@ -270,12 +277,9 @@ void io_destroy_buffers(struct io_ring_ctx *ctx)
kfree(bl);
}
- while (!list_empty(&ctx->io_buffers_pages)) {
- struct page *page;
-
- page = list_first_entry(&ctx->io_buffers_pages, struct page, lru);
- list_del_init(&page->lru);
- __free_page(page);
+ list_for_each_safe(item, tmp, &ctx->io_buffers_cache) {
+ buf = list_entry(item, struct io_buffer, list);
+ kmem_cache_free(io_buf_cachep, buf);
}
}
@@ -289,7 +293,7 @@ int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
return -EINVAL;
tmp = READ_ONCE(sqe->fd);
- if (!tmp || tmp > USHRT_MAX)
+ if (!tmp || tmp > MAX_BIDS_PER_BGID)
return -EINVAL;
memset(p, 0, sizeof(*p));
@@ -332,7 +336,7 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
return -EINVAL;
tmp = READ_ONCE(sqe->fd);
- if (!tmp || tmp > USHRT_MAX)
+ if (!tmp || tmp > MAX_BIDS_PER_BGID)
return -E2BIG;
p->nbufs = tmp;
p->addr = READ_ONCE(sqe->addr);
@@ -352,17 +356,18 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
tmp = READ_ONCE(sqe->off);
if (tmp > USHRT_MAX)
return -E2BIG;
- if (tmp + p->nbufs >= USHRT_MAX)
+ if (tmp + p->nbufs > MAX_BIDS_PER_BGID)
return -EINVAL;
p->bid = tmp;
return 0;
}
+#define IO_BUFFER_ALLOC_BATCH 64
+
static int io_refill_buffer_cache(struct io_ring_ctx *ctx)
{
- struct io_buffer *buf;
- struct page *page;
- int bufs_in_page;
+ struct io_buffer *bufs[IO_BUFFER_ALLOC_BATCH];
+ int allocated;
/*
* Completions that don't happen inline (eg not under uring_lock) will
@@ -382,22 +387,25 @@ static int io_refill_buffer_cache(struct io_ring_ctx *ctx)
/*
* No free buffers and no completion entries either. Allocate a new
- * page worth of buffer entries and add those to our freelist.
+ * batch of buffer entries and add those to our freelist.
*/
- page = alloc_page(GFP_KERNEL_ACCOUNT);
- if (!page)
- return -ENOMEM;
-
- list_add(&page->lru, &ctx->io_buffers_pages);
- buf = page_address(page);
- bufs_in_page = PAGE_SIZE / sizeof(*buf);
- while (bufs_in_page) {
- list_add_tail(&buf->list, &ctx->io_buffers_cache);
- buf++;
- bufs_in_page--;
+ allocated = kmem_cache_alloc_bulk(io_buf_cachep, GFP_KERNEL_ACCOUNT,
+ ARRAY_SIZE(bufs), (void **) bufs);
+ if (unlikely(!allocated)) {
+ /*
+ * Bulk alloc is all-or-nothing. If we fail to get a batch,
+ * retry single alloc to be on the safe side.
+ */
+ bufs[0] = kmem_cache_alloc(io_buf_cachep, GFP_KERNEL);
+ if (!bufs[0])
+ return -ENOMEM;
+ allocated = 1;
}
+ while (allocated)
+ list_add_tail(&bufs[--allocated]->list, &ctx->io_buffers_cache);
+
return 0;
}
diff --git a/io_uring/opdef.c b/io_uring/opdef.c
index 3b9c6489b8b6..25a3515a177c 100644
--- a/io_uring/opdef.c
+++ b/io_uring/opdef.c
@@ -33,6 +33,8 @@
#include "poll.h"
#include "cancel.h"
#include "rw.h"
+#include "waitid.h"
+#include "futex.h"
static int io_no_issue(struct io_kiocb *req, unsigned int issue_flags)
{
@@ -63,6 +65,7 @@ const struct io_issue_def io_issue_defs[] = {
.ioprio = 1,
.iopoll = 1,
.iopoll_queue = 1,
+ .vectored = 1,
.prep = io_prep_rw,
.issue = io_read,
},
@@ -76,6 +79,7 @@ const struct io_issue_def io_issue_defs[] = {
.ioprio = 1,
.iopoll = 1,
.iopoll_queue = 1,
+ .vectored = 1,
.prep = io_prep_rw,
.issue = io_write,
},
@@ -428,9 +432,45 @@ const struct io_issue_def io_issue_defs[] = {
.prep = io_eopnotsupp_prep,
#endif
},
+ [IORING_OP_READ_MULTISHOT] = {
+ .needs_file = 1,
+ .unbound_nonreg_file = 1,
+ .pollin = 1,
+ .buffer_select = 1,
+ .audit_skip = 1,
+ .prep = io_read_mshot_prep,
+ .issue = io_read_mshot,
+ },
+ [IORING_OP_WAITID] = {
+ .prep = io_waitid_prep,
+ .issue = io_waitid,
+ },
+ [IORING_OP_FUTEX_WAIT] = {
+#if defined(CONFIG_FUTEX)
+ .prep = io_futex_prep,
+ .issue = io_futex_wait,
+#else
+ .prep = io_eopnotsupp_prep,
+#endif
+ },
+ [IORING_OP_FUTEX_WAKE] = {
+#if defined(CONFIG_FUTEX)
+ .prep = io_futex_prep,
+ .issue = io_futex_wake,
+#else
+ .prep = io_eopnotsupp_prep,
+#endif
+ },
+ [IORING_OP_FUTEX_WAITV] = {
+#if defined(CONFIG_FUTEX)
+ .prep = io_futexv_prep,
+ .issue = io_futexv_wait,
+#else
+ .prep = io_eopnotsupp_prep,
+#endif
+ },
};
-
const struct io_cold_def io_cold_defs[] = {
[IORING_OP_NOP] = {
.name = "NOP",
@@ -648,6 +688,22 @@ const struct io_cold_def io_cold_defs[] = {
.fail = io_sendrecv_fail,
#endif
},
+ [IORING_OP_READ_MULTISHOT] = {
+ .name = "READ_MULTISHOT",
+ },
+ [IORING_OP_WAITID] = {
+ .name = "WAITID",
+ .async_size = sizeof(struct io_waitid_async),
+ },
+ [IORING_OP_FUTEX_WAIT] = {
+ .name = "FUTEX_WAIT",
+ },
+ [IORING_OP_FUTEX_WAKE] = {
+ .name = "FUTEX_WAKE",
+ },
+ [IORING_OP_FUTEX_WAITV] = {
+ .name = "FUTEX_WAITV",
+ },
};
const char *io_uring_get_opcode(u8 opcode)
diff --git a/io_uring/opdef.h b/io_uring/opdef.h
index c22c8696e749..9e5435ec27d0 100644
--- a/io_uring/opdef.h
+++ b/io_uring/opdef.h
@@ -29,6 +29,8 @@ struct io_issue_def {
unsigned iopoll_queue : 1;
/* opcode specific path will handle ->async_data allocation if needed */
unsigned manual_alloc : 1;
+ /* vectored opcode, set if 1) vectored, and 2) handler needs to know */
+ unsigned vectored : 1;
int (*issue)(struct io_kiocb *, unsigned int);
int (*prep)(struct io_kiocb *, const struct io_uring_sqe *);
diff --git a/io_uring/poll.c b/io_uring/poll.c
index 4c360ba8793a..d38d05edb4fa 100644
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -370,7 +370,7 @@ static void __io_poll_execute(struct io_kiocb *req, int mask)
req->io_task_work.func = io_poll_task_func;
trace_io_uring_task_add(req, mask);
- io_req_task_work_add(req);
+ __io_req_task_work_add(req, IOU_F_TWQ_LAZY_WAKE);
}
static inline void io_poll_execute(struct io_kiocb *req, int res)
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index d9c853d10587..7034be555334 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -1037,39 +1037,36 @@ struct page **io_pin_pages(unsigned long ubuf, unsigned long len, int *npages)
{
unsigned long start, end, nr_pages;
struct page **pages = NULL;
- int pret, ret = -ENOMEM;
+ int ret;
end = (ubuf + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
start = ubuf >> PAGE_SHIFT;
nr_pages = end - start;
+ WARN_ON(!nr_pages);
pages = kvmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);
if (!pages)
- goto done;
+ return ERR_PTR(-ENOMEM);
- ret = 0;
mmap_read_lock(current->mm);
- pret = pin_user_pages(ubuf, nr_pages, FOLL_WRITE | FOLL_LONGTERM,
- pages);
- if (pret == nr_pages)
+ ret = pin_user_pages(ubuf, nr_pages, FOLL_WRITE | FOLL_LONGTERM, pages);
+ mmap_read_unlock(current->mm);
+
+ /* success, mapped all pages */
+ if (ret == nr_pages) {
*npages = nr_pages;
- else
- ret = pret < 0 ? pret : -EFAULT;
+ return pages;
+ }
- mmap_read_unlock(current->mm);
- if (ret) {
+ /* partial map, or didn't map anything */
+ if (ret >= 0) {
/* if we did partial map, release any pages we did get */
- if (pret > 0)
- unpin_user_pages(pages, pret);
- goto done;
- }
- ret = 0;
-done:
- if (ret < 0) {
- kvfree(pages);
- pages = ERR_PTR(ret);
+ if (ret)
+ unpin_user_pages(pages, ret);
+ ret = -EFAULT;
}
- return pages;
+ kvfree(pages);
+ return ERR_PTR(ret);
}
static int io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov,
diff --git a/io_uring/rw.c b/io_uring/rw.c
index 8f68d5ad4564..3398e1d944c2 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -123,6 +123,22 @@ int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe)
return 0;
}
+/*
+ * Multishot read is prepared just like a normal read/write request, only
+ * difference is that we set the MULTISHOT flag.
+ */
+int io_read_mshot_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+{
+ int ret;
+
+ ret = io_prep_rw(req, sqe);
+ if (unlikely(ret))
+ return ret;
+
+ req->flags |= REQ_F_APOLL_MULTISHOT;
+ return 0;
+}
+
void io_readv_writev_cleanup(struct io_kiocb *req)
{
struct io_async_rw *io = req->async_data;
@@ -388,8 +404,7 @@ static struct iovec *__io_import_iovec(int ddir, struct io_kiocb *req,
buf = u64_to_user_ptr(rw->addr);
sqe_len = rw->len;
- if (opcode == IORING_OP_READ || opcode == IORING_OP_WRITE ||
- (req->flags & REQ_F_BUFFER_SELECT)) {
+ if (!io_issue_defs[opcode].vectored || req->flags & REQ_F_BUFFER_SELECT) {
if (io_do_buffer_select(req)) {
buf = io_buffer_select(req, &sqe_len, issue_flags);
if (!buf)
@@ -708,7 +723,7 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode)
return 0;
}
-int io_read(struct io_kiocb *req, unsigned int issue_flags)
+static int __io_read(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
struct io_rw_state __s, *s = &__s;
@@ -776,8 +791,11 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags)
if (ret == -EAGAIN || (req->flags & REQ_F_REISSUE)) {
req->flags &= ~REQ_F_REISSUE;
- /* if we can poll, just do that */
- if (req->opcode == IORING_OP_READ && file_can_poll(req->file))
+ /*
+ * If we can poll, just do that. For a vectored read, we'll
+ * need to copy state first.
+ */
+ if (file_can_poll(req->file) && !io_issue_defs[req->opcode].vectored)
return -EAGAIN;
/* IOPOLL retry should happen for io-wq threads */
if (!force_nonblock && !(req->ctx->flags & IORING_SETUP_IOPOLL))
@@ -853,7 +871,69 @@ done:
/* it's faster to check here then delegate to kfree */
if (iovec)
kfree(iovec);
- return kiocb_done(req, ret, issue_flags);
+ return ret;
+}
+
+int io_read(struct io_kiocb *req, unsigned int issue_flags)
+{
+ int ret;
+
+ ret = __io_read(req, issue_flags);
+ if (ret >= 0)
+ return kiocb_done(req, ret, issue_flags);
+
+ return ret;
+}
+
+int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
+{
+ unsigned int cflags = 0;
+ int ret;
+
+ /*
+ * Multishot MUST be used on a pollable file
+ */
+ if (!file_can_poll(req->file))
+ return -EBADFD;
+
+ ret = __io_read(req, issue_flags);
+
+ /*
+ * If we get -EAGAIN, recycle our buffer and just let normal poll
+ * handling arm it.
+ */
+ if (ret == -EAGAIN) {
+ io_kbuf_recycle(req, issue_flags);
+ return -EAGAIN;
+ }
+
+ /*
+ * Any successful return value will keep the multishot read armed.
+ */
+ if (ret > 0) {
+ /*
+ * Put our buffer and post a CQE. If we fail to post a CQE, then
+ * jump to the termination path. This request is then done.
+ */
+ cflags = io_put_kbuf(req, issue_flags);
+
+ if (io_fill_cqe_req_aux(req,
+ issue_flags & IO_URING_F_COMPLETE_DEFER,
+ ret, cflags | IORING_CQE_F_MORE)) {
+ if (issue_flags & IO_URING_F_MULTISHOT)
+ return IOU_ISSUE_SKIP_COMPLETE;
+ return -EAGAIN;
+ }
+ }
+
+ /*
+ * Either an error, or we've hit overflow posting the CQE. For any
+ * multishot request, hitting overflow will terminate it.
+ */
+ io_req_set_res(req, ret, cflags);
+ if (issue_flags & IO_URING_F_MULTISHOT)
+ return IOU_STOP_MULTISHOT;
+ return IOU_OK;
}
int io_write(struct io_kiocb *req, unsigned int issue_flags)
diff --git a/io_uring/rw.h b/io_uring/rw.h
index 4b89f9659366..c5aed03d42a4 100644
--- a/io_uring/rw.h
+++ b/io_uring/rw.h
@@ -23,3 +23,5 @@ int io_writev_prep_async(struct io_kiocb *req);
void io_readv_writev_cleanup(struct io_kiocb *req);
void io_rw_fail(struct io_kiocb *req);
void io_req_rw_complete(struct io_kiocb *req, struct io_tw_state *ts);
+int io_read_mshot_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags);
diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c
index 537795fddc87..acbc2924ecd2 100644
--- a/io_uring/uring_cmd.c
+++ b/io_uring/uring_cmd.c
@@ -13,6 +13,51 @@
#include "rsrc.h"
#include "uring_cmd.h"
+static void io_uring_cmd_del_cancelable(struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
+{
+ struct io_kiocb *req = cmd_to_io_kiocb(cmd);
+ struct io_ring_ctx *ctx = req->ctx;
+
+ if (!(cmd->flags & IORING_URING_CMD_CANCELABLE))
+ return;
+
+ cmd->flags &= ~IORING_URING_CMD_CANCELABLE;
+ io_ring_submit_lock(ctx, issue_flags);
+ hlist_del(&req->hash_node);
+ io_ring_submit_unlock(ctx, issue_flags);
+}
+
+/*
+ * Mark this command as concelable, then io_uring_try_cancel_uring_cmd()
+ * will try to cancel this issued command by sending ->uring_cmd() with
+ * issue_flags of IO_URING_F_CANCEL.
+ *
+ * The command is guaranteed to not be done when calling ->uring_cmd()
+ * with IO_URING_F_CANCEL, but it is driver's responsibility to deal
+ * with race between io_uring canceling and normal completion.
+ */
+void io_uring_cmd_mark_cancelable(struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
+{
+ struct io_kiocb *req = cmd_to_io_kiocb(cmd);
+ struct io_ring_ctx *ctx = req->ctx;
+
+ if (!(cmd->flags & IORING_URING_CMD_CANCELABLE)) {
+ cmd->flags |= IORING_URING_CMD_CANCELABLE;
+ io_ring_submit_lock(ctx, issue_flags);
+ hlist_add_head(&req->hash_node, &ctx->cancelable_uring_cmd);
+ io_ring_submit_unlock(ctx, issue_flags);
+ }
+}
+EXPORT_SYMBOL_GPL(io_uring_cmd_mark_cancelable);
+
+struct task_struct *io_uring_cmd_get_task(struct io_uring_cmd *cmd)
+{
+ return cmd_to_io_kiocb(cmd)->task;
+}
+EXPORT_SYMBOL_GPL(io_uring_cmd_get_task);
+
static void io_uring_cmd_work(struct io_kiocb *req, struct io_tw_state *ts)
{
struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
@@ -56,6 +101,8 @@ void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, ssize_t res2,
{
struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
+ io_uring_cmd_del_cancelable(ioucmd, issue_flags);
+
if (ret < 0)
req_set_fail(req);
@@ -91,7 +138,7 @@ int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
return -EINVAL;
ioucmd->flags = READ_ONCE(sqe->uring_cmd_flags);
- if (ioucmd->flags & ~IORING_URING_CMD_FIXED)
+ if (ioucmd->flags & ~IORING_URING_CMD_MASK)
return -EINVAL;
if (ioucmd->flags & IORING_URING_CMD_FIXED) {
@@ -128,6 +175,8 @@ int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags)
issue_flags |= IO_URING_F_SQE128;
if (ctx->flags & IORING_SETUP_CQE32)
issue_flags |= IO_URING_F_CQE32;
+ if (ctx->compat)
+ issue_flags |= IO_URING_F_COMPAT;
if (ctx->flags & IORING_SETUP_IOPOLL) {
if (!file->f_op->uring_cmd_iopoll)
return -EOPNOTSUPP;
@@ -165,6 +214,52 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
}
EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed);
+static inline int io_uring_cmd_getsockopt(struct socket *sock,
+ struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
+{
+ bool compat = !!(issue_flags & IO_URING_F_COMPAT);
+ int optlen, optname, level, err;
+ void __user *optval;
+
+ level = READ_ONCE(cmd->sqe->level);
+ if (level != SOL_SOCKET)
+ return -EOPNOTSUPP;
+
+ optval = u64_to_user_ptr(READ_ONCE(cmd->sqe->optval));
+ optname = READ_ONCE(cmd->sqe->optname);
+ optlen = READ_ONCE(cmd->sqe->optlen);
+
+ err = do_sock_getsockopt(sock, compat, level, optname,
+ USER_SOCKPTR(optval),
+ KERNEL_SOCKPTR(&optlen));
+ if (err)
+ return err;
+
+ /* On success, return optlen */
+ return optlen;
+}
+
+static inline int io_uring_cmd_setsockopt(struct socket *sock,
+ struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
+{
+ bool compat = !!(issue_flags & IO_URING_F_COMPAT);
+ int optname, optlen, level;
+ void __user *optval;
+ sockptr_t optval_s;
+
+ optval = u64_to_user_ptr(READ_ONCE(cmd->sqe->optval));
+ optname = READ_ONCE(cmd->sqe->optname);
+ optlen = READ_ONCE(cmd->sqe->optlen);
+ level = READ_ONCE(cmd->sqe->level);
+ optval_s = USER_SOCKPTR(optval);
+
+ return do_sock_setsockopt(sock, compat, level, optname, optval_s,
+ optlen);
+}
+
+#if defined(CONFIG_NET)
int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
{
struct socket *sock = cmd->file->private_data;
@@ -186,8 +281,13 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
if (ret)
return ret;
return arg;
+ case SOCKET_URING_OP_GETSOCKOPT:
+ return io_uring_cmd_getsockopt(sock, cmd, issue_flags);
+ case SOCKET_URING_OP_SETSOCKOPT:
+ return io_uring_cmd_setsockopt(sock, cmd, issue_flags);
default:
return -EOPNOTSUPP;
}
}
EXPORT_SYMBOL_GPL(io_uring_cmd_sock);
+#endif
diff --git a/io_uring/waitid.c b/io_uring/waitid.c
new file mode 100644
index 000000000000..6f851978606d
--- /dev/null
+++ b/io_uring/waitid.c
@@ -0,0 +1,372 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Support for async notification of waitid
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/compat.h>
+#include <linux/io_uring.h>
+
+#include <uapi/linux/io_uring.h>
+
+#include "io_uring.h"
+#include "cancel.h"
+#include "waitid.h"
+#include "../kernel/exit.h"
+
+static void io_waitid_cb(struct io_kiocb *req, struct io_tw_state *ts);
+
+#define IO_WAITID_CANCEL_FLAG BIT(31)
+#define IO_WAITID_REF_MASK GENMASK(30, 0)
+
+struct io_waitid {
+ struct file *file;
+ int which;
+ pid_t upid;
+ int options;
+ atomic_t refs;
+ struct wait_queue_head *head;
+ struct siginfo __user *infop;
+ struct waitid_info info;
+};
+
+static void io_waitid_free(struct io_kiocb *req)
+{
+ struct io_waitid_async *iwa = req->async_data;
+
+ put_pid(iwa->wo.wo_pid);
+ kfree(req->async_data);
+ req->async_data = NULL;
+ req->flags &= ~REQ_F_ASYNC_DATA;
+}
+
+#ifdef CONFIG_COMPAT
+static bool io_waitid_compat_copy_si(struct io_waitid *iw, int signo)
+{
+ struct compat_siginfo __user *infop;
+ bool ret;
+
+ infop = (struct compat_siginfo __user *) iw->infop;
+
+ if (!user_write_access_begin(infop, sizeof(*infop)))
+ return false;
+
+ unsafe_put_user(signo, &infop->si_signo, Efault);
+ unsafe_put_user(0, &infop->si_errno, Efault);
+ unsafe_put_user(iw->info.cause, &infop->si_code, Efault);
+ unsafe_put_user(iw->info.pid, &infop->si_pid, Efault);
+ unsafe_put_user(iw->info.uid, &infop->si_uid, Efault);
+ unsafe_put_user(iw->info.status, &infop->si_status, Efault);
+ ret = true;
+done:
+ user_write_access_end();
+ return ret;
+Efault:
+ ret = false;
+ goto done;
+}
+#endif
+
+static bool io_waitid_copy_si(struct io_kiocb *req, int signo)
+{
+ struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
+ bool ret;
+
+ if (!iw->infop)
+ return true;
+
+#ifdef CONFIG_COMPAT
+ if (req->ctx->compat)
+ return io_waitid_compat_copy_si(iw, signo);
+#endif
+
+ if (!user_write_access_begin(iw->infop, sizeof(*iw->infop)))
+ return false;
+
+ unsafe_put_user(signo, &iw->infop->si_signo, Efault);
+ unsafe_put_user(0, &iw->infop->si_errno, Efault);
+ unsafe_put_user(iw->info.cause, &iw->infop->si_code, Efault);
+ unsafe_put_user(iw->info.pid, &iw->infop->si_pid, Efault);
+ unsafe_put_user(iw->info.uid, &iw->infop->si_uid, Efault);
+ unsafe_put_user(iw->info.status, &iw->infop->si_status, Efault);
+ ret = true;
+done:
+ user_write_access_end();
+ return ret;
+Efault:
+ ret = false;
+ goto done;
+}
+
+static int io_waitid_finish(struct io_kiocb *req, int ret)
+{
+ int signo = 0;
+
+ if (ret > 0) {
+ signo = SIGCHLD;
+ ret = 0;
+ }
+
+ if (!io_waitid_copy_si(req, signo))
+ ret = -EFAULT;
+ io_waitid_free(req);
+ return ret;
+}
+
+static void io_waitid_complete(struct io_kiocb *req, int ret)
+{
+ struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
+ struct io_tw_state ts = { .locked = true };
+
+ /* anyone completing better be holding a reference */
+ WARN_ON_ONCE(!(atomic_read(&iw->refs) & IO_WAITID_REF_MASK));
+
+ lockdep_assert_held(&req->ctx->uring_lock);
+
+ /*
+ * Did cancel find it meanwhile?
+ */
+ if (hlist_unhashed(&req->hash_node))
+ return;
+
+ hlist_del_init(&req->hash_node);
+
+ ret = io_waitid_finish(req, ret);
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+ io_req_task_complete(req, &ts);
+}
+
+static bool __io_waitid_cancel(struct io_ring_ctx *ctx, struct io_kiocb *req)
+{
+ struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
+ struct io_waitid_async *iwa = req->async_data;
+
+ /*
+ * Mark us canceled regardless of ownership. This will prevent a
+ * potential retry from a spurious wakeup.
+ */
+ atomic_or(IO_WAITID_CANCEL_FLAG, &iw->refs);
+
+ /* claim ownership */
+ if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK)
+ return false;
+
+ spin_lock_irq(&iw->head->lock);
+ list_del_init(&iwa->wo.child_wait.entry);
+ spin_unlock_irq(&iw->head->lock);
+ io_waitid_complete(req, -ECANCELED);
+ return true;
+}
+
+int io_waitid_cancel(struct io_ring_ctx *ctx, struct io_cancel_data *cd,
+ unsigned int issue_flags)
+{
+ struct hlist_node *tmp;
+ struct io_kiocb *req;
+ int nr = 0;
+
+ if (cd->flags & (IORING_ASYNC_CANCEL_FD|IORING_ASYNC_CANCEL_FD_FIXED))
+ return -ENOENT;
+
+ io_ring_submit_lock(ctx, issue_flags);
+ hlist_for_each_entry_safe(req, tmp, &ctx->waitid_list, hash_node) {
+ if (req->cqe.user_data != cd->data &&
+ !(cd->flags & IORING_ASYNC_CANCEL_ANY))
+ continue;
+ if (__io_waitid_cancel(ctx, req))
+ nr++;
+ if (!(cd->flags & IORING_ASYNC_CANCEL_ALL))
+ break;
+ }
+ io_ring_submit_unlock(ctx, issue_flags);
+
+ if (nr)
+ return nr;
+
+ return -ENOENT;
+}
+
+bool io_waitid_remove_all(struct io_ring_ctx *ctx, struct task_struct *task,
+ bool cancel_all)
+{
+ struct hlist_node *tmp;
+ struct io_kiocb *req;
+ bool found = false;
+
+ lockdep_assert_held(&ctx->uring_lock);
+
+ hlist_for_each_entry_safe(req, tmp, &ctx->waitid_list, hash_node) {
+ if (!io_match_task_safe(req, task, cancel_all))
+ continue;
+ __io_waitid_cancel(ctx, req);
+ found = true;
+ }
+
+ return found;
+}
+
+static inline bool io_waitid_drop_issue_ref(struct io_kiocb *req)
+{
+ struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
+ struct io_waitid_async *iwa = req->async_data;
+
+ if (!atomic_sub_return(1, &iw->refs))
+ return false;
+
+ /*
+ * Wakeup triggered, racing with us. It was prevented from
+ * completing because of that, queue up the tw to do that.
+ */
+ req->io_task_work.func = io_waitid_cb;
+ io_req_task_work_add(req);
+ remove_wait_queue(iw->head, &iwa->wo.child_wait);
+ return true;
+}
+
+static void io_waitid_cb(struct io_kiocb *req, struct io_tw_state *ts)
+{
+ struct io_waitid_async *iwa = req->async_data;
+ struct io_ring_ctx *ctx = req->ctx;
+ int ret;
+
+ io_tw_lock(ctx, ts);
+
+ ret = __do_wait(&iwa->wo);
+
+ /*
+ * If we get -ERESTARTSYS here, we need to re-arm and check again
+ * to ensure we get another callback. If the retry works, then we can
+ * just remove ourselves from the waitqueue again and finish the
+ * request.
+ */
+ if (unlikely(ret == -ERESTARTSYS)) {
+ struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
+
+ /* Don't retry if cancel found it meanwhile */
+ ret = -ECANCELED;
+ if (!(atomic_read(&iw->refs) & IO_WAITID_CANCEL_FLAG)) {
+ iw->head = &current->signal->wait_chldexit;
+ add_wait_queue(iw->head, &iwa->wo.child_wait);
+ ret = __do_wait(&iwa->wo);
+ if (ret == -ERESTARTSYS) {
+ /* retry armed, drop our ref */
+ io_waitid_drop_issue_ref(req);
+ return;
+ }
+
+ remove_wait_queue(iw->head, &iwa->wo.child_wait);
+ }
+ }
+
+ io_waitid_complete(req, ret);
+}
+
+static int io_waitid_wait(struct wait_queue_entry *wait, unsigned mode,
+ int sync, void *key)
+{
+ struct wait_opts *wo = container_of(wait, struct wait_opts, child_wait);
+ struct io_waitid_async *iwa = container_of(wo, struct io_waitid_async, wo);
+ struct io_kiocb *req = iwa->req;
+ struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
+ struct task_struct *p = key;
+
+ if (!pid_child_should_wake(wo, p))
+ return 0;
+
+ /* cancel is in progress */
+ if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK)
+ return 1;
+
+ req->io_task_work.func = io_waitid_cb;
+ io_req_task_work_add(req);
+ list_del_init(&wait->entry);
+ return 1;
+}
+
+int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+{
+ struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
+
+ if (sqe->addr || sqe->buf_index || sqe->addr3 || sqe->waitid_flags)
+ return -EINVAL;
+
+ iw->which = READ_ONCE(sqe->len);
+ iw->upid = READ_ONCE(sqe->fd);
+ iw->options = READ_ONCE(sqe->file_index);
+ iw->infop = u64_to_user_ptr(READ_ONCE(sqe->addr2));
+ return 0;
+}
+
+int io_waitid(struct io_kiocb *req, unsigned int issue_flags)
+{
+ struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
+ struct io_ring_ctx *ctx = req->ctx;
+ struct io_waitid_async *iwa;
+ int ret;
+
+ if (io_alloc_async_data(req))
+ return -ENOMEM;
+
+ iwa = req->async_data;
+ iwa->req = req;
+
+ ret = kernel_waitid_prepare(&iwa->wo, iw->which, iw->upid, &iw->info,
+ iw->options, NULL);
+ if (ret)
+ goto done;
+
+ /*
+ * Mark the request as busy upfront, in case we're racing with the
+ * wakeup. If we are, then we'll notice when we drop this initial
+ * reference again after arming.
+ */
+ atomic_set(&iw->refs, 1);
+
+ /*
+ * Cancel must hold the ctx lock, so there's no risk of cancelation
+ * finding us until a) we remain on the list, and b) the lock is
+ * dropped. We only need to worry about racing with the wakeup
+ * callback.
+ */
+ io_ring_submit_lock(ctx, issue_flags);
+ hlist_add_head(&req->hash_node, &ctx->waitid_list);
+
+ init_waitqueue_func_entry(&iwa->wo.child_wait, io_waitid_wait);
+ iwa->wo.child_wait.private = req->task;
+ iw->head = &current->signal->wait_chldexit;
+ add_wait_queue(iw->head, &iwa->wo.child_wait);
+
+ ret = __do_wait(&iwa->wo);
+ if (ret == -ERESTARTSYS) {
+ /*
+ * Nobody else grabbed a reference, it'll complete when we get
+ * a waitqueue callback, or if someone cancels it.
+ */
+ if (!io_waitid_drop_issue_ref(req)) {
+ io_ring_submit_unlock(ctx, issue_flags);
+ return IOU_ISSUE_SKIP_COMPLETE;
+ }
+
+ /*
+ * Wakeup triggered, racing with us. It was prevented from
+ * completing because of that, queue up the tw to do that.
+ */
+ io_ring_submit_unlock(ctx, issue_flags);
+ return IOU_ISSUE_SKIP_COMPLETE;
+ }
+
+ hlist_del_init(&req->hash_node);
+ remove_wait_queue(iw->head, &iwa->wo.child_wait);
+ ret = io_waitid_finish(req, ret);
+
+ io_ring_submit_unlock(ctx, issue_flags);
+done:
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+ return IOU_OK;
+}
diff --git a/io_uring/waitid.h b/io_uring/waitid.h
new file mode 100644
index 000000000000..956a8adafe8c
--- /dev/null
+++ b/io_uring/waitid.h
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "../kernel/exit.h"
+
+struct io_waitid_async {
+ struct io_kiocb *req;
+ struct wait_opts wo;
+};
+
+int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+int io_waitid(struct io_kiocb *req, unsigned int issue_flags);
+int io_waitid_cancel(struct io_ring_ctx *ctx, struct io_cancel_data *cd,
+ unsigned int issue_flags);
+bool io_waitid_remove_all(struct io_ring_ctx *ctx, struct task_struct *task,
+ bool cancel_all);
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 74ad2215e1ba..491d20038cbe 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -1800,7 +1800,7 @@ static bool sockopt_buf_allocated(struct bpf_sockopt_kern *ctx,
}
int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
- int *optname, char __user *optval,
+ int *optname, sockptr_t optval,
int *optlen, char **kernel_optval)
{
struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
@@ -1823,7 +1823,8 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
ctx.optlen = *optlen;
- if (copy_from_user(ctx.optval, optval, min(*optlen, max_optlen)) != 0) {
+ if (copy_from_sockptr(ctx.optval, optval,
+ min(*optlen, max_optlen))) {
ret = -EFAULT;
goto out;
}
@@ -1890,8 +1891,8 @@ out:
}
int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
- int optname, char __user *optval,
- int __user *optlen, int max_optlen,
+ int optname, sockptr_t optval,
+ sockptr_t optlen, int max_optlen,
int retval)
{
struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
@@ -1918,8 +1919,8 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
* one that kernel returned as well to let
* BPF programs inspect the value.
*/
-
- if (get_user(ctx.optlen, optlen)) {
+ if (copy_from_sockptr(&ctx.optlen, optlen,
+ sizeof(ctx.optlen))) {
ret = -EFAULT;
goto out;
}
@@ -1930,8 +1931,8 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
}
orig_optlen = ctx.optlen;
- if (copy_from_user(ctx.optval, optval,
- min(ctx.optlen, max_optlen)) != 0) {
+ if (copy_from_sockptr(ctx.optval, optval,
+ min(ctx.optlen, max_optlen))) {
ret = -EFAULT;
goto out;
}
@@ -1945,7 +1946,8 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
if (ret < 0)
goto out;
- if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) {
+ if (!sockptr_is_null(optval) &&
+ (ctx.optlen > max_optlen || ctx.optlen < 0)) {
if (orig_optlen > PAGE_SIZE && ctx.optlen >= 0) {
pr_info_once("bpf getsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n",
ctx.optlen, max_optlen);
@@ -1957,11 +1959,12 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
}
if (ctx.optlen != 0) {
- if (optval && copy_to_user(optval, ctx.optval, ctx.optlen)) {
+ if (!sockptr_is_null(optval) &&
+ copy_to_sockptr(optval, ctx.optval, ctx.optlen)) {
ret = -EFAULT;
goto out;
}
- if (put_user(ctx.optlen, optlen)) {
+ if (copy_to_sockptr(optlen, &ctx.optlen, sizeof(ctx.optlen))) {
ret = -EFAULT;
goto out;
}
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 69e92ddef5dd..9e4c6780adde 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1743,9 +1743,6 @@ static int cpu_up(unsigned int cpu, enum cpuhp_state target)
if (!cpu_possible(cpu)) {
pr_err("can't online cpu %d because it is not configured as may-hotadd at boot time\n",
cpu);
-#if defined(CONFIG_IA64)
- pr_err("please check additional_cpus= boot parameter\n");
-#endif
return -EINVAL;
}
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index f488997b0717..d62f5957f36b 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -135,6 +135,8 @@ config DMA_COHERENT_POOL
config DMA_GLOBAL_POOL
select DMA_DECLARE_COHERENT
+ depends on !ARCH_HAS_DMA_SET_UNCACHED
+ depends on !DMA_DIRECT_REMAP
bool
config DMA_DIRECT_REMAP
@@ -142,6 +144,15 @@ config DMA_DIRECT_REMAP
select DMA_COHERENT_POOL
select DMA_NONCOHERENT_MMAP
+#
+# Fallback to arch code for DMA allocations. This should eventually go away.
+#
+config ARCH_HAS_DMA_ALLOC
+ depends on !ARCH_HAS_DMA_SET_UNCACHED
+ depends on !DMA_DIRECT_REMAP
+ depends on !DMA_GLOBAL_POOL
+ bool
+
config DMA_CMA
bool "DMA Contiguous Memory Allocator"
depends on HAVE_DMA_CONTIGUOUS && CMA
diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c
index 06366acd27b0..3de494375b7b 100644
--- a/kernel/dma/debug.c
+++ b/kernel/dma/debug.c
@@ -139,7 +139,7 @@ static const char *const maperr2str[] = {
static const char *type2name[] = {
[dma_debug_single] = "single",
- [dma_debug_sg] = "scather-gather",
+ [dma_debug_sg] = "scatter-gather",
[dma_debug_coherent] = "coherent",
[dma_debug_resource] = "resource",
};
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 9596ae1aa0da..ed3056eb20b8 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -220,13 +220,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
return dma_direct_alloc_no_mapping(dev, size, dma_handle, gfp);
if (!dev_is_dma_coherent(dev)) {
- /*
- * Fallback to the arch handler if it exists. This should
- * eventually go away.
- */
- if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
- !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
- !IS_ENABLED(CONFIG_DMA_GLOBAL_POOL) &&
+ if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_ALLOC) &&
!is_swiotlb_for_alloc(dev))
return arch_dma_alloc(dev, size, dma_handle, gfp,
attrs);
@@ -240,27 +234,24 @@ void *dma_direct_alloc(struct device *dev, size_t size,
dma_handle);
/*
- * Otherwise remap if the architecture is asking for it. But
- * given that remapping memory is a blocking operation we'll
- * instead have to dip into the atomic pools.
+ * Otherwise we require the architecture to either be able to
+ * mark arbitrary parts of the kernel direct mapping uncached,
+ * or remapped it uncached.
*/
+ set_uncached = IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED);
remap = IS_ENABLED(CONFIG_DMA_DIRECT_REMAP);
- if (remap) {
- if (dma_direct_use_pool(dev, gfp))
- return dma_direct_alloc_from_pool(dev, size,
- dma_handle, gfp);
- } else {
- if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED))
- return NULL;
- set_uncached = true;
+ if (!set_uncached && !remap) {
+ pr_warn_once("coherent DMA allocations not supported on this platform.\n");
+ return NULL;
}
}
/*
- * Decrypting memory may block, so allocate the memory from the atomic
- * pools if we can't block.
+ * Remapping or decrypting memory may block, allocate the memory from
+ * the atomic pools instead if we aren't allowed block.
*/
- if (force_dma_unencrypted(dev) && dma_direct_use_pool(dev, gfp))
+ if ((remap || force_dma_unencrypted(dev)) &&
+ dma_direct_use_pool(dev, gfp))
return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
/* we always manually zero the memory once we are done */
@@ -330,9 +321,7 @@ void dma_direct_free(struct device *dev, size_t size,
return;
}
- if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
- !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
- !IS_ENABLED(CONFIG_DMA_GLOBAL_POOL) &&
+ if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_ALLOC) &&
!dev_is_dma_coherent(dev) &&
!is_swiotlb_for_alloc(dev)) {
arch_dma_free(dev, size, cpu_addr, dma_addr, attrs);
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index dff067bd56b1..26202274784f 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -1301,11 +1301,13 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,
pool->slots[index + i].orig_addr = slot_addr(orig_addr, i);
tlb_addr = slot_addr(pool->start, index) + offset;
/*
- * When dir == DMA_FROM_DEVICE we could omit the copy from the orig
- * to the tlb buffer, if we knew for sure the device will
- * overwrite the entire current content. But we don't. Thus
- * unconditional bounce may prevent leaking swiotlb content (i.e.
- * kernel memory) to user-space.
+ * When the device is writing memory, i.e. dir == DMA_FROM_DEVICE, copy
+ * the original buffer to the TLB buffer before initiating DMA in order
+ * to preserve the original's data if the device does a partial write,
+ * i.e. if the device doesn't overwrite the entire buffer. Preserving
+ * the original data, even if it's garbage, is necessary to match
+ * hardware behavior. Use of swiotlb is supposed to be transparent,
+ * i.e. swiotlb must not corrupt memory by clobbering unwritten bytes.
*/
swiotlb_bounce(dev, tlb_addr, mapping_size, DMA_TO_DEVICE);
return tlb_addr;
diff --git a/kernel/exit.c b/kernel/exit.c
index edb50b4c9972..2b4a232f2f68 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -74,6 +74,8 @@
#include <asm/unistd.h>
#include <asm/mmu_context.h>
+#include "exit.h"
+
/*
* The default value should be high enough to not crash a system that randomly
* crashes its kernel from time to time, but low enough to at least not permit
@@ -1037,26 +1039,6 @@ SYSCALL_DEFINE1(exit_group, int, error_code)
return 0;
}
-struct waitid_info {
- pid_t pid;
- uid_t uid;
- int status;
- int cause;
-};
-
-struct wait_opts {
- enum pid_type wo_type;
- int wo_flags;
- struct pid *wo_pid;
-
- struct waitid_info *wo_info;
- int wo_stat;
- struct rusage *wo_rusage;
-
- wait_queue_entry_t child_wait;
- int notask_error;
-};
-
static int eligible_pid(struct wait_opts *wo, struct task_struct *p)
{
return wo->wo_type == PIDTYPE_MAX ||
@@ -1520,6 +1502,17 @@ static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk)
return 0;
}
+bool pid_child_should_wake(struct wait_opts *wo, struct task_struct *p)
+{
+ if (!eligible_pid(wo, p))
+ return false;
+
+ if ((wo->wo_flags & __WNOTHREAD) && wo->child_wait.private != p->parent)
+ return false;
+
+ return true;
+}
+
static int child_wait_callback(wait_queue_entry_t *wait, unsigned mode,
int sync, void *key)
{
@@ -1527,13 +1520,10 @@ static int child_wait_callback(wait_queue_entry_t *wait, unsigned mode,
child_wait);
struct task_struct *p = key;
- if (!eligible_pid(wo, p))
- return 0;
+ if (pid_child_should_wake(wo, p))
+ return default_wake_function(wait, mode, sync, key);
- if ((wo->wo_flags & __WNOTHREAD) && wait->private != p->parent)
- return 0;
-
- return default_wake_function(wait, mode, sync, key);
+ return 0;
}
void __wake_up_parent(struct task_struct *p, struct task_struct *parent)
@@ -1582,16 +1572,10 @@ static int do_wait_pid(struct wait_opts *wo)
return 0;
}
-static long do_wait(struct wait_opts *wo)
+long __do_wait(struct wait_opts *wo)
{
- int retval;
+ long retval;
- trace_sched_process_wait(wo->wo_pid);
-
- init_waitqueue_func_entry(&wo->child_wait, child_wait_callback);
- wo->child_wait.private = current;
- add_wait_queue(&current->signal->wait_chldexit, &wo->child_wait);
-repeat:
/*
* If there is nothing that can match our criteria, just get out.
* We will clear ->notask_error to zero if we see any child that
@@ -1603,24 +1587,23 @@ repeat:
(!wo->wo_pid || !pid_has_task(wo->wo_pid, wo->wo_type)))
goto notask;
- set_current_state(TASK_INTERRUPTIBLE);
read_lock(&tasklist_lock);
if (wo->wo_type == PIDTYPE_PID) {
retval = do_wait_pid(wo);
if (retval)
- goto end;
+ return retval;
} else {
struct task_struct *tsk = current;
do {
retval = do_wait_thread(wo, tsk);
if (retval)
- goto end;
+ return retval;
retval = ptrace_do_wait(wo, tsk);
if (retval)
- goto end;
+ return retval;
if (wo->wo_flags & __WNOTHREAD)
break;
@@ -1630,27 +1613,44 @@ repeat:
notask:
retval = wo->notask_error;
- if (!retval && !(wo->wo_flags & WNOHANG)) {
- retval = -ERESTARTSYS;
- if (!signal_pending(current)) {
- schedule();
- goto repeat;
- }
- }
-end:
+ if (!retval && !(wo->wo_flags & WNOHANG))
+ return -ERESTARTSYS;
+
+ return retval;
+}
+
+static long do_wait(struct wait_opts *wo)
+{
+ int retval;
+
+ trace_sched_process_wait(wo->wo_pid);
+
+ init_waitqueue_func_entry(&wo->child_wait, child_wait_callback);
+ wo->child_wait.private = current;
+ add_wait_queue(&current->signal->wait_chldexit, &wo->child_wait);
+
+ do {
+ set_current_state(TASK_INTERRUPTIBLE);
+ retval = __do_wait(wo);
+ if (retval != -ERESTARTSYS)
+ break;
+ if (signal_pending(current))
+ break;
+ schedule();
+ } while (1);
+
__set_current_state(TASK_RUNNING);
remove_wait_queue(&current->signal->wait_chldexit, &wo->child_wait);
return retval;
}
-static long kernel_waitid(int which, pid_t upid, struct waitid_info *infop,
- int options, struct rusage *ru)
+int kernel_waitid_prepare(struct wait_opts *wo, int which, pid_t upid,
+ struct waitid_info *infop, int options,
+ struct rusage *ru)
{
- struct wait_opts wo;
+ unsigned int f_flags = 0;
struct pid *pid = NULL;
enum pid_type type;
- long ret;
- unsigned int f_flags = 0;
if (options & ~(WNOHANG|WNOWAIT|WEXITED|WSTOPPED|WCONTINUED|
__WNOTHREAD|__WCLONE|__WALL))
@@ -1693,19 +1693,32 @@ static long kernel_waitid(int which, pid_t upid, struct waitid_info *infop,
return -EINVAL;
}
- wo.wo_type = type;
- wo.wo_pid = pid;
- wo.wo_flags = options;
- wo.wo_info = infop;
- wo.wo_rusage = ru;
+ wo->wo_type = type;
+ wo->wo_pid = pid;
+ wo->wo_flags = options;
+ wo->wo_info = infop;
+ wo->wo_rusage = ru;
if (f_flags & O_NONBLOCK)
- wo.wo_flags |= WNOHANG;
+ wo->wo_flags |= WNOHANG;
+
+ return 0;
+}
+
+static long kernel_waitid(int which, pid_t upid, struct waitid_info *infop,
+ int options, struct rusage *ru)
+{
+ struct wait_opts wo;
+ long ret;
+
+ ret = kernel_waitid_prepare(&wo, which, upid, infop, options, ru);
+ if (ret)
+ return ret;
ret = do_wait(&wo);
- if (!ret && !(options & WNOHANG) && (f_flags & O_NONBLOCK))
+ if (!ret && !(options & WNOHANG) && (wo.wo_flags & WNOHANG))
ret = -EAGAIN;
- put_pid(pid);
+ put_pid(wo.wo_pid);
return ret;
}
diff --git a/kernel/exit.h b/kernel/exit.h
new file mode 100644
index 000000000000..278faa26a653
--- /dev/null
+++ b/kernel/exit.h
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#ifndef LINUX_WAITID_H
+#define LINUX_WAITID_H
+
+struct waitid_info {
+ pid_t pid;
+ uid_t uid;
+ int status;
+ int cause;
+};
+
+struct wait_opts {
+ enum pid_type wo_type;
+ int wo_flags;
+ struct pid *wo_pid;
+
+ struct waitid_info *wo_info;
+ int wo_stat;
+ struct rusage *wo_rusage;
+
+ wait_queue_entry_t child_wait;
+ int notask_error;
+};
+
+bool pid_child_should_wake(struct wait_opts *wo, struct task_struct *p);
+long __do_wait(struct wait_opts *wo);
+int kernel_waitid_prepare(struct wait_opts *wo, int which, pid_t upid,
+ struct waitid_info *infop, int options,
+ struct rusage *ru);
+#endif
diff --git a/kernel/fork.c b/kernel/fork.c
index 640123767726..70e301b63a7b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1393,6 +1393,8 @@ EXPORT_SYMBOL_GPL(mmput_async);
/**
* set_mm_exe_file - change a reference to the mm's executable file
+ * @mm: The mm to change.
+ * @new_exe_file: The new file to use.
*
* This changes mm's executable file (shown as symlink /proc/[pid]/exe).
*
@@ -1432,6 +1434,8 @@ int set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
/**
* replace_mm_exe_file - replace a reference to the mm's executable file
+ * @mm: The mm to change.
+ * @new_exe_file: The new file to use.
*
* This changes mm's executable file (shown as symlink /proc/[pid]/exe).
*
@@ -1483,6 +1487,7 @@ int replace_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
/**
* get_mm_exe_file - acquire a reference to the mm's executable file
+ * @mm: The mm of interest.
*
* Returns %NULL if mm has no associated executable file.
* User must release file via fput().
@@ -1499,6 +1504,7 @@ struct file *get_mm_exe_file(struct mm_struct *mm)
/**
* get_task_exe_file - acquire a reference to the task's executable file
+ * @task: The task.
*
* Returns %NULL if task's mm (if any) has no associated executable file or
* this is a kernel thread with borrowed mm (see the comment above get_task_mm).
@@ -1521,6 +1527,7 @@ struct file *get_task_exe_file(struct task_struct *task)
/**
* get_task_mm - acquire a reference to the task's mm
+ * @task: The task.
*
* Returns %NULL if the task has no mm. Checks PF_KTHREAD (meaning
* this kernel workthread has transiently adopted a user mm with use_mm,
@@ -2100,11 +2107,11 @@ const struct file_operations pidfd_fops = {
* __pidfd_prepare - allocate a new pidfd_file and reserve a pidfd
* @pid: the struct pid for which to create a pidfd
* @flags: flags of the new @pidfd
- * @pidfd: the pidfd to return
+ * @ret: Where to return the file for the pidfd.
*
* Allocate a new file that stashes @pid and reserve a new pidfd number in the
* caller's file descriptor table. The pidfd is reserved but not installed yet.
-
+ *
* The helper doesn't perform checks on @pid which makes it useful for pidfds
* created via CLONE_PIDFD where @pid has no task attached when the pidfd and
* pidfd file are prepared.
@@ -2151,7 +2158,7 @@ static int __pidfd_prepare(struct pid *pid, unsigned int flags, struct file **re
* pidfd_prepare - allocate a new pidfd_file and reserve a pidfd
* @pid: the struct pid for which to create a pidfd
* @flags: flags of the new @pidfd
- * @pidfd: the pidfd to return
+ * @ret: Where to return the pidfd.
*
* Allocate a new file that stashes @pid and reserve a new pidfd number in the
* caller's file descriptor table. The pidfd is reserved but not installed yet.
@@ -3142,7 +3149,7 @@ static inline bool clone3_stack_valid(struct kernel_clone_args *kargs)
if (!access_ok((void __user *)kargs->stack, kargs->stack_size))
return false;
-#if !defined(CONFIG_STACK_GROWSUP) && !defined(CONFIG_IA64)
+#if !defined(CONFIG_STACK_GROWSUP)
kargs->stack += kargs->stack_size;
#endif
}
@@ -3179,7 +3186,7 @@ static bool clone3_args_valid(struct kernel_clone_args *kargs)
}
/**
- * clone3 - create a new process with specific properties
+ * sys_clone3 - create a new process with specific properties
* @uargs: argument structure
* @size: size of @uargs
*
diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h
index a06030a1a27b..8b195d06f4e8 100644
--- a/kernel/futex/futex.h
+++ b/kernel/futex/futex.h
@@ -52,6 +52,8 @@ static inline unsigned int futex_to_flags(unsigned int op)
return flags;
}
+#define FUTEX2_VALID_MASK (FUTEX2_SIZE_MASK | FUTEX2_PRIVATE)
+
/* FUTEX2_ to FLAGS_ */
static inline unsigned int futex2_to_flags(unsigned int flags2)
{
@@ -137,11 +139,16 @@ struct futex_pi_state {
union futex_key key;
} __randomize_layout;
+struct futex_q;
+typedef void (futex_wake_fn)(struct wake_q_head *wake_q, struct futex_q *q);
+
/**
* struct futex_q - The hashed futex queue entry, one per waiting task
* @list: priority-sorted list of tasks waiting on this futex
* @task: the task waiting on the futex
* @lock_ptr: the hash bucket lock
+ * @wake: the wake handler for this queue
+ * @wake_data: data associated with the wake handler
* @key: the key the futex is hashed on
* @pi_state: optional priority inheritance state
* @rt_waiter: rt_waiter storage for use with requeue_pi
@@ -166,6 +173,8 @@ struct futex_q {
struct task_struct *task;
spinlock_t *lock_ptr;
+ futex_wake_fn *wake;
+ void *wake_data;
union futex_key key;
struct futex_pi_state *pi_state;
struct rt_mutex_waiter *rt_waiter;
@@ -212,6 +221,7 @@ extern int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags,
struct futex_q *q, struct futex_hash_bucket **hb);
extern void futex_wait_queue(struct futex_hash_bucket *hb, struct futex_q *q,
struct hrtimer_sleeper *timeout);
+extern bool __futex_wake_mark(struct futex_q *q);
extern void futex_wake_mark(struct wake_q_head *wake_q, struct futex_q *q);
extern int fault_in_user_writeable(u32 __user *uaddr);
@@ -351,6 +361,16 @@ struct futex_vector {
struct futex_q q;
};
+extern int futex_parse_waitv(struct futex_vector *futexv,
+ struct futex_waitv __user *uwaitv,
+ unsigned int nr_futexes, futex_wake_fn *wake,
+ void *wake_data);
+
+extern int futex_wait_multiple_setup(struct futex_vector *vs, int count,
+ int *woken);
+
+extern int futex_unqueue_multiple(struct futex_vector *v, int count);
+
extern int futex_wait_multiple(struct futex_vector *vs, unsigned int count,
struct hrtimer_sleeper *to);
diff --git a/kernel/futex/requeue.c b/kernel/futex/requeue.c
index 16a3645bd786..eb21f065816b 100644
--- a/kernel/futex/requeue.c
+++ b/kernel/futex/requeue.c
@@ -58,6 +58,7 @@ enum {
const struct futex_q futex_q_init = {
/* list gets initialized in futex_queue()*/
+ .wake = futex_wake_mark,
.key = FUTEX_KEY_INIT,
.bitset = FUTEX_BITSET_MATCH_ANY,
.requeue_state = ATOMIC_INIT(Q_REQUEUE_PI_NONE),
@@ -593,7 +594,7 @@ retry_private:
/* Plain futexes just wake or requeue and are done */
if (!requeue_pi) {
if (++task_count <= nr_wake)
- futex_wake_mark(&wake_q, this);
+ this->wake(&wake_q, this);
else
requeue_futex(this, hb1, hb2, &key2);
continue;
diff --git a/kernel/futex/syscalls.c b/kernel/futex/syscalls.c
index 8200d86d30e1..4b6da9116aa6 100644
--- a/kernel/futex/syscalls.c
+++ b/kernel/futex/syscalls.c
@@ -179,19 +179,20 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
return do_futex(uaddr, op, val, tp, uaddr2, (unsigned long)utime, val3);
}
-#define FUTEX2_VALID_MASK (FUTEX2_SIZE_MASK | FUTEX2_PRIVATE)
-
/**
* futex_parse_waitv - Parse a waitv array from userspace
* @futexv: Kernel side list of waiters to be filled
* @uwaitv: Userspace list to be parsed
* @nr_futexes: Length of futexv
+ * @wake: Wake to call when futex is woken
+ * @wake_data: Data for the wake handler
*
* Return: Error code on failure, 0 on success
*/
-static int futex_parse_waitv(struct futex_vector *futexv,
- struct futex_waitv __user *uwaitv,
- unsigned int nr_futexes)
+int futex_parse_waitv(struct futex_vector *futexv,
+ struct futex_waitv __user *uwaitv,
+ unsigned int nr_futexes, futex_wake_fn *wake,
+ void *wake_data)
{
struct futex_waitv aux;
unsigned int i;
@@ -216,6 +217,8 @@ static int futex_parse_waitv(struct futex_vector *futexv,
futexv[i].w.val = aux.val;
futexv[i].w.uaddr = aux.uaddr;
futexv[i].q = futex_q_init;
+ futexv[i].q.wake = wake;
+ futexv[i].q.wake_data = wake_data;
}
return 0;
@@ -308,7 +311,8 @@ SYSCALL_DEFINE5(futex_waitv, struct futex_waitv __user *, waiters,
goto destroy_timer;
}
- ret = futex_parse_waitv(futexv, waiters, nr_futexes);
+ ret = futex_parse_waitv(futexv, waiters, nr_futexes, futex_wake_mark,
+ NULL);
if (!ret)
ret = futex_wait_multiple(futexv, nr_futexes, timeout ? &to : NULL);
@@ -423,7 +427,7 @@ SYSCALL_DEFINE4(futex_requeue,
if (!waiters)
return -EINVAL;
- ret = futex_parse_waitv(futexes, waiters, 2);
+ ret = futex_parse_waitv(futexes, waiters, 2, futex_wake_mark, NULL);
if (ret)
return ret;
diff --git a/kernel/futex/waitwake.c b/kernel/futex/waitwake.c
index 37860f794bf7..61b112897a84 100644
--- a/kernel/futex/waitwake.c
+++ b/kernel/futex/waitwake.c
@@ -106,20 +106,11 @@
* double_lock_hb() and double_unlock_hb(), respectively.
*/
-/*
- * The hash bucket lock must be held when this is called.
- * Afterwards, the futex_q must not be accessed. Callers
- * must ensure to later call wake_up_q() for the actual
- * wakeups to occur.
- */
-void futex_wake_mark(struct wake_q_head *wake_q, struct futex_q *q)
+bool __futex_wake_mark(struct futex_q *q)
{
- struct task_struct *p = q->task;
-
if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n"))
- return;
+ return false;
- get_task_struct(p);
__futex_unqueue(q);
/*
* The waiting task can free the futex_q as soon as q->lock_ptr = NULL
@@ -130,6 +121,26 @@ void futex_wake_mark(struct wake_q_head *wake_q, struct futex_q *q)
*/
smp_store_release(&q->lock_ptr, NULL);
+ return true;
+}
+
+/*
+ * The hash bucket lock must be held when this is called.
+ * Afterwards, the futex_q must not be accessed. Callers
+ * must ensure to later call wake_up_q() for the actual
+ * wakeups to occur.
+ */
+void futex_wake_mark(struct wake_q_head *wake_q, struct futex_q *q)
+{
+ struct task_struct *p = q->task;
+
+ get_task_struct(p);
+
+ if (!__futex_wake_mark(q)) {
+ put_task_struct(p);
+ return;
+ }
+
/*
* Queue the task for later wakeup for after we've released
* the hb->lock.
@@ -177,7 +188,7 @@ int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset)
if (!(this->bitset & bitset))
continue;
- futex_wake_mark(&wake_q, this);
+ this->wake(&wake_q, this);
if (++ret >= nr_wake)
break;
}
@@ -292,7 +303,7 @@ retry_private:
ret = -EINVAL;
goto out_unlock;
}
- futex_wake_mark(&wake_q, this);
+ this->wake(&wake_q, this);
if (++ret >= nr_wake)
break;
}
@@ -306,7 +317,7 @@ retry_private:
ret = -EINVAL;
goto out_unlock;
}
- futex_wake_mark(&wake_q, this);
+ this->wake(&wake_q, this);
if (++op_ret >= nr_wake2)
break;
}
@@ -361,7 +372,7 @@ void futex_wait_queue(struct futex_hash_bucket *hb, struct futex_q *q,
}
/**
- * unqueue_multiple - Remove various futexes from their hash bucket
+ * futex_unqueue_multiple - Remove various futexes from their hash bucket
* @v: The list of futexes to unqueue
* @count: Number of futexes in the list
*
@@ -371,7 +382,7 @@ void futex_wait_queue(struct futex_hash_bucket *hb, struct futex_q *q,
* - >=0 - Index of the last futex that was awoken;
* - -1 - No futex was awoken
*/
-static int unqueue_multiple(struct futex_vector *v, int count)
+int futex_unqueue_multiple(struct futex_vector *v, int count)
{
int ret = -1, i;
@@ -399,7 +410,7 @@ static int unqueue_multiple(struct futex_vector *v, int count)
* - 0 - Success
* - <0 - -EFAULT, -EWOULDBLOCK or -EINVAL
*/
-static int futex_wait_multiple_setup(struct futex_vector *vs, int count, int *woken)
+int futex_wait_multiple_setup(struct futex_vector *vs, int count, int *woken)
{
struct futex_hash_bucket *hb;
bool retry = false;
@@ -461,7 +472,7 @@ retry:
* was woken, we don't return error and return this index to
* userspace
*/
- *woken = unqueue_multiple(vs, i);
+ *woken = futex_unqueue_multiple(vs, i);
if (*woken >= 0)
return 1;
@@ -546,7 +557,7 @@ int futex_wait_multiple(struct futex_vector *vs, unsigned int count,
__set_current_state(TASK_RUNNING);
- ret = unqueue_multiple(vs, count);
+ ret = futex_unqueue_multiple(vs, count);
if (ret >= 0)
return ret;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 0c6185aefaef..075a632e6c7c 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1877,13 +1877,27 @@ static struct notifier_block kprobe_exceptions_nb = {
#ifdef CONFIG_KRETPROBES
#if !defined(CONFIG_KRETPROBE_ON_RETHOOK)
+
+/* callbacks for objpool of kretprobe instances */
+static int kretprobe_init_inst(void *nod, void *context)
+{
+ struct kretprobe_instance *ri = nod;
+
+ ri->rph = context;
+ return 0;
+}
+static int kretprobe_fini_pool(struct objpool_head *head, void *context)
+{
+ kfree(context);
+ return 0;
+}
+
static void free_rp_inst_rcu(struct rcu_head *head)
{
struct kretprobe_instance *ri = container_of(head, struct kretprobe_instance, rcu);
+ struct kretprobe_holder *rph = ri->rph;
- if (refcount_dec_and_test(&ri->rph->ref))
- kfree(ri->rph);
- kfree(ri);
+ objpool_drop(ri, &rph->pool);
}
NOKPROBE_SYMBOL(free_rp_inst_rcu);
@@ -1892,7 +1906,7 @@ static void recycle_rp_inst(struct kretprobe_instance *ri)
struct kretprobe *rp = get_kretprobe(ri);
if (likely(rp))
- freelist_add(&ri->freelist, &rp->freelist);
+ objpool_push(ri, &rp->rph->pool);
else
call_rcu(&ri->rcu, free_rp_inst_rcu);
}
@@ -1929,23 +1943,12 @@ NOKPROBE_SYMBOL(kprobe_flush_task);
static inline void free_rp_inst(struct kretprobe *rp)
{
- struct kretprobe_instance *ri;
- struct freelist_node *node;
- int count = 0;
-
- node = rp->freelist.head;
- while (node) {
- ri = container_of(node, struct kretprobe_instance, freelist);
- node = node->next;
-
- kfree(ri);
- count++;
- }
+ struct kretprobe_holder *rph = rp->rph;
- if (refcount_sub_and_test(count, &rp->rph->ref)) {
- kfree(rp->rph);
- rp->rph = NULL;
- }
+ if (!rph)
+ return;
+ rp->rph = NULL;
+ objpool_fini(&rph->pool);
}
/* This assumes the 'tsk' is the current task or the is not running. */
@@ -2087,19 +2090,17 @@ NOKPROBE_SYMBOL(__kretprobe_trampoline_handler)
static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
{
struct kretprobe *rp = container_of(p, struct kretprobe, kp);
+ struct kretprobe_holder *rph = rp->rph;
struct kretprobe_instance *ri;
- struct freelist_node *fn;
- fn = freelist_try_get(&rp->freelist);
- if (!fn) {
+ ri = objpool_pop(&rph->pool);
+ if (!ri) {
rp->nmissed++;
return 0;
}
- ri = container_of(fn, struct kretprobe_instance, freelist);
-
if (rp->entry_handler && rp->entry_handler(ri, regs)) {
- freelist_add(&ri->freelist, &rp->freelist);
+ objpool_push(ri, &rph->pool);
return 0;
}
@@ -2193,7 +2194,6 @@ int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long o
int register_kretprobe(struct kretprobe *rp)
{
int ret;
- struct kretprobe_instance *inst;
int i;
void *addr;
@@ -2227,19 +2227,12 @@ int register_kretprobe(struct kretprobe *rp)
rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus());
#ifdef CONFIG_KRETPROBE_ON_RETHOOK
- rp->rh = rethook_alloc((void *)rp, kretprobe_rethook_handler);
- if (!rp->rh)
- return -ENOMEM;
+ rp->rh = rethook_alloc((void *)rp, kretprobe_rethook_handler,
+ sizeof(struct kretprobe_instance) +
+ rp->data_size, rp->maxactive);
+ if (IS_ERR(rp->rh))
+ return PTR_ERR(rp->rh);
- for (i = 0; i < rp->maxactive; i++) {
- inst = kzalloc(struct_size(inst, data, rp->data_size), GFP_KERNEL);
- if (inst == NULL) {
- rethook_free(rp->rh);
- rp->rh = NULL;
- return -ENOMEM;
- }
- rethook_add_node(rp->rh, &inst->node);
- }
rp->nmissed = 0;
/* Establish function entry probe point */
ret = register_kprobe(&rp->kp);
@@ -2248,24 +2241,18 @@ int register_kretprobe(struct kretprobe *rp)
rp->rh = NULL;
}
#else /* !CONFIG_KRETPROBE_ON_RETHOOK */
- rp->freelist.head = NULL;
rp->rph = kzalloc(sizeof(struct kretprobe_holder), GFP_KERNEL);
if (!rp->rph)
return -ENOMEM;
- rp->rph->rp = rp;
- for (i = 0; i < rp->maxactive; i++) {
- inst = kzalloc(struct_size(inst, data, rp->data_size), GFP_KERNEL);
- if (inst == NULL) {
- refcount_set(&rp->rph->ref, i);
- free_rp_inst(rp);
- return -ENOMEM;
- }
- inst->rph = rp->rph;
- freelist_add(&inst->freelist, &rp->freelist);
+ if (objpool_init(&rp->rph->pool, rp->maxactive, rp->data_size +
+ sizeof(struct kretprobe_instance), GFP_KERNEL,
+ rp->rph, kretprobe_init_inst, kretprobe_fini_pool)) {
+ kfree(rp->rph);
+ rp->rph = NULL;
+ return -ENOMEM;
}
- refcount_set(&rp->rph->ref, i);
-
+ rp->rph->rp = rp;
rp->nmissed = 0;
/* Establish function entry probe point */
ret = register_kprobe(&rp->kp);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 81885748871d..3d7e2d702699 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -10253,9 +10253,9 @@ void normalize_rt_tasks(void)
#endif /* CONFIG_MAGIC_SYSRQ */
-#if defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB)
+#if defined(CONFIG_KGDB_KDB)
/*
- * These functions are only useful for the IA64 MCA handling, or kdb.
+ * These functions are only useful for kdb.
*
* They can only be called when the whole system has been
* stopped - every CPU needs to be quiescent, and no scheduling
@@ -10277,30 +10277,7 @@ struct task_struct *curr_task(int cpu)
return cpu_curr(cpu);
}
-#endif /* defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB) */
-
-#ifdef CONFIG_IA64
-/**
- * ia64_set_curr_task - set the current task for a given CPU.
- * @cpu: the processor in question.
- * @p: the task pointer to set.
- *
- * Description: This function must only be used when non-maskable interrupts
- * are serviced on a separate stack. It allows the architecture to switch the
- * notion of the current task on a CPU in a non-blocking manner. This function
- * must be called with all CPU's synchronized, and interrupts disabled, the
- * and caller must save the original value of the current task (see
- * curr_task() above) and restore that value before reenabling interrupts and
- * re-starting the system.
- *
- * ONLY VALID WHEN THE WHOLE SYSTEM IS STOPPED!
- */
-void ia64_set_curr_task(int cpu, struct task_struct *p)
-{
- cpu_curr(cpu) = p;
-}
-
-#endif
+#endif /* defined(CONFIG_KGDB_KDB) */
#ifdef CONFIG_CGROUP_SCHED
/* task_group_lock serializes the addition/removal of task groups */
diff --git a/kernel/signal.c b/kernel/signal.c
index f2a5578326ad..83fcbaf0e82d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1718,9 +1718,8 @@ void force_sigsegv(int sig)
force_sig(SIGSEGV);
}
-int force_sig_fault_to_task(int sig, int code, void __user *addr
- ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
- , struct task_struct *t)
+int force_sig_fault_to_task(int sig, int code, void __user *addr,
+ struct task_struct *t)
{
struct kernel_siginfo info;
@@ -1729,24 +1728,15 @@ int force_sig_fault_to_task(int sig, int code, void __user *addr
info.si_errno = 0;
info.si_code = code;
info.si_addr = addr;
-#ifdef __ia64__
- info.si_imm = imm;
- info.si_flags = flags;
- info.si_isr = isr;
-#endif
return force_sig_info_to_task(&info, t, HANDLER_CURRENT);
}
-int force_sig_fault(int sig, int code, void __user *addr
- ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr))
+int force_sig_fault(int sig, int code, void __user *addr)
{
- return force_sig_fault_to_task(sig, code, addr
- ___ARCH_SI_IA64(imm, flags, isr), current);
+ return force_sig_fault_to_task(sig, code, addr, current);
}
-int send_sig_fault(int sig, int code, void __user *addr
- ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
- , struct task_struct *t)
+int send_sig_fault(int sig, int code, void __user *addr, struct task_struct *t)
{
struct kernel_siginfo info;
@@ -1755,11 +1745,6 @@ int send_sig_fault(int sig, int code, void __user *addr
info.si_errno = 0;
info.si_code = code;
info.si_addr = addr;
-#ifdef __ia64__
- info.si_imm = imm;
- info.si_flags = flags;
- info.si_isr = isr;
-#endif
return send_sig_info(info.si_signo, &info, t);
}
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 9db51ea373b0..e1a6e3c675c0 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -51,8 +51,6 @@ COND_SYSCALL_COMPAT(io_pgetevents);
COND_SYSCALL(io_uring_setup);
COND_SYSCALL(io_uring_enter);
COND_SYSCALL(io_uring_register);
-COND_SYSCALL(lookup_dcookie);
-COND_SYSCALL_COMPAT(lookup_dcookie);
COND_SYSCALL(eventfd2);
COND_SYSCALL(epoll_create1);
COND_SYSCALL(epoll_ctl);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 2b6585751891..157f7ce2942d 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1939,15 +1939,6 @@ static struct ctl_table kern_table[] = {
.proc_handler = proc_dointvec,
},
#endif
-#ifdef CONFIG_IA64
- {
- .procname = "unaligned-dump-stack",
- .data = &unaligned_dump_stack,
- .maxlen = sizeof (int),
- .mode = 0644,
- .proc_handler = proc_dointvec,
- },
-#endif
#ifdef CONFIG_RT_MUTEXES
{
.procname = "max_lock_depth",
diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
index 881f90f0cbcf..6cd2a4e3afb8 100644
--- a/kernel/trace/fprobe.c
+++ b/kernel/trace/fprobe.c
@@ -187,7 +187,7 @@ static void fprobe_init(struct fprobe *fp)
static int fprobe_init_rethook(struct fprobe *fp, int num)
{
- int i, size;
+ int size;
if (num <= 0)
return -EINVAL;
@@ -205,26 +205,18 @@ static int fprobe_init_rethook(struct fprobe *fp, int num)
if (size <= 0)
return -EINVAL;
- fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler);
- if (!fp->rethook)
- return -ENOMEM;
- for (i = 0; i < size; i++) {
- struct fprobe_rethook_node *node;
-
- node = kzalloc(sizeof(*node) + fp->entry_data_size, GFP_KERNEL);
- if (!node) {
- rethook_free(fp->rethook);
- fp->rethook = NULL;
- return -ENOMEM;
- }
- rethook_add_node(fp->rethook, &node->node);
- }
+ /* Initialize rethook */
+ fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler,
+ sizeof(struct fprobe_rethook_node), size);
+ if (IS_ERR(fp->rethook))
+ return PTR_ERR(fp->rethook);
+
return 0;
}
static void fprobe_fail_cleanup(struct fprobe *fp)
{
- if (fp->rethook) {
+ if (!IS_ERR_OR_NULL(fp->rethook)) {
/* Don't need to cleanup rethook->handler because this is not used. */
rethook_free(fp->rethook);
fp->rethook = NULL;
@@ -379,14 +371,14 @@ int unregister_fprobe(struct fprobe *fp)
if (!fprobe_is_registered(fp))
return -EINVAL;
- if (fp->rethook)
+ if (!IS_ERR_OR_NULL(fp->rethook))
rethook_stop(fp->rethook);
ret = unregister_ftrace_function(&fp->ops);
if (ret < 0)
return ret;
- if (fp->rethook)
+ if (!IS_ERR_OR_NULL(fp->rethook))
rethook_free(fp->rethook);
ftrace_free_filter(&fp->ops);
diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c
index 5eb9b598f4e9..6fd7d4ecbbc6 100644
--- a/kernel/trace/rethook.c
+++ b/kernel/trace/rethook.c
@@ -8,7 +8,6 @@
#include <linux/preempt.h>
#include <linux/rethook.h>
#include <linux/slab.h>
-#include <linux/sort.h>
/* Return hook list (shadow stack by list) */
@@ -36,21 +35,7 @@ void rethook_flush_task(struct task_struct *tk)
static void rethook_free_rcu(struct rcu_head *head)
{
struct rethook *rh = container_of(head, struct rethook, rcu);
- struct rethook_node *rhn;
- struct freelist_node *node;
- int count = 1;
-
- node = rh->pool.head;
- while (node) {
- rhn = container_of(node, struct rethook_node, freelist);
- node = node->next;
- kfree(rhn);
- count++;
- }
-
- /* The rh->ref is the number of pooled node + 1 */
- if (refcount_sub_and_test(count, &rh->ref))
- kfree(rh);
+ objpool_fini(&rh->pool);
}
/**
@@ -83,54 +68,62 @@ void rethook_free(struct rethook *rh)
call_rcu(&rh->rcu, rethook_free_rcu);
}
+static int rethook_init_node(void *nod, void *context)
+{
+ struct rethook_node *node = nod;
+
+ node->rethook = context;
+ return 0;
+}
+
+static int rethook_fini_pool(struct objpool_head *head, void *context)
+{
+ kfree(context);
+ return 0;
+}
+
/**
* rethook_alloc() - Allocate struct rethook.
* @data: a data to pass the @handler when hooking the return.
- * @handler: the return hook callback function.
+ * @handler: the return hook callback function, must NOT be NULL
+ * @size: node size: rethook node and additional data
+ * @num: number of rethook nodes to be preallocated
*
* Allocate and initialize a new rethook with @data and @handler.
- * Return NULL if memory allocation fails or @handler is NULL.
+ * Return pointer of new rethook, or error codes for failures.
+ *
* Note that @handler == NULL means this rethook is going to be freed.
*/
-struct rethook *rethook_alloc(void *data, rethook_handler_t handler)
+struct rethook *rethook_alloc(void *data, rethook_handler_t handler,
+ int size, int num)
{
- struct rethook *rh = kzalloc(sizeof(struct rethook), GFP_KERNEL);
+ struct rethook *rh;
- if (!rh || !handler) {
- kfree(rh);
- return NULL;
- }
+ if (!handler || num <= 0 || size < sizeof(struct rethook_node))
+ return ERR_PTR(-EINVAL);
+
+ rh = kzalloc(sizeof(struct rethook), GFP_KERNEL);
+ if (!rh)
+ return ERR_PTR(-ENOMEM);
rh->data = data;
rh->handler = handler;
- rh->pool.head = NULL;
- refcount_set(&rh->ref, 1);
+ /* initialize the objpool for rethook nodes */
+ if (objpool_init(&rh->pool, num, size, GFP_KERNEL, rh,
+ rethook_init_node, rethook_fini_pool)) {
+ kfree(rh);
+ return ERR_PTR(-ENOMEM);
+ }
return rh;
}
-/**
- * rethook_add_node() - Add a new node to the rethook.
- * @rh: the struct rethook.
- * @node: the struct rethook_node to be added.
- *
- * Add @node to @rh. User must allocate @node (as a part of user's
- * data structure.) The @node fields are initialized in this function.
- */
-void rethook_add_node(struct rethook *rh, struct rethook_node *node)
-{
- node->rethook = rh;
- freelist_add(&node->freelist, &rh->pool);
- refcount_inc(&rh->ref);
-}
-
static void free_rethook_node_rcu(struct rcu_head *head)
{
struct rethook_node *node = container_of(head, struct rethook_node, rcu);
+ struct rethook *rh = node->rethook;
- if (refcount_dec_and_test(&node->rethook->ref))
- kfree(node->rethook);
- kfree(node);
+ objpool_drop(node, &rh->pool);
}
/**
@@ -145,7 +138,7 @@ void rethook_recycle(struct rethook_node *node)
lockdep_assert_preemption_disabled();
if (likely(READ_ONCE(node->rethook->handler)))
- freelist_add(&node->freelist, &node->rethook->pool);
+ objpool_push(node, &node->rethook->pool);
else
call_rcu(&node->rcu, free_rethook_node_rcu);
}
@@ -161,7 +154,6 @@ NOKPROBE_SYMBOL(rethook_recycle);
struct rethook_node *rethook_try_get(struct rethook *rh)
{
rethook_handler_t handler = READ_ONCE(rh->handler);
- struct freelist_node *fn;
lockdep_assert_preemption_disabled();
@@ -178,11 +170,7 @@ struct rethook_node *rethook_try_get(struct rethook *rh)
if (unlikely(!rcu_is_watching()))
return NULL;
- fn = freelist_try_get(&rh->pool);
- if (!fn)
- return NULL;
-
- return container_of(fn, struct rethook_node, freelist);
+ return (struct rethook_node *)objpool_pop(&rh->pool);
}
NOKPROBE_SYMBOL(rethook_try_get);
diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
index 72714cbf475c..03c851f57969 100644
--- a/kernel/trace/trace_eprobe.c
+++ b/kernel/trace/trace_eprobe.c
@@ -788,12 +788,9 @@ find_and_get_event(const char *system, const char *event_name)
name = trace_event_name(tp_event);
if (!name || strcmp(event_name, name))
continue;
- if (!trace_event_try_get_ref(tp_event)) {
+ if (!trace_event_try_get_ref(tp_event))
return NULL;
- break;
- }
return tp_event;
- break;
}
return NULL;
}
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index d145305d95fe..5cd6d4e26915 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -283,6 +283,13 @@ static DEFINE_PER_CPU(struct hrtimer, watchdog_hrtimer);
static DEFINE_PER_CPU(bool, softlockup_touch_sync);
static unsigned long soft_lockup_nmi_warn;
+static int __init softlockup_panic_setup(char *str)
+{
+ softlockup_panic = simple_strtoul(str, NULL, 0);
+ return 1;
+}
+__setup("softlockup_panic=", softlockup_panic_setup);
+
static int __init nowatchdog_setup(char *str)
{
watchdog_user_enabled = 0;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ce3a4abf40f8..cc7d53d9dc01 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -759,7 +759,7 @@ config SHRINKER_DEBUG
config DEBUG_STACK_USAGE
bool "Stack utilization instrumentation"
- depends on DEBUG_KERNEL && !IA64
+ depends on DEBUG_KERNEL
help
Enables the display of the minimum amount of free stack which each
task has ever had available in the sysrq-T and sysrq-P debug output.
@@ -2954,6 +2954,17 @@ config TEST_CLOCKSOURCE_WATCHDOG
If unsure, say N.
+config TEST_OBJPOOL
+ tristate "Test module for correctness and stress of objpool"
+ default n
+ depends on m && DEBUG_KERNEL
+ help
+ This builds the "test_objpool" module that should be used for
+ correctness verification and concurrent testings of objects
+ allocation and reclamation.
+
+ If unsure, say N.
+
endif # RUNTIME_TESTING_MENU
config ARCH_USE_MEMTEST
diff --git a/lib/Makefile b/lib/Makefile
index 1b311c7fd32b..9e0972f7b764 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -34,7 +34,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
is_single_threaded.o plist.o decompress.o kobject_uevent.o \
earlycpio.o seq_buf.o siphash.o dec_and_lock.o \
nmi_backtrace.o win_minmax.o memcat_p.o \
- buildid.o
+ buildid.o objpool.o
lib-$(CONFIG_PRINTK) += dump_stack.o
lib-$(CONFIG_SMP) += cpumask.o
@@ -107,6 +107,8 @@ obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
obj-$(CONFIG_TEST_REF_TRACKER) += test_ref_tracker.o
CFLAGS_test_fprobe.o += $(CC_FLAGS_FTRACE)
obj-$(CONFIG_FPROBE_SANITY_TEST) += test_fprobe.o
+obj-$(CONFIG_TEST_OBJPOOL) += test_objpool.o
+
#
# CFLAGS for compiling floating point code inside the kernel. x86/Makefile turns
# off the generation of FPU/SSE* instructions for kernel proper but FPU_FLAGS
diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c
index 353268b9f129..842894158944 100644
--- a/lib/decompress_unxz.c
+++ b/lib/decompress_unxz.c
@@ -133,9 +133,6 @@
#ifdef CONFIG_ARM
# define XZ_DEC_ARM
#endif
-#ifdef CONFIG_IA64
-# define XZ_DEC_IA64
-#endif
#ifdef CONFIG_SPARC
# define XZ_DEC_SPARC
#endif
diff --git a/lib/kunit/assert.c b/lib/kunit/assert.c
index 05a09652f5a1..dd1d633d0fe2 100644
--- a/lib/kunit/assert.c
+++ b/lib/kunit/assert.c
@@ -89,8 +89,7 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format);
/* Checks if `text` is a literal representing `value`, e.g. "5" and 5 */
-static bool is_literal(struct kunit *test, const char *text, long long value,
- gfp_t gfp)
+static bool is_literal(const char *text, long long value)
{
char *buffer;
int len;
@@ -100,14 +99,15 @@ static bool is_literal(struct kunit *test, const char *text, long long value,
if (strlen(text) != len)
return false;
- buffer = kunit_kmalloc(test, len+1, gfp);
+ buffer = kmalloc(len+1, GFP_KERNEL);
if (!buffer)
return false;
snprintf(buffer, len+1, "%lld", value);
ret = strncmp(buffer, text, len) == 0;
- kunit_kfree(test, buffer);
+ kfree(buffer);
+
return ret;
}
@@ -125,14 +125,12 @@ void kunit_binary_assert_format(const struct kunit_assert *assert,
binary_assert->text->left_text,
binary_assert->text->operation,
binary_assert->text->right_text);
- if (!is_literal(stream->test, binary_assert->text->left_text,
- binary_assert->left_value, stream->gfp))
+ if (!is_literal(binary_assert->text->left_text, binary_assert->left_value))
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)\n",
binary_assert->text->left_text,
binary_assert->left_value,
binary_assert->left_value);
- if (!is_literal(stream->test, binary_assert->text->right_text,
- binary_assert->right_value, stream->gfp))
+ if (!is_literal(binary_assert->text->right_text, binary_assert->right_value))
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)",
binary_assert->text->right_text,
binary_assert->right_value,
diff --git a/lib/kunit/debugfs.c b/lib/kunit/debugfs.c
index 22c5c496a68f..270d185737e6 100644
--- a/lib/kunit/debugfs.c
+++ b/lib/kunit/debugfs.c
@@ -37,14 +37,21 @@ void kunit_debugfs_init(void)
debugfs_rootdir = debugfs_create_dir(KUNIT_DEBUGFS_ROOT, NULL);
}
-static void debugfs_print_result(struct seq_file *seq,
- struct kunit_suite *suite,
- struct kunit_case *test_case)
+static void debugfs_print_result(struct seq_file *seq, struct string_stream *log)
{
- if (!test_case || !test_case->log)
+ struct string_stream_fragment *frag_container;
+
+ if (!log)
return;
- seq_printf(seq, "%s", test_case->log);
+ /*
+ * Walk the fragments so we don't need to allocate a temporary
+ * buffer to hold the entire string.
+ */
+ spin_lock(&log->lock);
+ list_for_each_entry(frag_container, &log->fragments, node)
+ seq_printf(seq, "%s", frag_container->fragment);
+ spin_unlock(&log->lock);
}
/*
@@ -69,10 +76,9 @@ static int debugfs_print_results(struct seq_file *seq, void *v)
seq_printf(seq, KUNIT_SUBTEST_INDENT "1..%zd\n", kunit_suite_num_test_cases(suite));
kunit_suite_for_each_test_case(suite, test_case)
- debugfs_print_result(seq, suite, test_case);
+ debugfs_print_result(seq, test_case->log);
- if (suite->log)
- seq_printf(seq, "%s", suite->log);
+ debugfs_print_result(seq, suite->log);
seq_printf(seq, "%s %d %s\n",
kunit_status_to_ok_not_ok(success), 1, suite->name);
@@ -105,9 +111,13 @@ void kunit_debugfs_create_suite(struct kunit_suite *suite)
struct kunit_case *test_case;
/* Allocate logs before creating debugfs representation. */
- suite->log = kzalloc(KUNIT_LOG_SIZE, GFP_KERNEL);
- kunit_suite_for_each_test_case(suite, test_case)
- test_case->log = kzalloc(KUNIT_LOG_SIZE, GFP_KERNEL);
+ suite->log = alloc_string_stream(GFP_KERNEL);
+ string_stream_set_append_newlines(suite->log, true);
+
+ kunit_suite_for_each_test_case(suite, test_case) {
+ test_case->log = alloc_string_stream(GFP_KERNEL);
+ string_stream_set_append_newlines(test_case->log, true);
+ }
suite->debugfs = debugfs_create_dir(suite->name, debugfs_rootdir);
@@ -121,7 +131,7 @@ void kunit_debugfs_destroy_suite(struct kunit_suite *suite)
struct kunit_case *test_case;
debugfs_remove_recursive(suite->debugfs);
- kfree(suite->log);
+ string_stream_destroy(suite->log);
kunit_suite_for_each_test_case(suite, test_case)
- kfree(test_case->log);
+ string_stream_destroy(test_case->log);
}
diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c
index a6348489d45f..1236b3cd2fbb 100644
--- a/lib/kunit/executor.c
+++ b/lib/kunit/executor.c
@@ -137,8 +137,10 @@ void kunit_free_suite_set(struct kunit_suite_set suite_set)
{
struct kunit_suite * const *suites;
- for (suites = suite_set.start; suites < suite_set.end; suites++)
+ for (suites = suite_set.start; suites < suite_set.end; suites++) {
+ kfree((*suites)->test_cases);
kfree(*suites);
+ }
kfree(suite_set.start);
}
@@ -155,10 +157,11 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
struct kunit_suite_set filtered = {NULL, NULL};
struct kunit_glob_filter parsed_glob;
struct kunit_attr_filter *parsed_filters = NULL;
+ struct kunit_suite * const *suites;
const size_t max = suite_set->end - suite_set->start;
- copy = kmalloc_array(max, sizeof(*filtered.start), GFP_KERNEL);
+ copy = kcalloc(max, sizeof(*filtered.start), GFP_KERNEL);
if (!copy) { /* won't be able to run anything, return an empty set */
return filtered;
}
@@ -193,7 +196,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
parsed_glob.test_glob);
if (IS_ERR(filtered_suite)) {
*err = PTR_ERR(filtered_suite);
- goto free_parsed_filters;
+ goto free_filtered_suite;
}
}
if (filter_count > 0 && parsed_filters != NULL) {
@@ -210,11 +213,11 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
filtered_suite = new_filtered_suite;
if (*err)
- goto free_parsed_filters;
+ goto free_filtered_suite;
if (IS_ERR(filtered_suite)) {
*err = PTR_ERR(filtered_suite);
- goto free_parsed_filters;
+ goto free_filtered_suite;
}
if (!filtered_suite)
break;
@@ -229,6 +232,14 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
filtered.start = copy_start;
filtered.end = copy;
+free_filtered_suite:
+ if (*err) {
+ for (suites = copy_start; suites < copy; suites++) {
+ kfree((*suites)->test_cases);
+ kfree(*suites);
+ }
+ }
+
free_parsed_filters:
if (filter_count)
kfree(parsed_filters);
@@ -241,7 +252,7 @@ free_parsed_glob:
free_copy:
if (*err)
- kfree(copy);
+ kfree(copy_start);
return filtered;
}
diff --git a/lib/kunit/executor_test.c b/lib/kunit/executor_test.c
index b4f6f96b2844..22d4ee86dbed 100644
--- a/lib/kunit/executor_test.c
+++ b/lib/kunit/executor_test.c
@@ -9,7 +9,7 @@
#include <kunit/test.h>
#include <kunit/attributes.h>
-static void kfree_at_end(struct kunit *test, const void *to_free);
+static void free_suite_set_at_end(struct kunit *test, const void *to_free);
static struct kunit_suite *alloc_fake_suite(struct kunit *test,
const char *suite_name,
struct kunit_case *test_cases);
@@ -56,7 +56,7 @@ static void filter_suites_test(struct kunit *test)
got = kunit_filter_suites(&suite_set, "suite2", NULL, NULL, &err);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
KUNIT_ASSERT_EQ(test, err, 0);
- kfree_at_end(test, got.start);
+ free_suite_set_at_end(test, &got);
/* Validate we just have suite2 */
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
@@ -82,7 +82,7 @@ static void filter_suites_test_glob_test(struct kunit *test)
got = kunit_filter_suites(&suite_set, "suite2.test2", NULL, NULL, &err);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
KUNIT_ASSERT_EQ(test, err, 0);
- kfree_at_end(test, got.start);
+ free_suite_set_at_end(test, &got);
/* Validate we just have suite2 */
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
@@ -109,7 +109,7 @@ static void filter_suites_to_empty_test(struct kunit *test)
got = kunit_filter_suites(&suite_set, "not_found", NULL, NULL, &err);
KUNIT_ASSERT_EQ(test, err, 0);
- kfree_at_end(test, got.start); /* just in case */
+ free_suite_set_at_end(test, &got); /* just in case */
KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end,
"should be empty to indicate no match");
@@ -172,7 +172,7 @@ static void filter_attr_test(struct kunit *test)
got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
KUNIT_ASSERT_EQ(test, err, 0);
- kfree_at_end(test, got.start);
+ free_suite_set_at_end(test, &got);
/* Validate we just have normal_suite */
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
@@ -200,7 +200,7 @@ static void filter_attr_empty_test(struct kunit *test)
got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err);
KUNIT_ASSERT_EQ(test, err, 0);
- kfree_at_end(test, got.start); /* just in case */
+ free_suite_set_at_end(test, &got); /* just in case */
KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end,
"should be empty to indicate no match");
@@ -222,7 +222,7 @@ static void filter_attr_skip_test(struct kunit *test)
got = kunit_filter_suites(&suite_set, NULL, filter, "skip", &err);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
KUNIT_ASSERT_EQ(test, err, 0);
- kfree_at_end(test, got.start);
+ free_suite_set_at_end(test, &got);
/* Validate we have both the slow and normal test */
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases);
@@ -256,18 +256,26 @@ kunit_test_suites(&executor_test_suite);
/* Test helpers */
-/* Use the resource API to register a call to kfree(to_free).
+static void free_suite_set(void *suite_set)
+{
+ kunit_free_suite_set(*(struct kunit_suite_set *)suite_set);
+ kfree(suite_set);
+}
+
+/* Use the resource API to register a call to free_suite_set.
* Since we never actually use the resource, it's safe to use on const data.
*/
-static void kfree_at_end(struct kunit *test, const void *to_free)
+static void free_suite_set_at_end(struct kunit *test, const void *to_free)
{
- /* kfree() handles NULL already, but avoid allocating a no-op cleanup. */
- if (IS_ERR_OR_NULL(to_free))
+ struct kunit_suite_set *free;
+
+ if (!((struct kunit_suite_set *)to_free)->start)
return;
- kunit_add_action(test,
- (kunit_action_t *)kfree,
- (void *)to_free);
+ free = kzalloc(sizeof(struct kunit_suite_set), GFP_KERNEL);
+ *free = *(struct kunit_suite_set *)to_free;
+
+ kunit_add_action(test, free_suite_set, (void *)free);
}
static struct kunit_suite *alloc_fake_suite(struct kunit *test,
diff --git a/lib/kunit/kunit-example-test.c b/lib/kunit/kunit-example-test.c
index 01a769f35e1d..6bb5c2ef6696 100644
--- a/lib/kunit/kunit-example-test.c
+++ b/lib/kunit/kunit-example-test.c
@@ -190,6 +190,7 @@ static void example_static_stub_test(struct kunit *test)
static const struct example_param {
int value;
} example_params_array[] = {
+ { .value = 3, },
{ .value = 2, },
{ .value = 1, },
{ .value = 0, },
@@ -213,8 +214,8 @@ static void example_params_test(struct kunit *test)
KUNIT_ASSERT_NOT_NULL(test, param);
/* Test can be skipped on unsupported param values */
- if (!param->value)
- kunit_skip(test, "unsupported param value");
+ if (!is_power_of_2(param->value))
+ kunit_skip(test, "unsupported param value %d", param->value);
/* You can use param values for parameterized testing */
KUNIT_EXPECT_EQ(test, param->value % param->value, 0);
diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c
index 83d8e90ca7a2..99d2a3a528e1 100644
--- a/lib/kunit/kunit-test.c
+++ b/lib/kunit/kunit-test.c
@@ -8,6 +8,7 @@
#include <kunit/test.h>
#include <kunit/test-bug.h>
+#include "string-stream.h"
#include "try-catch-impl.h"
struct kunit_try_catch_test_context {
@@ -530,12 +531,27 @@ static struct kunit_suite kunit_resource_test_suite = {
.test_cases = kunit_resource_test_cases,
};
+/*
+ * Log tests call string_stream functions, which aren't exported. So only
+ * build this code if this test is built-in.
+ */
+#if IS_BUILTIN(CONFIG_KUNIT_TEST)
+
+/* This avoids a cast warning if kfree() is passed direct to kunit_add_action(). */
+static void kfree_wrapper(void *p)
+{
+ kfree(p);
+}
+
static void kunit_log_test(struct kunit *test)
{
struct kunit_suite suite;
-
- suite.log = kunit_kzalloc(test, KUNIT_LOG_SIZE, GFP_KERNEL);
+#ifdef CONFIG_KUNIT_DEBUGFS
+ char *full_log;
+#endif
+ suite.log = kunit_alloc_string_stream(test, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, suite.log);
+ string_stream_set_append_newlines(suite.log, true);
kunit_log(KERN_INFO, test, "put this in log.");
kunit_log(KERN_INFO, test, "this too.");
@@ -543,14 +559,21 @@ static void kunit_log_test(struct kunit *test)
kunit_log(KERN_INFO, &suite, "along with this.");
#ifdef CONFIG_KUNIT_DEBUGFS
+ KUNIT_EXPECT_TRUE(test, test->log->append_newlines);
+
+ full_log = string_stream_get_string(test->log);
+ kunit_add_action(test, (kunit_action_t *)kfree, full_log);
KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
- strstr(test->log, "put this in log."));
+ strstr(full_log, "put this in log."));
KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
- strstr(test->log, "this too."));
+ strstr(full_log, "this too."));
+
+ full_log = string_stream_get_string(suite.log);
+ kunit_add_action(test, kfree_wrapper, full_log);
KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
- strstr(suite.log, "add to suite log."));
+ strstr(full_log, "add to suite log."));
KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
- strstr(suite.log, "along with this."));
+ strstr(full_log, "along with this."));
#else
KUNIT_EXPECT_NULL(test, test->log);
#endif
@@ -558,15 +581,30 @@ static void kunit_log_test(struct kunit *test)
static void kunit_log_newline_test(struct kunit *test)
{
+ char *full_log;
+
kunit_info(test, "Add newline\n");
if (test->log) {
- KUNIT_ASSERT_NOT_NULL_MSG(test, strstr(test->log, "Add newline\n"),
- "Missing log line, full log:\n%s", test->log);
- KUNIT_EXPECT_NULL(test, strstr(test->log, "Add newline\n\n"));
+ full_log = string_stream_get_string(test->log);
+ kunit_add_action(test, kfree_wrapper, full_log);
+ KUNIT_ASSERT_NOT_NULL_MSG(test, strstr(full_log, "Add newline\n"),
+ "Missing log line, full log:\n%s", full_log);
+ KUNIT_EXPECT_NULL(test, strstr(full_log, "Add newline\n\n"));
} else {
kunit_skip(test, "only useful when debugfs is enabled");
}
}
+#else
+static void kunit_log_test(struct kunit *test)
+{
+ kunit_skip(test, "Log tests only run when built-in");
+}
+
+static void kunit_log_newline_test(struct kunit *test)
+{
+ kunit_skip(test, "Log tests only run when built-in");
+}
+#endif /* IS_BUILTIN(CONFIG_KUNIT_TEST) */
static struct kunit_case kunit_log_test_cases[] = {
KUNIT_CASE(kunit_log_test),
diff --git a/lib/kunit/string-stream-test.c b/lib/kunit/string-stream-test.c
index 110f3a993250..06822766f29a 100644
--- a/lib/kunit/string-stream-test.c
+++ b/lib/kunit/string-stream-test.c
@@ -6,48 +6,539 @@
* Author: Brendan Higgins <brendanhiggins@google.com>
*/
+#include <kunit/static_stub.h>
#include <kunit/test.h>
+#include <linux/ktime.h>
#include <linux/slab.h>
+#include <linux/timekeeping.h>
#include "string-stream.h"
-static void string_stream_test_empty_on_creation(struct kunit *test)
+struct string_stream_test_priv {
+ /* For testing resource-managed free. */
+ struct string_stream *expected_free_stream;
+ bool stream_was_freed;
+ bool stream_free_again;
+};
+
+/* Avoids a cast warning if kfree() is passed direct to kunit_add_action(). */
+static void kfree_wrapper(void *p)
+{
+ kfree(p);
+}
+
+/* Avoids a cast warning if string_stream_destroy() is passed direct to kunit_add_action(). */
+static void cleanup_raw_stream(void *p)
+{
+ struct string_stream *stream = p;
+
+ string_stream_destroy(stream);
+}
+
+static char *get_concatenated_string(struct kunit *test, struct string_stream *stream)
+{
+ char *str = string_stream_get_string(stream);
+
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, str);
+ kunit_add_action(test, kfree_wrapper, (void *)str);
+
+ return str;
+}
+
+/* Managed string_stream object is initialized correctly. */
+static void string_stream_managed_init_test(struct kunit *test)
+{
+ struct string_stream *stream;
+
+ /* Resource-managed initialization. */
+ stream = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
+
+ KUNIT_EXPECT_EQ(test, stream->length, 0);
+ KUNIT_EXPECT_TRUE(test, list_empty(&stream->fragments));
+ KUNIT_EXPECT_TRUE(test, (stream->gfp == GFP_KERNEL));
+ KUNIT_EXPECT_FALSE(test, stream->append_newlines);
+ KUNIT_EXPECT_TRUE(test, string_stream_is_empty(stream));
+}
+
+/* Unmanaged string_stream object is initialized correctly. */
+static void string_stream_unmanaged_init_test(struct kunit *test)
+{
+ struct string_stream *stream;
+
+ stream = alloc_string_stream(GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
+ kunit_add_action(test, cleanup_raw_stream, stream);
+
+ KUNIT_EXPECT_EQ(test, stream->length, 0);
+ KUNIT_EXPECT_TRUE(test, list_empty(&stream->fragments));
+ KUNIT_EXPECT_EQ(test, stream->gfp, GFP_KERNEL);
+ KUNIT_EXPECT_FALSE(test, stream->append_newlines);
+
+ KUNIT_EXPECT_TRUE(test, string_stream_is_empty(stream));
+}
+
+static void string_stream_destroy_stub(struct string_stream *stream)
+{
+ struct kunit *fake_test = kunit_get_current_test();
+ struct string_stream_test_priv *priv = fake_test->priv;
+
+ /* The kunit could own string_streams other than the one we are testing. */
+ if (stream == priv->expected_free_stream) {
+ if (priv->stream_was_freed)
+ priv->stream_free_again = true;
+ else
+ priv->stream_was_freed = true;
+ }
+
+ /*
+ * Calling string_stream_destroy() will only call this function again
+ * because the redirection stub is still active.
+ * Avoid calling deactivate_static_stub() or changing current->kunit_test
+ * during cleanup.
+ */
+ string_stream_clear(stream);
+ kfree(stream);
+}
+
+/* kunit_free_string_stream() calls string_stream_desrtoy() */
+static void string_stream_managed_free_test(struct kunit *test)
+{
+ struct string_stream_test_priv *priv = test->priv;
+
+ priv->expected_free_stream = NULL;
+ priv->stream_was_freed = false;
+ priv->stream_free_again = false;
+
+ kunit_activate_static_stub(test,
+ string_stream_destroy,
+ string_stream_destroy_stub);
+
+ priv->expected_free_stream = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->expected_free_stream);
+
+ /* This should call the stub function. */
+ kunit_free_string_stream(test, priv->expected_free_stream);
+
+ KUNIT_EXPECT_TRUE(test, priv->stream_was_freed);
+ KUNIT_EXPECT_FALSE(test, priv->stream_free_again);
+}
+
+/* string_stream object is freed when test is cleaned up. */
+static void string_stream_resource_free_test(struct kunit *test)
+{
+ struct string_stream_test_priv *priv = test->priv;
+ struct kunit *fake_test;
+
+ fake_test = kunit_kzalloc(test, sizeof(*fake_test), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_test);
+
+ kunit_init_test(fake_test, "string_stream_fake_test", NULL);
+ fake_test->priv = priv;
+
+ /*
+ * Activate stub before creating string_stream so the
+ * string_stream will be cleaned up first.
+ */
+ priv->expected_free_stream = NULL;
+ priv->stream_was_freed = false;
+ priv->stream_free_again = false;
+
+ kunit_activate_static_stub(fake_test,
+ string_stream_destroy,
+ string_stream_destroy_stub);
+
+ priv->expected_free_stream = kunit_alloc_string_stream(fake_test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->expected_free_stream);
+
+ /* Set current->kunit_test to fake_test so the static stub will be called. */
+ current->kunit_test = fake_test;
+
+ /* Cleanup test - the stub function should be called */
+ kunit_cleanup(fake_test);
+
+ /* Set current->kunit_test back to current test. */
+ current->kunit_test = test;
+
+ KUNIT_EXPECT_TRUE(test, priv->stream_was_freed);
+ KUNIT_EXPECT_FALSE(test, priv->stream_free_again);
+}
+
+/*
+ * Add a series of lines to a string_stream. Check that all lines
+ * appear in the correct order and no characters are dropped.
+ */
+static void string_stream_line_add_test(struct kunit *test)
+{
+ struct string_stream *stream;
+ char line[60];
+ char *concat_string, *pos, *string_end;
+ size_t len, total_len;
+ int num_lines, i;
+
+ stream = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
+
+ /* Add series of sequence numbered lines */
+ total_len = 0;
+ for (i = 0; i < 100; ++i) {
+ len = snprintf(line, sizeof(line),
+ "The quick brown fox jumps over the lazy penguin %d\n", i);
+
+ /* Sanity-check that our test string isn't truncated */
+ KUNIT_ASSERT_LT(test, len, sizeof(line));
+
+ string_stream_add(stream, line);
+ total_len += len;
+ }
+ num_lines = i;
+
+ concat_string = get_concatenated_string(test, stream);
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test, concat_string);
+ KUNIT_EXPECT_EQ(test, strlen(concat_string), total_len);
+
+ /*
+ * Split the concatenated string at the newlines and check that
+ * all the original added strings are present.
+ */
+ pos = concat_string;
+ for (i = 0; i < num_lines; ++i) {
+ string_end = strchr(pos, '\n');
+ KUNIT_EXPECT_NOT_NULL(test, string_end);
+
+ /* Convert to NULL-terminated string */
+ *string_end = '\0';
+
+ snprintf(line, sizeof(line),
+ "The quick brown fox jumps over the lazy penguin %d", i);
+ KUNIT_EXPECT_STREQ(test, pos, line);
+
+ pos = string_end + 1;
+ }
+
+ /* There shouldn't be any more data after this */
+ KUNIT_EXPECT_EQ(test, strlen(pos), 0);
+}
+
+/* Add a series of lines of variable length to a string_stream. */
+static void string_stream_variable_length_line_test(struct kunit *test)
+{
+ static const char line[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ " 0123456789!$%^&*()_-+={}[]:;@'~#<>,.?/|";
+ struct string_stream *stream;
+ struct rnd_state rnd;
+ char *concat_string, *pos, *string_end;
+ size_t offset, total_len;
+ int num_lines, i;
+
+ stream = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
+
+ /*
+ * Log many lines of varying lengths until we have created
+ * many fragments.
+ * The "randomness" must be repeatable.
+ */
+ prandom_seed_state(&rnd, 3141592653589793238ULL);
+ total_len = 0;
+ for (i = 0; i < 100; ++i) {
+ offset = prandom_u32_state(&rnd) % (sizeof(line) - 1);
+ string_stream_add(stream, "%s\n", &line[offset]);
+ total_len += sizeof(line) - offset;
+ }
+ num_lines = i;
+
+ concat_string = get_concatenated_string(test, stream);
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test, concat_string);
+ KUNIT_EXPECT_EQ(test, strlen(concat_string), total_len);
+
+ /*
+ * Split the concatenated string at the newlines and check that
+ * all the original added strings are present.
+ */
+ prandom_seed_state(&rnd, 3141592653589793238ULL);
+ pos = concat_string;
+ for (i = 0; i < num_lines; ++i) {
+ string_end = strchr(pos, '\n');
+ KUNIT_EXPECT_NOT_NULL(test, string_end);
+
+ /* Convert to NULL-terminated string */
+ *string_end = '\0';
+
+ offset = prandom_u32_state(&rnd) % (sizeof(line) - 1);
+ KUNIT_EXPECT_STREQ(test, pos, &line[offset]);
+
+ pos = string_end + 1;
+ }
+
+ /* There shouldn't be any more data after this */
+ KUNIT_EXPECT_EQ(test, strlen(pos), 0);
+}
+
+/* Appending the content of one string stream to another. */
+static void string_stream_append_test(struct kunit *test)
+{
+ static const char * const strings_1[] = {
+ "one", "two", "three", "four", "five", "six",
+ "seven", "eight", "nine", "ten",
+ };
+ static const char * const strings_2[] = {
+ "Apple", "Pear", "Orange", "Banana", "Grape", "Apricot",
+ };
+ struct string_stream *stream_1, *stream_2;
+ const char *stream1_content_before_append, *stream_2_content;
+ char *combined_content;
+ size_t combined_length;
+ int i;
+
+ stream_1 = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream_1);
+
+ stream_2 = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream_2);
+
+ /* Append content of empty stream to empty stream */
+ string_stream_append(stream_1, stream_2);
+ KUNIT_EXPECT_EQ(test, strlen(get_concatenated_string(test, stream_1)), 0);
+
+ /* Add some data to stream_1 */
+ for (i = 0; i < ARRAY_SIZE(strings_1); ++i)
+ string_stream_add(stream_1, "%s\n", strings_1[i]);
+
+ stream1_content_before_append = get_concatenated_string(test, stream_1);
+
+ /* Append content of empty stream to non-empty stream */
+ string_stream_append(stream_1, stream_2);
+ KUNIT_EXPECT_STREQ(test, get_concatenated_string(test, stream_1),
+ stream1_content_before_append);
+
+ /* Add some data to stream_2 */
+ for (i = 0; i < ARRAY_SIZE(strings_2); ++i)
+ string_stream_add(stream_2, "%s\n", strings_2[i]);
+
+ /* Append content of non-empty stream to non-empty stream */
+ string_stream_append(stream_1, stream_2);
+
+ /*
+ * End result should be the original content of stream_1 plus
+ * the content of stream_2.
+ */
+ stream_2_content = get_concatenated_string(test, stream_2);
+ combined_length = strlen(stream1_content_before_append) + strlen(stream_2_content);
+ combined_length++; /* for terminating \0 */
+ combined_content = kunit_kmalloc(test, combined_length, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, combined_content);
+ snprintf(combined_content, combined_length, "%s%s",
+ stream1_content_before_append, stream_2_content);
+
+ KUNIT_EXPECT_STREQ(test, get_concatenated_string(test, stream_1), combined_content);
+
+ /* Append content of non-empty stream to empty stream */
+ kunit_free_string_stream(test, stream_1);
+
+ stream_1 = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream_1);
+
+ string_stream_append(stream_1, stream_2);
+ KUNIT_EXPECT_STREQ(test, get_concatenated_string(test, stream_1), stream_2_content);
+}
+
+/* Appending the content of one string stream to one with auto-newlining. */
+static void string_stream_append_auto_newline_test(struct kunit *test)
+{
+ struct string_stream *stream_1, *stream_2;
+
+ /* Stream 1 has newline appending enabled */
+ stream_1 = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream_1);
+ string_stream_set_append_newlines(stream_1, true);
+ KUNIT_EXPECT_TRUE(test, stream_1->append_newlines);
+
+ /* Stream 2 does not append newlines */
+ stream_2 = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream_2);
+
+ /* Appending a stream with a newline should not add another newline */
+ string_stream_add(stream_1, "Original string\n");
+ string_stream_add(stream_2, "Appended content\n");
+ string_stream_add(stream_2, "More stuff\n");
+ string_stream_append(stream_1, stream_2);
+ KUNIT_EXPECT_STREQ(test, get_concatenated_string(test, stream_1),
+ "Original string\nAppended content\nMore stuff\n");
+
+ kunit_free_string_stream(test, stream_2);
+ stream_2 = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream_2);
+
+ /*
+ * Appending a stream without newline should add a final newline.
+ * The appended string_stream is treated as a single string so newlines
+ * should not be inserted between fragments.
+ */
+ string_stream_add(stream_2, "Another");
+ string_stream_add(stream_2, "And again");
+ string_stream_append(stream_1, stream_2);
+ KUNIT_EXPECT_STREQ(test, get_concatenated_string(test, stream_1),
+ "Original string\nAppended content\nMore stuff\nAnotherAnd again\n");
+}
+
+/* Adding an empty string should not create a fragment. */
+static void string_stream_append_empty_string_test(struct kunit *test)
{
- struct string_stream *stream = alloc_string_stream(test, GFP_KERNEL);
+ struct string_stream *stream;
+ int original_frag_count;
+
+ stream = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
+ /* Formatted empty string */
+ string_stream_add(stream, "%s", "");
KUNIT_EXPECT_TRUE(test, string_stream_is_empty(stream));
+ KUNIT_EXPECT_TRUE(test, list_empty(&stream->fragments));
+
+ /* Adding an empty string to a non-empty stream */
+ string_stream_add(stream, "Add this line");
+ original_frag_count = list_count_nodes(&stream->fragments);
+
+ string_stream_add(stream, "%s", "");
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&stream->fragments), original_frag_count);
+ KUNIT_EXPECT_STREQ(test, get_concatenated_string(test, stream), "Add this line");
}
-static void string_stream_test_not_empty_after_add(struct kunit *test)
+/* Adding strings without automatic newline appending */
+static void string_stream_no_auto_newline_test(struct kunit *test)
{
- struct string_stream *stream = alloc_string_stream(test, GFP_KERNEL);
+ struct string_stream *stream;
- string_stream_add(stream, "Foo");
+ stream = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
- KUNIT_EXPECT_FALSE(test, string_stream_is_empty(stream));
+ /*
+ * Add some strings with and without newlines. All formatted newlines
+ * should be preserved. It should not add any extra newlines.
+ */
+ string_stream_add(stream, "One");
+ string_stream_add(stream, "Two\n");
+ string_stream_add(stream, "%s\n", "Three");
+ string_stream_add(stream, "%s", "Four\n");
+ string_stream_add(stream, "Five\n%s", "Six");
+ string_stream_add(stream, "Seven\n\n");
+ string_stream_add(stream, "Eight");
+ KUNIT_EXPECT_STREQ(test, get_concatenated_string(test, stream),
+ "OneTwo\nThree\nFour\nFive\nSixSeven\n\nEight");
}
-static void string_stream_test_get_string(struct kunit *test)
+/* Adding strings with automatic newline appending */
+static void string_stream_auto_newline_test(struct kunit *test)
{
- struct string_stream *stream = alloc_string_stream(test, GFP_KERNEL);
- char *output;
+ struct string_stream *stream;
+
+ stream = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
+
+ string_stream_set_append_newlines(stream, true);
+ KUNIT_EXPECT_TRUE(test, stream->append_newlines);
+
+ /*
+ * Add some strings with and without newlines. Newlines should
+ * be appended to lines that do not end with \n, but newlines
+ * resulting from the formatting should not be changed.
+ */
+ string_stream_add(stream, "One");
+ string_stream_add(stream, "Two\n");
+ string_stream_add(stream, "%s\n", "Three");
+ string_stream_add(stream, "%s", "Four\n");
+ string_stream_add(stream, "Five\n%s", "Six");
+ string_stream_add(stream, "Seven\n\n");
+ string_stream_add(stream, "Eight");
+ KUNIT_EXPECT_STREQ(test, get_concatenated_string(test, stream),
+ "One\nTwo\nThree\nFour\nFive\nSix\nSeven\n\nEight\n");
+}
+
+/*
+ * This doesn't actually "test" anything. It reports time taken
+ * and memory used for logging a large number of lines.
+ */
+static void string_stream_performance_test(struct kunit *test)
+{
+ struct string_stream_fragment *frag_container;
+ struct string_stream *stream;
+ char test_line[101];
+ ktime_t start_time, end_time;
+ size_t len, bytes_requested, actual_bytes_used, total_string_length;
+ int offset, i;
+
+ stream = kunit_alloc_string_stream(test, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
+
+ memset(test_line, 'x', sizeof(test_line) - 1);
+ test_line[sizeof(test_line) - 1] = '\0';
+
+ start_time = ktime_get();
+ for (i = 0; i < 10000; i++) {
+ offset = i % (sizeof(test_line) - 1);
+ string_stream_add(stream, "%s: %d\n", &test_line[offset], i);
+ }
+ end_time = ktime_get();
+
+ /*
+ * Calculate memory used. This doesn't include invisible
+ * overhead due to kernel allocator fragment size rounding.
+ */
+ bytes_requested = sizeof(*stream);
+ actual_bytes_used = ksize(stream);
+ total_string_length = 0;
+
+ list_for_each_entry(frag_container, &stream->fragments, node) {
+ bytes_requested += sizeof(*frag_container);
+ actual_bytes_used += ksize(frag_container);
+
+ len = strlen(frag_container->fragment);
+ total_string_length += len;
+ bytes_requested += len + 1; /* +1 for '\0' */
+ actual_bytes_used += ksize(frag_container->fragment);
+ }
+
+ kunit_info(test, "Time elapsed: %lld us\n",
+ ktime_us_delta(end_time, start_time));
+ kunit_info(test, "Total string length: %zu\n", total_string_length);
+ kunit_info(test, "Bytes requested: %zu\n", bytes_requested);
+ kunit_info(test, "Actual bytes allocated: %zu\n", actual_bytes_used);
+}
+
+static int string_stream_test_init(struct kunit *test)
+{
+ struct string_stream_test_priv *priv;
+
+ priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
- string_stream_add(stream, "Foo");
- string_stream_add(stream, " %s", "bar");
+ test->priv = priv;
- output = string_stream_get_string(stream);
- KUNIT_ASSERT_STREQ(test, output, "Foo bar");
+ return 0;
}
static struct kunit_case string_stream_test_cases[] = {
- KUNIT_CASE(string_stream_test_empty_on_creation),
- KUNIT_CASE(string_stream_test_not_empty_after_add),
- KUNIT_CASE(string_stream_test_get_string),
+ KUNIT_CASE(string_stream_managed_init_test),
+ KUNIT_CASE(string_stream_unmanaged_init_test),
+ KUNIT_CASE(string_stream_managed_free_test),
+ KUNIT_CASE(string_stream_resource_free_test),
+ KUNIT_CASE(string_stream_line_add_test),
+ KUNIT_CASE(string_stream_variable_length_line_test),
+ KUNIT_CASE(string_stream_append_test),
+ KUNIT_CASE(string_stream_append_auto_newline_test),
+ KUNIT_CASE(string_stream_append_empty_string_test),
+ KUNIT_CASE(string_stream_no_auto_newline_test),
+ KUNIT_CASE(string_stream_auto_newline_test),
+ KUNIT_CASE(string_stream_performance_test),
{}
};
static struct kunit_suite string_stream_test_suite = {
.name = "string-stream-test",
- .test_cases = string_stream_test_cases
+ .test_cases = string_stream_test_cases,
+ .init = string_stream_test_init,
};
kunit_test_suites(&string_stream_test_suite);
diff --git a/lib/kunit/string-stream.c b/lib/kunit/string-stream.c
index cc32743c1171..a6f3616c2048 100644
--- a/lib/kunit/string-stream.c
+++ b/lib/kunit/string-stream.c
@@ -6,6 +6,7 @@
* Author: Brendan Higgins <brendanhiggins@google.com>
*/
+#include <kunit/static_stub.h>
#include <kunit/test.h>
#include <linux/list.h>
#include <linux/slab.h>
@@ -13,30 +14,28 @@
#include "string-stream.h"
-static struct string_stream_fragment *alloc_string_stream_fragment(
- struct kunit *test, int len, gfp_t gfp)
+static struct string_stream_fragment *alloc_string_stream_fragment(int len, gfp_t gfp)
{
struct string_stream_fragment *frag;
- frag = kunit_kzalloc(test, sizeof(*frag), gfp);
+ frag = kzalloc(sizeof(*frag), gfp);
if (!frag)
return ERR_PTR(-ENOMEM);
- frag->fragment = kunit_kmalloc(test, len, gfp);
+ frag->fragment = kmalloc(len, gfp);
if (!frag->fragment) {
- kunit_kfree(test, frag);
+ kfree(frag);
return ERR_PTR(-ENOMEM);
}
return frag;
}
-static void string_stream_fragment_destroy(struct kunit *test,
- struct string_stream_fragment *frag)
+static void string_stream_fragment_destroy(struct string_stream_fragment *frag)
{
list_del(&frag->node);
- kunit_kfree(test, frag->fragment);
- kunit_kfree(test, frag);
+ kfree(frag->fragment);
+ kfree(frag);
}
int string_stream_vadd(struct string_stream *stream,
@@ -44,26 +43,44 @@ int string_stream_vadd(struct string_stream *stream,
va_list args)
{
struct string_stream_fragment *frag_container;
- int len;
+ int buf_len, result_len;
va_list args_for_counting;
/* Make a copy because `vsnprintf` could change it */
va_copy(args_for_counting, args);
- /* Need space for null byte. */
- len = vsnprintf(NULL, 0, fmt, args_for_counting) + 1;
+ /* Evaluate length of formatted string */
+ buf_len = vsnprintf(NULL, 0, fmt, args_for_counting);
va_end(args_for_counting);
- frag_container = alloc_string_stream_fragment(stream->test,
- len,
- stream->gfp);
+ if (buf_len == 0)
+ return 0;
+
+ /* Reserve one extra for possible appended newline. */
+ if (stream->append_newlines)
+ buf_len++;
+
+ /* Need space for null byte. */
+ buf_len++;
+
+ frag_container = alloc_string_stream_fragment(buf_len, stream->gfp);
if (IS_ERR(frag_container))
return PTR_ERR(frag_container);
- len = vsnprintf(frag_container->fragment, len, fmt, args);
+ if (stream->append_newlines) {
+ /* Don't include reserved newline byte in writeable length. */
+ result_len = vsnprintf(frag_container->fragment, buf_len - 1, fmt, args);
+
+ /* Append newline if necessary. */
+ if (frag_container->fragment[result_len - 1] != '\n')
+ result_len = strlcat(frag_container->fragment, "\n", buf_len);
+ } else {
+ result_len = vsnprintf(frag_container->fragment, buf_len, fmt, args);
+ }
+
spin_lock(&stream->lock);
- stream->length += len;
+ stream->length += result_len;
list_add_tail(&frag_container->node, &stream->fragments);
spin_unlock(&stream->lock);
@@ -82,7 +99,7 @@ int string_stream_add(struct string_stream *stream, const char *fmt, ...)
return result;
}
-static void string_stream_clear(struct string_stream *stream)
+void string_stream_clear(struct string_stream *stream)
{
struct string_stream_fragment *frag_container, *frag_container_safe;
@@ -91,7 +108,7 @@ static void string_stream_clear(struct string_stream *stream)
frag_container_safe,
&stream->fragments,
node) {
- string_stream_fragment_destroy(stream->test, frag_container);
+ string_stream_fragment_destroy(frag_container);
}
stream->length = 0;
spin_unlock(&stream->lock);
@@ -103,7 +120,7 @@ char *string_stream_get_string(struct string_stream *stream)
size_t buf_len = stream->length + 1; /* +1 for null byte. */
char *buf;
- buf = kunit_kzalloc(stream->test, buf_len, stream->gfp);
+ buf = kzalloc(buf_len, stream->gfp);
if (!buf)
return NULL;
@@ -119,13 +136,17 @@ int string_stream_append(struct string_stream *stream,
struct string_stream *other)
{
const char *other_content;
+ int ret;
other_content = string_stream_get_string(other);
if (!other_content)
return -ENOMEM;
- return string_stream_add(stream, other_content);
+ ret = string_stream_add(stream, other_content);
+ kfree(other_content);
+
+ return ret;
}
bool string_stream_is_empty(struct string_stream *stream)
@@ -133,16 +154,15 @@ bool string_stream_is_empty(struct string_stream *stream)
return list_empty(&stream->fragments);
}
-struct string_stream *alloc_string_stream(struct kunit *test, gfp_t gfp)
+struct string_stream *alloc_string_stream(gfp_t gfp)
{
struct string_stream *stream;
- stream = kunit_kzalloc(test, sizeof(*stream), gfp);
+ stream = kzalloc(sizeof(*stream), gfp);
if (!stream)
return ERR_PTR(-ENOMEM);
stream->gfp = gfp;
- stream->test = test;
INIT_LIST_HEAD(&stream->fragments);
spin_lock_init(&stream->lock);
@@ -151,5 +171,37 @@ struct string_stream *alloc_string_stream(struct kunit *test, gfp_t gfp)
void string_stream_destroy(struct string_stream *stream)
{
+ KUNIT_STATIC_STUB_REDIRECT(string_stream_destroy, stream);
+
+ if (!stream)
+ return;
+
string_stream_clear(stream);
+ kfree(stream);
+}
+
+static void resource_free_string_stream(void *p)
+{
+ struct string_stream *stream = p;
+
+ string_stream_destroy(stream);
+}
+
+struct string_stream *kunit_alloc_string_stream(struct kunit *test, gfp_t gfp)
+{
+ struct string_stream *stream;
+
+ stream = alloc_string_stream(gfp);
+ if (IS_ERR(stream))
+ return stream;
+
+ if (kunit_add_action_or_reset(test, resource_free_string_stream, stream) != 0)
+ return ERR_PTR(-ENOMEM);
+
+ return stream;
+}
+
+void kunit_free_string_stream(struct kunit *test, struct string_stream *stream)
+{
+ kunit_release_action(test, resource_free_string_stream, (void *)stream);
}
diff --git a/lib/kunit/string-stream.h b/lib/kunit/string-stream.h
index b669f9a75a94..7be2450c7079 100644
--- a/lib/kunit/string-stream.h
+++ b/lib/kunit/string-stream.h
@@ -23,13 +23,17 @@ struct string_stream {
struct list_head fragments;
/* length and fragments are protected by this lock */
spinlock_t lock;
- struct kunit *test;
gfp_t gfp;
+ bool append_newlines;
};
struct kunit;
-struct string_stream *alloc_string_stream(struct kunit *test, gfp_t gfp);
+struct string_stream *kunit_alloc_string_stream(struct kunit *test, gfp_t gfp);
+void kunit_free_string_stream(struct kunit *test, struct string_stream *stream);
+
+struct string_stream *alloc_string_stream(gfp_t gfp);
+void free_string_stream(struct string_stream *stream);
int __printf(2, 3) string_stream_add(struct string_stream *stream,
const char *fmt, ...);
@@ -38,6 +42,8 @@ int __printf(2, 0) string_stream_vadd(struct string_stream *stream,
const char *fmt,
va_list args);
+void string_stream_clear(struct string_stream *stream);
+
char *string_stream_get_string(struct string_stream *stream);
int string_stream_append(struct string_stream *stream,
@@ -47,4 +53,10 @@ bool string_stream_is_empty(struct string_stream *stream);
void string_stream_destroy(struct string_stream *stream);
+static inline void string_stream_set_append_newlines(struct string_stream *stream,
+ bool append_newlines)
+{
+ stream->append_newlines = append_newlines;
+}
+
#endif /* _KUNIT_STRING_STREAM_H */
diff --git a/lib/kunit/test.c b/lib/kunit/test.c
index 421f13981412..f2eb71f1a66c 100644
--- a/lib/kunit/test.c
+++ b/lib/kunit/test.c
@@ -109,51 +109,17 @@ static void kunit_print_test_stats(struct kunit *test,
stats.total);
}
-/**
- * kunit_log_newline() - Add newline to the end of log if one is not
- * already present.
- * @log: The log to add the newline to.
- */
-static void kunit_log_newline(char *log)
-{
- int log_len, len_left;
-
- log_len = strlen(log);
- len_left = KUNIT_LOG_SIZE - log_len - 1;
-
- if (log_len > 0 && log[log_len - 1] != '\n')
- strncat(log, "\n", len_left);
-}
-
-/*
- * Append formatted message to log, size of which is limited to
- * KUNIT_LOG_SIZE bytes (including null terminating byte).
- */
-void kunit_log_append(char *log, const char *fmt, ...)
+/* Append formatted message to log. */
+void kunit_log_append(struct string_stream *log, const char *fmt, ...)
{
va_list args;
- int len, log_len, len_left;
if (!log)
return;
- log_len = strlen(log);
- len_left = KUNIT_LOG_SIZE - log_len - 1;
- if (len_left <= 0)
- return;
-
- /* Evaluate length of line to add to log */
va_start(args, fmt);
- len = vsnprintf(NULL, 0, fmt, args) + 1;
+ string_stream_vadd(log, fmt, args);
va_end(args);
-
- /* Print formatted line to the log */
- va_start(args, fmt);
- vsnprintf(log + log_len, min(len, len_left), fmt, args);
- va_end(args);
-
- /* Add newline to end of log if not already present. */
- kunit_log_newline(log);
}
EXPORT_SYMBOL_GPL(kunit_log_append);
@@ -296,7 +262,7 @@ static void kunit_print_string_stream(struct kunit *test,
kunit_err(test, "\n");
} else {
kunit_err(test, "%s", buf);
- kunit_kfree(test, buf);
+ kfree(buf);
}
}
@@ -308,7 +274,7 @@ static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,
kunit_set_failure(test);
- stream = alloc_string_stream(test, GFP_KERNEL);
+ stream = kunit_alloc_string_stream(test, GFP_KERNEL);
if (IS_ERR(stream)) {
WARN(true,
"Could not allocate stream to print failed assertion in %s:%d\n",
@@ -322,7 +288,7 @@ static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,
kunit_print_string_stream(test, stream);
- string_stream_destroy(stream);
+ kunit_free_string_stream(test, stream);
}
void __noreturn __kunit_abort(struct kunit *test)
@@ -359,14 +325,14 @@ void __kunit_do_failed_assertion(struct kunit *test,
}
EXPORT_SYMBOL_GPL(__kunit_do_failed_assertion);
-void kunit_init_test(struct kunit *test, const char *name, char *log)
+void kunit_init_test(struct kunit *test, const char *name, struct string_stream *log)
{
spin_lock_init(&test->lock);
INIT_LIST_HEAD(&test->resources);
test->name = name;
test->log = log;
if (test->log)
- test->log[0] = '\0';
+ string_stream_clear(log);
test->status = KUNIT_SUCCESS;
test->status_comment[0] = '\0';
}
@@ -648,12 +614,14 @@ int kunit_run_tests(struct kunit_suite *suite)
param_desc,
test.status_comment);
+ kunit_update_stats(&param_stats, test.status);
+
/* Get next param. */
param_desc[0] = '\0';
test.param_value = test_case->generate_params(test.param_value, param_desc);
test.param_index++;
-
- kunit_update_stats(&param_stats, test.status);
+ test.status = KUNIT_SUCCESS;
+ test.status_comment[0] = '\0';
}
}
diff --git a/lib/objpool.c b/lib/objpool.c
new file mode 100644
index 000000000000..ce0087f64400
--- /dev/null
+++ b/lib/objpool.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/objpool.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/atomic.h>
+#include <linux/irqflags.h>
+#include <linux/cpumask.h>
+#include <linux/log2.h>
+
+/*
+ * objpool: ring-array based lockless MPMC/FIFO queues
+ *
+ * Copyright: wuqiang.matt@bytedance.com,mhiramat@kernel.org
+ */
+
+/* initialize percpu objpool_slot */
+static int
+objpool_init_percpu_slot(struct objpool_head *pool,
+ struct objpool_slot *slot,
+ int nodes, void *context,
+ objpool_init_obj_cb objinit)
+{
+ void *obj = (void *)&slot->entries[pool->capacity];
+ int i;
+
+ /* initialize elements of percpu objpool_slot */
+ slot->mask = pool->capacity - 1;
+
+ for (i = 0; i < nodes; i++) {
+ if (objinit) {
+ int rc = objinit(obj, context);
+ if (rc)
+ return rc;
+ }
+ slot->entries[slot->tail & slot->mask] = obj;
+ obj = obj + pool->obj_size;
+ slot->tail++;
+ slot->last = slot->tail;
+ pool->nr_objs++;
+ }
+
+ return 0;
+}
+
+/* allocate and initialize percpu slots */
+static int
+objpool_init_percpu_slots(struct objpool_head *pool, int nr_objs,
+ void *context, objpool_init_obj_cb objinit)
+{
+ int i, cpu_count = 0;
+
+ for (i = 0; i < pool->nr_cpus; i++) {
+
+ struct objpool_slot *slot;
+ int nodes, size, rc;
+
+ /* skip the cpu node which could never be present */
+ if (!cpu_possible(i))
+ continue;
+
+ /* compute how many objects to be allocated with this slot */
+ nodes = nr_objs / num_possible_cpus();
+ if (cpu_count < (nr_objs % num_possible_cpus()))
+ nodes++;
+ cpu_count++;
+
+ size = struct_size(slot, entries, pool->capacity) +
+ pool->obj_size * nodes;
+
+ /*
+ * here we allocate percpu-slot & objs together in a single
+ * allocation to make it more compact, taking advantage of
+ * warm caches and TLB hits. in default vmalloc is used to
+ * reduce the pressure of kernel slab system. as we know,
+ * mimimal size of vmalloc is one page since vmalloc would
+ * always align the requested size to page size
+ */
+ if (pool->gfp & GFP_ATOMIC)
+ slot = kmalloc_node(size, pool->gfp, cpu_to_node(i));
+ else
+ slot = __vmalloc_node(size, sizeof(void *), pool->gfp,
+ cpu_to_node(i), __builtin_return_address(0));
+ if (!slot)
+ return -ENOMEM;
+ memset(slot, 0, size);
+ pool->cpu_slots[i] = slot;
+
+ /* initialize the objpool_slot of cpu node i */
+ rc = objpool_init_percpu_slot(pool, slot, nodes, context, objinit);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+/* cleanup all percpu slots of the object pool */
+static void objpool_fini_percpu_slots(struct objpool_head *pool)
+{
+ int i;
+
+ if (!pool->cpu_slots)
+ return;
+
+ for (i = 0; i < pool->nr_cpus; i++)
+ kvfree(pool->cpu_slots[i]);
+ kfree(pool->cpu_slots);
+}
+
+/* initialize object pool and pre-allocate objects */
+int objpool_init(struct objpool_head *pool, int nr_objs, int object_size,
+ gfp_t gfp, void *context, objpool_init_obj_cb objinit,
+ objpool_fini_cb release)
+{
+ int rc, capacity, slot_size;
+
+ /* check input parameters */
+ if (nr_objs <= 0 || nr_objs > OBJPOOL_NR_OBJECT_MAX ||
+ object_size <= 0 || object_size > OBJPOOL_OBJECT_SIZE_MAX)
+ return -EINVAL;
+
+ /* align up to unsigned long size */
+ object_size = ALIGN(object_size, sizeof(long));
+
+ /* calculate capacity of percpu objpool_slot */
+ capacity = roundup_pow_of_two(nr_objs);
+ if (!capacity)
+ return -EINVAL;
+
+ /* initialize objpool pool */
+ memset(pool, 0, sizeof(struct objpool_head));
+ pool->nr_cpus = nr_cpu_ids;
+ pool->obj_size = object_size;
+ pool->capacity = capacity;
+ pool->gfp = gfp & ~__GFP_ZERO;
+ pool->context = context;
+ pool->release = release;
+ slot_size = pool->nr_cpus * sizeof(struct objpool_slot);
+ pool->cpu_slots = kzalloc(slot_size, pool->gfp);
+ if (!pool->cpu_slots)
+ return -ENOMEM;
+
+ /* initialize per-cpu slots */
+ rc = objpool_init_percpu_slots(pool, nr_objs, context, objinit);
+ if (rc)
+ objpool_fini_percpu_slots(pool);
+ else
+ refcount_set(&pool->ref, pool->nr_objs + 1);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(objpool_init);
+
+/* adding object to slot, abort if the slot was already full */
+static inline int
+objpool_try_add_slot(void *obj, struct objpool_head *pool, int cpu)
+{
+ struct objpool_slot *slot = pool->cpu_slots[cpu];
+ uint32_t head, tail;
+
+ /* loading tail and head as a local snapshot, tail first */
+ tail = READ_ONCE(slot->tail);
+
+ do {
+ head = READ_ONCE(slot->head);
+ /* fault caught: something must be wrong */
+ WARN_ON_ONCE(tail - head > pool->nr_objs);
+ } while (!try_cmpxchg_acquire(&slot->tail, &tail, tail + 1));
+
+ /* now the tail position is reserved for the given obj */
+ WRITE_ONCE(slot->entries[tail & slot->mask], obj);
+ /* update sequence to make this obj available for pop() */
+ smp_store_release(&slot->last, tail + 1);
+
+ return 0;
+}
+
+/* reclaim an object to object pool */
+int objpool_push(void *obj, struct objpool_head *pool)
+{
+ unsigned long flags;
+ int rc;
+
+ /* disable local irq to avoid preemption & interruption */
+ raw_local_irq_save(flags);
+ rc = objpool_try_add_slot(obj, pool, raw_smp_processor_id());
+ raw_local_irq_restore(flags);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(objpool_push);
+
+/* try to retrieve object from slot */
+static inline void *objpool_try_get_slot(struct objpool_head *pool, int cpu)
+{
+ struct objpool_slot *slot = pool->cpu_slots[cpu];
+ /* load head snapshot, other cpus may change it */
+ uint32_t head = smp_load_acquire(&slot->head);
+
+ while (head != READ_ONCE(slot->last)) {
+ void *obj;
+
+ /* obj must be retrieved before moving forward head */
+ obj = READ_ONCE(slot->entries[head & slot->mask]);
+
+ /* move head forward to mark it's consumption */
+ if (try_cmpxchg_release(&slot->head, &head, head + 1))
+ return obj;
+ }
+
+ return NULL;
+}
+
+/* allocate an object from object pool */
+void *objpool_pop(struct objpool_head *pool)
+{
+ void *obj = NULL;
+ unsigned long flags;
+ int i, cpu;
+
+ /* disable local irq to avoid preemption & interruption */
+ raw_local_irq_save(flags);
+
+ cpu = raw_smp_processor_id();
+ for (i = 0; i < num_possible_cpus(); i++) {
+ obj = objpool_try_get_slot(pool, cpu);
+ if (obj)
+ break;
+ cpu = cpumask_next_wrap(cpu, cpu_possible_mask, -1, 1);
+ }
+ raw_local_irq_restore(flags);
+
+ return obj;
+}
+EXPORT_SYMBOL_GPL(objpool_pop);
+
+/* release whole objpool forcely */
+void objpool_free(struct objpool_head *pool)
+{
+ if (!pool->cpu_slots)
+ return;
+
+ /* release percpu slots */
+ objpool_fini_percpu_slots(pool);
+
+ /* call user's cleanup callback if provided */
+ if (pool->release)
+ pool->release(pool, pool->context);
+}
+EXPORT_SYMBOL_GPL(objpool_free);
+
+/* drop the allocated object, rather reclaim it to objpool */
+int objpool_drop(void *obj, struct objpool_head *pool)
+{
+ if (!obj || !pool)
+ return -EINVAL;
+
+ if (refcount_dec_and_test(&pool->ref)) {
+ objpool_free(pool);
+ return 0;
+ }
+
+ return -EAGAIN;
+}
+EXPORT_SYMBOL_GPL(objpool_drop);
+
+/* drop unused objects and defref objpool for releasing */
+void objpool_fini(struct objpool_head *pool)
+{
+ int count = 1; /* extra ref for objpool itself */
+
+ /* drop all remained objects from objpool */
+ while (objpool_pop(pool))
+ count++;
+
+ if (refcount_sub_and_test(count, &pool->ref))
+ objpool_free(pool);
+}
+EXPORT_SYMBOL_GPL(objpool_fini);
diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile
index 035b0a4db476..1c5420ff254e 100644
--- a/lib/raid6/Makefile
+++ b/lib/raid6/Makefile
@@ -2,7 +2,7 @@
obj-$(CONFIG_RAID6_PQ) += raid6_pq.o
raid6_pq-y += algos.o recov.o tables.o int1.o int2.o int4.o \
- int8.o int16.o int32.o
+ int8.o
raid6_pq-$(CONFIG_X86) += recov_ssse3.o recov_avx2.o mmx.o sse1.o sse2.o avx2.o avx512.o recov_avx512.o
raid6_pq-$(CONFIG_ALTIVEC) += altivec1.o altivec2.o altivec4.o altivec8.o \
@@ -55,7 +55,7 @@ endif
quiet_cmd_unroll = UNROLL $@
cmd_unroll = $(AWK) -v N=$* -f $(srctree)/$(src)/unroll.awk < $< > $@
-targets += int1.c int2.c int4.c int8.c int16.c int32.c
+targets += int1.c int2.c int4.c int8.c
$(obj)/int%.c: $(src)/int.uc $(src)/unroll.awk FORCE
$(call if_changed,unroll)
diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c
index 0ec534faf019..cd2e88ee1f14 100644
--- a/lib/raid6/algos.c
+++ b/lib/raid6/algos.c
@@ -81,10 +81,6 @@ const struct raid6_calls * const raid6_algos[] = {
&raid6_lsx,
#endif
#endif
-#if defined(__ia64__)
- &raid6_intx32,
- &raid6_intx16,
-#endif
&raid6_intx8,
&raid6_intx4,
&raid6_intx2,
diff --git a/lib/raid6/int.uc b/lib/raid6/int.uc
index 558aeac9342a..1ba56c3fa482 100644
--- a/lib/raid6/int.uc
+++ b/lib/raid6/int.uc
@@ -42,13 +42,6 @@ typedef u32 unative_t;
/*
- * IA-64 wants insane amounts of unrolling. On other architectures that
- * is just a waste of space.
- */
-#if ($# <= 8) || defined(__ia64__)
-
-
-/*
* These sub-operations are separate inlines since they can sometimes be
* specially optimized using architecture-specific hacks.
*/
@@ -152,5 +145,3 @@ const struct raid6_calls raid6_intx$# = {
"int" NSTRING "x$#",
0
};
-
-#endif
diff --git a/lib/test_objpool.c b/lib/test_objpool.c
new file mode 100644
index 000000000000..a94078402138
--- /dev/null
+++ b/lib/test_objpool.c
@@ -0,0 +1,690 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Test module for lockless object pool
+ *
+ * Copyright: wuqiang.matt@bytedance.com
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/completion.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/hrtimer.h>
+#include <linux/objpool.h>
+
+#define OT_NR_MAX_BULK (16)
+
+/* memory usage */
+struct ot_mem_stat {
+ atomic_long_t alloc;
+ atomic_long_t free;
+};
+
+/* object allocation results */
+struct ot_obj_stat {
+ unsigned long nhits;
+ unsigned long nmiss;
+};
+
+/* control & results per testcase */
+struct ot_data {
+ struct rw_semaphore start;
+ struct completion wait;
+ struct completion rcu;
+ atomic_t nthreads ____cacheline_aligned_in_smp;
+ atomic_t stop ____cacheline_aligned_in_smp;
+ struct ot_mem_stat kmalloc;
+ struct ot_mem_stat vmalloc;
+ struct ot_obj_stat objects;
+ u64 duration;
+};
+
+/* testcase */
+struct ot_test {
+ int async; /* synchronous or asynchronous */
+ int mode; /* only mode 0 supported */
+ int objsz; /* object size */
+ int duration; /* ms */
+ int delay; /* ms */
+ int bulk_normal;
+ int bulk_irq;
+ unsigned long hrtimer; /* ms */
+ const char *name;
+ struct ot_data data;
+};
+
+/* per-cpu worker */
+struct ot_item {
+ struct objpool_head *pool; /* pool head */
+ struct ot_test *test; /* test parameters */
+
+ void (*worker)(struct ot_item *item, int irq);
+
+ /* hrtimer control */
+ ktime_t hrtcycle;
+ struct hrtimer hrtimer;
+
+ int bulk[2]; /* for thread and irq */
+ int delay;
+ u32 niters;
+
+ /* summary per thread */
+ struct ot_obj_stat stat[2]; /* thread and irq */
+ u64 duration;
+};
+
+/*
+ * memory leakage checking
+ */
+
+static void *ot_kzalloc(struct ot_test *test, long size)
+{
+ void *ptr = kzalloc(size, GFP_KERNEL);
+
+ if (ptr)
+ atomic_long_add(size, &test->data.kmalloc.alloc);
+ return ptr;
+}
+
+static void ot_kfree(struct ot_test *test, void *ptr, long size)
+{
+ if (!ptr)
+ return;
+ atomic_long_add(size, &test->data.kmalloc.free);
+ kfree(ptr);
+}
+
+static void ot_mem_report(struct ot_test *test)
+{
+ long alloc, free;
+
+ pr_info("memory allocation summary for %s\n", test->name);
+
+ alloc = atomic_long_read(&test->data.kmalloc.alloc);
+ free = atomic_long_read(&test->data.kmalloc.free);
+ pr_info(" kmalloc: %lu - %lu = %lu\n", alloc, free, alloc - free);
+
+ alloc = atomic_long_read(&test->data.vmalloc.alloc);
+ free = atomic_long_read(&test->data.vmalloc.free);
+ pr_info(" vmalloc: %lu - %lu = %lu\n", alloc, free, alloc - free);
+}
+
+/* user object instance */
+struct ot_node {
+ void *owner;
+ unsigned long data;
+ unsigned long refs;
+ unsigned long payload[32];
+};
+
+/* user objpool manager */
+struct ot_context {
+ struct objpool_head pool; /* objpool head */
+ struct ot_test *test; /* test parameters */
+ void *ptr; /* user pool buffer */
+ unsigned long size; /* buffer size */
+ struct rcu_head rcu;
+};
+
+static DEFINE_PER_CPU(struct ot_item, ot_pcup_items);
+
+static int ot_init_data(struct ot_data *data)
+{
+ memset(data, 0, sizeof(*data));
+ init_rwsem(&data->start);
+ init_completion(&data->wait);
+ init_completion(&data->rcu);
+ atomic_set(&data->nthreads, 1);
+
+ return 0;
+}
+
+static int ot_init_node(void *nod, void *context)
+{
+ struct ot_context *sop = context;
+ struct ot_node *on = nod;
+
+ on->owner = &sop->pool;
+ return 0;
+}
+
+static enum hrtimer_restart ot_hrtimer_handler(struct hrtimer *hrt)
+{
+ struct ot_item *item = container_of(hrt, struct ot_item, hrtimer);
+ struct ot_test *test = item->test;
+
+ if (atomic_read_acquire(&test->data.stop))
+ return HRTIMER_NORESTART;
+
+ /* do bulk-testings for objects pop/push */
+ item->worker(item, 1);
+
+ hrtimer_forward(hrt, hrt->base->get_time(), item->hrtcycle);
+ return HRTIMER_RESTART;
+}
+
+static void ot_start_hrtimer(struct ot_item *item)
+{
+ if (!item->test->hrtimer)
+ return;
+ hrtimer_start(&item->hrtimer, item->hrtcycle, HRTIMER_MODE_REL);
+}
+
+static void ot_stop_hrtimer(struct ot_item *item)
+{
+ if (!item->test->hrtimer)
+ return;
+ hrtimer_cancel(&item->hrtimer);
+}
+
+static int ot_init_hrtimer(struct ot_item *item, unsigned long hrtimer)
+{
+ struct hrtimer *hrt = &item->hrtimer;
+
+ if (!hrtimer)
+ return -ENOENT;
+
+ item->hrtcycle = ktime_set(0, hrtimer * 1000000UL);
+ hrtimer_init(hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ hrt->function = ot_hrtimer_handler;
+ return 0;
+}
+
+static int ot_init_cpu_item(struct ot_item *item,
+ struct ot_test *test,
+ struct objpool_head *pool,
+ void (*worker)(struct ot_item *, int))
+{
+ memset(item, 0, sizeof(*item));
+ item->pool = pool;
+ item->test = test;
+ item->worker = worker;
+
+ item->bulk[0] = test->bulk_normal;
+ item->bulk[1] = test->bulk_irq;
+ item->delay = test->delay;
+
+ /* initialize hrtimer */
+ ot_init_hrtimer(item, item->test->hrtimer);
+ return 0;
+}
+
+static int ot_thread_worker(void *arg)
+{
+ struct ot_item *item = arg;
+ struct ot_test *test = item->test;
+ ktime_t start;
+
+ atomic_inc(&test->data.nthreads);
+ down_read(&test->data.start);
+ up_read(&test->data.start);
+ start = ktime_get();
+ ot_start_hrtimer(item);
+ do {
+ if (atomic_read_acquire(&test->data.stop))
+ break;
+ /* do bulk-testings for objects pop/push */
+ item->worker(item, 0);
+ } while (!kthread_should_stop());
+ ot_stop_hrtimer(item);
+ item->duration = (u64) ktime_us_delta(ktime_get(), start);
+ if (atomic_dec_and_test(&test->data.nthreads))
+ complete(&test->data.wait);
+
+ return 0;
+}
+
+static void ot_perf_report(struct ot_test *test, u64 duration)
+{
+ struct ot_obj_stat total, normal = {0}, irq = {0};
+ int cpu, nthreads = 0;
+
+ pr_info("\n");
+ pr_info("Testing summary for %s\n", test->name);
+
+ for_each_possible_cpu(cpu) {
+ struct ot_item *item = per_cpu_ptr(&ot_pcup_items, cpu);
+ if (!item->duration)
+ continue;
+ normal.nhits += item->stat[0].nhits;
+ normal.nmiss += item->stat[0].nmiss;
+ irq.nhits += item->stat[1].nhits;
+ irq.nmiss += item->stat[1].nmiss;
+ pr_info("CPU: %d duration: %lluus\n", cpu, item->duration);
+ pr_info("\tthread:\t%16lu hits \t%16lu miss\n",
+ item->stat[0].nhits, item->stat[0].nmiss);
+ pr_info("\tirq: \t%16lu hits \t%16lu miss\n",
+ item->stat[1].nhits, item->stat[1].nmiss);
+ pr_info("\ttotal: \t%16lu hits \t%16lu miss\n",
+ item->stat[0].nhits + item->stat[1].nhits,
+ item->stat[0].nmiss + item->stat[1].nmiss);
+ nthreads++;
+ }
+
+ total.nhits = normal.nhits + irq.nhits;
+ total.nmiss = normal.nmiss + irq.nmiss;
+
+ pr_info("ALL: \tnthreads: %d duration: %lluus\n", nthreads, duration);
+ pr_info("SUM: \t%16lu hits \t%16lu miss\n",
+ total.nhits, total.nmiss);
+
+ test->data.objects = total;
+ test->data.duration = duration;
+}
+
+/*
+ * synchronous test cases for objpool manipulation
+ */
+
+/* objpool manipulation for synchronous mode (percpu objpool) */
+static struct ot_context *ot_init_sync_m0(struct ot_test *test)
+{
+ struct ot_context *sop = NULL;
+ int max = num_possible_cpus() << 3;
+ gfp_t gfp = GFP_KERNEL;
+
+ sop = (struct ot_context *)ot_kzalloc(test, sizeof(*sop));
+ if (!sop)
+ return NULL;
+ sop->test = test;
+ if (test->objsz < 512)
+ gfp = GFP_ATOMIC;
+
+ if (objpool_init(&sop->pool, max, test->objsz,
+ gfp, sop, ot_init_node, NULL)) {
+ ot_kfree(test, sop, sizeof(*sop));
+ return NULL;
+ }
+ WARN_ON(max != sop->pool.nr_objs);
+
+ return sop;
+}
+
+static void ot_fini_sync(struct ot_context *sop)
+{
+ objpool_fini(&sop->pool);
+ ot_kfree(sop->test, sop, sizeof(*sop));
+}
+
+struct {
+ struct ot_context * (*init)(struct ot_test *oc);
+ void (*fini)(struct ot_context *sop);
+} g_ot_sync_ops[] = {
+ {.init = ot_init_sync_m0, .fini = ot_fini_sync},
+};
+
+/*
+ * synchronous test cases: performance mode
+ */
+
+static void ot_bulk_sync(struct ot_item *item, int irq)
+{
+ struct ot_node *nods[OT_NR_MAX_BULK];
+ int i;
+
+ for (i = 0; i < item->bulk[irq]; i++)
+ nods[i] = objpool_pop(item->pool);
+
+ if (!irq && (item->delay || !(++(item->niters) & 0x7FFF)))
+ msleep(item->delay);
+
+ while (i-- > 0) {
+ struct ot_node *on = nods[i];
+ if (on) {
+ on->refs++;
+ objpool_push(on, item->pool);
+ item->stat[irq].nhits++;
+ } else {
+ item->stat[irq].nmiss++;
+ }
+ }
+}
+
+static int ot_start_sync(struct ot_test *test)
+{
+ struct ot_context *sop;
+ ktime_t start;
+ u64 duration;
+ unsigned long timeout;
+ int cpu;
+
+ /* initialize objpool for syncrhonous testcase */
+ sop = g_ot_sync_ops[test->mode].init(test);
+ if (!sop)
+ return -ENOMEM;
+
+ /* grab rwsem to block testing threads */
+ down_write(&test->data.start);
+
+ for_each_possible_cpu(cpu) {
+ struct ot_item *item = per_cpu_ptr(&ot_pcup_items, cpu);
+ struct task_struct *work;
+
+ ot_init_cpu_item(item, test, &sop->pool, ot_bulk_sync);
+
+ /* skip offline cpus */
+ if (!cpu_online(cpu))
+ continue;
+
+ work = kthread_create_on_node(ot_thread_worker, item,
+ cpu_to_node(cpu), "ot_worker_%d", cpu);
+ if (IS_ERR(work)) {
+ pr_err("failed to create thread for cpu %d\n", cpu);
+ } else {
+ kthread_bind(work, cpu);
+ wake_up_process(work);
+ }
+ }
+
+ /* wait a while to make sure all threads waiting at start line */
+ msleep(20);
+
+ /* in case no threads were created: memory insufficient ? */
+ if (atomic_dec_and_test(&test->data.nthreads))
+ complete(&test->data.wait);
+
+ // sched_set_fifo_low(current);
+
+ /* start objpool testing threads */
+ start = ktime_get();
+ up_write(&test->data.start);
+
+ /* yeild cpu to worker threads for duration ms */
+ timeout = msecs_to_jiffies(test->duration);
+ schedule_timeout_interruptible(timeout);
+
+ /* tell workers threads to quit */
+ atomic_set_release(&test->data.stop, 1);
+
+ /* wait all workers threads finish and quit */
+ wait_for_completion(&test->data.wait);
+ duration = (u64) ktime_us_delta(ktime_get(), start);
+
+ /* cleanup objpool */
+ g_ot_sync_ops[test->mode].fini(sop);
+
+ /* report testing summary and performance results */
+ ot_perf_report(test, duration);
+
+ /* report memory allocation summary */
+ ot_mem_report(test);
+
+ return 0;
+}
+
+/*
+ * asynchronous test cases: pool lifecycle controlled by refcount
+ */
+
+static void ot_fini_async_rcu(struct rcu_head *rcu)
+{
+ struct ot_context *sop = container_of(rcu, struct ot_context, rcu);
+ struct ot_test *test = sop->test;
+
+ /* here all cpus are aware of the stop event: test->data.stop = 1 */
+ WARN_ON(!atomic_read_acquire(&test->data.stop));
+
+ objpool_fini(&sop->pool);
+ complete(&test->data.rcu);
+}
+
+static void ot_fini_async(struct ot_context *sop)
+{
+ /* make sure the stop event is acknowledged by all cores */
+ call_rcu(&sop->rcu, ot_fini_async_rcu);
+}
+
+static int ot_objpool_release(struct objpool_head *head, void *context)
+{
+ struct ot_context *sop = context;
+
+ WARN_ON(!head || !sop || head != &sop->pool);
+
+ /* do context cleaning if needed */
+ if (sop)
+ ot_kfree(sop->test, sop, sizeof(*sop));
+
+ return 0;
+}
+
+static struct ot_context *ot_init_async_m0(struct ot_test *test)
+{
+ struct ot_context *sop = NULL;
+ int max = num_possible_cpus() << 3;
+ gfp_t gfp = GFP_KERNEL;
+
+ sop = (struct ot_context *)ot_kzalloc(test, sizeof(*sop));
+ if (!sop)
+ return NULL;
+ sop->test = test;
+ if (test->objsz < 512)
+ gfp = GFP_ATOMIC;
+
+ if (objpool_init(&sop->pool, max, test->objsz, gfp, sop,
+ ot_init_node, ot_objpool_release)) {
+ ot_kfree(test, sop, sizeof(*sop));
+ return NULL;
+ }
+ WARN_ON(max != sop->pool.nr_objs);
+
+ return sop;
+}
+
+struct {
+ struct ot_context * (*init)(struct ot_test *oc);
+ void (*fini)(struct ot_context *sop);
+} g_ot_async_ops[] = {
+ {.init = ot_init_async_m0, .fini = ot_fini_async},
+};
+
+static void ot_nod_recycle(struct ot_node *on, struct objpool_head *pool,
+ int release)
+{
+ struct ot_context *sop;
+
+ on->refs++;
+
+ if (!release) {
+ /* push object back to opjpool for reuse */
+ objpool_push(on, pool);
+ return;
+ }
+
+ sop = container_of(pool, struct ot_context, pool);
+ WARN_ON(sop != pool->context);
+
+ /* unref objpool with nod removed forever */
+ objpool_drop(on, pool);
+}
+
+static void ot_bulk_async(struct ot_item *item, int irq)
+{
+ struct ot_test *test = item->test;
+ struct ot_node *nods[OT_NR_MAX_BULK];
+ int i, stop;
+
+ for (i = 0; i < item->bulk[irq]; i++)
+ nods[i] = objpool_pop(item->pool);
+
+ if (!irq) {
+ if (item->delay || !(++(item->niters) & 0x7FFF))
+ msleep(item->delay);
+ get_cpu();
+ }
+
+ stop = atomic_read_acquire(&test->data.stop);
+
+ /* drop all objects and deref objpool */
+ while (i-- > 0) {
+ struct ot_node *on = nods[i];
+
+ if (on) {
+ on->refs++;
+ ot_nod_recycle(on, item->pool, stop);
+ item->stat[irq].nhits++;
+ } else {
+ item->stat[irq].nmiss++;
+ }
+ }
+
+ if (!irq)
+ put_cpu();
+}
+
+static int ot_start_async(struct ot_test *test)
+{
+ struct ot_context *sop;
+ ktime_t start;
+ u64 duration;
+ unsigned long timeout;
+ int cpu;
+
+ /* initialize objpool for syncrhonous testcase */
+ sop = g_ot_async_ops[test->mode].init(test);
+ if (!sop)
+ return -ENOMEM;
+
+ /* grab rwsem to block testing threads */
+ down_write(&test->data.start);
+
+ for_each_possible_cpu(cpu) {
+ struct ot_item *item = per_cpu_ptr(&ot_pcup_items, cpu);
+ struct task_struct *work;
+
+ ot_init_cpu_item(item, test, &sop->pool, ot_bulk_async);
+
+ /* skip offline cpus */
+ if (!cpu_online(cpu))
+ continue;
+
+ work = kthread_create_on_node(ot_thread_worker, item,
+ cpu_to_node(cpu), "ot_worker_%d", cpu);
+ if (IS_ERR(work)) {
+ pr_err("failed to create thread for cpu %d\n", cpu);
+ } else {
+ kthread_bind(work, cpu);
+ wake_up_process(work);
+ }
+ }
+
+ /* wait a while to make sure all threads waiting at start line */
+ msleep(20);
+
+ /* in case no threads were created: memory insufficient ? */
+ if (atomic_dec_and_test(&test->data.nthreads))
+ complete(&test->data.wait);
+
+ /* start objpool testing threads */
+ start = ktime_get();
+ up_write(&test->data.start);
+
+ /* yeild cpu to worker threads for duration ms */
+ timeout = msecs_to_jiffies(test->duration);
+ schedule_timeout_interruptible(timeout);
+
+ /* tell workers threads to quit */
+ atomic_set_release(&test->data.stop, 1);
+
+ /* do async-finalization */
+ g_ot_async_ops[test->mode].fini(sop);
+
+ /* wait all workers threads finish and quit */
+ wait_for_completion(&test->data.wait);
+ duration = (u64) ktime_us_delta(ktime_get(), start);
+
+ /* assure rcu callback is triggered */
+ wait_for_completion(&test->data.rcu);
+
+ /*
+ * now we are sure that objpool is finalized either
+ * by rcu callback or by worker threads
+ */
+
+ /* report testing summary and performance results */
+ ot_perf_report(test, duration);
+
+ /* report memory allocation summary */
+ ot_mem_report(test);
+
+ return 0;
+}
+
+/*
+ * predefined testing cases:
+ * synchronous case / overrun case / async case
+ *
+ * async: synchronous or asynchronous testing
+ * mode: only mode 0 supported
+ * objsz: object size
+ * duration: int, total test time in ms
+ * delay: int, delay (in ms) between each iteration
+ * bulk_normal: int, repeat times for thread worker
+ * bulk_irq: int, repeat times for irq consumer
+ * hrtimer: unsigned long, hrtimer intervnal in ms
+ * name: char *, tag for current test ot_item
+ */
+
+#define NODE_COMPACT sizeof(struct ot_node)
+#define NODE_VMALLOC (512)
+
+struct ot_test g_testcases[] = {
+
+ /* sync & normal */
+ {0, 0, NODE_COMPACT, 1000, 0, 1, 0, 0, "sync: percpu objpool"},
+ {0, 0, NODE_VMALLOC, 1000, 0, 1, 0, 0, "sync: percpu objpool from vmalloc"},
+
+ /* sync & hrtimer */
+ {0, 0, NODE_COMPACT, 1000, 0, 1, 1, 4, "sync & hrtimer: percpu objpool"},
+ {0, 0, NODE_VMALLOC, 1000, 0, 1, 1, 4, "sync & hrtimer: percpu objpool from vmalloc"},
+
+ /* sync & overrun */
+ {0, 0, NODE_COMPACT, 1000, 0, 16, 0, 0, "sync overrun: percpu objpool"},
+ {0, 0, NODE_VMALLOC, 1000, 0, 16, 0, 0, "sync overrun: percpu objpool from vmalloc"},
+
+ /* async mode */
+ {1, 0, NODE_COMPACT, 1000, 100, 1, 0, 0, "async: percpu objpool"},
+ {1, 0, NODE_VMALLOC, 1000, 100, 1, 0, 0, "async: percpu objpool from vmalloc"},
+
+ /* async + hrtimer mode */
+ {1, 0, NODE_COMPACT, 1000, 0, 4, 4, 4, "async & hrtimer: percpu objpool"},
+ {1, 0, NODE_VMALLOC, 1000, 0, 4, 4, 4, "async & hrtimer: percpu objpool from vmalloc"},
+};
+
+static int __init ot_mod_init(void)
+{
+ int i;
+
+ /* perform testings */
+ for (i = 0; i < ARRAY_SIZE(g_testcases); i++) {
+ ot_init_data(&g_testcases[i].data);
+ if (g_testcases[i].async)
+ ot_start_async(&g_testcases[i]);
+ else
+ ot_start_sync(&g_testcases[i]);
+ }
+
+ /* show tests summary */
+ pr_info("\n");
+ pr_info("Summary of testcases:\n");
+ for (i = 0; i < ARRAY_SIZE(g_testcases); i++) {
+ pr_info(" duration: %lluus \thits: %10lu \tmiss: %10lu \t%s\n",
+ g_testcases[i].data.duration, g_testcases[i].data.objects.nhits,
+ g_testcases[i].data.objects.nmiss, g_testcases[i].name);
+ }
+
+ return -EAGAIN;
+}
+
+static void __exit ot_mod_exit(void)
+{
+}
+
+module_init(ot_mod_init);
+module_exit(ot_mod_exit);
+
+MODULE_LICENSE("GPL"); \ No newline at end of file
diff --git a/lib/ucs2_string.c b/lib/ucs2_string.c
index 0a559a42359b..9308bcfb2ad5 100644
--- a/lib/ucs2_string.c
+++ b/lib/ucs2_string.c
@@ -32,6 +32,58 @@ ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength)
}
EXPORT_SYMBOL(ucs2_strsize);
+/**
+ * ucs2_strscpy() - Copy a UCS2 string into a sized buffer.
+ *
+ * @dst: Pointer to the destination buffer where to copy the string to.
+ * @src: Pointer to the source buffer where to copy the string from.
+ * @count: Size of the destination buffer, in UCS2 (16-bit) characters.
+ *
+ * Like strscpy(), only for UCS2 strings.
+ *
+ * Copy the source string @src, or as much of it as fits, into the destination
+ * buffer @dst. The behavior is undefined if the string buffers overlap. The
+ * destination buffer @dst is always NUL-terminated, unless it's zero-sized.
+ *
+ * Return: The number of characters copied into @dst (excluding the trailing
+ * %NUL terminator) or -E2BIG if @count is 0 or @src was truncated due to the
+ * destination buffer being too small.
+ */
+ssize_t ucs2_strscpy(ucs2_char_t *dst, const ucs2_char_t *src, size_t count)
+{
+ long res;
+
+ /*
+ * Ensure that we have a valid amount of space. We need to store at
+ * least one NUL-character.
+ */
+ if (count == 0 || WARN_ON_ONCE(count > INT_MAX / sizeof(*dst)))
+ return -E2BIG;
+
+ /*
+ * Copy at most 'count' characters, return early if we find a
+ * NUL-terminator.
+ */
+ for (res = 0; res < count; res++) {
+ ucs2_char_t c;
+
+ c = src[res];
+ dst[res] = c;
+
+ if (!c)
+ return res;
+ }
+
+ /*
+ * The loop above terminated without finding a NUL-terminator,
+ * exceeding the 'count': Enforce proper NUL-termination and return
+ * error.
+ */
+ dst[count - 1] = 0;
+ return -E2BIG;
+}
+EXPORT_SYMBOL(ucs2_strscpy);
+
int
ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len)
{
diff --git a/lib/xz/Kconfig b/lib/xz/Kconfig
index adce22ac18d6..aef086a6bf2f 100644
--- a/lib/xz/Kconfig
+++ b/lib/xz/Kconfig
@@ -19,11 +19,6 @@ config XZ_DEC_POWERPC
default y
select XZ_DEC_BCJ
-config XZ_DEC_IA64
- bool "IA-64 BCJ filter decoder" if EXPERT
- default y
- select XZ_DEC_BCJ
-
config XZ_DEC_ARM
bool "ARM BCJ filter decoder" if EXPERT
default y
diff --git a/mm/mmap.c b/mm/mmap.c
index 853489ca05ef..da2e3bd6dba1 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1944,9 +1944,9 @@ static int acct_stack_growth(struct vm_area_struct *vma,
return 0;
}
-#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
+#if defined(CONFIG_STACK_GROWSUP)
/*
- * PA-RISC uses this for its stack; IA64 for its Register Backing Store.
+ * PA-RISC uses this for its stack.
* vma is the last one with address > vma->vm_end. Have to extend vma.
*/
static int expand_upwards(struct vm_area_struct *vma, unsigned long address)
@@ -2043,7 +2043,7 @@ static int expand_upwards(struct vm_area_struct *vma, unsigned long address)
validate_mm(mm);
return error;
}
-#endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */
+#endif /* CONFIG_STACK_GROWSUP */
/*
* vma is the first one with address < vma->vm_start. Have to extend vma.
diff --git a/net/802/fddi.c b/net/802/fddi.c
index 7533ce26ba5f..888379ae35ec 100644
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -175,4 +175,5 @@ struct net_device *alloc_fddidev(int sizeof_priv)
}
EXPORT_SYMBOL(alloc_fddidev);
+MODULE_DESCRIPTION("Core routines for FDDI network devices");
MODULE_LICENSE("GPL");
diff --git a/net/802/garp.c b/net/802/garp.c
index ab24b21fbb49..6a743d004301 100644
--- a/net/802/garp.c
+++ b/net/802/garp.c
@@ -21,6 +21,7 @@
static unsigned int garp_join_time __read_mostly = 200;
module_param(garp_join_time, uint, 0644);
MODULE_PARM_DESC(garp_join_time, "Join time in ms (default 200ms)");
+MODULE_DESCRIPTION("IEEE 802.1D Generic Attribute Registration Protocol (GARP)");
MODULE_LICENSE("GPL");
static const struct garp_state_trans {
diff --git a/net/802/mrp.c b/net/802/mrp.c
index eafc21ecc287..3154d7409493 100644
--- a/net/802/mrp.c
+++ b/net/802/mrp.c
@@ -26,6 +26,7 @@ static unsigned int mrp_periodic_time __read_mostly = 1000;
module_param(mrp_periodic_time, uint, 0644);
MODULE_PARM_DESC(mrp_periodic_time, "Periodic time in ms (default 1s)");
+MODULE_DESCRIPTION("IEEE 802.1Q Multiple Registration Protocol (MRP)");
MODULE_LICENSE("GPL");
static const u8
diff --git a/net/802/p8022.c b/net/802/p8022.c
index 79c23173116c..78c25168d7c9 100644
--- a/net/802/p8022.c
+++ b/net/802/p8022.c
@@ -60,4 +60,5 @@ void unregister_8022_client(struct datalink_proto *proto)
EXPORT_SYMBOL(register_8022_client);
EXPORT_SYMBOL(unregister_8022_client);
+MODULE_DESCRIPTION("Support for 802.2 demultiplexing off Ethernet");
MODULE_LICENSE("GPL");
diff --git a/net/802/psnap.c b/net/802/psnap.c
index 1406bfdbda13..fca9d454905f 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -160,4 +160,5 @@ void unregister_snap_client(struct datalink_proto *proto)
kfree(proto);
}
+MODULE_DESCRIPTION("SNAP data link layer. Derived from 802.2");
MODULE_LICENSE("GPL");
diff --git a/net/802/stp.c b/net/802/stp.c
index d550d9f88f60..03c9f75e92c9 100644
--- a/net/802/stp.c
+++ b/net/802/stp.c
@@ -98,4 +98,5 @@ void stp_proto_unregister(const struct stp_proto *proto)
}
EXPORT_SYMBOL_GPL(stp_proto_unregister);
+MODULE_DESCRIPTION("SAP demux for IEEE 802.1D Spanning Tree Protocol (STP)");
MODULE_LICENSE("GPL");
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index e40aa3e3641c..e45187b88220 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -738,5 +738,6 @@ static void __exit vlan_cleanup_module(void)
module_init(vlan_proto_init);
module_exit(vlan_cleanup_module);
+MODULE_DESCRIPTION("802.1Q/802.1ad VLAN Protocol");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
diff --git a/net/core/dev_addr_lists_test.c b/net/core/dev_addr_lists_test.c
index 90e7e3811ae7..4dbd0dc6aea2 100644
--- a/net/core/dev_addr_lists_test.c
+++ b/net/core/dev_addr_lists_test.c
@@ -233,4 +233,5 @@ static struct kunit_suite dev_addr_test_suite = {
};
kunit_test_suite(dev_addr_test_suite);
+MODULE_DESCRIPTION("KUnit tests for struct netdev_hw_addr_list");
MODULE_LICENSE("GPL");
diff --git a/net/core/selftests.c b/net/core/selftests.c
index 94fe3146a959..8f801e6e3b91 100644
--- a/net/core/selftests.c
+++ b/net/core/selftests.c
@@ -405,5 +405,6 @@ void net_selftest_get_strings(u8 *data)
}
EXPORT_SYMBOL_GPL(net_selftest_get_strings);
+MODULE_DESCRIPTION("Common library for generic PHY ethtool selftests");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
diff --git a/net/core/sock.c b/net/core/sock.c
index 1d28e3e87970..fef349dd72fa 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2003,14 +2003,6 @@ lenout:
return 0;
}
-int sock_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- return sk_getsockopt(sock->sk, level, optname,
- USER_SOCKPTR(optval),
- USER_SOCKPTR(optlen));
-}
-
/*
* Initialize an sk_lock.
*
diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
index 10e96ed6c9e3..b3271957ad9a 100644
--- a/net/ipv4/esp4_offload.c
+++ b/net/ipv4/esp4_offload.c
@@ -33,6 +33,7 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head,
int offset = skb_gro_offset(skb);
struct xfrm_offload *xo;
struct xfrm_state *x;
+ int encap_type = 0;
__be32 seq;
__be32 spi;
@@ -70,6 +71,9 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head,
xo->flags |= XFRM_GRO;
+ if (NAPI_GRO_CB(skb)->proto == IPPROTO_UDP)
+ encap_type = UDP_ENCAP_ESPINUDP;
+
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
XFRM_SPI_SKB_CB(skb)->family = AF_INET;
XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
@@ -77,7 +81,7 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head,
/* We don't need to handle errors from xfrm_input, it does all
* the error handling and frees the resources on error. */
- xfrm_input(skb, IPPROTO_ESP, spi, -2);
+ xfrm_input(skb, IPPROTO_ESP, spi, encap_type);
return ERR_PTR(-EINPROGRESS);
out_reset:
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index b8607763d113..e63a3bf99617 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -517,7 +517,7 @@ static struct rtable *icmp_route_lookup(struct net *net,
} else
return rt;
- err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4_dec), AF_INET);
+ err = xfrm_decode_session_reverse(net, skb_in, flowi4_to_flowi(&fl4_dec), AF_INET);
if (err)
goto relookup_failed;
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index d1e7d0ceb7ed..9ab9b3ebe0cd 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -288,11 +288,11 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
switch (skb->protocol) {
case htons(ETH_P_IP):
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
- xfrm_decode_session(skb, &fl, AF_INET);
+ xfrm_decode_session(dev_net(dev), skb, &fl, AF_INET);
break;
case htons(ETH_P_IPV6):
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
- xfrm_decode_session(skb, &fl, AF_INET6);
+ xfrm_decode_session(dev_net(dev), skb, &fl, AF_INET6);
break;
default:
goto tx_err;
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index bd135165482a..591a2737808e 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -62,7 +62,7 @@ int ip_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb, un
#ifdef CONFIG_XFRM
if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
- xfrm_decode_session(skb, flowi4_to_flowi(&fl4), AF_INET) == 0) {
+ xfrm_decode_session(net, skb, flowi4_to_flowi(&fl4), AF_INET) == 0) {
struct dst_entry *dst = skb_dst(skb);
skb_dst_set(skb, NULL);
dst = xfrm_lookup(net, dst, flowi4_to_flowi(&fl4), sk, 0);
diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c
index 6a845e906a1d..ef5472ed6158 100644
--- a/net/ipv4/tcp_ao.c
+++ b/net/ipv4/tcp_ao.c
@@ -1533,10 +1533,6 @@ static struct tcp_ao_key *tcp_ao_key_alloc(struct sock *sk,
goto err_free_pool;
tfm = crypto_ahash_reqtfm(hp.req);
- if (crypto_ahash_alignmask(tfm) > TCP_AO_KEY_ALIGN) {
- err = -EOPNOTSUPP;
- goto err_pool_end;
- }
digest_size = crypto_ahash_digestsize(tfm);
tcp_sigpool_end(&hp);
@@ -1551,8 +1547,6 @@ static struct tcp_ao_key *tcp_ao_key_alloc(struct sock *sk,
key->digest_size = digest_size;
return key;
-err_pool_end:
- tcp_sigpool_end(&hp);
err_free_pool:
tcp_sigpool_release(pool_id);
return ERR_PTR(err);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 1734fd6a1ce0..89e5a806b82e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2630,6 +2630,19 @@ void udp_destroy_sock(struct sock *sk)
}
}
+static void set_xfrm_gro_udp_encap_rcv(__u16 encap_type, unsigned short family,
+ struct sock *sk)
+{
+#ifdef CONFIG_XFRM
+ if (udp_test_bit(GRO_ENABLED, sk) && encap_type == UDP_ENCAP_ESPINUDP) {
+ if (family == AF_INET)
+ WRITE_ONCE(udp_sk(sk)->gro_receive, xfrm4_gro_udp_encap_rcv);
+ else if (IS_ENABLED(CONFIG_IPV6) && family == AF_INET6)
+ WRITE_ONCE(udp_sk(sk)->gro_receive, ipv6_stub->xfrm6_gro_udp_encap_rcv);
+ }
+#endif
+}
+
/*
* Socket option code for UDP
*/
@@ -2679,6 +2692,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
case 0:
#ifdef CONFIG_XFRM
case UDP_ENCAP_ESPINUDP:
+ set_xfrm_gro_udp_encap_rcv(val, sk->sk_family, sk);
+ fallthrough;
case UDP_ENCAP_ESPINUDP_NON_IKE:
#if IS_ENABLED(CONFIG_IPV6)
if (sk->sk_family == AF_INET6)
@@ -2721,6 +2736,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
udp_tunnel_encap_enable(sk);
udp_assign_bit(GRO_ENABLED, sk, valbool);
udp_assign_bit(ACCEPT_L4, sk, valbool);
+ set_xfrm_gro_udp_encap_rcv(up->encap_type, sk->sk_family, sk);
break;
/*
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 183f6dc37242..c54676998eb6 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -17,6 +17,8 @@
#include <linux/netfilter_ipv4.h>
#include <net/ip.h>
#include <net/xfrm.h>
+#include <net/protocol.h>
+#include <net/gro.h>
static int xfrm4_rcv_encap_finish2(struct net *net, struct sock *sk,
struct sk_buff *skb)
@@ -72,14 +74,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
return 0;
}
-/* If it's a keepalive packet, then just eat it.
- * If it's an encapsulated packet, then pass it to the
- * IPsec xfrm input.
- * Returns 0 if skb passed to xfrm or was dropped.
- * Returns >0 if skb should be passed to UDP.
- * Returns <0 if skb should be resubmitted (-ret is protocol)
- */
-int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
+static int __xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb, bool pull)
{
struct udp_sock *up = udp_sk(sk);
struct udphdr *uh;
@@ -110,7 +105,7 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
case UDP_ENCAP_ESPINUDP:
/* Check if this is a keepalive packet. If so, eat it. */
if (len == 1 && udpdata[0] == 0xff) {
- goto drop;
+ return -EINVAL;
} else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
/* ESP Packet without Non-ESP header */
len = sizeof(struct udphdr);
@@ -121,7 +116,7 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
case UDP_ENCAP_ESPINUDP_NON_IKE:
/* Check if this is a keepalive packet. If so, eat it. */
if (len == 1 && udpdata[0] == 0xff) {
- goto drop;
+ return -EINVAL;
} else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
udpdata32[0] == 0 && udpdata32[1] == 0) {
@@ -139,7 +134,7 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
* protocol to ESP, and then call into the transform receiver.
*/
if (skb_unclone(skb, GFP_ATOMIC))
- goto drop;
+ return -EINVAL;
/* Now we can update and verify the packet length... */
iph = ip_hdr(skb);
@@ -147,25 +142,89 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
iph->tot_len = htons(ntohs(iph->tot_len) - len);
if (skb->len < iphlen + len) {
/* packet is too small!?! */
- goto drop;
+ return -EINVAL;
}
/* pull the data buffer up to the ESP header and set the
* transport header to point to ESP. Keep UDP on the stack
* for later.
*/
- __skb_pull(skb, len);
- skb_reset_transport_header(skb);
+ if (pull) {
+ __skb_pull(skb, len);
+ skb_reset_transport_header(skb);
+ } else {
+ skb_set_transport_header(skb, len);
+ }
/* process ESP */
- return xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);
-
-drop:
- kfree_skb(skb);
return 0;
}
+
+/* If it's a keepalive packet, then just eat it.
+ * If it's an encapsulated packet, then pass it to the
+ * IPsec xfrm input.
+ * Returns 0 if skb passed to xfrm or was dropped.
+ * Returns >0 if skb should be passed to UDP.
+ * Returns <0 if skb should be resubmitted (-ret is protocol)
+ */
+int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
+{
+ int ret;
+
+ ret = __xfrm4_udp_encap_rcv(sk, skb, true);
+ if (!ret)
+ return xfrm4_rcv_encap(skb, IPPROTO_ESP, 0,
+ udp_sk(sk)->encap_type);
+
+ if (ret < 0) {
+ kfree_skb(skb);
+ return 0;
+ }
+
+ return ret;
+}
EXPORT_SYMBOL(xfrm4_udp_encap_rcv);
+struct sk_buff *xfrm4_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
+ struct sk_buff *skb)
+{
+ int offset = skb_gro_offset(skb);
+ const struct net_offload *ops;
+ struct sk_buff *pp = NULL;
+ int ret;
+
+ offset = offset - sizeof(struct udphdr);
+
+ if (!pskb_pull(skb, offset))
+ return NULL;
+
+ rcu_read_lock();
+ ops = rcu_dereference(inet_offloads[IPPROTO_ESP]);
+ if (!ops || !ops->callbacks.gro_receive)
+ goto out;
+
+ ret = __xfrm4_udp_encap_rcv(sk, skb, false);
+ if (ret)
+ goto out;
+
+ skb_push(skb, offset);
+ NAPI_GRO_CB(skb)->proto = IPPROTO_UDP;
+
+ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
+ rcu_read_unlock();
+
+ return pp;
+
+out:
+ rcu_read_unlock();
+ skb_push(skb, offset);
+ NAPI_GRO_CB(skb)->same_flow = 0;
+ NAPI_GRO_CB(skb)->flush = 1;
+
+ return NULL;
+}
+EXPORT_SYMBOL(xfrm4_gro_udp_encap_rcv);
+
int xfrm4_rcv(struct sk_buff *skb)
{
return xfrm4_rcv_spi(skb, ip_hdr(skb)->protocol, 0);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index c35d302a3da9..13a1833a4df5 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -1050,6 +1050,7 @@ static const struct ipv6_stub ipv6_stub_impl = {
#if IS_ENABLED(CONFIG_XFRM)
.xfrm6_local_rxpmtu = xfrm6_local_rxpmtu,
.xfrm6_udp_encap_rcv = xfrm6_udp_encap_rcv,
+ .xfrm6_gro_udp_encap_rcv = xfrm6_gro_udp_encap_rcv,
.xfrm6_rcv_encap = xfrm6_rcv_encap,
#endif
.nd_tbl = &nd_tbl,
diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
index a189e08370a5..527b7caddbc6 100644
--- a/net/ipv6/esp6_offload.c
+++ b/net/ipv6/esp6_offload.c
@@ -34,7 +34,9 @@ static __u16 esp6_nexthdr_esp_offset(struct ipv6hdr *ipv6_hdr, int nhlen)
int off = sizeof(struct ipv6hdr);
struct ipv6_opt_hdr *exthdr;
- if (likely(ipv6_hdr->nexthdr == NEXTHDR_ESP))
+ /* ESP or ESPINUDP */
+ if (likely(ipv6_hdr->nexthdr == NEXTHDR_ESP ||
+ ipv6_hdr->nexthdr == NEXTHDR_UDP))
return offsetof(struct ipv6hdr, nexthdr);
while (off < nhlen) {
@@ -54,10 +56,14 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head,
int offset = skb_gro_offset(skb);
struct xfrm_offload *xo;
struct xfrm_state *x;
+ int encap_type = 0;
__be32 seq;
__be32 spi;
int nhoff;
+ if (NAPI_GRO_CB(skb)->proto == IPPROTO_UDP)
+ encap_type = UDP_ENCAP_ESPINUDP;
+
if (!pskb_pull(skb, offset))
return NULL;
@@ -104,7 +110,7 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head,
/* We don't need to handle errors from xfrm_input, it does all
* the error handling and frees the resources on error. */
- xfrm_input(skb, IPPROTO_ESP, spi, -2);
+ xfrm_input(skb, IPPROTO_ESP, spi, encap_type);
return ERR_PTR(-EINPROGRESS);
out_reset:
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 8fb4a791881a..f62427097126 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -385,7 +385,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net,
return dst;
}
- err = xfrm_decode_session_reverse(skb, flowi6_to_flowi(&fl2), AF_INET6);
+ err = xfrm_decode_session_reverse(net, skb, flowi6_to_flowi(&fl2), AF_INET6);
if (err)
goto relookup_failed;
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 73c85d4e0e9c..e550240c85e1 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -569,11 +569,11 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
goto tx_err;
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
- xfrm_decode_session(skb, &fl, AF_INET6);
+ xfrm_decode_session(dev_net(dev), skb, &fl, AF_INET6);
break;
case htons(ETH_P_IP):
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
- xfrm_decode_session(skb, &fl, AF_INET);
+ xfrm_decode_session(dev_net(dev), skb, &fl, AF_INET);
break;
default:
goto tx_err;
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 857713d7a38a..53d255838e6a 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -61,7 +61,7 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff
#ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
- xfrm_decode_session(skb, flowi6_to_flowi(&fl6), AF_INET6) == 0) {
+ xfrm_decode_session(net, skb, flowi6_to_flowi(&fl6), AF_INET6) == 0) {
skb_dst_set(skb, NULL);
dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0);
if (IS_ERR(dst))
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 4156387248e4..6e36e5047fba 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -16,6 +16,8 @@
#include <linux/netfilter_ipv6.h>
#include <net/ipv6.h>
#include <net/xfrm.h>
+#include <net/protocol.h>
+#include <net/gro.h>
int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
struct ip6_tnl *t)
@@ -67,14 +69,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
return 0;
}
-/* If it's a keepalive packet, then just eat it.
- * If it's an encapsulated packet, then pass it to the
- * IPsec xfrm input.
- * Returns 0 if skb passed to xfrm or was dropped.
- * Returns >0 if skb should be passed to UDP.
- * Returns <0 if skb should be resubmitted (-ret is protocol)
- */
-int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
+static int __xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb, bool pull)
{
struct udp_sock *up = udp_sk(sk);
struct udphdr *uh;
@@ -85,9 +80,6 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
__be32 *udpdata32;
u16 encap_type;
- if (skb->protocol == htons(ETH_P_IP))
- return xfrm4_udp_encap_rcv(sk, skb);
-
encap_type = READ_ONCE(up->encap_type);
/* if this is not encapsulated socket, then just return now */
if (!encap_type)
@@ -109,7 +101,7 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
case UDP_ENCAP_ESPINUDP:
/* Check if this is a keepalive packet. If so, eat it. */
if (len == 1 && udpdata[0] == 0xff) {
- goto drop;
+ return -EINVAL;
} else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
/* ESP Packet without Non-ESP header */
len = sizeof(struct udphdr);
@@ -120,7 +112,7 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
case UDP_ENCAP_ESPINUDP_NON_IKE:
/* Check if this is a keepalive packet. If so, eat it. */
if (len == 1 && udpdata[0] == 0xff) {
- goto drop;
+ return -EINVAL;
} else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
udpdata32[0] == 0 && udpdata32[1] == 0) {
@@ -138,31 +130,100 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
* protocol to ESP, and then call into the transform receiver.
*/
if (skb_unclone(skb, GFP_ATOMIC))
- goto drop;
+ return -EINVAL;
/* Now we can update and verify the packet length... */
ip6h = ipv6_hdr(skb);
ip6h->payload_len = htons(ntohs(ip6h->payload_len) - len);
if (skb->len < ip6hlen + len) {
/* packet is too small!?! */
- goto drop;
+ return -EINVAL;
}
/* pull the data buffer up to the ESP header and set the
* transport header to point to ESP. Keep UDP on the stack
* for later.
*/
- __skb_pull(skb, len);
- skb_reset_transport_header(skb);
+ if (pull) {
+ __skb_pull(skb, len);
+ skb_reset_transport_header(skb);
+ } else {
+ skb_set_transport_header(skb, len);
+ }
/* process ESP */
- return xfrm6_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);
-
-drop:
- kfree_skb(skb);
return 0;
}
+/* If it's a keepalive packet, then just eat it.
+ * If it's an encapsulated packet, then pass it to the
+ * IPsec xfrm input.
+ * Returns 0 if skb passed to xfrm or was dropped.
+ * Returns >0 if skb should be passed to UDP.
+ * Returns <0 if skb should be resubmitted (-ret is protocol)
+ */
+int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
+{
+ int ret;
+
+ if (skb->protocol == htons(ETH_P_IP))
+ return xfrm4_udp_encap_rcv(sk, skb);
+
+ ret = __xfrm6_udp_encap_rcv(sk, skb, true);
+ if (!ret)
+ return xfrm6_rcv_encap(skb, IPPROTO_ESP, 0,
+ udp_sk(sk)->encap_type);
+
+ if (ret < 0) {
+ kfree_skb(skb);
+ return 0;
+ }
+
+ return ret;
+}
+
+struct sk_buff *xfrm6_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
+ struct sk_buff *skb)
+{
+ int offset = skb_gro_offset(skb);
+ const struct net_offload *ops;
+ struct sk_buff *pp = NULL;
+ int ret;
+
+ if (skb->protocol == htons(ETH_P_IP))
+ return xfrm4_gro_udp_encap_rcv(sk, head, skb);
+
+ offset = offset - sizeof(struct udphdr);
+
+ if (!pskb_pull(skb, offset))
+ return NULL;
+
+ rcu_read_lock();
+ ops = rcu_dereference(inet6_offloads[IPPROTO_ESP]);
+ if (!ops || !ops->callbacks.gro_receive)
+ goto out;
+
+ ret = __xfrm6_udp_encap_rcv(sk, skb, false);
+ if (ret)
+ goto out;
+
+ skb_push(skb, offset);
+ NAPI_GRO_CB(skb)->proto = IPPROTO_UDP;
+
+ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
+ rcu_read_unlock();
+
+ return pp;
+
+out:
+ rcu_read_unlock();
+ skb_push(skb, offset);
+ NAPI_GRO_CB(skb)->same_flow = 0;
+ NAPI_GRO_CB(skb)->flush = 1;
+
+ return NULL;
+}
+
int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t)
{
return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
diff --git a/net/netfilter/nf_nat_proto.c b/net/netfilter/nf_nat_proto.c
index 6d969468c779..dc450cc81222 100644
--- a/net/netfilter/nf_nat_proto.c
+++ b/net/netfilter/nf_nat_proto.c
@@ -668,7 +668,7 @@ static int nf_xfrm_me_harder(struct net *net, struct sk_buff *skb, unsigned int
struct flowi fl;
int err;
- err = xfrm_decode_session(skb, &fl, family);
+ err = xfrm_decode_session(net, skb, &fl, family);
if (err < 0)
return err;
diff --git a/net/socket.c b/net/socket.c
index 5740475e084c..0d1c4e78fc7f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2279,33 +2279,23 @@ static bool sock_use_custom_sol_socket(const struct socket *sock)
return test_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags);
}
-/*
- * Set a socket option. Because we don't know the option lengths we have
- * to pass the user mode parameter for the protocols to sort out.
- */
-int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
- int optlen)
+int do_sock_setsockopt(struct socket *sock, bool compat, int level,
+ int optname, sockptr_t optval, int optlen)
{
- sockptr_t optval = USER_SOCKPTR(user_optval);
const struct proto_ops *ops;
char *kernel_optval = NULL;
- int err, fput_needed;
- struct socket *sock;
+ int err;
if (optlen < 0)
return -EINVAL;
- sock = sockfd_lookup_light(fd, &err, &fput_needed);
- if (!sock)
- return err;
-
err = security_socket_setsockopt(sock, level, optname);
if (err)
goto out_put;
- if (!in_compat_syscall())
+ if (!compat)
err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
- user_optval, &optlen,
+ optval, &optlen,
&kernel_optval);
if (err < 0)
goto out_put;
@@ -2326,6 +2316,27 @@ int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
optlen);
kfree(kernel_optval);
out_put:
+ return err;
+}
+EXPORT_SYMBOL(do_sock_setsockopt);
+
+/* Set a socket option. Because we don't know the option lengths we have
+ * to pass the user mode parameter for the protocols to sort out.
+ */
+int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
+ int optlen)
+{
+ sockptr_t optval = USER_SOCKPTR(user_optval);
+ bool compat = in_compat_syscall();
+ int err, fput_needed;
+ struct socket *sock;
+
+ sock = sockfd_lookup_light(fd, &err, &fput_needed);
+ if (!sock)
+ return err;
+
+ err = do_sock_setsockopt(sock, compat, level, optname, optval, optlen);
+
fput_light(sock->file, fput_needed);
return err;
}
@@ -2339,43 +2350,62 @@ SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level,
int optname));
-/*
- * Get a socket option. Because we don't know the option lengths we have
- * to pass a user mode parameter for the protocols to sort out.
- */
-int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
- int __user *optlen)
+int do_sock_getsockopt(struct socket *sock, bool compat, int level,
+ int optname, sockptr_t optval, sockptr_t optlen)
{
int max_optlen __maybe_unused;
const struct proto_ops *ops;
- int err, fput_needed;
- struct socket *sock;
-
- sock = sockfd_lookup_light(fd, &err, &fput_needed);
- if (!sock)
- return err;
+ int err;
err = security_socket_getsockopt(sock, level, optname);
if (err)
- goto out_put;
+ return err;
- if (!in_compat_syscall())
+ if (!compat)
max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
ops = READ_ONCE(sock->ops);
- if (level == SOL_SOCKET)
- err = sock_getsockopt(sock, level, optname, optval, optlen);
- else if (unlikely(!ops->getsockopt))
+ if (level == SOL_SOCKET) {
+ err = sk_getsockopt(sock->sk, level, optname, optval, optlen);
+ } else if (unlikely(!ops->getsockopt)) {
err = -EOPNOTSUPP;
- else
- err = ops->getsockopt(sock, level, optname, optval,
- optlen);
+ } else {
+ if (WARN_ONCE(optval.is_kernel || optlen.is_kernel,
+ "Invalid argument type"))
+ return -EOPNOTSUPP;
+
+ err = ops->getsockopt(sock, level, optname, optval.user,
+ optlen.user);
+ }
- if (!in_compat_syscall())
+ if (!compat)
err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname,
optval, optlen, max_optlen,
err);
-out_put:
+
+ return err;
+}
+EXPORT_SYMBOL(do_sock_getsockopt);
+
+/*
+ * Get a socket option. Because we don't know the option lengths we have
+ * to pass a user mode parameter for the protocols to sort out.
+ */
+int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
+ int __user *optlen)
+{
+ int err, fput_needed;
+ struct socket *sock;
+ bool compat;
+
+ sock = sockfd_lookup_light(fd, &err, &fput_needed);
+ if (!sock)
+ return err;
+
+ compat = in_compat_syscall();
+ err = do_sock_getsockopt(sock, compat, level, optname,
+ USER_SOCKPTR(optval), USER_SOCKPTR(optlen));
+
fput_light(sock->file, fput_needed);
return err;
}
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index d5ee96789d4b..bd4ce21d76d7 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -462,7 +462,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
struct xfrm_offload *xo = xfrm_offload(skb);
struct sec_path *sp;
- if (encap_type < 0) {
+ if (encap_type < 0 || (xo && xo->flags & XFRM_GRO)) {
x = xfrm_input_state(skb);
if (unlikely(x->km.state != XFRM_STATE_VALID)) {
@@ -485,9 +485,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
seq = XFRM_SKB_CB(skb)->seq.input.low;
goto resume;
}
-
- /* encap_type < -1 indicates a GRO call. */
- encap_type = 0;
+ /* GRO call */
seq = XFRM_SPI_SKB_CB(skb)->seq;
if (xo && (xo->flags & CRYPTO_DONE)) {
diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c
index e21cc71095bb..21d50d75c260 100644
--- a/net/xfrm/xfrm_interface_core.c
+++ b/net/xfrm/xfrm_interface_core.c
@@ -536,7 +536,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
switch (skb->protocol) {
case htons(ETH_P_IPV6):
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
- xfrm_decode_session(skb, &fl, AF_INET6);
+ xfrm_decode_session(dev_net(dev), skb, &fl, AF_INET6);
if (!dst) {
fl.u.ip6.flowi6_oif = dev->ifindex;
fl.u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
@@ -551,7 +551,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
break;
case htons(ETH_P_IP):
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
- xfrm_decode_session(skb, &fl, AF_INET);
+ xfrm_decode_session(dev_net(dev), skb, &fl, AF_INET);
if (!dst) {
struct rtable *rt;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 5cdd3bca3637..c13dc3ef7910 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -149,6 +149,21 @@ struct xfrm_pol_inexact_candidates {
struct hlist_head *res[XFRM_POL_CAND_MAX];
};
+struct xfrm_flow_keys {
+ struct flow_dissector_key_basic basic;
+ struct flow_dissector_key_control control;
+ union {
+ struct flow_dissector_key_ipv4_addrs ipv4;
+ struct flow_dissector_key_ipv6_addrs ipv6;
+ } addrs;
+ struct flow_dissector_key_ip ip;
+ struct flow_dissector_key_icmp icmp;
+ struct flow_dissector_key_ports ports;
+ struct flow_dissector_key_keyid gre;
+};
+
+static struct flow_dissector xfrm_session_dissector __ro_after_init;
+
static DEFINE_SPINLOCK(xfrm_if_cb_lock);
static struct xfrm_if_cb const __rcu *xfrm_if_cb __read_mostly;
@@ -2858,7 +2873,7 @@ static void xfrm_policy_queue_process(struct timer_list *t)
/* Fixup the mark to support VTI. */
skb_mark = skb->mark;
skb->mark = pol->mark.v;
- xfrm_decode_session(skb, &fl, dst->ops->family);
+ xfrm_decode_session(net, skb, &fl, dst->ops->family);
skb->mark = skb_mark;
spin_unlock(&pq->hold_queue.lock);
@@ -2894,7 +2909,7 @@ static void xfrm_policy_queue_process(struct timer_list *t)
/* Fixup the mark to support VTI. */
skb_mark = skb->mark;
skb->mark = pol->mark.v;
- xfrm_decode_session(skb, &fl, skb_dst(skb)->ops->family);
+ xfrm_decode_session(net, skb, &fl, skb_dst(skb)->ops->family);
skb->mark = skb_mark;
dst_hold(xfrm_dst_path(skb_dst(skb)));
@@ -3372,209 +3387,106 @@ xfrm_policy_ok(const struct xfrm_tmpl *tmpl, const struct sec_path *sp, int star
}
static void
-decode_session4(struct sk_buff *skb, struct flowi *fl, bool reverse)
+decode_session4(const struct xfrm_flow_keys *flkeys, struct flowi *fl, bool reverse)
{
- const struct iphdr *iph = ip_hdr(skb);
- int ihl = iph->ihl;
- u8 *xprth = skb_network_header(skb) + ihl * 4;
struct flowi4 *fl4 = &fl->u.ip4;
- int oif = 0;
-
- if (skb_dst(skb) && skb_dst(skb)->dev)
- oif = skb_dst(skb)->dev->ifindex;
memset(fl4, 0, sizeof(struct flowi4));
- fl4->flowi4_mark = skb->mark;
- fl4->flowi4_oif = reverse ? skb->skb_iif : oif;
-
- fl4->flowi4_proto = iph->protocol;
- fl4->daddr = reverse ? iph->saddr : iph->daddr;
- fl4->saddr = reverse ? iph->daddr : iph->saddr;
- fl4->flowi4_tos = iph->tos & ~INET_ECN_MASK;
-
- if (!ip_is_fragment(iph)) {
- switch (iph->protocol) {
- case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
- case IPPROTO_TCP:
- case IPPROTO_SCTP:
- case IPPROTO_DCCP:
- if (xprth + 4 < skb->data ||
- pskb_may_pull(skb, xprth + 4 - skb->data)) {
- __be16 *ports;
-
- xprth = skb_network_header(skb) + ihl * 4;
- ports = (__be16 *)xprth;
-
- fl4->fl4_sport = ports[!!reverse];
- fl4->fl4_dport = ports[!reverse];
- }
- break;
- case IPPROTO_ICMP:
- if (xprth + 2 < skb->data ||
- pskb_may_pull(skb, xprth + 2 - skb->data)) {
- u8 *icmp;
- xprth = skb_network_header(skb) + ihl * 4;
- icmp = xprth;
+ if (reverse) {
+ fl4->saddr = flkeys->addrs.ipv4.dst;
+ fl4->daddr = flkeys->addrs.ipv4.src;
+ fl4->fl4_sport = flkeys->ports.dst;
+ fl4->fl4_dport = flkeys->ports.src;
+ } else {
+ fl4->saddr = flkeys->addrs.ipv4.src;
+ fl4->daddr = flkeys->addrs.ipv4.dst;
+ fl4->fl4_sport = flkeys->ports.src;
+ fl4->fl4_dport = flkeys->ports.dst;
+ }
- fl4->fl4_icmp_type = icmp[0];
- fl4->fl4_icmp_code = icmp[1];
- }
- break;
- case IPPROTO_GRE:
- if (xprth + 12 < skb->data ||
- pskb_may_pull(skb, xprth + 12 - skb->data)) {
- __be16 *greflags;
- __be32 *gre_hdr;
-
- xprth = skb_network_header(skb) + ihl * 4;
- greflags = (__be16 *)xprth;
- gre_hdr = (__be32 *)xprth;
-
- if (greflags[0] & GRE_KEY) {
- if (greflags[0] & GRE_CSUM)
- gre_hdr++;
- fl4->fl4_gre_key = gre_hdr[1];
- }
- }
- break;
- default:
- break;
- }
+ switch (flkeys->basic.ip_proto) {
+ case IPPROTO_GRE:
+ fl4->fl4_gre_key = flkeys->gre.keyid;
+ break;
+ case IPPROTO_ICMP:
+ fl4->fl4_icmp_type = flkeys->icmp.type;
+ fl4->fl4_icmp_code = flkeys->icmp.code;
+ break;
}
+
+ fl4->flowi4_proto = flkeys->basic.ip_proto;
+ fl4->flowi4_tos = flkeys->ip.tos;
}
#if IS_ENABLED(CONFIG_IPV6)
static void
-decode_session6(struct sk_buff *skb, struct flowi *fl, bool reverse)
+decode_session6(const struct xfrm_flow_keys *flkeys, struct flowi *fl, bool reverse)
{
struct flowi6 *fl6 = &fl->u.ip6;
- int onlyproto = 0;
- const struct ipv6hdr *hdr = ipv6_hdr(skb);
- u32 offset = sizeof(*hdr);
- struct ipv6_opt_hdr *exthdr;
- const unsigned char *nh = skb_network_header(skb);
- u16 nhoff = IP6CB(skb)->nhoff;
- int oif = 0;
- u8 nexthdr;
-
- if (!nhoff)
- nhoff = offsetof(struct ipv6hdr, nexthdr);
-
- nexthdr = nh[nhoff];
-
- if (skb_dst(skb) && skb_dst(skb)->dev)
- oif = skb_dst(skb)->dev->ifindex;
memset(fl6, 0, sizeof(struct flowi6));
- fl6->flowi6_mark = skb->mark;
- fl6->flowi6_oif = reverse ? skb->skb_iif : oif;
-
- fl6->daddr = reverse ? hdr->saddr : hdr->daddr;
- fl6->saddr = reverse ? hdr->daddr : hdr->saddr;
-
- while (nh + offset + sizeof(*exthdr) < skb->data ||
- pskb_may_pull(skb, nh + offset + sizeof(*exthdr) - skb->data)) {
- nh = skb_network_header(skb);
- exthdr = (struct ipv6_opt_hdr *)(nh + offset);
-
- switch (nexthdr) {
- case NEXTHDR_FRAGMENT:
- onlyproto = 1;
- fallthrough;
- case NEXTHDR_ROUTING:
- case NEXTHDR_HOP:
- case NEXTHDR_DEST:
- offset += ipv6_optlen(exthdr);
- nexthdr = exthdr->nexthdr;
- break;
- case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
- case IPPROTO_TCP:
- case IPPROTO_SCTP:
- case IPPROTO_DCCP:
- if (!onlyproto && (nh + offset + 4 < skb->data ||
- pskb_may_pull(skb, nh + offset + 4 - skb->data))) {
- __be16 *ports;
-
- nh = skb_network_header(skb);
- ports = (__be16 *)(nh + offset);
- fl6->fl6_sport = ports[!!reverse];
- fl6->fl6_dport = ports[!reverse];
- }
- fl6->flowi6_proto = nexthdr;
- return;
- case IPPROTO_ICMPV6:
- if (!onlyproto && (nh + offset + 2 < skb->data ||
- pskb_may_pull(skb, nh + offset + 2 - skb->data))) {
- u8 *icmp;
-
- nh = skb_network_header(skb);
- icmp = (u8 *)(nh + offset);
- fl6->fl6_icmp_type = icmp[0];
- fl6->fl6_icmp_code = icmp[1];
- }
- fl6->flowi6_proto = nexthdr;
- return;
- case IPPROTO_GRE:
- if (!onlyproto &&
- (nh + offset + 12 < skb->data ||
- pskb_may_pull(skb, nh + offset + 12 - skb->data))) {
- struct gre_base_hdr *gre_hdr;
- __be32 *gre_key;
-
- nh = skb_network_header(skb);
- gre_hdr = (struct gre_base_hdr *)(nh + offset);
- gre_key = (__be32 *)(gre_hdr + 1);
-
- if (gre_hdr->flags & GRE_KEY) {
- if (gre_hdr->flags & GRE_CSUM)
- gre_key++;
- fl6->fl6_gre_key = *gre_key;
- }
- }
- fl6->flowi6_proto = nexthdr;
- return;
-#if IS_ENABLED(CONFIG_IPV6_MIP6)
- case IPPROTO_MH:
- offset += ipv6_optlen(exthdr);
- if (!onlyproto && (nh + offset + 3 < skb->data ||
- pskb_may_pull(skb, nh + offset + 3 - skb->data))) {
- struct ip6_mh *mh;
-
- nh = skb_network_header(skb);
- mh = (struct ip6_mh *)(nh + offset);
- fl6->fl6_mh_type = mh->ip6mh_type;
- }
- fl6->flowi6_proto = nexthdr;
- return;
-#endif
- default:
- fl6->flowi6_proto = nexthdr;
- return;
- }
+ if (reverse) {
+ fl6->saddr = flkeys->addrs.ipv6.dst;
+ fl6->daddr = flkeys->addrs.ipv6.src;
+ fl6->fl6_sport = flkeys->ports.dst;
+ fl6->fl6_dport = flkeys->ports.src;
+ } else {
+ fl6->saddr = flkeys->addrs.ipv6.src;
+ fl6->daddr = flkeys->addrs.ipv6.dst;
+ fl6->fl6_sport = flkeys->ports.src;
+ fl6->fl6_dport = flkeys->ports.dst;
+ }
+
+ switch (flkeys->basic.ip_proto) {
+ case IPPROTO_GRE:
+ fl6->fl6_gre_key = flkeys->gre.keyid;
+ break;
+ case IPPROTO_ICMPV6:
+ fl6->fl6_icmp_type = flkeys->icmp.type;
+ fl6->fl6_icmp_code = flkeys->icmp.code;
+ break;
}
+
+ fl6->flowi6_proto = flkeys->basic.ip_proto;
}
#endif
-int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+int __xfrm_decode_session(struct net *net, struct sk_buff *skb, struct flowi *fl,
unsigned int family, int reverse)
{
+ struct xfrm_flow_keys flkeys;
+
+ memset(&flkeys, 0, sizeof(flkeys));
+ __skb_flow_dissect(net, skb, &xfrm_session_dissector, &flkeys,
+ NULL, 0, 0, 0, FLOW_DISSECTOR_F_STOP_AT_ENCAP);
+
switch (family) {
case AF_INET:
- decode_session4(skb, fl, reverse);
+ decode_session4(&flkeys, fl, reverse);
break;
#if IS_ENABLED(CONFIG_IPV6)
case AF_INET6:
- decode_session6(skb, fl, reverse);
+ decode_session6(&flkeys, fl, reverse);
break;
#endif
default:
return -EAFNOSUPPORT;
}
+ fl->flowi_mark = skb->mark;
+ if (reverse) {
+ fl->flowi_oif = skb->skb_iif;
+ } else {
+ int oif = 0;
+
+ if (skb_dst(skb) && skb_dst(skb)->dev)
+ oif = skb_dst(skb)->dev->ifindex;
+
+ fl->flowi_oif = oif;
+ }
+
return security_xfrm_decode_session(skb, &fl->flowi_secid);
}
EXPORT_SYMBOL(__xfrm_decode_session);
@@ -3623,7 +3535,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
reverse = dir & ~XFRM_POLICY_MASK;
dir &= XFRM_POLICY_MASK;
- if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) {
+ if (__xfrm_decode_session(net, skb, &fl, family, reverse) < 0) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
return 0;
}
@@ -3779,7 +3691,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
struct dst_entry *dst;
int res = 1;
- if (xfrm_decode_session(skb, &fl, family) < 0) {
+ if (xfrm_decode_session(net, skb, &fl, family) < 0) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMFWDHDRERROR);
return 0;
}
@@ -4258,8 +4170,47 @@ static struct pernet_operations __net_initdata xfrm_net_ops = {
.exit = xfrm_net_exit,
};
+static const struct flow_dissector_key xfrm_flow_dissector_keys[] = {
+ {
+ .key_id = FLOW_DISSECTOR_KEY_CONTROL,
+ .offset = offsetof(struct xfrm_flow_keys, control),
+ },
+ {
+ .key_id = FLOW_DISSECTOR_KEY_BASIC,
+ .offset = offsetof(struct xfrm_flow_keys, basic),
+ },
+ {
+ .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+ .offset = offsetof(struct xfrm_flow_keys, addrs.ipv4),
+ },
+ {
+ .key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+ .offset = offsetof(struct xfrm_flow_keys, addrs.ipv6),
+ },
+ {
+ .key_id = FLOW_DISSECTOR_KEY_PORTS,
+ .offset = offsetof(struct xfrm_flow_keys, ports),
+ },
+ {
+ .key_id = FLOW_DISSECTOR_KEY_GRE_KEYID,
+ .offset = offsetof(struct xfrm_flow_keys, gre),
+ },
+ {
+ .key_id = FLOW_DISSECTOR_KEY_IP,
+ .offset = offsetof(struct xfrm_flow_keys, ip),
+ },
+ {
+ .key_id = FLOW_DISSECTOR_KEY_ICMP,
+ .offset = offsetof(struct xfrm_flow_keys, icmp),
+ },
+};
+
void __init xfrm_init(void)
{
+ skb_flow_dissector_init(&xfrm_session_dissector,
+ xfrm_flow_dissector_keys,
+ ARRAY_SIZE(xfrm_flow_dissector_keys));
+
register_pernet_subsys(&xfrm_net_ops);
xfrm_dev_init();
xfrm_input_init();
diff --git a/samples/kprobes/kretprobe_example.c b/samples/kprobes/kretprobe_example.c
index cbf16542d84e..ed79fd3d48fb 100644
--- a/samples/kprobes/kretprobe_example.c
+++ b/samples/kprobes/kretprobe_example.c
@@ -35,7 +35,7 @@ struct my_data {
ktime_t entry_stamp;
};
-/* Here we use the entry_hanlder to timestamp function entry */
+/* Here we use the entry_handler to timestamp function entry */
static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
struct my_data *data;
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 3764d1911b51..93405264ff23 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -1262,7 +1262,7 @@ static long mbochs_ioctl(struct vfio_device *vdev, unsigned int cmd,
case VFIO_DEVICE_QUERY_GFX_PLANE:
{
- struct vfio_device_gfx_plane_info plane;
+ struct vfio_device_gfx_plane_info plane = {};
minsz = offsetofend(struct vfio_device_gfx_plane_info,
region_index);
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 064e1c0a7aa8..72ea5832c927 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -591,7 +591,7 @@ static long mdpy_ioctl(struct vfio_device *vdev, unsigned int cmd,
case VFIO_DEVICE_QUERY_GFX_PLANE:
{
- struct vfio_device_gfx_plane_info plane;
+ struct vfio_device_gfx_plane_info plane = {};
minsz = offsetofend(struct vfio_device_gfx_plane_info,
region_index);
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 5af00387c519..69ba0281f9e0 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -29,6 +29,8 @@
#include <linux/serial.h>
#include <uapi/linux/serial_reg.h>
#include <linux/eventfd.h>
+#include <linux/anon_inodes.h>
+
/*
* #defines
*/
@@ -124,10 +126,32 @@ struct serial_port {
u8 intr_trigger_level; /* interrupt trigger level */
};
+struct mtty_data {
+ u64 magic;
+#define MTTY_MAGIC 0x7e9d09898c3e2c4e /* Nothing clever, just random */
+ u32 major_ver;
+#define MTTY_MAJOR_VER 1
+ u32 minor_ver;
+#define MTTY_MINOR_VER 0
+ u32 nr_ports;
+ u32 flags;
+ struct serial_port ports[2];
+};
+
+struct mdev_state;
+
+struct mtty_migration_file {
+ struct file *filp;
+ struct mutex lock;
+ struct mdev_state *mdev_state;
+ struct mtty_data data;
+ ssize_t filled_size;
+ u8 disabled:1;
+};
+
/* State of each mdev device */
struct mdev_state {
struct vfio_device vdev;
- int irq_fd;
struct eventfd_ctx *intx_evtfd;
struct eventfd_ctx *msi_evtfd;
int irq_index;
@@ -141,6 +165,13 @@ struct mdev_state {
struct mutex rxtx_lock;
struct vfio_device_info dev_info;
int nr_ports;
+ enum vfio_device_mig_state state;
+ struct mutex state_mutex;
+ struct mutex reset_mutex;
+ struct mtty_migration_file *saving_migf;
+ struct mtty_migration_file *resuming_migf;
+ u8 deferred_reset:1;
+ u8 intx_mask:1;
};
static struct mtty_type {
@@ -166,10 +197,6 @@ static const struct file_operations vd_fops = {
static const struct vfio_device_ops mtty_dev_ops;
-/* function prototypes */
-
-static int mtty_trigger_interrupt(struct mdev_state *mdev_state);
-
/* Helper functions */
static void dump_buffer(u8 *buf, uint32_t count)
@@ -186,6 +213,36 @@ static void dump_buffer(u8 *buf, uint32_t count)
#endif
}
+static bool is_intx(struct mdev_state *mdev_state)
+{
+ return mdev_state->irq_index == VFIO_PCI_INTX_IRQ_INDEX;
+}
+
+static bool is_msi(struct mdev_state *mdev_state)
+{
+ return mdev_state->irq_index == VFIO_PCI_MSI_IRQ_INDEX;
+}
+
+static bool is_noirq(struct mdev_state *mdev_state)
+{
+ return !is_intx(mdev_state) && !is_msi(mdev_state);
+}
+
+static void mtty_trigger_interrupt(struct mdev_state *mdev_state)
+{
+ lockdep_assert_held(&mdev_state->ops_lock);
+
+ if (is_msi(mdev_state)) {
+ if (mdev_state->msi_evtfd)
+ eventfd_signal(mdev_state->msi_evtfd, 1);
+ } else if (is_intx(mdev_state)) {
+ if (mdev_state->intx_evtfd && !mdev_state->intx_mask) {
+ eventfd_signal(mdev_state->intx_evtfd, 1);
+ mdev_state->intx_mask = true;
+ }
+ }
+}
+
static void mtty_create_config_space(struct mdev_state *mdev_state)
{
/* PCI dev ID */
@@ -717,6 +774,543 @@ accessfailed:
return ret;
}
+static size_t mtty_data_size(struct mdev_state *mdev_state)
+{
+ return offsetof(struct mtty_data, ports) +
+ (mdev_state->nr_ports * sizeof(struct serial_port));
+}
+
+static void mtty_disable_file(struct mtty_migration_file *migf)
+{
+ mutex_lock(&migf->lock);
+ migf->disabled = true;
+ migf->filled_size = 0;
+ migf->filp->f_pos = 0;
+ mutex_unlock(&migf->lock);
+}
+
+static void mtty_disable_files(struct mdev_state *mdev_state)
+{
+ if (mdev_state->saving_migf) {
+ mtty_disable_file(mdev_state->saving_migf);
+ fput(mdev_state->saving_migf->filp);
+ mdev_state->saving_migf = NULL;
+ }
+
+ if (mdev_state->resuming_migf) {
+ mtty_disable_file(mdev_state->resuming_migf);
+ fput(mdev_state->resuming_migf->filp);
+ mdev_state->resuming_migf = NULL;
+ }
+}
+
+static void mtty_state_mutex_unlock(struct mdev_state *mdev_state)
+{
+again:
+ mutex_lock(&mdev_state->reset_mutex);
+ if (mdev_state->deferred_reset) {
+ mdev_state->deferred_reset = false;
+ mutex_unlock(&mdev_state->reset_mutex);
+ mdev_state->state = VFIO_DEVICE_STATE_RUNNING;
+ mtty_disable_files(mdev_state);
+ goto again;
+ }
+ mutex_unlock(&mdev_state->state_mutex);
+ mutex_unlock(&mdev_state->reset_mutex);
+}
+
+static int mtty_release_migf(struct inode *inode, struct file *filp)
+{
+ struct mtty_migration_file *migf = filp->private_data;
+
+ mtty_disable_file(migf);
+ mutex_destroy(&migf->lock);
+ kfree(migf);
+
+ return 0;
+}
+
+static long mtty_precopy_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct mtty_migration_file *migf = filp->private_data;
+ struct mdev_state *mdev_state = migf->mdev_state;
+ loff_t *pos = &filp->f_pos;
+ struct vfio_precopy_info info = {};
+ unsigned long minsz;
+ int ret;
+
+ if (cmd != VFIO_MIG_GET_PRECOPY_INFO)
+ return -ENOTTY;
+
+ minsz = offsetofend(struct vfio_precopy_info, dirty_bytes);
+
+ if (copy_from_user(&info, (void __user *)arg, minsz))
+ return -EFAULT;
+ if (info.argsz < minsz)
+ return -EINVAL;
+
+ mutex_lock(&mdev_state->state_mutex);
+ if (mdev_state->state != VFIO_DEVICE_STATE_PRE_COPY &&
+ mdev_state->state != VFIO_DEVICE_STATE_PRE_COPY_P2P) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ mutex_lock(&migf->lock);
+
+ if (migf->disabled) {
+ mutex_unlock(&migf->lock);
+ ret = -ENODEV;
+ goto unlock;
+ }
+
+ if (*pos > migf->filled_size) {
+ mutex_unlock(&migf->lock);
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ info.dirty_bytes = 0;
+ info.initial_bytes = migf->filled_size - *pos;
+ mutex_unlock(&migf->lock);
+
+ ret = copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
+unlock:
+ mtty_state_mutex_unlock(mdev_state);
+ return ret;
+}
+
+static ssize_t mtty_save_read(struct file *filp, char __user *buf,
+ size_t len, loff_t *pos)
+{
+ struct mtty_migration_file *migf = filp->private_data;
+ ssize_t ret = 0;
+
+ if (pos)
+ return -ESPIPE;
+
+ pos = &filp->f_pos;
+
+ mutex_lock(&migf->lock);
+
+ dev_dbg(migf->mdev_state->vdev.dev, "%s ask %zu\n", __func__, len);
+
+ if (migf->disabled) {
+ ret = -ENODEV;
+ goto out_unlock;
+ }
+
+ if (*pos > migf->filled_size) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ len = min_t(size_t, migf->filled_size - *pos, len);
+ if (len) {
+ if (copy_to_user(buf, (void *)&migf->data + *pos, len)) {
+ ret = -EFAULT;
+ goto out_unlock;
+ }
+ *pos += len;
+ ret = len;
+ }
+out_unlock:
+ dev_dbg(migf->mdev_state->vdev.dev, "%s read %zu\n", __func__, ret);
+ mutex_unlock(&migf->lock);
+ return ret;
+}
+
+static const struct file_operations mtty_save_fops = {
+ .owner = THIS_MODULE,
+ .read = mtty_save_read,
+ .unlocked_ioctl = mtty_precopy_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
+ .release = mtty_release_migf,
+ .llseek = no_llseek,
+};
+
+static void mtty_save_state(struct mdev_state *mdev_state)
+{
+ struct mtty_migration_file *migf = mdev_state->saving_migf;
+ int i;
+
+ mutex_lock(&migf->lock);
+ for (i = 0; i < mdev_state->nr_ports; i++) {
+ memcpy(&migf->data.ports[i],
+ &mdev_state->s[i], sizeof(struct serial_port));
+ migf->filled_size += sizeof(struct serial_port);
+ }
+ dev_dbg(mdev_state->vdev.dev,
+ "%s filled to %zu\n", __func__, migf->filled_size);
+ mutex_unlock(&migf->lock);
+}
+
+static int mtty_load_state(struct mdev_state *mdev_state)
+{
+ struct mtty_migration_file *migf = mdev_state->resuming_migf;
+ int i;
+
+ mutex_lock(&migf->lock);
+ /* magic and version already tested by resume write fn */
+ if (migf->filled_size < mtty_data_size(mdev_state)) {
+ dev_dbg(mdev_state->vdev.dev, "%s expected %zu, got %zu\n",
+ __func__, mtty_data_size(mdev_state),
+ migf->filled_size);
+ mutex_unlock(&migf->lock);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < mdev_state->nr_ports; i++)
+ memcpy(&mdev_state->s[i],
+ &migf->data.ports[i], sizeof(struct serial_port));
+
+ mutex_unlock(&migf->lock);
+ return 0;
+}
+
+static struct mtty_migration_file *
+mtty_save_device_data(struct mdev_state *mdev_state,
+ enum vfio_device_mig_state state)
+{
+ struct mtty_migration_file *migf = mdev_state->saving_migf;
+ struct mtty_migration_file *ret = NULL;
+
+ if (migf) {
+ if (state == VFIO_DEVICE_STATE_STOP_COPY)
+ goto fill_data;
+ return ret;
+ }
+
+ migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT);
+ if (!migf)
+ return ERR_PTR(-ENOMEM);
+
+ migf->filp = anon_inode_getfile("mtty_mig", &mtty_save_fops,
+ migf, O_RDONLY);
+ if (IS_ERR(migf->filp)) {
+ int rc = PTR_ERR(migf->filp);
+
+ kfree(migf);
+ return ERR_PTR(rc);
+ }
+
+ stream_open(migf->filp->f_inode, migf->filp);
+ mutex_init(&migf->lock);
+ migf->mdev_state = mdev_state;
+
+ migf->data.magic = MTTY_MAGIC;
+ migf->data.major_ver = MTTY_MAJOR_VER;
+ migf->data.minor_ver = MTTY_MINOR_VER;
+ migf->data.nr_ports = mdev_state->nr_ports;
+
+ migf->filled_size = offsetof(struct mtty_data, ports);
+
+ dev_dbg(mdev_state->vdev.dev, "%s filled header to %zu\n",
+ __func__, migf->filled_size);
+
+ ret = mdev_state->saving_migf = migf;
+
+fill_data:
+ if (state == VFIO_DEVICE_STATE_STOP_COPY)
+ mtty_save_state(mdev_state);
+
+ return ret;
+}
+
+static ssize_t mtty_resume_write(struct file *filp, const char __user *buf,
+ size_t len, loff_t *pos)
+{
+ struct mtty_migration_file *migf = filp->private_data;
+ struct mdev_state *mdev_state = migf->mdev_state;
+ loff_t requested_length;
+ ssize_t ret = 0;
+
+ if (pos)
+ return -ESPIPE;
+
+ pos = &filp->f_pos;
+
+ if (*pos < 0 ||
+ check_add_overflow((loff_t)len, *pos, &requested_length))
+ return -EINVAL;
+
+ if (requested_length > mtty_data_size(mdev_state))
+ return -ENOMEM;
+
+ mutex_lock(&migf->lock);
+
+ if (migf->disabled) {
+ ret = -ENODEV;
+ goto out_unlock;
+ }
+
+ if (copy_from_user((void *)&migf->data + *pos, buf, len)) {
+ ret = -EFAULT;
+ goto out_unlock;
+ }
+
+ *pos += len;
+ ret = len;
+
+ dev_dbg(migf->mdev_state->vdev.dev, "%s received %zu, total %zu\n",
+ __func__, len, migf->filled_size + len);
+
+ if (migf->filled_size < offsetof(struct mtty_data, ports) &&
+ migf->filled_size + len >= offsetof(struct mtty_data, ports)) {
+ if (migf->data.magic != MTTY_MAGIC || migf->data.flags ||
+ migf->data.major_ver != MTTY_MAJOR_VER ||
+ migf->data.minor_ver != MTTY_MINOR_VER ||
+ migf->data.nr_ports != mdev_state->nr_ports) {
+ dev_dbg(migf->mdev_state->vdev.dev,
+ "%s failed validation\n", __func__);
+ ret = -EFAULT;
+ } else {
+ dev_dbg(migf->mdev_state->vdev.dev,
+ "%s header validated\n", __func__);
+ }
+ }
+
+ migf->filled_size += len;
+
+out_unlock:
+ mutex_unlock(&migf->lock);
+ return ret;
+}
+
+static const struct file_operations mtty_resume_fops = {
+ .owner = THIS_MODULE,
+ .write = mtty_resume_write,
+ .release = mtty_release_migf,
+ .llseek = no_llseek,
+};
+
+static struct mtty_migration_file *
+mtty_resume_device_data(struct mdev_state *mdev_state)
+{
+ struct mtty_migration_file *migf;
+ int ret;
+
+ migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT);
+ if (!migf)
+ return ERR_PTR(-ENOMEM);
+
+ migf->filp = anon_inode_getfile("mtty_mig", &mtty_resume_fops,
+ migf, O_WRONLY);
+ if (IS_ERR(migf->filp)) {
+ ret = PTR_ERR(migf->filp);
+ kfree(migf);
+ return ERR_PTR(ret);
+ }
+
+ stream_open(migf->filp->f_inode, migf->filp);
+ mutex_init(&migf->lock);
+ migf->mdev_state = mdev_state;
+
+ mdev_state->resuming_migf = migf;
+
+ return migf;
+}
+
+static struct file *mtty_step_state(struct mdev_state *mdev_state,
+ enum vfio_device_mig_state new)
+{
+ enum vfio_device_mig_state cur = mdev_state->state;
+
+ dev_dbg(mdev_state->vdev.dev, "%s: %d -> %d\n", __func__, cur, new);
+
+ /*
+ * The following state transitions are no-op considering
+ * mtty does not do DMA nor require any explicit start/stop.
+ *
+ * RUNNING -> RUNNING_P2P
+ * RUNNING_P2P -> RUNNING
+ * RUNNING_P2P -> STOP
+ * PRE_COPY -> PRE_COPY_P2P
+ * PRE_COPY_P2P -> PRE_COPY
+ * STOP -> RUNNING_P2P
+ */
+ if ((cur == VFIO_DEVICE_STATE_RUNNING &&
+ new == VFIO_DEVICE_STATE_RUNNING_P2P) ||
+ (cur == VFIO_DEVICE_STATE_RUNNING_P2P &&
+ (new == VFIO_DEVICE_STATE_RUNNING ||
+ new == VFIO_DEVICE_STATE_STOP)) ||
+ (cur == VFIO_DEVICE_STATE_PRE_COPY &&
+ new == VFIO_DEVICE_STATE_PRE_COPY_P2P) ||
+ (cur == VFIO_DEVICE_STATE_PRE_COPY_P2P &&
+ new == VFIO_DEVICE_STATE_PRE_COPY) ||
+ (cur == VFIO_DEVICE_STATE_STOP &&
+ new == VFIO_DEVICE_STATE_RUNNING_P2P))
+ return NULL;
+
+ /*
+ * The following state transitions simply close migration files,
+ * with the exception of RESUMING -> STOP, which needs to load
+ * the state first.
+ *
+ * RESUMING -> STOP
+ * PRE_COPY -> RUNNING
+ * PRE_COPY_P2P -> RUNNING_P2P
+ * STOP_COPY -> STOP
+ */
+ if (cur == VFIO_DEVICE_STATE_RESUMING &&
+ new == VFIO_DEVICE_STATE_STOP) {
+ int ret;
+
+ ret = mtty_load_state(mdev_state);
+ if (ret)
+ return ERR_PTR(ret);
+ mtty_disable_files(mdev_state);
+ return NULL;
+ }
+
+ if ((cur == VFIO_DEVICE_STATE_PRE_COPY &&
+ new == VFIO_DEVICE_STATE_RUNNING) ||
+ (cur == VFIO_DEVICE_STATE_PRE_COPY_P2P &&
+ new == VFIO_DEVICE_STATE_RUNNING_P2P) ||
+ (cur == VFIO_DEVICE_STATE_STOP_COPY &&
+ new == VFIO_DEVICE_STATE_STOP)) {
+ mtty_disable_files(mdev_state);
+ return NULL;
+ }
+
+ /*
+ * The following state transitions return migration files.
+ *
+ * RUNNING -> PRE_COPY
+ * RUNNING_P2P -> PRE_COPY_P2P
+ * STOP -> STOP_COPY
+ * STOP -> RESUMING
+ * PRE_COPY_P2P -> STOP_COPY
+ */
+ if ((cur == VFIO_DEVICE_STATE_RUNNING &&
+ new == VFIO_DEVICE_STATE_PRE_COPY) ||
+ (cur == VFIO_DEVICE_STATE_RUNNING_P2P &&
+ new == VFIO_DEVICE_STATE_PRE_COPY_P2P) ||
+ (cur == VFIO_DEVICE_STATE_STOP &&
+ new == VFIO_DEVICE_STATE_STOP_COPY) ||
+ (cur == VFIO_DEVICE_STATE_PRE_COPY_P2P &&
+ new == VFIO_DEVICE_STATE_STOP_COPY)) {
+ struct mtty_migration_file *migf;
+
+ migf = mtty_save_device_data(mdev_state, new);
+ if (IS_ERR(migf))
+ return ERR_CAST(migf);
+
+ if (migf) {
+ get_file(migf->filp);
+
+ return migf->filp;
+ }
+ return NULL;
+ }
+
+ if (cur == VFIO_DEVICE_STATE_STOP &&
+ new == VFIO_DEVICE_STATE_RESUMING) {
+ struct mtty_migration_file *migf;
+
+ migf = mtty_resume_device_data(mdev_state);
+ if (IS_ERR(migf))
+ return ERR_CAST(migf);
+
+ get_file(migf->filp);
+
+ return migf->filp;
+ }
+
+ /* vfio_mig_get_next_state() does not use arcs other than the above */
+ WARN_ON(true);
+ return ERR_PTR(-EINVAL);
+}
+
+static struct file *mtty_set_state(struct vfio_device *vdev,
+ enum vfio_device_mig_state new_state)
+{
+ struct mdev_state *mdev_state =
+ container_of(vdev, struct mdev_state, vdev);
+ struct file *ret = NULL;
+
+ dev_dbg(vdev->dev, "%s -> %d\n", __func__, new_state);
+
+ mutex_lock(&mdev_state->state_mutex);
+ while (mdev_state->state != new_state) {
+ enum vfio_device_mig_state next_state;
+ int rc = vfio_mig_get_next_state(vdev, mdev_state->state,
+ new_state, &next_state);
+ if (rc) {
+ ret = ERR_PTR(rc);
+ break;
+ }
+
+ ret = mtty_step_state(mdev_state, next_state);
+ if (IS_ERR(ret))
+ break;
+
+ mdev_state->state = next_state;
+
+ if (WARN_ON(ret && new_state != next_state)) {
+ fput(ret);
+ ret = ERR_PTR(-EINVAL);
+ break;
+ }
+ }
+ mtty_state_mutex_unlock(mdev_state);
+ return ret;
+}
+
+static int mtty_get_state(struct vfio_device *vdev,
+ enum vfio_device_mig_state *current_state)
+{
+ struct mdev_state *mdev_state =
+ container_of(vdev, struct mdev_state, vdev);
+
+ mutex_lock(&mdev_state->state_mutex);
+ *current_state = mdev_state->state;
+ mtty_state_mutex_unlock(mdev_state);
+ return 0;
+}
+
+static int mtty_get_data_size(struct vfio_device *vdev,
+ unsigned long *stop_copy_length)
+{
+ struct mdev_state *mdev_state =
+ container_of(vdev, struct mdev_state, vdev);
+
+ *stop_copy_length = mtty_data_size(mdev_state);
+ return 0;
+}
+
+static const struct vfio_migration_ops mtty_migration_ops = {
+ .migration_set_state = mtty_set_state,
+ .migration_get_state = mtty_get_state,
+ .migration_get_data_size = mtty_get_data_size,
+};
+
+static int mtty_log_start(struct vfio_device *vdev,
+ struct rb_root_cached *ranges,
+ u32 nnodes, u64 *page_size)
+{
+ return 0;
+}
+
+static int mtty_log_stop(struct vfio_device *vdev)
+{
+ return 0;
+}
+
+static int mtty_log_read_and_clear(struct vfio_device *vdev,
+ unsigned long iova, unsigned long length,
+ struct iova_bitmap *dirty)
+{
+ return 0;
+}
+
+static const struct vfio_log_ops mtty_log_ops = {
+ .log_start = mtty_log_start,
+ .log_stop = mtty_log_stop,
+ .log_read_and_clear = mtty_log_read_and_clear,
+};
+
static int mtty_init_dev(struct vfio_device *vdev)
{
struct mdev_state *mdev_state =
@@ -749,6 +1343,16 @@ static int mtty_init_dev(struct vfio_device *vdev)
mutex_init(&mdev_state->ops_lock);
mdev_state->mdev = mdev;
mtty_create_config_space(mdev_state);
+
+ mutex_init(&mdev_state->state_mutex);
+ mutex_init(&mdev_state->reset_mutex);
+ vdev->migration_flags = VFIO_MIGRATION_STOP_COPY |
+ VFIO_MIGRATION_P2P |
+ VFIO_MIGRATION_PRE_COPY;
+ vdev->mig_ops = &mtty_migration_ops;
+ vdev->log_ops = &mtty_log_ops;
+ mdev_state->state = VFIO_DEVICE_STATE_RUNNING;
+
return 0;
err_nr_ports:
@@ -782,6 +1386,8 @@ static void mtty_release_dev(struct vfio_device *vdev)
struct mdev_state *mdev_state =
container_of(vdev, struct mdev_state, vdev);
+ mutex_destroy(&mdev_state->reset_mutex);
+ mutex_destroy(&mdev_state->state_mutex);
atomic_add(mdev_state->nr_ports, &mdev_avail_ports);
kfree(mdev_state->vconfig);
}
@@ -798,6 +1404,15 @@ static int mtty_reset(struct mdev_state *mdev_state)
{
pr_info("%s: called\n", __func__);
+ mutex_lock(&mdev_state->reset_mutex);
+ mdev_state->deferred_reset = true;
+ if (!mutex_trylock(&mdev_state->state_mutex)) {
+ mutex_unlock(&mdev_state->reset_mutex);
+ return 0;
+ }
+ mutex_unlock(&mdev_state->reset_mutex);
+ mtty_state_mutex_unlock(mdev_state);
+
return 0;
}
@@ -921,6 +1536,25 @@ write_err:
return -EFAULT;
}
+static void mtty_disable_intx(struct mdev_state *mdev_state)
+{
+ if (mdev_state->intx_evtfd) {
+ eventfd_ctx_put(mdev_state->intx_evtfd);
+ mdev_state->intx_evtfd = NULL;
+ mdev_state->intx_mask = false;
+ mdev_state->irq_index = -1;
+ }
+}
+
+static void mtty_disable_msi(struct mdev_state *mdev_state)
+{
+ if (mdev_state->msi_evtfd) {
+ eventfd_ctx_put(mdev_state->msi_evtfd);
+ mdev_state->msi_evtfd = NULL;
+ mdev_state->irq_index = -1;
+ }
+}
+
static int mtty_set_irqs(struct mdev_state *mdev_state, uint32_t flags,
unsigned int index, unsigned int start,
unsigned int count, void *data)
@@ -932,59 +1566,113 @@ static int mtty_set_irqs(struct mdev_state *mdev_state, uint32_t flags,
case VFIO_PCI_INTX_IRQ_INDEX:
switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
case VFIO_IRQ_SET_ACTION_MASK:
+ if (!is_intx(mdev_state) || start != 0 || count != 1) {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (flags & VFIO_IRQ_SET_DATA_NONE) {
+ mdev_state->intx_mask = true;
+ } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
+ uint8_t mask = *(uint8_t *)data;
+
+ if (mask)
+ mdev_state->intx_mask = true;
+ } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
+ ret = -ENOTTY; /* No support for mask fd */
+ }
+ break;
case VFIO_IRQ_SET_ACTION_UNMASK:
+ if (!is_intx(mdev_state) || start != 0 || count != 1) {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (flags & VFIO_IRQ_SET_DATA_NONE) {
+ mdev_state->intx_mask = false;
+ } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
+ uint8_t mask = *(uint8_t *)data;
+
+ if (mask)
+ mdev_state->intx_mask = false;
+ } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
+ ret = -ENOTTY; /* No support for unmask fd */
+ }
break;
case VFIO_IRQ_SET_ACTION_TRIGGER:
- {
- if (flags & VFIO_IRQ_SET_DATA_NONE) {
- pr_info("%s: disable INTx\n", __func__);
- if (mdev_state->intx_evtfd)
- eventfd_ctx_put(mdev_state->intx_evtfd);
+ if (is_intx(mdev_state) && !count &&
+ (flags & VFIO_IRQ_SET_DATA_NONE)) {
+ mtty_disable_intx(mdev_state);
+ break;
+ }
+
+ if (!(is_intx(mdev_state) || is_noirq(mdev_state)) ||
+ start != 0 || count != 1) {
+ ret = -EINVAL;
break;
}
if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
int fd = *(int *)data;
+ struct eventfd_ctx *evt;
- if (fd > 0) {
- struct eventfd_ctx *evt;
-
- evt = eventfd_ctx_fdget(fd);
- if (IS_ERR(evt)) {
- ret = PTR_ERR(evt);
- break;
- }
- mdev_state->intx_evtfd = evt;
- mdev_state->irq_fd = fd;
- mdev_state->irq_index = index;
+ mtty_disable_intx(mdev_state);
+
+ if (fd < 0)
+ break;
+
+ evt = eventfd_ctx_fdget(fd);
+ if (IS_ERR(evt)) {
+ ret = PTR_ERR(evt);
break;
}
+ mdev_state->intx_evtfd = evt;
+ mdev_state->irq_index = index;
+ break;
+ }
+
+ if (!is_intx(mdev_state)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (flags & VFIO_IRQ_SET_DATA_NONE) {
+ mtty_trigger_interrupt(mdev_state);
+ } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
+ uint8_t trigger = *(uint8_t *)data;
+
+ if (trigger)
+ mtty_trigger_interrupt(mdev_state);
}
break;
}
- }
break;
case VFIO_PCI_MSI_IRQ_INDEX:
switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
case VFIO_IRQ_SET_ACTION_MASK:
case VFIO_IRQ_SET_ACTION_UNMASK:
+ ret = -ENOTTY;
break;
case VFIO_IRQ_SET_ACTION_TRIGGER:
- if (flags & VFIO_IRQ_SET_DATA_NONE) {
- if (mdev_state->msi_evtfd)
- eventfd_ctx_put(mdev_state->msi_evtfd);
- pr_info("%s: disable MSI\n", __func__);
- mdev_state->irq_index = VFIO_PCI_INTX_IRQ_INDEX;
+ if (is_msi(mdev_state) && !count &&
+ (flags & VFIO_IRQ_SET_DATA_NONE)) {
+ mtty_disable_msi(mdev_state);
+ break;
+ }
+
+ if (!(is_msi(mdev_state) || is_noirq(mdev_state)) ||
+ start != 0 || count != 1) {
+ ret = -EINVAL;
break;
}
+
if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
int fd = *(int *)data;
struct eventfd_ctx *evt;
- if (fd <= 0)
- break;
+ mtty_disable_msi(mdev_state);
- if (mdev_state->msi_evtfd)
+ if (fd < 0)
break;
evt = eventfd_ctx_fdget(fd);
@@ -993,20 +1681,37 @@ static int mtty_set_irqs(struct mdev_state *mdev_state, uint32_t flags,
break;
}
mdev_state->msi_evtfd = evt;
- mdev_state->irq_fd = fd;
mdev_state->irq_index = index;
+ break;
+ }
+
+ if (!is_msi(mdev_state)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (flags & VFIO_IRQ_SET_DATA_NONE) {
+ mtty_trigger_interrupt(mdev_state);
+ } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
+ uint8_t trigger = *(uint8_t *)data;
+
+ if (trigger)
+ mtty_trigger_interrupt(mdev_state);
}
break;
- }
- break;
+ }
+ break;
case VFIO_PCI_MSIX_IRQ_INDEX:
- pr_info("%s: MSIX_IRQ\n", __func__);
+ dev_dbg(mdev_state->vdev.dev, "%s: MSIX_IRQ\n", __func__);
+ ret = -ENOTTY;
break;
case VFIO_PCI_ERR_IRQ_INDEX:
- pr_info("%s: ERR_IRQ\n", __func__);
+ dev_dbg(mdev_state->vdev.dev, "%s: ERR_IRQ\n", __func__);
+ ret = -ENOTTY;
break;
case VFIO_PCI_REQ_IRQ_INDEX:
- pr_info("%s: REQ_IRQ\n", __func__);
+ dev_dbg(mdev_state->vdev.dev, "%s: REQ_IRQ\n", __func__);
+ ret = -ENOTTY;
break;
}
@@ -1014,33 +1719,6 @@ static int mtty_set_irqs(struct mdev_state *mdev_state, uint32_t flags,
return ret;
}
-static int mtty_trigger_interrupt(struct mdev_state *mdev_state)
-{
- int ret = -1;
-
- if ((mdev_state->irq_index == VFIO_PCI_MSI_IRQ_INDEX) &&
- (!mdev_state->msi_evtfd))
- return -EINVAL;
- else if ((mdev_state->irq_index == VFIO_PCI_INTX_IRQ_INDEX) &&
- (!mdev_state->intx_evtfd)) {
- pr_info("%s: Intr eventfd not found\n", __func__);
- return -EINVAL;
- }
-
- if (mdev_state->irq_index == VFIO_PCI_MSI_IRQ_INDEX)
- ret = eventfd_signal(mdev_state->msi_evtfd, 1);
- else
- ret = eventfd_signal(mdev_state->intx_evtfd, 1);
-
-#if defined(DEBUG_INTR)
- pr_info("Intx triggered\n");
-#endif
- if (ret != 1)
- pr_err("%s: eventfd signal failed (%d)\n", __func__, ret);
-
- return ret;
-}
-
static int mtty_get_region_info(struct mdev_state *mdev_state,
struct vfio_region_info *region_info,
u16 *cap_type_id, void **cap_type)
@@ -1084,22 +1762,16 @@ static int mtty_get_region_info(struct mdev_state *mdev_state,
static int mtty_get_irq_info(struct vfio_irq_info *irq_info)
{
- switch (irq_info->index) {
- case VFIO_PCI_INTX_IRQ_INDEX:
- case VFIO_PCI_MSI_IRQ_INDEX:
- case VFIO_PCI_REQ_IRQ_INDEX:
- break;
-
- default:
+ if (irq_info->index != VFIO_PCI_INTX_IRQ_INDEX &&
+ irq_info->index != VFIO_PCI_MSI_IRQ_INDEX)
return -EINVAL;
- }
irq_info->flags = VFIO_IRQ_INFO_EVENTFD;
irq_info->count = 1;
if (irq_info->index == VFIO_PCI_INTX_IRQ_INDEX)
- irq_info->flags |= (VFIO_IRQ_INFO_MASKABLE |
- VFIO_IRQ_INFO_AUTOMASKED);
+ irq_info->flags |= VFIO_IRQ_INFO_MASKABLE |
+ VFIO_IRQ_INFO_AUTOMASKED;
else
irq_info->flags |= VFIO_IRQ_INFO_NORESIZE;
@@ -1262,6 +1934,16 @@ static unsigned int mtty_get_available(struct mdev_type *mtype)
return atomic_read(&mdev_avail_ports) / type->nr_ports;
}
+static void mtty_close(struct vfio_device *vdev)
+{
+ struct mdev_state *mdev_state =
+ container_of(vdev, struct mdev_state, vdev);
+
+ mtty_disable_files(mdev_state);
+ mtty_disable_intx(mdev_state);
+ mtty_disable_msi(mdev_state);
+}
+
static const struct vfio_device_ops mtty_dev_ops = {
.name = "vfio-mtty",
.init = mtty_init_dev,
@@ -1273,6 +1955,7 @@ static const struct vfio_device_ops mtty_dev_ops = {
.unbind_iommufd = vfio_iommufd_emulated_unbind,
.attach_ioas = vfio_iommufd_emulated_attach_ioas,
.detach_ioas = vfio_iommufd_emulated_detach_ioas,
+ .close_device = mtty_close,
};
static struct mdev_driver mtty_driver = {
diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh
index 56d3c338d91d..c3064ac31003 100755
--- a/scripts/headers_install.sh
+++ b/scripts/headers_install.sh
@@ -74,7 +74,6 @@ arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_16K
arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_4K
arch/arc/include/uapi/asm/swab.h:CONFIG_ARC_HAS_SWAPE
arch/arm/include/uapi/asm/ptrace.h:CONFIG_CPU_ENDIAN_BE8
-arch/hexagon/include/uapi/asm/ptrace.h:CONFIG_HEXAGON_ARCH_VERSION
arch/hexagon/include/uapi/asm/user.h:CONFIG_HEXAGON_ARCH_VERSION
arch/m68k/include/uapi/asm/ptrace.h:CONFIG_COLDFIRE
arch/nios2/include/uapi/asm/swab.h:CONFIG_NIOS2_CI_SWAB_NO
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 6e199a745ccb..08a3e603db19 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -185,7 +185,7 @@ if (defined($ENV{'KBUILD_VERBOSE'}) && $ENV{'KBUILD_VERBOSE'} =~ '1') {
if (defined($ENV{'KCFLAGS'})) {
my $kcflags = "$ENV{'KCFLAGS'}";
- if ($kcflags =~ /Werror/) {
+ if ($kcflags =~ /(\s|^)-Werror(\s|$)/) {
$Werror = 1;
}
}
diff --git a/security/keys/key.c b/security/keys/key.c
index 5c0c7df833f8..0260a1902922 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -693,6 +693,7 @@ error:
spin_unlock(&key_serial_lock);
return key;
}
+EXPORT_SYMBOL(key_lookup);
/*
* Find and lock the specified key type against removal.
diff --git a/tools/arch/ia64/include/asm/barrier.h b/tools/arch/ia64/include/asm/barrier.h
deleted file mode 100644
index 6fffe5682713..000000000000
--- a/tools/arch/ia64/include/asm/barrier.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copied from the kernel sources to tools/:
- *
- * Memory barrier definitions. This is based on information published
- * in the Processor Abstraction Layer and the System Abstraction Layer
- * manual.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- */
-#ifndef _TOOLS_LINUX_ASM_IA64_BARRIER_H
-#define _TOOLS_LINUX_ASM_IA64_BARRIER_H
-
-#include <linux/compiler.h>
-
-/*
- * Macros to force memory ordering. In these descriptions, "previous"
- * and "subsequent" refer to program order; "visible" means that all
- * architecturally visible effects of a memory access have occurred
- * (at a minimum, this means the memory has been read or written).
- *
- * wmb(): Guarantees that all preceding stores to memory-
- * like regions are visible before any subsequent
- * stores and that all following stores will be
- * visible only after all previous stores.
- * rmb(): Like wmb(), but for reads.
- * mb(): wmb()/rmb() combo, i.e., all previous memory
- * accesses are visible before all subsequent
- * accesses and vice versa. This is also known as
- * a "fence."
- *
- * Note: "mb()" and its variants cannot be used as a fence to order
- * accesses to memory mapped I/O registers. For that, mf.a needs to
- * be used. However, we don't want to always use mf.a because (a)
- * it's (presumably) much slower than mf and (b) mf.a is supported for
- * sequential memory pages only.
- */
-
-#define mb() ia64_mf()
-#define rmb() mb()
-#define wmb() mb()
-
-#define smp_store_release(p, v) \
-do { \
- barrier(); \
- WRITE_ONCE(*p, v); \
-} while (0)
-
-#define smp_load_acquire(p) \
-({ \
- typeof(*p) ___p1 = READ_ONCE(*p); \
- barrier(); \
- ___p1; \
-})
-
-#endif /* _TOOLS_LINUX_ASM_IA64_BARRIER_H */
diff --git a/tools/arch/ia64/include/uapi/asm/bitsperlong.h b/tools/arch/ia64/include/uapi/asm/bitsperlong.h
deleted file mode 100644
index 1146d55563db..000000000000
--- a/tools/arch/ia64/include/uapi/asm/bitsperlong.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef __ASM_IA64_BITSPERLONG_H
-#define __ASM_IA64_BITSPERLONG_H
-
-#define __BITS_PER_LONG 64
-
-#include <asm-generic/bitsperlong.h>
-
-#endif /* __ASM_IA64_BITSPERLONG_H */
diff --git a/tools/arch/ia64/include/uapi/asm/mman.h b/tools/arch/ia64/include/uapi/asm/mman.h
deleted file mode 100644
index 2a19bb1db4ab..000000000000
--- a/tools/arch/ia64/include/uapi/asm/mman.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H
-#define TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H
-#include <uapi/asm-generic/mman.h>
-/* MAP_32BIT is undefined on ia64, fix it for perf */
-#define MAP_32BIT 0
-#endif
diff --git a/tools/include/io_uring/mini_liburing.h b/tools/include/io_uring/mini_liburing.h
new file mode 100644
index 000000000000..9ccb16074eb5
--- /dev/null
+++ b/tools/include/io_uring/mini_liburing.h
@@ -0,0 +1,282 @@
+/* SPDX-License-Identifier: MIT */
+
+#include <linux/io_uring.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+struct io_sq_ring {
+ unsigned int *head;
+ unsigned int *tail;
+ unsigned int *ring_mask;
+ unsigned int *ring_entries;
+ unsigned int *flags;
+ unsigned int *array;
+};
+
+struct io_cq_ring {
+ unsigned int *head;
+ unsigned int *tail;
+ unsigned int *ring_mask;
+ unsigned int *ring_entries;
+ struct io_uring_cqe *cqes;
+};
+
+struct io_uring_sq {
+ unsigned int *khead;
+ unsigned int *ktail;
+ unsigned int *kring_mask;
+ unsigned int *kring_entries;
+ unsigned int *kflags;
+ unsigned int *kdropped;
+ unsigned int *array;
+ struct io_uring_sqe *sqes;
+
+ unsigned int sqe_head;
+ unsigned int sqe_tail;
+
+ size_t ring_sz;
+};
+
+struct io_uring_cq {
+ unsigned int *khead;
+ unsigned int *ktail;
+ unsigned int *kring_mask;
+ unsigned int *kring_entries;
+ unsigned int *koverflow;
+ struct io_uring_cqe *cqes;
+
+ size_t ring_sz;
+};
+
+struct io_uring {
+ struct io_uring_sq sq;
+ struct io_uring_cq cq;
+ int ring_fd;
+};
+
+#if defined(__x86_64) || defined(__i386__)
+#define read_barrier() __asm__ __volatile__("":::"memory")
+#define write_barrier() __asm__ __volatile__("":::"memory")
+#else
+#define read_barrier() __sync_synchronize()
+#define write_barrier() __sync_synchronize()
+#endif
+
+static inline int io_uring_mmap(int fd, struct io_uring_params *p,
+ struct io_uring_sq *sq, struct io_uring_cq *cq)
+{
+ size_t size;
+ void *ptr;
+ int ret;
+
+ sq->ring_sz = p->sq_off.array + p->sq_entries * sizeof(unsigned int);
+ ptr = mmap(0, sq->ring_sz, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_POPULATE, fd, IORING_OFF_SQ_RING);
+ if (ptr == MAP_FAILED)
+ return -errno;
+ sq->khead = ptr + p->sq_off.head;
+ sq->ktail = ptr + p->sq_off.tail;
+ sq->kring_mask = ptr + p->sq_off.ring_mask;
+ sq->kring_entries = ptr + p->sq_off.ring_entries;
+ sq->kflags = ptr + p->sq_off.flags;
+ sq->kdropped = ptr + p->sq_off.dropped;
+ sq->array = ptr + p->sq_off.array;
+
+ size = p->sq_entries * sizeof(struct io_uring_sqe);
+ sq->sqes = mmap(0, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_POPULATE, fd, IORING_OFF_SQES);
+ if (sq->sqes == MAP_FAILED) {
+ ret = -errno;
+err:
+ munmap(sq->khead, sq->ring_sz);
+ return ret;
+ }
+
+ cq->ring_sz = p->cq_off.cqes + p->cq_entries * sizeof(struct io_uring_cqe);
+ ptr = mmap(0, cq->ring_sz, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_POPULATE, fd, IORING_OFF_CQ_RING);
+ if (ptr == MAP_FAILED) {
+ ret = -errno;
+ munmap(sq->sqes, p->sq_entries * sizeof(struct io_uring_sqe));
+ goto err;
+ }
+ cq->khead = ptr + p->cq_off.head;
+ cq->ktail = ptr + p->cq_off.tail;
+ cq->kring_mask = ptr + p->cq_off.ring_mask;
+ cq->kring_entries = ptr + p->cq_off.ring_entries;
+ cq->koverflow = ptr + p->cq_off.overflow;
+ cq->cqes = ptr + p->cq_off.cqes;
+ return 0;
+}
+
+static inline int io_uring_setup(unsigned int entries,
+ struct io_uring_params *p)
+{
+ return syscall(__NR_io_uring_setup, entries, p);
+}
+
+static inline int io_uring_enter(int fd, unsigned int to_submit,
+ unsigned int min_complete,
+ unsigned int flags, sigset_t *sig)
+{
+ return syscall(__NR_io_uring_enter, fd, to_submit, min_complete,
+ flags, sig, _NSIG / 8);
+}
+
+static inline int io_uring_queue_init(unsigned int entries,
+ struct io_uring *ring,
+ unsigned int flags)
+{
+ struct io_uring_params p;
+ int fd, ret;
+
+ memset(ring, 0, sizeof(*ring));
+ memset(&p, 0, sizeof(p));
+ p.flags = flags;
+
+ fd = io_uring_setup(entries, &p);
+ if (fd < 0)
+ return fd;
+ ret = io_uring_mmap(fd, &p, &ring->sq, &ring->cq);
+ if (!ret)
+ ring->ring_fd = fd;
+ else
+ close(fd);
+ return ret;
+}
+
+/* Get a sqe */
+static inline struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring)
+{
+ struct io_uring_sq *sq = &ring->sq;
+
+ if (sq->sqe_tail + 1 - sq->sqe_head > *sq->kring_entries)
+ return NULL;
+ return &sq->sqes[sq->sqe_tail++ & *sq->kring_mask];
+}
+
+static inline int io_uring_wait_cqe(struct io_uring *ring,
+ struct io_uring_cqe **cqe_ptr)
+{
+ struct io_uring_cq *cq = &ring->cq;
+ const unsigned int mask = *cq->kring_mask;
+ unsigned int head = *cq->khead;
+ int ret;
+
+ *cqe_ptr = NULL;
+ do {
+ read_barrier();
+ if (head != *cq->ktail) {
+ *cqe_ptr = &cq->cqes[head & mask];
+ break;
+ }
+ ret = io_uring_enter(ring->ring_fd, 0, 1,
+ IORING_ENTER_GETEVENTS, NULL);
+ if (ret < 0)
+ return -errno;
+ } while (1);
+
+ return 0;
+}
+
+static inline int io_uring_submit(struct io_uring *ring)
+{
+ struct io_uring_sq *sq = &ring->sq;
+ const unsigned int mask = *sq->kring_mask;
+ unsigned int ktail, submitted, to_submit;
+ int ret;
+
+ read_barrier();
+ if (*sq->khead != *sq->ktail) {
+ submitted = *sq->kring_entries;
+ goto submit;
+ }
+ if (sq->sqe_head == sq->sqe_tail)
+ return 0;
+
+ ktail = *sq->ktail;
+ to_submit = sq->sqe_tail - sq->sqe_head;
+ for (submitted = 0; submitted < to_submit; submitted++) {
+ read_barrier();
+ sq->array[ktail++ & mask] = sq->sqe_head++ & mask;
+ }
+ if (!submitted)
+ return 0;
+
+ if (*sq->ktail != ktail) {
+ write_barrier();
+ *sq->ktail = ktail;
+ write_barrier();
+ }
+submit:
+ ret = io_uring_enter(ring->ring_fd, submitted, 0,
+ IORING_ENTER_GETEVENTS, NULL);
+ return ret < 0 ? -errno : ret;
+}
+
+static inline void io_uring_queue_exit(struct io_uring *ring)
+{
+ struct io_uring_sq *sq = &ring->sq;
+
+ munmap(sq->sqes, *sq->kring_entries * sizeof(struct io_uring_sqe));
+ munmap(sq->khead, sq->ring_sz);
+ close(ring->ring_fd);
+}
+
+/* Prepare and send the SQE */
+static inline void io_uring_prep_cmd(struct io_uring_sqe *sqe, int op,
+ int sockfd,
+ int level, int optname,
+ const void *optval,
+ int optlen)
+{
+ memset(sqe, 0, sizeof(*sqe));
+ sqe->opcode = (__u8)IORING_OP_URING_CMD;
+ sqe->fd = sockfd;
+ sqe->cmd_op = op;
+
+ sqe->level = level;
+ sqe->optname = optname;
+ sqe->optval = (unsigned long long)optval;
+ sqe->optlen = optlen;
+}
+
+static inline int io_uring_register_buffers(struct io_uring *ring,
+ const struct iovec *iovecs,
+ unsigned int nr_iovecs)
+{
+ int ret;
+
+ ret = syscall(__NR_io_uring_register, ring->ring_fd,
+ IORING_REGISTER_BUFFERS, iovecs, nr_iovecs);
+ return (ret < 0) ? -errno : ret;
+}
+
+static inline void io_uring_prep_send(struct io_uring_sqe *sqe, int sockfd,
+ const void *buf, size_t len, int flags)
+{
+ memset(sqe, 0, sizeof(*sqe));
+ sqe->opcode = (__u8)IORING_OP_SEND;
+ sqe->fd = sockfd;
+ sqe->addr = (unsigned long)buf;
+ sqe->len = len;
+ sqe->msg_flags = (__u32)flags;
+}
+
+static inline void io_uring_prep_sendzc(struct io_uring_sqe *sqe, int sockfd,
+ const void *buf, size_t len, int flags,
+ unsigned int zc_flags)
+{
+ io_uring_prep_send(sqe, sockfd, buf, len, flags);
+ sqe->opcode = (__u8)IORING_OP_SEND_ZC;
+ sqe->ioprio = zc_flags;
+}
+
+static inline void io_uring_cqe_seen(struct io_uring *ring)
+{
+ *(&ring->cq)->khead += 1;
+ write_barrier();
+}
diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h
index abe087c53b4b..76d946445391 100644
--- a/tools/include/uapi/asm-generic/unistd.h
+++ b/tools/include/uapi/asm-generic/unistd.h
@@ -71,7 +71,7 @@ __SYSCALL(__NR_fremovexattr, sys_fremovexattr)
#define __NR_getcwd 17
__SYSCALL(__NR_getcwd, sys_getcwd)
#define __NR_lookup_dcookie 18
-__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
+__SYSCALL(__NR_lookup_dcookie, sys_ni_syscall)
#define __NR_eventfd2 19
__SYSCALL(__NR_eventfd2, sys_eventfd2)
#define __NR_epoll_create1 20
diff --git a/tools/include/uapi/linux/io_uring.h b/tools/include/uapi/linux/io_uring.h
new file mode 100644
index 000000000000..f1c16f817742
--- /dev/null
+++ b/tools/include/uapi/linux/io_uring.h
@@ -0,0 +1,757 @@
+/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */
+/*
+ * Header file for the io_uring interface.
+ *
+ * Copyright (C) 2019 Jens Axboe
+ * Copyright (C) 2019 Christoph Hellwig
+ */
+#ifndef LINUX_IO_URING_H
+#define LINUX_IO_URING_H
+
+#include <linux/fs.h>
+#include <linux/types.h>
+/*
+ * this file is shared with liburing and that has to autodetect
+ * if linux/time_types.h is available or not, it can
+ * define UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H
+ * if linux/time_types.h is not available
+ */
+#ifndef UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H
+#include <linux/time_types.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * IO submission data structure (Submission Queue Entry)
+ */
+struct io_uring_sqe {
+ __u8 opcode; /* type of operation for this sqe */
+ __u8 flags; /* IOSQE_ flags */
+ __u16 ioprio; /* ioprio for the request */
+ __s32 fd; /* file descriptor to do IO on */
+ union {
+ __u64 off; /* offset into file */
+ __u64 addr2;
+ struct {
+ __u32 cmd_op;
+ __u32 __pad1;
+ };
+ };
+ union {
+ __u64 addr; /* pointer to buffer or iovecs */
+ __u64 splice_off_in;
+ struct {
+ __u32 level;
+ __u32 optname;
+ };
+ };
+ __u32 len; /* buffer size or number of iovecs */
+ union {
+ __kernel_rwf_t rw_flags;
+ __u32 fsync_flags;
+ __u16 poll_events; /* compatibility */
+ __u32 poll32_events; /* word-reversed for BE */
+ __u32 sync_range_flags;
+ __u32 msg_flags;
+ __u32 timeout_flags;
+ __u32 accept_flags;
+ __u32 cancel_flags;
+ __u32 open_flags;
+ __u32 statx_flags;
+ __u32 fadvise_advice;
+ __u32 splice_flags;
+ __u32 rename_flags;
+ __u32 unlink_flags;
+ __u32 hardlink_flags;
+ __u32 xattr_flags;
+ __u32 msg_ring_flags;
+ __u32 uring_cmd_flags;
+ __u32 waitid_flags;
+ __u32 futex_flags;
+ };
+ __u64 user_data; /* data to be passed back at completion time */
+ /* pack this to avoid bogus arm OABI complaints */
+ union {
+ /* index into fixed buffers, if used */
+ __u16 buf_index;
+ /* for grouped buffer selection */
+ __u16 buf_group;
+ } __attribute__((packed));
+ /* personality to use, if used */
+ __u16 personality;
+ union {
+ __s32 splice_fd_in;
+ __u32 file_index;
+ __u32 optlen;
+ struct {
+ __u16 addr_len;
+ __u16 __pad3[1];
+ };
+ };
+ union {
+ struct {
+ __u64 addr3;
+ __u64 __pad2[1];
+ };
+ __u64 optval;
+ /*
+ * If the ring is initialized with IORING_SETUP_SQE128, then
+ * this field is used for 80 bytes of arbitrary command data
+ */
+ __u8 cmd[0];
+ };
+};
+
+/*
+ * If sqe->file_index is set to this for opcodes that instantiate a new
+ * direct descriptor (like openat/openat2/accept), then io_uring will allocate
+ * an available direct descriptor instead of having the application pass one
+ * in. The picked direct descriptor will be returned in cqe->res, or -ENFILE
+ * if the space is full.
+ */
+#define IORING_FILE_INDEX_ALLOC (~0U)
+
+enum {
+ IOSQE_FIXED_FILE_BIT,
+ IOSQE_IO_DRAIN_BIT,
+ IOSQE_IO_LINK_BIT,
+ IOSQE_IO_HARDLINK_BIT,
+ IOSQE_ASYNC_BIT,
+ IOSQE_BUFFER_SELECT_BIT,
+ IOSQE_CQE_SKIP_SUCCESS_BIT,
+};
+
+/*
+ * sqe->flags
+ */
+/* use fixed fileset */
+#define IOSQE_FIXED_FILE (1U << IOSQE_FIXED_FILE_BIT)
+/* issue after inflight IO */
+#define IOSQE_IO_DRAIN (1U << IOSQE_IO_DRAIN_BIT)
+/* links next sqe */
+#define IOSQE_IO_LINK (1U << IOSQE_IO_LINK_BIT)
+/* like LINK, but stronger */
+#define IOSQE_IO_HARDLINK (1U << IOSQE_IO_HARDLINK_BIT)
+/* always go async */
+#define IOSQE_ASYNC (1U << IOSQE_ASYNC_BIT)
+/* select buffer from sqe->buf_group */
+#define IOSQE_BUFFER_SELECT (1U << IOSQE_BUFFER_SELECT_BIT)
+/* don't post CQE if request succeeded */
+#define IOSQE_CQE_SKIP_SUCCESS (1U << IOSQE_CQE_SKIP_SUCCESS_BIT)
+
+/*
+ * io_uring_setup() flags
+ */
+#define IORING_SETUP_IOPOLL (1U << 0) /* io_context is polled */
+#define IORING_SETUP_SQPOLL (1U << 1) /* SQ poll thread */
+#define IORING_SETUP_SQ_AFF (1U << 2) /* sq_thread_cpu is valid */
+#define IORING_SETUP_CQSIZE (1U << 3) /* app defines CQ size */
+#define IORING_SETUP_CLAMP (1U << 4) /* clamp SQ/CQ ring sizes */
+#define IORING_SETUP_ATTACH_WQ (1U << 5) /* attach to existing wq */
+#define IORING_SETUP_R_DISABLED (1U << 6) /* start with ring disabled */
+#define IORING_SETUP_SUBMIT_ALL (1U << 7) /* continue submit on error */
+/*
+ * Cooperative task running. When requests complete, they often require
+ * forcing the submitter to transition to the kernel to complete. If this
+ * flag is set, work will be done when the task transitions anyway, rather
+ * than force an inter-processor interrupt reschedule. This avoids interrupting
+ * a task running in userspace, and saves an IPI.
+ */
+#define IORING_SETUP_COOP_TASKRUN (1U << 8)
+/*
+ * If COOP_TASKRUN is set, get notified if task work is available for
+ * running and a kernel transition would be needed to run it. This sets
+ * IORING_SQ_TASKRUN in the sq ring flags. Not valid with COOP_TASKRUN.
+ */
+#define IORING_SETUP_TASKRUN_FLAG (1U << 9)
+#define IORING_SETUP_SQE128 (1U << 10) /* SQEs are 128 byte */
+#define IORING_SETUP_CQE32 (1U << 11) /* CQEs are 32 byte */
+/*
+ * Only one task is allowed to submit requests
+ */
+#define IORING_SETUP_SINGLE_ISSUER (1U << 12)
+
+/*
+ * Defer running task work to get events.
+ * Rather than running bits of task work whenever the task transitions
+ * try to do it just before it is needed.
+ */
+#define IORING_SETUP_DEFER_TASKRUN (1U << 13)
+
+/*
+ * Application provides the memory for the rings
+ */
+#define IORING_SETUP_NO_MMAP (1U << 14)
+
+/*
+ * Register the ring fd in itself for use with
+ * IORING_REGISTER_USE_REGISTERED_RING; return a registered fd index rather
+ * than an fd.
+ */
+#define IORING_SETUP_REGISTERED_FD_ONLY (1U << 15)
+
+/*
+ * Removes indirection through the SQ index array.
+ */
+#define IORING_SETUP_NO_SQARRAY (1U << 16)
+
+enum io_uring_op {
+ IORING_OP_NOP,
+ IORING_OP_READV,
+ IORING_OP_WRITEV,
+ IORING_OP_FSYNC,
+ IORING_OP_READ_FIXED,
+ IORING_OP_WRITE_FIXED,
+ IORING_OP_POLL_ADD,
+ IORING_OP_POLL_REMOVE,
+ IORING_OP_SYNC_FILE_RANGE,
+ IORING_OP_SENDMSG,
+ IORING_OP_RECVMSG,
+ IORING_OP_TIMEOUT,
+ IORING_OP_TIMEOUT_REMOVE,
+ IORING_OP_ACCEPT,
+ IORING_OP_ASYNC_CANCEL,
+ IORING_OP_LINK_TIMEOUT,
+ IORING_OP_CONNECT,
+ IORING_OP_FALLOCATE,
+ IORING_OP_OPENAT,
+ IORING_OP_CLOSE,
+ IORING_OP_FILES_UPDATE,
+ IORING_OP_STATX,
+ IORING_OP_READ,
+ IORING_OP_WRITE,
+ IORING_OP_FADVISE,
+ IORING_OP_MADVISE,
+ IORING_OP_SEND,
+ IORING_OP_RECV,
+ IORING_OP_OPENAT2,
+ IORING_OP_EPOLL_CTL,
+ IORING_OP_SPLICE,
+ IORING_OP_PROVIDE_BUFFERS,
+ IORING_OP_REMOVE_BUFFERS,
+ IORING_OP_TEE,
+ IORING_OP_SHUTDOWN,
+ IORING_OP_RENAMEAT,
+ IORING_OP_UNLINKAT,
+ IORING_OP_MKDIRAT,
+ IORING_OP_SYMLINKAT,
+ IORING_OP_LINKAT,
+ IORING_OP_MSG_RING,
+ IORING_OP_FSETXATTR,
+ IORING_OP_SETXATTR,
+ IORING_OP_FGETXATTR,
+ IORING_OP_GETXATTR,
+ IORING_OP_SOCKET,
+ IORING_OP_URING_CMD,
+ IORING_OP_SEND_ZC,
+ IORING_OP_SENDMSG_ZC,
+ IORING_OP_READ_MULTISHOT,
+ IORING_OP_WAITID,
+ IORING_OP_FUTEX_WAIT,
+ IORING_OP_FUTEX_WAKE,
+ IORING_OP_FUTEX_WAITV,
+
+ /* this goes last, obviously */
+ IORING_OP_LAST,
+};
+
+/*
+ * sqe->uring_cmd_flags top 8bits aren't available for userspace
+ * IORING_URING_CMD_FIXED use registered buffer; pass this flag
+ * along with setting sqe->buf_index.
+ */
+#define IORING_URING_CMD_FIXED (1U << 0)
+#define IORING_URING_CMD_MASK IORING_URING_CMD_FIXED
+
+
+/*
+ * sqe->fsync_flags
+ */
+#define IORING_FSYNC_DATASYNC (1U << 0)
+
+/*
+ * sqe->timeout_flags
+ */
+#define IORING_TIMEOUT_ABS (1U << 0)
+#define IORING_TIMEOUT_UPDATE (1U << 1)
+#define IORING_TIMEOUT_BOOTTIME (1U << 2)
+#define IORING_TIMEOUT_REALTIME (1U << 3)
+#define IORING_LINK_TIMEOUT_UPDATE (1U << 4)
+#define IORING_TIMEOUT_ETIME_SUCCESS (1U << 5)
+#define IORING_TIMEOUT_MULTISHOT (1U << 6)
+#define IORING_TIMEOUT_CLOCK_MASK (IORING_TIMEOUT_BOOTTIME | IORING_TIMEOUT_REALTIME)
+#define IORING_TIMEOUT_UPDATE_MASK (IORING_TIMEOUT_UPDATE | IORING_LINK_TIMEOUT_UPDATE)
+/*
+ * sqe->splice_flags
+ * extends splice(2) flags
+ */
+#define SPLICE_F_FD_IN_FIXED (1U << 31) /* the last bit of __u32 */
+
+/*
+ * POLL_ADD flags. Note that since sqe->poll_events is the flag space, the
+ * command flags for POLL_ADD are stored in sqe->len.
+ *
+ * IORING_POLL_ADD_MULTI Multishot poll. Sets IORING_CQE_F_MORE if
+ * the poll handler will continue to report
+ * CQEs on behalf of the same SQE.
+ *
+ * IORING_POLL_UPDATE Update existing poll request, matching
+ * sqe->addr as the old user_data field.
+ *
+ * IORING_POLL_LEVEL Level triggered poll.
+ */
+#define IORING_POLL_ADD_MULTI (1U << 0)
+#define IORING_POLL_UPDATE_EVENTS (1U << 1)
+#define IORING_POLL_UPDATE_USER_DATA (1U << 2)
+#define IORING_POLL_ADD_LEVEL (1U << 3)
+
+/*
+ * ASYNC_CANCEL flags.
+ *
+ * IORING_ASYNC_CANCEL_ALL Cancel all requests that match the given key
+ * IORING_ASYNC_CANCEL_FD Key off 'fd' for cancelation rather than the
+ * request 'user_data'
+ * IORING_ASYNC_CANCEL_ANY Match any request
+ * IORING_ASYNC_CANCEL_FD_FIXED 'fd' passed in is a fixed descriptor
+ * IORING_ASYNC_CANCEL_USERDATA Match on user_data, default for no other key
+ * IORING_ASYNC_CANCEL_OP Match request based on opcode
+ */
+#define IORING_ASYNC_CANCEL_ALL (1U << 0)
+#define IORING_ASYNC_CANCEL_FD (1U << 1)
+#define IORING_ASYNC_CANCEL_ANY (1U << 2)
+#define IORING_ASYNC_CANCEL_FD_FIXED (1U << 3)
+#define IORING_ASYNC_CANCEL_USERDATA (1U << 4)
+#define IORING_ASYNC_CANCEL_OP (1U << 5)
+
+/*
+ * send/sendmsg and recv/recvmsg flags (sqe->ioprio)
+ *
+ * IORING_RECVSEND_POLL_FIRST If set, instead of first attempting to send
+ * or receive and arm poll if that yields an
+ * -EAGAIN result, arm poll upfront and skip
+ * the initial transfer attempt.
+ *
+ * IORING_RECV_MULTISHOT Multishot recv. Sets IORING_CQE_F_MORE if
+ * the handler will continue to report
+ * CQEs on behalf of the same SQE.
+ *
+ * IORING_RECVSEND_FIXED_BUF Use registered buffers, the index is stored in
+ * the buf_index field.
+ *
+ * IORING_SEND_ZC_REPORT_USAGE
+ * If set, SEND[MSG]_ZC should report
+ * the zerocopy usage in cqe.res
+ * for the IORING_CQE_F_NOTIF cqe.
+ * 0 is reported if zerocopy was actually possible.
+ * IORING_NOTIF_USAGE_ZC_COPIED if data was copied
+ * (at least partially).
+ */
+#define IORING_RECVSEND_POLL_FIRST (1U << 0)
+#define IORING_RECV_MULTISHOT (1U << 1)
+#define IORING_RECVSEND_FIXED_BUF (1U << 2)
+#define IORING_SEND_ZC_REPORT_USAGE (1U << 3)
+
+/*
+ * cqe.res for IORING_CQE_F_NOTIF if
+ * IORING_SEND_ZC_REPORT_USAGE was requested
+ *
+ * It should be treated as a flag, all other
+ * bits of cqe.res should be treated as reserved!
+ */
+#define IORING_NOTIF_USAGE_ZC_COPIED (1U << 31)
+
+/*
+ * accept flags stored in sqe->ioprio
+ */
+#define IORING_ACCEPT_MULTISHOT (1U << 0)
+
+/*
+ * IORING_OP_MSG_RING command types, stored in sqe->addr
+ */
+enum {
+ IORING_MSG_DATA, /* pass sqe->len as 'res' and off as user_data */
+ IORING_MSG_SEND_FD, /* send a registered fd to another ring */
+};
+
+/*
+ * IORING_OP_MSG_RING flags (sqe->msg_ring_flags)
+ *
+ * IORING_MSG_RING_CQE_SKIP Don't post a CQE to the target ring. Not
+ * applicable for IORING_MSG_DATA, obviously.
+ */
+#define IORING_MSG_RING_CQE_SKIP (1U << 0)
+/* Pass through the flags from sqe->file_index to cqe->flags */
+#define IORING_MSG_RING_FLAGS_PASS (1U << 1)
+
+/*
+ * IO completion data structure (Completion Queue Entry)
+ */
+struct io_uring_cqe {
+ __u64 user_data; /* sqe->data submission passed back */
+ __s32 res; /* result code for this event */
+ __u32 flags;
+
+ /*
+ * If the ring is initialized with IORING_SETUP_CQE32, then this field
+ * contains 16-bytes of padding, doubling the size of the CQE.
+ */
+ __u64 big_cqe[];
+};
+
+/*
+ * cqe->flags
+ *
+ * IORING_CQE_F_BUFFER If set, the upper 16 bits are the buffer ID
+ * IORING_CQE_F_MORE If set, parent SQE will generate more CQE entries
+ * IORING_CQE_F_SOCK_NONEMPTY If set, more data to read after socket recv
+ * IORING_CQE_F_NOTIF Set for notification CQEs. Can be used to distinct
+ * them from sends.
+ */
+#define IORING_CQE_F_BUFFER (1U << 0)
+#define IORING_CQE_F_MORE (1U << 1)
+#define IORING_CQE_F_SOCK_NONEMPTY (1U << 2)
+#define IORING_CQE_F_NOTIF (1U << 3)
+
+enum {
+ IORING_CQE_BUFFER_SHIFT = 16,
+};
+
+/*
+ * Magic offsets for the application to mmap the data it needs
+ */
+#define IORING_OFF_SQ_RING 0ULL
+#define IORING_OFF_CQ_RING 0x8000000ULL
+#define IORING_OFF_SQES 0x10000000ULL
+#define IORING_OFF_PBUF_RING 0x80000000ULL
+#define IORING_OFF_PBUF_SHIFT 16
+#define IORING_OFF_MMAP_MASK 0xf8000000ULL
+
+/*
+ * Filled with the offset for mmap(2)
+ */
+struct io_sqring_offsets {
+ __u32 head;
+ __u32 tail;
+ __u32 ring_mask;
+ __u32 ring_entries;
+ __u32 flags;
+ __u32 dropped;
+ __u32 array;
+ __u32 resv1;
+ __u64 user_addr;
+};
+
+/*
+ * sq_ring->flags
+ */
+#define IORING_SQ_NEED_WAKEUP (1U << 0) /* needs io_uring_enter wakeup */
+#define IORING_SQ_CQ_OVERFLOW (1U << 1) /* CQ ring is overflown */
+#define IORING_SQ_TASKRUN (1U << 2) /* task should enter the kernel */
+
+struct io_cqring_offsets {
+ __u32 head;
+ __u32 tail;
+ __u32 ring_mask;
+ __u32 ring_entries;
+ __u32 overflow;
+ __u32 cqes;
+ __u32 flags;
+ __u32 resv1;
+ __u64 user_addr;
+};
+
+/*
+ * cq_ring->flags
+ */
+
+/* disable eventfd notifications */
+#define IORING_CQ_EVENTFD_DISABLED (1U << 0)
+
+/*
+ * io_uring_enter(2) flags
+ */
+#define IORING_ENTER_GETEVENTS (1U << 0)
+#define IORING_ENTER_SQ_WAKEUP (1U << 1)
+#define IORING_ENTER_SQ_WAIT (1U << 2)
+#define IORING_ENTER_EXT_ARG (1U << 3)
+#define IORING_ENTER_REGISTERED_RING (1U << 4)
+
+/*
+ * Passed in for io_uring_setup(2). Copied back with updated info on success
+ */
+struct io_uring_params {
+ __u32 sq_entries;
+ __u32 cq_entries;
+ __u32 flags;
+ __u32 sq_thread_cpu;
+ __u32 sq_thread_idle;
+ __u32 features;
+ __u32 wq_fd;
+ __u32 resv[3];
+ struct io_sqring_offsets sq_off;
+ struct io_cqring_offsets cq_off;
+};
+
+/*
+ * io_uring_params->features flags
+ */
+#define IORING_FEAT_SINGLE_MMAP (1U << 0)
+#define IORING_FEAT_NODROP (1U << 1)
+#define IORING_FEAT_SUBMIT_STABLE (1U << 2)
+#define IORING_FEAT_RW_CUR_POS (1U << 3)
+#define IORING_FEAT_CUR_PERSONALITY (1U << 4)
+#define IORING_FEAT_FAST_POLL (1U << 5)
+#define IORING_FEAT_POLL_32BITS (1U << 6)
+#define IORING_FEAT_SQPOLL_NONFIXED (1U << 7)
+#define IORING_FEAT_EXT_ARG (1U << 8)
+#define IORING_FEAT_NATIVE_WORKERS (1U << 9)
+#define IORING_FEAT_RSRC_TAGS (1U << 10)
+#define IORING_FEAT_CQE_SKIP (1U << 11)
+#define IORING_FEAT_LINKED_FILE (1U << 12)
+#define IORING_FEAT_REG_REG_RING (1U << 13)
+
+/*
+ * io_uring_register(2) opcodes and arguments
+ */
+enum {
+ IORING_REGISTER_BUFFERS = 0,
+ IORING_UNREGISTER_BUFFERS = 1,
+ IORING_REGISTER_FILES = 2,
+ IORING_UNREGISTER_FILES = 3,
+ IORING_REGISTER_EVENTFD = 4,
+ IORING_UNREGISTER_EVENTFD = 5,
+ IORING_REGISTER_FILES_UPDATE = 6,
+ IORING_REGISTER_EVENTFD_ASYNC = 7,
+ IORING_REGISTER_PROBE = 8,
+ IORING_REGISTER_PERSONALITY = 9,
+ IORING_UNREGISTER_PERSONALITY = 10,
+ IORING_REGISTER_RESTRICTIONS = 11,
+ IORING_REGISTER_ENABLE_RINGS = 12,
+
+ /* extended with tagging */
+ IORING_REGISTER_FILES2 = 13,
+ IORING_REGISTER_FILES_UPDATE2 = 14,
+ IORING_REGISTER_BUFFERS2 = 15,
+ IORING_REGISTER_BUFFERS_UPDATE = 16,
+
+ /* set/clear io-wq thread affinities */
+ IORING_REGISTER_IOWQ_AFF = 17,
+ IORING_UNREGISTER_IOWQ_AFF = 18,
+
+ /* set/get max number of io-wq workers */
+ IORING_REGISTER_IOWQ_MAX_WORKERS = 19,
+
+ /* register/unregister io_uring fd with the ring */
+ IORING_REGISTER_RING_FDS = 20,
+ IORING_UNREGISTER_RING_FDS = 21,
+
+ /* register ring based provide buffer group */
+ IORING_REGISTER_PBUF_RING = 22,
+ IORING_UNREGISTER_PBUF_RING = 23,
+
+ /* sync cancelation API */
+ IORING_REGISTER_SYNC_CANCEL = 24,
+
+ /* register a range of fixed file slots for automatic slot allocation */
+ IORING_REGISTER_FILE_ALLOC_RANGE = 25,
+
+ /* this goes last */
+ IORING_REGISTER_LAST,
+
+ /* flag added to the opcode to use a registered ring fd */
+ IORING_REGISTER_USE_REGISTERED_RING = 1U << 31
+};
+
+/* io-wq worker categories */
+enum {
+ IO_WQ_BOUND,
+ IO_WQ_UNBOUND,
+};
+
+/* deprecated, see struct io_uring_rsrc_update */
+struct io_uring_files_update {
+ __u32 offset;
+ __u32 resv;
+ __aligned_u64 /* __s32 * */ fds;
+};
+
+/*
+ * Register a fully sparse file space, rather than pass in an array of all
+ * -1 file descriptors.
+ */
+#define IORING_RSRC_REGISTER_SPARSE (1U << 0)
+
+struct io_uring_rsrc_register {
+ __u32 nr;
+ __u32 flags;
+ __u64 resv2;
+ __aligned_u64 data;
+ __aligned_u64 tags;
+};
+
+struct io_uring_rsrc_update {
+ __u32 offset;
+ __u32 resv;
+ __aligned_u64 data;
+};
+
+struct io_uring_rsrc_update2 {
+ __u32 offset;
+ __u32 resv;
+ __aligned_u64 data;
+ __aligned_u64 tags;
+ __u32 nr;
+ __u32 resv2;
+};
+
+/* Skip updating fd indexes set to this value in the fd table */
+#define IORING_REGISTER_FILES_SKIP (-2)
+
+#define IO_URING_OP_SUPPORTED (1U << 0)
+
+struct io_uring_probe_op {
+ __u8 op;
+ __u8 resv;
+ __u16 flags; /* IO_URING_OP_* flags */
+ __u32 resv2;
+};
+
+struct io_uring_probe {
+ __u8 last_op; /* last opcode supported */
+ __u8 ops_len; /* length of ops[] array below */
+ __u16 resv;
+ __u32 resv2[3];
+ struct io_uring_probe_op ops[];
+};
+
+struct io_uring_restriction {
+ __u16 opcode;
+ union {
+ __u8 register_op; /* IORING_RESTRICTION_REGISTER_OP */
+ __u8 sqe_op; /* IORING_RESTRICTION_SQE_OP */
+ __u8 sqe_flags; /* IORING_RESTRICTION_SQE_FLAGS_* */
+ };
+ __u8 resv;
+ __u32 resv2[3];
+};
+
+struct io_uring_buf {
+ __u64 addr;
+ __u32 len;
+ __u16 bid;
+ __u16 resv;
+};
+
+struct io_uring_buf_ring {
+ union {
+ /*
+ * To avoid spilling into more pages than we need to, the
+ * ring tail is overlaid with the io_uring_buf->resv field.
+ */
+ struct {
+ __u64 resv1;
+ __u32 resv2;
+ __u16 resv3;
+ __u16 tail;
+ };
+ __DECLARE_FLEX_ARRAY(struct io_uring_buf, bufs);
+ };
+};
+
+/*
+ * Flags for IORING_REGISTER_PBUF_RING.
+ *
+ * IOU_PBUF_RING_MMAP: If set, kernel will allocate the memory for the ring.
+ * The application must not set a ring_addr in struct
+ * io_uring_buf_reg, instead it must subsequently call
+ * mmap(2) with the offset set as:
+ * IORING_OFF_PBUF_RING | (bgid << IORING_OFF_PBUF_SHIFT)
+ * to get a virtual mapping for the ring.
+ */
+enum {
+ IOU_PBUF_RING_MMAP = 1,
+};
+
+/* argument for IORING_(UN)REGISTER_PBUF_RING */
+struct io_uring_buf_reg {
+ __u64 ring_addr;
+ __u32 ring_entries;
+ __u16 bgid;
+ __u16 flags;
+ __u64 resv[3];
+};
+
+/*
+ * io_uring_restriction->opcode values
+ */
+enum {
+ /* Allow an io_uring_register(2) opcode */
+ IORING_RESTRICTION_REGISTER_OP = 0,
+
+ /* Allow an sqe opcode */
+ IORING_RESTRICTION_SQE_OP = 1,
+
+ /* Allow sqe flags */
+ IORING_RESTRICTION_SQE_FLAGS_ALLOWED = 2,
+
+ /* Require sqe flags (these flags must be set on each submission) */
+ IORING_RESTRICTION_SQE_FLAGS_REQUIRED = 3,
+
+ IORING_RESTRICTION_LAST
+};
+
+struct io_uring_getevents_arg {
+ __u64 sigmask;
+ __u32 sigmask_sz;
+ __u32 pad;
+ __u64 ts;
+};
+
+/*
+ * Argument for IORING_REGISTER_SYNC_CANCEL
+ */
+struct io_uring_sync_cancel_reg {
+ __u64 addr;
+ __s32 fd;
+ __u32 flags;
+ struct __kernel_timespec timeout;
+ __u8 opcode;
+ __u8 pad[7];
+ __u64 pad2[3];
+};
+
+/*
+ * Argument for IORING_REGISTER_FILE_ALLOC_RANGE
+ * The range is specified as [off, off + len)
+ */
+struct io_uring_file_index_range {
+ __u32 off;
+ __u32 len;
+ __u64 resv;
+};
+
+struct io_uring_recvmsg_out {
+ __u32 namelen;
+ __u32 controllen;
+ __u32 payloadlen;
+ __u32 flags;
+};
+
+/*
+ * Argument for IORING_OP_URING_CMD when file is a socket
+ */
+enum {
+ SOCKET_URING_OP_SIOCINQ = 0,
+ SOCKET_URING_OP_SIOCOUTQ,
+ SOCKET_URING_OP_GETSOCKOPT,
+ SOCKET_URING_OP_SETSOCKOPT,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/objtool/noreturns.h b/tools/objtool/noreturns.h
index e92f67383dde..649ebdef9c3f 100644
--- a/tools/objtool/noreturns.h
+++ b/tools/objtool/noreturns.h
@@ -11,6 +11,7 @@ NORETURN(__kunit_abort)
NORETURN(__module_put_and_kthread_exit)
NORETURN(__reiserfs_panic)
NORETURN(__stack_chk_fail)
+NORETURN(__tdx_hypercall_failed)
NORETURN(__ubsan_handle_builtin_unreachable)
NORETURN(arch_call_rest_init)
NORETURN(arch_cpu_idle_dead)
diff --git a/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl b/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
index cb5e757f6621..80be0e98ea0c 100644
--- a/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
+++ b/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
@@ -214,7 +214,7 @@
203 n64 io_submit sys_io_submit
204 n64 io_cancel sys_io_cancel
205 n64 exit_group sys_exit_group
-206 n64 lookup_dcookie sys_lookup_dcookie
+206 n64 lookup_dcookie sys_ni_syscall
207 n64 epoll_create sys_epoll_create
208 n64 epoll_ctl sys_epoll_ctl
209 n64 epoll_wait sys_epoll_wait
diff --git a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
index 20e50586e8a2..e1412519b4ad 100644
--- a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
+++ b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
@@ -294,7 +294,7 @@
233 32 fadvise64 sys_ppc32_fadvise64 compat_sys_ppc32_fadvise64
233 64 fadvise64 sys_fadvise64
234 nospu exit_group sys_exit_group
-235 nospu lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie
+235 nospu lookup_dcookie sys_ni_syscall
236 common epoll_create sys_epoll_create
237 common epoll_ctl sys_epoll_ctl
238 common epoll_wait sys_epoll_wait
diff --git a/tools/perf/arch/s390/entry/syscalls/syscall.tbl b/tools/perf/arch/s390/entry/syscalls/syscall.tbl
index 0122cc156952..cc0bc144b661 100644
--- a/tools/perf/arch/s390/entry/syscalls/syscall.tbl
+++ b/tools/perf/arch/s390/entry/syscalls/syscall.tbl
@@ -100,7 +100,7 @@
106 common stat sys_newstat compat_sys_newstat
107 common lstat sys_newlstat compat_sys_newlstat
108 common fstat sys_newfstat compat_sys_newfstat
-110 common lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie
+110 common lookup_dcookie - -
111 common vhangup sys_vhangup sys_vhangup
112 common idle - -
114 common wait4 sys_wait4 compat_sys_wait4
diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
index 1d6eee30eceb..2a62eaf30d69 100644
--- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
@@ -220,7 +220,7 @@
209 64 io_submit sys_io_submit
210 common io_cancel sys_io_cancel
211 64 get_thread_area
-212 common lookup_dcookie sys_lookup_dcookie
+212 common lookup_dcookie
213 common epoll_create sys_epoll_create
214 64 epoll_ctl_old
215 64 epoll_wait_old
diff --git a/tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py b/tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py
index 904df0ea0a1e..feb9f9421c7b 100755
--- a/tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py
+++ b/tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py
@@ -30,8 +30,7 @@ import getopt
import Gnuplot
from numpy import *
from decimal import *
-sys.path.append('../intel_pstate_tracer')
-#import intel_pstate_tracer
+sys.path.append(os.path.join(os.path.dirname(__file__), "..", "intel_pstate_tracer"))
import intel_pstate_tracer as ipt
__license__ = "GPL version 2"
diff --git a/tools/testing/selftests/amd-pstate/gitsource.sh b/tools/testing/selftests/amd-pstate/gitsource.sh
index 5f2171f0116d..4cde62f90468 100755
--- a/tools/testing/selftests/amd-pstate/gitsource.sh
+++ b/tools/testing/selftests/amd-pstate/gitsource.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Testing and monitor the cpu desire performance, frequency, load,
@@ -66,12 +66,15 @@ post_clear_gitsource()
install_gitsource()
{
- if [ ! -d $git_name ]; then
+ if [ ! -d $SCRIPTDIR/$git_name ]; then
+ pushd $(pwd) > /dev/null 2>&1
+ cd $SCRIPTDIR
printf "Download gitsource, please wait a moment ...\n\n"
wget -O $git_tar $gitsource_url > /dev/null 2>&1
printf "Tar gitsource ...\n\n"
tar -xzf $git_tar
+ popd > /dev/null 2>&1
fi
}
@@ -79,12 +82,14 @@ install_gitsource()
run_gitsource()
{
echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
- ./amd_pstate_trace.py -n tracer-gitsource-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
+ $TRACER -n tracer-gitsource-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
printf "Make and test gitsource for $1 #$2 make_cpus: $MAKE_CPUS\n"
- cd $git_name
- perf stat -a --per-socket -I 1000 -e power/energy-pkg/ /usr/bin/time -o ../$OUTFILE_GIT.time-gitsource-$1-$2.log make test -j$MAKE_CPUS > ../$OUTFILE_GIT-perf-$1-$2.log 2>&1
- cd ..
+ BACKUP_DIR=$(pwd)
+ pushd $BACKUP_DIR > /dev/null 2>&1
+ cd $SCRIPTDIR/$git_name
+ $PERF stat -a --per-socket -I 1000 -e power/energy-pkg/ /usr/bin/time -o $BACKUP_DIR/$OUTFILE_GIT.time-gitsource-$1-$2.log make test -j$MAKE_CPUS > $BACKUP_DIR/$OUTFILE_GIT-perf-$1-$2.log 2>&1
+ popd > /dev/null 2>&1
for job in `jobs -p`
do
diff --git a/tools/testing/selftests/amd-pstate/run.sh b/tools/testing/selftests/amd-pstate/run.sh
index de4d8e9c9565..b053eea8bb19 100755
--- a/tools/testing/selftests/amd-pstate/run.sh
+++ b/tools/testing/selftests/amd-pstate/run.sh
@@ -8,9 +8,12 @@ else
FILE_MAIN=DONE
fi
-source basic.sh
-source tbench.sh
-source gitsource.sh
+SCRIPTDIR=`dirname "$0"`
+TRACER=$SCRIPTDIR/../../../power/x86/amd_pstate_tracer/amd_pstate_trace.py
+
+source $SCRIPTDIR/basic.sh
+source $SCRIPTDIR/tbench.sh
+source $SCRIPTDIR/gitsource.sh
# amd-pstate-ut only run on x86/x86_64 AMD systems.
ARCH=$(uname -m 2>/dev/null | sed -e 's/i.86/x86/' -e 's/x86_64/x86/')
@@ -22,6 +25,7 @@ OUTFILE=selftest
OUTFILE_TBENCH="$OUTFILE.tbench"
OUTFILE_GIT="$OUTFILE.gitsource"
+PERF=/usr/bin/perf
SYSFS=
CPUROOT=
CPUFREQROOT=
@@ -151,6 +155,7 @@ help()
[-p <tbench process number>]
[-l <loop times for tbench>]
[-i <amd tracer interval>]
+ [-b <perf binary>]
[-m <comparative test: acpi-cpufreq>]
\n"
exit 2
@@ -158,7 +163,7 @@ help()
parse_arguments()
{
- while getopts ho:c:t:p:l:i:m: arg
+ while getopts ho:c:t:p:l:i:b:m: arg
do
case $arg in
h) # --help
@@ -189,6 +194,10 @@ parse_arguments()
TRACER_INTERVAL=$OPTARG
;;
+ b) # --perf-binary
+ PERF=`realpath $OPTARG`
+ ;;
+
m) # --comparative-test
COMPARATIVE_TEST=$OPTARG
;;
@@ -202,8 +211,8 @@ parse_arguments()
command_perf()
{
- if ! command -v perf > /dev/null; then
- echo $msg please install perf. >&2
+ if ! $PERF -v; then
+ echo $msg please install perf or provide perf binary path as argument >&2
exit $ksft_skip
fi
}
diff --git a/tools/testing/selftests/amd-pstate/tbench.sh b/tools/testing/selftests/amd-pstate/tbench.sh
index 49c9850341f6..2a98d9c9202e 100755
--- a/tools/testing/selftests/amd-pstate/tbench.sh
+++ b/tools/testing/selftests/amd-pstate/tbench.sh
@@ -64,11 +64,11 @@ post_clear_tbench()
run_tbench()
{
echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
- ./amd_pstate_trace.py -n tracer-tbench-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
+ $TRACER -n tracer-tbench-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
printf "Test tbench for $1 #$2 time_limit: $TIME_LIMIT procs_num: $PROCESS_NUM\n"
tbench_srv > /dev/null 2>&1 &
- perf stat -a --per-socket -I 1000 -e power/energy-pkg/ tbench -t $TIME_LIMIT $PROCESS_NUM > $OUTFILE_TBENCH-perf-$1-$2.log 2>&1
+ $PERF stat -a --per-socket -I 1000 -e power/energy-pkg/ tbench -t $TIME_LIMIT $PROCESS_NUM > $OUTFILE_TBENCH-perf-$1-$2.log 2>&1
pid=`pidof tbench_srv`
kill $pid
diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c
index e3d262831d91..1189e77c8152 100644
--- a/tools/testing/selftests/arm64/abi/hwcap.c
+++ b/tools/testing/selftests/arm64/abi/hwcap.c
@@ -81,6 +81,20 @@ static void lrcpc_sigill(void)
asm volatile(".inst 0xb8bfc3e0" : : : );
}
+static void lse128_sigill(void)
+{
+ u64 __attribute__ ((aligned (16))) mem[2] = { 10, 20 };
+ register u64 *memp asm ("x0") = mem;
+ register u64 val0 asm ("x1") = 5;
+ register u64 val1 asm ("x2") = 4;
+
+ /* SWPP X1, X2, [X0] */
+ asm volatile(".inst 0x19228001"
+ : "+r" (memp), "+r" (val0), "+r" (val1)
+ :
+ : "cc", "memory");
+}
+
static void mops_sigill(void)
{
char dst[1], src[1];
@@ -226,6 +240,12 @@ static void sveaes_sigill(void)
asm volatile(".inst 0x4522e400" : : : "z0");
}
+static void sveb16b16_sigill(void)
+{
+ /* BFADD ZA.H[W0, 0], {Z0.H-Z1.H} */
+ asm volatile(".inst 0xC1E41C00" : : : );
+}
+
static void svepmull_sigill(void)
{
/* PMULLB Z0.Q, Z0.D, Z0.D */
@@ -289,6 +309,19 @@ static void uscat_sigbus(void)
asm volatile(".inst 0xb820003f" : : : );
}
+static void lrcpc3_sigill(void)
+{
+ int data[2] = { 1, 2 };
+
+ register int *src asm ("x0") = data;
+ register int data0 asm ("w2") = 0;
+ register int data1 asm ("w3") = 0;
+
+ /* LDIAPP w2, w3, [x0] */
+ asm volatile(".inst 0x99431802"
+ : "=r" (data0), "=r" (data1) : "r" (src) :);
+}
+
static const struct hwcap_data {
const char *name;
unsigned long at_hwcap;
@@ -349,6 +382,13 @@ static const struct hwcap_data {
.sigill_fn = ilrcpc_sigill,
},
{
+ .name = "LRCPC3",
+ .at_hwcap = AT_HWCAP2,
+ .hwcap_bit = HWCAP2_LRCPC3,
+ .cpuinfo = "lrcpc3",
+ .sigill_fn = lrcpc3_sigill,
+ },
+ {
.name = "LSE",
.at_hwcap = AT_HWCAP,
.hwcap_bit = HWCAP_ATOMICS,
@@ -365,6 +405,13 @@ static const struct hwcap_data {
.sigbus_reliable = true,
},
{
+ .name = "LSE128",
+ .at_hwcap = AT_HWCAP2,
+ .hwcap_bit = HWCAP2_LSE128,
+ .cpuinfo = "lse128",
+ .sigill_fn = lse128_sigill,
+ },
+ {
.name = "MOPS",
.at_hwcap = AT_HWCAP2,
.hwcap_bit = HWCAP2_MOPS,
@@ -494,6 +541,13 @@ static const struct hwcap_data {
.sigill_fn = sveaes_sigill,
},
{
+ .name = "SVE2 B16B16",
+ .at_hwcap = AT_HWCAP2,
+ .hwcap_bit = HWCAP2_SVE_B16B16,
+ .cpuinfo = "sveb16b16",
+ .sigill_fn = sveb16b16_sigill,
+ },
+ {
.name = "SVE2 PMULL",
.at_hwcap = AT_HWCAP2,
.hwcap_bit = HWCAP2_SVEPMULL,
diff --git a/tools/testing/selftests/arm64/fp/sve-test.S b/tools/testing/selftests/arm64/fp/sve-test.S
index 4328895dfc87..547d077e3517 100644
--- a/tools/testing/selftests/arm64/fp/sve-test.S
+++ b/tools/testing/selftests/arm64/fp/sve-test.S
@@ -473,6 +473,13 @@ function _start
// mov x8, #__NR_sched_yield // Encourage preemption
// svc #0
+#ifdef SSVE
+ mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=0,SM=1
+ and x1, x0, #3
+ cmp x1, #1
+ b.ne svcr_barf
+#endif
+
mov x21, #0
0: mov x0, x21
bl check_zreg
@@ -553,3 +560,15 @@ function vl_barf
mov x1, #1
svc #0
endfunction
+
+function svcr_barf
+ mov x10, x0
+
+ puts "Bad SVCR: "
+ mov x0, x10
+ bl putdecn
+
+ mov x8, #__NR_exit
+ mov x1, #1
+ svc #0
+endfunction
diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt.c b/tools/testing/selftests/bpf/prog_tests/sockopt.c
index 9e6a5e3ed4de..5a4491d4edfe 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockopt.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockopt.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <test_progs.h>
+#include <io_uring/mini_liburing.h>
#include "cgroup_helpers.h"
static char bpf_log_buf[4096];
@@ -38,6 +39,7 @@ static struct sockopt_test {
socklen_t get_optlen_ret;
enum sockopt_test_error error;
+ bool io_uring_support;
} tests[] = {
/* ==================== getsockopt ==================== */
@@ -251,7 +253,9 @@ static struct sockopt_test {
.attach_type = BPF_CGROUP_GETSOCKOPT,
.expected_attach_type = BPF_CGROUP_GETSOCKOPT,
+ .get_level = SOL_SOCKET,
.get_optlen = 64,
+ .io_uring_support = true,
},
{
.descr = "getsockopt: deny bigger ctx->optlen",
@@ -276,6 +280,7 @@ static struct sockopt_test {
.get_optlen = 64,
.error = EFAULT_GETSOCKOPT,
+ .io_uring_support = true,
},
{
.descr = "getsockopt: ignore >PAGE_SIZE optlen",
@@ -318,6 +323,7 @@ static struct sockopt_test {
.get_optval = {}, /* the changes are ignored */
.get_optlen = PAGE_SIZE + 1,
.error = EOPNOTSUPP_GETSOCKOPT,
+ .io_uring_support = true,
},
{
.descr = "getsockopt: support smaller ctx->optlen",
@@ -337,8 +343,10 @@ static struct sockopt_test {
.attach_type = BPF_CGROUP_GETSOCKOPT,
.expected_attach_type = BPF_CGROUP_GETSOCKOPT,
+ .get_level = SOL_SOCKET,
.get_optlen = 64,
.get_optlen_ret = 32,
+ .io_uring_support = true,
},
{
.descr = "getsockopt: deny writing to ctx->optval",
@@ -518,6 +526,7 @@ static struct sockopt_test {
.set_level = 123,
.set_optlen = 1,
+ .io_uring_support = true,
},
{
.descr = "setsockopt: allow changing ctx->level",
@@ -572,6 +581,7 @@ static struct sockopt_test {
.set_optname = 123,
.set_optlen = 1,
+ .io_uring_support = true,
},
{
.descr = "setsockopt: allow changing ctx->optname",
@@ -624,6 +634,7 @@ static struct sockopt_test {
.expected_attach_type = BPF_CGROUP_SETSOCKOPT,
.set_optlen = 64,
+ .io_uring_support = true,
},
{
.descr = "setsockopt: ctx->optlen == -1 is ok",
@@ -640,6 +651,7 @@ static struct sockopt_test {
.expected_attach_type = BPF_CGROUP_SETSOCKOPT,
.set_optlen = 64,
+ .io_uring_support = true,
},
{
.descr = "setsockopt: deny ctx->optlen < 0 (except -1)",
@@ -658,6 +670,7 @@ static struct sockopt_test {
.set_optlen = 4,
.error = EFAULT_SETSOCKOPT,
+ .io_uring_support = true,
},
{
.descr = "setsockopt: deny ctx->optlen > input optlen",
@@ -675,6 +688,7 @@ static struct sockopt_test {
.set_optlen = 64,
.error = EFAULT_SETSOCKOPT,
+ .io_uring_support = true,
},
{
.descr = "setsockopt: ignore >PAGE_SIZE optlen",
@@ -940,7 +954,89 @@ static int load_prog(const struct bpf_insn *insns,
return fd;
}
-static int run_test(int cgroup_fd, struct sockopt_test *test)
+/* Core function that handles io_uring ring initialization,
+ * sending SQE with sockopt command and waiting for the CQE.
+ */
+static int uring_sockopt(int op, int fd, int level, int optname,
+ const void *optval, socklen_t optlen)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct io_uring ring;
+ int err;
+
+ err = io_uring_queue_init(1, &ring, 0);
+ if (!ASSERT_OK(err, "io_uring initialization"))
+ return err;
+
+ sqe = io_uring_get_sqe(&ring);
+ if (!ASSERT_NEQ(sqe, NULL, "Get an SQE")) {
+ err = -1;
+ goto fail;
+ }
+
+ io_uring_prep_cmd(sqe, op, fd, level, optname, optval, optlen);
+
+ err = io_uring_submit(&ring);
+ if (!ASSERT_EQ(err, 1, "Submit SQE"))
+ goto fail;
+
+ err = io_uring_wait_cqe(&ring, &cqe);
+ if (!ASSERT_OK(err, "Wait for CQE"))
+ goto fail;
+
+ err = cqe->res;
+
+fail:
+ io_uring_queue_exit(&ring);
+
+ return err;
+}
+
+static int uring_setsockopt(int fd, int level, int optname, const void *optval,
+ socklen_t optlen)
+{
+ return uring_sockopt(SOCKET_URING_OP_SETSOCKOPT, fd, level, optname,
+ optval, optlen);
+}
+
+static int uring_getsockopt(int fd, int level, int optname, void *optval,
+ socklen_t *optlen)
+{
+ int ret = uring_sockopt(SOCKET_URING_OP_GETSOCKOPT, fd, level, optname,
+ optval, *optlen);
+ if (ret < 0)
+ return ret;
+
+ /* Populate optlen back to be compatible with systemcall interface,
+ * and simplify the test.
+ */
+ *optlen = ret;
+
+ return 0;
+}
+
+/* Execute the setsocktopt operation */
+static int call_setsockopt(bool use_io_uring, int fd, int level, int optname,
+ const void *optval, socklen_t optlen)
+{
+ if (use_io_uring)
+ return uring_setsockopt(fd, level, optname, optval, optlen);
+
+ return setsockopt(fd, level, optname, optval, optlen);
+}
+
+/* Execute the getsocktopt operation */
+static int call_getsockopt(bool use_io_uring, int fd, int level, int optname,
+ void *optval, socklen_t *optlen)
+{
+ if (use_io_uring)
+ return uring_getsockopt(fd, level, optname, optval, optlen);
+
+ return getsockopt(fd, level, optname, optval, optlen);
+}
+
+static int run_test(int cgroup_fd, struct sockopt_test *test, bool use_io_uring)
{
int sock_fd, err, prog_fd;
void *optval = NULL;
@@ -980,8 +1076,9 @@ static int run_test(int cgroup_fd, struct sockopt_test *test)
test->set_optlen = num_pages * sysconf(_SC_PAGESIZE) + remainder;
}
- err = setsockopt(sock_fd, test->set_level, test->set_optname,
- test->set_optval, test->set_optlen);
+ err = call_setsockopt(use_io_uring, sock_fd, test->set_level,
+ test->set_optname, test->set_optval,
+ test->set_optlen);
if (err) {
if (errno == EPERM && test->error == EPERM_SETSOCKOPT)
goto close_sock_fd;
@@ -1008,8 +1105,8 @@ static int run_test(int cgroup_fd, struct sockopt_test *test)
socklen_t expected_get_optlen = test->get_optlen_ret ?:
test->get_optlen;
- err = getsockopt(sock_fd, test->get_level, test->get_optname,
- optval, &optlen);
+ err = call_getsockopt(use_io_uring, sock_fd, test->get_level,
+ test->get_optname, optval, &optlen);
if (err) {
if (errno == EOPNOTSUPP && test->error == EOPNOTSUPP_GETSOCKOPT)
goto free_optval;
@@ -1063,7 +1160,11 @@ void test_sockopt(void)
if (!test__start_subtest(tests[i].descr))
continue;
- ASSERT_OK(run_test(cgroup_fd, &tests[i]), tests[i].descr);
+ ASSERT_OK(run_test(cgroup_fd, &tests[i], false),
+ tests[i].descr);
+ if (tests[i].io_uring_support)
+ ASSERT_OK(run_test(cgroup_fd, &tests[i], true),
+ tests[i].descr);
}
close(cgroup_fd);
diff --git a/tools/testing/selftests/cachestat/test_cachestat.c b/tools/testing/selftests/cachestat/test_cachestat.c
index 4804c7dc7b31..b171fd53b004 100644
--- a/tools/testing/selftests/cachestat/test_cachestat.c
+++ b/tools/testing/selftests/cachestat/test_cachestat.c
@@ -27,7 +27,7 @@ static const char * const dev_files[] = {
void print_cachestat(struct cachestat *cs)
{
ksft_print_msg(
- "Using cachestat: Cached: %lu, Dirty: %lu, Writeback: %lu, Evicted: %lu, Recently Evicted: %lu\n",
+ "Using cachestat: Cached: %llu, Dirty: %llu, Writeback: %llu, Evicted: %llu, Recently Evicted: %llu\n",
cs->nr_cache, cs->nr_dirty, cs->nr_writeback,
cs->nr_evicted, cs->nr_recently_evicted);
}
diff --git a/tools/testing/selftests/capabilities/Makefile b/tools/testing/selftests/capabilities/Makefile
index 6e9d98d457d5..411ac098308f 100644
--- a/tools/testing/selftests/capabilities/Makefile
+++ b/tools/testing/selftests/capabilities/Makefile
@@ -2,7 +2,7 @@
TEST_GEN_FILES := validate_cap
TEST_GEN_PROGS := test_execve
-CFLAGS += -O2 -g -std=gnu99 -Wall
+CFLAGS += -O2 -g -std=gnu99 -Wall $(KHDR_INCLUDES)
LDLIBS += -lcap-ng -lrt -ldl
include ../lib.mk
diff --git a/tools/testing/selftests/capabilities/test_execve.c b/tools/testing/selftests/capabilities/test_execve.c
index df0ef02b4036..e3a352b020a7 100644
--- a/tools/testing/selftests/capabilities/test_execve.c
+++ b/tools/testing/selftests/capabilities/test_execve.c
@@ -20,14 +20,6 @@
#include "../kselftest.h"
-#ifndef PR_CAP_AMBIENT
-#define PR_CAP_AMBIENT 47
-# define PR_CAP_AMBIENT_IS_SET 1
-# define PR_CAP_AMBIENT_RAISE 2
-# define PR_CAP_AMBIENT_LOWER 3
-# define PR_CAP_AMBIENT_CLEAR_ALL 4
-#endif
-
static int nerrs;
static pid_t mpid; /* main() pid is used to avoid duplicate test counts */
diff --git a/tools/testing/selftests/capabilities/validate_cap.c b/tools/testing/selftests/capabilities/validate_cap.c
index cdfc94268fe6..60b4e7b716a7 100644
--- a/tools/testing/selftests/capabilities/validate_cap.c
+++ b/tools/testing/selftests/capabilities/validate_cap.c
@@ -9,14 +9,6 @@
#include "../kselftest.h"
-#ifndef PR_CAP_AMBIENT
-#define PR_CAP_AMBIENT 47
-# define PR_CAP_AMBIENT_IS_SET 1
-# define PR_CAP_AMBIENT_RAISE 2
-# define PR_CAP_AMBIENT_LOWER 3
-# define PR_CAP_AMBIENT_CLEAR_ALL 4
-#endif
-
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 19)
# define HAVE_GETAUXVAL
#endif
diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c
index e60cf4da8fb0..9429d361059e 100644
--- a/tools/testing/selftests/clone3/clone3.c
+++ b/tools/testing/selftests/clone3/clone3.c
@@ -7,6 +7,7 @@
#include <inttypes.h>
#include <linux/types.h>
#include <linux/sched.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -103,8 +104,8 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode)
return 0;
}
-static void test_clone3(uint64_t flags, size_t size, int expected,
- enum test_mode test_mode)
+static bool test_clone3(uint64_t flags, size_t size, int expected,
+ enum test_mode test_mode)
{
int ret;
@@ -114,92 +115,210 @@ static void test_clone3(uint64_t flags, size_t size, int expected,
ret = call_clone3(flags, size, test_mode);
ksft_print_msg("[%d] clone3() with flags says: %d expected %d\n",
getpid(), ret, expected);
- if (ret != expected)
- ksft_test_result_fail(
+ if (ret != expected) {
+ ksft_print_msg(
"[%d] Result (%d) is different than expected (%d)\n",
getpid(), ret, expected);
- else
- ksft_test_result_pass(
- "[%d] Result (%d) matches expectation (%d)\n",
- getpid(), ret, expected);
-}
-
-int main(int argc, char *argv[])
-{
- uid_t uid = getuid();
-
- ksft_print_header();
- ksft_set_plan(19);
- test_clone3_supported();
-
- /* Just a simple clone3() should return 0.*/
- test_clone3(0, 0, 0, CLONE3_ARGS_NO_TEST);
-
- /* Do a clone3() in a new PID NS.*/
- if (uid == 0)
- test_clone3(CLONE_NEWPID, 0, 0, CLONE3_ARGS_NO_TEST);
- else
- ksft_test_result_skip("Skipping clone3() with CLONE_NEWPID\n");
-
- /* Do a clone3() with CLONE_ARGS_SIZE_VER0. */
- test_clone3(0, CLONE_ARGS_SIZE_VER0, 0, CLONE3_ARGS_NO_TEST);
-
- /* Do a clone3() with CLONE_ARGS_SIZE_VER0 - 8 */
- test_clone3(0, CLONE_ARGS_SIZE_VER0 - 8, -EINVAL, CLONE3_ARGS_NO_TEST);
-
- /* Do a clone3() with sizeof(struct clone_args) + 8 */
- test_clone3(0, sizeof(struct __clone_args) + 8, 0, CLONE3_ARGS_NO_TEST);
-
- /* Do a clone3() with exit_signal having highest 32 bits non-zero */
- test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_BIG);
+ return false;
+ }
- /* Do a clone3() with negative 32-bit exit_signal */
- test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_NEG);
+ return true;
+}
- /* Do a clone3() with exit_signal not fitting into CSIGNAL mask */
- test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_CSIG);
+typedef bool (*filter_function)(void);
+typedef size_t (*size_function)(void);
- /* Do a clone3() with NSIG < exit_signal < CSIG */
- test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG);
+static bool not_root(void)
+{
+ if (getuid() != 0) {
+ ksft_print_msg("Not running as root\n");
+ return true;
+ }
- test_clone3(0, sizeof(struct __clone_args) + 8, 0, CLONE3_ARGS_ALL_0);
+ return false;
+}
- test_clone3(0, sizeof(struct __clone_args) + 16, -E2BIG,
- CLONE3_ARGS_ALL_0);
+static size_t page_size_plus_8(void)
+{
+ return getpagesize() + 8;
+}
- test_clone3(0, sizeof(struct __clone_args) * 2, -E2BIG,
- CLONE3_ARGS_ALL_0);
+struct test {
+ const char *name;
+ uint64_t flags;
+ size_t size;
+ size_function size_function;
+ int expected;
+ enum test_mode test_mode;
+ filter_function filter;
+};
- /* Do a clone3() with > page size */
- test_clone3(0, getpagesize() + 8, -E2BIG, CLONE3_ARGS_NO_TEST);
+static const struct test tests[] = {
+ {
+ .name = "simple clone3()",
+ .flags = 0,
+ .size = 0,
+ .expected = 0,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ },
+ {
+ .name = "clone3() in a new PID_NS",
+ .flags = CLONE_NEWPID,
+ .size = 0,
+ .expected = 0,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ .filter = not_root,
+ },
+ {
+ .name = "CLONE_ARGS_SIZE_VER0",
+ .flags = 0,
+ .size = CLONE_ARGS_SIZE_VER0,
+ .expected = 0,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ },
+ {
+ .name = "CLONE_ARGS_SIZE_VER0 - 8",
+ .flags = 0,
+ .size = CLONE_ARGS_SIZE_VER0 - 8,
+ .expected = -EINVAL,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ },
+ {
+ .name = "sizeof(struct clone_args) + 8",
+ .flags = 0,
+ .size = sizeof(struct __clone_args) + 8,
+ .expected = 0,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ },
+ {
+ .name = "exit_signal with highest 32 bits non-zero",
+ .flags = 0,
+ .size = 0,
+ .expected = -EINVAL,
+ .test_mode = CLONE3_ARGS_INVAL_EXIT_SIGNAL_BIG,
+ },
+ {
+ .name = "negative 32-bit exit_signal",
+ .flags = 0,
+ .size = 0,
+ .expected = -EINVAL,
+ .test_mode = CLONE3_ARGS_INVAL_EXIT_SIGNAL_NEG,
+ },
+ {
+ .name = "exit_signal not fitting into CSIGNAL mask",
+ .flags = 0,
+ .size = 0,
+ .expected = -EINVAL,
+ .test_mode = CLONE3_ARGS_INVAL_EXIT_SIGNAL_CSIG,
+ },
+ {
+ .name = "NSIG < exit_signal < CSIG",
+ .flags = 0,
+ .size = 0,
+ .expected = -EINVAL,
+ .test_mode = CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG,
+ },
+ {
+ .name = "Arguments sizeof(struct clone_args) + 8",
+ .flags = 0,
+ .size = sizeof(struct __clone_args) + 8,
+ .expected = 0,
+ .test_mode = CLONE3_ARGS_ALL_0,
+ },
+ {
+ .name = "Arguments sizeof(struct clone_args) + 16",
+ .flags = 0,
+ .size = sizeof(struct __clone_args) + 16,
+ .expected = -E2BIG,
+ .test_mode = CLONE3_ARGS_ALL_0,
+ },
+ {
+ .name = "Arguments sizeof(struct clone_arg) * 2",
+ .flags = 0,
+ .size = sizeof(struct __clone_args) + 16,
+ .expected = -E2BIG,
+ .test_mode = CLONE3_ARGS_ALL_0,
+ },
+ {
+ .name = "Arguments > page size",
+ .flags = 0,
+ .size_function = page_size_plus_8,
+ .expected = -E2BIG,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ },
+ {
+ .name = "CLONE_ARGS_SIZE_VER0 in a new PID NS",
+ .flags = CLONE_NEWPID,
+ .size = CLONE_ARGS_SIZE_VER0,
+ .expected = 0,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ .filter = not_root,
+ },
+ {
+ .name = "CLONE_ARGS_SIZE_VER0 - 8 in a new PID NS",
+ .flags = CLONE_NEWPID,
+ .size = CLONE_ARGS_SIZE_VER0 - 8,
+ .expected = -EINVAL,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ },
+ {
+ .name = "sizeof(struct clone_args) + 8 in a new PID NS",
+ .flags = CLONE_NEWPID,
+ .size = sizeof(struct __clone_args) + 8,
+ .expected = 0,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ .filter = not_root,
+ },
+ {
+ .name = "Arguments > page size in a new PID NS",
+ .flags = CLONE_NEWPID,
+ .size_function = page_size_plus_8,
+ .expected = -E2BIG,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ },
+ {
+ .name = "New time NS",
+ .flags = CLONE_NEWTIME,
+ .size = 0,
+ .expected = 0,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ },
+ {
+ .name = "exit signal (SIGCHLD) in flags",
+ .flags = SIGCHLD,
+ .size = 0,
+ .expected = -EINVAL,
+ .test_mode = CLONE3_ARGS_NO_TEST,
+ },
+};
- /* Do a clone3() with CLONE_ARGS_SIZE_VER0 in a new PID NS. */
- if (uid == 0)
- test_clone3(CLONE_NEWPID, CLONE_ARGS_SIZE_VER0, 0,
- CLONE3_ARGS_NO_TEST);
- else
- ksft_test_result_skip("Skipping clone3() with CLONE_NEWPID\n");
+int main(int argc, char *argv[])
+{
+ size_t size;
+ int i;
- /* Do a clone3() with CLONE_ARGS_SIZE_VER0 - 8 in a new PID NS */
- test_clone3(CLONE_NEWPID, CLONE_ARGS_SIZE_VER0 - 8, -EINVAL,
- CLONE3_ARGS_NO_TEST);
+ ksft_print_header();
+ ksft_set_plan(ARRAY_SIZE(tests));
+ test_clone3_supported();
- /* Do a clone3() with sizeof(struct clone_args) + 8 in a new PID NS */
- if (uid == 0)
- test_clone3(CLONE_NEWPID, sizeof(struct __clone_args) + 8, 0,
- CLONE3_ARGS_NO_TEST);
- else
- ksft_test_result_skip("Skipping clone3() with CLONE_NEWPID\n");
+ for (i = 0; i < ARRAY_SIZE(tests); i++) {
+ if (tests[i].filter && tests[i].filter()) {
+ ksft_test_result_skip("%s\n", tests[i].name);
+ continue;
+ }
- /* Do a clone3() with > page size in a new PID NS */
- test_clone3(CLONE_NEWPID, getpagesize() + 8, -E2BIG,
- CLONE3_ARGS_NO_TEST);
+ if (tests[i].size_function)
+ size = tests[i].size_function();
+ else
+ size = tests[i].size;
- /* Do a clone3() in a new time namespace */
- test_clone3(CLONE_NEWTIME, 0, 0, CLONE3_ARGS_NO_TEST);
+ ksft_print_msg("Running test '%s'\n", tests[i].name);
- /* Do a clone3() with exit signal (SIGCHLD) in flags */
- test_clone3(SIGCHLD, 0, -EINVAL, CLONE3_ARGS_NO_TEST);
+ ksft_test_result(test_clone3(tests[i].flags, size,
+ tests[i].expected,
+ tests[i].test_mode),
+ "%s\n", tests[i].name);
+ }
ksft_finished();
}
diff --git a/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c b/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c
index 52d3f0364bda..31b56d625655 100644
--- a/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c
+++ b/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c
@@ -27,9 +27,7 @@
#include "../kselftest_harness.h"
#include "clone3_selftests.h"
-#ifndef MAX_PID_NS_LEVEL
#define MAX_PID_NS_LEVEL 32
-#endif
static void child_exit(int ret)
{
diff --git a/tools/testing/selftests/clone3/clone3_clear_sighand.c b/tools/testing/selftests/clone3/clone3_clear_sighand.c
index 47a8c0fc3676..54a8b2445be9 100644
--- a/tools/testing/selftests/clone3/clone3_clear_sighand.c
+++ b/tools/testing/selftests/clone3/clone3_clear_sighand.c
@@ -16,10 +16,6 @@
#include "../kselftest.h"
#include "clone3_selftests.h"
-#ifndef CLONE_CLEAR_SIGHAND
-#define CLONE_CLEAR_SIGHAND 0x100000000ULL
-#endif
-
static void nop_handler(int signo)
{
}
diff --git a/tools/testing/selftests/clone3/clone3_selftests.h b/tools/testing/selftests/clone3/clone3_selftests.h
index e81ffaaee02b..3d2663fe50ba 100644
--- a/tools/testing/selftests/clone3/clone3_selftests.h
+++ b/tools/testing/selftests/clone3/clone3_selftests.h
@@ -15,10 +15,6 @@
#define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr)))
-#ifndef CLONE_INTO_CGROUP
-#define CLONE_INTO_CGROUP 0x200000000ULL /* Clone into a specific cgroup given the right permissions. */
-#endif
-
#ifndef __NR_clone3
#define __NR_clone3 -1
#endif
@@ -32,18 +28,9 @@ struct __clone_args {
__aligned_u64 stack;
__aligned_u64 stack_size;
__aligned_u64 tls;
-#ifndef CLONE_ARGS_SIZE_VER0
-#define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */
-#endif
__aligned_u64 set_tid;
__aligned_u64 set_tid_size;
-#ifndef CLONE_ARGS_SIZE_VER1
-#define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */
-#endif
__aligned_u64 cgroup;
-#ifndef CLONE_ARGS_SIZE_VER2
-#define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */
-#endif
};
static pid_t sys_clone3(struct __clone_args *args, size_t size)
diff --git a/tools/testing/selftests/clone3/clone3_set_tid.c b/tools/testing/selftests/clone3/clone3_set_tid.c
index 0229e9ebb995..ed785afb6077 100644
--- a/tools/testing/selftests/clone3/clone3_set_tid.c
+++ b/tools/testing/selftests/clone3/clone3_set_tid.c
@@ -23,9 +23,7 @@
#include "../kselftest.h"
#include "clone3_selftests.h"
-#ifndef MAX_PID_NS_LEVEL
#define MAX_PID_NS_LEVEL 32
-#endif
static int pipe_1[2];
static int pipe_2[2];
diff --git a/tools/testing/selftests/core/close_range_test.c b/tools/testing/selftests/core/close_range_test.c
index 749239930ca8..534576f06df1 100644
--- a/tools/testing/selftests/core/close_range_test.c
+++ b/tools/testing/selftests/core/close_range_test.c
@@ -16,34 +16,6 @@
#include "../kselftest_harness.h"
#include "../clone3/clone3_selftests.h"
-#ifndef __NR_close_range
- #if defined __alpha__
- #define __NR_close_range 546
- #elif defined _MIPS_SIM
- #if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */
- #define __NR_close_range (436 + 4000)
- #endif
- #if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */
- #define __NR_close_range (436 + 6000)
- #endif
- #if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */
- #define __NR_close_range (436 + 5000)
- #endif
- #elif defined __ia64__
- #define __NR_close_range (436 + 1024)
- #else
- #define __NR_close_range 436
- #endif
-#endif
-
-#ifndef CLOSE_RANGE_UNSHARE
-#define CLOSE_RANGE_UNSHARE (1U << 1)
-#endif
-
-#ifndef CLOSE_RANGE_CLOEXEC
-#define CLOSE_RANGE_CLOEXEC (1U << 2)
-#endif
-
static inline int sys_close_range(unsigned int fd, unsigned int max_fd,
unsigned int flags)
{
diff --git a/tools/testing/selftests/damon/debugfs_attrs.sh b/tools/testing/selftests/damon/debugfs_attrs.sh
index 902e312bca89..902e312bca89 100644..100755
--- a/tools/testing/selftests/damon/debugfs_attrs.sh
+++ b/tools/testing/selftests/damon/debugfs_attrs.sh
diff --git a/tools/testing/selftests/damon/debugfs_duplicate_context_creation.sh b/tools/testing/selftests/damon/debugfs_duplicate_context_creation.sh
index 4a76e37ef16b..4a76e37ef16b 100644..100755
--- a/tools/testing/selftests/damon/debugfs_duplicate_context_creation.sh
+++ b/tools/testing/selftests/damon/debugfs_duplicate_context_creation.sh
diff --git a/tools/testing/selftests/damon/debugfs_empty_targets.sh b/tools/testing/selftests/damon/debugfs_empty_targets.sh
index 87aff8083822..87aff8083822 100644..100755
--- a/tools/testing/selftests/damon/debugfs_empty_targets.sh
+++ b/tools/testing/selftests/damon/debugfs_empty_targets.sh
diff --git a/tools/testing/selftests/damon/debugfs_huge_count_read_write.sh b/tools/testing/selftests/damon/debugfs_huge_count_read_write.sh
index 922cadac2950..922cadac2950 100644..100755
--- a/tools/testing/selftests/damon/debugfs_huge_count_read_write.sh
+++ b/tools/testing/selftests/damon/debugfs_huge_count_read_write.sh
diff --git a/tools/testing/selftests/damon/debugfs_rm_non_contexts.sh b/tools/testing/selftests/damon/debugfs_rm_non_contexts.sh
index f3ffeb1343cf..f3ffeb1343cf 100644..100755
--- a/tools/testing/selftests/damon/debugfs_rm_non_contexts.sh
+++ b/tools/testing/selftests/damon/debugfs_rm_non_contexts.sh
diff --git a/tools/testing/selftests/damon/debugfs_schemes.sh b/tools/testing/selftests/damon/debugfs_schemes.sh
index 5b39ab44731c..5b39ab44731c 100644..100755
--- a/tools/testing/selftests/damon/debugfs_schemes.sh
+++ b/tools/testing/selftests/damon/debugfs_schemes.sh
diff --git a/tools/testing/selftests/damon/debugfs_target_ids.sh b/tools/testing/selftests/damon/debugfs_target_ids.sh
index 49aeabdb0aae..49aeabdb0aae 100644..100755
--- a/tools/testing/selftests/damon/debugfs_target_ids.sh
+++ b/tools/testing/selftests/damon/debugfs_target_ids.sh
diff --git a/tools/testing/selftests/damon/lru_sort.sh b/tools/testing/selftests/damon/lru_sort.sh
index 61b80197c896..61b80197c896 100644..100755
--- a/tools/testing/selftests/damon/lru_sort.sh
+++ b/tools/testing/selftests/damon/lru_sort.sh
diff --git a/tools/testing/selftests/damon/reclaim.sh b/tools/testing/selftests/damon/reclaim.sh
index 78dbc2334cbe..78dbc2334cbe 100644..100755
--- a/tools/testing/selftests/damon/reclaim.sh
+++ b/tools/testing/selftests/damon/reclaim.sh
diff --git a/tools/testing/selftests/damon/sysfs.sh b/tools/testing/selftests/damon/sysfs.sh
index 60a9a305aef0..60a9a305aef0 100644..100755
--- a/tools/testing/selftests/damon/sysfs.sh
+++ b/tools/testing/selftests/damon/sysfs.sh
diff --git a/tools/testing/selftests/damon/sysfs_update_removed_scheme_dir.sh b/tools/testing/selftests/damon/sysfs_update_removed_scheme_dir.sh
index ade35576e748..ade35576e748 100644..100755
--- a/tools/testing/selftests/damon/sysfs_update_removed_scheme_dir.sh
+++ b/tools/testing/selftests/damon/sysfs_update_removed_scheme_dir.sh
diff --git a/tools/testing/selftests/dmabuf-heaps/.gitignore b/tools/testing/selftests/dmabuf-heaps/.gitignore
new file mode 100644
index 000000000000..b500e76b9045
--- /dev/null
+++ b/tools/testing/selftests/dmabuf-heaps/.gitignore
@@ -0,0 +1 @@
+dmabuf-heap
diff --git a/tools/testing/selftests/efivarfs/create-read.c b/tools/testing/selftests/efivarfs/create-read.c
index 9674a19396a3..7bc7af4eb2c1 100644
--- a/tools/testing/selftests/efivarfs/create-read.c
+++ b/tools/testing/selftests/efivarfs/create-read.c
@@ -32,8 +32,10 @@ int main(int argc, char **argv)
rc = read(fd, buf, sizeof(buf));
if (rc != 0) {
fprintf(stderr, "Reading a new var should return EOF\n");
+ close(fd);
return EXIT_FAILURE;
}
+ close(fd);
return EXIT_SUCCESS;
}
diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c
index 67bf7254a48f..bf79d664c8e6 100644
--- a/tools/testing/selftests/exec/execveat.c
+++ b/tools/testing/selftests/exec/execveat.c
@@ -23,6 +23,9 @@
#include "../kselftest.h"
+#define TESTS_EXPECTED 51
+#define TEST_NAME_LEN (PATH_MAX * 4)
+
static char longpath[2 * PATH_MAX] = "";
static char *envp[] = { "IN_TEST=yes", NULL, NULL };
static char *argv[] = { "execveat", "99", NULL };
@@ -43,71 +46,85 @@ static int execveat_(int fd, const char *path, char **argv, char **envp,
static int _check_execveat_fail(int fd, const char *path, int flags,
int expected_errno, const char *errno_str)
{
+ char test_name[TEST_NAME_LEN];
int rc;
errno = 0;
- printf("Check failure of execveat(%d, '%s', %d) with %s... ",
- fd, path?:"(null)", flags, errno_str);
+ snprintf(test_name, sizeof(test_name),
+ "Check failure of execveat(%d, '%s', %d) with %s",
+ fd, path?:"(null)", flags, errno_str);
rc = execveat_(fd, path, argv, envp, flags);
if (rc > 0) {
- printf("[FAIL] (unexpected success from execveat(2))\n");
+ ksft_print_msg("unexpected success from execveat(2)\n");
+ ksft_test_result_fail("%s\n", test_name);
return 1;
}
if (errno != expected_errno) {
- printf("[FAIL] (expected errno %d (%s) not %d (%s)\n",
- expected_errno, strerror(expected_errno),
- errno, strerror(errno));
+ ksft_print_msg("expected errno %d (%s) not %d (%s)\n",
+ expected_errno, strerror(expected_errno),
+ errno, strerror(errno));
+ ksft_test_result_fail("%s\n", test_name);
return 1;
}
- printf("[OK]\n");
+ ksft_test_result_pass("%s\n", test_name);
return 0;
}
static int check_execveat_invoked_rc(int fd, const char *path, int flags,
int expected_rc, int expected_rc2)
{
+ char test_name[TEST_NAME_LEN];
int status;
int rc;
pid_t child;
int pathlen = path ? strlen(path) : 0;
if (pathlen > 40)
- printf("Check success of execveat(%d, '%.20s...%s', %d)... ",
- fd, path, (path + pathlen - 20), flags);
+ snprintf(test_name, sizeof(test_name),
+ "Check success of execveat(%d, '%.20s...%s', %d)... ",
+ fd, path, (path + pathlen - 20), flags);
else
- printf("Check success of execveat(%d, '%s', %d)... ",
- fd, path?:"(null)", flags);
+ snprintf(test_name, sizeof(test_name),
+ "Check success of execveat(%d, '%s', %d)... ",
+ fd, path?:"(null)", flags);
+
child = fork();
if (child < 0) {
- printf("[FAIL] (fork() failed)\n");
+ ksft_perror("fork() failed");
+ ksft_test_result_fail("%s\n", test_name);
return 1;
}
if (child == 0) {
/* Child: do execveat(). */
rc = execveat_(fd, path, argv, envp, flags);
- printf("[FAIL]: execveat() failed, rc=%d errno=%d (%s)\n",
- rc, errno, strerror(errno));
+ ksft_print_msg("execveat() failed, rc=%d errno=%d (%s)\n",
+ rc, errno, strerror(errno));
+ ksft_test_result_fail("%s\n", test_name);
exit(1); /* should not reach here */
}
/* Parent: wait for & check child's exit status. */
rc = waitpid(child, &status, 0);
if (rc != child) {
- printf("[FAIL] (waitpid(%d,...) returned %d)\n", child, rc);
+ ksft_print_msg("waitpid(%d,...) returned %d\n", child, rc);
+ ksft_test_result_fail("%s\n", test_name);
return 1;
}
if (!WIFEXITED(status)) {
- printf("[FAIL] (child %d did not exit cleanly, status=%08x)\n",
- child, status);
+ ksft_print_msg("child %d did not exit cleanly, status=%08x\n",
+ child, status);
+ ksft_test_result_fail("%s\n", test_name);
return 1;
}
if ((WEXITSTATUS(status) != expected_rc) &&
(WEXITSTATUS(status) != expected_rc2)) {
- printf("[FAIL] (child %d exited with %d not %d nor %d)\n",
- child, WEXITSTATUS(status), expected_rc, expected_rc2);
+ ksft_print_msg("child %d exited with %d not %d nor %d\n",
+ child, WEXITSTATUS(status), expected_rc,
+ expected_rc2);
+ ksft_test_result_fail("%s\n", test_name);
return 1;
}
- printf("[OK]\n");
+ ksft_test_result_pass("%s\n", test_name);
return 0;
}
@@ -129,11 +146,9 @@ static int open_or_die(const char *filename, int flags)
{
int fd = open(filename, flags);
- if (fd < 0) {
- printf("Failed to open '%s'; "
+ if (fd < 0)
+ ksft_exit_fail_msg("Failed to open '%s'; "
"check prerequisites are available\n", filename);
- exit(1);
- }
return fd;
}
@@ -162,8 +177,7 @@ static int check_execveat_pathmax(int root_dfd, const char *src, int is_script)
char *cwd = getcwd(NULL, 0);
if (!cwd) {
- printf("Failed to getcwd(), errno=%d (%s)\n",
- errno, strerror(errno));
+ ksft_perror("Failed to getcwd()");
return 2;
}
strcpy(longpath, cwd);
@@ -193,12 +207,12 @@ static int check_execveat_pathmax(int root_dfd, const char *src, int is_script)
*/
fd = open(longpath, O_RDONLY);
if (fd > 0) {
- printf("Invoke copy of '%s' via filename of length %zu:\n",
- src, strlen(longpath));
+ ksft_print_msg("Invoke copy of '%s' via filename of length %zu:\n",
+ src, strlen(longpath));
fail += check_execveat(fd, "", AT_EMPTY_PATH);
} else {
- printf("Failed to open length %zu filename, errno=%d (%s)\n",
- strlen(longpath), errno, strerror(errno));
+ ksft_print_msg("Failed to open length %zu filename, errno=%d (%s)\n",
+ strlen(longpath), errno, strerror(errno));
fail++;
}
@@ -405,28 +419,31 @@ int main(int argc, char **argv)
const char *in_test = getenv("IN_TEST");
if (verbose) {
- printf(" invoked with:");
+ ksft_print_msg("invoked with:\n");
for (ii = 0; ii < argc; ii++)
- printf(" [%d]='%s'", ii, argv[ii]);
- printf("\n");
+ ksft_print_msg("\t[%d]='%s\n'", ii, argv[ii]);
}
/* Check expected environment transferred. */
if (!in_test || strcmp(in_test, "yes") != 0) {
- printf("[FAIL] (no IN_TEST=yes in env)\n");
+ ksft_print_msg("no IN_TEST=yes in env\n");
return 1;
}
/* Use the final argument as an exit code. */
rc = atoi(argv[argc - 1]);
- fflush(stdout);
+ exit(rc);
} else {
+ ksft_print_header();
+ ksft_set_plan(TESTS_EXPECTED);
prerequisites();
if (verbose)
envp[1] = "VERBOSE=1";
rc = run_tests();
if (rc > 0)
printf("%d tests failed\n", rc);
+ ksft_finished();
}
+
return rc;
}
diff --git a/tools/testing/selftests/firmware/fw_namespace.c b/tools/testing/selftests/firmware/fw_namespace.c
index 4c6f0cd83c5b..04757dc7e546 100644
--- a/tools/testing/selftests/firmware/fw_namespace.c
+++ b/tools/testing/selftests/firmware/fw_namespace.c
@@ -17,10 +17,6 @@
#include <sys/wait.h>
#include <unistd.h>
-#ifndef CLONE_NEWNS
-# define CLONE_NEWNS 0x00020000
-#endif
-
static char *fw_path = NULL;
static void die(char *fmt, ...)
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc
index ff7499eb98d6..21db6b720754 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc
@@ -28,6 +28,12 @@ s390*)
mips*)
ARG1=%r4
;;
+loongarch*)
+ ARG1=%r4
+;;
+riscv*)
+ ARG1=%a0
+;;
*)
echo "Please implement other architecture here"
exit_untested
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
index a202b2ea4baf..4e086f871cee 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
@@ -31,6 +31,9 @@ mips*)
loongarch*)
ARG1=%r4
;;
+riscv*)
+ ARG1=%a0
+;;
*)
echo "Please implement other architecture here"
exit_untested
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc
index 1df61e13a812..8f1292ad80ff 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc
@@ -44,6 +44,10 @@ loongarch*)
GOODREG=%r4
BADREG=%r12
;;
+riscv*)
+ GOODREG=%a0
+ BADREG=%a8
+;;
*)
echo "Please implement other architecture here"
exit_untested
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index 33d08600be13..6ed328c863c4 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -86,12 +86,13 @@ TEST_F(iommufd, cmd_fail)
TEST_F(iommufd, cmd_length)
{
-#define TEST_LENGTH(_struct, _ioctl) \
+#define TEST_LENGTH(_struct, _ioctl, _last) \
{ \
+ size_t min_size = offsetofend(struct _struct, _last); \
struct { \
struct _struct cmd; \
uint8_t extra; \
- } cmd = { .cmd = { .size = sizeof(struct _struct) - 1 }, \
+ } cmd = { .cmd = { .size = min_size - 1 }, \
.extra = UINT8_MAX }; \
int old_errno; \
int rc; \
@@ -112,16 +113,19 @@ TEST_F(iommufd, cmd_length)
} \
}
- TEST_LENGTH(iommu_destroy, IOMMU_DESTROY);
- TEST_LENGTH(iommu_hw_info, IOMMU_GET_HW_INFO);
- TEST_LENGTH(iommu_ioas_alloc, IOMMU_IOAS_ALLOC);
- TEST_LENGTH(iommu_ioas_iova_ranges, IOMMU_IOAS_IOVA_RANGES);
- TEST_LENGTH(iommu_ioas_allow_iovas, IOMMU_IOAS_ALLOW_IOVAS);
- TEST_LENGTH(iommu_ioas_map, IOMMU_IOAS_MAP);
- TEST_LENGTH(iommu_ioas_copy, IOMMU_IOAS_COPY);
- TEST_LENGTH(iommu_ioas_unmap, IOMMU_IOAS_UNMAP);
- TEST_LENGTH(iommu_option, IOMMU_OPTION);
- TEST_LENGTH(iommu_vfio_ioas, IOMMU_VFIO_IOAS);
+ TEST_LENGTH(iommu_destroy, IOMMU_DESTROY, id);
+ TEST_LENGTH(iommu_hw_info, IOMMU_GET_HW_INFO, __reserved);
+ TEST_LENGTH(iommu_hwpt_alloc, IOMMU_HWPT_ALLOC, __reserved);
+ TEST_LENGTH(iommu_ioas_alloc, IOMMU_IOAS_ALLOC, out_ioas_id);
+ TEST_LENGTH(iommu_ioas_iova_ranges, IOMMU_IOAS_IOVA_RANGES,
+ out_iova_alignment);
+ TEST_LENGTH(iommu_ioas_allow_iovas, IOMMU_IOAS_ALLOW_IOVAS,
+ allowed_iovas);
+ TEST_LENGTH(iommu_ioas_map, IOMMU_IOAS_MAP, iova);
+ TEST_LENGTH(iommu_ioas_copy, IOMMU_IOAS_COPY, src_iova);
+ TEST_LENGTH(iommu_ioas_unmap, IOMMU_IOAS_UNMAP, length);
+ TEST_LENGTH(iommu_option, IOMMU_OPTION, val64);
+ TEST_LENGTH(iommu_vfio_ioas, IOMMU_VFIO_IOAS, __reserved);
#undef TEST_LENGTH
}
@@ -260,6 +264,121 @@ TEST_F(iommufd_ioas, ioas_destroy)
}
}
+TEST_F(iommufd_ioas, alloc_hwpt_nested)
+{
+ const uint32_t min_data_len =
+ offsetofend(struct iommu_hwpt_selftest, iotlb);
+ struct iommu_hwpt_selftest data = {
+ .iotlb = IOMMU_TEST_IOTLB_DEFAULT,
+ };
+ uint32_t nested_hwpt_id[2] = {};
+ uint32_t parent_hwpt_id = 0;
+ uint32_t parent_hwpt_id_not_work = 0;
+ uint32_t test_hwpt_id = 0;
+
+ if (self->device_id) {
+ /* Negative tests */
+ test_err_hwpt_alloc(ENOENT, self->ioas_id, self->device_id, 0,
+ &test_hwpt_id);
+ test_err_hwpt_alloc(EINVAL, self->device_id, self->device_id, 0,
+ &test_hwpt_id);
+
+ test_cmd_hwpt_alloc(self->device_id, self->ioas_id,
+ IOMMU_HWPT_ALLOC_NEST_PARENT,
+ &parent_hwpt_id);
+
+ test_cmd_hwpt_alloc(self->device_id, self->ioas_id, 0,
+ &parent_hwpt_id_not_work);
+
+ /* Negative nested tests */
+ test_err_hwpt_alloc_nested(EINVAL, self->device_id,
+ parent_hwpt_id, 0,
+ &nested_hwpt_id[0],
+ IOMMU_HWPT_DATA_NONE, &data,
+ sizeof(data));
+ test_err_hwpt_alloc_nested(EOPNOTSUPP, self->device_id,
+ parent_hwpt_id, 0,
+ &nested_hwpt_id[0],
+ IOMMU_HWPT_DATA_SELFTEST + 1, &data,
+ sizeof(data));
+ test_err_hwpt_alloc_nested(EINVAL, self->device_id,
+ parent_hwpt_id, 0,
+ &nested_hwpt_id[0],
+ IOMMU_HWPT_DATA_SELFTEST, &data,
+ min_data_len - 1);
+ test_err_hwpt_alloc_nested(EFAULT, self->device_id,
+ parent_hwpt_id, 0,
+ &nested_hwpt_id[0],
+ IOMMU_HWPT_DATA_SELFTEST, NULL,
+ sizeof(data));
+ test_err_hwpt_alloc_nested(
+ EOPNOTSUPP, self->device_id, parent_hwpt_id,
+ IOMMU_HWPT_ALLOC_NEST_PARENT, &nested_hwpt_id[0],
+ IOMMU_HWPT_DATA_SELFTEST, &data, sizeof(data));
+ test_err_hwpt_alloc_nested(EINVAL, self->device_id,
+ parent_hwpt_id_not_work, 0,
+ &nested_hwpt_id[0],
+ IOMMU_HWPT_DATA_SELFTEST, &data,
+ sizeof(data));
+
+ /* Allocate two nested hwpts sharing one common parent hwpt */
+ test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id, 0,
+ &nested_hwpt_id[0],
+ IOMMU_HWPT_DATA_SELFTEST, &data,
+ sizeof(data));
+ test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id, 0,
+ &nested_hwpt_id[1],
+ IOMMU_HWPT_DATA_SELFTEST, &data,
+ sizeof(data));
+
+ /* Negative test: a nested hwpt on top of a nested hwpt */
+ test_err_hwpt_alloc_nested(EINVAL, self->device_id,
+ nested_hwpt_id[0], 0, &test_hwpt_id,
+ IOMMU_HWPT_DATA_SELFTEST, &data,
+ sizeof(data));
+ /* Negative test: parent hwpt now cannot be freed */
+ EXPECT_ERRNO(EBUSY,
+ _test_ioctl_destroy(self->fd, parent_hwpt_id));
+
+ /* Attach device to nested_hwpt_id[0] that then will be busy */
+ test_cmd_mock_domain_replace(self->stdev_id, nested_hwpt_id[0]);
+ EXPECT_ERRNO(EBUSY,
+ _test_ioctl_destroy(self->fd, nested_hwpt_id[0]));
+
+ /* Switch from nested_hwpt_id[0] to nested_hwpt_id[1] */
+ test_cmd_mock_domain_replace(self->stdev_id, nested_hwpt_id[1]);
+ EXPECT_ERRNO(EBUSY,
+ _test_ioctl_destroy(self->fd, nested_hwpt_id[1]));
+ test_ioctl_destroy(nested_hwpt_id[0]);
+
+ /* Detach from nested_hwpt_id[1] and destroy it */
+ test_cmd_mock_domain_replace(self->stdev_id, parent_hwpt_id);
+ test_ioctl_destroy(nested_hwpt_id[1]);
+
+ /* Detach from the parent hw_pagetable and destroy it */
+ test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
+ test_ioctl_destroy(parent_hwpt_id);
+ test_ioctl_destroy(parent_hwpt_id_not_work);
+ } else {
+ test_err_hwpt_alloc(ENOENT, self->device_id, self->ioas_id, 0,
+ &parent_hwpt_id);
+ test_err_hwpt_alloc_nested(ENOENT, self->device_id,
+ parent_hwpt_id, 0,
+ &nested_hwpt_id[0],
+ IOMMU_HWPT_DATA_SELFTEST, &data,
+ sizeof(data));
+ test_err_hwpt_alloc_nested(ENOENT, self->device_id,
+ parent_hwpt_id, 0,
+ &nested_hwpt_id[1],
+ IOMMU_HWPT_DATA_SELFTEST, &data,
+ sizeof(data));
+ test_err_mock_domain_replace(ENOENT, self->stdev_id,
+ nested_hwpt_id[0]);
+ test_err_mock_domain_replace(ENOENT, self->stdev_id,
+ nested_hwpt_id[1]);
+ }
+}
+
TEST_F(iommufd_ioas, hwpt_attach)
{
/* Create a device attached directly to a hwpt */
@@ -1404,16 +1523,242 @@ TEST_F(iommufd_mock_domain, alloc_hwpt)
int i;
for (i = 0; i != variant->mock_domains; i++) {
+ uint32_t hwpt_id[2];
uint32_t stddev_id;
- uint32_t hwpt_id;
- test_cmd_hwpt_alloc(self->idev_ids[0], self->ioas_id, &hwpt_id);
- test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
+ test_err_hwpt_alloc(EOPNOTSUPP,
+ self->idev_ids[i], self->ioas_id,
+ ~IOMMU_HWPT_ALLOC_NEST_PARENT, &hwpt_id[0]);
+ test_cmd_hwpt_alloc(self->idev_ids[i], self->ioas_id,
+ 0, &hwpt_id[0]);
+ test_cmd_hwpt_alloc(self->idev_ids[i], self->ioas_id,
+ IOMMU_HWPT_ALLOC_NEST_PARENT, &hwpt_id[1]);
+
+ /* Do a hw_pagetable rotation test */
+ test_cmd_mock_domain_replace(self->stdev_ids[i], hwpt_id[0]);
+ EXPECT_ERRNO(EBUSY, _test_ioctl_destroy(self->fd, hwpt_id[0]));
+ test_cmd_mock_domain_replace(self->stdev_ids[i], hwpt_id[1]);
+ EXPECT_ERRNO(EBUSY, _test_ioctl_destroy(self->fd, hwpt_id[1]));
+ test_cmd_mock_domain_replace(self->stdev_ids[i], self->ioas_id);
+ test_ioctl_destroy(hwpt_id[1]);
+
+ test_cmd_mock_domain(hwpt_id[0], &stddev_id, NULL, NULL);
test_ioctl_destroy(stddev_id);
- test_ioctl_destroy(hwpt_id);
+ test_ioctl_destroy(hwpt_id[0]);
}
}
+FIXTURE(iommufd_dirty_tracking)
+{
+ int fd;
+ uint32_t ioas_id;
+ uint32_t hwpt_id;
+ uint32_t stdev_id;
+ uint32_t idev_id;
+ unsigned long page_size;
+ unsigned long bitmap_size;
+ void *bitmap;
+ void *buffer;
+};
+
+FIXTURE_VARIANT(iommufd_dirty_tracking)
+{
+ unsigned long buffer_size;
+};
+
+FIXTURE_SETUP(iommufd_dirty_tracking)
+{
+ void *vrc;
+ int rc;
+
+ self->fd = open("/dev/iommu", O_RDWR);
+ ASSERT_NE(-1, self->fd);
+
+ rc = posix_memalign(&self->buffer, HUGEPAGE_SIZE, variant->buffer_size);
+ if (rc || !self->buffer) {
+ SKIP(return, "Skipping buffer_size=%lu due to errno=%d",
+ variant->buffer_size, rc);
+ }
+
+ assert((uintptr_t)self->buffer % HUGEPAGE_SIZE == 0);
+ vrc = mmap(self->buffer, variant->buffer_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ assert(vrc == self->buffer);
+
+ self->page_size = MOCK_PAGE_SIZE;
+ self->bitmap_size =
+ variant->buffer_size / self->page_size / BITS_PER_BYTE;
+
+ /* Provision with an extra (MOCK_PAGE_SIZE) for the unaligned case */
+ rc = posix_memalign(&self->bitmap, PAGE_SIZE,
+ self->bitmap_size + MOCK_PAGE_SIZE);
+ assert(!rc);
+ assert(self->bitmap);
+ assert((uintptr_t)self->bitmap % PAGE_SIZE == 0);
+
+ test_ioctl_ioas_alloc(&self->ioas_id);
+ test_cmd_mock_domain(self->ioas_id, &self->stdev_id, &self->hwpt_id,
+ &self->idev_id);
+}
+
+FIXTURE_TEARDOWN(iommufd_dirty_tracking)
+{
+ munmap(self->buffer, variant->buffer_size);
+ munmap(self->bitmap, self->bitmap_size);
+ teardown_iommufd(self->fd, _metadata);
+}
+
+FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty128k)
+{
+ /* one u32 index bitmap */
+ .buffer_size = 128UL * 1024UL,
+};
+
+FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty256k)
+{
+ /* one u64 index bitmap */
+ .buffer_size = 256UL * 1024UL,
+};
+
+FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty640k)
+{
+ /* two u64 index and trailing end bitmap */
+ .buffer_size = 640UL * 1024UL,
+};
+
+FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty128M)
+{
+ /* 4K bitmap (128M IOVA range) */
+ .buffer_size = 128UL * 1024UL * 1024UL,
+};
+
+FIXTURE_VARIANT_ADD(iommufd_dirty_tracking, domain_dirty256M)
+{
+ /* 8K bitmap (256M IOVA range) */
+ .buffer_size = 256UL * 1024UL * 1024UL,
+};
+
+TEST_F(iommufd_dirty_tracking, enforce_dirty)
+{
+ uint32_t ioas_id, stddev_id, idev_id;
+ uint32_t hwpt_id, _hwpt_id;
+ uint32_t dev_flags;
+
+ /* Regular case */
+ dev_flags = MOCK_FLAGS_DEVICE_NO_DIRTY;
+ test_cmd_hwpt_alloc(self->idev_id, self->ioas_id,
+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
+ test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
+ test_err_mock_domain_flags(EINVAL, hwpt_id, dev_flags, &stddev_id,
+ NULL);
+ test_ioctl_destroy(stddev_id);
+ test_ioctl_destroy(hwpt_id);
+
+ /* IOMMU device does not support dirty tracking */
+ test_ioctl_ioas_alloc(&ioas_id);
+ test_cmd_mock_domain_flags(ioas_id, dev_flags, &stddev_id, &_hwpt_id,
+ &idev_id);
+ test_err_hwpt_alloc(EOPNOTSUPP, idev_id, ioas_id,
+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
+ test_ioctl_destroy(stddev_id);
+}
+
+TEST_F(iommufd_dirty_tracking, set_dirty_tracking)
+{
+ uint32_t stddev_id;
+ uint32_t hwpt_id;
+
+ test_cmd_hwpt_alloc(self->idev_id, self->ioas_id,
+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
+ test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
+ test_cmd_set_dirty_tracking(hwpt_id, true);
+ test_cmd_set_dirty_tracking(hwpt_id, false);
+
+ test_ioctl_destroy(stddev_id);
+ test_ioctl_destroy(hwpt_id);
+}
+
+TEST_F(iommufd_dirty_tracking, device_dirty_capability)
+{
+ uint32_t caps = 0;
+ uint32_t stddev_id;
+ uint32_t hwpt_id;
+
+ test_cmd_hwpt_alloc(self->idev_id, self->ioas_id, 0, &hwpt_id);
+ test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
+ test_cmd_get_hw_capabilities(self->idev_id, caps,
+ IOMMU_HW_CAP_DIRTY_TRACKING);
+ ASSERT_EQ(IOMMU_HW_CAP_DIRTY_TRACKING,
+ caps & IOMMU_HW_CAP_DIRTY_TRACKING);
+
+ test_ioctl_destroy(stddev_id);
+ test_ioctl_destroy(hwpt_id);
+}
+
+TEST_F(iommufd_dirty_tracking, get_dirty_bitmap)
+{
+ uint32_t stddev_id;
+ uint32_t hwpt_id;
+ uint32_t ioas_id;
+
+ test_ioctl_ioas_alloc(&ioas_id);
+ test_ioctl_ioas_map_fixed_id(ioas_id, self->buffer,
+ variant->buffer_size, MOCK_APERTURE_START);
+
+ test_cmd_hwpt_alloc(self->idev_id, ioas_id,
+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
+ test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
+
+ test_cmd_set_dirty_tracking(hwpt_id, true);
+
+ test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
+ MOCK_APERTURE_START, self->page_size,
+ self->bitmap, self->bitmap_size, 0, _metadata);
+
+ /* PAGE_SIZE unaligned bitmap */
+ test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
+ MOCK_APERTURE_START, self->page_size,
+ self->bitmap + MOCK_PAGE_SIZE,
+ self->bitmap_size, 0, _metadata);
+
+ test_ioctl_destroy(stddev_id);
+ test_ioctl_destroy(hwpt_id);
+}
+
+TEST_F(iommufd_dirty_tracking, get_dirty_bitmap_no_clear)
+{
+ uint32_t stddev_id;
+ uint32_t hwpt_id;
+ uint32_t ioas_id;
+
+ test_ioctl_ioas_alloc(&ioas_id);
+ test_ioctl_ioas_map_fixed_id(ioas_id, self->buffer,
+ variant->buffer_size, MOCK_APERTURE_START);
+
+ test_cmd_hwpt_alloc(self->idev_id, ioas_id,
+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
+ test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
+
+ test_cmd_set_dirty_tracking(hwpt_id, true);
+
+ test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
+ MOCK_APERTURE_START, self->page_size,
+ self->bitmap, self->bitmap_size,
+ IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR,
+ _metadata);
+
+ /* Unaligned bitmap */
+ test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
+ MOCK_APERTURE_START, self->page_size,
+ self->bitmap + MOCK_PAGE_SIZE,
+ self->bitmap_size,
+ IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR,
+ _metadata);
+
+ test_ioctl_destroy(stddev_id);
+ test_ioctl_destroy(hwpt_id);
+}
+
/* VFIO compatibility IOCTLs */
TEST_F(iommufd, simple_ioctls)
@@ -1729,7 +2074,7 @@ TEST_F(vfio_compat_mock_domain, map)
ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
ASSERT_EQ(BUFFER_SIZE, unmap_cmd.size);
- /* UNMAP_FLAG_ALL requres 0 iova/size */
+ /* UNMAP_FLAG_ALL requires 0 iova/size */
ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));
unmap_cmd.flags = VFIO_DMA_UNMAP_FLAG_ALL;
EXPECT_ERRNO(EINVAL, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
diff --git a/tools/testing/selftests/iommu/iommufd_fail_nth.c b/tools/testing/selftests/iommu/iommufd_fail_nth.c
index a220ca2a689d..f590417cd67a 100644
--- a/tools/testing/selftests/iommu/iommufd_fail_nth.c
+++ b/tools/testing/selftests/iommu/iommufd_fail_nth.c
@@ -105,7 +105,7 @@ static bool fail_nth_next(struct __test_metadata *_metadata,
/*
* This is just an arbitrary limit based on the current kernel
- * situation. Changes in the kernel can dramtically change the number of
+ * situation. Changes in the kernel can dramatically change the number of
* required fault injection sites, so if this hits it doesn't
* necessarily mean a test failure, just that the limit has to be made
* bigger.
@@ -612,10 +612,11 @@ TEST_FAIL_NTH(basic_fail_nth, device)
&idev_id))
return -1;
- if (_test_cmd_get_hw_info(self->fd, idev_id, &info, sizeof(info)))
+ if (_test_cmd_get_hw_info(self->fd, idev_id, &info, sizeof(info), NULL))
return -1;
- if (_test_cmd_hwpt_alloc(self->fd, idev_id, ioas_id, &hwpt_id))
+ if (_test_cmd_hwpt_alloc(self->fd, idev_id, ioas_id, 0, &hwpt_id,
+ IOMMU_HWPT_DATA_NONE, 0, 0))
return -1;
if (_test_cmd_mock_domain_replace(self->fd, stdev_id, ioas_id2, NULL))
diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
index e0753d03ecaa..050e9751321c 100644
--- a/tools/testing/selftests/iommu/iommufd_utils.h
+++ b/tools/testing/selftests/iommu/iommufd_utils.h
@@ -16,6 +16,25 @@
/* Hack to make assertions more readable */
#define _IOMMU_TEST_CMD(x) IOMMU_TEST_CMD
+/* Imported from include/asm-generic/bitops/generic-non-atomic.h */
+#define BITS_PER_BYTE 8
+#define BITS_PER_LONG __BITS_PER_LONG
+#define BIT_MASK(nr) (1UL << ((nr) % __BITS_PER_LONG))
+#define BIT_WORD(nr) ((nr) / __BITS_PER_LONG)
+
+static inline void set_bit(unsigned int nr, unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+ *p |= mask;
+}
+
+static inline bool test_bit(unsigned int nr, unsigned long *addr)
+{
+ return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG - 1)));
+}
+
static void *buffer;
static unsigned long BUFFER_SIZE;
@@ -74,6 +93,38 @@ static int _test_cmd_mock_domain(int fd, unsigned int ioas_id, __u32 *stdev_id,
EXPECT_ERRNO(_errno, _test_cmd_mock_domain(self->fd, ioas_id, \
stdev_id, hwpt_id, NULL))
+static int _test_cmd_mock_domain_flags(int fd, unsigned int ioas_id,
+ __u32 stdev_flags, __u32 *stdev_id,
+ __u32 *hwpt_id, __u32 *idev_id)
+{
+ struct iommu_test_cmd cmd = {
+ .size = sizeof(cmd),
+ .op = IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS,
+ .id = ioas_id,
+ .mock_domain_flags = { .dev_flags = stdev_flags },
+ };
+ int ret;
+
+ ret = ioctl(fd, IOMMU_TEST_CMD, &cmd);
+ if (ret)
+ return ret;
+ if (stdev_id)
+ *stdev_id = cmd.mock_domain_flags.out_stdev_id;
+ assert(cmd.id != 0);
+ if (hwpt_id)
+ *hwpt_id = cmd.mock_domain_flags.out_hwpt_id;
+ if (idev_id)
+ *idev_id = cmd.mock_domain_flags.out_idev_id;
+ return 0;
+}
+#define test_cmd_mock_domain_flags(ioas_id, flags, stdev_id, hwpt_id, idev_id) \
+ ASSERT_EQ(0, _test_cmd_mock_domain_flags(self->fd, ioas_id, flags, \
+ stdev_id, hwpt_id, idev_id))
+#define test_err_mock_domain_flags(_errno, ioas_id, flags, stdev_id, hwpt_id) \
+ EXPECT_ERRNO(_errno, \
+ _test_cmd_mock_domain_flags(self->fd, ioas_id, flags, \
+ stdev_id, hwpt_id, NULL))
+
static int _test_cmd_mock_domain_replace(int fd, __u32 stdev_id, __u32 pt_id,
__u32 *hwpt_id)
{
@@ -103,12 +154,17 @@ static int _test_cmd_mock_domain_replace(int fd, __u32 stdev_id, __u32 pt_id,
pt_id, NULL))
static int _test_cmd_hwpt_alloc(int fd, __u32 device_id, __u32 pt_id,
- __u32 *hwpt_id)
+ __u32 flags, __u32 *hwpt_id, __u32 data_type,
+ void *data, size_t data_len)
{
struct iommu_hwpt_alloc cmd = {
.size = sizeof(cmd),
+ .flags = flags,
.dev_id = device_id,
.pt_id = pt_id,
+ .data_type = data_type,
+ .data_len = data_len,
+ .data_uptr = (uint64_t)data,
};
int ret;
@@ -120,8 +176,24 @@ static int _test_cmd_hwpt_alloc(int fd, __u32 device_id, __u32 pt_id,
return 0;
}
-#define test_cmd_hwpt_alloc(device_id, pt_id, hwpt_id) \
- ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, hwpt_id))
+#define test_cmd_hwpt_alloc(device_id, pt_id, flags, hwpt_id) \
+ ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, flags, \
+ hwpt_id, IOMMU_HWPT_DATA_NONE, NULL, \
+ 0))
+#define test_err_hwpt_alloc(_errno, device_id, pt_id, flags, hwpt_id) \
+ EXPECT_ERRNO(_errno, _test_cmd_hwpt_alloc( \
+ self->fd, device_id, pt_id, flags, \
+ hwpt_id, IOMMU_HWPT_DATA_NONE, NULL, 0))
+
+#define test_cmd_hwpt_alloc_nested(device_id, pt_id, flags, hwpt_id, \
+ data_type, data, data_len) \
+ ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, flags, \
+ hwpt_id, data_type, data, data_len))
+#define test_err_hwpt_alloc_nested(_errno, device_id, pt_id, flags, hwpt_id, \
+ data_type, data, data_len) \
+ EXPECT_ERRNO(_errno, \
+ _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, flags, \
+ hwpt_id, data_type, data, data_len))
static int _test_cmd_access_replace_ioas(int fd, __u32 access_id,
unsigned int ioas_id)
@@ -142,6 +214,126 @@ static int _test_cmd_access_replace_ioas(int fd, __u32 access_id,
#define test_cmd_access_replace_ioas(access_id, ioas_id) \
ASSERT_EQ(0, _test_cmd_access_replace_ioas(self->fd, access_id, ioas_id))
+static int _test_cmd_set_dirty_tracking(int fd, __u32 hwpt_id, bool enabled)
+{
+ struct iommu_hwpt_set_dirty_tracking cmd = {
+ .size = sizeof(cmd),
+ .flags = enabled ? IOMMU_HWPT_DIRTY_TRACKING_ENABLE : 0,
+ .hwpt_id = hwpt_id,
+ };
+ int ret;
+
+ ret = ioctl(fd, IOMMU_HWPT_SET_DIRTY_TRACKING, &cmd);
+ if (ret)
+ return -errno;
+ return 0;
+}
+#define test_cmd_set_dirty_tracking(hwpt_id, enabled) \
+ ASSERT_EQ(0, _test_cmd_set_dirty_tracking(self->fd, hwpt_id, enabled))
+
+static int _test_cmd_get_dirty_bitmap(int fd, __u32 hwpt_id, size_t length,
+ __u64 iova, size_t page_size,
+ __u64 *bitmap, __u32 flags)
+{
+ struct iommu_hwpt_get_dirty_bitmap cmd = {
+ .size = sizeof(cmd),
+ .hwpt_id = hwpt_id,
+ .flags = flags,
+ .iova = iova,
+ .length = length,
+ .page_size = page_size,
+ .data = (uintptr_t)bitmap,
+ };
+ int ret;
+
+ ret = ioctl(fd, IOMMU_HWPT_GET_DIRTY_BITMAP, &cmd);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+#define test_cmd_get_dirty_bitmap(fd, hwpt_id, length, iova, page_size, \
+ bitmap, flags) \
+ ASSERT_EQ(0, _test_cmd_get_dirty_bitmap(fd, hwpt_id, length, iova, \
+ page_size, bitmap, flags))
+
+static int _test_cmd_mock_domain_set_dirty(int fd, __u32 hwpt_id, size_t length,
+ __u64 iova, size_t page_size,
+ __u64 *bitmap, __u64 *dirty)
+{
+ struct iommu_test_cmd cmd = {
+ .size = sizeof(cmd),
+ .op = IOMMU_TEST_OP_DIRTY,
+ .id = hwpt_id,
+ .dirty = {
+ .iova = iova,
+ .length = length,
+ .page_size = page_size,
+ .uptr = (uintptr_t)bitmap,
+ }
+ };
+ int ret;
+
+ ret = ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_DIRTY), &cmd);
+ if (ret)
+ return -ret;
+ if (dirty)
+ *dirty = cmd.dirty.out_nr_dirty;
+ return 0;
+}
+
+#define test_cmd_mock_domain_set_dirty(fd, hwpt_id, length, iova, page_size, \
+ bitmap, nr) \
+ ASSERT_EQ(0, \
+ _test_cmd_mock_domain_set_dirty(fd, hwpt_id, length, iova, \
+ page_size, bitmap, nr))
+
+static int _test_mock_dirty_bitmaps(int fd, __u32 hwpt_id, size_t length,
+ __u64 iova, size_t page_size, __u64 *bitmap,
+ __u64 bitmap_size, __u32 flags,
+ struct __test_metadata *_metadata)
+{
+ unsigned long i, count, nbits = bitmap_size * BITS_PER_BYTE;
+ unsigned long nr = nbits / 2;
+ __u64 out_dirty = 0;
+
+ /* Mark all even bits as dirty in the mock domain */
+ for (count = 0, i = 0; i < nbits; count += !(i % 2), i++)
+ if (!(i % 2))
+ set_bit(i, (unsigned long *)bitmap);
+ ASSERT_EQ(nr, count);
+
+ test_cmd_mock_domain_set_dirty(fd, hwpt_id, length, iova, page_size,
+ bitmap, &out_dirty);
+ ASSERT_EQ(nr, out_dirty);
+
+ /* Expect all even bits as dirty in the user bitmap */
+ memset(bitmap, 0, bitmap_size);
+ test_cmd_get_dirty_bitmap(fd, hwpt_id, length, iova, page_size, bitmap,
+ flags);
+ for (count = 0, i = 0; i < nbits; count += !(i % 2), i++)
+ ASSERT_EQ(!(i % 2), test_bit(i, (unsigned long *)bitmap));
+ ASSERT_EQ(count, out_dirty);
+
+ memset(bitmap, 0, bitmap_size);
+ test_cmd_get_dirty_bitmap(fd, hwpt_id, length, iova, page_size, bitmap,
+ flags);
+
+ /* It as read already -- expect all zeroes */
+ for (i = 0; i < nbits; i++) {
+ ASSERT_EQ(!(i % 2) && (flags &
+ IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR),
+ test_bit(i, (unsigned long *)bitmap));
+ }
+
+ return 0;
+}
+#define test_mock_dirty_bitmaps(hwpt_id, length, iova, page_size, bitmap, \
+ bitmap_size, flags, _metadata) \
+ ASSERT_EQ(0, _test_mock_dirty_bitmaps(self->fd, hwpt_id, length, iova, \
+ page_size, bitmap, bitmap_size, \
+ flags, _metadata))
+
static int _test_cmd_create_access(int fd, unsigned int ioas_id,
__u32 *access_id, unsigned int flags)
{
@@ -266,6 +458,17 @@ static int _test_ioctl_ioas_map(int fd, unsigned int ioas_id, void *buffer,
IOMMU_IOAS_MAP_READABLE)); \
})
+#define test_ioctl_ioas_map_fixed_id(ioas_id, buffer, length, iova) \
+ ({ \
+ __u64 __iova = iova; \
+ ASSERT_EQ(0, \
+ _test_ioctl_ioas_map( \
+ self->fd, ioas_id, buffer, length, &__iova, \
+ IOMMU_IOAS_MAP_FIXED_IOVA | \
+ IOMMU_IOAS_MAP_WRITEABLE | \
+ IOMMU_IOAS_MAP_READABLE)); \
+ })
+
#define test_err_ioctl_ioas_map_fixed(_errno, buffer, length, iova) \
({ \
__u64 __iova = iova; \
@@ -354,8 +557,8 @@ static void teardown_iommufd(int fd, struct __test_metadata *_metadata)
#endif
/* @data can be NULL */
-static int _test_cmd_get_hw_info(int fd, __u32 device_id,
- void *data, size_t data_len)
+static int _test_cmd_get_hw_info(int fd, __u32 device_id, void *data,
+ size_t data_len, uint32_t *capabilities)
{
struct iommu_test_hw_info *info = (struct iommu_test_hw_info *)data;
struct iommu_hw_info cmd = {
@@ -363,6 +566,7 @@ static int _test_cmd_get_hw_info(int fd, __u32 device_id,
.dev_id = device_id,
.data_len = data_len,
.data_uptr = (uint64_t)data,
+ .out_capabilities = 0,
};
int ret;
@@ -399,14 +603,19 @@ static int _test_cmd_get_hw_info(int fd, __u32 device_id,
assert(!info->flags);
}
+ if (capabilities)
+ *capabilities = cmd.out_capabilities;
+
return 0;
}
-#define test_cmd_get_hw_info(device_id, data, data_len) \
- ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, \
- data, data_len))
+#define test_cmd_get_hw_info(device_id, data, data_len) \
+ ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, data, \
+ data_len, NULL))
+
+#define test_err_get_hw_info(_errno, device_id, data, data_len) \
+ EXPECT_ERRNO(_errno, _test_cmd_get_hw_info(self->fd, device_id, data, \
+ data_len, NULL))
-#define test_err_get_hw_info(_errno, device_id, data, data_len) \
- EXPECT_ERRNO(_errno, \
- _test_cmd_get_hw_info(self->fd, device_id, \
- data, data_len))
+#define test_cmd_get_hw_capabilities(device_id, caps, mask) \
+ ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, NULL, 0, &caps))
diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
index 529d29a35900..a781e6311810 100644
--- a/tools/testing/selftests/kselftest.h
+++ b/tools/testing/selftests/kselftest.h
@@ -48,6 +48,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
+#include <string.h>
#include <stdio.h>
#endif
@@ -77,6 +78,8 @@
#define KSFT_XPASS 3
#define KSFT_SKIP 4
+#define __printf(a, b) __attribute__((format(printf, a, b)))
+
/* counters */
struct ksft_count {
unsigned int ksft_pass;
@@ -129,7 +132,7 @@ static inline void ksft_print_header(void)
static inline void ksft_set_plan(unsigned int plan)
{
ksft_plan = plan;
- printf("1..%d\n", ksft_plan);
+ printf("1..%u\n", ksft_plan);
}
static inline void ksft_print_cnts(void)
@@ -137,13 +140,13 @@ static inline void ksft_print_cnts(void)
if (ksft_plan != ksft_test_num())
printf("# Planned tests != run tests (%u != %u)\n",
ksft_plan, ksft_test_num());
- printf("# Totals: pass:%d fail:%d xfail:%d xpass:%d skip:%d error:%d\n",
+ printf("# Totals: pass:%u fail:%u xfail:%u xpass:%u skip:%u error:%u\n",
ksft_cnt.ksft_pass, ksft_cnt.ksft_fail,
ksft_cnt.ksft_xfail, ksft_cnt.ksft_xpass,
ksft_cnt.ksft_xskip, ksft_cnt.ksft_error);
}
-static inline void ksft_print_msg(const char *msg, ...)
+static inline __printf(1, 2) void ksft_print_msg(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
@@ -155,7 +158,20 @@ static inline void ksft_print_msg(const char *msg, ...)
va_end(args);
}
-static inline void ksft_test_result_pass(const char *msg, ...)
+static inline void ksft_perror(const char *msg)
+{
+#ifndef NOLIBC
+ ksft_print_msg("%s: %s (%d)\n", msg, strerror(errno), errno);
+#else
+ /*
+ * nolibc doesn't provide strerror() and it seems
+ * inappropriate to add one, just print the errno.
+ */
+ ksft_print_msg("%s: %d)\n", msg, errno);
+#endif
+}
+
+static inline __printf(1, 2) void ksft_test_result_pass(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
@@ -163,13 +179,13 @@ static inline void ksft_test_result_pass(const char *msg, ...)
ksft_cnt.ksft_pass++;
va_start(args, msg);
- printf("ok %d ", ksft_test_num());
+ printf("ok %u ", ksft_test_num());
errno = saved_errno;
vprintf(msg, args);
va_end(args);
}
-static inline void ksft_test_result_fail(const char *msg, ...)
+static inline __printf(1, 2) void ksft_test_result_fail(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
@@ -177,7 +193,7 @@ static inline void ksft_test_result_fail(const char *msg, ...)
ksft_cnt.ksft_fail++;
va_start(args, msg);
- printf("not ok %d ", ksft_test_num());
+ printf("not ok %u ", ksft_test_num());
errno = saved_errno;
vprintf(msg, args);
va_end(args);
@@ -195,7 +211,7 @@ static inline void ksft_test_result_fail(const char *msg, ...)
ksft_test_result_fail(fmt, ##__VA_ARGS__);\
} while (0)
-static inline void ksft_test_result_xfail(const char *msg, ...)
+static inline __printf(1, 2) void ksft_test_result_xfail(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
@@ -203,13 +219,13 @@ static inline void ksft_test_result_xfail(const char *msg, ...)
ksft_cnt.ksft_xfail++;
va_start(args, msg);
- printf("ok %d # XFAIL ", ksft_test_num());
+ printf("ok %u # XFAIL ", ksft_test_num());
errno = saved_errno;
vprintf(msg, args);
va_end(args);
}
-static inline void ksft_test_result_skip(const char *msg, ...)
+static inline __printf(1, 2) void ksft_test_result_skip(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
@@ -217,14 +233,14 @@ static inline void ksft_test_result_skip(const char *msg, ...)
ksft_cnt.ksft_xskip++;
va_start(args, msg);
- printf("ok %d # SKIP ", ksft_test_num());
+ printf("ok %u # SKIP ", ksft_test_num());
errno = saved_errno;
vprintf(msg, args);
va_end(args);
}
/* TODO: how does "error" differ from "fail" or "skip"? */
-static inline void ksft_test_result_error(const char *msg, ...)
+static inline __printf(1, 2) void ksft_test_result_error(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
@@ -232,7 +248,7 @@ static inline void ksft_test_result_error(const char *msg, ...)
ksft_cnt.ksft_error++;
va_start(args, msg);
- printf("not ok %d # error ", ksft_test_num());
+ printf("not ok %u # error ", ksft_test_num());
errno = saved_errno;
vprintf(msg, args);
va_end(args);
@@ -271,7 +287,7 @@ static inline int ksft_exit_fail(void)
ksft_cnt.ksft_xfail + \
ksft_cnt.ksft_xskip)
-static inline int ksft_exit_fail_msg(const char *msg, ...)
+static inline __printf(1, 2) int ksft_exit_fail_msg(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
@@ -298,7 +314,7 @@ static inline int ksft_exit_xpass(void)
exit(KSFT_XPASS);
}
-static inline int ksft_exit_skip(const char *msg, ...)
+static inline __printf(1, 2) int ksft_exit_skip(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testing/selftests/kvm/include/test_util.h
index 7e614adc6cf4..8e5f413a593d 100644
--- a/tools/testing/selftests/kvm/include/test_util.h
+++ b/tools/testing/selftests/kvm/include/test_util.h
@@ -33,7 +33,7 @@ static inline int _no_printf(const char *format, ...) { return 0; }
#define pr_info(...) _no_printf(__VA_ARGS__)
#endif
-void print_skip(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
+void __printf(1, 2) print_skip(const char *fmt, ...);
#define __TEST_REQUIRE(f, fmt, ...) \
do { \
if (!(f)) \
@@ -46,9 +46,9 @@ ssize_t test_write(int fd, const void *buf, size_t count);
ssize_t test_read(int fd, void *buf, size_t count);
int test_seq_read(const char *path, char **bufp, size_t *sizep);
-void test_assert(bool exp, const char *exp_str,
- const char *file, unsigned int line, const char *fmt, ...)
- __attribute__((format(printf, 5, 6)));
+void __printf(5, 6) test_assert(bool exp, const char *exp_str,
+ const char *file, unsigned int line,
+ const char *fmt, ...);
#define TEST_ASSERT(e, fmt, ...) \
test_assert((e), #e, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
diff --git a/tools/testing/selftests/mm/mremap_test.c b/tools/testing/selftests/mm/mremap_test.c
index 5c3773de9f0f..1dbfcf6df255 100644
--- a/tools/testing/selftests/mm/mremap_test.c
+++ b/tools/testing/selftests/mm/mremap_test.c
@@ -338,7 +338,7 @@ static long long remap_region(struct config c, unsigned int threshold_mb,
char c = (char) rand();
if (((char *) dest_addr)[i] != c) {
- ksft_print_msg("Data after remap doesn't match at offset %d\n",
+ ksft_print_msg("Data after remap doesn't match at offset %llu\n",
i);
ksft_print_msg("Expected: %#x\t Got: %#x\n", c & 0xff,
((char *) dest_addr)[i] & 0xff);
diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index 92f3be3dd8e5..1af3156a9db8 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -34,7 +34,7 @@ extern int test_nr;
extern int iteration_nr;
#ifdef __GNUC__
-__attribute__((format(printf, 1, 2)))
+__printf(1, 2)
#endif
static inline void sigsafe_printf(const char *format, ...)
{
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index b9804ceb9494..5b2aca4c5f10 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -100,6 +100,7 @@ $(OUTPUT)/reuseport_bpf_numa: LDLIBS += -lnuma
$(OUTPUT)/tcp_mmap: LDLIBS += -lpthread -lcrypto
$(OUTPUT)/tcp_inq: LDLIBS += -lpthread
$(OUTPUT)/bind_bhash: LDLIBS += -lpthread
+$(OUTPUT)/io_uring_zerocopy_tx: CFLAGS += -I../../../include/
# Rules to generate bpf obj nat6to4.o
CLANG ?= clang
diff --git a/tools/testing/selftests/net/io_uring_zerocopy_tx.c b/tools/testing/selftests/net/io_uring_zerocopy_tx.c
index 154287740172..76e604e4810e 100644
--- a/tools/testing/selftests/net/io_uring_zerocopy_tx.c
+++ b/tools/testing/selftests/net/io_uring_zerocopy_tx.c
@@ -36,6 +36,8 @@
#include <sys/un.h>
#include <sys/wait.h>
+#include <io_uring/mini_liburing.h>
+
#define NOTIF_TAG 0xfffffffULL
#define NONZC_TAG 0
#define ZC_TAG 1
@@ -60,272 +62,6 @@ static struct sockaddr_storage cfg_dst_addr;
static char payload[IP_MAXPACKET] __attribute__((aligned(4096)));
-struct io_sq_ring {
- unsigned *head;
- unsigned *tail;
- unsigned *ring_mask;
- unsigned *ring_entries;
- unsigned *flags;
- unsigned *array;
-};
-
-struct io_cq_ring {
- unsigned *head;
- unsigned *tail;
- unsigned *ring_mask;
- unsigned *ring_entries;
- struct io_uring_cqe *cqes;
-};
-
-struct io_uring_sq {
- unsigned *khead;
- unsigned *ktail;
- unsigned *kring_mask;
- unsigned *kring_entries;
- unsigned *kflags;
- unsigned *kdropped;
- unsigned *array;
- struct io_uring_sqe *sqes;
-
- unsigned sqe_head;
- unsigned sqe_tail;
-
- size_t ring_sz;
-};
-
-struct io_uring_cq {
- unsigned *khead;
- unsigned *ktail;
- unsigned *kring_mask;
- unsigned *kring_entries;
- unsigned *koverflow;
- struct io_uring_cqe *cqes;
-
- size_t ring_sz;
-};
-
-struct io_uring {
- struct io_uring_sq sq;
- struct io_uring_cq cq;
- int ring_fd;
-};
-
-#ifdef __alpha__
-# ifndef __NR_io_uring_setup
-# define __NR_io_uring_setup 535
-# endif
-# ifndef __NR_io_uring_enter
-# define __NR_io_uring_enter 536
-# endif
-# ifndef __NR_io_uring_register
-# define __NR_io_uring_register 537
-# endif
-#else /* !__alpha__ */
-# ifndef __NR_io_uring_setup
-# define __NR_io_uring_setup 425
-# endif
-# ifndef __NR_io_uring_enter
-# define __NR_io_uring_enter 426
-# endif
-# ifndef __NR_io_uring_register
-# define __NR_io_uring_register 427
-# endif
-#endif
-
-#if defined(__x86_64) || defined(__i386__)
-#define read_barrier() __asm__ __volatile__("":::"memory")
-#define write_barrier() __asm__ __volatile__("":::"memory")
-#else
-
-#define read_barrier() __sync_synchronize()
-#define write_barrier() __sync_synchronize()
-#endif
-
-static int io_uring_setup(unsigned int entries, struct io_uring_params *p)
-{
- return syscall(__NR_io_uring_setup, entries, p);
-}
-
-static int io_uring_enter(int fd, unsigned int to_submit,
- unsigned int min_complete,
- unsigned int flags, sigset_t *sig)
-{
- return syscall(__NR_io_uring_enter, fd, to_submit, min_complete,
- flags, sig, _NSIG / 8);
-}
-
-static int io_uring_register_buffers(struct io_uring *ring,
- const struct iovec *iovecs,
- unsigned nr_iovecs)
-{
- int ret;
-
- ret = syscall(__NR_io_uring_register, ring->ring_fd,
- IORING_REGISTER_BUFFERS, iovecs, nr_iovecs);
- return (ret < 0) ? -errno : ret;
-}
-
-static int io_uring_mmap(int fd, struct io_uring_params *p,
- struct io_uring_sq *sq, struct io_uring_cq *cq)
-{
- size_t size;
- void *ptr;
- int ret;
-
- sq->ring_sz = p->sq_off.array + p->sq_entries * sizeof(unsigned);
- ptr = mmap(0, sq->ring_sz, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_POPULATE, fd, IORING_OFF_SQ_RING);
- if (ptr == MAP_FAILED)
- return -errno;
- sq->khead = ptr + p->sq_off.head;
- sq->ktail = ptr + p->sq_off.tail;
- sq->kring_mask = ptr + p->sq_off.ring_mask;
- sq->kring_entries = ptr + p->sq_off.ring_entries;
- sq->kflags = ptr + p->sq_off.flags;
- sq->kdropped = ptr + p->sq_off.dropped;
- sq->array = ptr + p->sq_off.array;
-
- size = p->sq_entries * sizeof(struct io_uring_sqe);
- sq->sqes = mmap(0, size, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_POPULATE, fd, IORING_OFF_SQES);
- if (sq->sqes == MAP_FAILED) {
- ret = -errno;
-err:
- munmap(sq->khead, sq->ring_sz);
- return ret;
- }
-
- cq->ring_sz = p->cq_off.cqes + p->cq_entries * sizeof(struct io_uring_cqe);
- ptr = mmap(0, cq->ring_sz, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_POPULATE, fd, IORING_OFF_CQ_RING);
- if (ptr == MAP_FAILED) {
- ret = -errno;
- munmap(sq->sqes, p->sq_entries * sizeof(struct io_uring_sqe));
- goto err;
- }
- cq->khead = ptr + p->cq_off.head;
- cq->ktail = ptr + p->cq_off.tail;
- cq->kring_mask = ptr + p->cq_off.ring_mask;
- cq->kring_entries = ptr + p->cq_off.ring_entries;
- cq->koverflow = ptr + p->cq_off.overflow;
- cq->cqes = ptr + p->cq_off.cqes;
- return 0;
-}
-
-static int io_uring_queue_init(unsigned entries, struct io_uring *ring,
- unsigned flags)
-{
- struct io_uring_params p;
- int fd, ret;
-
- memset(ring, 0, sizeof(*ring));
- memset(&p, 0, sizeof(p));
- p.flags = flags;
-
- fd = io_uring_setup(entries, &p);
- if (fd < 0)
- return fd;
- ret = io_uring_mmap(fd, &p, &ring->sq, &ring->cq);
- if (!ret)
- ring->ring_fd = fd;
- else
- close(fd);
- return ret;
-}
-
-static int io_uring_submit(struct io_uring *ring)
-{
- struct io_uring_sq *sq = &ring->sq;
- const unsigned mask = *sq->kring_mask;
- unsigned ktail, submitted, to_submit;
- int ret;
-
- read_barrier();
- if (*sq->khead != *sq->ktail) {
- submitted = *sq->kring_entries;
- goto submit;
- }
- if (sq->sqe_head == sq->sqe_tail)
- return 0;
-
- ktail = *sq->ktail;
- to_submit = sq->sqe_tail - sq->sqe_head;
- for (submitted = 0; submitted < to_submit; submitted++) {
- read_barrier();
- sq->array[ktail++ & mask] = sq->sqe_head++ & mask;
- }
- if (!submitted)
- return 0;
-
- if (*sq->ktail != ktail) {
- write_barrier();
- *sq->ktail = ktail;
- write_barrier();
- }
-submit:
- ret = io_uring_enter(ring->ring_fd, submitted, 0,
- IORING_ENTER_GETEVENTS, NULL);
- return ret < 0 ? -errno : ret;
-}
-
-static inline void io_uring_prep_send(struct io_uring_sqe *sqe, int sockfd,
- const void *buf, size_t len, int flags)
-{
- memset(sqe, 0, sizeof(*sqe));
- sqe->opcode = (__u8) IORING_OP_SEND;
- sqe->fd = sockfd;
- sqe->addr = (unsigned long) buf;
- sqe->len = len;
- sqe->msg_flags = (__u32) flags;
-}
-
-static inline void io_uring_prep_sendzc(struct io_uring_sqe *sqe, int sockfd,
- const void *buf, size_t len, int flags,
- unsigned zc_flags)
-{
- io_uring_prep_send(sqe, sockfd, buf, len, flags);
- sqe->opcode = (__u8) IORING_OP_SEND_ZC;
- sqe->ioprio = zc_flags;
-}
-
-static struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring)
-{
- struct io_uring_sq *sq = &ring->sq;
-
- if (sq->sqe_tail + 1 - sq->sqe_head > *sq->kring_entries)
- return NULL;
- return &sq->sqes[sq->sqe_tail++ & *sq->kring_mask];
-}
-
-static int io_uring_wait_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr)
-{
- struct io_uring_cq *cq = &ring->cq;
- const unsigned mask = *cq->kring_mask;
- unsigned head = *cq->khead;
- int ret;
-
- *cqe_ptr = NULL;
- do {
- read_barrier();
- if (head != *cq->ktail) {
- *cqe_ptr = &cq->cqes[head & mask];
- break;
- }
- ret = io_uring_enter(ring->ring_fd, 0, 1,
- IORING_ENTER_GETEVENTS, NULL);
- if (ret < 0)
- return -errno;
- } while (1);
-
- return 0;
-}
-
-static inline void io_uring_cqe_seen(struct io_uring *ring)
-{
- *(&ring->cq)->khead += 1;
- write_barrier();
-}
-
static unsigned long gettimeofday_ms(void)
{
struct timeval tv;
diff --git a/tools/testing/selftests/openat2/openat2_test.c b/tools/testing/selftests/openat2/openat2_test.c
index 7fb902099de4..9024754530b2 100644
--- a/tools/testing/selftests/openat2/openat2_test.c
+++ b/tools/testing/selftests/openat2/openat2_test.c
@@ -300,7 +300,7 @@ void test_openat2_flags(void)
ksft_print_msg("openat2 unexpectedly returned ");
if (fdpath)
- ksft_print_msg("%d['%s'] with %X (!= %X)\n",
+ ksft_print_msg("%d['%s'] with %X (!= %llX)\n",
fd, fdpath, fdflags,
test->how.flags);
else
diff --git a/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c b/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c
index 4e86f927880c..01cc37bf611c 100644
--- a/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c
+++ b/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c
@@ -62,7 +62,7 @@ static void error_report(struct error *err, const char *test_name)
break;
case PIDFD_PASS:
- ksft_test_result_pass("%s test: Passed\n");
+ ksft_test_result_pass("%s test: Passed\n", test_name);
break;
default:
diff --git a/tools/testing/selftests/pidfd/pidfd_test.c b/tools/testing/selftests/pidfd/pidfd_test.c
index 00a07e7c571c..c081ae91313a 100644
--- a/tools/testing/selftests/pidfd/pidfd_test.c
+++ b/tools/testing/selftests/pidfd/pidfd_test.c
@@ -381,13 +381,13 @@ static int test_pidfd_send_signal_syscall_support(void)
static void *test_pidfd_poll_exec_thread(void *priv)
{
- ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n",
+ ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n",
getpid(), syscall(SYS_gettid));
ksft_print_msg("Child Thread: doing exec of sleep\n");
execl("/bin/sleep", "sleep", str(CHILD_THREAD_MIN_WAIT), (char *)NULL);
- ksft_print_msg("Child Thread: DONE. pid %d tid %d\n",
+ ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n",
getpid(), syscall(SYS_gettid));
return NULL;
}
@@ -427,7 +427,7 @@ static int child_poll_exec_test(void *args)
{
pthread_t t1;
- ksft_print_msg("Child (pidfd): starting. pid %d tid %d\n", getpid(),
+ ksft_print_msg("Child (pidfd): starting. pid %d tid %ld\n", getpid(),
syscall(SYS_gettid));
pthread_create(&t1, NULL, test_pidfd_poll_exec_thread, NULL);
/*
@@ -480,10 +480,10 @@ static void test_pidfd_poll_exec(int use_waitpid)
static void *test_pidfd_poll_leader_exit_thread(void *priv)
{
- ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n",
+ ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n",
getpid(), syscall(SYS_gettid));
sleep(CHILD_THREAD_MIN_WAIT);
- ksft_print_msg("Child Thread: DONE. pid %d tid %d\n", getpid(), syscall(SYS_gettid));
+ ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n", getpid(), syscall(SYS_gettid));
return NULL;
}
@@ -492,7 +492,7 @@ static int child_poll_leader_exit_test(void *args)
{
pthread_t t1, t2;
- ksft_print_msg("Child: starting. pid %d tid %d\n", getpid(), syscall(SYS_gettid));
+ ksft_print_msg("Child: starting. pid %d tid %ld\n", getpid(), syscall(SYS_gettid));
pthread_create(&t1, NULL, test_pidfd_poll_leader_exit_thread, NULL);
pthread_create(&t2, NULL, test_pidfd_poll_leader_exit_thread, NULL);
diff --git a/tools/testing/selftests/resctrl/Makefile b/tools/testing/selftests/resctrl/Makefile
index 5073dbc96125..2deac2031de9 100644
--- a/tools/testing/selftests/resctrl/Makefile
+++ b/tools/testing/selftests/resctrl/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2
+CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE
CFLAGS += $(KHDR_INCLUDES)
TEST_GEN_PROGS := resctrl_tests
diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c
index d3cbb829ff6a..bcbca356d56a 100644
--- a/tools/testing/selftests/resctrl/cache.c
+++ b/tools/testing/selftests/resctrl/cache.c
@@ -205,10 +205,11 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)
* cache_val: execute benchmark and measure LLC occupancy resctrl
* and perf cache miss for the benchmark
* @param: parameters passed to cache_val()
+ * @span: buffer size for the benchmark
*
* Return: 0 on success. non-zero on failure.
*/
-int cat_val(struct resctrl_val_param *param)
+int cat_val(struct resctrl_val_param *param, size_t span)
{
int memflush = 1, operation = 0, ret = 0;
char *resctrl_val = param->resctrl_val;
@@ -245,7 +246,7 @@ int cat_val(struct resctrl_val_param *param)
if (ret)
break;
- if (run_fill_buf(param->span, memflush, operation, true)) {
+ if (run_fill_buf(span, memflush, operation, true)) {
fprintf(stderr, "Error-running fill buffer\n");
ret = -1;
goto pe_close;
@@ -294,7 +295,7 @@ int show_cache_info(unsigned long sum_llc_val, int no_of_bits,
ret = platform && abs((int)diff_percent) > max_diff_percent &&
(cmt ? (abs(avg_diff) > max_diff) : true);
- ksft_print_msg("%s Check cache miss rate within %d%%\n",
+ ksft_print_msg("%s Check cache miss rate within %lu%%\n",
ret ? "Fail:" : "Pass:", max_diff_percent);
ksft_print_msg("Percent diff=%d\n", abs((int)diff_percent));
diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
index 3848dfb46aba..224ba8544d8a 100644
--- a/tools/testing/selftests/resctrl/cat_test.c
+++ b/tools/testing/selftests/resctrl/cat_test.c
@@ -41,7 +41,7 @@ static int cat_setup(struct resctrl_val_param *p)
return ret;
}
-static int check_results(struct resctrl_val_param *param)
+static int check_results(struct resctrl_val_param *param, size_t span)
{
char *token_array[8], temp[512];
unsigned long sum_llc_perf_miss = 0;
@@ -76,7 +76,7 @@ static int check_results(struct resctrl_val_param *param)
fclose(fp);
no_of_bits = count_bits(param->mask);
- return show_cache_info(sum_llc_perf_miss, no_of_bits, param->span / 64,
+ return show_cache_info(sum_llc_perf_miss, no_of_bits, span / 64,
MAX_DIFF, MAX_DIFF_PERCENT, runs - 1,
get_vendor() == ARCH_INTEL, false);
}
@@ -96,6 +96,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
char cbm_mask[256];
int count_of_bits;
char pipe_message;
+ size_t span;
/* Get default cbm mask for L3/L2 cache */
ret = get_cbm_mask(cache_type, cbm_mask);
@@ -140,7 +141,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
/* Set param values for parent thread which will be allocated bitmask
* with (max_bits - n) bits
*/
- param.span = cache_size * (count_of_bits - n) / count_of_bits;
+ span = cache_size * (count_of_bits - n) / count_of_bits;
strcpy(param.ctrlgrp, "c2");
strcpy(param.mongrp, "m2");
strcpy(param.filename, RESULT_FILE_NAME2);
@@ -162,23 +163,17 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
param.mask = l_mask_1;
strcpy(param.ctrlgrp, "c1");
strcpy(param.mongrp, "m1");
- param.span = cache_size * n / count_of_bits;
+ span = cache_size * n / count_of_bits;
strcpy(param.filename, RESULT_FILE_NAME1);
param.num_of_runs = 0;
param.cpu_no = sibling_cpu_no;
- } else {
- ret = signal_handler_register();
- if (ret) {
- kill(bm_pid, SIGKILL);
- goto out;
- }
}
remove(param.filename);
- ret = cat_val(&param);
+ ret = cat_val(&param, span);
if (ret == 0)
- ret = check_results(&param);
+ ret = check_results(&param, span);
if (bm_pid == 0) {
/* Tell parent that child is ready */
@@ -208,10 +203,8 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
}
close(pipefd[0]);
kill(bm_pid, SIGKILL);
- signal_handler_unregister();
}
-out:
cat_test_cleanup();
return ret;
diff --git a/tools/testing/selftests/resctrl/cmt_test.c b/tools/testing/selftests/resctrl/cmt_test.c
index cb2197647c6c..50bdbce9fba9 100644
--- a/tools/testing/selftests/resctrl/cmt_test.c
+++ b/tools/testing/selftests/resctrl/cmt_test.c
@@ -27,7 +27,7 @@ static int cmt_setup(struct resctrl_val_param *p)
return 0;
}
-static int check_results(struct resctrl_val_param *param, int no_of_bits)
+static int check_results(struct resctrl_val_param *param, size_t span, int no_of_bits)
{
char *token_array[8], temp[512];
unsigned long sum_llc_occu_resc = 0;
@@ -58,7 +58,7 @@ static int check_results(struct resctrl_val_param *param, int no_of_bits)
}
fclose(fp);
- return show_cache_info(sum_llc_occu_resc, no_of_bits, param->span,
+ return show_cache_info(sum_llc_occu_resc, no_of_bits, span,
MAX_DIFF, MAX_DIFF_PERCENT, runs - 1,
true, true);
}
@@ -68,16 +68,17 @@ void cmt_test_cleanup(void)
remove(RESULT_FILE_NAME);
}
-int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd)
{
+ const char * const *cmd = benchmark_cmd;
+ const char *new_cmd[BENCHMARK_ARGS];
unsigned long cache_size = 0;
unsigned long long_mask;
+ char *span_str = NULL;
char cbm_mask[256];
int count_of_bits;
- int ret;
-
- if (!validate_resctrl_feature_request(CMT_STR))
- return -1;
+ size_t span;
+ int ret, i;
ret = get_cbm_mask("L3", cbm_mask);
if (ret)
@@ -105,24 +106,36 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
.cpu_no = cpu_no,
.filename = RESULT_FILE_NAME,
.mask = ~(long_mask << n) & long_mask,
- .span = cache_size * n / count_of_bits,
.num_of_runs = 0,
.setup = cmt_setup,
};
- if (strcmp(benchmark_cmd[0], "fill_buf") == 0)
- sprintf(benchmark_cmd[1], "%zu", param.span);
+ span = cache_size * n / count_of_bits;
+
+ if (strcmp(cmd[0], "fill_buf") == 0) {
+ /* Duplicate the command to be able to replace span in it */
+ for (i = 0; benchmark_cmd[i]; i++)
+ new_cmd[i] = benchmark_cmd[i];
+ new_cmd[i] = NULL;
+
+ ret = asprintf(&span_str, "%zu", span);
+ if (ret < 0)
+ return -1;
+ new_cmd[1] = span_str;
+ cmd = new_cmd;
+ }
remove(RESULT_FILE_NAME);
- ret = resctrl_val(benchmark_cmd, &param);
+ ret = resctrl_val(cmd, &param);
if (ret)
goto out;
- ret = check_results(&param, n);
+ ret = check_results(&param, span, n);
out:
cmt_test_cleanup();
+ free(span_str);
return ret;
}
diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c
index 4d2f145804b8..d3bf4368341e 100644
--- a/tools/testing/selftests/resctrl/mba_test.c
+++ b/tools/testing/selftests/resctrl/mba_test.c
@@ -12,7 +12,7 @@
#define RESULT_FILE_NAME "result_mba"
#define NUM_OF_RUNS 5
-#define MAX_DIFF_PERCENT 5
+#define MAX_DIFF_PERCENT 8
#define ALLOCATION_MAX 100
#define ALLOCATION_MIN 10
#define ALLOCATION_STEP 10
@@ -141,7 +141,7 @@ void mba_test_cleanup(void)
remove(RESULT_FILE_NAME);
}
-int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
+int mba_schemata_change(int cpu_no, const char * const *benchmark_cmd)
{
struct resctrl_val_param param = {
.resctrl_val = MBA_STR,
@@ -149,7 +149,7 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
.mongrp = "m1",
.cpu_no = cpu_no,
.filename = RESULT_FILE_NAME,
- .bw_report = bw_report,
+ .bw_report = "reads",
.setup = mba_setup
};
int ret;
diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
index c7de6f5977f6..741533f2b075 100644
--- a/tools/testing/selftests/resctrl/mbm_test.c
+++ b/tools/testing/selftests/resctrl/mbm_test.c
@@ -11,7 +11,7 @@
#include "resctrl.h"
#define RESULT_FILE_NAME "result_mbm"
-#define MAX_DIFF_PERCENT 5
+#define MAX_DIFF_PERCENT 8
#define NUM_OF_RUNS 5
static int
@@ -95,7 +95,7 @@ static int mbm_setup(struct resctrl_val_param *p)
return END_OF_TESTS;
/* Set up shemata with 100% allocation on the first run. */
- if (p->num_of_runs == 0)
+ if (p->num_of_runs == 0 && validate_resctrl_feature_request("MB", NULL))
ret = write_schemata(p->ctrlgrp, "100", p->cpu_no,
p->resctrl_val);
@@ -109,16 +109,15 @@ void mbm_test_cleanup(void)
remove(RESULT_FILE_NAME);
}
-int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd)
+int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd)
{
struct resctrl_val_param param = {
.resctrl_val = MBM_STR,
.ctrlgrp = "c1",
.mongrp = "m1",
- .span = span,
.cpu_no = cpu_no,
.filename = RESULT_FILE_NAME,
- .bw_report = bw_report,
+ .bw_report = "reads",
.setup = mbm_setup
};
int ret;
@@ -129,7 +128,7 @@ int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd
if (ret)
goto out;
- ret = check_results(span);
+ ret = check_results(DEFAULT_SPAN);
out:
mbm_test_cleanup();
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
index 838d1a438f33..a33f414f6019 100644
--- a/tools/testing/selftests/resctrl/resctrl.h
+++ b/tools/testing/selftests/resctrl/resctrl.h
@@ -1,5 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#define _GNU_SOURCE
#ifndef RESCTRL_H
#define RESCTRL_H
#include <stdio.h>
@@ -28,16 +27,16 @@
#define RESCTRL_PATH "/sys/fs/resctrl"
#define PHYS_ID_PATH "/sys/devices/system/cpu/cpu"
#define INFO_PATH "/sys/fs/resctrl/info"
-#define L3_PATH "/sys/fs/resctrl/info/L3"
-#define MB_PATH "/sys/fs/resctrl/info/MB"
-#define L3_MON_PATH "/sys/fs/resctrl/info/L3_MON"
-#define L3_MON_FEATURES_PATH "/sys/fs/resctrl/info/L3_MON/mon_features"
#define ARCH_INTEL 1
#define ARCH_AMD 2
#define END_OF_TESTS 1
+#define BENCHMARK_ARGS 64
+
+#define DEFAULT_SPAN (250 * MB)
+
#define PARENT_EXIT(err_msg) \
do { \
perror(err_msg); \
@@ -52,7 +51,6 @@
* @ctrlgrp: Name of the control monitor group (con_mon grp)
* @mongrp: Name of the monitor group (mon grp)
* @cpu_no: CPU number to which the benchmark would be binded
- * @span: Memory bytes accessed in each benchmark iteration
* @filename: Name of file to which the o/p should be written
* @bw_report: Bandwidth report type (reads vs writes)
* @setup: Call back function to setup test environment
@@ -62,7 +60,6 @@ struct resctrl_val_param {
char ctrlgrp[64];
char mongrp[64];
int cpu_no;
- size_t span;
char filename[64];
char *bw_report;
unsigned long mask;
@@ -86,10 +83,9 @@ int get_resource_id(int cpu_no, int *resource_id);
int mount_resctrlfs(void);
int umount_resctrlfs(void);
int validate_bw_report_request(char *bw_report);
-bool validate_resctrl_feature_request(const char *resctrl_val);
+bool validate_resctrl_feature_request(const char *resource, const char *feature);
char *fgrep(FILE *inf, const char *str);
int taskset_benchmark(pid_t bm_pid, int cpu_no);
-void run_benchmark(int signum, siginfo_t *info, void *ucontext);
int write_schemata(char *ctrlgrp, char *schemata, int cpu_no,
char *resctrl_val);
int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
@@ -97,21 +93,21 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
int group_fd, unsigned long flags);
int run_fill_buf(size_t span, int memflush, int op, bool once);
-int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param);
-int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd);
+int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param);
+int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd);
void tests_cleanup(void);
void mbm_test_cleanup(void);
-int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd);
+int mba_schemata_change(int cpu_no, const char * const *benchmark_cmd);
void mba_test_cleanup(void);
int get_cbm_mask(char *cache_type, char *cbm_mask);
int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);
void ctrlc_handler(int signum, siginfo_t *info, void *ptr);
int signal_handler_register(void);
void signal_handler_unregister(void);
-int cat_val(struct resctrl_val_param *param);
+int cat_val(struct resctrl_val_param *param, size_t span);
void cat_test_cleanup(void);
int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type);
-int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd);
+int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd);
unsigned int count_bits(unsigned long n);
void cmt_test_cleanup(void);
int get_core_sibling(int cpu_no);
diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
index d511daeb6851..2bbe3045a018 100644
--- a/tools/testing/selftests/resctrl/resctrl_tests.c
+++ b/tools/testing/selftests/resctrl/resctrl_tests.c
@@ -10,9 +10,6 @@
*/
#include "resctrl.h"
-#define BENCHMARK_ARGS 64
-#define BENCHMARK_ARG_SIZE 64
-
static int detect_vendor(void)
{
FILE *inf = fopen("/proc/cpuinfo", "r");
@@ -52,8 +49,8 @@ int get_vendor(void)
static void cmd_help(void)
{
- printf("usage: resctrl_tests [-h] [-b \"benchmark_cmd [options]\"] [-t test list] [-n no_of_bits]\n");
- printf("\t-b benchmark_cmd [options]: run specified benchmark for MBM, MBA and CMT\n");
+ printf("usage: resctrl_tests [-h] [-t test list] [-n no_of_bits] [-b benchmark_cmd [option]...]\n");
+ printf("\t-b benchmark_cmd [option]...: run specified benchmark for MBM, MBA and CMT\n");
printf("\t default benchmark is builtin fill_buf\n");
printf("\t-t test list: run tests specified in the test list, ");
printf("e.g. -t mbm,mba,cmt,cat\n");
@@ -70,72 +67,98 @@ void tests_cleanup(void)
cat_test_cleanup();
}
-static void run_mbm_test(char **benchmark_cmd, size_t span,
- int cpu_no, char *bw_report)
+static int test_prepare(void)
{
int res;
- ksft_print_msg("Starting MBM BW change ...\n");
+ res = signal_handler_register();
+ if (res) {
+ ksft_print_msg("Failed to register signal handler\n");
+ return res;
+ }
res = mount_resctrlfs();
if (res) {
- ksft_exit_fail_msg("Failed to mount resctrl FS\n");
+ signal_handler_unregister();
+ ksft_print_msg("Failed to mount resctrl FS\n");
+ return res;
+ }
+ return 0;
+}
+
+static void test_cleanup(void)
+{
+ umount_resctrlfs();
+ signal_handler_unregister();
+}
+
+static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
+{
+ int res;
+
+ ksft_print_msg("Starting MBM BW change ...\n");
+
+ if (test_prepare()) {
+ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
return;
}
- if (!validate_resctrl_feature_request(MBM_STR) || (get_vendor() != ARCH_INTEL)) {
+ if (!validate_resctrl_feature_request("L3_MON", "mbm_total_bytes") ||
+ !validate_resctrl_feature_request("L3_MON", "mbm_local_bytes") ||
+ (get_vendor() != ARCH_INTEL)) {
ksft_test_result_skip("Hardware does not support MBM or MBM is disabled\n");
- goto umount;
+ goto cleanup;
}
- res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd);
+ res = mbm_bw_change(cpu_no, benchmark_cmd);
ksft_test_result(!res, "MBM: bw change\n");
if ((get_vendor() == ARCH_INTEL) && res)
ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
-umount:
- umount_resctrlfs();
+cleanup:
+ test_cleanup();
}
-static void run_mba_test(char **benchmark_cmd, int cpu_no, char *bw_report)
+static void run_mba_test(const char * const *benchmark_cmd, int cpu_no)
{
int res;
ksft_print_msg("Starting MBA Schemata change ...\n");
- res = mount_resctrlfs();
- if (res) {
- ksft_exit_fail_msg("Failed to mount resctrl FS\n");
+ if (test_prepare()) {
+ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
return;
}
- if (!validate_resctrl_feature_request(MBA_STR) || (get_vendor() != ARCH_INTEL)) {
+ if (!validate_resctrl_feature_request("MB", NULL) ||
+ !validate_resctrl_feature_request("L3_MON", "mbm_local_bytes") ||
+ (get_vendor() != ARCH_INTEL)) {
ksft_test_result_skip("Hardware does not support MBA or MBA is disabled\n");
- goto umount;
+ goto cleanup;
}
- res = mba_schemata_change(cpu_no, bw_report, benchmark_cmd);
+ res = mba_schemata_change(cpu_no, benchmark_cmd);
ksft_test_result(!res, "MBA: schemata change\n");
-umount:
- umount_resctrlfs();
+cleanup:
+ test_cleanup();
}
-static void run_cmt_test(char **benchmark_cmd, int cpu_no)
+static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no)
{
int res;
ksft_print_msg("Starting CMT test ...\n");
- res = mount_resctrlfs();
- if (res) {
- ksft_exit_fail_msg("Failed to mount resctrl FS\n");
+ if (test_prepare()) {
+ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
return;
}
- if (!validate_resctrl_feature_request(CMT_STR)) {
+ if (!validate_resctrl_feature_request("L3_MON", "llc_occupancy") ||
+ !validate_resctrl_feature_request("L3", NULL)) {
ksft_test_result_skip("Hardware does not support CMT or CMT is disabled\n");
- goto umount;
+ goto cleanup;
}
res = cmt_resctrl_val(cpu_no, 5, benchmark_cmd);
@@ -143,8 +166,8 @@ static void run_cmt_test(char **benchmark_cmd, int cpu_no)
if ((get_vendor() == ARCH_INTEL) && res)
ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
-umount:
- umount_resctrlfs();
+cleanup:
+ test_cleanup();
}
static void run_cat_test(int cpu_no, int no_of_bits)
@@ -153,48 +176,53 @@ static void run_cat_test(int cpu_no, int no_of_bits)
ksft_print_msg("Starting CAT test ...\n");
- res = mount_resctrlfs();
- if (res) {
- ksft_exit_fail_msg("Failed to mount resctrl FS\n");
+ if (test_prepare()) {
+ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
return;
}
- if (!validate_resctrl_feature_request(CAT_STR)) {
+ if (!validate_resctrl_feature_request("L3", NULL)) {
ksft_test_result_skip("Hardware does not support CAT or CAT is disabled\n");
- goto umount;
+ goto cleanup;
}
res = cat_perf_miss_val(cpu_no, no_of_bits, "L3");
ksft_test_result(!res, "CAT: test\n");
-umount:
- umount_resctrlfs();
+cleanup:
+ test_cleanup();
}
int main(int argc, char **argv)
{
- bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true;
- char *benchmark_cmd[BENCHMARK_ARGS], bw_report[64], bm_type[64];
- char benchmark_cmd_area[BENCHMARK_ARGS][BENCHMARK_ARG_SIZE];
- int c, cpu_no = 1, argc_new = argc, i, no_of_bits = 0;
- int ben_ind, ben_count, tests = 0;
- size_t span = 250 * MB;
+ bool mbm_test = true, mba_test = true, cmt_test = true;
+ const char *benchmark_cmd[BENCHMARK_ARGS] = {};
+ int c, cpu_no = 1, i, no_of_bits = 0;
+ char *span_str = NULL;
bool cat_test = true;
+ int tests = 0;
+ int ret;
- for (i = 0; i < argc; i++) {
- if (strcmp(argv[i], "-b") == 0) {
- ben_ind = i + 1;
- ben_count = argc - ben_ind;
- argc_new = ben_ind - 1;
- has_ben = true;
- break;
- }
- }
-
- while ((c = getopt(argc_new, argv, "ht:b:n:p:")) != -1) {
+ while ((c = getopt(argc, argv, "ht:b:n:p:")) != -1) {
char *token;
switch (c) {
+ case 'b':
+ /*
+ * First move optind back to the (first) optarg and
+ * then build the benchmark command using the
+ * remaining arguments.
+ */
+ optind--;
+ if (argc - optind >= BENCHMARK_ARGS)
+ ksft_exit_fail_msg("Too long benchmark command");
+
+ /* Extract benchmark command from command line. */
+ for (i = 0; i < argc - optind; i++)
+ benchmark_cmd[i] = argv[i + optind];
+ benchmark_cmd[i] = NULL;
+
+ goto last_arg;
case 't':
token = strtok(optarg, ",");
@@ -243,6 +271,7 @@ int main(int argc, char **argv)
return -1;
}
}
+last_arg:
ksft_print_header();
@@ -254,29 +283,6 @@ int main(int argc, char **argv)
if (geteuid() != 0)
return ksft_exit_skip("Not running as root. Skipping...\n");
- if (has_ben) {
- /* Extract benchmark command from command line. */
- for (i = ben_ind; i < argc; i++) {
- benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i];
- sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]);
- }
- benchmark_cmd[ben_count] = NULL;
- } else {
- /* If no benchmark is given by "-b" argument, use fill_buf. */
- for (i = 0; i < 5; i++)
- benchmark_cmd[i] = benchmark_cmd_area[i];
-
- strcpy(benchmark_cmd[0], "fill_buf");
- sprintf(benchmark_cmd[1], "%zu", span);
- strcpy(benchmark_cmd[2], "1");
- strcpy(benchmark_cmd[3], "0");
- strcpy(benchmark_cmd[4], "false");
- benchmark_cmd[5] = NULL;
- }
-
- sprintf(bw_report, "reads");
- sprintf(bm_type, "fill_buf");
-
if (!check_resctrlfs_support())
return ksft_exit_skip("resctrl FS does not exist. Enable X86_CPU_RESCTRL config option.\n");
@@ -285,13 +291,26 @@ int main(int argc, char **argv)
filter_dmesg();
+ if (!benchmark_cmd[0]) {
+ /* If no benchmark is given by "-b" argument, use fill_buf. */
+ benchmark_cmd[0] = "fill_buf";
+ ret = asprintf(&span_str, "%u", DEFAULT_SPAN);
+ if (ret < 0)
+ ksft_exit_fail_msg("Out of memory!\n");
+ benchmark_cmd[1] = span_str;
+ benchmark_cmd[2] = "1";
+ benchmark_cmd[3] = "0";
+ benchmark_cmd[4] = "false";
+ benchmark_cmd[5] = NULL;
+ }
+
ksft_set_plan(tests ? : 4);
if (mbm_test)
- run_mbm_test(benchmark_cmd, span, cpu_no, bw_report);
+ run_mbm_test(benchmark_cmd, cpu_no);
if (mba_test)
- run_mba_test(benchmark_cmd, cpu_no, bw_report);
+ run_mba_test(benchmark_cmd, cpu_no);
if (cmt_test)
run_cmt_test(benchmark_cmd, cpu_no);
@@ -299,5 +318,6 @@ int main(int argc, char **argv)
if (cat_test)
run_cat_test(cpu_no, no_of_bits);
+ free(span_str);
ksft_finished();
}
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
index f0f6c5f6e98b..88789678917b 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -468,7 +468,9 @@ pid_t bm_pid, ppid;
void ctrlc_handler(int signum, siginfo_t *info, void *ptr)
{
- kill(bm_pid, SIGKILL);
+ /* Only kill child after bm_pid is set after fork() */
+ if (bm_pid)
+ kill(bm_pid, SIGKILL);
umount_resctrlfs();
tests_cleanup();
ksft_print_msg("Ending\n\n");
@@ -482,9 +484,11 @@ void ctrlc_handler(int signum, siginfo_t *info, void *ptr)
*/
int signal_handler_register(void)
{
- struct sigaction sigact;
+ struct sigaction sigact = {};
int ret = 0;
+ bm_pid = 0;
+
sigact.sa_sigaction = ctrlc_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_SIGINFO;
@@ -504,7 +508,7 @@ int signal_handler_register(void)
*/
void signal_handler_unregister(void)
{
- struct sigaction sigact;
+ struct sigaction sigact = {};
sigact.sa_handler = SIG_DFL;
sigemptyset(&sigact.sa_mask);
@@ -622,6 +626,56 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)
}
/*
+ * run_benchmark - Run a specified benchmark or fill_buf (default benchmark)
+ * in specified signal. Direct benchmark stdio to /dev/null.
+ * @signum: signal number
+ * @info: signal info
+ * @ucontext: user context in signal handling
+ */
+static void run_benchmark(int signum, siginfo_t *info, void *ucontext)
+{
+ int operation, ret, memflush;
+ char **benchmark_cmd;
+ size_t span;
+ bool once;
+ FILE *fp;
+
+ benchmark_cmd = info->si_ptr;
+
+ /*
+ * Direct stdio of child to /dev/null, so that only parent writes to
+ * stdio (console)
+ */
+ fp = freopen("/dev/null", "w", stdout);
+ if (!fp)
+ PARENT_EXIT("Unable to direct benchmark status to /dev/null");
+
+ if (strcmp(benchmark_cmd[0], "fill_buf") == 0) {
+ /* Execute default fill_buf benchmark */
+ span = strtoul(benchmark_cmd[1], NULL, 10);
+ memflush = atoi(benchmark_cmd[2]);
+ operation = atoi(benchmark_cmd[3]);
+ if (!strcmp(benchmark_cmd[4], "true"))
+ once = true;
+ else if (!strcmp(benchmark_cmd[4], "false"))
+ once = false;
+ else
+ PARENT_EXIT("Invalid once parameter");
+
+ if (run_fill_buf(span, memflush, operation, once))
+ fprintf(stderr, "Error in running fill buffer\n");
+ } else {
+ /* Execute specified benchmark */
+ ret = execvp(benchmark_cmd[0], benchmark_cmd);
+ if (ret)
+ perror("wrong\n");
+ }
+
+ fclose(stdout);
+ PARENT_EXIT("Unable to run specified benchmark");
+}
+
+/*
* resctrl_val: execute benchmark and measure memory bandwidth on
* the benchmark
* @benchmark_cmd: benchmark command and its arguments
@@ -629,7 +683,7 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)
*
* Return: 0 on success. non-zero on failure.
*/
-int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param)
{
char *resctrl_val = param->resctrl_val;
unsigned long bw_resc_start = 0;
@@ -706,28 +760,30 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
ksft_print_msg("Benchmark PID: %d\n", bm_pid);
- ret = signal_handler_register();
- if (ret)
- goto out;
-
- value.sival_ptr = benchmark_cmd;
+ /*
+ * The cast removes constness but nothing mutates benchmark_cmd within
+ * the context of this process. At the receiving process, it becomes
+ * argv, which is mutable, on exec() but that's after fork() so it
+ * doesn't matter for the process running the tests.
+ */
+ value.sival_ptr = (void *)benchmark_cmd;
/* Taskset benchmark to specified cpu */
ret = taskset_benchmark(bm_pid, param->cpu_no);
if (ret)
- goto unregister;
+ goto out;
/* Write benchmark to specified control&monitoring grp in resctrl FS */
ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp,
resctrl_val);
if (ret)
- goto unregister;
+ goto out;
if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
ret = initialize_mem_bw_imc();
if (ret)
- goto unregister;
+ goto out;
initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp,
param->cpu_no, resctrl_val);
@@ -742,7 +798,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
sizeof(pipe_message)) {
perror("# failed reading message from child process");
close(pipefd[0]);
- goto unregister;
+ goto out;
}
}
close(pipefd[0]);
@@ -751,7 +807,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
if (sigqueue(bm_pid, SIGUSR1, value) == -1) {
perror("# sigqueue SIGUSR1 to child");
ret = errno;
- goto unregister;
+ goto out;
}
/* Give benchmark enough time to fully run */
@@ -780,8 +836,6 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
}
}
-unregister:
- signal_handler_unregister();
out:
kill(bm_pid, SIGKILL);
diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c
index bd36ee206602..5ebd43683876 100644
--- a/tools/testing/selftests/resctrl/resctrlfs.c
+++ b/tools/testing/selftests/resctrl/resctrlfs.c
@@ -8,6 +8,9 @@
* Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>,
* Fenghua Yu <fenghua.yu@intel.com>
*/
+#include <fcntl.h>
+#include <limits.h>
+
#include "resctrl.h"
static int find_resctrl_mount(char *buffer)
@@ -292,58 +295,6 @@ int taskset_benchmark(pid_t bm_pid, int cpu_no)
}
/*
- * run_benchmark - Run a specified benchmark or fill_buf (default benchmark)
- * in specified signal. Direct benchmark stdio to /dev/null.
- * @signum: signal number
- * @info: signal info
- * @ucontext: user context in signal handling
- *
- * Return: void
- */
-void run_benchmark(int signum, siginfo_t *info, void *ucontext)
-{
- int operation, ret, memflush;
- char **benchmark_cmd;
- size_t span;
- bool once;
- FILE *fp;
-
- benchmark_cmd = info->si_ptr;
-
- /*
- * Direct stdio of child to /dev/null, so that only parent writes to
- * stdio (console)
- */
- fp = freopen("/dev/null", "w", stdout);
- if (!fp)
- PARENT_EXIT("Unable to direct benchmark status to /dev/null");
-
- if (strcmp(benchmark_cmd[0], "fill_buf") == 0) {
- /* Execute default fill_buf benchmark */
- span = strtoul(benchmark_cmd[1], NULL, 10);
- memflush = atoi(benchmark_cmd[2]);
- operation = atoi(benchmark_cmd[3]);
- if (!strcmp(benchmark_cmd[4], "true"))
- once = true;
- else if (!strcmp(benchmark_cmd[4], "false"))
- once = false;
- else
- PARENT_EXIT("Invalid once parameter");
-
- if (run_fill_buf(span, memflush, operation, once))
- fprintf(stderr, "Error in running fill buffer\n");
- } else {
- /* Execute specified benchmark */
- ret = execvp(benchmark_cmd[0], benchmark_cmd);
- if (ret)
- perror("wrong\n");
- }
-
- fclose(stdout);
- PARENT_EXIT("Unable to run specified benchmark");
-}
-
-/*
* create_grp - Create a group only if one doesn't exist
* @grp_name: Name of the group
* @grp: Full path and name of the group
@@ -488,9 +439,8 @@ out:
*/
int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
{
- char controlgroup[1024], schema[1024], reason[64];
- int resource_id, ret = 0;
- FILE *fp;
+ char controlgroup[1024], reason[128], schema[1024] = {};
+ int resource_id, fd, schema_len = -1, ret = 0;
if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) &&
strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) &&
@@ -518,28 +468,39 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) ||
!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
- sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata);
+ schema_len = snprintf(schema, sizeof(schema), "%s%d%c%s\n",
+ "L3:", resource_id, '=', schemata);
if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) ||
!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)))
- sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata);
-
- fp = fopen(controlgroup, "w");
- if (!fp) {
- sprintf(reason, "Failed to open control group");
+ schema_len = snprintf(schema, sizeof(schema), "%s%d%c%s\n",
+ "MB:", resource_id, '=', schemata);
+ if (schema_len < 0 || schema_len >= sizeof(schema)) {
+ snprintf(reason, sizeof(reason),
+ "snprintf() failed with return value : %d", schema_len);
ret = -1;
-
goto out;
}
- if (fprintf(fp, "%s\n", schema) < 0) {
- sprintf(reason, "Failed to write schemata in control group");
- fclose(fp);
+ fd = open(controlgroup, O_WRONLY);
+ if (fd < 0) {
+ snprintf(reason, sizeof(reason),
+ "open() failed : %s", strerror(errno));
ret = -1;
- goto out;
+ goto err_schema_not_empty;
}
- fclose(fp);
+ if (write(fd, schema, schema_len) < 0) {
+ snprintf(reason, sizeof(reason),
+ "write() failed : %s", strerror(errno));
+ close(fd);
+ ret = -1;
+
+ goto err_schema_not_empty;
+ }
+ close(fd);
+err_schema_not_empty:
+ schema[schema_len - 1] = 0;
out:
ksft_print_msg("Write schema \"%s\" to resctrl FS%s%s\n",
schema, ret ? " # " : "",
@@ -604,63 +565,46 @@ char *fgrep(FILE *inf, const char *str)
/*
* validate_resctrl_feature_request - Check if requested feature is valid.
- * @resctrl_val: Requested feature
+ * @resource: Required resource (e.g., MB, L3, L2, L3_MON, etc.)
+ * @feature: Required monitor feature (in mon_features file). Can only be
+ * set for L3_MON. Must be NULL for all other resources.
*
- * Return: True if the feature is supported, else false. False is also
- * returned if resctrl FS is not mounted.
+ * Return: True if the resource/feature is supported, else false. False is
+ * also returned if resctrl FS is not mounted.
*/
-bool validate_resctrl_feature_request(const char *resctrl_val)
+bool validate_resctrl_feature_request(const char *resource, const char *feature)
{
+ char res_path[PATH_MAX];
struct stat statbuf;
- bool found = false;
char *res;
FILE *inf;
int ret;
- if (!resctrl_val)
+ if (!resource)
return false;
ret = find_resctrl_mount(NULL);
if (ret)
return false;
- if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
- if (!stat(L3_PATH, &statbuf))
- return true;
- } else if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
- if (!stat(MB_PATH, &statbuf))
- return true;
- } else if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
- !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
- if (!stat(L3_MON_PATH, &statbuf)) {
- inf = fopen(L3_MON_FEATURES_PATH, "r");
- if (!inf)
- return false;
-
- if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
- res = fgrep(inf, "llc_occupancy");
- if (res) {
- found = true;
- free(res);
- }
- }
-
- if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
- res = fgrep(inf, "mbm_total_bytes");
- if (res) {
- free(res);
- res = fgrep(inf, "mbm_local_bytes");
- if (res) {
- found = true;
- free(res);
- }
- }
- }
- fclose(inf);
- }
- }
+ snprintf(res_path, sizeof(res_path), "%s/%s", INFO_PATH, resource);
+
+ if (stat(res_path, &statbuf))
+ return false;
+
+ if (!feature)
+ return true;
+
+ snprintf(res_path, sizeof(res_path), "%s/%s/mon_features", INFO_PATH, resource);
+ inf = fopen(res_path, "r");
+ if (!inf)
+ return false;
+
+ res = fgrep(inf, feature);
+ free(res);
+ fclose(inf);
- return found;
+ return !!res;
}
int filter_dmesg(void)
diff --git a/tools/testing/selftests/rseq/param_test.c b/tools/testing/selftests/rseq/param_test.c
index bf951a490bb4..20403d58345c 100644
--- a/tools/testing/selftests/rseq/param_test.c
+++ b/tools/testing/selftests/rseq/param_test.c
@@ -1231,7 +1231,7 @@ void *test_membarrier_worker_thread(void *arg)
}
/* Wait for initialization. */
- while (!atomic_load(&args->percpu_list_ptr)) {}
+ while (!__atomic_load_n(&args->percpu_list_ptr, __ATOMIC_ACQUIRE)) {}
for (i = 0; i < iters; ++i) {
int ret;
@@ -1299,22 +1299,22 @@ void *test_membarrier_manager_thread(void *arg)
test_membarrier_init_percpu_list(&list_a);
test_membarrier_init_percpu_list(&list_b);
- atomic_store(&args->percpu_list_ptr, (intptr_t)&list_a);
+ __atomic_store_n(&args->percpu_list_ptr, (intptr_t)&list_a, __ATOMIC_RELEASE);
- while (!atomic_load(&args->stop)) {
+ while (!__atomic_load_n(&args->stop, __ATOMIC_ACQUIRE)) {
/* list_a is "active". */
cpu_a = rand() % CPU_SETSIZE;
/*
* As list_b is "inactive", we should never see changes
* to list_b.
*/
- if (expect_b != atomic_load(&list_b.c[cpu_b].head->data)) {
+ if (expect_b != __atomic_load_n(&list_b.c[cpu_b].head->data, __ATOMIC_ACQUIRE)) {
fprintf(stderr, "Membarrier test failed\n");
abort();
}
/* Make list_b "active". */
- atomic_store(&args->percpu_list_ptr, (intptr_t)&list_b);
+ __atomic_store_n(&args->percpu_list_ptr, (intptr_t)&list_b, __ATOMIC_RELEASE);
if (rseq_membarrier_expedited(cpu_a) &&
errno != ENXIO /* missing CPU */) {
perror("sys_membarrier");
@@ -1324,27 +1324,27 @@ void *test_membarrier_manager_thread(void *arg)
* Cpu A should now only modify list_b, so the values
* in list_a should be stable.
*/
- expect_a = atomic_load(&list_a.c[cpu_a].head->data);
+ expect_a = __atomic_load_n(&list_a.c[cpu_a].head->data, __ATOMIC_ACQUIRE);
cpu_b = rand() % CPU_SETSIZE;
/*
* As list_a is "inactive", we should never see changes
* to list_a.
*/
- if (expect_a != atomic_load(&list_a.c[cpu_a].head->data)) {
+ if (expect_a != __atomic_load_n(&list_a.c[cpu_a].head->data, __ATOMIC_ACQUIRE)) {
fprintf(stderr, "Membarrier test failed\n");
abort();
}
/* Make list_a "active". */
- atomic_store(&args->percpu_list_ptr, (intptr_t)&list_a);
+ __atomic_store_n(&args->percpu_list_ptr, (intptr_t)&list_a, __ATOMIC_RELEASE);
if (rseq_membarrier_expedited(cpu_b) &&
errno != ENXIO /* missing CPU*/) {
perror("sys_membarrier");
abort();
}
/* Remember a value from list_b. */
- expect_b = atomic_load(&list_b.c[cpu_b].head->data);
+ expect_b = __atomic_load_n(&list_b.c[cpu_b].head->data, __ATOMIC_ACQUIRE);
}
test_membarrier_free_percpu_list(&list_a);
@@ -1401,7 +1401,7 @@ void test_membarrier(void)
}
}
- atomic_store(&thread_args.stop, 1);
+ __atomic_store_n(&thread_args.stop, 1, __ATOMIC_RELEASE);
ret = pthread_join(manager_thread, NULL);
if (ret) {
errno = ret;
diff --git a/tools/testing/selftests/sigaltstack/sas.c b/tools/testing/selftests/sigaltstack/sas.c
index 98d37cb744fb..07227fab1cc9 100644
--- a/tools/testing/selftests/sigaltstack/sas.c
+++ b/tools/testing/selftests/sigaltstack/sas.c
@@ -111,7 +111,7 @@ int main(void)
/* Make sure more than the required minimum. */
stack_size = getauxval(AT_MINSIGSTKSZ) + SIGSTKSZ;
- ksft_print_msg("[NOTE]\tthe stack size is %lu\n", stack_size);
+ ksft_print_msg("[NOTE]\tthe stack size is %u\n", stack_size);
ksft_print_header();
ksft_set_plan(3);
diff --git a/tools/testing/selftests/static_keys/test_static_keys.sh b/tools/testing/selftests/static_keys/test_static_keys.sh
index fc9f8cde7d42..3b0f17b81ac2 100755
--- a/tools/testing/selftests/static_keys/test_static_keys.sh
+++ b/tools/testing/selftests/static_keys/test_static_keys.sh
@@ -6,18 +6,18 @@
ksft_skip=4
if ! /sbin/modprobe -q -n test_static_key_base; then
- echo "static_key: module test_static_key_base is not found [SKIP]"
+ echo "static_keys: module test_static_key_base is not found [SKIP]"
exit $ksft_skip
fi
if ! /sbin/modprobe -q -n test_static_keys; then
- echo "static_key: module test_static_keys is not found [SKIP]"
+ echo "static_keys: module test_static_keys is not found [SKIP]"
exit $ksft_skip
fi
if /sbin/modprobe -q test_static_key_base; then
if /sbin/modprobe -q test_static_keys; then
- echo "static_key: ok"
+ echo "static_keys: ok"
/sbin/modprobe -q -r test_static_keys
/sbin/modprobe -q -r test_static_key_base
else
@@ -25,6 +25,6 @@ if /sbin/modprobe -q test_static_key_base; then
/sbin/modprobe -q -r test_static_key_base
fi
else
- echo "static_key: [FAIL]"
+ echo "static_keys: [FAIL]"
exit 1
fi
diff --git a/tools/testing/selftests/tdx/.gitignore b/tools/testing/selftests/tdx/.gitignore
new file mode 100644
index 000000000000..5db4d15cc673
--- /dev/null
+++ b/tools/testing/selftests/tdx/.gitignore
@@ -0,0 +1 @@
+tdx_guest_test
diff --git a/tools/testing/selftests/timers/nsleep-lat.c b/tools/testing/selftests/timers/nsleep-lat.c
index eb3e79ed7b4a..edb5acacf214 100644
--- a/tools/testing/selftests/timers/nsleep-lat.c
+++ b/tools/testing/selftests/timers/nsleep-lat.c
@@ -118,7 +118,7 @@ int nanosleep_lat_test(int clockid, long long ns)
clock_gettime(clockid, &end);
if (((timespec_sub(start, end)/count)-ns) > UNRESONABLE_LATENCY) {
- printf("Large rel latency: %lld ns :", (timespec_sub(start, end)/count)-ns);
+ ksft_print_msg("Large rel latency: %lld ns :", (timespec_sub(start, end)/count)-ns);
return -1;
}
@@ -132,20 +132,23 @@ int nanosleep_lat_test(int clockid, long long ns)
}
if (latency/count > UNRESONABLE_LATENCY) {
- printf("Large abs latency: %lld ns :", latency/count);
+ ksft_print_msg("Large abs latency: %lld ns :", latency/count);
return -1;
}
return 0;
}
-
+#define SKIPPED_CLOCK_COUNT 3
int main(int argc, char **argv)
{
long long length;
int clockid, ret;
+ ksft_print_header();
+ ksft_set_plan(NR_CLOCKIDS - CLOCK_REALTIME - SKIPPED_CLOCK_COUNT);
+
for (clockid = CLOCK_REALTIME; clockid < NR_CLOCKIDS; clockid++) {
/* Skip cputime clockids since nanosleep won't increment cputime */
@@ -154,9 +157,6 @@ int main(int argc, char **argv)
clockid == CLOCK_HWSPECIFIC)
continue;
- printf("nsleep latency %-26s ", clockstring(clockid));
- fflush(stdout);
-
length = 10;
while (length <= (NSEC_PER_SEC * 10)) {
ret = nanosleep_lat_test(clockid, length);
@@ -167,14 +167,12 @@ int main(int argc, char **argv)
}
if (ret == UNSUPPORTED) {
- printf("[UNSUPPORTED]\n");
- continue;
- }
- if (ret < 0) {
- printf("[FAILED]\n");
- return ksft_exit_fail();
+ ksft_test_result_skip("%s\n", clockstring(clockid));
+ } else {
+ ksft_test_result(ret >= 0, "%s\n",
+ clockstring(clockid));
}
- printf("[OK]\n");
}
- return ksft_exit_pass();
+
+ ksft_finished();
}
diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c
index 8a17c0e8d82b..d49dd3ffd0d9 100644
--- a/tools/testing/selftests/timers/posix_timers.c
+++ b/tools/testing/selftests/timers/posix_timers.c
@@ -76,22 +76,21 @@ static int check_diff(struct timeval start, struct timeval end)
static int check_itimer(int which)
{
+ const char *name;
int err;
struct timeval start, end;
struct itimerval val = {
.it_value.tv_sec = DELAY,
};
- printf("Check itimer ");
-
if (which == ITIMER_VIRTUAL)
- printf("virtual... ");
+ name = "ITIMER_VIRTUAL";
else if (which == ITIMER_PROF)
- printf("prof... ");
+ name = "ITIMER_PROF";
else if (which == ITIMER_REAL)
- printf("real... ");
-
- fflush(stdout);
+ name = "ITIMER_REAL";
+ else
+ return -1;
done = 0;
@@ -104,13 +103,13 @@ static int check_itimer(int which)
err = gettimeofday(&start, NULL);
if (err < 0) {
- perror("Can't call gettimeofday()\n");
+ ksft_perror("Can't call gettimeofday()");
return -1;
}
err = setitimer(which, &val, NULL);
if (err < 0) {
- perror("Can't set timer\n");
+ ksft_perror("Can't set timer");
return -1;
}
@@ -123,20 +122,18 @@ static int check_itimer(int which)
err = gettimeofday(&end, NULL);
if (err < 0) {
- perror("Can't call gettimeofday()\n");
+ ksft_perror("Can't call gettimeofday()");
return -1;
}
- if (!check_diff(start, end))
- printf("[OK]\n");
- else
- printf("[FAIL]\n");
+ ksft_test_result(check_diff(start, end) == 0, "%s\n", name);
return 0;
}
static int check_timer_create(int which)
{
+ const char *type;
int err;
timer_t id;
struct timeval start, end;
@@ -144,31 +141,32 @@ static int check_timer_create(int which)
.it_value.tv_sec = DELAY,
};
- printf("Check timer_create() ");
if (which == CLOCK_THREAD_CPUTIME_ID) {
- printf("per thread... ");
+ type = "thread";
} else if (which == CLOCK_PROCESS_CPUTIME_ID) {
- printf("per process... ");
+ type = "process";
+ } else {
+ ksft_print_msg("Unknown timer_create() type %d\n", which);
+ return -1;
}
- fflush(stdout);
done = 0;
err = timer_create(which, NULL, &id);
if (err < 0) {
- perror("Can't create timer\n");
+ ksft_perror("Can't create timer");
return -1;
}
signal(SIGALRM, sig_handler);
err = gettimeofday(&start, NULL);
if (err < 0) {
- perror("Can't call gettimeofday()\n");
+ ksft_perror("Can't call gettimeofday()");
return -1;
}
err = timer_settime(id, 0, &val, NULL);
if (err < 0) {
- perror("Can't set timer\n");
+ ksft_perror("Can't set timer");
return -1;
}
@@ -176,14 +174,12 @@ static int check_timer_create(int which)
err = gettimeofday(&end, NULL);
if (err < 0) {
- perror("Can't call gettimeofday()\n");
+ ksft_perror("Can't call gettimeofday()");
return -1;
}
- if (!check_diff(start, end))
- printf("[OK]\n");
- else
- printf("[FAIL]\n");
+ ksft_test_result(check_diff(start, end) == 0,
+ "timer_create() per %s\n", type);
return 0;
}
@@ -220,25 +216,25 @@ static int check_timer_distribution(void)
.it_interval.tv_nsec = 1000 * 1000,
};
- printf("Check timer_create() per process signal distribution... ");
- fflush(stdout);
-
remain = nthreads + 1; /* worker threads + this thread */
signal(SIGALRM, distribution_handler);
err = timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id);
if (err < 0) {
- perror("Can't create timer\n");
+ ksft_perror("Can't create timer");
return -1;
}
err = timer_settime(id, 0, &val, NULL);
if (err < 0) {
- perror("Can't set timer\n");
+ ksft_perror("Can't set timer");
return -1;
}
for (i = 0; i < nthreads; i++) {
- if (pthread_create(&threads[i], NULL, distribution_thread, NULL)) {
- perror("Can't create thread\n");
+ err = pthread_create(&threads[i], NULL, distribution_thread,
+ NULL);
+ if (err) {
+ ksft_print_msg("Can't create thread: %s (%d)\n",
+ strerror(errno), errno);
return -1;
}
}
@@ -247,25 +243,30 @@ static int check_timer_distribution(void)
while (__atomic_load_n(&remain, __ATOMIC_RELAXED));
for (i = 0; i < nthreads; i++) {
- if (pthread_join(threads[i], NULL)) {
- perror("Can't join thread\n");
+ err = pthread_join(threads[i], NULL);
+ if (err) {
+ ksft_print_msg("Can't join thread: %s (%d)\n",
+ strerror(errno), errno);
return -1;
}
}
if (timer_delete(id)) {
- perror("Can't delete timer\n");
+ ksft_perror("Can't delete timer");
return -1;
}
- printf("[OK]\n");
+ ksft_test_result_pass("check_timer_distribution\n");
return 0;
}
int main(int argc, char **argv)
{
- printf("Testing posix timers. False negative may happen on CPU execution \n");
- printf("based timers if other threads run on the CPU...\n");
+ ksft_print_header();
+ ksft_set_plan(6);
+
+ ksft_print_msg("Testing posix timers. False negative may happen on CPU execution \n");
+ ksft_print_msg("based timers if other threads run on the CPU...\n");
if (check_itimer(ITIMER_VIRTUAL) < 0)
return ksft_exit_fail();
@@ -294,5 +295,5 @@ int main(int argc, char **argv)
if (check_timer_distribution() < 0)
return ksft_exit_fail();
- return ksft_exit_pass();
+ ksft_finished();
}
diff --git a/tools/testing/selftests/uevent/uevent_filtering.c b/tools/testing/selftests/uevent/uevent_filtering.c
index 5cebfb356345..dbe55f3a66f4 100644
--- a/tools/testing/selftests/uevent/uevent_filtering.c
+++ b/tools/testing/selftests/uevent/uevent_filtering.c
@@ -78,7 +78,7 @@ static int uevent_listener(unsigned long post_flags, bool expect_uevent,
{
int sk_fd, ret;
socklen_t sk_addr_len;
- int fret = -1, rcv_buf_sz = __UEVENT_BUFFER_SIZE;
+ int rcv_buf_sz = __UEVENT_BUFFER_SIZE;
uint64_t sync_add = 1;
struct sockaddr_nl sk_addr = { 0 }, rcv_addr = { 0 };
char buf[__UEVENT_BUFFER_SIZE] = { 0 };
@@ -121,6 +121,7 @@ static int uevent_listener(unsigned long post_flags, bool expect_uevent,
if ((size_t)sk_addr_len != sizeof(sk_addr)) {
fprintf(stderr, "Invalid socket address size\n");
+ ret = -1;
goto on_error;
}
@@ -147,11 +148,12 @@ static int uevent_listener(unsigned long post_flags, bool expect_uevent,
ret = write_nointr(sync_fd, &sync_add, sizeof(sync_add));
close(sync_fd);
if (ret != sizeof(sync_add)) {
+ ret = -1;
fprintf(stderr, "Failed to synchronize with parent process\n");
goto on_error;
}
- fret = 0;
+ ret = 0;
for (;;) {
ssize_t r;
@@ -187,7 +189,7 @@ static int uevent_listener(unsigned long post_flags, bool expect_uevent,
on_error:
close(sk_fd);
- return fret;
+ return ret;
}
int trigger_uevent(unsigned int times)
diff --git a/tools/testing/selftests/user_events/.gitignore b/tools/testing/selftests/user_events/.gitignore
new file mode 100644
index 000000000000..f570febd211b
--- /dev/null
+++ b/tools/testing/selftests/user_events/.gitignore
@@ -0,0 +1,4 @@
+abi_test
+dyn_test
+ftrace_test
+perf_test
diff --git a/usr/include/Makefile b/usr/include/Makefile
index 07796df0a295..338c81f1fcf3 100644
--- a/usr/include/Makefile
+++ b/usr/include/Makefile
@@ -59,12 +59,6 @@ ifeq ($(SRCARCH),arc)
no-header-test += linux/bpf_perf_event.h
endif
-ifeq ($(SRCARCH),ia64)
-no-header-test += asm/setup.h
-no-header-test += asm/sigcontext.h
-no-header-test += linux/if_bonding.h
-endif
-
ifeq ($(SRCARCH),powerpc)
no-header-test += linux/bpf_perf_event.h
endif