aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.get_maintainer.ignore1
-rw-r--r--.gitignore8
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-at91.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/keystone/ti,sci.txt3
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt66
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt82
-rw-r--r--Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt51
-rw-r--r--Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt4
-rw-r--r--Documentation/driver-model/devres.txt3
-rw-r--r--MAINTAINERS7
-rw-r--r--Makefile21
-rw-r--r--arch/alpha/Makefile2
-rw-r--r--arch/alpha/configs/defconfig (renamed from arch/alpha/defconfig)0
-rw-r--r--arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi2
-rw-r--r--arch/arm/configs/sama5_defconfig2
-rw-r--r--arch/arm/configs/socfpga_defconfig3
-rw-r--r--arch/arm/mach-at91/Kconfig26
-rw-r--r--arch/arm/mach-at91/at91sam9.c18
-rw-r--r--arch/arm/mach-at91/generic.h2
-rw-r--r--arch/arm/mach-at91/pm.c193
-rw-r--r--arch/arm/mach-at91/pm_suspend.S111
-rw-r--r--arch/arm/mach-ixp4xx/common.c1
-rw-r--r--arch/arm/mach-mvebu/board-v7.c1
-rw-r--r--arch/arm/mach-mvebu/coherency_ll.S2
-rw-r--r--arch/arm/mach-mvebu/kirkwood.c2
-rw-r--r--arch/arm/mach-mvebu/pm-board.c11
-rw-r--r--arch/arm/mach-mvebu/pmsu_ll.S3
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c2
-rw-r--r--arch/arm64/Kconfig.platforms6
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts4
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra186.dtsi7
-rw-r--r--arch/arm64/boot/dts/sprd/whale2.dtsi16
l---------arch/csky/boot/dts/include/dt-bindings1
-rw-r--r--arch/csky/include/asm/Kbuild4
-rw-r--r--arch/h8300/include/asm/Kbuild1
-rw-r--r--arch/ia64/kernel/Makefile.gate2
-rw-r--r--arch/mips/Kconfig6
-rw-r--r--arch/mips/alchemy/common/platform.c22
-rw-r--r--arch/mips/generic/init.c4
-rw-r--r--arch/mips/include/asm/mach-ip27/topology.h11
-rw-r--r--arch/mips/include/asm/pci/bridge.h14
-rw-r--r--arch/mips/include/asm/sn/irq_alloc.h11
-rw-r--r--arch/mips/include/asm/xtalk/xtalk.h9
-rw-r--r--arch/mips/kernel/cpu-probe.c8
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c21
-rw-r--r--arch/mips/pci/Makefile3
-rw-r--r--arch/mips/pci/ops-bridge.c302
-rw-r--r--arch/mips/pci/pci-ip27.c181
-rw-r--r--arch/mips/pci/pci-xtalk-bridge.c610
-rw-r--r--arch/mips/pnx833x/Platform2
-rw-r--r--arch/mips/sgi-ip22/ip22-platform.c13
-rw-r--r--arch/mips/sgi-ip27/ip27-init.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c190
-rw-r--r--arch/mips/sgi-ip27/ip27-xtalk.c61
-rw-r--r--arch/nds32/include/asm/Kbuild3
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash.h6
-rw-r--r--arch/powerpc/include/asm/mmu_context.h1
-rw-r--r--arch/powerpc/kernel/cacheinfo.c1
-rw-r--r--arch/powerpc/mm/book3s32/hash_low.S3
-rw-r--r--arch/powerpc/mm/hugetlbpage.c2
-rw-r--r--arch/riscv/Kconfig6
-rw-r--r--arch/riscv/Makefile5
-rw-r--r--arch/riscv/include/asm/Kbuild5
-rw-r--r--arch/riscv/include/asm/bug.h35
-rw-r--r--arch/riscv/include/asm/cacheflush.h2
-rw-r--r--arch/riscv/include/asm/csr.h123
-rw-r--r--arch/riscv/include/asm/elf.h6
-rw-r--r--arch/riscv/include/asm/futex.h13
-rw-r--r--arch/riscv/include/asm/irqflags.h10
-rw-r--r--arch/riscv/include/asm/mmu_context.h59
-rw-r--r--arch/riscv/include/asm/ptrace.h21
-rw-r--r--arch/riscv/include/asm/sbi.h19
-rw-r--r--arch/riscv/include/asm/sifive_l2_cache.h16
-rw-r--r--arch/riscv/include/asm/thread_info.h4
-rw-r--r--arch/riscv/include/asm/uaccess.h28
-rw-r--r--arch/riscv/kernel/asm-offsets.c3
-rw-r--r--arch/riscv/kernel/cpu.c3
-rw-r--r--arch/riscv/kernel/entry.S22
-rw-r--r--arch/riscv/kernel/head.S33
-rw-r--r--arch/riscv/kernel/irq.c19
-rw-r--r--arch/riscv/kernel/perf_event.c4
-rw-r--r--arch/riscv/kernel/reset.c15
-rw-r--r--arch/riscv/kernel/setup.c6
-rw-r--r--arch/riscv/kernel/signal.c6
-rw-r--r--arch/riscv/kernel/smp.c61
-rw-r--r--arch/riscv/kernel/smpboot.c22
-rw-r--r--arch/riscv/kernel/stacktrace.c14
-rw-r--r--arch/riscv/kernel/traps.c30
-rw-r--r--arch/riscv/kernel/vdso/Makefile2
-rw-r--r--arch/riscv/mm/Makefile2
-rw-r--r--arch/riscv/mm/cacheflush.c61
-rw-r--r--arch/riscv/mm/context.c69
-rw-r--r--arch/riscv/mm/fault.c9
-rw-r--r--arch/riscv/mm/sifive_l2_cache.c175
-rw-r--r--arch/sh/Makefile4
-rw-r--r--arch/sh/boot/.gitignore1
-rw-r--r--arch/sh/kernel/vsyscall/Makefile3
-rw-r--r--arch/um/include/asm/mmu_context.h1
-rw-r--r--arch/unicore32/include/asm/mmu_context.h1
-rw-r--r--arch/x86/include/asm/mmu_context.h6
-rw-r--r--arch/x86/include/asm/mpx.h15
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/mm/Makefile2
-rw-r--r--arch/x86/mm/mpx.c10
-rw-r--r--arch/xtensa/boot/lib/Makefile2
-rw-r--r--arch/xtensa/include/asm/Kbuild1
-rw-r--r--drivers/amba/tegra-ahb.c6
-rw-r--r--drivers/clocksource/Kconfig14
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/clocksource/timer-atmel-tcb.c (renamed from drivers/clocksource/tcb_clksrc.c)126
-rw-r--r--drivers/clocksource/timer-milbeaut.c66
-rw-r--r--drivers/clocksource/timer-sun4i.c5
-rw-r--r--drivers/clocksource/timer-tegra20.c63
-rw-r--r--drivers/firmware/ti_sci.c651
-rw-r--r--drivers/firmware/ti_sci.h102
-rw-r--r--drivers/gpio/gpio-thunderx.c16
-rw-r--r--drivers/hid/intel-ish-hid/Makefile2
-rw-r--r--drivers/i2c/i2c-core-base.c118
-rw-r--r--drivers/iommu/Kconfig1
-rw-r--r--drivers/iommu/dma-iommu.c48
-rw-r--r--drivers/irqchip/Kconfig27
-rw-r--r--drivers/irqchip/Makefile2
-rw-r--r--drivers/irqchip/irq-bcm7038-l1.c3
-rw-r--r--drivers/irqchip/irq-bcm7120-l2.c3
-rw-r--r--drivers/irqchip/irq-brcmstb-l2.c2
-rw-r--r--drivers/irqchip/irq-gic-pm.c76
-rw-r--r--drivers/irqchip/irq-gic-v2m.c8
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c84
-rw-r--r--drivers/irqchip/irq-gic-v3-mbi.c10
-rw-r--r--drivers/irqchip/irq-imx-irqsteer.c4
-rw-r--r--drivers/irqchip/irq-ls-scfg-msi.c7
-rw-r--r--drivers/irqchip/irq-renesas-intc-irqpin.c4
-rw-r--r--drivers/irqchip/irq-stm32-exti.c233
-rw-r--r--drivers/irqchip/irq-ti-sci-inta.c615
-rw-r--r--drivers/irqchip/irq-ti-sci-intr.c275
-rw-r--r--drivers/media/common/b2c2/Makefile4
-rw-r--r--drivers/media/dvb-frontends/cxd2880/Makefile2
-rw-r--r--drivers/media/i2c/smiapp/Makefile2
-rw-r--r--drivers/media/mmc/siano/Makefile3
-rw-r--r--drivers/media/pci/b2c2/Makefile2
-rw-r--r--drivers/media/pci/bt8xx/Makefile5
-rw-r--r--drivers/media/pci/cx18/Makefile4
-rw-r--r--drivers/media/pci/cx23885/Makefile4
-rw-r--r--drivers/media/pci/cx88/Makefile4
-rw-r--r--drivers/media/pci/ddbridge/Makefile4
-rw-r--r--drivers/media/pci/dm1105/Makefile2
-rw-r--r--drivers/media/pci/mantis/Makefile2
-rw-r--r--drivers/media/pci/netup_unidvb/Makefile2
-rw-r--r--drivers/media/pci/ngene/Makefile4
-rw-r--r--drivers/media/pci/pluto2/Makefile2
-rw-r--r--drivers/media/pci/pt1/Makefile4
-rw-r--r--drivers/media/pci/pt3/Makefile4
-rw-r--r--drivers/media/pci/smipcie/Makefile5
-rw-r--r--drivers/media/pci/ttpci/Makefile4
-rw-r--r--drivers/media/platform/sti/c8sectpfe/Makefile5
-rw-r--r--drivers/media/radio/Makefile2
-rw-r--r--drivers/media/spi/Makefile4
-rw-r--r--drivers/media/usb/as102/Makefile2
-rw-r--r--drivers/media/usb/au0828/Makefile4
-rw-r--r--drivers/media/usb/b2c2/Makefile2
-rw-r--r--drivers/media/usb/cx231xx/Makefile5
-rw-r--r--drivers/media/usb/em28xx/Makefile4
-rw-r--r--drivers/media/usb/go7007/Makefile2
-rw-r--r--drivers/media/usb/pvrusb2/Makefile4
-rw-r--r--drivers/media/usb/siano/Makefile2
-rw-r--r--drivers/media/usb/tm6000/Makefile4
-rw-r--r--drivers/media/usb/ttusb-budget/Makefile2
-rw-r--r--drivers/media/usb/usbvision/Makefile2
-rw-r--r--drivers/misc/Kconfig24
-rw-r--r--drivers/misc/atmel_tclib.c5
-rw-r--r--drivers/net/ethernet/chelsio/libcxgb/Makefile2
-rw-r--r--drivers/pwm/pwm-atmel-tcb.c2
-rw-r--r--drivers/soc/fsl/qe/gpio.c4
-rw-r--r--drivers/soc/ixp4xx/ixp4xx-qmgr.c4
-rw-r--r--drivers/soc/ti/Kconfig6
-rw-r--r--drivers/soc/ti/Makefile1
-rw-r--r--drivers/soc/ti/ti_sci_inta_msi.c146
-rw-r--r--drivers/target/iscsi/cxgbit/Makefile6
-rw-r--r--drivers/tty/hvc/hvc_riscv_sbi.c1
-rw-r--r--drivers/usb/storage/Makefile2
-rw-r--r--drivers/video/fbdev/efifb.c8
-rw-r--r--fs/cifs/cifs_debug.c2
-rw-r--r--fs/cifs/cifsfs.c14
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/connect.c41
-rw-r--r--fs/cifs/smb2ops.c134
-rw-r--r--fs/cifs/smb2pdu.c21
-rw-r--r--fs/cifs/smbdirect.c8
-rw-r--r--fs/cifs/transport.c2
-rw-r--r--fs/ext4/block_validity.c8
-rw-r--r--fs/ext4/extents.c17
-rw-r--r--fs/ext4/file.c7
-rw-r--r--fs/ext4/fsmap.c2
-rw-r--r--fs/ext4/ioctl.c2
-rw-r--r--fs/ext4/namei.c5
-rw-r--r--fs/ext4/super.c4
-rw-r--r--fs/jbd2/journal.c49
-rw-r--r--fs/jbd2/revoke.c32
-rw-r--r--fs/jbd2/transaction.c8
-rw-r--r--fs/ocfs2/dlm/Makefile3
-rw-r--r--fs/ocfs2/dlmfs/Makefile2
-rw-r--r--fs/unicode/README.utf8data28
-rw-r--r--fs/unicode/utf8-norm.c2
-rw-r--r--fs/xfs/Makefile4
-rw-r--r--include/asm-generic/mm_hooks.h1
-rw-r--r--include/linux/clk/at91_pmc.h1
-rw-r--r--include/linux/dma-iommu.h24
-rw-r--r--include/linux/i2c.h3
-rw-r--r--include/linux/irq.h2
-rw-r--r--include/linux/irqchip/arm-gic-v3.h12
-rw-r--r--include/linux/irqdomain.h1
-rw-r--r--include/linux/jbd2.h8
-rw-r--r--include/linux/msi.h36
-rw-r--r--include/linux/platform_data/xtalk-bridge.h22
-rw-r--r--include/linux/soc/ti/ti_sci_inta_msi.h23
-rw-r--r--include/linux/soc/ti/ti_sci_protocol.h124
-rw-r--r--include/soc/at91/atmel_tcb.h (renamed from include/linux/atmel_tc.h)4
-rw-r--r--include/sound/hdaudio.h1
-rw-r--r--kernel/irq/Kconfig3
-rw-r--r--kernel/irq/chip.c27
-rw-r--r--kernel/irq/irqdomain.c2
-rw-r--r--mm/mmap.c15
-rw-r--r--net/bpfilter/Makefile2
-rw-r--r--samples/Makefile24
-rw-r--r--samples/seccomp/Makefile2
-rw-r--r--samples/vfs/Makefile2
-rw-r--r--scripts/Kbuild.include8
-rw-r--r--scripts/Kconfig.include8
-rw-r--r--scripts/Makefile.extrawarn25
-rw-r--r--scripts/Makefile.host12
-rw-r--r--scripts/Makefile.lib26
-rw-r--r--scripts/dtc/Makefile6
-rw-r--r--scripts/genksyms/Makefile4
-rw-r--r--scripts/kconfig/Makefile8
-rw-r--r--scripts/kconfig/confdata.c13
-rwxr-xr-xscripts/modules-check.sh16
-rw-r--r--sound/hda/hdac_device.c7
-rw-r--r--sound/hda/hdac_sysfs.c3
-rw-r--r--sound/pci/hda/patch_realtek.c96
-rw-r--r--tools/arch/x86/include/uapi/asm/kvm.h1
-rw-r--r--tools/arch/x86/include/uapi/asm/perf_regs.h23
-rw-r--r--tools/arch/x86/lib/memcpy_64.S3
-rw-r--r--tools/lib/traceevent/Documentation/Makefile207
-rw-r--r--tools/lib/traceevent/Documentation/asciidoc.conf120
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-commands.txt153
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-cpus.txt77
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt78
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-event_find.txt103
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-event_get.txt99
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-event_list.txt122
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-field_find.txt118
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt122
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-field_print.txt126
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-field_read.txt81
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-fields.txt105
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt91
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-filter.txt209
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt183
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-func_find.txt88
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-handle.txt101
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-header_page.txt102
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt104
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-long_size.txt78
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-page_size.txt82
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt90
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt82
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt137
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt156
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt155
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt104
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-strerror.txt85
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-tseq.txt158
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent.txt203
-rw-r--r--tools/lib/traceevent/Documentation/manpage-1.72.xsl14
-rw-r--r--tools/lib/traceevent/Documentation/manpage-base.xsl35
-rw-r--r--tools/lib/traceevent/Documentation/manpage-bold-literal.xsl17
-rw-r--r--tools/lib/traceevent/Documentation/manpage-normal.xsl13
-rw-r--r--tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl21
-rw-r--r--tools/lib/traceevent/Makefile46
-rw-r--r--tools/lib/traceevent/libtraceevent.pc.template4
-rw-r--r--tools/objtool/Makefile3
-rw-r--r--tools/pci/Makefile2
-rw-r--r--tools/perf/Documentation/perf-list.txt12
-rw-r--r--tools/perf/Documentation/perf-record.txt8
-rw-r--r--tools/perf/Documentation/perf-stat.txt4
-rw-r--r--tools/perf/Documentation/perf.data-file-format.txt24
-rw-r--r--tools/perf/Documentation/perf.txt2
-rw-r--r--tools/perf/arch/x86/include/perf_regs.h26
-rw-r--r--tools/perf/arch/x86/util/perf_regs.c44
-rw-r--r--tools/perf/builtin-annotate.c4
-rw-r--r--tools/perf/builtin-inject.c4
-rw-r--r--tools/perf/builtin-record.c229
-rw-r--r--tools/perf/builtin-report.c16
-rw-r--r--tools/perf/builtin-stat.c21
-rw-r--r--tools/perf/perf.h1
-rw-r--r--tools/perf/pmu-events/arch/arm64/arm/cortex-a57-a72/core-imp-def.json179
-rw-r--r--tools/perf/pmu-events/arch/arm64/mapfile.csv5
-rw-r--r--tools/perf/pmu-events/jevents.c2
-rwxr-xr-xtools/perf/scripts/python/exported-sql-viewer.py340
-rw-r--r--tools/perf/tests/dso-data.c4
-rw-r--r--tools/perf/tests/make2
-rwxr-xr-xtools/perf/tests/shell/record+zstd_comp_decomp.sh34
-rw-r--r--tools/perf/util/Build2
-rw-r--r--tools/perf/util/annotate.c2
-rw-r--r--tools/perf/util/compress.h53
-rw-r--r--tools/perf/util/env.h11
-rw-r--r--tools/perf/util/event.c1
-rw-r--r--tools/perf/util/event.h7
-rw-r--r--tools/perf/util/evlist.c8
-rw-r--r--tools/perf/util/evlist.h2
-rw-r--r--tools/perf/util/evsel.c2
-rw-r--r--tools/perf/util/evsel.h3
-rw-r--r--tools/perf/util/header.c53
-rw-r--r--tools/perf/util/header.h1
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c31
-rw-r--r--tools/perf/util/machine.c3
-rw-r--r--tools/perf/util/mmap.c102
-rw-r--r--tools/perf/util/mmap.h16
-rw-r--r--tools/perf/util/parse-events.c27
-rw-r--r--tools/perf/util/parse-events.h1
-rw-r--r--tools/perf/util/parse-events.l1
-rw-r--r--tools/perf/util/parse-regs-options.c33
-rw-r--r--tools/perf/util/parse-regs-options.h3
-rw-r--r--tools/perf/util/perf_regs.c10
-rw-r--r--tools/perf/util/perf_regs.h3
-rw-r--r--tools/perf/util/session.c133
-rw-r--r--tools/perf/util/session.h14
-rw-r--r--tools/perf/util/stat-display.c107
-rw-r--r--tools/perf/util/stat.c8
-rw-r--r--tools/perf/util/thread.c3
-rw-r--r--tools/perf/util/tool.h2
-rw-r--r--tools/perf/util/unwind-libunwind-local.c6
-rw-r--r--tools/perf/util/unwind-libunwind.c10
-rw-r--r--tools/perf/util/zstd.c111
335 files changed, 10559 insertions, 2044 deletions
diff --git a/.get_maintainer.ignore b/.get_maintainer.ignore
index cca6d870f7a5..a64d21913745 100644
--- a/.get_maintainer.ignore
+++ b/.get_maintainer.ignore
@@ -1 +1,2 @@
1Christoph Hellwig <hch@lst.de> 1Christoph Hellwig <hch@lst.de>
2Marc Gonzalez <marc.w.gonzalez@free.fr>
diff --git a/.gitignore b/.gitignore
index d263ca9a276c..7587ef56b92d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,12 +81,14 @@ modules.builtin
81/tar-install/ 81/tar-install/
82 82
83# 83#
84# git files that we don't want to ignore even if they are dot-files 84# We don't want to ignore the following even if they are dot-files
85# 85#
86!.clang-format
87!.cocciconfig
88!.get_maintainer.ignore
89!.gitattributes
86!.gitignore 90!.gitignore
87!.mailmap 91!.mailmap
88!.cocciconfig
89!.clang-format
90 92
91# 93#
92# Generated include files 94# Generated include files
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index 4bf1b4da7659..99dee23c74a4 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -25,6 +25,7 @@ compatible: must be one of:
25 o "atmel,at91sam9n12" 25 o "atmel,at91sam9n12"
26 o "atmel,at91sam9rl" 26 o "atmel,at91sam9rl"
27 o "atmel,at91sam9xe" 27 o "atmel,at91sam9xe"
28 o "microchip,sam9x60"
28 * "atmel,sama5" for SoCs using a Cortex-A5, shall be extended with the specific 29 * "atmel,sama5" for SoCs using a Cortex-A5, shall be extended with the specific
29 SoC family: 30 SoC family:
30 o "atmel,sama5d2" shall be extended with the specific SoC compatible: 31 o "atmel,sama5d2" shall be extended with the specific SoC compatible:
diff --git a/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt b/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
index b56a02c10ae6..6f0cd31c1520 100644
--- a/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+++ b/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
@@ -24,7 +24,8 @@ relationship between the TI-SCI parent node to the child node.
24 24
25Required properties: 25Required properties:
26------------------- 26-------------------
27- compatible: should be "ti,k2g-sci" 27- compatible: should be "ti,k2g-sci" for TI 66AK2G SoC
28 should be "ti,am654-sci" for for TI AM654 SoC
28- mbox-names: 29- mbox-names:
29 "rx" - Mailbox corresponding to receive path 30 "rx" - Mailbox corresponding to receive path
30 "tx" - Mailbox corresponding to transmit path 31 "tx" - Mailbox corresponding to transmit path
diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt
new file mode 100644
index 000000000000..7841cb099e13
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt
@@ -0,0 +1,66 @@
1Texas Instruments K3 Interrupt Aggregator
2=========================================
3
4The Interrupt Aggregator (INTA) provides a centralized machine
5which handles the termination of system events to that they can
6be coherently processed by the host(s) in the system. A maximum
7of 64 events can be mapped to a single interrupt.
8
9
10 Interrupt Aggregator
11 +-----------------------------------------+
12 | Intmap VINT |
13 | +--------------+ +------------+ |
14 m ------>| | vint | bit | | 0 |.....|63| vint0 |
15 . | +--------------+ +------------+ | +------+
16 . | . . | | HOST |
17Globalevents ------>| . . |------>| IRQ |
18 . | . . | | CTRL |
19 . | . . | +------+
20 n ------>| +--------------+ +------------+ |
21 | | vint | bit | | 0 |.....|63| vintx |
22 | +--------------+ +------------+ |
23 | |
24 +-----------------------------------------+
25
26Configuration of these Intmap registers that maps global events to vint is done
27by a system controller (like the Device Memory and Security Controller on K3
28AM654 SoC). Driver should request the system controller to get the range
29of global events and vints assigned to the requesting host. Management
30of these requested resources should be handled by driver and requests
31system controller to map specific global event to vint, bit pair.
32
33Communication between the host processor running an OS and the system
34controller happens through a protocol called TI System Control Interface
35(TISCI protocol). For more details refer:
36Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
37
38TISCI Interrupt Aggregator Node:
39-------------------------------
40- compatible: Must be "ti,sci-inta".
41- reg: Should contain registers location and length.
42- interrupt-controller: Identifies the node as an interrupt controller
43- msi-controller: Identifies the node as an MSI controller.
44- interrupt-parent: phandle of irq parent.
45- ti,sci: Phandle to TI-SCI compatible System controller node.
46- ti,sci-dev-id: TISCI device ID of the Interrupt Aggregator.
47- ti,sci-rm-range-vint: Array of TISCI subtype ids representing vints(inta
48 outputs) range within this INTA, assigned to the
49 requesting host context.
50- ti,sci-rm-range-global-event: Array of TISCI subtype ids representing the
51 global events range reaching this IA and are assigned
52 to the requesting host context.
53
54Example:
55--------
56main_udmass_inta: interrupt-controller@33d00000 {
57 compatible = "ti,sci-inta";
58 reg = <0x0 0x33d00000 0x0 0x100000>;
59 interrupt-controller;
60 msi-controller;
61 interrupt-parent = <&main_navss_intr>;
62 ti,sci = <&dmsc>;
63 ti,sci-dev-id = <179>;
64 ti,sci-rm-range-vint = <0x0>;
65 ti,sci-rm-range-global-event = <0x1>;
66};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
new file mode 100644
index 000000000000..1a8718f8855d
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
@@ -0,0 +1,82 @@
1Texas Instruments K3 Interrupt Router
2=====================================
3
4The Interrupt Router (INTR) module provides a mechanism to mux M
5interrupt inputs to N interrupt outputs, where all M inputs are selectable
6to be driven per N output. An Interrupt Router can either handle edge triggered
7or level triggered interrupts and that is fixed in hardware.
8
9 Interrupt Router
10 +----------------------+
11 | Inputs Outputs |
12 +-------+ | +------+ +-----+ |
13 | GPIO |----------->| | irq0 | | 0 | | Host IRQ
14 +-------+ | +------+ +-----+ | controller
15 | . . | +-------+
16 +-------+ | . . |----->| IRQ |
17 | INTA |----------->| . . | +-------+
18 +-------+ | . +-----+ |
19 | +------+ | N | |
20 | | irqM | +-----+ |
21 | +------+ |
22 | |
23 +----------------------+
24
25There is one register per output (MUXCNTL_N) that controls the selection.
26Configuration of these MUXCNTL_N registers is done by a system controller
27(like the Device Memory and Security Controller on K3 AM654 SoC). System
28controller will keep track of the used and unused registers within the Router.
29Driver should request the system controller to get the range of GIC IRQs
30assigned to the requesting hosts. It is the drivers responsibility to keep
31track of Host IRQs.
32
33Communication between the host processor running an OS and the system
34controller happens through a protocol called TI System Control Interface
35(TISCI protocol). For more details refer:
36Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
37
38TISCI Interrupt Router Node:
39----------------------------
40Required Properties:
41- compatible: Must be "ti,sci-intr".
42- ti,intr-trigger-type: Should be one of the following:
43 1: If intr supports edge triggered interrupts.
44 4: If intr supports level triggered interrupts.
45- interrupt-controller: Identifies the node as an interrupt controller
46- #interrupt-cells: Specifies the number of cells needed to encode an
47 interrupt source. The value should be 2.
48 First cell should contain the TISCI device ID of source
49 Second cell should contain the interrupt source offset
50 within the device.
51- ti,sci: Phandle to TI-SCI compatible System controller node.
52- ti,sci-dst-id: TISCI device ID of the destination IRQ controller.
53- ti,sci-rm-range-girq: Array of TISCI subtype ids representing the host irqs
54 assigned to this interrupt router. Each subtype id
55 corresponds to a range of host irqs.
56
57For more details on TISCI IRQ resource management refer:
58http://downloads.ti.com/tisci/esd/latest/2_tisci_msgs/rm/rm_irq.html
59
60Example:
61--------
62The following example demonstrates both interrupt router node and the consumer
63node(main gpio) on the AM654 SoC:
64
65main_intr: interrupt-controller0 {
66 compatible = "ti,sci-intr";
67 ti,intr-trigger-type = <1>;
68 interrupt-controller;
69 interrupt-parent = <&gic500>;
70 #interrupt-cells = <2>;
71 ti,sci = <&dmsc>;
72 ti,sci-dst-id = <56>;
73 ti,sci-rm-range-girq = <0x1>;
74};
75
76main_gpio0: gpio@600000 {
77 ...
78 interrupt-parent = <&main_intr>;
79 interrupts = <57 256>, <57 257>, <57 258>,
80 <57 259>, <57 260>, <57 261>;
81 ...
82};
diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt
new file mode 100644
index 000000000000..73d8f19c3bd9
--- /dev/null
+++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt
@@ -0,0 +1,51 @@
1SiFive L2 Cache Controller
2--------------------------
3The SiFive Level 2 Cache Controller is used to provide access to fast copies
4of memory for masters in a Core Complex. The Level 2 Cache Controller also
5acts as directory-based coherency manager.
6All the properties in ePAPR/DeviceTree specification applies for this platform
7
8Required Properties:
9--------------------
10- compatible: Should be "sifive,fu540-c000-ccache" and "cache"
11
12- cache-block-size: Specifies the block size in bytes of the cache.
13 Should be 64
14
15- cache-level: Should be set to 2 for a level 2 cache
16
17- cache-sets: Specifies the number of associativity sets of the cache.
18 Should be 1024
19
20- cache-size: Specifies the size in bytes of the cache. Should be 2097152
21
22- cache-unified: Specifies the cache is a unified cache
23
24- interrupts: Must contain 3 entries (DirError, DataError and DataFail signals)
25
26- reg: Physical base address and size of L2 cache controller registers map
27
28Optional Properties:
29--------------------
30- next-level-cache: phandle to the next level cache if present.
31
32- memory-region: reference to the reserved-memory for the L2 Loosely Integrated
33 Memory region. The reserved memory node should be defined as per the bindings
34 in reserved-memory.txt
35
36
37Example:
38
39 cache-controller@2010000 {
40 compatible = "sifive,fu540-c000-ccache", "cache";
41 cache-block-size = <64>;
42 cache-level = <2>;
43 cache-sets = <1024>;
44 cache-size = <2097152>;
45 cache-unified;
46 interrupt-parent = <&plic0>;
47 interrupts = <1 2 3>;
48 reg = <0x0 0x2010000 0x0 0x1000>;
49 next-level-cache = <&L25 &L40 &L36>;
50 memory-region = <&l2_lim>;
51 };
diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt
index 5c2e23574ca0..3da9d515c03a 100644
--- a/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt
+++ b/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt
@@ -2,7 +2,9 @@ Allwinner A1X SoCs Timer Controller
2 2
3Required properties: 3Required properties:
4 4
5- compatible : should be "allwinner,sun4i-a10-timer" 5- compatible : should be one of the following:
6 "allwinner,sun4i-a10-timer"
7 "allwinner,suniv-f1c100s-timer"
6- reg : Specifies base physical address and size of the registers. 8- reg : Specifies base physical address and size of the registers.
7- interrupts : The interrupt of the first timer 9- interrupts : The interrupt of the first timer
8- clocks: phandle to the source clock (usually a 24 MHz fixed clock) 10- clocks: phandle to the source clock (usually a 24 MHz fixed clock)
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 99994a461359..69c7fa7f616c 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -271,6 +271,9 @@ GPIO
271 devm_gpio_request_one() 271 devm_gpio_request_one()
272 devm_gpio_free() 272 devm_gpio_free()
273 273
274I2C
275 devm_i2c_new_dummy_device()
276
274IIO 277IIO
275 devm_iio_device_alloc() 278 devm_iio_device_alloc()
276 devm_iio_device_free() 279 devm_iio_device_free()
diff --git a/MAINTAINERS b/MAINTAINERS
index 9cc6767e1b12..5cfbea4ce575 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8542,6 +8542,7 @@ F: scripts/Kbuild*
8542F: scripts/Makefile* 8542F: scripts/Makefile*
8543F: scripts/basic/ 8543F: scripts/basic/
8544F: scripts/mk* 8544F: scripts/mk*
8545F: scripts/*vmlinux*
8545F: scripts/mod/ 8546F: scripts/mod/
8546F: scripts/package/ 8547F: scripts/package/
8547 8548
@@ -15547,6 +15548,12 @@ F: Documentation/devicetree/bindings/reset/ti,sci-reset.txt
15547F: Documentation/devicetree/bindings/clock/ti,sci-clk.txt 15548F: Documentation/devicetree/bindings/clock/ti,sci-clk.txt
15548F: drivers/clk/keystone/sci-clk.c 15549F: drivers/clk/keystone/sci-clk.c
15549F: drivers/reset/reset-ti-sci.c 15550F: drivers/reset/reset-ti-sci.c
15551F: Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
15552F: Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt
15553F: drivers/irqchip/irq-ti-sci-intr.c
15554F: drivers/irqchip/irq-ti-sci-inta.c
15555F: include/linux/soc/ti/ti_sci_inta_msi.h
15556F: drivers/soc/ti/ti_sci_inta_msi.c
15550 15557
15551Texas Instruments ASoC drivers 15558Texas Instruments ASoC drivers
15552M: Peter Ujfalusi <peter.ujfalusi@ti.com> 15559M: Peter Ujfalusi <peter.ujfalusi@ti.com>
diff --git a/Makefile b/Makefile
index a61a95b6b38f..1232a1454d5c 100644
--- a/Makefile
+++ b/Makefile
@@ -537,7 +537,7 @@ endif
537# Some architectures define CROSS_COMPILE in arch/$(SRCARCH)/Makefile. 537# Some architectures define CROSS_COMPILE in arch/$(SRCARCH)/Makefile.
538# CC_VERSION_TEXT is referenced from Kconfig (so it needs export), 538# CC_VERSION_TEXT is referenced from Kconfig (so it needs export),
539# and from include/config/auto.conf.cmd to detect the compiler upgrade. 539# and from include/config/auto.conf.cmd to detect the compiler upgrade.
540CC_VERSION_TEXT = $(shell $(CC) --version | head -n 1) 540CC_VERSION_TEXT = $(shell $(CC) --version 2>/dev/null | head -n 1)
541 541
542ifeq ($(config-targets),1) 542ifeq ($(config-targets),1)
543# =========================================================================== 543# ===========================================================================
@@ -651,7 +651,7 @@ ifeq ($(may-sync-config),1)
651# Read in dependencies to all Kconfig* files, make sure to run syncconfig if 651# Read in dependencies to all Kconfig* files, make sure to run syncconfig if
652# changes are detected. This should be included after arch/$(SRCARCH)/Makefile 652# changes are detected. This should be included after arch/$(SRCARCH)/Makefile
653# because some architectures define CROSS_COMPILE there. 653# because some architectures define CROSS_COMPILE there.
654-include include/config/auto.conf.cmd 654include include/config/auto.conf.cmd
655 655
656$(KCONFIG_CONFIG): 656$(KCONFIG_CONFIG):
657 @echo >&2 '***' 657 @echo >&2 '***'
@@ -692,7 +692,6 @@ KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)
692KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,) 692KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
693KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation) 693KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation)
694KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow) 694KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)
695KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context)
696KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) 695KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
697 696
698ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE 697ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
@@ -732,16 +731,15 @@ stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG) := -fstack-protector-strong
732KBUILD_CFLAGS += $(stackp-flags-y) 731KBUILD_CFLAGS += $(stackp-flags-y)
733 732
734ifdef CONFIG_CC_IS_CLANG 733ifdef CONFIG_CC_IS_CLANG
735KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,) 734KBUILD_CPPFLAGS += -Qunused-arguments
736KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier) 735KBUILD_CFLAGS += -Wno-format-invalid-specifier
737KBUILD_CFLAGS += $(call cc-disable-warning, gnu) 736KBUILD_CFLAGS += -Wno-gnu
738# Quiet clang warning: comparison of unsigned expression < 0 is always false 737# Quiet clang warning: comparison of unsigned expression < 0 is always false
739KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare) 738KBUILD_CFLAGS += -Wno-tautological-compare
740# CLANG uses a _MergedGlobals as optimization, but this breaks modpost, as the 739# CLANG uses a _MergedGlobals as optimization, but this breaks modpost, as the
741# source of a reference will be _MergedGlobals and not on of the whitelisted names. 740# source of a reference will be _MergedGlobals and not on of the whitelisted names.
742# See modpost pattern 2 741# See modpost pattern 2
743KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,) 742KBUILD_CFLAGS += -mno-global-merge
744KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
745else 743else
746 744
747# These warnings generated too much noise in a regular build. 745# These warnings generated too much noise in a regular build.
@@ -842,7 +840,7 @@ NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
842KBUILD_CFLAGS += -Wdeclaration-after-statement 840KBUILD_CFLAGS += -Wdeclaration-after-statement
843 841
844# Variable Length Arrays (VLAs) should not be used anywhere in the kernel 842# Variable Length Arrays (VLAs) should not be used anywhere in the kernel
845KBUILD_CFLAGS += $(call cc-option,-Wvla) 843KBUILD_CFLAGS += -Wvla
846 844
847# disable pointer signed / unsigned warnings in gcc 4.0 845# disable pointer signed / unsigned warnings in gcc 4.0
848KBUILD_CFLAGS += -Wno-pointer-sign 846KBUILD_CFLAGS += -Wno-pointer-sign
@@ -1018,7 +1016,7 @@ export KBUILD_VMLINUX_LIBS := $(libs-y1)
1018export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds 1016export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds
1019export LDFLAGS_vmlinux 1017export LDFLAGS_vmlinux
1020# used by scripts/package/Makefile 1018# used by scripts/package/Makefile
1021export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch include scripts tools) 1019export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) LICENSES arch include scripts tools)
1022 1020
1023vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) 1021vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS)
1024 1022
@@ -1290,6 +1288,7 @@ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
1290 $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order 1288 $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
1291 @$(kecho) ' Building modules, stage 2.'; 1289 @$(kecho) ' Building modules, stage 2.';
1292 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost 1290 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
1291 $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh
1293 1292
1294modules.builtin: $(vmlinux-dirs:%=%/modules.builtin) 1293modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
1295 $(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin 1294 $(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 12dee59b011c..b3314e0dcb6f 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -8,6 +8,8 @@
8# Copyright (C) 1994 by Linus Torvalds 8# Copyright (C) 1994 by Linus Torvalds
9# 9#
10 10
11KBUILD_DEFCONFIG := defconfig
12
11NM := $(NM) -B 13NM := $(NM) -B
12 14
13LDFLAGS_vmlinux := -static -N #-relax 15LDFLAGS_vmlinux := -static -N #-relax
diff --git a/arch/alpha/defconfig b/arch/alpha/configs/defconfig
index f4ec420d7f2d..f4ec420d7f2d 100644
--- a/arch/alpha/defconfig
+++ b/arch/alpha/configs/defconfig
diff --git a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
index 4990ed90dcea..3e39b9a1f35d 100644
--- a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
+++ b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
@@ -153,7 +153,7 @@
153 pinctrl-names = "default"; 153 pinctrl-names = "default";
154 pinctrl-0 = <&mmc1_pins>; 154 pinctrl-0 = <&mmc1_pins>;
155 wp-gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>; /* gpio_126 */ 155 wp-gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>; /* gpio_126 */
156 cd-gpios = <&gpio4 14 IRQ_TYPE_LEVEL_LOW>; /* gpio_110 */ 156 cd-gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* gpio_110 */
157 vmmc-supply = <&vmmc1>; 157 vmmc-supply = <&vmmc1>;
158 bus-width = <4>; 158 bus-width = <4>;
159 cap-power-off-card; 159 cap-power-off-card;
diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig
index 515cb37eeab6..d5341b0bd88d 100644
--- a/arch/arm/configs/sama5_defconfig
+++ b/arch/arm/configs/sama5_defconfig
@@ -150,7 +150,7 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
150CONFIG_V4L_PLATFORM_DRIVERS=y 150CONFIG_V4L_PLATFORM_DRIVERS=y
151CONFIG_SOC_CAMERA=y 151CONFIG_SOC_CAMERA=y
152CONFIG_VIDEO_ATMEL_ISI=y 152CONFIG_VIDEO_ATMEL_ISI=y
153CONFIG_SOC_CAMERA_OV2640=y 153CONFIG_SOC_CAMERA_OV2640=m
154CONFIG_DRM=y 154CONFIG_DRM=y
155CONFIG_DRM_ATMEL_HLCDC=y 155CONFIG_DRM_ATMEL_HLCDC=y
156CONFIG_DRM_PANEL_SIMPLE=y 156CONFIG_DRM_PANEL_SIMPLE=y
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index 9d42cfe85f5b..6701a975e785 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -21,7 +21,6 @@ CONFIG_NEON=y
21CONFIG_OPROFILE=y 21CONFIG_OPROFILE=y
22CONFIG_MODULES=y 22CONFIG_MODULES=y
23CONFIG_MODULE_UNLOAD=y 23CONFIG_MODULE_UNLOAD=y
24# CONFIG_LBDAF is not set
25# CONFIG_BLK_DEV_BSG is not set 24# CONFIG_BLK_DEV_BSG is not set
26CONFIG_NET=y 25CONFIG_NET=y
27CONFIG_PACKET=y 26CONFIG_PACKET=y
@@ -128,6 +127,8 @@ CONFIG_RTC_DRV_DS1307=y
128CONFIG_DMADEVICES=y 127CONFIG_DMADEVICES=y
129CONFIG_PL330_DMA=y 128CONFIG_PL330_DMA=y
130CONFIG_DMATEST=m 129CONFIG_DMATEST=m
130CONFIG_IIO=y
131CONFIG_LTC2497=y
131CONFIG_FPGA=y 132CONFIG_FPGA=y
132CONFIG_FPGA_MGR_SOCFPGA=y 133CONFIG_FPGA_MGR_SOCFPGA=y
133CONFIG_FPGA_MGR_SOCFPGA_A10=y 134CONFIG_FPGA_MGR_SOCFPGA_A10=y
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 903f23c309df..a2220e522f62 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -21,7 +21,6 @@ config SOC_SAMA5D2
21 depends on ARCH_MULTI_V7 21 depends on ARCH_MULTI_V7
22 select SOC_SAMA5 22 select SOC_SAMA5
23 select CACHE_L2X0 23 select CACHE_L2X0
24 select HAVE_FB_ATMEL
25 select HAVE_AT91_UTMI 24 select HAVE_AT91_UTMI
26 select HAVE_AT91_USB_CLK 25 select HAVE_AT91_USB_CLK
27 select HAVE_AT91_H32MX 26 select HAVE_AT91_H32MX
@@ -36,7 +35,6 @@ config SOC_SAMA5D3
36 bool "SAMA5D3 family" 35 bool "SAMA5D3 family"
37 depends on ARCH_MULTI_V7 36 depends on ARCH_MULTI_V7
38 select SOC_SAMA5 37 select SOC_SAMA5
39 select HAVE_FB_ATMEL
40 select HAVE_AT91_UTMI 38 select HAVE_AT91_UTMI
41 select HAVE_AT91_SMD 39 select HAVE_AT91_SMD
42 select HAVE_AT91_USB_CLK 40 select HAVE_AT91_USB_CLK
@@ -50,7 +48,6 @@ config SOC_SAMA5D4
50 depends on ARCH_MULTI_V7 48 depends on ARCH_MULTI_V7
51 select SOC_SAMA5 49 select SOC_SAMA5
52 select CACHE_L2X0 50 select CACHE_L2X0
53 select HAVE_FB_ATMEL
54 select HAVE_AT91_UTMI 51 select HAVE_AT91_UTMI
55 select HAVE_AT91_SMD 52 select HAVE_AT91_SMD
56 select HAVE_AT91_USB_CLK 53 select HAVE_AT91_USB_CLK
@@ -107,6 +104,29 @@ config SOC_AT91SAM9
107 AT91SAM9X35 104 AT91SAM9X35
108 AT91SAM9XE 105 AT91SAM9XE
109 106
107comment "Clocksource driver selection"
108
109config ATMEL_CLOCKSOURCE_PIT
110 bool "Periodic Interval Timer (PIT) support"
111 depends on SOC_AT91SAM9 || SOC_SAMA5
112 default SOC_AT91SAM9 || SOC_SAMA5
113 select ATMEL_PIT
114 help
115 Select this to get a clocksource based on the Atmel Periodic Interval
116 Timer. It has a relatively low resolution and the TC Block clocksource
117 should be preferred.
118
119config ATMEL_CLOCKSOURCE_TCB
120 bool "Timer Counter Blocks (TCB) support"
121 default SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAMA5
122 select ATMEL_TCB_CLKSRC
123 help
124 Select this to get a high precision clocksource based on a
125 TC block with a 5+ MHz base clock rate.
126 On platforms with 16-bit counters, two timer channels are combined
127 to make a single 32-bit timer.
128 It can also be used as a clock event device supporting oneshot mode.
129
110config HAVE_AT91_UTMI 130config HAVE_AT91_UTMI
111 bool 131 bool
112 132
diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
index 3dbdef4d3cbf..c12563b09656 100644
--- a/arch/arm/mach-at91/at91sam9.c
+++ b/arch/arm/mach-at91/at91sam9.c
@@ -32,3 +32,21 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
32 .init_machine = at91sam9_init, 32 .init_machine = at91sam9_init,
33 .dt_compat = at91_dt_board_compat, 33 .dt_compat = at91_dt_board_compat,
34MACHINE_END 34MACHINE_END
35
36static void __init sam9x60_init(void)
37{
38 of_platform_default_populate(NULL, NULL, NULL);
39
40 sam9x60_pm_init();
41}
42
43static const char *const sam9x60_dt_board_compat[] __initconst = {
44 "microchip,sam9x60",
45 NULL
46};
47
48DT_MACHINE_START(sam9x60_dt, "Microchip SAM9X60")
49 /* Maintainer: Microchip */
50 .init_machine = sam9x60_init,
51 .dt_compat = sam9x60_dt_board_compat,
52MACHINE_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index e2bd17237964..72b45accfa0f 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -14,11 +14,13 @@
14#ifdef CONFIG_PM 14#ifdef CONFIG_PM
15extern void __init at91rm9200_pm_init(void); 15extern void __init at91rm9200_pm_init(void);
16extern void __init at91sam9_pm_init(void); 16extern void __init at91sam9_pm_init(void);
17extern void __init sam9x60_pm_init(void);
17extern void __init sama5_pm_init(void); 18extern void __init sama5_pm_init(void);
18extern void __init sama5d2_pm_init(void); 19extern void __init sama5d2_pm_init(void);
19#else 20#else
20static inline void __init at91rm9200_pm_init(void) { } 21static inline void __init at91rm9200_pm_init(void) { }
21static inline void __init at91sam9_pm_init(void) { } 22static inline void __init at91sam9_pm_init(void) { }
23static inline void __init sam9x60_pm_init(void) { }
22static inline void __init sama5_pm_init(void) { } 24static inline void __init sama5_pm_init(void) { }
23static inline void __init sama5d2_pm_init(void) { } 25static inline void __init sama5d2_pm_init(void) { }
24#endif 26#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 2a757dcaa1a5..6c8147536f3d 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -39,6 +39,20 @@ extern void at91_pinctrl_gpio_suspend(void);
39extern void at91_pinctrl_gpio_resume(void); 39extern void at91_pinctrl_gpio_resume(void);
40#endif 40#endif
41 41
42struct at91_soc_pm {
43 int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity);
44 int (*config_pmc_ws)(void __iomem *pmc, u32 mode, u32 polarity);
45 const struct of_device_id *ws_ids;
46 struct at91_pm_data data;
47};
48
49static struct at91_soc_pm soc_pm = {
50 .data = {
51 .standby_mode = AT91_PM_STANDBY,
52 .suspend_mode = AT91_PM_ULP0,
53 },
54};
55
42static const match_table_t pm_modes __initconst = { 56static const match_table_t pm_modes __initconst = {
43 { AT91_PM_STANDBY, "standby" }, 57 { AT91_PM_STANDBY, "standby" },
44 { AT91_PM_ULP0, "ulp0" }, 58 { AT91_PM_ULP0, "ulp0" },
@@ -47,16 +61,11 @@ static const match_table_t pm_modes __initconst = {
47 { -1, NULL }, 61 { -1, NULL },
48}; 62};
49 63
50static struct at91_pm_data pm_data = {
51 .standby_mode = AT91_PM_STANDBY,
52 .suspend_mode = AT91_PM_ULP0,
53};
54
55#define at91_ramc_read(id, field) \ 64#define at91_ramc_read(id, field) \
56 __raw_readl(pm_data.ramc[id] + field) 65 __raw_readl(soc_pm.data.ramc[id] + field)
57 66
58#define at91_ramc_write(id, field, value) \ 67#define at91_ramc_write(id, field, value) \
59 __raw_writel(value, pm_data.ramc[id] + field) 68 __raw_writel(value, soc_pm.data.ramc[id] + field)
60 69
61static int at91_pm_valid_state(suspend_state_t state) 70static int at91_pm_valid_state(suspend_state_t state)
62{ 71{
@@ -91,6 +100,8 @@ static const struct wakeup_source_info ws_info[] = {
91 { .pmc_fsmr_bit = AT91_PMC_RTCAL, .shdwc_mr_bit = BIT(17) }, 100 { .pmc_fsmr_bit = AT91_PMC_RTCAL, .shdwc_mr_bit = BIT(17) },
92 { .pmc_fsmr_bit = AT91_PMC_USBAL }, 101 { .pmc_fsmr_bit = AT91_PMC_USBAL },
93 { .pmc_fsmr_bit = AT91_PMC_SDMMC_CD }, 102 { .pmc_fsmr_bit = AT91_PMC_SDMMC_CD },
103 { .pmc_fsmr_bit = AT91_PMC_RTTAL },
104 { .pmc_fsmr_bit = AT91_PMC_RXLP_MCE },
94}; 105};
95 106
96static const struct of_device_id sama5d2_ws_ids[] = { 107static const struct of_device_id sama5d2_ws_ids[] = {
@@ -105,6 +116,17 @@ static const struct of_device_id sama5d2_ws_ids[] = {
105 { /* sentinel */ } 116 { /* sentinel */ }
106}; 117};
107 118
119static const struct of_device_id sam9x60_ws_ids[] = {
120 { .compatible = "atmel,at91sam9x5-rtc", .data = &ws_info[1] },
121 { .compatible = "atmel,at91rm9200-ohci", .data = &ws_info[2] },
122 { .compatible = "usb-ohci", .data = &ws_info[2] },
123 { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] },
124 { .compatible = "usb-ehci", .data = &ws_info[2] },
125 { .compatible = "atmel,at91sam9260-rtt", .data = &ws_info[4] },
126 { .compatible = "cdns,sam9x60-macb", .data = &ws_info[5] },
127 { /* sentinel */ }
128};
129
108static int at91_pm_config_ws(unsigned int pm_mode, bool set) 130static int at91_pm_config_ws(unsigned int pm_mode, bool set)
109{ 131{
110 const struct wakeup_source_info *wsi; 132 const struct wakeup_source_info *wsi;
@@ -116,24 +138,22 @@ static int at91_pm_config_ws(unsigned int pm_mode, bool set)
116 if (pm_mode != AT91_PM_ULP1) 138 if (pm_mode != AT91_PM_ULP1)
117 return 0; 139 return 0;
118 140
119 if (!pm_data.pmc || !pm_data.shdwc) 141 if (!soc_pm.data.pmc || !soc_pm.data.shdwc || !soc_pm.ws_ids)
120 return -EPERM; 142 return -EPERM;
121 143
122 if (!set) { 144 if (!set) {
123 writel(mode, pm_data.pmc + AT91_PMC_FSMR); 145 writel(mode, soc_pm.data.pmc + AT91_PMC_FSMR);
124 return 0; 146 return 0;
125 } 147 }
126 148
127 /* SHDWC.WUIR */ 149 if (soc_pm.config_shdwc_ws)
128 val = readl(pm_data.shdwc + 0x0c); 150 soc_pm.config_shdwc_ws(soc_pm.data.shdwc, &mode, &polarity);
129 mode |= (val & 0x3ff);
130 polarity |= ((val >> 16) & 0x3ff);
131 151
132 /* SHDWC.MR */ 152 /* SHDWC.MR */
133 val = readl(pm_data.shdwc + 0x04); 153 val = readl(soc_pm.data.shdwc + 0x04);
134 154
135 /* Loop through defined wakeup sources. */ 155 /* Loop through defined wakeup sources. */
136 for_each_matching_node_and_match(np, sama5d2_ws_ids, &match) { 156 for_each_matching_node_and_match(np, soc_pm.ws_ids, &match) {
137 pdev = of_find_device_by_node(np); 157 pdev = of_find_device_by_node(np);
138 if (!pdev) 158 if (!pdev)
139 continue; 159 continue;
@@ -155,8 +175,8 @@ put_device:
155 } 175 }
156 176
157 if (mode) { 177 if (mode) {
158 writel(mode, pm_data.pmc + AT91_PMC_FSMR); 178 if (soc_pm.config_pmc_ws)
159 writel(polarity, pm_data.pmc + AT91_PMC_FSPR); 179 soc_pm.config_pmc_ws(soc_pm.data.pmc, mode, polarity);
160 } else { 180 } else {
161 pr_err("AT91: PM: no ULP1 wakeup sources found!"); 181 pr_err("AT91: PM: no ULP1 wakeup sources found!");
162 } 182 }
@@ -164,6 +184,34 @@ put_device:
164 return mode ? 0 : -EPERM; 184 return mode ? 0 : -EPERM;
165} 185}
166 186
187static int at91_sama5d2_config_shdwc_ws(void __iomem *shdwc, u32 *mode,
188 u32 *polarity)
189{
190 u32 val;
191
192 /* SHDWC.WUIR */
193 val = readl(shdwc + 0x0c);
194 *mode |= (val & 0x3ff);
195 *polarity |= ((val >> 16) & 0x3ff);
196
197 return 0;
198}
199
200static int at91_sama5d2_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
201{
202 writel(mode, pmc + AT91_PMC_FSMR);
203 writel(polarity, pmc + AT91_PMC_FSPR);
204
205 return 0;
206}
207
208static int at91_sam9x60_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
209{
210 writel(mode, pmc + AT91_PMC_FSMR);
211
212 return 0;
213}
214
167/* 215/*
168 * Called after processes are frozen, but before we shutdown devices. 216 * Called after processes are frozen, but before we shutdown devices.
169 */ 217 */
@@ -171,18 +219,18 @@ static int at91_pm_begin(suspend_state_t state)
171{ 219{
172 switch (state) { 220 switch (state) {
173 case PM_SUSPEND_MEM: 221 case PM_SUSPEND_MEM:
174 pm_data.mode = pm_data.suspend_mode; 222 soc_pm.data.mode = soc_pm.data.suspend_mode;
175 break; 223 break;
176 224
177 case PM_SUSPEND_STANDBY: 225 case PM_SUSPEND_STANDBY:
178 pm_data.mode = pm_data.standby_mode; 226 soc_pm.data.mode = soc_pm.data.standby_mode;
179 break; 227 break;
180 228
181 default: 229 default:
182 pm_data.mode = -1; 230 soc_pm.data.mode = -1;
183 } 231 }
184 232
185 return at91_pm_config_ws(pm_data.mode, true); 233 return at91_pm_config_ws(soc_pm.data.mode, true);
186} 234}
187 235
188/* 236/*
@@ -194,10 +242,10 @@ static int at91_pm_verify_clocks(void)
194 unsigned long scsr; 242 unsigned long scsr;
195 int i; 243 int i;
196 244
197 scsr = readl(pm_data.pmc + AT91_PMC_SCSR); 245 scsr = readl(soc_pm.data.pmc + AT91_PMC_SCSR);
198 246
199 /* USB must not be using PLLB */ 247 /* USB must not be using PLLB */
200 if ((scsr & pm_data.uhp_udp_mask) != 0) { 248 if ((scsr & soc_pm.data.uhp_udp_mask) != 0) {
201 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); 249 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
202 return 0; 250 return 0;
203 } 251 }
@@ -208,7 +256,7 @@ static int at91_pm_verify_clocks(void)
208 256
209 if ((scsr & (AT91_PMC_PCK0 << i)) == 0) 257 if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
210 continue; 258 continue;
211 css = readl(pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS; 259 css = readl(soc_pm.data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
212 if (css != AT91_PMC_CSS_SLOW) { 260 if (css != AT91_PMC_CSS_SLOW) {
213 pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); 261 pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
214 return 0; 262 return 0;
@@ -230,7 +278,7 @@ static int at91_pm_verify_clocks(void)
230 */ 278 */
231int at91_suspend_entering_slow_clock(void) 279int at91_suspend_entering_slow_clock(void)
232{ 280{
233 return (pm_data.mode >= AT91_PM_ULP0); 281 return (soc_pm.data.mode >= AT91_PM_ULP0);
234} 282}
235EXPORT_SYMBOL(at91_suspend_entering_slow_clock); 283EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
236 284
@@ -243,14 +291,14 @@ static int at91_suspend_finish(unsigned long val)
243 flush_cache_all(); 291 flush_cache_all();
244 outer_disable(); 292 outer_disable();
245 293
246 at91_suspend_sram_fn(&pm_data); 294 at91_suspend_sram_fn(&soc_pm.data);
247 295
248 return 0; 296 return 0;
249} 297}
250 298
251static void at91_pm_suspend(suspend_state_t state) 299static void at91_pm_suspend(suspend_state_t state)
252{ 300{
253 if (pm_data.mode == AT91_PM_BACKUP) { 301 if (soc_pm.data.mode == AT91_PM_BACKUP) {
254 pm_bu->suspended = 1; 302 pm_bu->suspended = 1;
255 303
256 cpu_suspend(0, at91_suspend_finish); 304 cpu_suspend(0, at91_suspend_finish);
@@ -289,7 +337,7 @@ static int at91_pm_enter(suspend_state_t state)
289 /* 337 /*
290 * Ensure that clocks are in a valid state. 338 * Ensure that clocks are in a valid state.
291 */ 339 */
292 if (pm_data.mode >= AT91_PM_ULP0 && 340 if (soc_pm.data.mode >= AT91_PM_ULP0 &&
293 !at91_pm_verify_clocks()) 341 !at91_pm_verify_clocks())
294 goto error; 342 goto error;
295 343
@@ -318,7 +366,7 @@ error:
318 */ 366 */
319static void at91_pm_end(void) 367static void at91_pm_end(void)
320{ 368{
321 at91_pm_config_ws(pm_data.mode, false); 369 at91_pm_config_ws(soc_pm.data.mode, false);
322} 370}
323 371
324 372
@@ -351,7 +399,7 @@ static void at91rm9200_standby(void)
351 " str %2, [%1, %3]\n\t" 399 " str %2, [%1, %3]\n\t"
352 " mcr p15, 0, %0, c7, c0, 4\n\t" 400 " mcr p15, 0, %0, c7, c0, 4\n\t"
353 : 401 :
354 : "r" (0), "r" (pm_data.ramc[0]), 402 : "r" (0), "r" (soc_pm.data.ramc[0]),
355 "r" (1), "r" (AT91_MC_SDRAMC_SRR)); 403 "r" (1), "r" (AT91_MC_SDRAMC_SRR));
356} 404}
357 405
@@ -374,7 +422,7 @@ static void at91_ddr_standby(void)
374 at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr); 422 at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr);
375 } 423 }
376 424
377 if (pm_data.ramc[1]) { 425 if (soc_pm.data.ramc[1]) {
378 saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); 426 saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
379 lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; 427 lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
380 lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; 428 lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
@@ -392,14 +440,14 @@ static void at91_ddr_standby(void)
392 440
393 /* self-refresh mode now */ 441 /* self-refresh mode now */
394 at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); 442 at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
395 if (pm_data.ramc[1]) 443 if (soc_pm.data.ramc[1])
396 at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); 444 at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
397 445
398 cpu_do_idle(); 446 cpu_do_idle();
399 447
400 at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0); 448 at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0);
401 at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); 449 at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
402 if (pm_data.ramc[1]) { 450 if (soc_pm.data.ramc[1]) {
403 at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1); 451 at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1);
404 at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); 452 at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
405 } 453 }
@@ -429,7 +477,7 @@ static void at91sam9_sdram_standby(void)
429 u32 lpr0, lpr1 = 0; 477 u32 lpr0, lpr1 = 0;
430 u32 saved_lpr0, saved_lpr1 = 0; 478 u32 saved_lpr0, saved_lpr1 = 0;
431 479
432 if (pm_data.ramc[1]) { 480 if (soc_pm.data.ramc[1]) {
433 saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR); 481 saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
434 lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB; 482 lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
435 lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; 483 lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
@@ -441,13 +489,13 @@ static void at91sam9_sdram_standby(void)
441 489
442 /* self-refresh mode now */ 490 /* self-refresh mode now */
443 at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0); 491 at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
444 if (pm_data.ramc[1]) 492 if (soc_pm.data.ramc[1])
445 at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1); 493 at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
446 494
447 cpu_do_idle(); 495 cpu_do_idle();
448 496
449 at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0); 497 at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
450 if (pm_data.ramc[1]) 498 if (soc_pm.data.ramc[1])
451 at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1); 499 at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
452} 500}
453 501
@@ -480,14 +528,14 @@ static __init void at91_dt_ramc(void)
480 const struct ramc_info *ramc; 528 const struct ramc_info *ramc;
481 529
482 for_each_matching_node_and_match(np, ramc_ids, &of_id) { 530 for_each_matching_node_and_match(np, ramc_ids, &of_id) {
483 pm_data.ramc[idx] = of_iomap(np, 0); 531 soc_pm.data.ramc[idx] = of_iomap(np, 0);
484 if (!pm_data.ramc[idx]) 532 if (!soc_pm.data.ramc[idx])
485 panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx); 533 panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
486 534
487 ramc = of_id->data; 535 ramc = of_id->data;
488 if (!standby) 536 if (!standby)
489 standby = ramc->idle; 537 standby = ramc->idle;
490 pm_data.memctrl = ramc->memctrl; 538 soc_pm.data.memctrl = ramc->memctrl;
491 539
492 idx++; 540 idx++;
493 } 541 }
@@ -509,12 +557,17 @@ static void at91rm9200_idle(void)
509 * Disable the processor clock. The processor will be automatically 557 * Disable the processor clock. The processor will be automatically
510 * re-enabled by an interrupt or by a reset. 558 * re-enabled by an interrupt or by a reset.
511 */ 559 */
512 writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR); 560 writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR);
561}
562
563static void at91sam9x60_idle(void)
564{
565 cpu_do_idle();
513} 566}
514 567
515static void at91sam9_idle(void) 568static void at91sam9_idle(void)
516{ 569{
517 writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR); 570 writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR);
518 cpu_do_idle(); 571 cpu_do_idle();
519} 572}
520 573
@@ -566,8 +619,8 @@ static void __init at91_pm_sram_init(void)
566 619
567static bool __init at91_is_pm_mode_active(int pm_mode) 620static bool __init at91_is_pm_mode_active(int pm_mode)
568{ 621{
569 return (pm_data.standby_mode == pm_mode || 622 return (soc_pm.data.standby_mode == pm_mode ||
570 pm_data.suspend_mode == pm_mode); 623 soc_pm.data.suspend_mode == pm_mode);
571} 624}
572 625
573static int __init at91_pm_backup_init(void) 626static int __init at91_pm_backup_init(void)
@@ -577,6 +630,9 @@ static int __init at91_pm_backup_init(void)
577 struct platform_device *pdev = NULL; 630 struct platform_device *pdev = NULL;
578 int ret = -ENODEV; 631 int ret = -ENODEV;
579 632
633 if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
634 return -EPERM;
635
580 if (!at91_is_pm_mode_active(AT91_PM_BACKUP)) 636 if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
581 return 0; 637 return 0;
582 638
@@ -586,7 +642,7 @@ static int __init at91_pm_backup_init(void)
586 return ret; 642 return ret;
587 } 643 }
588 644
589 pm_data.sfrbu = of_iomap(np, 0); 645 soc_pm.data.sfrbu = of_iomap(np, 0);
590 of_node_put(np); 646 of_node_put(np);
591 647
592 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam"); 648 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam");
@@ -622,8 +678,8 @@ static int __init at91_pm_backup_init(void)
622securam_fail: 678securam_fail:
623 put_device(&pdev->dev); 679 put_device(&pdev->dev);
624securam_fail_no_ref_dev: 680securam_fail_no_ref_dev:
625 iounmap(pm_data.sfrbu); 681 iounmap(soc_pm.data.sfrbu);
626 pm_data.sfrbu = NULL; 682 soc_pm.data.sfrbu = NULL;
627 return ret; 683 return ret;
628} 684}
629 685
@@ -632,10 +688,10 @@ static void __init at91_pm_use_default_mode(int pm_mode)
632 if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP) 688 if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP)
633 return; 689 return;
634 690
635 if (pm_data.standby_mode == pm_mode) 691 if (soc_pm.data.standby_mode == pm_mode)
636 pm_data.standby_mode = AT91_PM_ULP0; 692 soc_pm.data.standby_mode = AT91_PM_ULP0;
637 if (pm_data.suspend_mode == pm_mode) 693 if (soc_pm.data.suspend_mode == pm_mode)
638 pm_data.suspend_mode = AT91_PM_ULP0; 694 soc_pm.data.suspend_mode = AT91_PM_ULP0;
639} 695}
640 696
641static void __init at91_pm_modes_init(void) 697static void __init at91_pm_modes_init(void)
@@ -653,7 +709,7 @@ static void __init at91_pm_modes_init(void)
653 goto ulp1_default; 709 goto ulp1_default;
654 } 710 }
655 711
656 pm_data.shdwc = of_iomap(np, 0); 712 soc_pm.data.shdwc = of_iomap(np, 0);
657 of_node_put(np); 713 of_node_put(np);
658 714
659 ret = at91_pm_backup_init(); 715 ret = at91_pm_backup_init();
@@ -667,8 +723,8 @@ static void __init at91_pm_modes_init(void)
667 return; 723 return;
668 724
669unmap: 725unmap:
670 iounmap(pm_data.shdwc); 726 iounmap(soc_pm.data.shdwc);
671 pm_data.shdwc = NULL; 727 soc_pm.data.shdwc = NULL;
672ulp1_default: 728ulp1_default:
673 at91_pm_use_default_mode(AT91_PM_ULP1); 729 at91_pm_use_default_mode(AT91_PM_ULP1);
674backup_default: 730backup_default:
@@ -711,14 +767,14 @@ static void __init at91_pm_init(void (*pm_idle)(void))
711 platform_device_register(&at91_cpuidle_device); 767 platform_device_register(&at91_cpuidle_device);
712 768
713 pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id); 769 pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id);
714 pm_data.pmc = of_iomap(pmc_np, 0); 770 soc_pm.data.pmc = of_iomap(pmc_np, 0);
715 if (!pm_data.pmc) { 771 if (!soc_pm.data.pmc) {
716 pr_err("AT91: PM not supported, PMC not found\n"); 772 pr_err("AT91: PM not supported, PMC not found\n");
717 return; 773 return;
718 } 774 }
719 775
720 pmc = of_id->data; 776 pmc = of_id->data;
721 pm_data.uhp_udp_mask = pmc->uhp_udp_mask; 777 soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask;
722 778
723 if (pm_idle) 779 if (pm_idle)
724 arm_pm_idle = pm_idle; 780 arm_pm_idle = pm_idle;
@@ -728,8 +784,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
728 if (at91_suspend_sram_fn) { 784 if (at91_suspend_sram_fn) {
729 suspend_set_ops(&at91_pm_ops); 785 suspend_set_ops(&at91_pm_ops);
730 pr_info("AT91: PM: standby: %s, suspend: %s\n", 786 pr_info("AT91: PM: standby: %s, suspend: %s\n",
731 pm_modes[pm_data.standby_mode].pattern, 787 pm_modes[soc_pm.data.standby_mode].pattern,
732 pm_modes[pm_data.suspend_mode].pattern); 788 pm_modes[soc_pm.data.suspend_mode].pattern);
733 } else { 789 } else {
734 pr_info("AT91: PM not supported, due to no SRAM allocated\n"); 790 pr_info("AT91: PM not supported, due to no SRAM allocated\n");
735 } 791 }
@@ -750,6 +806,19 @@ void __init at91rm9200_pm_init(void)
750 at91_pm_init(at91rm9200_idle); 806 at91_pm_init(at91rm9200_idle);
751} 807}
752 808
809void __init sam9x60_pm_init(void)
810{
811 if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
812 return;
813
814 at91_pm_modes_init();
815 at91_dt_ramc();
816 at91_pm_init(at91sam9x60_idle);
817
818 soc_pm.ws_ids = sam9x60_ws_ids;
819 soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
820}
821
753void __init at91sam9_pm_init(void) 822void __init at91sam9_pm_init(void)
754{ 823{
755 if (!IS_ENABLED(CONFIG_SOC_AT91SAM9)) 824 if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
@@ -775,6 +844,10 @@ void __init sama5d2_pm_init(void)
775 844
776 at91_pm_modes_init(); 845 at91_pm_modes_init();
777 sama5_pm_init(); 846 sama5_pm_init();
847
848 soc_pm.ws_ids = sama5d2_ws_ids;
849 soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws;
850 soc_pm.config_pmc_ws = at91_sama5d2_config_pmc_ws;
778} 851}
779 852
780static int __init at91_pm_modes_select(char *str) 853static int __init at91_pm_modes_select(char *str)
@@ -795,8 +868,8 @@ static int __init at91_pm_modes_select(char *str)
795 if (suspend < 0) 868 if (suspend < 0)
796 return 0; 869 return 0;
797 870
798 pm_data.standby_mode = standby; 871 soc_pm.data.standby_mode = standby;
799 pm_data.suspend_mode = suspend; 872 soc_pm.data.suspend_mode = suspend;
800 873
801 return 0; 874 return 0;
802} 875}
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index bfe1c4d06901..77e29309cc6e 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -51,15 +51,6 @@ tmp2 .req r5
51 .endm 51 .endm
52 52
53/* 53/*
54 * Wait until PLLA has locked.
55 */
56 .macro wait_pllalock
571: ldr tmp1, [pmc, #AT91_PMC_SR]
58 tst tmp1, #AT91_PMC_LOCKA
59 beq 1b
60 .endm
61
62/*
63 * Put the processor to enter the idle state 54 * Put the processor to enter the idle state
64 */ 55 */
65 .macro at91_cpu_idle 56 .macro at91_cpu_idle
@@ -178,11 +169,46 @@ ENDPROC(at91_backup_mode)
178 orr tmp1, tmp1, #AT91_PMC_KEY 169 orr tmp1, tmp1, #AT91_PMC_KEY
179 str tmp1, [pmc, #AT91_CKGR_MOR] 170 str tmp1, [pmc, #AT91_CKGR_MOR]
180 171
172 /* Save RC oscillator state */
173 ldr tmp1, [pmc, #AT91_PMC_SR]
174 str tmp1, .saved_osc_status
175 tst tmp1, #AT91_PMC_MOSCRCS
176 bne 1f
177
178 /* Turn off RC oscillator */
179 ldr tmp1, [pmc, #AT91_CKGR_MOR]
180 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
181 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
182 orr tmp1, tmp1, #AT91_PMC_KEY
183 str tmp1, [pmc, #AT91_CKGR_MOR]
184
185 /* Wait main RC disabled done */
1862: ldr tmp1, [pmc, #AT91_PMC_SR]
187 tst tmp1, #AT91_PMC_MOSCRCS
188 bne 2b
189
181 /* Wait for interrupt */ 190 /* Wait for interrupt */
182 at91_cpu_idle 1911: at91_cpu_idle
183 192
184 /* Turn on the crystal oscillator */ 193 /* Restore RC oscillator state */
194 ldr tmp1, .saved_osc_status
195 tst tmp1, #AT91_PMC_MOSCRCS
196 beq 4f
197
198 /* Turn on RC oscillator */
185 ldr tmp1, [pmc, #AT91_CKGR_MOR] 199 ldr tmp1, [pmc, #AT91_CKGR_MOR]
200 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
201 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
202 orr tmp1, tmp1, #AT91_PMC_KEY
203 str tmp1, [pmc, #AT91_CKGR_MOR]
204
205 /* Wait main RC stabilization */
2063: ldr tmp1, [pmc, #AT91_PMC_SR]
207 tst tmp1, #AT91_PMC_MOSCRCS
208 beq 3b
209
210 /* Turn on the crystal oscillator */
2114: ldr tmp1, [pmc, #AT91_CKGR_MOR]
186 orr tmp1, tmp1, #AT91_PMC_MOSCEN 212 orr tmp1, tmp1, #AT91_PMC_MOSCEN
187 orr tmp1, tmp1, #AT91_PMC_KEY 213 orr tmp1, tmp1, #AT91_PMC_KEY
188 str tmp1, [pmc, #AT91_CKGR_MOR] 214 str tmp1, [pmc, #AT91_CKGR_MOR]
@@ -197,8 +223,26 @@ ENDPROC(at91_backup_mode)
197.macro at91_pm_ulp1_mode 223.macro at91_pm_ulp1_mode
198 ldr pmc, .pmc_base 224 ldr pmc, .pmc_base
199 225
200 /* Switch the main clock source to 12-MHz RC oscillator */ 226 /* Save RC oscillator state and check if it is enabled. */
227 ldr tmp1, [pmc, #AT91_PMC_SR]
228 str tmp1, .saved_osc_status
229 tst tmp1, #AT91_PMC_MOSCRCS
230 bne 2f
231
232 /* Enable RC oscillator */
201 ldr tmp1, [pmc, #AT91_CKGR_MOR] 233 ldr tmp1, [pmc, #AT91_CKGR_MOR]
234 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
235 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
236 orr tmp1, tmp1, #AT91_PMC_KEY
237 str tmp1, [pmc, #AT91_CKGR_MOR]
238
239 /* Wait main RC stabilization */
2401: ldr tmp1, [pmc, #AT91_PMC_SR]
241 tst tmp1, #AT91_PMC_MOSCRCS
242 beq 1b
243
244 /* Switch the main clock source to 12-MHz RC oscillator */
2452: ldr tmp1, [pmc, #AT91_CKGR_MOR]
202 bic tmp1, tmp1, #AT91_PMC_MOSCSEL 246 bic tmp1, tmp1, #AT91_PMC_MOSCSEL
203 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 247 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
204 orr tmp1, tmp1, #AT91_PMC_KEY 248 orr tmp1, tmp1, #AT91_PMC_KEY
@@ -262,6 +306,25 @@ ENDPROC(at91_backup_mode)
262 str tmp1, [pmc, #AT91_PMC_MCKR] 306 str tmp1, [pmc, #AT91_PMC_MCKR]
263 307
264 wait_mckrdy 308 wait_mckrdy
309
310 /* Restore RC oscillator state */
311 ldr tmp1, .saved_osc_status
312 tst tmp1, #AT91_PMC_MOSCRCS
313 bne 3f
314
315 /* Disable RC oscillator */
316 ldr tmp1, [pmc, #AT91_CKGR_MOR]
317 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
318 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
319 orr tmp1, tmp1, #AT91_PMC_KEY
320 str tmp1, [pmc, #AT91_CKGR_MOR]
321
322 /* Wait RC oscillator disable done */
3234: ldr tmp1, [pmc, #AT91_PMC_SR]
324 tst tmp1, #AT91_PMC_MOSCRCS
325 bne 4b
326
3273:
265.endm 328.endm
266 329
267ENTRY(at91_ulp_mode) 330ENTRY(at91_ulp_mode)
@@ -279,14 +342,6 @@ ENTRY(at91_ulp_mode)
279 342
280 wait_mckrdy 343 wait_mckrdy
281 344
282 /* Save PLLA setting and disable it */
283 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
284 str tmp1, .saved_pllar
285
286 mov tmp1, #AT91_PMC_PLLCOUNT
287 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
288 str tmp1, [pmc, #AT91_CKGR_PLLAR]
289
290 ldr r0, .pm_mode 345 ldr r0, .pm_mode
291 cmp r0, #AT91_PM_ULP1 346 cmp r0, #AT91_PM_ULP1
292 beq ulp1_mode 347 beq ulp1_mode
@@ -301,18 +356,6 @@ ulp1_mode:
301ulp_exit: 356ulp_exit:
302 ldr pmc, .pmc_base 357 ldr pmc, .pmc_base
303 358
304 /* Restore PLLA setting */
305 ldr tmp1, .saved_pllar
306 str tmp1, [pmc, #AT91_CKGR_PLLAR]
307
308 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
309 bne 3f
310 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
311 beq 4f
3123:
313 wait_pllalock
3144:
315
316 /* 359 /*
317 * Restore master clock setting 360 * Restore master clock setting
318 */ 361 */
@@ -465,8 +508,6 @@ ENDPROC(at91_sramc_self_refresh)
465 .word 0 508 .word 0
466.saved_mckr: 509.saved_mckr:
467 .word 0 510 .word 0
468.saved_pllar:
469 .word 0
470.saved_sam9_lpr: 511.saved_sam9_lpr:
471 .word 0 512 .word 0
472.saved_sam9_lpr1: 513.saved_sam9_lpr1:
@@ -475,6 +516,8 @@ ENDPROC(at91_sramc_self_refresh)
475 .word 0 516 .word 0
476.saved_sam9_mdr1: 517.saved_sam9_mdr1:
477 .word 0 518 .word 0
519.saved_osc_status:
520 .word 0
478 521
479ENTRY(at91_pm_suspend_in_sram_sz) 522ENTRY(at91_pm_suspend_in_sram_sz)
480 .word .-at91_pm_suspend_in_sram 523 .word .-at91_pm_suspend_in_sram
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index cc5f15679d29..381f452de28d 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -27,7 +27,6 @@
27#include <linux/cpu.h> 27#include <linux/cpu.h>
28#include <linux/pci.h> 28#include <linux/pci.h>
29#include <linux/sched_clock.h> 29#include <linux/sched_clock.h>
30#include <linux/bitops.h>
31#include <linux/irqchip/irq-ixp4xx.h> 30#include <linux/irqchip/irq-ixp4xx.h>
32#include <linux/platform_data/timer-ixp4xx.h> 31#include <linux/platform_data/timer-ixp4xx.h>
33#include <mach/udc.h> 32#include <mach/udc.h>
diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
index 0b10acd7d1b9..d2df5ef9382b 100644
--- a/arch/arm/mach-mvebu/board-v7.c
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -136,7 +136,6 @@ static void __init i2c_quirk(void)
136 136
137 of_update_property(np, new_compat); 137 of_update_property(np, new_compat);
138 } 138 }
139 return;
140} 139}
141 140
142static void __init mvebu_dt_init(void) 141static void __init mvebu_dt_init(void)
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
index 8b2fbc8b6bc6..2d962fe48821 100644
--- a/arch/arm/mach-mvebu/coherency_ll.S
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -66,7 +66,7 @@ ENDPROC(ll_get_coherency_base)
66 * fabric registers 66 * fabric registers
67 */ 67 */
68ENTRY(ll_get_coherency_cpumask) 68ENTRY(ll_get_coherency_cpumask)
69 mrc 15, 0, r3, cr0, cr0, 5 69 mrc p15, 0, r3, cr0, cr0, 5
70 and r3, r3, #15 70 and r3, r3, #15
71 mov r2, #(1 << 24) 71 mov r2, #(1 << 24)
72 lsl r3, r2, r3 72 lsl r3, r2, r3
diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c
index 9b5f4d665374..ceaad6d5927e 100644
--- a/arch/arm/mach-mvebu/kirkwood.c
+++ b/arch/arm/mach-mvebu/kirkwood.c
@@ -108,8 +108,6 @@ static void __init kirkwood_dt_eth_fixup(void)
108 clk_prepare_enable(clk); 108 clk_prepare_enable(clk);
109 109
110 /* store MAC address register contents in local-mac-address */ 110 /* store MAC address register contents in local-mac-address */
111 pr_err(FW_INFO "%pOF: local-mac-address is not set\n", np);
112
113 pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL); 111 pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL);
114 if (!pmac) 112 if (!pmac)
115 goto eth_fixup_no_mem; 113 goto eth_fixup_no_mem;
diff --git a/arch/arm/mach-mvebu/pm-board.c b/arch/arm/mach-mvebu/pm-board.c
index db17121d7d63..070552511699 100644
--- a/arch/arm/mach-mvebu/pm-board.c
+++ b/arch/arm/mach-mvebu/pm-board.c
@@ -79,7 +79,7 @@ static void mvebu_armada_pm_enter(void __iomem *sdram_reg, u32 srcmd)
79static int __init mvebu_armada_pm_init(void) 79static int __init mvebu_armada_pm_init(void)
80{ 80{
81 struct device_node *np; 81 struct device_node *np;
82 struct device_node *gpio_ctrl_np; 82 struct device_node *gpio_ctrl_np = NULL;
83 int ret = 0, i; 83 int ret = 0, i;
84 84
85 if (!of_machine_is_compatible("marvell,axp-gp")) 85 if (!of_machine_is_compatible("marvell,axp-gp"))
@@ -126,18 +126,23 @@ static int __init mvebu_armada_pm_init(void)
126 goto out; 126 goto out;
127 } 127 }
128 128
129 if (gpio_ctrl_np)
130 of_node_put(gpio_ctrl_np);
129 gpio_ctrl_np = args.np; 131 gpio_ctrl_np = args.np;
130 pic_raw_gpios[i] = args.args[0]; 132 pic_raw_gpios[i] = args.args[0];
131 } 133 }
132 134
133 gpio_ctrl = of_iomap(gpio_ctrl_np, 0); 135 gpio_ctrl = of_iomap(gpio_ctrl_np, 0);
134 if (!gpio_ctrl) 136 if (!gpio_ctrl) {
135 return -ENOMEM; 137 ret = -ENOMEM;
138 goto out;
139 }
136 140
137 mvebu_pm_suspend_init(mvebu_armada_pm_enter); 141 mvebu_pm_suspend_init(mvebu_armada_pm_enter);
138 142
139out: 143out:
140 of_node_put(np); 144 of_node_put(np);
145 of_node_put(gpio_ctrl_np);
141 return ret; 146 return ret;
142} 147}
143 148
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
index 88651221dbdd..7aae9a25cfeb 100644
--- a/arch/arm/mach-mvebu/pmsu_ll.S
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -16,7 +16,7 @@
16ENTRY(armada_38x_scu_power_up) 16ENTRY(armada_38x_scu_power_up)
17 mrc p15, 4, r1, c15, c0 @ get SCU base address 17 mrc p15, 4, r1, c15, c0 @ get SCU base address
18 orr r1, r1, #0x8 @ SCU CPU Power Status Register 18 orr r1, r1, #0x8 @ SCU CPU Power Status Register
19 mrc 15, 0, r0, cr0, cr0, 5 @ get the CPU ID 19 mrc p15, 0, r0, cr0, cr0, 5 @ get the CPU ID
20 and r0, r0, #15 20 and r0, r0, #15
21 add r1, r1, r0 21 add r1, r1, r0
22 mov r0, #0x0 22 mov r0, #0x0
@@ -56,7 +56,6 @@ ENDPROC(armada_38x_cpu_resume)
56 56
57/* The following code will be executed from SRAM */ 57/* The following code will be executed from SRAM */
58ENTRY(mvebu_boot_wa_start) 58ENTRY(mvebu_boot_wa_start)
59mvebu_boot_wa_start:
60ARM_BE8(setend be) 59ARM_BE8(setend be)
61 adr r0, 1f 60 adr r0, 1f
62 ldr r0, [r0] @ load the address of the 61 ldr r0, [r0] @ load the address of the
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 1b15d593837e..b6e814166ee0 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -749,7 +749,7 @@ static void __init ams_delta_init(void)
749 ARRAY_SIZE(ams_delta_gpio_tables)); 749 ARRAY_SIZE(ams_delta_gpio_tables));
750 750
751 leds_pdev = gpio_led_register_device(PLATFORM_DEVID_NONE, &leds_pdata); 751 leds_pdev = gpio_led_register_device(PLATFORM_DEVID_NONE, &leds_pdata);
752 if (!IS_ERR(leds_pdev)) { 752 if (!IS_ERR_OR_NULL(leds_pdev)) {
753 leds_gpio_table.dev_id = dev_name(&leds_pdev->dev); 753 leds_gpio_table.dev_id = dev_name(&leds_pdev->dev);
754 gpiod_add_lookup_table(&leds_gpio_table); 754 gpiod_add_lookup_table(&leds_gpio_table);
755 } 755 }
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 0f4d91824e4b..42eca656faa8 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -87,6 +87,11 @@ config ARCH_EXYNOS
87config ARCH_K3 87config ARCH_K3
88 bool "Texas Instruments Inc. K3 multicore SoC architecture" 88 bool "Texas Instruments Inc. K3 multicore SoC architecture"
89 select PM_GENERIC_DOMAINS if PM 89 select PM_GENERIC_DOMAINS if PM
90 select MAILBOX
91 select TI_MESSAGE_MANAGER
92 select TI_SCI_PROTOCOL
93 select TI_SCI_INTR_IRQCHIP
94 select TI_SCI_INTA_IRQCHIP
90 help 95 help
91 This enables support for Texas Instruments' K3 multicore SoC 96 This enables support for Texas Instruments' K3 multicore SoC
92 architecture. 97 architecture.
@@ -215,6 +220,7 @@ config ARCH_SYNQUACER
215config ARCH_TEGRA 220config ARCH_TEGRA
216 bool "NVIDIA Tegra SoC Family" 221 bool "NVIDIA Tegra SoC Family"
217 select ARCH_HAS_RESET_CONTROLLER 222 select ARCH_HAS_RESET_CONTROLLER
223 select ARM_GIC_PM
218 select CLKDEV_LOOKUP 224 select CLKDEV_LOOKUP
219 select CLKSRC_MMIO 225 select CLKSRC_MMIO
220 select TIMER_OF 226 select TIMER_OF
diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
index 75ee6cf1e1b4..14d7fea82daf 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
@@ -59,7 +59,7 @@
59 }; 59 };
60 60
61 padctl@3520000 { 61 padctl@3520000 {
62 status = "okay"; 62 status = "disabled";
63 63
64 avdd-pll-erefeut-supply = <&vdd_1v8_pll>; 64 avdd-pll-erefeut-supply = <&vdd_1v8_pll>;
65 avdd-usb-supply = <&vdd_3v3_sys>; 65 avdd-usb-supply = <&vdd_3v3_sys>;
@@ -137,7 +137,7 @@
137 }; 137 };
138 138
139 usb@3530000 { 139 usb@3530000 {
140 status = "okay"; 140 status = "disabled";
141 141
142 phys = <&{/padctl@3520000/pads/usb2/lanes/usb2-0}>, 142 phys = <&{/padctl@3520000/pads/usb2/lanes/usb2-0}>,
143 <&{/padctl@3520000/pads/usb2/lanes/usb2-1}>, 143 <&{/padctl@3520000/pads/usb2/lanes/usb2-1}>,
diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index f0bb6ced4976..426ac0bdf6a6 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -60,6 +60,7 @@
60 clock-names = "master_bus", "slave_bus", "rx", "tx", "ptp_ref"; 60 clock-names = "master_bus", "slave_bus", "rx", "tx", "ptp_ref";
61 resets = <&bpmp TEGRA186_RESET_EQOS>; 61 resets = <&bpmp TEGRA186_RESET_EQOS>;
62 reset-names = "eqos"; 62 reset-names = "eqos";
63 iommus = <&smmu TEGRA186_SID_EQOS>;
63 status = "disabled"; 64 status = "disabled";
64 65
65 snps,write-requests = <1>; 66 snps,write-requests = <1>;
@@ -338,6 +339,7 @@
338 <&bpmp TEGRA186_RESET_HDA2CODEC_2X>; 339 <&bpmp TEGRA186_RESET_HDA2CODEC_2X>;
339 reset-names = "hda", "hda2hdmi", "hda2codec_2x"; 340 reset-names = "hda", "hda2hdmi", "hda2codec_2x";
340 power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISP>; 341 power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISP>;
342 iommus = <&smmu TEGRA186_SID_HDA>;
341 status = "disabled"; 343 status = "disabled";
342 }; 344 };
343 345
@@ -671,6 +673,10 @@
671 <&bpmp TEGRA186_RESET_PCIEXCLK>; 673 <&bpmp TEGRA186_RESET_PCIEXCLK>;
672 reset-names = "afi", "pex", "pcie_x"; 674 reset-names = "afi", "pex", "pcie_x";
673 675
676 iommus = <&smmu TEGRA186_SID_AFI>;
677 iommu-map = <0x0 &smmu TEGRA186_SID_AFI 0x1000>;
678 iommu-map-mask = <0x0>;
679
674 status = "disabled"; 680 status = "disabled";
675 681
676 pci@1,0 { 682 pci@1,0 {
@@ -1158,6 +1164,7 @@
1158 1164
1159 bpmp: bpmp { 1165 bpmp: bpmp {
1160 compatible = "nvidia,tegra186-bpmp"; 1166 compatible = "nvidia,tegra186-bpmp";
1167 iommus = <&smmu TEGRA186_SID_BPMP>;
1161 mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB 1168 mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB
1162 TEGRA_HSP_DB_MASTER_BPMP>; 1169 TEGRA_HSP_DB_MASTER_BPMP>;
1163 shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>; 1170 shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
diff --git a/arch/arm64/boot/dts/sprd/whale2.dtsi b/arch/arm64/boot/dts/sprd/whale2.dtsi
index eb6be5675f79..4bb862c6b083 100644
--- a/arch/arm64/boot/dts/sprd/whale2.dtsi
+++ b/arch/arm64/boot/dts/sprd/whale2.dtsi
@@ -75,7 +75,9 @@
75 "sprd,sc9836-uart"; 75 "sprd,sc9836-uart";
76 reg = <0x0 0x100>; 76 reg = <0x0 0x100>;
77 interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; 77 interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
78 clocks = <&ext_26m>; 78 clock-names = "enable", "uart", "source";
79 clocks = <&apapb_gate CLK_UART0_EB>,
80 <&ap_clk CLK_UART0>, <&ext_26m>;
79 status = "disabled"; 81 status = "disabled";
80 }; 82 };
81 83
@@ -84,7 +86,9 @@
84 "sprd,sc9836-uart"; 86 "sprd,sc9836-uart";
85 reg = <0x100000 0x100>; 87 reg = <0x100000 0x100>;
86 interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; 88 interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
87 clocks = <&ext_26m>; 89 clock-names = "enable", "uart", "source";
90 clocks = <&apapb_gate CLK_UART1_EB>,
91 <&ap_clk CLK_UART1>, <&ext_26m>;
88 status = "disabled"; 92 status = "disabled";
89 }; 93 };
90 94
@@ -93,7 +97,9 @@
93 "sprd,sc9836-uart"; 97 "sprd,sc9836-uart";
94 reg = <0x200000 0x100>; 98 reg = <0x200000 0x100>;
95 interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; 99 interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
96 clocks = <&ext_26m>; 100 clock-names = "enable", "uart", "source";
101 clocks = <&apapb_gate CLK_UART2_EB>,
102 <&ap_clk CLK_UART2>, <&ext_26m>;
97 status = "disabled"; 103 status = "disabled";
98 }; 104 };
99 105
@@ -102,7 +108,9 @@
102 "sprd,sc9836-uart"; 108 "sprd,sc9836-uart";
103 reg = <0x300000 0x100>; 109 reg = <0x300000 0x100>;
104 interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; 110 interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
105 clocks = <&ext_26m>; 111 clock-names = "enable", "uart", "source";
112 clocks = <&apapb_gate CLK_UART3_EB>,
113 <&ap_clk CLK_UART3>, <&ext_26m>;
106 status = "disabled"; 114 status = "disabled";
107 }; 115 };
108 }; 116 };
diff --git a/arch/csky/boot/dts/include/dt-bindings b/arch/csky/boot/dts/include/dt-bindings
deleted file mode 120000
index 08c00e4972fa..000000000000
--- a/arch/csky/boot/dts/include/dt-bindings
+++ /dev/null
@@ -1 +0,0 @@
1../../../../../include/dt-bindings \ No newline at end of file
diff --git a/arch/csky/include/asm/Kbuild b/arch/csky/include/asm/Kbuild
index a9b63efef416..c1a6c0f31150 100644
--- a/arch/csky/include/asm/Kbuild
+++ b/arch/csky/include/asm/Kbuild
@@ -1,6 +1,5 @@
1generic-y += asm-offsets.h 1generic-y += asm-offsets.h
2generic-y += bugs.h 2generic-y += bugs.h
3generic-y += clkdev.h
4generic-y += compat.h 3generic-y += compat.h
5generic-y += current.h 4generic-y += current.h
6generic-y += delay.h 5generic-y += delay.h
@@ -29,15 +28,12 @@ generic-y += local64.h
29generic-y += mm-arch-hooks.h 28generic-y += mm-arch-hooks.h
30generic-y += mmiowb.h 29generic-y += mmiowb.h
31generic-y += module.h 30generic-y += module.h
32generic-y += mutex.h
33generic-y += pci.h 31generic-y += pci.h
34generic-y += percpu.h 32generic-y += percpu.h
35generic-y += preempt.h 33generic-y += preempt.h
36generic-y += qrwlock.h 34generic-y += qrwlock.h
37generic-y += scatterlist.h
38generic-y += sections.h 35generic-y += sections.h
39generic-y += serial.h 36generic-y += serial.h
40generic-y += shm.h
41generic-y += timex.h 37generic-y += timex.h
42generic-y += topology.h 38generic-y += topology.h
43generic-y += trace_clock.h 39generic-y += trace_clock.h
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
index 79cd1e605ec4..789214ac99bf 100644
--- a/arch/h8300/include/asm/Kbuild
+++ b/arch/h8300/include/asm/Kbuild
@@ -38,7 +38,6 @@ generic-y += pci.h
38generic-y += percpu.h 38generic-y += percpu.h
39generic-y += pgalloc.h 39generic-y += pgalloc.h
40generic-y += preempt.h 40generic-y += preempt.h
41generic-y += scatterlist.h
42generic-y += sections.h 41generic-y += sections.h
43generic-y += serial.h 42generic-y += serial.h
44generic-y += shmparam.h 43generic-y += shmparam.h
diff --git a/arch/ia64/kernel/Makefile.gate b/arch/ia64/kernel/Makefile.gate
index f53faf48b7ce..846867bff6d6 100644
--- a/arch/ia64/kernel/Makefile.gate
+++ b/arch/ia64/kernel/Makefile.gate
@@ -11,7 +11,7 @@ quiet_cmd_gate = GATE $@
11 cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ 11 cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
12 12
13GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \ 13GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
14 $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) 14 -Wl,--hash-style=sysv
15$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE 15$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
16 $(call if_changed,gate) 16 $(call if_changed,gate)
17 17
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 677e5bfeff47..70d3200476bf 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -674,7 +674,10 @@ config SGI_IP27
674 select SYS_HAS_EARLY_PRINTK 674 select SYS_HAS_EARLY_PRINTK
675 select HAVE_PCI 675 select HAVE_PCI
676 select IRQ_MIPS_CPU 676 select IRQ_MIPS_CPU
677 select IRQ_DOMAIN_HIERARCHY
677 select NR_CPUS_DEFAULT_64 678 select NR_CPUS_DEFAULT_64
679 select PCI_DRIVERS_GENERIC
680 select PCI_XTALK_BRIDGE
678 select SYS_HAS_CPU_R10000 681 select SYS_HAS_CPU_R10000
679 select SYS_SUPPORTS_64BIT_KERNEL 682 select SYS_SUPPORTS_64BIT_KERNEL
680 select SYS_SUPPORTS_BIG_ENDIAN 683 select SYS_SUPPORTS_BIG_ENDIAN
@@ -1241,6 +1244,9 @@ config IRQ_GT641XX
1241config PCI_GT64XXX_PCI0 1244config PCI_GT64XXX_PCI0
1242 bool 1245 bool
1243 1246
1247config PCI_XTALK_BRIDGE
1248 bool
1249
1244config NO_EXCEPT_FILL 1250config NO_EXCEPT_FILL
1245 bool 1251 bool
1246 1252
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index 1454d9f6ab2d..b8f3397c59c9 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -131,9 +131,7 @@ static void __init alchemy_setup_uarts(int ctype)
131} 131}
132 132
133 133
134/* The dmamask must be set for OHCI/EHCI to work */ 134static u64 alchemy_all_dmamask = DMA_BIT_MASK(32);
135static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32);
136static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32);
137 135
138/* Power on callback for the ehci platform driver */ 136/* Power on callback for the ehci platform driver */
139static int alchemy_ehci_power_on(struct platform_device *pdev) 137static int alchemy_ehci_power_on(struct platform_device *pdev)
@@ -231,7 +229,7 @@ static void __init alchemy_setup_usb(int ctype)
231 res[1].flags = IORESOURCE_IRQ; 229 res[1].flags = IORESOURCE_IRQ;
232 pdev->name = "ohci-platform"; 230 pdev->name = "ohci-platform";
233 pdev->id = 0; 231 pdev->id = 0;
234 pdev->dev.dma_mask = &alchemy_ohci_dmamask; 232 pdev->dev.dma_mask = &alchemy_all_dmamask;
235 pdev->dev.platform_data = &alchemy_ohci_pdata; 233 pdev->dev.platform_data = &alchemy_ohci_pdata;
236 234
237 if (platform_device_register(pdev)) 235 if (platform_device_register(pdev))
@@ -251,7 +249,7 @@ static void __init alchemy_setup_usb(int ctype)
251 res[1].flags = IORESOURCE_IRQ; 249 res[1].flags = IORESOURCE_IRQ;
252 pdev->name = "ehci-platform"; 250 pdev->name = "ehci-platform";
253 pdev->id = 0; 251 pdev->id = 0;
254 pdev->dev.dma_mask = &alchemy_ehci_dmamask; 252 pdev->dev.dma_mask = &alchemy_all_dmamask;
255 pdev->dev.platform_data = &alchemy_ehci_pdata; 253 pdev->dev.platform_data = &alchemy_ehci_pdata;
256 254
257 if (platform_device_register(pdev)) 255 if (platform_device_register(pdev))
@@ -271,7 +269,7 @@ static void __init alchemy_setup_usb(int ctype)
271 res[1].flags = IORESOURCE_IRQ; 269 res[1].flags = IORESOURCE_IRQ;
272 pdev->name = "ohci-platform"; 270 pdev->name = "ohci-platform";
273 pdev->id = 1; 271 pdev->id = 1;
274 pdev->dev.dma_mask = &alchemy_ohci_dmamask; 272 pdev->dev.dma_mask = &alchemy_all_dmamask;
275 pdev->dev.platform_data = &alchemy_ohci_pdata; 273 pdev->dev.platform_data = &alchemy_ohci_pdata;
276 274
277 if (platform_device_register(pdev)) 275 if (platform_device_register(pdev))
@@ -338,7 +336,11 @@ static struct platform_device au1xxx_eth0_device = {
338 .name = "au1000-eth", 336 .name = "au1000-eth",
339 .id = 0, 337 .id = 0,
340 .num_resources = MAC_RES_COUNT, 338 .num_resources = MAC_RES_COUNT,
341 .dev.platform_data = &au1xxx_eth0_platform_data, 339 .dev = {
340 .dma_mask = &alchemy_all_dmamask,
341 .coherent_dma_mask = DMA_BIT_MASK(32),
342 .platform_data = &au1xxx_eth0_platform_data,
343 },
342}; 344};
343 345
344static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = { 346static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
@@ -370,7 +372,11 @@ static struct platform_device au1xxx_eth1_device = {
370 .name = "au1000-eth", 372 .name = "au1000-eth",
371 .id = 1, 373 .id = 1,
372 .num_resources = MAC_RES_COUNT, 374 .num_resources = MAC_RES_COUNT,
373 .dev.platform_data = &au1xxx_eth1_platform_data, 375 .dev = {
376 .dma_mask = &alchemy_all_dmamask,
377 .coherent_dma_mask = DMA_BIT_MASK(32),
378 .platform_data = &au1xxx_eth1_platform_data,
379 },
374}; 380};
375 381
376void __init au1xxx_override_eth_cfg(unsigned int port, 382void __init au1xxx_override_eth_cfg(unsigned int port,
diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c
index a106f8113842..a84475f1924f 100644
--- a/arch/mips/generic/init.c
+++ b/arch/mips/generic/init.c
@@ -43,14 +43,14 @@ void __init *plat_get_fdt(void)
43 /* Already set up */ 43 /* Already set up */
44 return (void *)fdt; 44 return (void *)fdt;
45 45
46 if ((fw_arg0 == -2) && !fdt_check_header((void *)fw_arg1)) { 46 if ((fw_arg0 == -2) && !fdt_check_header((void *)fw_passed_dtb)) {
47 /* 47 /*
48 * We booted using the UHI boot protocol, so we have been 48 * We booted using the UHI boot protocol, so we have been
49 * provided with the appropriate device tree for the board. 49 * provided with the appropriate device tree for the board.
50 * Make use of it & search for any machine struct based upon 50 * Make use of it & search for any machine struct based upon
51 * the root compatible string. 51 * the root compatible string.
52 */ 52 */
53 fdt = (void *)fw_arg1; 53 fdt = (void *)fw_passed_dtb;
54 54
55 for_each_mips_machine(check_mach) { 55 for_each_mips_machine(check_mach) {
56 match = mips_machine_is_compatible(check_mach, fdt); 56 match = mips_machine_is_compatible(check_mach, fdt);
diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h
index 42ea1313626c..965f0793a5f9 100644
--- a/arch/mips/include/asm/mach-ip27/topology.h
+++ b/arch/mips/include/asm/mach-ip27/topology.h
@@ -7,18 +7,9 @@
7#include <asm/mmzone.h> 7#include <asm/mmzone.h>
8 8
9struct cpuinfo_ip27 { 9struct cpuinfo_ip27 {
10// cpuid_t p_cpuid; /* PROM assigned cpuid */
11 cnodeid_t p_nodeid; /* my node ID in compact-id-space */ 10 cnodeid_t p_nodeid; /* my node ID in compact-id-space */
12 nasid_t p_nasid; /* my node ID in numa-as-id-space */ 11 nasid_t p_nasid; /* my node ID in numa-as-id-space */
13 unsigned char p_slice; /* Physical position on node board */ 12 unsigned char p_slice; /* Physical position on node board */
14#if 0
15 unsigned long loops_per_sec;
16 unsigned long ipi_count;
17 unsigned long irq_attempt[NR_IRQS];
18 unsigned long smp_local_irq_count;
19 unsigned long prof_multiplier;
20 unsigned long prof_counter;
21#endif
22}; 13};
23 14
24extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS]; 15extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
@@ -30,7 +21,7 @@ extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
30struct pci_bus; 21struct pci_bus;
31extern int pcibus_to_node(struct pci_bus *); 22extern int pcibus_to_node(struct pci_bus *);
32 23
33#define cpumask_of_pcibus(bus) (cpu_online_mask) 24#define cpumask_of_pcibus(bus) (cpumask_of_node(pcibus_to_node(bus)))
34 25
35extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; 26extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
36 27
diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h
index 23574c27eb40..a92cd30b48c9 100644
--- a/arch/mips/include/asm/pci/bridge.h
+++ b/arch/mips/include/asm/pci/bridge.h
@@ -801,15 +801,13 @@ struct bridge_err_cmdword {
801#define PCI64_ATTR_RMF_SHFT 48 801#define PCI64_ATTR_RMF_SHFT 48
802 802
803struct bridge_controller { 803struct bridge_controller {
804 struct pci_controller pc;
805 struct resource mem;
806 struct resource io;
807 struct resource busn; 804 struct resource busn;
808 struct bridge_regs *base; 805 struct bridge_regs *base;
809 nasid_t nasid; 806 unsigned long baddr;
810 unsigned int widget_id; 807 unsigned long intr_addr;
811 u64 baddr; 808 struct irq_domain *domain;
812 unsigned int pci_int[8]; 809 unsigned int pci_int[8];
810 nasid_t nasid;
813}; 811};
814 812
815#define BRIDGE_CONTROLLER(bus) \ 813#define BRIDGE_CONTROLLER(bus) \
@@ -822,8 +820,4 @@ struct bridge_controller {
822#define bridge_clr(bc, reg, val) \ 820#define bridge_clr(bc, reg, val) \
823 __raw_writel(__raw_readl(&bc->base->reg) & ~(val), &bc->base->reg) 821 __raw_writel(__raw_readl(&bc->base->reg) & ~(val), &bc->base->reg)
824 822
825extern int request_bridge_irq(struct bridge_controller *bc, int pin);
826
827extern struct pci_ops bridge_pci_ops;
828
829#endif /* _ASM_PCI_BRIDGE_H */ 823#endif /* _ASM_PCI_BRIDGE_H */
diff --git a/arch/mips/include/asm/sn/irq_alloc.h b/arch/mips/include/asm/sn/irq_alloc.h
new file mode 100644
index 000000000000..09b89cecff56
--- /dev/null
+++ b/arch/mips/include/asm/sn/irq_alloc.h
@@ -0,0 +1,11 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __ASM_SN_IRQ_ALLOC_H
3#define __ASM_SN_IRQ_ALLOC_H
4
5struct irq_alloc_info {
6 void *ctrl;
7 nasid_t nasid;
8 int pin;
9};
10
11#endif /* __ASM_SN_IRQ_ALLOC_H */
diff --git a/arch/mips/include/asm/xtalk/xtalk.h b/arch/mips/include/asm/xtalk/xtalk.h
index 26d2ed1fa917..680e7efebbaf 100644
--- a/arch/mips/include/asm/xtalk/xtalk.h
+++ b/arch/mips/include/asm/xtalk/xtalk.h
@@ -47,15 +47,6 @@ typedef struct xtalk_piomap_s *xtalk_piomap_t;
47#define XIO_PORT(x) ((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT)) 47#define XIO_PORT(x) ((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT))
48#define XIO_PACK(p, o) ((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS)) 48#define XIO_PACK(p, o) ((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS))
49 49
50#ifdef CONFIG_PCI
51extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
52#else
53static inline int bridge_probe(nasid_t nasid, int widget, int masterwid)
54{
55 return 0;
56}
57#endif
58
59#endif /* !__ASSEMBLY__ */ 50#endif /* !__ASSEMBLY__ */
60 51
61#endif /* _ASM_XTALK_XTALK_H */ 52#endif /* _ASM_XTALK_XTALK_H */
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index d5e335e6846a..6126b77d5a62 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -1973,6 +1973,14 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
1973 panic("Unknown Ingenic Processor ID!"); 1973 panic("Unknown Ingenic Processor ID!");
1974 break; 1974 break;
1975 } 1975 }
1976
1977 /*
1978 * The config0 register in the Xburst CPUs with a processor ID of
1979 * PRID_COMP_INGENIC_D0 report themselves as MIPS32r2 compatible,
1980 * but they don't actually support this ISA.
1981 */
1982 if ((c->processor_id & PRID_COMP_MASK) == PRID_COMP_INGENIC_D0)
1983 c->isa_level &= ~MIPS_CPU_ISA_M32R2;
1976} 1984}
1977 1985
1978static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu) 1986static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index 413863508f6f..d67fb64e908c 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -64,17 +64,11 @@ struct mips_perf_event {
64 #define CNTR_EVEN 0x55555555 64 #define CNTR_EVEN 0x55555555
65 #define CNTR_ODD 0xaaaaaaaa 65 #define CNTR_ODD 0xaaaaaaaa
66 #define CNTR_ALL 0xffffffff 66 #define CNTR_ALL 0xffffffff
67#ifdef CONFIG_MIPS_MT_SMP
68 enum { 67 enum {
69 T = 0, 68 T = 0,
70 V = 1, 69 V = 1,
71 P = 2, 70 P = 2,
72 } range; 71 } range;
73#else
74 #define T
75 #define V
76 #define P
77#endif
78}; 72};
79 73
80static struct mips_perf_event raw_event; 74static struct mips_perf_event raw_event;
@@ -325,9 +319,7 @@ static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
325{ 319{
326 struct perf_event *event = container_of(evt, struct perf_event, hw); 320 struct perf_event *event = container_of(evt, struct perf_event, hw);
327 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); 321 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
328#ifdef CONFIG_MIPS_MT_SMP
329 unsigned int range = evt->event_base >> 24; 322 unsigned int range = evt->event_base >> 24;
330#endif /* CONFIG_MIPS_MT_SMP */
331 323
332 WARN_ON(idx < 0 || idx >= mipspmu.num_counters); 324 WARN_ON(idx < 0 || idx >= mipspmu.num_counters);
333 325
@@ -336,21 +328,15 @@ static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
336 /* Make sure interrupt enabled. */ 328 /* Make sure interrupt enabled. */
337 MIPS_PERFCTRL_IE; 329 MIPS_PERFCTRL_IE;
338 330
339#ifdef CONFIG_CPU_BMIPS5000 331 if (IS_ENABLED(CONFIG_CPU_BMIPS5000)) {
340 {
341 /* enable the counter for the calling thread */ 332 /* enable the counter for the calling thread */
342 cpuc->saved_ctrl[idx] |= 333 cpuc->saved_ctrl[idx] |=
343 (1 << (12 + vpe_id())) | BRCM_PERFCTRL_TC; 334 (1 << (12 + vpe_id())) | BRCM_PERFCTRL_TC;
344 } 335 } else if (IS_ENABLED(CONFIG_MIPS_MT_SMP) && range > V) {
345#else
346#ifdef CONFIG_MIPS_MT_SMP
347 if (range > V) {
348 /* The counter is processor wide. Set it up to count all TCs. */ 336 /* The counter is processor wide. Set it up to count all TCs. */
349 pr_debug("Enabling perf counter for all TCs\n"); 337 pr_debug("Enabling perf counter for all TCs\n");
350 cpuc->saved_ctrl[idx] |= M_TC_EN_ALL; 338 cpuc->saved_ctrl[idx] |= M_TC_EN_ALL;
351 } else 339 } else {
352#endif /* CONFIG_MIPS_MT_SMP */
353 {
354 unsigned int cpu, ctrl; 340 unsigned int cpu, ctrl;
355 341
356 /* 342 /*
@@ -365,7 +351,6 @@ static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
365 cpuc->saved_ctrl[idx] |= ctrl; 351 cpuc->saved_ctrl[idx] |= ctrl;
366 pr_debug("Enabling perf counter for CPU%d\n", cpu); 352 pr_debug("Enabling perf counter for CPU%d\n", cpu);
367 } 353 }
368#endif /* CONFIG_CPU_BMIPS5000 */
369 /* 354 /*
370 * We do not actually let the counter run. Leave it until start(). 355 * We do not actually let the counter run. Leave it until start().
371 */ 356 */
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index c4f976593061..d6de4cb2e31c 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o
26obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o 26obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
27obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o 27obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
28obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o 28obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
29obj-$(CONFIG_PCI_XTALK_BRIDGE) += pci-xtalk-bridge.o
29# 30#
30# These are still pretty much in the old state, watch, go blind. 31# These are still pretty much in the old state, watch, go blind.
31# 32#
@@ -39,7 +40,7 @@ obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o pci-malta.o
39obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o 40obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o
40obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o 41obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o
41obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o 42obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o
42obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o 43obj-$(CONFIG_SGI_IP27) += pci-ip27.o
43obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o 44obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o
44obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o 45obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
45obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o 46obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o
diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c
deleted file mode 100644
index df95b0da08f2..000000000000
--- a/arch/mips/pci/ops-bridge.c
+++ /dev/null
@@ -1,302 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1999, 2000, 04, 06 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 */
9#include <linux/pci.h>
10#include <asm/paccess.h>
11#include <asm/pci/bridge.h>
12#include <asm/sn/arch.h>
13#include <asm/sn/intr.h>
14#include <asm/sn/sn0/hub.h>
15
16/*
17 * Most of the IOC3 PCI config register aren't present
18 * we emulate what is needed for a normal PCI enumeration
19 */
20static u32 emulate_ioc3_cfg(int where, int size)
21{
22 if (size == 1 && where == 0x3d)
23 return 0x01;
24 else if (size == 2 && where == 0x3c)
25 return 0x0100;
26 else if (size == 4 && where == 0x3c)
27 return 0x00000100;
28
29 return 0;
30}
31
32/*
33 * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is
34 * not really documented, so right now I can't write code which uses it.
35 * Therefore we use type 0 accesses for now even though they won't work
36 * correctly for PCI-to-PCI bridges.
37 *
38 * The function is complicated by the ultimate brokenness of the IOC3 chip
39 * which is used in SGI systems. The IOC3 can only handle 32-bit PCI
40 * accesses and does only decode parts of it's address space.
41 */
42
43static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
44 int where, int size, u32 * value)
45{
46 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
47 struct bridge_regs *bridge = bc->base;
48 int slot = PCI_SLOT(devfn);
49 int fn = PCI_FUNC(devfn);
50 volatile void *addr;
51 u32 cf, shift, mask;
52 int res;
53
54 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
55 if (get_dbe(cf, (u32 *) addr))
56 return PCIBIOS_DEVICE_NOT_FOUND;
57
58 /*
59 * IOC3 is broken beyond belief ... Don't even give the
60 * generic PCI code a chance to look at it for real ...
61 */
62 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
63 goto is_ioc3;
64
65 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
66
67 if (size == 1)
68 res = get_dbe(*value, (u8 *) addr);
69 else if (size == 2)
70 res = get_dbe(*value, (u16 *) addr);
71 else
72 res = get_dbe(*value, (u32 *) addr);
73
74 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
75
76is_ioc3:
77
78 /*
79 * IOC3 special handling
80 */
81 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
82 *value = emulate_ioc3_cfg(where, size);
83 return PCIBIOS_SUCCESSFUL;
84 }
85
86 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
87
88 if (get_dbe(cf, (u32 *) addr))
89 return PCIBIOS_DEVICE_NOT_FOUND;
90
91 shift = ((where & 3) << 3);
92 mask = (0xffffffffU >> ((4 - size) << 3));
93 *value = (cf >> shift) & mask;
94
95 return PCIBIOS_SUCCESSFUL;
96}
97
98static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
99 int where, int size, u32 * value)
100{
101 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
102 struct bridge_regs *bridge = bc->base;
103 int busno = bus->number;
104 int slot = PCI_SLOT(devfn);
105 int fn = PCI_FUNC(devfn);
106 volatile void *addr;
107 u32 cf, shift, mask;
108 int res;
109
110 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
111 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
112 if (get_dbe(cf, (u32 *) addr))
113 return PCIBIOS_DEVICE_NOT_FOUND;
114
115 /*
116 * IOC3 is broken beyond belief ... Don't even give the
117 * generic PCI code a chance to look at it for real ...
118 */
119 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
120 goto is_ioc3;
121
122 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
123 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
124
125 if (size == 1)
126 res = get_dbe(*value, (u8 *) addr);
127 else if (size == 2)
128 res = get_dbe(*value, (u16 *) addr);
129 else
130 res = get_dbe(*value, (u32 *) addr);
131
132 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
133
134is_ioc3:
135
136 /*
137 * IOC3 special handling
138 */
139 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
140 *value = emulate_ioc3_cfg(where, size);
141 return PCIBIOS_SUCCESSFUL;
142 }
143
144 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
145 addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
146
147 if (get_dbe(cf, (u32 *) addr))
148 return PCIBIOS_DEVICE_NOT_FOUND;
149
150 shift = ((where & 3) << 3);
151 mask = (0xffffffffU >> ((4 - size) << 3));
152 *value = (cf >> shift) & mask;
153
154 return PCIBIOS_SUCCESSFUL;
155}
156
157static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
158 int where, int size, u32 * value)
159{
160 if (!pci_is_root_bus(bus))
161 return pci_conf1_read_config(bus, devfn, where, size, value);
162
163 return pci_conf0_read_config(bus, devfn, where, size, value);
164}
165
166static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
167 int where, int size, u32 value)
168{
169 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
170 struct bridge_regs *bridge = bc->base;
171 int slot = PCI_SLOT(devfn);
172 int fn = PCI_FUNC(devfn);
173 volatile void *addr;
174 u32 cf, shift, mask, smask;
175 int res;
176
177 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
178 if (get_dbe(cf, (u32 *) addr))
179 return PCIBIOS_DEVICE_NOT_FOUND;
180
181 /*
182 * IOC3 is broken beyond belief ... Don't even give the
183 * generic PCI code a chance to look at it for real ...
184 */
185 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
186 goto is_ioc3;
187
188 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
189
190 if (size == 1) {
191 res = put_dbe(value, (u8 *) addr);
192 } else if (size == 2) {
193 res = put_dbe(value, (u16 *) addr);
194 } else {
195 res = put_dbe(value, (u32 *) addr);
196 }
197
198 if (res)
199 return PCIBIOS_DEVICE_NOT_FOUND;
200
201 return PCIBIOS_SUCCESSFUL;
202
203is_ioc3:
204
205 /*
206 * IOC3 special handling
207 */
208 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
209 return PCIBIOS_SUCCESSFUL;
210
211 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
212
213 if (get_dbe(cf, (u32 *) addr))
214 return PCIBIOS_DEVICE_NOT_FOUND;
215
216 shift = ((where & 3) << 3);
217 mask = (0xffffffffU >> ((4 - size) << 3));
218 smask = mask << shift;
219
220 cf = (cf & ~smask) | ((value & mask) << shift);
221 if (put_dbe(cf, (u32 *) addr))
222 return PCIBIOS_DEVICE_NOT_FOUND;
223
224 return PCIBIOS_SUCCESSFUL;
225}
226
227static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
228 int where, int size, u32 value)
229{
230 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
231 struct bridge_regs *bridge = bc->base;
232 int slot = PCI_SLOT(devfn);
233 int fn = PCI_FUNC(devfn);
234 int busno = bus->number;
235 volatile void *addr;
236 u32 cf, shift, mask, smask;
237 int res;
238
239 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
240 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
241 if (get_dbe(cf, (u32 *) addr))
242 return PCIBIOS_DEVICE_NOT_FOUND;
243
244 /*
245 * IOC3 is broken beyond belief ... Don't even give the
246 * generic PCI code a chance to look at it for real ...
247 */
248 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
249 goto is_ioc3;
250
251 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
252
253 if (size == 1) {
254 res = put_dbe(value, (u8 *) addr);
255 } else if (size == 2) {
256 res = put_dbe(value, (u16 *) addr);
257 } else {
258 res = put_dbe(value, (u32 *) addr);
259 }
260
261 if (res)
262 return PCIBIOS_DEVICE_NOT_FOUND;
263
264 return PCIBIOS_SUCCESSFUL;
265
266is_ioc3:
267
268 /*
269 * IOC3 special handling
270 */
271 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
272 return PCIBIOS_SUCCESSFUL;
273
274 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
275
276 if (get_dbe(cf, (u32 *) addr))
277 return PCIBIOS_DEVICE_NOT_FOUND;
278
279 shift = ((where & 3) << 3);
280 mask = (0xffffffffU >> ((4 - size) << 3));
281 smask = mask << shift;
282
283 cf = (cf & ~smask) | ((value & mask) << shift);
284 if (put_dbe(cf, (u32 *) addr))
285 return PCIBIOS_DEVICE_NOT_FOUND;
286
287 return PCIBIOS_SUCCESSFUL;
288}
289
290static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
291 int where, int size, u32 value)
292{
293 if (!pci_is_root_bus(bus))
294 return pci_conf1_write_config(bus, devfn, where, size, value);
295
296 return pci_conf0_write_config(bus, devfn, where, size, value);
297}
298
299struct pci_ops bridge_pci_ops = {
300 .read = pci_read_config,
301 .write = pci_write_config,
302};
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
index 3c177b4d0609..441eb9383b20 100644
--- a/arch/mips/pci/pci-ip27.c
+++ b/arch/mips/pci/pci-ip27.c
@@ -7,162 +7,7 @@
7 * Copyright (C) 1999, 2000, 04 Ralf Baechle (ralf@linux-mips.org) 7 * Copyright (C) 1999, 2000, 04 Ralf Baechle (ralf@linux-mips.org)
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */ 9 */
10#include <linux/kernel.h>
11#include <linux/export.h>
12#include <linux/pci.h>
13#include <linux/smp.h>
14#include <linux/dma-direct.h>
15#include <asm/sn/arch.h>
16#include <asm/pci/bridge.h> 10#include <asm/pci/bridge.h>
17#include <asm/paccess.h>
18#include <asm/sn/intr.h>
19#include <asm/sn/sn0/hub.h>
20
21/*
22 * Max #PCI busses we can handle; ie, max #PCI bridges.
23 */
24#define MAX_PCI_BUSSES 40
25
26/*
27 * XXX: No kmalloc available when we do our crosstalk scan,
28 * we should try to move it later in the boot process.
29 */
30static struct bridge_controller bridges[MAX_PCI_BUSSES];
31
32extern struct pci_ops bridge_pci_ops;
33
34int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
35{
36 unsigned long offset = NODE_OFFSET(nasid);
37 struct bridge_controller *bc;
38 static int num_bridges = 0;
39 int slot;
40
41 pci_set_flags(PCI_PROBE_ONLY);
42
43 printk("a bridge\n");
44
45 /* XXX: kludge alert.. */
46 if (!num_bridges)
47 ioport_resource.end = ~0UL;
48
49 bc = &bridges[num_bridges];
50
51 bc->pc.pci_ops = &bridge_pci_ops;
52 bc->pc.mem_resource = &bc->mem;
53 bc->pc.io_resource = &bc->io;
54
55 bc->pc.index = num_bridges;
56
57 bc->mem.name = "Bridge PCI MEM";
58 bc->pc.mem_offset = offset;
59 bc->mem.start = 0;
60 bc->mem.end = ~0UL;
61 bc->mem.flags = IORESOURCE_MEM;
62
63 bc->io.name = "Bridge IO MEM";
64 bc->pc.io_offset = offset;
65 bc->io.start = 0UL;
66 bc->io.end = ~0UL;
67 bc->io.flags = IORESOURCE_IO;
68
69 bc->widget_id = widget_id;
70 bc->nasid = nasid;
71
72 bc->baddr = (u64)masterwid << 60 | PCI64_ATTR_BAR;
73
74 /*
75 * point to this bridge
76 */
77 bc->base = (struct bridge_regs *)RAW_NODE_SWIN_BASE(nasid, widget_id);
78
79 /*
80 * Clear all pending interrupts.
81 */
82 bridge_write(bc, b_int_rst_stat, BRIDGE_IRR_ALL_CLR);
83
84 /*
85 * Until otherwise set up, assume all interrupts are from slot 0
86 */
87 bridge_write(bc, b_int_device, 0x0);
88
89 /*
90 * swap pio's to pci mem and io space (big windows)
91 */
92 bridge_set(bc, b_wid_control, BRIDGE_CTRL_IO_SWAP |
93 BRIDGE_CTRL_MEM_SWAP);
94#ifdef CONFIG_PAGE_SIZE_4KB
95 bridge_clr(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
96#else /* 16kB or larger */
97 bridge_set(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
98#endif
99
100 /*
101 * Hmm... IRIX sets additional bits in the address which
102 * are documented as reserved in the bridge docs.
103 */
104 bridge_write(bc, b_wid_int_upper, 0x8000 | (masterwid << 16));
105 bridge_write(bc, b_wid_int_lower, 0x01800090); /* PI_INT_PEND_MOD off*/
106 bridge_write(bc, b_dir_map, (masterwid << 20)); /* DMA */
107 bridge_write(bc, b_int_enable, 0);
108
109 for (slot = 0; slot < 8; slot ++) {
110 bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR);
111 bc->pci_int[slot] = -1;
112 }
113 bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */
114
115 register_pci_controller(&bc->pc);
116
117 num_bridges++;
118
119 return 0;
120}
121
122/*
123 * All observed requests have pin == 1. We could have a global here, that
124 * gets incremented and returned every time - unfortunately, pci_map_irq
125 * may be called on the same device over and over, and need to return the
126 * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7].
127 *
128 * A given PCI device, in general, should be able to intr any of the cpus
129 * on any one of the hubs connected to its xbow.
130 */
131int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
132{
133 return 0;
134}
135
136static inline struct pci_dev *bridge_root_dev(struct pci_dev *dev)
137{
138 while (dev->bus->parent) {
139 /* Move up the chain of bridges. */
140 dev = dev->bus->self;
141 }
142
143 return dev;
144}
145
146/* Do platform specific device initialization at pci_enable_device() time */
147int pcibios_plat_dev_init(struct pci_dev *dev)
148{
149 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
150 struct pci_dev *rdev = bridge_root_dev(dev);
151 int slot = PCI_SLOT(rdev->devfn);
152 int irq;
153
154 irq = bc->pci_int[slot];
155 if (irq == -1) {
156 irq = request_bridge_irq(bc, slot);
157 if (irq < 0)
158 return irq;
159
160 bc->pci_int[slot] = irq;
161 }
162 dev->irq = irq;
163
164 return 0;
165}
166 11
167dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) 12dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
168{ 13{
@@ -177,29 +22,6 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
177 return dma_addr & ~(0xffUL << 56); 22 return dma_addr & ~(0xffUL << 56);
178} 23}
179 24
180/*
181 * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses
182 * to find the slot number in sense of the bridge device register.
183 * XXX This also means multiple devices might rely on conflicting bridge
184 * settings.
185 */
186
187static inline void pci_disable_swapping(struct pci_dev *dev)
188{
189 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
190 struct bridge_regs *bridge = bc->base;
191 int slot = PCI_SLOT(dev->devfn);
192
193 /* Turn off byte swapping */
194 bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
195 bridge->b_widget.w_tflush; /* Flush */
196}
197
198static void pci_fixup_ioc3(struct pci_dev *d)
199{
200 pci_disable_swapping(d);
201}
202
203#ifdef CONFIG_NUMA 25#ifdef CONFIG_NUMA
204int pcibus_to_node(struct pci_bus *bus) 26int pcibus_to_node(struct pci_bus *bus)
205{ 27{
@@ -209,6 +31,3 @@ int pcibus_to_node(struct pci_bus *bus)
209} 31}
210EXPORT_SYMBOL(pcibus_to_node); 32EXPORT_SYMBOL(pcibus_to_node);
211#endif /* CONFIG_NUMA */ 33#endif /* CONFIG_NUMA */
212
213DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
214 pci_fixup_ioc3);
diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
new file mode 100644
index 000000000000..bcf7f559789a
--- /dev/null
+++ b/arch/mips/pci/pci-xtalk-bridge.c
@@ -0,0 +1,610 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2003 Christoph Hellwig (hch@lst.de)
4 * Copyright (C) 1999, 2000, 04 Ralf Baechle (ralf@linux-mips.org)
5 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
6 */
7#include <linux/kernel.h>
8#include <linux/export.h>
9#include <linux/pci.h>
10#include <linux/smp.h>
11#include <linux/dma-direct.h>
12#include <linux/platform_device.h>
13#include <linux/platform_data/xtalk-bridge.h>
14
15#include <asm/pci/bridge.h>
16#include <asm/paccess.h>
17#include <asm/sn/irq_alloc.h>
18
19/*
20 * Most of the IOC3 PCI config register aren't present
21 * we emulate what is needed for a normal PCI enumeration
22 */
23static u32 emulate_ioc3_cfg(int where, int size)
24{
25 if (size == 1 && where == 0x3d)
26 return 0x01;
27 else if (size == 2 && where == 0x3c)
28 return 0x0100;
29 else if (size == 4 && where == 0x3c)
30 return 0x00000100;
31
32 return 0;
33}
34
35static void bridge_disable_swapping(struct pci_dev *dev)
36{
37 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
38 int slot = PCI_SLOT(dev->devfn);
39
40 /* Turn off byte swapping */
41 bridge_clr(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR);
42 bridge_read(bc, b_widget.w_tflush); /* Flush */
43}
44
45DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
46 bridge_disable_swapping);
47
48
49/*
50 * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is
51 * not really documented, so right now I can't write code which uses it.
52 * Therefore we use type 0 accesses for now even though they won't work
53 * correctly for PCI-to-PCI bridges.
54 *
55 * The function is complicated by the ultimate brokenness of the IOC3 chip
56 * which is used in SGI systems. The IOC3 can only handle 32-bit PCI
57 * accesses and does only decode parts of it's address space.
58 */
59static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
60 int where, int size, u32 *value)
61{
62 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
63 struct bridge_regs *bridge = bc->base;
64 int slot = PCI_SLOT(devfn);
65 int fn = PCI_FUNC(devfn);
66 void *addr;
67 u32 cf, shift, mask;
68 int res;
69
70 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
71 if (get_dbe(cf, (u32 *)addr))
72 return PCIBIOS_DEVICE_NOT_FOUND;
73
74 /*
75 * IOC3 is broken beyond belief ... Don't even give the
76 * generic PCI code a chance to look at it for real ...
77 */
78 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
79 goto is_ioc3;
80
81 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
82
83 if (size == 1)
84 res = get_dbe(*value, (u8 *)addr);
85 else if (size == 2)
86 res = get_dbe(*value, (u16 *)addr);
87 else
88 res = get_dbe(*value, (u32 *)addr);
89
90 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
91
92is_ioc3:
93
94 /*
95 * IOC3 special handling
96 */
97 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
98 *value = emulate_ioc3_cfg(where, size);
99 return PCIBIOS_SUCCESSFUL;
100 }
101
102 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
103 if (get_dbe(cf, (u32 *)addr))
104 return PCIBIOS_DEVICE_NOT_FOUND;
105
106 shift = ((where & 3) << 3);
107 mask = (0xffffffffU >> ((4 - size) << 3));
108 *value = (cf >> shift) & mask;
109
110 return PCIBIOS_SUCCESSFUL;
111}
112
113static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
114 int where, int size, u32 *value)
115{
116 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
117 struct bridge_regs *bridge = bc->base;
118 int busno = bus->number;
119 int slot = PCI_SLOT(devfn);
120 int fn = PCI_FUNC(devfn);
121 void *addr;
122 u32 cf, shift, mask;
123 int res;
124
125 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
126 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
127 if (get_dbe(cf, (u32 *)addr))
128 return PCIBIOS_DEVICE_NOT_FOUND;
129
130 /*
131 * IOC3 is broken beyond belief ... Don't even give the
132 * generic PCI code a chance to look at it for real ...
133 */
134 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
135 goto is_ioc3;
136
137 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
138
139 if (size == 1)
140 res = get_dbe(*value, (u8 *)addr);
141 else if (size == 2)
142 res = get_dbe(*value, (u16 *)addr);
143 else
144 res = get_dbe(*value, (u32 *)addr);
145
146 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
147
148is_ioc3:
149
150 /*
151 * IOC3 special handling
152 */
153 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
154 *value = emulate_ioc3_cfg(where, size);
155 return PCIBIOS_SUCCESSFUL;
156 }
157
158 addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
159 if (get_dbe(cf, (u32 *)addr))
160 return PCIBIOS_DEVICE_NOT_FOUND;
161
162 shift = ((where & 3) << 3);
163 mask = (0xffffffffU >> ((4 - size) << 3));
164 *value = (cf >> shift) & mask;
165
166 return PCIBIOS_SUCCESSFUL;
167}
168
169static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
170 int where, int size, u32 *value)
171{
172 if (!pci_is_root_bus(bus))
173 return pci_conf1_read_config(bus, devfn, where, size, value);
174
175 return pci_conf0_read_config(bus, devfn, where, size, value);
176}
177
178static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
179 int where, int size, u32 value)
180{
181 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
182 struct bridge_regs *bridge = bc->base;
183 int slot = PCI_SLOT(devfn);
184 int fn = PCI_FUNC(devfn);
185 void *addr;
186 u32 cf, shift, mask, smask;
187 int res;
188
189 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
190 if (get_dbe(cf, (u32 *)addr))
191 return PCIBIOS_DEVICE_NOT_FOUND;
192
193 /*
194 * IOC3 is broken beyond belief ... Don't even give the
195 * generic PCI code a chance to look at it for real ...
196 */
197 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
198 goto is_ioc3;
199
200 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
201
202 if (size == 1)
203 res = put_dbe(value, (u8 *)addr);
204 else if (size == 2)
205 res = put_dbe(value, (u16 *)addr);
206 else
207 res = put_dbe(value, (u32 *)addr);
208
209 if (res)
210 return PCIBIOS_DEVICE_NOT_FOUND;
211
212 return PCIBIOS_SUCCESSFUL;
213
214is_ioc3:
215
216 /*
217 * IOC3 special handling
218 */
219 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
220 return PCIBIOS_SUCCESSFUL;
221
222 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
223
224 if (get_dbe(cf, (u32 *)addr))
225 return PCIBIOS_DEVICE_NOT_FOUND;
226
227 shift = ((where & 3) << 3);
228 mask = (0xffffffffU >> ((4 - size) << 3));
229 smask = mask << shift;
230
231 cf = (cf & ~smask) | ((value & mask) << shift);
232 if (put_dbe(cf, (u32 *)addr))
233 return PCIBIOS_DEVICE_NOT_FOUND;
234
235 return PCIBIOS_SUCCESSFUL;
236}
237
238static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
239 int where, int size, u32 value)
240{
241 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
242 struct bridge_regs *bridge = bc->base;
243 int slot = PCI_SLOT(devfn);
244 int fn = PCI_FUNC(devfn);
245 int busno = bus->number;
246 void *addr;
247 u32 cf, shift, mask, smask;
248 int res;
249
250 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
251 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
252 if (get_dbe(cf, (u32 *)addr))
253 return PCIBIOS_DEVICE_NOT_FOUND;
254
255 /*
256 * IOC3 is broken beyond belief ... Don't even give the
257 * generic PCI code a chance to look at it for real ...
258 */
259 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
260 goto is_ioc3;
261
262 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
263
264 if (size == 1)
265 res = put_dbe(value, (u8 *)addr);
266 else if (size == 2)
267 res = put_dbe(value, (u16 *)addr);
268 else
269 res = put_dbe(value, (u32 *)addr);
270
271 if (res)
272 return PCIBIOS_DEVICE_NOT_FOUND;
273
274 return PCIBIOS_SUCCESSFUL;
275
276is_ioc3:
277
278 /*
279 * IOC3 special handling
280 */
281 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
282 return PCIBIOS_SUCCESSFUL;
283
284 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
285 if (get_dbe(cf, (u32 *)addr))
286 return PCIBIOS_DEVICE_NOT_FOUND;
287
288 shift = ((where & 3) << 3);
289 mask = (0xffffffffU >> ((4 - size) << 3));
290 smask = mask << shift;
291
292 cf = (cf & ~smask) | ((value & mask) << shift);
293 if (put_dbe(cf, (u32 *)addr))
294 return PCIBIOS_DEVICE_NOT_FOUND;
295
296 return PCIBIOS_SUCCESSFUL;
297}
298
299static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
300 int where, int size, u32 value)
301{
302 if (!pci_is_root_bus(bus))
303 return pci_conf1_write_config(bus, devfn, where, size, value);
304
305 return pci_conf0_write_config(bus, devfn, where, size, value);
306}
307
308static struct pci_ops bridge_pci_ops = {
309 .read = pci_read_config,
310 .write = pci_write_config,
311};
312
313struct bridge_irq_chip_data {
314 struct bridge_controller *bc;
315 nasid_t nasid;
316};
317
318static int bridge_set_affinity(struct irq_data *d, const struct cpumask *mask,
319 bool force)
320{
321#ifdef CONFIG_NUMA
322 struct bridge_irq_chip_data *data = d->chip_data;
323 int bit = d->parent_data->hwirq;
324 int pin = d->hwirq;
325 nasid_t nasid;
326 int ret, cpu;
327
328 ret = irq_chip_set_affinity_parent(d, mask, force);
329 if (ret >= 0) {
330 cpu = cpumask_first_and(mask, cpu_online_mask);
331 nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
332 bridge_write(data->bc, b_int_addr[pin].addr,
333 (((data->bc->intr_addr >> 30) & 0x30000) |
334 bit | (nasid << 8)));
335 bridge_read(data->bc, b_wid_tflush);
336 }
337 return ret;
338#else
339 return irq_chip_set_affinity_parent(d, mask, force);
340#endif
341}
342
343struct irq_chip bridge_irq_chip = {
344 .name = "BRIDGE",
345 .irq_mask = irq_chip_mask_parent,
346 .irq_unmask = irq_chip_unmask_parent,
347 .irq_set_affinity = bridge_set_affinity
348};
349
350static int bridge_domain_alloc(struct irq_domain *domain, unsigned int virq,
351 unsigned int nr_irqs, void *arg)
352{
353 struct bridge_irq_chip_data *data;
354 struct irq_alloc_info *info = arg;
355 int ret;
356
357 if (nr_irqs > 1 || !info)
358 return -EINVAL;
359
360 data = kzalloc(sizeof(*data), GFP_KERNEL);
361 if (!data)
362 return -ENOMEM;
363
364 ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
365 if (ret >= 0) {
366 data->bc = info->ctrl;
367 data->nasid = info->nasid;
368 irq_domain_set_info(domain, virq, info->pin, &bridge_irq_chip,
369 data, handle_level_irq, NULL, NULL);
370 } else {
371 kfree(data);
372 }
373
374 return ret;
375}
376
377static void bridge_domain_free(struct irq_domain *domain, unsigned int virq,
378 unsigned int nr_irqs)
379{
380 struct irq_data *irqd = irq_domain_get_irq_data(domain, virq);
381
382 if (nr_irqs)
383 return;
384
385 kfree(irqd->chip_data);
386 irq_domain_free_irqs_top(domain, virq, nr_irqs);
387}
388
389static int bridge_domain_activate(struct irq_domain *domain,
390 struct irq_data *irqd, bool reserve)
391{
392 struct bridge_irq_chip_data *data = irqd->chip_data;
393 struct bridge_controller *bc = data->bc;
394 int bit = irqd->parent_data->hwirq;
395 int pin = irqd->hwirq;
396 u32 device;
397
398 bridge_write(bc, b_int_addr[pin].addr,
399 (((bc->intr_addr >> 30) & 0x30000) |
400 bit | (data->nasid << 8)));
401 bridge_set(bc, b_int_enable, (1 << pin));
402 bridge_set(bc, b_int_enable, 0x7ffffe00); /* more stuff in int_enable */
403
404 /*
405 * Enable sending of an interrupt clear packt to the hub on a high to
406 * low transition of the interrupt pin.
407 *
408 * IRIX sets additional bits in the address which are documented as
409 * reserved in the bridge docs.
410 */
411 bridge_set(bc, b_int_mode, (1UL << pin));
412
413 /*
414 * We assume the bridge to have a 1:1 mapping between devices
415 * (slots) and intr pins.
416 */
417 device = bridge_read(bc, b_int_device);
418 device &= ~(7 << (pin*3));
419 device |= (pin << (pin*3));
420 bridge_write(bc, b_int_device, device);
421
422 bridge_read(bc, b_wid_tflush);
423 return 0;
424}
425
426static void bridge_domain_deactivate(struct irq_domain *domain,
427 struct irq_data *irqd)
428{
429 struct bridge_irq_chip_data *data = irqd->chip_data;
430
431 bridge_clr(data->bc, b_int_enable, (1 << irqd->hwirq));
432 bridge_read(data->bc, b_wid_tflush);
433}
434
435static const struct irq_domain_ops bridge_domain_ops = {
436 .alloc = bridge_domain_alloc,
437 .free = bridge_domain_free,
438 .activate = bridge_domain_activate,
439 .deactivate = bridge_domain_deactivate
440};
441
442/*
443 * All observed requests have pin == 1. We could have a global here, that
444 * gets incremented and returned every time - unfortunately, pci_map_irq
445 * may be called on the same device over and over, and need to return the
446 * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7].
447 *
448 * A given PCI device, in general, should be able to intr any of the cpus
449 * on any one of the hubs connected to its xbow.
450 */
451static int bridge_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
452{
453 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
454 struct irq_alloc_info info;
455 int irq;
456
457 irq = bc->pci_int[slot];
458 if (irq == -1) {
459 info.ctrl = bc;
460 info.nasid = bc->nasid;
461 info.pin = slot;
462
463 irq = irq_domain_alloc_irqs(bc->domain, 1, bc->nasid, &info);
464 if (irq < 0)
465 return irq;
466
467 bc->pci_int[slot] = irq;
468 }
469 return irq;
470}
471
472static int bridge_probe(struct platform_device *pdev)
473{
474 struct xtalk_bridge_platform_data *bd = dev_get_platdata(&pdev->dev);
475 struct device *dev = &pdev->dev;
476 struct bridge_controller *bc;
477 struct pci_host_bridge *host;
478 struct irq_domain *domain, *parent;
479 struct fwnode_handle *fn;
480 int slot;
481 int err;
482
483 parent = irq_get_default_host();
484 if (!parent)
485 return -ENODEV;
486 fn = irq_domain_alloc_named_fwnode("BRIDGE");
487 if (!fn)
488 return -ENOMEM;
489 domain = irq_domain_create_hierarchy(parent, 0, 8, fn,
490 &bridge_domain_ops, NULL);
491 irq_domain_free_fwnode(fn);
492 if (!domain)
493 return -ENOMEM;
494
495 pci_set_flags(PCI_PROBE_ONLY);
496
497 host = devm_pci_alloc_host_bridge(dev, sizeof(*bc));
498 if (!host) {
499 err = -ENOMEM;
500 goto err_remove_domain;
501 }
502
503 bc = pci_host_bridge_priv(host);
504
505 bc->busn.name = "Bridge PCI busn";
506 bc->busn.start = 0;
507 bc->busn.end = 0xff;
508 bc->busn.flags = IORESOURCE_BUS;
509
510 bc->domain = domain;
511
512 pci_add_resource_offset(&host->windows, &bd->mem, bd->mem_offset);
513 pci_add_resource_offset(&host->windows, &bd->io, bd->io_offset);
514 pci_add_resource(&host->windows, &bc->busn);
515
516 err = devm_request_pci_bus_resources(dev, &host->windows);
517 if (err < 0)
518 goto err_free_resource;
519
520 bc->nasid = bd->nasid;
521
522 bc->baddr = (u64)bd->masterwid << 60 | PCI64_ATTR_BAR;
523 bc->base = (struct bridge_regs *)bd->bridge_addr;
524 bc->intr_addr = bd->intr_addr;
525
526 /*
527 * Clear all pending interrupts.
528 */
529 bridge_write(bc, b_int_rst_stat, BRIDGE_IRR_ALL_CLR);
530
531 /*
532 * Until otherwise set up, assume all interrupts are from slot 0
533 */
534 bridge_write(bc, b_int_device, 0x0);
535
536 /*
537 * disable swapping for big windows
538 */
539 bridge_clr(bc, b_wid_control,
540 BRIDGE_CTRL_IO_SWAP | BRIDGE_CTRL_MEM_SWAP);
541#ifdef CONFIG_PAGE_SIZE_4KB
542 bridge_clr(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
543#else /* 16kB or larger */
544 bridge_set(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
545#endif
546
547 /*
548 * Hmm... IRIX sets additional bits in the address which
549 * are documented as reserved in the bridge docs.
550 */
551 bridge_write(bc, b_wid_int_upper,
552 ((bc->intr_addr >> 32) & 0xffff) | (bd->masterwid << 16));
553 bridge_write(bc, b_wid_int_lower, bc->intr_addr & 0xffffffff);
554 bridge_write(bc, b_dir_map, (bd->masterwid << 20)); /* DMA */
555 bridge_write(bc, b_int_enable, 0);
556
557 for (slot = 0; slot < 8; slot++) {
558 bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR);
559 bc->pci_int[slot] = -1;
560 }
561 bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */
562
563 host->dev.parent = dev;
564 host->sysdata = bc;
565 host->busnr = 0;
566 host->ops = &bridge_pci_ops;
567 host->map_irq = bridge_map_irq;
568 host->swizzle_irq = pci_common_swizzle;
569
570 err = pci_scan_root_bus_bridge(host);
571 if (err < 0)
572 goto err_free_resource;
573
574 pci_bus_claim_resources(host->bus);
575 pci_bus_add_devices(host->bus);
576
577 platform_set_drvdata(pdev, host->bus);
578
579 return 0;
580
581err_free_resource:
582 pci_free_resource_list(&host->windows);
583err_remove_domain:
584 irq_domain_remove(domain);
585 return err;
586}
587
588static int bridge_remove(struct platform_device *pdev)
589{
590 struct pci_bus *bus = platform_get_drvdata(pdev);
591 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
592
593 irq_domain_remove(bc->domain);
594 pci_lock_rescan_remove();
595 pci_stop_root_bus(bus);
596 pci_remove_root_bus(bus);
597 pci_unlock_rescan_remove();
598
599 return 0;
600}
601
602static struct platform_driver bridge_driver = {
603 .probe = bridge_probe,
604 .remove = bridge_remove,
605 .driver = {
606 .name = "xtalk-bridge",
607 }
608};
609
610builtin_platform_driver(bridge_driver);
diff --git a/arch/mips/pnx833x/Platform b/arch/mips/pnx833x/Platform
index 794526caab12..6b1a847d593f 100644
--- a/arch/mips/pnx833x/Platform
+++ b/arch/mips/pnx833x/Platform
@@ -1,5 +1,5 @@
1# NXP STB225 1# NXP STB225
2platform-$(CONFIG_SOC_PNX833X) += pnx833x/ 2platform-$(CONFIG_SOC_PNX833X) += pnx833x/
3cflags-$(CONFIG_SOC_PNX833X) += -Iarch/mips/include/asm/mach-pnx833x 3cflags-$(CONFIG_SOC_PNX833X) += -I $(srctree)/arch/mips/include/asm/mach-pnx833x
4load-$(CONFIG_NXP_STB220) += 0xffffffff80001000 4load-$(CONFIG_NXP_STB220) += 0xffffffff80001000
5load-$(CONFIG_NXP_STB225) += 0xffffffff80001000 5load-$(CONFIG_NXP_STB225) += 0xffffffff80001000
diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c
index 37ad26716579..0b2002e02a47 100644
--- a/arch/mips/sgi-ip22/ip22-platform.c
+++ b/arch/mips/sgi-ip22/ip22-platform.c
@@ -3,6 +3,7 @@
3#include <linux/if_ether.h> 3#include <linux/if_ether.h>
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/platform_device.h> 5#include <linux/platform_device.h>
6#include <linux/dma-mapping.h>
6 7
7#include <asm/paccess.h> 8#include <asm/paccess.h>
8#include <asm/sgi/ip22.h> 9#include <asm/sgi/ip22.h>
@@ -25,6 +26,8 @@ static struct sgiwd93_platform_data sgiwd93_0_pd = {
25 .irq = SGI_WD93_0_IRQ, 26 .irq = SGI_WD93_0_IRQ,
26}; 27};
27 28
29static u64 sgiwd93_0_dma_mask = DMA_BIT_MASK(32);
30
28static struct platform_device sgiwd93_0_device = { 31static struct platform_device sgiwd93_0_device = {
29 .name = "sgiwd93", 32 .name = "sgiwd93",
30 .id = 0, 33 .id = 0,
@@ -32,6 +35,8 @@ static struct platform_device sgiwd93_0_device = {
32 .resource = sgiwd93_0_resources, 35 .resource = sgiwd93_0_resources,
33 .dev = { 36 .dev = {
34 .platform_data = &sgiwd93_0_pd, 37 .platform_data = &sgiwd93_0_pd,
38 .dma_mask = &sgiwd93_0_dma_mask,
39 .coherent_dma_mask = DMA_BIT_MASK(32),
35 }, 40 },
36}; 41};
37 42
@@ -49,6 +54,8 @@ static struct sgiwd93_platform_data sgiwd93_1_pd = {
49 .irq = SGI_WD93_1_IRQ, 54 .irq = SGI_WD93_1_IRQ,
50}; 55};
51 56
57static u64 sgiwd93_1_dma_mask = DMA_BIT_MASK(32);
58
52static struct platform_device sgiwd93_1_device = { 59static struct platform_device sgiwd93_1_device = {
53 .name = "sgiwd93", 60 .name = "sgiwd93",
54 .id = 1, 61 .id = 1,
@@ -56,6 +63,8 @@ static struct platform_device sgiwd93_1_device = {
56 .resource = sgiwd93_1_resources, 63 .resource = sgiwd93_1_resources,
57 .dev = { 64 .dev = {
58 .platform_data = &sgiwd93_1_pd, 65 .platform_data = &sgiwd93_1_pd,
66 .dma_mask = &sgiwd93_1_dma_mask,
67 .coherent_dma_mask = DMA_BIT_MASK(32),
59 }, 68 },
60}; 69};
61 70
@@ -96,6 +105,8 @@ static struct resource sgiseeq_0_resources[] = {
96 105
97static struct sgiseeq_platform_data eth0_pd; 106static struct sgiseeq_platform_data eth0_pd;
98 107
108static u64 sgiseeq_dma_mask = DMA_BIT_MASK(32);
109
99static struct platform_device eth0_device = { 110static struct platform_device eth0_device = {
100 .name = "sgiseeq", 111 .name = "sgiseeq",
101 .id = 0, 112 .id = 0,
@@ -103,6 +114,8 @@ static struct platform_device eth0_device = {
103 .resource = sgiseeq_0_resources, 114 .resource = sgiseeq_0_resources,
104 .dev = { 115 .dev = {
105 .platform_data = &eth0_pd, 116 .platform_data = &eth0_pd,
117 .dma_mask = &sgiseeq_dma_mask,
118 .coherent_dma_mask = DMA_BIT_MASK(32),
106 }, 119 },
107}; 120};
108 121
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index 6074efeff894..066b33f50bcc 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -184,5 +184,7 @@ void __init plat_mem_setup(void)
184 184
185 ioc3_eth_init(); 185 ioc3_eth_init();
186 186
187 ioport_resource.start = 0;
188 ioport_resource.end = ~0UL;
187 set_io_port_base(IO_BASE); 189 set_io_port_base(IO_BASE);
188} 190}
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index a32f843cdbe0..37be04975831 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -12,22 +12,20 @@
12#include <linux/ioport.h> 12#include <linux/ioport.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/bitops.h> 14#include <linux/bitops.h>
15#include <linux/sched.h>
15 16
16#include <asm/io.h> 17#include <asm/io.h>
17#include <asm/irq_cpu.h> 18#include <asm/irq_cpu.h>
18#include <asm/pci/bridge.h>
19#include <asm/sn/addrs.h> 19#include <asm/sn/addrs.h>
20#include <asm/sn/agent.h> 20#include <asm/sn/agent.h>
21#include <asm/sn/arch.h> 21#include <asm/sn/arch.h>
22#include <asm/sn/hub.h> 22#include <asm/sn/hub.h>
23#include <asm/sn/intr.h> 23#include <asm/sn/intr.h>
24#include <asm/sn/irq_alloc.h>
24 25
25struct hub_irq_data { 26struct hub_irq_data {
26 struct bridge_controller *bc;
27 u64 *irq_mask[2]; 27 u64 *irq_mask[2];
28 cpuid_t cpu; 28 cpuid_t cpu;
29 int bit;
30 int pin;
31}; 29};
32 30
33static DECLARE_BITMAP(hub_irq_map, IP27_HUB_IRQ_COUNT); 31static DECLARE_BITMAP(hub_irq_map, IP27_HUB_IRQ_COUNT);
@@ -54,7 +52,7 @@ static void enable_hub_irq(struct irq_data *d)
54 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); 52 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
55 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu); 53 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu);
56 54
57 set_bit(hd->bit, mask); 55 set_bit(d->hwirq, mask);
58 __raw_writeq(mask[0], hd->irq_mask[0]); 56 __raw_writeq(mask[0], hd->irq_mask[0]);
59 __raw_writeq(mask[1], hd->irq_mask[1]); 57 __raw_writeq(mask[1], hd->irq_mask[1]);
60} 58}
@@ -64,71 +62,11 @@ static void disable_hub_irq(struct irq_data *d)
64 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); 62 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
65 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu); 63 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu);
66 64
67 clear_bit(hd->bit, mask); 65 clear_bit(d->hwirq, mask);
68 __raw_writeq(mask[0], hd->irq_mask[0]); 66 __raw_writeq(mask[0], hd->irq_mask[0]);
69 __raw_writeq(mask[1], hd->irq_mask[1]); 67 __raw_writeq(mask[1], hd->irq_mask[1]);
70} 68}
71 69
72static unsigned int startup_bridge_irq(struct irq_data *d)
73{
74 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
75 struct bridge_controller *bc;
76 nasid_t nasid;
77 u32 device;
78 int pin;
79
80 if (!hd)
81 return -EINVAL;
82
83 pin = hd->pin;
84 bc = hd->bc;
85
86 nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(hd->cpu));
87 bridge_write(bc, b_int_addr[pin].addr,
88 (0x20000 | hd->bit | (nasid << 8)));
89 bridge_set(bc, b_int_enable, (1 << pin));
90 bridge_set(bc, b_int_enable, 0x7ffffe00); /* more stuff in int_enable */
91
92 /*
93 * Enable sending of an interrupt clear packt to the hub on a high to
94 * low transition of the interrupt pin.
95 *
96 * IRIX sets additional bits in the address which are documented as
97 * reserved in the bridge docs.
98 */
99 bridge_set(bc, b_int_mode, (1UL << pin));
100
101 /*
102 * We assume the bridge to have a 1:1 mapping between devices
103 * (slots) and intr pins.
104 */
105 device = bridge_read(bc, b_int_device);
106 device &= ~(7 << (pin*3));
107 device |= (pin << (pin*3));
108 bridge_write(bc, b_int_device, device);
109
110 bridge_read(bc, b_wid_tflush);
111
112 enable_hub_irq(d);
113
114 return 0; /* Never anything pending. */
115}
116
117static void shutdown_bridge_irq(struct irq_data *d)
118{
119 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
120 struct bridge_controller *bc;
121
122 if (!hd)
123 return;
124
125 disable_hub_irq(d);
126
127 bc = hd->bc;
128 bridge_clr(bc, b_int_enable, (1 << hd->pin));
129 bridge_read(bc, b_wid_tflush);
130}
131
132static void setup_hub_mask(struct hub_irq_data *hd, const struct cpumask *mask) 70static void setup_hub_mask(struct hub_irq_data *hd, const struct cpumask *mask)
133{ 71{
134 nasid_t nasid; 72 nasid_t nasid;
@@ -144,9 +82,6 @@ static void setup_hub_mask(struct hub_irq_data *hd, const struct cpumask *mask)
144 hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_B); 82 hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_B);
145 hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_B); 83 hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_B);
146 } 84 }
147
148 /* Make sure it's not already pending when we connect it. */
149 REMOTE_HUB_CLR_INTR(nasid, hd->bit);
150} 85}
151 86
152static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask, 87static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask,
@@ -163,7 +98,7 @@ static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask,
163 setup_hub_mask(hd, mask); 98 setup_hub_mask(hd, mask);
164 99
165 if (irqd_is_started(d)) 100 if (irqd_is_started(d))
166 startup_bridge_irq(d); 101 enable_hub_irq(d);
167 102
168 irq_data_update_effective_affinity(d, cpumask_of(hd->cpu)); 103 irq_data_update_effective_affinity(d, cpumask_of(hd->cpu));
169 104
@@ -172,20 +107,22 @@ static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask,
172 107
173static struct irq_chip hub_irq_type = { 108static struct irq_chip hub_irq_type = {
174 .name = "HUB", 109 .name = "HUB",
175 .irq_startup = startup_bridge_irq,
176 .irq_shutdown = shutdown_bridge_irq,
177 .irq_mask = disable_hub_irq, 110 .irq_mask = disable_hub_irq,
178 .irq_unmask = enable_hub_irq, 111 .irq_unmask = enable_hub_irq,
179 .irq_set_affinity = set_affinity_hub_irq, 112 .irq_set_affinity = set_affinity_hub_irq,
180}; 113};
181 114
182int request_bridge_irq(struct bridge_controller *bc, int pin) 115static int hub_domain_alloc(struct irq_domain *domain, unsigned int virq,
116 unsigned int nr_irqs, void *arg)
183{ 117{
118 struct irq_alloc_info *info = arg;
184 struct hub_irq_data *hd; 119 struct hub_irq_data *hd;
185 struct hub_data *hub; 120 struct hub_data *hub;
186 struct irq_desc *desc; 121 struct irq_desc *desc;
187 int swlevel; 122 int swlevel;
188 int irq; 123
124 if (nr_irqs > 1 || !info)
125 return -EINVAL;
189 126
190 hd = kzalloc(sizeof(*hd), GFP_KERNEL); 127 hd = kzalloc(sizeof(*hd), GFP_KERNEL);
191 if (!hd) 128 if (!hd)
@@ -196,46 +133,41 @@ int request_bridge_irq(struct bridge_controller *bc, int pin)
196 kfree(hd); 133 kfree(hd);
197 return -EAGAIN; 134 return -EAGAIN;
198 } 135 }
199 irq = swlevel + IP27_HUB_IRQ_BASE; 136 irq_domain_set_info(domain, virq, swlevel, &hub_irq_type, hd,
200 137 handle_level_irq, NULL, NULL);
201 hd->bc = bc;
202 hd->bit = swlevel;
203 hd->pin = pin;
204 irq_set_chip_data(irq, hd);
205 138
206 /* use CPU connected to nearest hub */ 139 /* use CPU connected to nearest hub */
207 hub = hub_data(NASID_TO_COMPACT_NODEID(bc->nasid)); 140 hub = hub_data(NASID_TO_COMPACT_NODEID(info->nasid));
208 setup_hub_mask(hd, &hub->h_cpus); 141 setup_hub_mask(hd, &hub->h_cpus);
209 142
210 desc = irq_to_desc(irq); 143 /* Make sure it's not already pending when we connect it. */
211 desc->irq_common_data.node = bc->nasid; 144 REMOTE_HUB_CLR_INTR(info->nasid, swlevel);
145
146 desc = irq_to_desc(virq);
147 desc->irq_common_data.node = info->nasid;
212 cpumask_copy(desc->irq_common_data.affinity, &hub->h_cpus); 148 cpumask_copy(desc->irq_common_data.affinity, &hub->h_cpus);
213 149
214 return irq; 150 return 0;
215} 151}
216 152
217void ip27_hub_irq_init(void) 153static void hub_domain_free(struct irq_domain *domain,
154 unsigned int virq, unsigned int nr_irqs)
218{ 155{
219 int i; 156 struct irq_data *irqd;
220 157
221 for (i = IP27_HUB_IRQ_BASE; 158 if (nr_irqs > 1)
222 i < (IP27_HUB_IRQ_BASE + IP27_HUB_IRQ_COUNT); i++) 159 return;
223 irq_set_chip_and_handler(i, &hub_irq_type, handle_level_irq);
224
225 /*
226 * Some interrupts are reserved by hardware or by software convention.
227 * Mark these as reserved right away so they won't be used accidentally
228 * later.
229 */
230 for (i = 0; i <= BASE_PCI_IRQ; i++)
231 set_bit(i, hub_irq_map);
232
233 set_bit(IP_PEND0_6_63, hub_irq_map);
234 160
235 for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) 161 irqd = irq_domain_get_irq_data(domain, virq);
236 set_bit(i, hub_irq_map); 162 if (irqd && irqd->chip_data)
163 kfree(irqd->chip_data);
237} 164}
238 165
166static const struct irq_domain_ops hub_domain_ops = {
167 .alloc = hub_domain_alloc,
168 .free = hub_domain_free,
169};
170
239/* 171/*
240 * This code is unnecessarily complex, because we do 172 * This code is unnecessarily complex, because we do
241 * intr enabling. Basically, once we grab the set of intrs we need 173 * intr enabling. Basically, once we grab the set of intrs we need
@@ -252,7 +184,9 @@ static void ip27_do_irq_mask0(struct irq_desc *desc)
252{ 184{
253 cpuid_t cpu = smp_processor_id(); 185 cpuid_t cpu = smp_processor_id();
254 unsigned long *mask = per_cpu(irq_enable_mask, cpu); 186 unsigned long *mask = per_cpu(irq_enable_mask, cpu);
187 struct irq_domain *domain;
255 u64 pend0; 188 u64 pend0;
189 int irq;
256 190
257 /* copied from Irix intpend0() */ 191 /* copied from Irix intpend0() */
258 pend0 = LOCAL_HUB_L(PI_INT_PEND0); 192 pend0 = LOCAL_HUB_L(PI_INT_PEND0);
@@ -276,7 +210,14 @@ static void ip27_do_irq_mask0(struct irq_desc *desc)
276 generic_smp_call_function_interrupt(); 210 generic_smp_call_function_interrupt();
277 } else 211 } else
278#endif 212#endif
279 generic_handle_irq(__ffs(pend0) + IP27_HUB_IRQ_BASE); 213 {
214 domain = irq_desc_get_handler_data(desc);
215 irq = irq_linear_revmap(domain, __ffs(pend0));
216 if (irq)
217 generic_handle_irq(irq);
218 else
219 spurious_interrupt();
220 }
280 221
281 LOCAL_HUB_L(PI_INT_PEND0); 222 LOCAL_HUB_L(PI_INT_PEND0);
282} 223}
@@ -285,7 +226,9 @@ static void ip27_do_irq_mask1(struct irq_desc *desc)
285{ 226{
286 cpuid_t cpu = smp_processor_id(); 227 cpuid_t cpu = smp_processor_id();
287 unsigned long *mask = per_cpu(irq_enable_mask, cpu); 228 unsigned long *mask = per_cpu(irq_enable_mask, cpu);
229 struct irq_domain *domain;
288 u64 pend1; 230 u64 pend1;
231 int irq;
289 232
290 /* copied from Irix intpend0() */ 233 /* copied from Irix intpend0() */
291 pend1 = LOCAL_HUB_L(PI_INT_PEND1); 234 pend1 = LOCAL_HUB_L(PI_INT_PEND1);
@@ -294,7 +237,12 @@ static void ip27_do_irq_mask1(struct irq_desc *desc)
294 if (!pend1) 237 if (!pend1)
295 return; 238 return;
296 239
297 generic_handle_irq(__ffs(pend1) + IP27_HUB_IRQ_BASE + 64); 240 domain = irq_desc_get_handler_data(desc);
241 irq = irq_linear_revmap(domain, __ffs(pend1) + 64);
242 if (irq)
243 generic_handle_irq(irq);
244 else
245 spurious_interrupt();
298 246
299 LOCAL_HUB_L(PI_INT_PEND1); 247 LOCAL_HUB_L(PI_INT_PEND1);
300} 248}
@@ -325,11 +273,41 @@ void install_ipi(void)
325 273
326void __init arch_init_irq(void) 274void __init arch_init_irq(void)
327{ 275{
276 struct irq_domain *domain;
277 struct fwnode_handle *fn;
278 int i;
279
328 mips_cpu_irq_init(); 280 mips_cpu_irq_init();
329 ip27_hub_irq_init(); 281
282 /*
283 * Some interrupts are reserved by hardware or by software convention.
284 * Mark these as reserved right away so they won't be used accidentally
285 * later.
286 */
287 for (i = 0; i <= BASE_PCI_IRQ; i++)
288 set_bit(i, hub_irq_map);
289
290 set_bit(IP_PEND0_6_63, hub_irq_map);
291
292 for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++)
293 set_bit(i, hub_irq_map);
294
295 fn = irq_domain_alloc_named_fwnode("HUB");
296 WARN_ON(fn == NULL);
297 if (!fn)
298 return;
299 domain = irq_domain_create_linear(fn, IP27_HUB_IRQ_COUNT,
300 &hub_domain_ops, NULL);
301 WARN_ON(domain == NULL);
302 if (!domain)
303 return;
304
305 irq_set_default_host(domain);
330 306
331 irq_set_percpu_devid(IP27_HUB_PEND0_IRQ); 307 irq_set_percpu_devid(IP27_HUB_PEND0_IRQ);
332 irq_set_chained_handler(IP27_HUB_PEND0_IRQ, ip27_do_irq_mask0); 308 irq_set_chained_handler_and_data(IP27_HUB_PEND0_IRQ, ip27_do_irq_mask0,
309 domain);
333 irq_set_percpu_devid(IP27_HUB_PEND1_IRQ); 310 irq_set_percpu_devid(IP27_HUB_PEND1_IRQ);
334 irq_set_chained_handler(IP27_HUB_PEND1_IRQ, ip27_do_irq_mask1); 311 irq_set_chained_handler_and_data(IP27_HUB_PEND1_IRQ, ip27_do_irq_mask1,
312 domain);
335} 313}
diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c
index ce06aaa115ae..bd5cb855c6e5 100644
--- a/arch/mips/sgi-ip27/ip27-xtalk.c
+++ b/arch/mips/sgi-ip27/ip27-xtalk.c
@@ -9,6 +9,9 @@
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/smp.h> 11#include <linux/smp.h>
12#include <linux/platform_device.h>
13#include <linux/platform_data/xtalk-bridge.h>
14#include <asm/sn/addrs.h>
12#include <asm/sn/types.h> 15#include <asm/sn/types.h>
13#include <asm/sn/klconfig.h> 16#include <asm/sn/klconfig.h>
14#include <asm/sn/hub.h> 17#include <asm/sn/hub.h>
@@ -20,7 +23,48 @@
20#define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbow in Xbridge */ 23#define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbow in Xbridge */
21#define BASE_XBOW_PORT 8 /* Lowest external port */ 24#define BASE_XBOW_PORT 8 /* Lowest external port */
22 25
23extern int bridge_probe(nasid_t nasid, int widget, int masterwid); 26static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
27{
28 struct xtalk_bridge_platform_data *bd;
29 struct platform_device *pdev;
30 unsigned long offset;
31
32 bd = kzalloc(sizeof(*bd), GFP_KERNEL);
33 if (!bd)
34 goto no_mem;
35 pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
36 if (!pdev) {
37 kfree(bd);
38 goto no_mem;
39 }
40
41 offset = NODE_OFFSET(nasid);
42
43 bd->bridge_addr = RAW_NODE_SWIN_BASE(nasid, widget);
44 bd->intr_addr = BIT_ULL(47) + 0x01800000 + PI_INT_PEND_MOD;
45 bd->nasid = nasid;
46 bd->masterwid = masterwid;
47
48 bd->mem.name = "Bridge PCI MEM";
49 bd->mem.start = offset + (widget << SWIN_SIZE_BITS);
50 bd->mem.end = bd->mem.start + SWIN_SIZE - 1;
51 bd->mem.flags = IORESOURCE_MEM;
52 bd->mem_offset = offset;
53
54 bd->io.name = "Bridge PCI IO";
55 bd->io.start = offset + (widget << SWIN_SIZE_BITS);
56 bd->io.end = bd->io.start + SWIN_SIZE - 1;
57 bd->io.flags = IORESOURCE_IO;
58 bd->io_offset = offset;
59
60 platform_device_add_data(pdev, bd, sizeof(*bd));
61 platform_device_add(pdev);
62 pr_info("xtalk:n%d/%x bridge widget\n", nasid, widget);
63 return;
64
65no_mem:
66 pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
67}
24 68
25static int probe_one_port(nasid_t nasid, int widget, int masterwid) 69static int probe_one_port(nasid_t nasid, int widget, int masterwid)
26{ 70{
@@ -31,13 +75,10 @@ static int probe_one_port(nasid_t nasid, int widget, int masterwid)
31 (RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID); 75 (RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID);
32 partnum = XWIDGET_PART_NUM(widget_id); 76 partnum = XWIDGET_PART_NUM(widget_id);
33 77
34 printk(KERN_INFO "Cpu %d, Nasid 0x%x, widget 0x%x (partnum 0x%x) is ",
35 smp_processor_id(), nasid, widget, partnum);
36
37 switch (partnum) { 78 switch (partnum) {
38 case BRIDGE_WIDGET_PART_NUM: 79 case BRIDGE_WIDGET_PART_NUM:
39 case XBRIDGE_WIDGET_PART_NUM: 80 case XBRIDGE_WIDGET_PART_NUM:
40 bridge_probe(nasid, widget, masterwid); 81 bridge_platform_create(nasid, widget, masterwid);
41 break; 82 break;
42 default: 83 default:
43 break; 84 break;
@@ -52,8 +93,6 @@ static int xbow_probe(nasid_t nasid)
52 klxbow_t *xbow_p; 93 klxbow_t *xbow_p;
53 unsigned masterwid, i; 94 unsigned masterwid, i;
54 95
55 printk("is xbow\n");
56
57 /* 96 /*
58 * found xbow, so may have multiple bridges 97 * found xbow, so may have multiple bridges
59 * need to probe xbow 98 * need to probe xbow
@@ -117,19 +156,17 @@ static void xtalk_probe_node(cnodeid_t nid)
117 (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID); 156 (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
118 partnum = XWIDGET_PART_NUM(widget_id); 157 partnum = XWIDGET_PART_NUM(widget_id);
119 158
120 printk(KERN_INFO "Cpu %d, Nasid 0x%x: partnum 0x%x is ",
121 smp_processor_id(), nasid, partnum);
122
123 switch (partnum) { 159 switch (partnum) {
124 case BRIDGE_WIDGET_PART_NUM: 160 case BRIDGE_WIDGET_PART_NUM:
125 bridge_probe(nasid, 0x8, 0xa); 161 bridge_platform_create(nasid, 0x8, 0xa);
126 break; 162 break;
127 case XBOW_WIDGET_PART_NUM: 163 case XBOW_WIDGET_PART_NUM:
128 case XXBOW_WIDGET_PART_NUM: 164 case XXBOW_WIDGET_PART_NUM:
165 pr_info("xtalk:n%d/0 xbow widget\n", nasid);
129 xbow_probe(nasid); 166 xbow_probe(nasid);
130 break; 167 break;
131 default: 168 default:
132 printk(" unknown widget??\n"); 169 pr_info("xtalk:n%d/0 unknown widget (0x%x)\n", nasid, partnum);
133 break; 170 break;
134 } 171 }
135} 172}
diff --git a/arch/nds32/include/asm/Kbuild b/arch/nds32/include/asm/Kbuild
index f43b44d692ca..f37d5004a01c 100644
--- a/arch/nds32/include/asm/Kbuild
+++ b/arch/nds32/include/asm/Kbuild
@@ -4,10 +4,8 @@ generic-y += bitops.h
4generic-y += bug.h 4generic-y += bug.h
5generic-y += bugs.h 5generic-y += bugs.h
6generic-y += checksum.h 6generic-y += checksum.h
7generic-y += clkdev.h
8generic-y += cmpxchg.h 7generic-y += cmpxchg.h
9generic-y += compat.h 8generic-y += compat.h
10generic-y += cputime.h
11generic-y += device.h 9generic-y += device.h
12generic-y += div64.h 10generic-y += div64.h
13generic-y += dma.h 11generic-y += dma.h
@@ -26,7 +24,6 @@ generic-y += kdebug.h
26generic-y += kmap_types.h 24generic-y += kmap_types.h
27generic-y += kprobes.h 25generic-y += kprobes.h
28generic-y += kvm_para.h 26generic-y += kvm_para.h
29generic-y += limits.h
30generic-y += local.h 27generic-y += local.h
31generic-y += local64.h 28generic-y += local64.h
32generic-y += mm-arch-hooks.h 29generic-y += mm-arch-hooks.h
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 258ea6b2f2e7..c345b79414a9 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -211,7 +211,7 @@ endif
211 211
212asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1) 212asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1)
213 213
214KBUILD_CPPFLAGS += -Iarch/$(ARCH) $(asinstr) 214KBUILD_CPPFLAGS += -I $(srctree)/arch/$(ARCH) $(asinstr)
215KBUILD_AFLAGS += $(AFLAGS-y) 215KBUILD_AFLAGS += $(AFLAGS-y)
216KBUILD_CFLAGS += $(call cc-option,-msoft-float) 216KBUILD_CFLAGS += $(call cc-option,-msoft-float)
217KBUILD_CFLAGS += -pipe $(CFLAGS-y) 217KBUILD_CFLAGS += -pipe $(CFLAGS-y)
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h
index 1d1183048cfd..2781ebf6add4 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -93,6 +93,7 @@
93#define VMALLOC_REGION_ID NON_LINEAR_REGION_ID(H_VMALLOC_START) 93#define VMALLOC_REGION_ID NON_LINEAR_REGION_ID(H_VMALLOC_START)
94#define IO_REGION_ID NON_LINEAR_REGION_ID(H_KERN_IO_START) 94#define IO_REGION_ID NON_LINEAR_REGION_ID(H_KERN_IO_START)
95#define VMEMMAP_REGION_ID NON_LINEAR_REGION_ID(H_VMEMMAP_START) 95#define VMEMMAP_REGION_ID NON_LINEAR_REGION_ID(H_VMEMMAP_START)
96#define INVALID_REGION_ID (VMEMMAP_REGION_ID + 1)
96 97
97/* 98/*
98 * Defines the address of the vmemap area, in its own region on 99 * Defines the address of the vmemap area, in its own region on
@@ -119,14 +120,15 @@ static inline int get_region_id(unsigned long ea)
119 if (id == 0) 120 if (id == 0)
120 return USER_REGION_ID; 121 return USER_REGION_ID;
121 122
123 if (id != (PAGE_OFFSET >> 60))
124 return INVALID_REGION_ID;
125
122 if (ea < H_KERN_VIRT_START) 126 if (ea < H_KERN_VIRT_START)
123 return LINEAR_MAP_REGION_ID; 127 return LINEAR_MAP_REGION_ID;
124 128
125 VM_BUG_ON(id != 0xc);
126 BUILD_BUG_ON(NON_LINEAR_REGION_ID(H_VMALLOC_START) != 2); 129 BUILD_BUG_ON(NON_LINEAR_REGION_ID(H_VMALLOC_START) != 2);
127 130
128 region_id = NON_LINEAR_REGION_ID(ea); 131 region_id = NON_LINEAR_REGION_ID(ea);
129 VM_BUG_ON(region_id > VMEMMAP_REGION_ID);
130 return region_id; 132 return region_id;
131} 133}
132 134
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index 611204e588b9..58efca934311 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -232,7 +232,6 @@ static inline void enter_lazy_tlb(struct mm_struct *mm,
232extern void arch_exit_mmap(struct mm_struct *mm); 232extern void arch_exit_mmap(struct mm_struct *mm);
233 233
234static inline void arch_unmap(struct mm_struct *mm, 234static inline void arch_unmap(struct mm_struct *mm,
235 struct vm_area_struct *vma,
236 unsigned long start, unsigned long end) 235 unsigned long start, unsigned long end)
237{ 236{
238 if (start <= mm->context.vdso_base && mm->context.vdso_base < end) 237 if (start <= mm->context.vdso_base && mm->context.vdso_base < end)
diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c
index f2ed3ef4b129..862e2890bd3d 100644
--- a/arch/powerpc/kernel/cacheinfo.c
+++ b/arch/powerpc/kernel/cacheinfo.c
@@ -767,7 +767,6 @@ static void cacheinfo_create_index_dir(struct cache *cache, int index,
767 cache_dir->kobj, "index%d", index); 767 cache_dir->kobj, "index%d", index);
768 if (rc) { 768 if (rc) {
769 kobject_put(&index_dir->kobj); 769 kobject_put(&index_dir->kobj);
770 kfree(index_dir);
771 return; 770 return;
772 } 771 }
773 772
diff --git a/arch/powerpc/mm/book3s32/hash_low.S b/arch/powerpc/mm/book3s32/hash_low.S
index e27792d0b744..8366c2abeafc 100644
--- a/arch/powerpc/mm/book3s32/hash_low.S
+++ b/arch/powerpc/mm/book3s32/hash_low.S
@@ -539,7 +539,8 @@ _GLOBAL(flush_hash_pages)
539#ifdef CONFIG_SMP 539#ifdef CONFIG_SMP
540 lis r9, (mmu_hash_lock - PAGE_OFFSET)@ha 540 lis r9, (mmu_hash_lock - PAGE_OFFSET)@ha
541 addi r9, r9, (mmu_hash_lock - PAGE_OFFSET)@l 541 addi r9, r9, (mmu_hash_lock - PAGE_OFFSET)@l
542 lwz r8,TASK_CPU(r2) 542 tophys (r8, r2)
543 lwz r8, TASK_CPU(r8)
543 oris r8,r8,9 544 oris r8,r8,9
54410: lwarx r0,0,r9 54510: lwarx r0,0,r9
545 cmpi 0,r0,0 546 cmpi 0,r0,0
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index c5c9ff2d7afc..b5d92dc32844 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -556,7 +556,7 @@ static int __init add_huge_page_size(unsigned long long size)
556 if (size <= PAGE_SIZE || !is_power_of_2(size)) 556 if (size <= PAGE_SIZE || !is_power_of_2(size))
557 return -EINVAL; 557 return -EINVAL;
558 558
559 mmu_psize = check_and_get_huge_psize(size); 559 mmu_psize = check_and_get_huge_psize(shift);
560 if (mmu_psize < 0) 560 if (mmu_psize < 0)
561 return -EINVAL; 561 return -EINVAL;
562 562
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index e66745decea1..ee32c66e1af3 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -27,7 +27,7 @@ config RISCV
27 select GENERIC_STRNCPY_FROM_USER 27 select GENERIC_STRNCPY_FROM_USER
28 select GENERIC_STRNLEN_USER 28 select GENERIC_STRNLEN_USER
29 select GENERIC_SMP_IDLE_THREAD 29 select GENERIC_SMP_IDLE_THREAD
30 select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A 30 select GENERIC_ATOMIC64 if !64BIT
31 select HAVE_ARCH_AUDITSYSCALL 31 select HAVE_ARCH_AUDITSYSCALL
32 select HAVE_MEMBLOCK_NODE_MAP 32 select HAVE_MEMBLOCK_NODE_MAP
33 select HAVE_DMA_CONTIGUOUS 33 select HAVE_DMA_CONTIGUOUS
@@ -35,7 +35,6 @@ config RISCV
35 select HAVE_PERF_EVENTS 35 select HAVE_PERF_EVENTS
36 select HAVE_SYSCALL_TRACEPOINTS 36 select HAVE_SYSCALL_TRACEPOINTS
37 select IRQ_DOMAIN 37 select IRQ_DOMAIN
38 select RISCV_ISA_A if SMP
39 select SPARSE_IRQ 38 select SPARSE_IRQ
40 select SYSCTL_EXCEPTION_TRACE 39 select SYSCTL_EXCEPTION_TRACE
41 select HAVE_ARCH_TRACEHOOK 40 select HAVE_ARCH_TRACEHOOK
@@ -195,9 +194,6 @@ config RISCV_ISA_C
195 194
196 If you don't know what to do here, say Y. 195 If you don't know what to do here, say Y.
197 196
198config RISCV_ISA_A
199 def_bool y
200
201menu "supported PMU type" 197menu "supported PMU type"
202 depends on PERF_EVENTS 198 depends on PERF_EVENTS
203 199
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index c6342e638ef7..6b0741c9f348 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -39,9 +39,8 @@ endif
39KBUILD_CFLAGS += -Wall 39KBUILD_CFLAGS += -Wall
40 40
41# ISA string setting 41# ISA string setting
42riscv-march-$(CONFIG_ARCH_RV32I) := rv32im 42riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
43riscv-march-$(CONFIG_ARCH_RV64I) := rv64im 43riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima
44riscv-march-$(CONFIG_RISCV_ISA_A) := $(riscv-march-y)a
45riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd 44riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
46riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c 45riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
47KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y)) 46KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index cccd12cf27d4..3d019e062c6f 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -1,9 +1,9 @@
1generic-y += bugs.h 1generic-y += bugs.h
2generic-y += checksum.h 2generic-y += checksum.h
3generic-y += compat.h 3generic-y += compat.h
4generic-y += cputime.h
5generic-y += device.h 4generic-y += device.h
6generic-y += div64.h 5generic-y += div64.h
6generic-y += extable.h
7generic-y += dma.h 7generic-y += dma.h
8generic-y += dma-contiguous.h 8generic-y += dma-contiguous.h
9generic-y += dma-mapping.h 9generic-y += dma-mapping.h
@@ -11,7 +11,6 @@ generic-y += emergency-restart.h
11generic-y += exec.h 11generic-y += exec.h
12generic-y += fb.h 12generic-y += fb.h
13generic-y += hardirq.h 13generic-y += hardirq.h
14generic-y += hash.h
15generic-y += hw_irq.h 14generic-y += hw_irq.h
16generic-y += irq_regs.h 15generic-y += irq_regs.h
17generic-y += irq_work.h 16generic-y += irq_work.h
@@ -21,10 +20,8 @@ generic-y += kvm_para.h
21generic-y += local.h 20generic-y += local.h
22generic-y += local64.h 21generic-y += local64.h
23generic-y += mm-arch-hooks.h 22generic-y += mm-arch-hooks.h
24generic-y += mutex.h
25generic-y += percpu.h 23generic-y += percpu.h
26generic-y += preempt.h 24generic-y += preempt.h
27generic-y += scatterlist.h
28generic-y += sections.h 25generic-y += sections.h
29generic-y += serial.h 26generic-y += serial.h
30generic-y += shmparam.h 27generic-y += shmparam.h
diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h
index bfc7f099ab1f..52a1fbdeab3b 100644
--- a/arch/riscv/include/asm/bug.h
+++ b/arch/riscv/include/asm/bug.h
@@ -21,7 +21,12 @@
21#include <asm/asm.h> 21#include <asm/asm.h>
22 22
23#ifdef CONFIG_GENERIC_BUG 23#ifdef CONFIG_GENERIC_BUG
24#define __BUG_INSN _AC(0x00100073, UL) /* ebreak */ 24#define __INSN_LENGTH_MASK _UL(0x3)
25#define __INSN_LENGTH_32 _UL(0x3)
26#define __COMPRESSED_INSN_MASK _UL(0xffff)
27
28#define __BUG_INSN_32 _UL(0x00100073) /* ebreak */
29#define __BUG_INSN_16 _UL(0x9002) /* c.ebreak */
25 30
26#ifndef __ASSEMBLY__ 31#ifndef __ASSEMBLY__
27typedef u32 bug_insn_t; 32typedef u32 bug_insn_t;
@@ -38,38 +43,46 @@ typedef u32 bug_insn_t;
38#define __BUG_ENTRY \ 43#define __BUG_ENTRY \
39 __BUG_ENTRY_ADDR "\n\t" \ 44 __BUG_ENTRY_ADDR "\n\t" \
40 __BUG_ENTRY_FILE "\n\t" \ 45 __BUG_ENTRY_FILE "\n\t" \
41 RISCV_SHORT " %1" 46 RISCV_SHORT " %1\n\t" \
47 RISCV_SHORT " %2"
42#else 48#else
43#define __BUG_ENTRY \ 49#define __BUG_ENTRY \
44 __BUG_ENTRY_ADDR 50 __BUG_ENTRY_ADDR "\n\t" \
51 RISCV_SHORT " %2"
45#endif 52#endif
46 53
47#define BUG() \ 54#define __BUG_FLAGS(flags) \
48do { \ 55do { \
49 __asm__ __volatile__ ( \ 56 __asm__ __volatile__ ( \
50 "1:\n\t" \ 57 "1:\n\t" \
51 "ebreak\n" \ 58 "ebreak\n" \
52 ".pushsection __bug_table,\"a\"\n\t" \ 59 ".pushsection __bug_table,\"aw\"\n\t" \
53 "2:\n\t" \ 60 "2:\n\t" \
54 __BUG_ENTRY "\n\t" \ 61 __BUG_ENTRY "\n\t" \
55 ".org 2b + %2\n\t" \ 62 ".org 2b + %3\n\t" \
56 ".popsection" \ 63 ".popsection" \
57 : \ 64 : \
58 : "i" (__FILE__), "i" (__LINE__), \ 65 : "i" (__FILE__), "i" (__LINE__), \
59 "i" (sizeof(struct bug_entry))); \ 66 "i" (flags), \
60 unreachable(); \ 67 "i" (sizeof(struct bug_entry))); \
61} while (0) 68} while (0)
69
62#endif /* !__ASSEMBLY__ */ 70#endif /* !__ASSEMBLY__ */
63#else /* CONFIG_GENERIC_BUG */ 71#else /* CONFIG_GENERIC_BUG */
64#ifndef __ASSEMBLY__ 72#ifndef __ASSEMBLY__
65#define BUG() \ 73#define __BUG_FLAGS(flags) do { \
66do { \
67 __asm__ __volatile__ ("ebreak\n"); \ 74 __asm__ __volatile__ ("ebreak\n"); \
68 unreachable(); \
69} while (0) 75} while (0)
70#endif /* !__ASSEMBLY__ */ 76#endif /* !__ASSEMBLY__ */
71#endif /* CONFIG_GENERIC_BUG */ 77#endif /* CONFIG_GENERIC_BUG */
72 78
79#define BUG() do { \
80 __BUG_FLAGS(0); \
81 unreachable(); \
82} while (0)
83
84#define __WARN_FLAGS(flags) __BUG_FLAGS(BUGFLAG_WARNING|(flags))
85
73#define HAVE_ARCH_BUG 86#define HAVE_ARCH_BUG
74 87
75#include <asm-generic/bug.h> 88#include <asm-generic/bug.h>
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
index 8f13074413a7..1f4ba68ab9aa 100644
--- a/arch/riscv/include/asm/cacheflush.h
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -47,7 +47,7 @@ static inline void flush_dcache_page(struct page *page)
47 47
48#else /* CONFIG_SMP */ 48#else /* CONFIG_SMP */
49 49
50#define flush_icache_all() sbi_remote_fence_i(NULL) 50void flush_icache_all(void);
51void flush_icache_mm(struct mm_struct *mm, bool local); 51void flush_icache_mm(struct mm_struct *mm, bool local);
52 52
53#endif /* CONFIG_SMP */ 53#endif /* CONFIG_SMP */
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 28a0d1cb374c..3c3c26c3a1f1 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -14,64 +14,95 @@
14#ifndef _ASM_RISCV_CSR_H 14#ifndef _ASM_RISCV_CSR_H
15#define _ASM_RISCV_CSR_H 15#define _ASM_RISCV_CSR_H
16 16
17#include <asm/asm.h>
17#include <linux/const.h> 18#include <linux/const.h>
18 19
19/* Status register flags */ 20/* Status register flags */
20#define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */ 21#define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
21#define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */ 22#define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */
22#define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */ 23#define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */
23#define SR_SUM _AC(0x00040000, UL) /* Supervisor may access User Memory */ 24#define SR_SUM _AC(0x00040000, UL) /* Supervisor User Memory Access */
24 25
25#define SR_FS _AC(0x00006000, UL) /* Floating-point Status */ 26#define SR_FS _AC(0x00006000, UL) /* Floating-point Status */
26#define SR_FS_OFF _AC(0x00000000, UL) 27#define SR_FS_OFF _AC(0x00000000, UL)
27#define SR_FS_INITIAL _AC(0x00002000, UL) 28#define SR_FS_INITIAL _AC(0x00002000, UL)
28#define SR_FS_CLEAN _AC(0x00004000, UL) 29#define SR_FS_CLEAN _AC(0x00004000, UL)
29#define SR_FS_DIRTY _AC(0x00006000, UL) 30#define SR_FS_DIRTY _AC(0x00006000, UL)
30 31
31#define SR_XS _AC(0x00018000, UL) /* Extension Status */ 32#define SR_XS _AC(0x00018000, UL) /* Extension Status */
32#define SR_XS_OFF _AC(0x00000000, UL) 33#define SR_XS_OFF _AC(0x00000000, UL)
33#define SR_XS_INITIAL _AC(0x00008000, UL) 34#define SR_XS_INITIAL _AC(0x00008000, UL)
34#define SR_XS_CLEAN _AC(0x00010000, UL) 35#define SR_XS_CLEAN _AC(0x00010000, UL)
35#define SR_XS_DIRTY _AC(0x00018000, UL) 36#define SR_XS_DIRTY _AC(0x00018000, UL)
36 37
37#ifndef CONFIG_64BIT 38#ifndef CONFIG_64BIT
38#define SR_SD _AC(0x80000000, UL) /* FS/XS dirty */ 39#define SR_SD _AC(0x80000000, UL) /* FS/XS dirty */
39#else 40#else
40#define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */ 41#define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */
41#endif 42#endif
42 43
43/* SATP flags */ 44/* SATP flags */
44#if __riscv_xlen == 32 45#ifndef CONFIG_64BIT
45#define SATP_PPN _AC(0x003FFFFF, UL) 46#define SATP_PPN _AC(0x003FFFFF, UL)
46#define SATP_MODE_32 _AC(0x80000000, UL) 47#define SATP_MODE_32 _AC(0x80000000, UL)
47#define SATP_MODE SATP_MODE_32 48#define SATP_MODE SATP_MODE_32
48#else 49#else
49#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL) 50#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL)
50#define SATP_MODE_39 _AC(0x8000000000000000, UL) 51#define SATP_MODE_39 _AC(0x8000000000000000, UL)
51#define SATP_MODE SATP_MODE_39 52#define SATP_MODE SATP_MODE_39
52#endif 53#endif
53 54
54/* Interrupt Enable and Interrupt Pending flags */ 55/* SCAUSE */
55#define SIE_SSIE _AC(0x00000002, UL) /* Software Interrupt Enable */ 56#define SCAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1))
56#define SIE_STIE _AC(0x00000020, UL) /* Timer Interrupt Enable */ 57
57#define SIE_SEIE _AC(0x00000200, UL) /* External Interrupt Enable */ 58#define IRQ_U_SOFT 0
58 59#define IRQ_S_SOFT 1
59#define EXC_INST_MISALIGNED 0 60#define IRQ_M_SOFT 3
60#define EXC_INST_ACCESS 1 61#define IRQ_U_TIMER 4
61#define EXC_BREAKPOINT 3 62#define IRQ_S_TIMER 5
62#define EXC_LOAD_ACCESS 5 63#define IRQ_M_TIMER 7
63#define EXC_STORE_ACCESS 7 64#define IRQ_U_EXT 8
64#define EXC_SYSCALL 8 65#define IRQ_S_EXT 9
65#define EXC_INST_PAGE_FAULT 12 66#define IRQ_M_EXT 11
66#define EXC_LOAD_PAGE_FAULT 13 67
67#define EXC_STORE_PAGE_FAULT 15 68#define EXC_INST_MISALIGNED 0
69#define EXC_INST_ACCESS 1
70#define EXC_BREAKPOINT 3
71#define EXC_LOAD_ACCESS 5
72#define EXC_STORE_ACCESS 7
73#define EXC_SYSCALL 8
74#define EXC_INST_PAGE_FAULT 12
75#define EXC_LOAD_PAGE_FAULT 13
76#define EXC_STORE_PAGE_FAULT 15
77
78/* SIE (Interrupt Enable) and SIP (Interrupt Pending) flags */
79#define SIE_SSIE (_AC(0x1, UL) << IRQ_S_SOFT)
80#define SIE_STIE (_AC(0x1, UL) << IRQ_S_TIMER)
81#define SIE_SEIE (_AC(0x1, UL) << IRQ_S_EXT)
82
83#define CSR_CYCLE 0xc00
84#define CSR_TIME 0xc01
85#define CSR_INSTRET 0xc02
86#define CSR_SSTATUS 0x100
87#define CSR_SIE 0x104
88#define CSR_STVEC 0x105
89#define CSR_SCOUNTEREN 0x106
90#define CSR_SSCRATCH 0x140
91#define CSR_SEPC 0x141
92#define CSR_SCAUSE 0x142
93#define CSR_STVAL 0x143
94#define CSR_SIP 0x144
95#define CSR_SATP 0x180
96#define CSR_CYCLEH 0xc80
97#define CSR_TIMEH 0xc81
98#define CSR_INSTRETH 0xc82
68 99
69#ifndef __ASSEMBLY__ 100#ifndef __ASSEMBLY__
70 101
71#define csr_swap(csr, val) \ 102#define csr_swap(csr, val) \
72({ \ 103({ \
73 unsigned long __v = (unsigned long)(val); \ 104 unsigned long __v = (unsigned long)(val); \
74 __asm__ __volatile__ ("csrrw %0, " #csr ", %1" \ 105 __asm__ __volatile__ ("csrrw %0, " __ASM_STR(csr) ", %1"\
75 : "=r" (__v) : "rK" (__v) \ 106 : "=r" (__v) : "rK" (__v) \
76 : "memory"); \ 107 : "memory"); \
77 __v; \ 108 __v; \
@@ -80,7 +111,7 @@
80#define csr_read(csr) \ 111#define csr_read(csr) \
81({ \ 112({ \
82 register unsigned long __v; \ 113 register unsigned long __v; \
83 __asm__ __volatile__ ("csrr %0, " #csr \ 114 __asm__ __volatile__ ("csrr %0, " __ASM_STR(csr) \
84 : "=r" (__v) : \ 115 : "=r" (__v) : \
85 : "memory"); \ 116 : "memory"); \
86 __v; \ 117 __v; \
@@ -89,7 +120,7 @@
89#define csr_write(csr, val) \ 120#define csr_write(csr, val) \
90({ \ 121({ \
91 unsigned long __v = (unsigned long)(val); \ 122 unsigned long __v = (unsigned long)(val); \
92 __asm__ __volatile__ ("csrw " #csr ", %0" \ 123 __asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0" \
93 : : "rK" (__v) \ 124 : : "rK" (__v) \
94 : "memory"); \ 125 : "memory"); \
95}) 126})
@@ -97,7 +128,7 @@
97#define csr_read_set(csr, val) \ 128#define csr_read_set(csr, val) \
98({ \ 129({ \
99 unsigned long __v = (unsigned long)(val); \ 130 unsigned long __v = (unsigned long)(val); \
100 __asm__ __volatile__ ("csrrs %0, " #csr ", %1" \ 131 __asm__ __volatile__ ("csrrs %0, " __ASM_STR(csr) ", %1"\
101 : "=r" (__v) : "rK" (__v) \ 132 : "=r" (__v) : "rK" (__v) \
102 : "memory"); \ 133 : "memory"); \
103 __v; \ 134 __v; \
@@ -106,7 +137,7 @@
106#define csr_set(csr, val) \ 137#define csr_set(csr, val) \
107({ \ 138({ \
108 unsigned long __v = (unsigned long)(val); \ 139 unsigned long __v = (unsigned long)(val); \
109 __asm__ __volatile__ ("csrs " #csr ", %0" \ 140 __asm__ __volatile__ ("csrs " __ASM_STR(csr) ", %0" \
110 : : "rK" (__v) \ 141 : : "rK" (__v) \
111 : "memory"); \ 142 : "memory"); \
112}) 143})
@@ -114,7 +145,7 @@
114#define csr_read_clear(csr, val) \ 145#define csr_read_clear(csr, val) \
115({ \ 146({ \
116 unsigned long __v = (unsigned long)(val); \ 147 unsigned long __v = (unsigned long)(val); \
117 __asm__ __volatile__ ("csrrc %0, " #csr ", %1" \ 148 __asm__ __volatile__ ("csrrc %0, " __ASM_STR(csr) ", %1"\
118 : "=r" (__v) : "rK" (__v) \ 149 : "=r" (__v) : "rK" (__v) \
119 : "memory"); \ 150 : "memory"); \
120 __v; \ 151 __v; \
@@ -123,7 +154,7 @@
123#define csr_clear(csr, val) \ 154#define csr_clear(csr, val) \
124({ \ 155({ \
125 unsigned long __v = (unsigned long)(val); \ 156 unsigned long __v = (unsigned long)(val); \
126 __asm__ __volatile__ ("csrc " #csr ", %0" \ 157 __asm__ __volatile__ ("csrc " __ASM_STR(csr) ", %0" \
127 : : "rK" (__v) \ 158 : : "rK" (__v) \
128 : "memory"); \ 159 : "memory"); \
129}) 160})
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index 697fc23b0d5a..ce0cd7d77eb0 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -27,13 +27,7 @@
27#define ELF_CLASS ELFCLASS32 27#define ELF_CLASS ELFCLASS32
28#endif 28#endif
29 29
30#if defined(__LITTLE_ENDIAN)
31#define ELF_DATA ELFDATA2LSB 30#define ELF_DATA ELFDATA2LSB
32#elif defined(__BIG_ENDIAN)
33#define ELF_DATA ELFDATA2MSB
34#else
35#error "Unknown endianness"
36#endif
37 31
38/* 32/*
39 * This is used to ensure we don't load something for the wrong architecture. 33 * This is used to ensure we don't load something for the wrong architecture.
diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
index 66641624d8a5..4ad6409c4647 100644
--- a/arch/riscv/include/asm/futex.h
+++ b/arch/riscv/include/asm/futex.h
@@ -7,18 +7,6 @@
7#ifndef _ASM_FUTEX_H 7#ifndef _ASM_FUTEX_H
8#define _ASM_FUTEX_H 8#define _ASM_FUTEX_H
9 9
10#ifndef CONFIG_RISCV_ISA_A
11/*
12 * Use the generic interrupt disabling versions if the A extension
13 * is not supported.
14 */
15#ifdef CONFIG_SMP
16#error "Can't support generic futex calls without A extension on SMP"
17#endif
18#include <asm-generic/futex.h>
19
20#else /* CONFIG_RISCV_ISA_A */
21
22#include <linux/futex.h> 10#include <linux/futex.h>
23#include <linux/uaccess.h> 11#include <linux/uaccess.h>
24#include <linux/errno.h> 12#include <linux/errno.h>
@@ -124,5 +112,4 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
124 return ret; 112 return ret;
125} 113}
126 114
127#endif /* CONFIG_RISCV_ISA_A */
128#endif /* _ASM_FUTEX_H */ 115#endif /* _ASM_FUTEX_H */
diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h
index 07a3c6d5706f..1a69b3bcd371 100644
--- a/arch/riscv/include/asm/irqflags.h
+++ b/arch/riscv/include/asm/irqflags.h
@@ -21,25 +21,25 @@
21/* read interrupt enabled status */ 21/* read interrupt enabled status */
22static inline unsigned long arch_local_save_flags(void) 22static inline unsigned long arch_local_save_flags(void)
23{ 23{
24 return csr_read(sstatus); 24 return csr_read(CSR_SSTATUS);
25} 25}
26 26
27/* unconditionally enable interrupts */ 27/* unconditionally enable interrupts */
28static inline void arch_local_irq_enable(void) 28static inline void arch_local_irq_enable(void)
29{ 29{
30 csr_set(sstatus, SR_SIE); 30 csr_set(CSR_SSTATUS, SR_SIE);
31} 31}
32 32
33/* unconditionally disable interrupts */ 33/* unconditionally disable interrupts */
34static inline void arch_local_irq_disable(void) 34static inline void arch_local_irq_disable(void)
35{ 35{
36 csr_clear(sstatus, SR_SIE); 36 csr_clear(CSR_SSTATUS, SR_SIE);
37} 37}
38 38
39/* get status and disable interrupts */ 39/* get status and disable interrupts */
40static inline unsigned long arch_local_irq_save(void) 40static inline unsigned long arch_local_irq_save(void)
41{ 41{
42 return csr_read_clear(sstatus, SR_SIE); 42 return csr_read_clear(CSR_SSTATUS, SR_SIE);
43} 43}
44 44
45/* test flags */ 45/* test flags */
@@ -57,7 +57,7 @@ static inline int arch_irqs_disabled(void)
57/* set interrupt enabled status */ 57/* set interrupt enabled status */
58static inline void arch_local_irq_restore(unsigned long flags) 58static inline void arch_local_irq_restore(unsigned long flags)
59{ 59{
60 csr_set(sstatus, flags & SR_SIE); 60 csr_set(CSR_SSTATUS, flags & SR_SIE);
61} 61}
62 62
63#endif /* _ASM_RISCV_IRQFLAGS_H */ 63#endif /* _ASM_RISCV_IRQFLAGS_H */
diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h
index 336d60ec5698..bf4f097a9051 100644
--- a/arch/riscv/include/asm/mmu_context.h
+++ b/arch/riscv/include/asm/mmu_context.h
@@ -20,8 +20,6 @@
20 20
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/sched.h> 22#include <linux/sched.h>
23#include <asm/tlbflush.h>
24#include <asm/cacheflush.h>
25 23
26static inline void enter_lazy_tlb(struct mm_struct *mm, 24static inline void enter_lazy_tlb(struct mm_struct *mm,
27 struct task_struct *task) 25 struct task_struct *task)
@@ -39,61 +37,8 @@ static inline void destroy_context(struct mm_struct *mm)
39{ 37{
40} 38}
41 39
42/* 40void switch_mm(struct mm_struct *prev, struct mm_struct *next,
43 * When necessary, performs a deferred icache flush for the given MM context, 41 struct task_struct *task);
44 * on the local CPU. RISC-V has no direct mechanism for instruction cache
45 * shoot downs, so instead we send an IPI that informs the remote harts they
46 * need to flush their local instruction caches. To avoid pathologically slow
47 * behavior in a common case (a bunch of single-hart processes on a many-hart
48 * machine, ie 'make -j') we avoid the IPIs for harts that are not currently
49 * executing a MM context and instead schedule a deferred local instruction
50 * cache flush to be performed before execution resumes on each hart. This
51 * actually performs that local instruction cache flush, which implicitly only
52 * refers to the current hart.
53 */
54static inline void flush_icache_deferred(struct mm_struct *mm)
55{
56#ifdef CONFIG_SMP
57 unsigned int cpu = smp_processor_id();
58 cpumask_t *mask = &mm->context.icache_stale_mask;
59
60 if (cpumask_test_cpu(cpu, mask)) {
61 cpumask_clear_cpu(cpu, mask);
62 /*
63 * Ensure the remote hart's writes are visible to this hart.
64 * This pairs with a barrier in flush_icache_mm.
65 */
66 smp_mb();
67 local_flush_icache_all();
68 }
69#endif
70}
71
72static inline void switch_mm(struct mm_struct *prev,
73 struct mm_struct *next, struct task_struct *task)
74{
75 if (likely(prev != next)) {
76 /*
77 * Mark the current MM context as inactive, and the next as
78 * active. This is at least used by the icache flushing
79 * routines in order to determine who should
80 */
81 unsigned int cpu = smp_processor_id();
82
83 cpumask_clear_cpu(cpu, mm_cpumask(prev));
84 cpumask_set_cpu(cpu, mm_cpumask(next));
85
86 /*
87 * Use the old spbtr name instead of using the current satp
88 * name to support binutils 2.29 which doesn't know about the
89 * privileged ISA 1.10 yet.
90 */
91 csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE);
92 local_flush_tlb_all();
93
94 flush_icache_deferred(next);
95 }
96}
97 42
98static inline void activate_mm(struct mm_struct *prev, 43static inline void activate_mm(struct mm_struct *prev,
99 struct mm_struct *next) 44 struct mm_struct *next)
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
index d35ec2f41381..9c867a4bac83 100644
--- a/arch/riscv/include/asm/ptrace.h
+++ b/arch/riscv/include/asm/ptrace.h
@@ -70,47 +70,38 @@ struct pt_regs {
70 70
71 71
72/* Helpers for working with the instruction pointer */ 72/* Helpers for working with the instruction pointer */
73#define GET_IP(regs) ((regs)->sepc)
74#define SET_IP(regs, val) (GET_IP(regs) = (val))
75
76static inline unsigned long instruction_pointer(struct pt_regs *regs) 73static inline unsigned long instruction_pointer(struct pt_regs *regs)
77{ 74{
78 return GET_IP(regs); 75 return regs->sepc;
79} 76}
80static inline void instruction_pointer_set(struct pt_regs *regs, 77static inline void instruction_pointer_set(struct pt_regs *regs,
81 unsigned long val) 78 unsigned long val)
82{ 79{
83 SET_IP(regs, val); 80 regs->sepc = val;
84} 81}
85 82
86#define profile_pc(regs) instruction_pointer(regs) 83#define profile_pc(regs) instruction_pointer(regs)
87 84
88/* Helpers for working with the user stack pointer */ 85/* Helpers for working with the user stack pointer */
89#define GET_USP(regs) ((regs)->sp)
90#define SET_USP(regs, val) (GET_USP(regs) = (val))
91
92static inline unsigned long user_stack_pointer(struct pt_regs *regs) 86static inline unsigned long user_stack_pointer(struct pt_regs *regs)
93{ 87{
94 return GET_USP(regs); 88 return regs->sp;
95} 89}
96static inline void user_stack_pointer_set(struct pt_regs *regs, 90static inline void user_stack_pointer_set(struct pt_regs *regs,
97 unsigned long val) 91 unsigned long val)
98{ 92{
99 SET_USP(regs, val); 93 regs->sp = val;
100} 94}
101 95
102/* Helpers for working with the frame pointer */ 96/* Helpers for working with the frame pointer */
103#define GET_FP(regs) ((regs)->s0)
104#define SET_FP(regs, val) (GET_FP(regs) = (val))
105
106static inline unsigned long frame_pointer(struct pt_regs *regs) 97static inline unsigned long frame_pointer(struct pt_regs *regs)
107{ 98{
108 return GET_FP(regs); 99 return regs->s0;
109} 100}
110static inline void frame_pointer_set(struct pt_regs *regs, 101static inline void frame_pointer_set(struct pt_regs *regs,
111 unsigned long val) 102 unsigned long val)
112{ 103{
113 SET_FP(regs, val); 104 regs->s0 = val;
114} 105}
115 106
116static inline unsigned long regs_return_value(struct pt_regs *regs) 107static inline unsigned long regs_return_value(struct pt_regs *regs)
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index b6bb10b92fe2..19f231615510 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -26,22 +26,27 @@
26#define SBI_REMOTE_SFENCE_VMA_ASID 7 26#define SBI_REMOTE_SFENCE_VMA_ASID 7
27#define SBI_SHUTDOWN 8 27#define SBI_SHUTDOWN 8
28 28
29#define SBI_CALL(which, arg0, arg1, arg2) ({ \ 29#define SBI_CALL(which, arg0, arg1, arg2, arg3) ({ \
30 register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ 30 register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \
31 register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ 31 register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \
32 register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ 32 register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \
33 register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); \
33 register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ 34 register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \
34 asm volatile ("ecall" \ 35 asm volatile ("ecall" \
35 : "+r" (a0) \ 36 : "+r" (a0) \
36 : "r" (a1), "r" (a2), "r" (a7) \ 37 : "r" (a1), "r" (a2), "r" (a3), "r" (a7) \
37 : "memory"); \ 38 : "memory"); \
38 a0; \ 39 a0; \
39}) 40})
40 41
41/* Lazy implementations until SBI is finalized */ 42/* Lazy implementations until SBI is finalized */
42#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0) 43#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0, 0)
43#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0) 44#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0, 0)
44#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0) 45#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0, 0)
46#define SBI_CALL_3(which, arg0, arg1, arg2) \
47 SBI_CALL(which, arg0, arg1, arg2, 0)
48#define SBI_CALL_4(which, arg0, arg1, arg2, arg3) \
49 SBI_CALL(which, arg0, arg1, arg2, arg3)
45 50
46static inline void sbi_console_putchar(int ch) 51static inline void sbi_console_putchar(int ch)
47{ 52{
@@ -86,7 +91,7 @@ static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask,
86 unsigned long start, 91 unsigned long start,
87 unsigned long size) 92 unsigned long size)
88{ 93{
89 SBI_CALL_1(SBI_REMOTE_SFENCE_VMA, hart_mask); 94 SBI_CALL_3(SBI_REMOTE_SFENCE_VMA, hart_mask, start, size);
90} 95}
91 96
92static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, 97static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
@@ -94,7 +99,7 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
94 unsigned long size, 99 unsigned long size,
95 unsigned long asid) 100 unsigned long asid)
96{ 101{
97 SBI_CALL_1(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask); 102 SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid);
98} 103}
99 104
100#endif 105#endif
diff --git a/arch/riscv/include/asm/sifive_l2_cache.h b/arch/riscv/include/asm/sifive_l2_cache.h
new file mode 100644
index 000000000000..04f6748fc50b
--- /dev/null
+++ b/arch/riscv/include/asm/sifive_l2_cache.h
@@ -0,0 +1,16 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * SiFive L2 Cache Controller header file
4 *
5 */
6
7#ifndef _ASM_RISCV_SIFIVE_L2_CACHE_H
8#define _ASM_RISCV_SIFIVE_L2_CACHE_H
9
10extern int register_sifive_l2_error_notifier(struct notifier_block *nb);
11extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb);
12
13#define SIFIVE_L2_ERR_TYPE_CE 0
14#define SIFIVE_L2_ERR_TYPE_UE 1
15
16#endif /* _ASM_RISCV_SIFIVE_L2_CACHE_H */
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 1c9cc8389928..9c039870019b 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -28,7 +28,9 @@
28#include <asm/processor.h> 28#include <asm/processor.h>
29#include <asm/csr.h> 29#include <asm/csr.h>
30 30
31typedef unsigned long mm_segment_t; 31typedef struct {
32 unsigned long seg;
33} mm_segment_t;
32 34
33/* 35/*
34 * low level task data that entry.S needs immediate access to 36 * low level task data that entry.S needs immediate access to
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index fb53a8089e76..b26f407be5c8 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -23,6 +23,7 @@
23#include <linux/compiler.h> 23#include <linux/compiler.h>
24#include <linux/thread_info.h> 24#include <linux/thread_info.h>
25#include <asm/byteorder.h> 25#include <asm/byteorder.h>
26#include <asm/extable.h>
26#include <asm/asm.h> 27#include <asm/asm.h>
27 28
28#define __enable_user_access() \ 29#define __enable_user_access() \
@@ -38,8 +39,10 @@
38 * For historical reasons, these macros are grossly misnamed. 39 * For historical reasons, these macros are grossly misnamed.
39 */ 40 */
40 41
41#define KERNEL_DS (~0UL) 42#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
42#define USER_DS (TASK_SIZE) 43
44#define KERNEL_DS MAKE_MM_SEG(~0UL)
45#define USER_DS MAKE_MM_SEG(TASK_SIZE)
43 46
44#define get_fs() (current_thread_info()->addr_limit) 47#define get_fs() (current_thread_info()->addr_limit)
45 48
@@ -48,9 +51,9 @@ static inline void set_fs(mm_segment_t fs)
48 current_thread_info()->addr_limit = fs; 51 current_thread_info()->addr_limit = fs;
49} 52}
50 53
51#define segment_eq(a, b) ((a) == (b)) 54#define segment_eq(a, b) ((a).seg == (b).seg)
52 55
53#define user_addr_max() (get_fs()) 56#define user_addr_max() (get_fs().seg)
54 57
55 58
56/** 59/**
@@ -82,7 +85,7 @@ static inline int __access_ok(unsigned long addr, unsigned long size)
82{ 85{
83 const mm_segment_t fs = get_fs(); 86 const mm_segment_t fs = get_fs();
84 87
85 return (size <= fs) && (addr <= (fs - size)); 88 return size <= fs.seg && addr <= fs.seg - size;
86} 89}
87 90
88/* 91/*
@@ -98,21 +101,8 @@ static inline int __access_ok(unsigned long addr, unsigned long size)
98 * on our cache or tlb entries. 101 * on our cache or tlb entries.
99 */ 102 */
100 103
101struct exception_table_entry {
102 unsigned long insn, fixup;
103};
104
105extern int fixup_exception(struct pt_regs *state);
106
107#if defined(__LITTLE_ENDIAN)
108#define __MSW 1
109#define __LSW 0 104#define __LSW 0
110#elif defined(__BIG_ENDIAN) 105#define __MSW 1
111#define __MSW 0
112#define __LSW 1
113#else
114#error "Unknown endianness"
115#endif
116 106
117/* 107/*
118 * The "__xxx" versions of the user access functions do not verify the address 108 * The "__xxx" versions of the user access functions do not verify the address
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index dac98348c6a3..578bb5efc085 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -312,9 +312,6 @@ void asm_offsets(void)
312 - offsetof(struct task_struct, thread.fstate.f[0]) 312 - offsetof(struct task_struct, thread.fstate.f[0])
313 ); 313 );
314 314
315 /* The assembler needs access to THREAD_SIZE as well. */
316 DEFINE(ASM_THREAD_SIZE, THREAD_SIZE);
317
318 /* 315 /*
319 * We allocate a pt_regs on the stack when entering the kernel. This 316 * We allocate a pt_regs on the stack when entering the kernel. This
320 * ensures the alignment is sane. 317 * ensures the alignment is sane.
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index cf2fca12414a..c8d2a3223099 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -136,8 +136,7 @@ static void c_stop(struct seq_file *m, void *v)
136static int c_show(struct seq_file *m, void *v) 136static int c_show(struct seq_file *m, void *v)
137{ 137{
138 unsigned long cpu_id = (unsigned long)v - 1; 138 unsigned long cpu_id = (unsigned long)v - 1;
139 struct device_node *node = of_get_cpu_node(cpuid_to_hartid_map(cpu_id), 139 struct device_node *node = of_get_cpu_node(cpu_id, NULL);
140 NULL);
141 const char *compat, *isa, *mmu; 140 const char *compat, *isa, *mmu;
142 141
143 seq_printf(m, "processor\t: %lu\n", cpu_id); 142 seq_printf(m, "processor\t: %lu\n", cpu_id);
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index fd9b57c8b4ce..1c1ecc238cfa 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -37,11 +37,11 @@
37 * the kernel thread pointer. If we came from the kernel, sscratch 37 * the kernel thread pointer. If we came from the kernel, sscratch
38 * will contain 0, and we should continue on the current TP. 38 * will contain 0, and we should continue on the current TP.
39 */ 39 */
40 csrrw tp, sscratch, tp 40 csrrw tp, CSR_SSCRATCH, tp
41 bnez tp, _save_context 41 bnez tp, _save_context
42 42
43_restore_kernel_tpsp: 43_restore_kernel_tpsp:
44 csrr tp, sscratch 44 csrr tp, CSR_SSCRATCH
45 REG_S sp, TASK_TI_KERNEL_SP(tp) 45 REG_S sp, TASK_TI_KERNEL_SP(tp)
46_save_context: 46_save_context:
47 REG_S sp, TASK_TI_USER_SP(tp) 47 REG_S sp, TASK_TI_USER_SP(tp)
@@ -87,11 +87,11 @@ _save_context:
87 li t0, SR_SUM | SR_FS 87 li t0, SR_SUM | SR_FS
88 88
89 REG_L s0, TASK_TI_USER_SP(tp) 89 REG_L s0, TASK_TI_USER_SP(tp)
90 csrrc s1, sstatus, t0 90 csrrc s1, CSR_SSTATUS, t0
91 csrr s2, sepc 91 csrr s2, CSR_SEPC
92 csrr s3, sbadaddr 92 csrr s3, CSR_STVAL
93 csrr s4, scause 93 csrr s4, CSR_SCAUSE
94 csrr s5, sscratch 94 csrr s5, CSR_SSCRATCH
95 REG_S s0, PT_SP(sp) 95 REG_S s0, PT_SP(sp)
96 REG_S s1, PT_SSTATUS(sp) 96 REG_S s1, PT_SSTATUS(sp)
97 REG_S s2, PT_SEPC(sp) 97 REG_S s2, PT_SEPC(sp)
@@ -107,8 +107,8 @@ _save_context:
107 .macro RESTORE_ALL 107 .macro RESTORE_ALL
108 REG_L a0, PT_SSTATUS(sp) 108 REG_L a0, PT_SSTATUS(sp)
109 REG_L a2, PT_SEPC(sp) 109 REG_L a2, PT_SEPC(sp)
110 csrw sstatus, a0 110 csrw CSR_SSTATUS, a0
111 csrw sepc, a2 111 csrw CSR_SEPC, a2
112 112
113 REG_L x1, PT_RA(sp) 113 REG_L x1, PT_RA(sp)
114 REG_L x3, PT_GP(sp) 114 REG_L x3, PT_GP(sp)
@@ -155,7 +155,7 @@ ENTRY(handle_exception)
155 * Set sscratch register to 0, so that if a recursive exception 155 * Set sscratch register to 0, so that if a recursive exception
156 * occurs, the exception vector knows it came from the kernel 156 * occurs, the exception vector knows it came from the kernel
157 */ 157 */
158 csrw sscratch, x0 158 csrw CSR_SSCRATCH, x0
159 159
160 /* Load the global pointer */ 160 /* Load the global pointer */
161.option push 161.option push
@@ -248,7 +248,7 @@ resume_userspace:
248 * Save TP into sscratch, so we can find the kernel data structures 248 * Save TP into sscratch, so we can find the kernel data structures
249 * again. 249 * again.
250 */ 250 */
251 csrw sscratch, tp 251 csrw CSR_SSCRATCH, tp
252 252
253restore_all: 253restore_all:
254 RESTORE_ALL 254 RESTORE_ALL
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index fe884cd69abd..370c66ce187a 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -23,7 +23,8 @@
23__INIT 23__INIT
24ENTRY(_start) 24ENTRY(_start)
25 /* Mask all interrupts */ 25 /* Mask all interrupts */
26 csrw sie, zero 26 csrw CSR_SIE, zero
27 csrw CSR_SIP, zero
27 28
28 /* Load the global pointer */ 29 /* Load the global pointer */
29.option push 30.option push
@@ -68,14 +69,10 @@ clear_bss_done:
68 /* Restore C environment */ 69 /* Restore C environment */
69 la tp, init_task 70 la tp, init_task
70 sw zero, TASK_TI_CPU(tp) 71 sw zero, TASK_TI_CPU(tp)
71 72 la sp, init_thread_union + THREAD_SIZE
72 la sp, init_thread_union
73 li a0, ASM_THREAD_SIZE
74 add sp, sp, a0
75 73
76 /* Start the kernel */ 74 /* Start the kernel */
77 mv a0, s0 75 mv a0, s1
78 mv a1, s1
79 call parse_dtb 76 call parse_dtb
80 tail start_kernel 77 tail start_kernel
81 78
@@ -89,7 +86,7 @@ relocate:
89 /* Point stvec to virtual address of intruction after satp write */ 86 /* Point stvec to virtual address of intruction after satp write */
90 la a0, 1f 87 la a0, 1f
91 add a0, a0, a1 88 add a0, a0, a1
92 csrw stvec, a0 89 csrw CSR_STVEC, a0
93 90
94 /* Compute satp for kernel page tables, but don't load it yet */ 91 /* Compute satp for kernel page tables, but don't load it yet */
95 la a2, swapper_pg_dir 92 la a2, swapper_pg_dir
@@ -99,18 +96,20 @@ relocate:
99 96
100 /* 97 /*
101 * Load trampoline page directory, which will cause us to trap to 98 * Load trampoline page directory, which will cause us to trap to
102 * stvec if VA != PA, or simply fall through if VA == PA 99 * stvec if VA != PA, or simply fall through if VA == PA. We need a
100 * full fence here because setup_vm() just wrote these PTEs and we need
101 * to ensure the new translations are in use.
103 */ 102 */
104 la a0, trampoline_pg_dir 103 la a0, trampoline_pg_dir
105 srl a0, a0, PAGE_SHIFT 104 srl a0, a0, PAGE_SHIFT
106 or a0, a0, a1 105 or a0, a0, a1
107 sfence.vma 106 sfence.vma
108 csrw sptbr, a0 107 csrw CSR_SATP, a0
109.align 2 108.align 2
1101: 1091:
111 /* Set trap vector to spin forever to help debug */ 110 /* Set trap vector to spin forever to help debug */
112 la a0, .Lsecondary_park 111 la a0, .Lsecondary_park
113 csrw stvec, a0 112 csrw CSR_STVEC, a0
114 113
115 /* Reload the global pointer */ 114 /* Reload the global pointer */
116.option push 115.option push
@@ -118,8 +117,14 @@ relocate:
118 la gp, __global_pointer$ 117 la gp, __global_pointer$
119.option pop 118.option pop
120 119
121 /* Switch to kernel page tables */ 120 /*
122 csrw sptbr, a2 121 * Switch to kernel page tables. A full fence is necessary in order to
122 * avoid using the trampoline translations, which are only correct for
123 * the first superpage. Fetching the fence is guarnteed to work
124 * because that first superpage is translated the same way.
125 */
126 csrw CSR_SATP, a2
127 sfence.vma
123 128
124 ret 129 ret
125 130
@@ -130,7 +135,7 @@ relocate:
130 135
131 /* Set trap vector to spin forever to help debug */ 136 /* Set trap vector to spin forever to help debug */
132 la a3, .Lsecondary_park 137 la a3, .Lsecondary_park
133 csrw stvec, a3 138 csrw CSR_STVEC, a3
134 139
135 slli a3, a0, LGREG 140 slli a3, a0, LGREG
136 la a1, __cpu_up_stack_pointer 141 la a1, __cpu_up_stack_pointer
diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c
index 48e6b7db83a1..6d8659388c49 100644
--- a/arch/riscv/kernel/irq.c
+++ b/arch/riscv/kernel/irq.c
@@ -14,17 +14,9 @@
14/* 14/*
15 * Possible interrupt causes: 15 * Possible interrupt causes:
16 */ 16 */
17#define INTERRUPT_CAUSE_SOFTWARE 1 17#define INTERRUPT_CAUSE_SOFTWARE IRQ_S_SOFT
18#define INTERRUPT_CAUSE_TIMER 5 18#define INTERRUPT_CAUSE_TIMER IRQ_S_TIMER
19#define INTERRUPT_CAUSE_EXTERNAL 9 19#define INTERRUPT_CAUSE_EXTERNAL IRQ_S_EXT
20
21/*
22 * The high order bit of the trap cause register is always set for
23 * interrupts, which allows us to differentiate them from exceptions
24 * quickly. The INTERRUPT_CAUSE_* macros don't contain that bit, so we
25 * need to mask it off.
26 */
27#define INTERRUPT_CAUSE_FLAG (1UL << (__riscv_xlen - 1))
28 20
29int arch_show_interrupts(struct seq_file *p, int prec) 21int arch_show_interrupts(struct seq_file *p, int prec)
30{ 22{
@@ -37,7 +29,7 @@ asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs)
37 struct pt_regs *old_regs = set_irq_regs(regs); 29 struct pt_regs *old_regs = set_irq_regs(regs);
38 30
39 irq_enter(); 31 irq_enter();
40 switch (regs->scause & ~INTERRUPT_CAUSE_FLAG) { 32 switch (regs->scause & ~SCAUSE_IRQ_FLAG) {
41 case INTERRUPT_CAUSE_TIMER: 33 case INTERRUPT_CAUSE_TIMER:
42 riscv_timer_interrupt(); 34 riscv_timer_interrupt();
43 break; 35 break;
@@ -54,7 +46,8 @@ asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs)
54 handle_arch_irq(regs); 46 handle_arch_irq(regs);
55 break; 47 break;
56 default: 48 default:
57 panic("unexpected interrupt cause"); 49 pr_alert("unexpected interrupt cause 0x%lx", regs->scause);
50 BUG();
58 } 51 }
59 irq_exit(); 52 irq_exit();
60 53
diff --git a/arch/riscv/kernel/perf_event.c b/arch/riscv/kernel/perf_event.c
index 667ee70defea..91626d9ae5f2 100644
--- a/arch/riscv/kernel/perf_event.c
+++ b/arch/riscv/kernel/perf_event.c
@@ -185,10 +185,10 @@ static inline u64 read_counter(int idx)
185 185
186 switch (idx) { 186 switch (idx) {
187 case RISCV_PMU_CYCLE: 187 case RISCV_PMU_CYCLE:
188 val = csr_read(cycle); 188 val = csr_read(CSR_CYCLE);
189 break; 189 break;
190 case RISCV_PMU_INSTRET: 190 case RISCV_PMU_INSTRET:
191 val = csr_read(instret); 191 val = csr_read(CSR_INSTRET);
192 break; 192 break;
193 default: 193 default:
194 WARN_ON_ONCE(idx < 0 || idx > RISCV_MAX_COUNTERS); 194 WARN_ON_ONCE(idx < 0 || idx > RISCV_MAX_COUNTERS);
diff --git a/arch/riscv/kernel/reset.c b/arch/riscv/kernel/reset.c
index 2a53d26ffdd6..ed637aee514b 100644
--- a/arch/riscv/kernel/reset.c
+++ b/arch/riscv/kernel/reset.c
@@ -12,11 +12,15 @@
12 */ 12 */
13 13
14#include <linux/reboot.h> 14#include <linux/reboot.h>
15#include <linux/export.h>
16#include <asm/sbi.h> 15#include <asm/sbi.h>
17 16
18void (*pm_power_off)(void) = machine_power_off; 17static void default_power_off(void)
19EXPORT_SYMBOL(pm_power_off); 18{
19 sbi_shutdown();
20 while (1);
21}
22
23void (*pm_power_off)(void) = default_power_off;
20 24
21void machine_restart(char *cmd) 25void machine_restart(char *cmd)
22{ 26{
@@ -26,11 +30,10 @@ void machine_restart(char *cmd)
26 30
27void machine_halt(void) 31void machine_halt(void)
28{ 32{
29 machine_power_off(); 33 pm_power_off();
30} 34}
31 35
32void machine_power_off(void) 36void machine_power_off(void)
33{ 37{
34 sbi_shutdown(); 38 pm_power_off();
35 while (1);
36} 39}
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 540a331d1376..d93bcce004e3 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -52,9 +52,11 @@ struct screen_info screen_info = {
52atomic_t hart_lottery; 52atomic_t hart_lottery;
53unsigned long boot_cpu_hartid; 53unsigned long boot_cpu_hartid;
54 54
55void __init parse_dtb(unsigned int hartid, void *dtb) 55void __init parse_dtb(phys_addr_t dtb_phys)
56{ 56{
57 if (early_init_dt_scan(__va(dtb))) 57 void *dtb = __va(dtb_phys);
58
59 if (early_init_dt_scan(dtb))
58 return; 60 return;
59 61
60 pr_err("No DTB passed to the kernel\n"); 62 pr_err("No DTB passed to the kernel\n");
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 837e1646091a..804d6ee4f3c5 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -234,6 +234,9 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
234 234
235 /* Are we from a system call? */ 235 /* Are we from a system call? */
236 if (regs->scause == EXC_SYSCALL) { 236 if (regs->scause == EXC_SYSCALL) {
237 /* Avoid additional syscall restarting via ret_from_exception */
238 regs->scause = -1UL;
239
237 /* If so, check system call restarting.. */ 240 /* If so, check system call restarting.. */
238 switch (regs->a0) { 241 switch (regs->a0) {
239 case -ERESTART_RESTARTBLOCK: 242 case -ERESTART_RESTARTBLOCK:
@@ -272,6 +275,9 @@ static void do_signal(struct pt_regs *regs)
272 275
273 /* Did we come from a system call? */ 276 /* Did we come from a system call? */
274 if (regs->scause == EXC_SYSCALL) { 277 if (regs->scause == EXC_SYSCALL) {
278 /* Avoid additional syscall restarting via ret_from_exception */
279 regs->scause = -1UL;
280
275 /* Restart the system call - no handlers present */ 281 /* Restart the system call - no handlers present */
276 switch (regs->a0) { 282 switch (regs->a0) {
277 case -ERESTARTNOHAND: 283 case -ERESTARTNOHAND:
diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index 0c41d07ec281..b2537ffa855c 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -42,7 +42,7 @@ unsigned long __cpuid_to_hartid_map[NR_CPUS] = {
42 42
43void __init smp_setup_processor_id(void) 43void __init smp_setup_processor_id(void)
44{ 44{
45 cpuid_to_hartid_map(0) = boot_cpu_hartid; 45 cpuid_to_hartid_map(0) = boot_cpu_hartid;
46} 46}
47 47
48/* A collection of single bit ipi messages. */ 48/* A collection of single bit ipi messages. */
@@ -53,7 +53,7 @@ static struct {
53 53
54int riscv_hartid_to_cpuid(int hartid) 54int riscv_hartid_to_cpuid(int hartid)
55{ 55{
56 int i = -1; 56 int i;
57 57
58 for (i = 0; i < NR_CPUS; i++) 58 for (i = 0; i < NR_CPUS; i++)
59 if (cpuid_to_hartid_map(i) == hartid) 59 if (cpuid_to_hartid_map(i) == hartid)
@@ -70,6 +70,12 @@ void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out)
70 for_each_cpu(cpu, in) 70 for_each_cpu(cpu, in)
71 cpumask_set_cpu(cpuid_to_hartid_map(cpu), out); 71 cpumask_set_cpu(cpuid_to_hartid_map(cpu), out);
72} 72}
73
74bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
75{
76 return phys_id == cpuid_to_hartid_map(cpu);
77}
78
73/* Unsupported */ 79/* Unsupported */
74int setup_profiling_timer(unsigned int multiplier) 80int setup_profiling_timer(unsigned int multiplier)
75{ 81{
@@ -89,7 +95,7 @@ void riscv_software_interrupt(void)
89 unsigned long *stats = ipi_data[smp_processor_id()].stats; 95 unsigned long *stats = ipi_data[smp_processor_id()].stats;
90 96
91 /* Clear pending IPI */ 97 /* Clear pending IPI */
92 csr_clear(sip, SIE_SSIE); 98 csr_clear(CSR_SIP, SIE_SSIE);
93 99
94 while (true) { 100 while (true) {
95 unsigned long ops; 101 unsigned long ops;
@@ -199,52 +205,3 @@ void smp_send_reschedule(int cpu)
199 send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); 205 send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE);
200} 206}
201 207
202/*
203 * Performs an icache flush for the given MM context. RISC-V has no direct
204 * mechanism for instruction cache shoot downs, so instead we send an IPI that
205 * informs the remote harts they need to flush their local instruction caches.
206 * To avoid pathologically slow behavior in a common case (a bunch of
207 * single-hart processes on a many-hart machine, ie 'make -j') we avoid the
208 * IPIs for harts that are not currently executing a MM context and instead
209 * schedule a deferred local instruction cache flush to be performed before
210 * execution resumes on each hart.
211 */
212void flush_icache_mm(struct mm_struct *mm, bool local)
213{
214 unsigned int cpu;
215 cpumask_t others, hmask, *mask;
216
217 preempt_disable();
218
219 /* Mark every hart's icache as needing a flush for this MM. */
220 mask = &mm->context.icache_stale_mask;
221 cpumask_setall(mask);
222 /* Flush this hart's I$ now, and mark it as flushed. */
223 cpu = smp_processor_id();
224 cpumask_clear_cpu(cpu, mask);
225 local_flush_icache_all();
226
227 /*
228 * Flush the I$ of other harts concurrently executing, and mark them as
229 * flushed.
230 */
231 cpumask_andnot(&others, mm_cpumask(mm), cpumask_of(cpu));
232 local |= cpumask_empty(&others);
233 if (mm != current->active_mm || !local) {
234 cpumask_clear(&hmask);
235 riscv_cpuid_to_hartid_mask(&others, &hmask);
236 sbi_remote_fence_i(hmask.bits);
237 } else {
238 /*
239 * It's assumed that at least one strongly ordered operation is
240 * performed on this hart between setting a hart's cpumask bit
241 * and scheduling this MM context on that hart. Sending an SBI
242 * remote message will do this, but in the case where no
243 * messages are sent we still need to order this hart's writes
244 * with flush_icache_deferred().
245 */
246 smp_mb();
247 }
248
249 preempt_enable();
250}
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index eb533b5c2c8c..7a0b62252524 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -47,6 +47,17 @@ void __init smp_prepare_boot_cpu(void)
47 47
48void __init smp_prepare_cpus(unsigned int max_cpus) 48void __init smp_prepare_cpus(unsigned int max_cpus)
49{ 49{
50 int cpuid;
51
52 /* This covers non-smp usecase mandated by "nosmp" option */
53 if (max_cpus == 0)
54 return;
55
56 for_each_possible_cpu(cpuid) {
57 if (cpuid == smp_processor_id())
58 continue;
59 set_cpu_present(cpuid, true);
60 }
50} 61}
51 62
52void __init setup_smp(void) 63void __init setup_smp(void)
@@ -73,12 +84,19 @@ void __init setup_smp(void)
73 } 84 }
74 85
75 cpuid_to_hartid_map(cpuid) = hart; 86 cpuid_to_hartid_map(cpuid) = hart;
76 set_cpu_possible(cpuid, true);
77 set_cpu_present(cpuid, true);
78 cpuid++; 87 cpuid++;
79 } 88 }
80 89
81 BUG_ON(!found_boot_cpu); 90 BUG_ON(!found_boot_cpu);
91
92 if (cpuid > nr_cpu_ids)
93 pr_warn("Total number of cpus [%d] is greater than nr_cpus option value [%d]\n",
94 cpuid, nr_cpu_ids);
95
96 for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) {
97 if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID)
98 set_cpu_possible(cpuid, true);
99 }
82} 100}
83 101
84int __cpu_up(unsigned int cpu, struct task_struct *tidle) 102int __cpu_up(unsigned int cpu, struct task_struct *tidle)
diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
index 4d403274c2e8..e80a5e8da119 100644
--- a/arch/riscv/kernel/stacktrace.c
+++ b/arch/riscv/kernel/stacktrace.c
@@ -33,9 +33,9 @@ static void notrace walk_stackframe(struct task_struct *task,
33 unsigned long fp, sp, pc; 33 unsigned long fp, sp, pc;
34 34
35 if (regs) { 35 if (regs) {
36 fp = GET_FP(regs); 36 fp = frame_pointer(regs);
37 sp = GET_USP(regs); 37 sp = user_stack_pointer(regs);
38 pc = GET_IP(regs); 38 pc = instruction_pointer(regs);
39 } else if (task == NULL || task == current) { 39 } else if (task == NULL || task == current) {
40 const register unsigned long current_sp __asm__ ("sp"); 40 const register unsigned long current_sp __asm__ ("sp");
41 fp = (unsigned long)__builtin_frame_address(0); 41 fp = (unsigned long)__builtin_frame_address(0);
@@ -64,12 +64,8 @@ static void notrace walk_stackframe(struct task_struct *task,
64 frame = (struct stackframe *)fp - 1; 64 frame = (struct stackframe *)fp - 1;
65 sp = fp; 65 sp = fp;
66 fp = frame->fp; 66 fp = frame->fp;
67#ifdef HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
68 pc = ftrace_graph_ret_addr(current, NULL, frame->ra, 67 pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
69 (unsigned long *)(fp - 8)); 68 (unsigned long *)(fp - 8));
70#else
71 pc = frame->ra - 0x4;
72#endif
73 } 69 }
74} 70}
75 71
@@ -82,8 +78,8 @@ static void notrace walk_stackframe(struct task_struct *task,
82 unsigned long *ksp; 78 unsigned long *ksp;
83 79
84 if (regs) { 80 if (regs) {
85 sp = GET_USP(regs); 81 sp = user_stack_pointer(regs);
86 pc = GET_IP(regs); 82 pc = instruction_pointer(regs);
87 } else if (task == NULL || task == current) { 83 } else if (task == NULL || task == current) {
88 const register unsigned long current_sp __asm__ ("sp"); 84 const register unsigned long current_sp __asm__ ("sp");
89 sp = current_sp; 85 sp = current_sp;
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 24a9333dda2c..3d1a651dc54c 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -70,7 +70,7 @@ void do_trap(struct pt_regs *regs, int signo, int code,
70 && printk_ratelimit()) { 70 && printk_ratelimit()) {
71 pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x" REG_FMT, 71 pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x" REG_FMT,
72 tsk->comm, task_pid_nr(tsk), signo, code, addr); 72 tsk->comm, task_pid_nr(tsk), signo, code, addr);
73 print_vma_addr(KERN_CONT " in ", GET_IP(regs)); 73 print_vma_addr(KERN_CONT " in ", instruction_pointer(regs));
74 pr_cont("\n"); 74 pr_cont("\n");
75 show_regs(regs); 75 show_regs(regs);
76 } 76 }
@@ -118,6 +118,17 @@ DO_ERROR_INFO(do_trap_ecall_s,
118DO_ERROR_INFO(do_trap_ecall_m, 118DO_ERROR_INFO(do_trap_ecall_m,
119 SIGILL, ILL_ILLTRP, "environment call from M-mode"); 119 SIGILL, ILL_ILLTRP, "environment call from M-mode");
120 120
121#ifdef CONFIG_GENERIC_BUG
122static inline unsigned long get_break_insn_length(unsigned long pc)
123{
124 bug_insn_t insn;
125
126 if (probe_kernel_address((bug_insn_t *)pc, insn))
127 return 0;
128 return (((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ? 4UL : 2UL);
129}
130#endif /* CONFIG_GENERIC_BUG */
131
121asmlinkage void do_trap_break(struct pt_regs *regs) 132asmlinkage void do_trap_break(struct pt_regs *regs)
122{ 133{
123#ifdef CONFIG_GENERIC_BUG 134#ifdef CONFIG_GENERIC_BUG
@@ -129,8 +140,8 @@ asmlinkage void do_trap_break(struct pt_regs *regs)
129 case BUG_TRAP_TYPE_NONE: 140 case BUG_TRAP_TYPE_NONE:
130 break; 141 break;
131 case BUG_TRAP_TYPE_WARN: 142 case BUG_TRAP_TYPE_WARN:
132 regs->sepc += sizeof(bug_insn_t); 143 regs->sepc += get_break_insn_length(regs->sepc);
133 return; 144 break;
134 case BUG_TRAP_TYPE_BUG: 145 case BUG_TRAP_TYPE_BUG:
135 die(regs, "Kernel BUG"); 146 die(regs, "Kernel BUG");
136 } 147 }
@@ -145,11 +156,14 @@ int is_valid_bugaddr(unsigned long pc)
145{ 156{
146 bug_insn_t insn; 157 bug_insn_t insn;
147 158
148 if (pc < PAGE_OFFSET) 159 if (pc < VMALLOC_START)
149 return 0; 160 return 0;
150 if (probe_kernel_address((bug_insn_t *)pc, insn)) 161 if (probe_kernel_address((bug_insn_t *)pc, insn))
151 return 0; 162 return 0;
152 return (insn == __BUG_INSN); 163 if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32)
164 return (insn == __BUG_INSN_32);
165 else
166 return ((insn & __COMPRESSED_INSN_MASK) == __BUG_INSN_16);
153} 167}
154#endif /* CONFIG_GENERIC_BUG */ 168#endif /* CONFIG_GENERIC_BUG */
155 169
@@ -159,9 +173,9 @@ void __init trap_init(void)
159 * Set sup0 scratch register to 0, indicating to exception vector 173 * Set sup0 scratch register to 0, indicating to exception vector
160 * that we are presently executing in the kernel 174 * that we are presently executing in the kernel
161 */ 175 */
162 csr_write(sscratch, 0); 176 csr_write(CSR_SSCRATCH, 0);
163 /* Set the exception vector address */ 177 /* Set the exception vector address */
164 csr_write(stvec, &handle_exception); 178 csr_write(CSR_STVEC, &handle_exception);
165 /* Enable all interrupts */ 179 /* Enable all interrupts */
166 csr_write(sie, -1); 180 csr_write(CSR_SIE, -1);
167} 181}
diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
index fec62b24df89..b07b765f312a 100644
--- a/arch/riscv/kernel/vdso/Makefile
+++ b/arch/riscv/kernel/vdso/Makefile
@@ -36,7 +36,7 @@ $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE
36# these symbols in the kernel code rather than hand-coded addresses. 36# these symbols in the kernel code rather than hand-coded addresses.
37 37
38SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ 38SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \
39 $(call cc-ldoption, -Wl$(comma)--hash-style=both) 39 -Wl,--hash-style=both
40$(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE 40$(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE
41 $(call if_changed,vdsold) 41 $(call if_changed,vdsold)
42 42
diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index b68aac701803..8db569141485 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -9,3 +9,5 @@ obj-y += fault.o
9obj-y += extable.o 9obj-y += extable.o
10obj-y += ioremap.o 10obj-y += ioremap.o
11obj-y += cacheflush.o 11obj-y += cacheflush.o
12obj-y += context.o
13obj-y += sifive_l2_cache.o
diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
index 498c0a0814fe..497b7d07af0c 100644
--- a/arch/riscv/mm/cacheflush.c
+++ b/arch/riscv/mm/cacheflush.c
@@ -14,6 +14,67 @@
14#include <asm/pgtable.h> 14#include <asm/pgtable.h>
15#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
16 16
17#ifdef CONFIG_SMP
18
19#include <asm/sbi.h>
20
21void flush_icache_all(void)
22{
23 sbi_remote_fence_i(NULL);
24}
25
26/*
27 * Performs an icache flush for the given MM context. RISC-V has no direct
28 * mechanism for instruction cache shoot downs, so instead we send an IPI that
29 * informs the remote harts they need to flush their local instruction caches.
30 * To avoid pathologically slow behavior in a common case (a bunch of
31 * single-hart processes on a many-hart machine, ie 'make -j') we avoid the
32 * IPIs for harts that are not currently executing a MM context and instead
33 * schedule a deferred local instruction cache flush to be performed before
34 * execution resumes on each hart.
35 */
36void flush_icache_mm(struct mm_struct *mm, bool local)
37{
38 unsigned int cpu;
39 cpumask_t others, hmask, *mask;
40
41 preempt_disable();
42
43 /* Mark every hart's icache as needing a flush for this MM. */
44 mask = &mm->context.icache_stale_mask;
45 cpumask_setall(mask);
46 /* Flush this hart's I$ now, and mark it as flushed. */
47 cpu = smp_processor_id();
48 cpumask_clear_cpu(cpu, mask);
49 local_flush_icache_all();
50
51 /*
52 * Flush the I$ of other harts concurrently executing, and mark them as
53 * flushed.
54 */
55 cpumask_andnot(&others, mm_cpumask(mm), cpumask_of(cpu));
56 local |= cpumask_empty(&others);
57 if (mm != current->active_mm || !local) {
58 cpumask_clear(&hmask);
59 riscv_cpuid_to_hartid_mask(&others, &hmask);
60 sbi_remote_fence_i(hmask.bits);
61 } else {
62 /*
63 * It's assumed that at least one strongly ordered operation is
64 * performed on this hart between setting a hart's cpumask bit
65 * and scheduling this MM context on that hart. Sending an SBI
66 * remote message will do this, but in the case where no
67 * messages are sent we still need to order this hart's writes
68 * with flush_icache_deferred().
69 */
70 smp_mb();
71 }
72
73 preempt_enable();
74}
75
76#endif /* CONFIG_SMP */
77
17void flush_icache_pte(pte_t pte) 78void flush_icache_pte(pte_t pte)
18{ 79{
19 struct page *page = pte_page(pte); 80 struct page *page = pte_page(pte);
diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
new file mode 100644
index 000000000000..89ceb3cbe218
--- /dev/null
+++ b/arch/riscv/mm/context.c
@@ -0,0 +1,69 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2012 Regents of the University of California
4 * Copyright (C) 2017 SiFive
5 */
6
7#include <linux/mm.h>
8#include <asm/tlbflush.h>
9#include <asm/cacheflush.h>
10
11/*
12 * When necessary, performs a deferred icache flush for the given MM context,
13 * on the local CPU. RISC-V has no direct mechanism for instruction cache
14 * shoot downs, so instead we send an IPI that informs the remote harts they
15 * need to flush their local instruction caches. To avoid pathologically slow
16 * behavior in a common case (a bunch of single-hart processes on a many-hart
17 * machine, ie 'make -j') we avoid the IPIs for harts that are not currently
18 * executing a MM context and instead schedule a deferred local instruction
19 * cache flush to be performed before execution resumes on each hart. This
20 * actually performs that local instruction cache flush, which implicitly only
21 * refers to the current hart.
22 */
23static inline void flush_icache_deferred(struct mm_struct *mm)
24{
25#ifdef CONFIG_SMP
26 unsigned int cpu = smp_processor_id();
27 cpumask_t *mask = &mm->context.icache_stale_mask;
28
29 if (cpumask_test_cpu(cpu, mask)) {
30 cpumask_clear_cpu(cpu, mask);
31 /*
32 * Ensure the remote hart's writes are visible to this hart.
33 * This pairs with a barrier in flush_icache_mm.
34 */
35 smp_mb();
36 local_flush_icache_all();
37 }
38
39#endif
40}
41
42void switch_mm(struct mm_struct *prev, struct mm_struct *next,
43 struct task_struct *task)
44{
45 unsigned int cpu;
46
47 if (unlikely(prev == next))
48 return;
49
50 /*
51 * Mark the current MM context as inactive, and the next as
52 * active. This is at least used by the icache flushing
53 * routines in order to determine who should be flushed.
54 */
55 cpu = smp_processor_id();
56
57 cpumask_clear_cpu(cpu, mm_cpumask(prev));
58 cpumask_set_cpu(cpu, mm_cpumask(next));
59
60 /*
61 * Use the old spbtr name instead of using the current satp
62 * name to support binutils 2.29 which doesn't know about the
63 * privileged ISA 1.10 yet.
64 */
65 csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE);
66 local_flush_tlb_all();
67
68 flush_icache_deferred(next);
69}
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index 88401d5125bc..cec8be9e2d6a 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -229,8 +229,9 @@ vmalloc_fault:
229 pte_t *pte_k; 229 pte_t *pte_k;
230 int index; 230 int index;
231 231
232 /* User mode accesses just cause a SIGSEGV */
232 if (user_mode(regs)) 233 if (user_mode(regs))
233 goto bad_area; 234 return do_trap(regs, SIGSEGV, code, addr, tsk);
234 235
235 /* 236 /*
236 * Synchronize this task's top level page-table 237 * Synchronize this task's top level page-table
@@ -239,13 +240,9 @@ vmalloc_fault:
239 * Do _not_ use "tsk->active_mm->pgd" here. 240 * Do _not_ use "tsk->active_mm->pgd" here.
240 * We might be inside an interrupt in the middle 241 * We might be inside an interrupt in the middle
241 * of a task switch. 242 * of a task switch.
242 *
243 * Note: Use the old spbtr name instead of using the current
244 * satp name to support binutils 2.29 which doesn't know about
245 * the privileged ISA 1.10 yet.
246 */ 243 */
247 index = pgd_index(addr); 244 index = pgd_index(addr);
248 pgd = (pgd_t *)pfn_to_virt(csr_read(sptbr)) + index; 245 pgd = (pgd_t *)pfn_to_virt(csr_read(CSR_SATP)) + index;
249 pgd_k = init_mm.pgd + index; 246 pgd_k = init_mm.pgd + index;
250 247
251 if (!pgd_present(*pgd_k)) 248 if (!pgd_present(*pgd_k))
diff --git a/arch/riscv/mm/sifive_l2_cache.c b/arch/riscv/mm/sifive_l2_cache.c
new file mode 100644
index 000000000000..4eb64619b3f4
--- /dev/null
+++ b/arch/riscv/mm/sifive_l2_cache.c
@@ -0,0 +1,175 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * SiFive L2 cache controller Driver
4 *
5 * Copyright (C) 2018-2019 SiFive, Inc.
6 *
7 */
8#include <linux/debugfs.h>
9#include <linux/interrupt.h>
10#include <linux/of_irq.h>
11#include <linux/of_address.h>
12#include <asm/sifive_l2_cache.h>
13
14#define SIFIVE_L2_DIRECCFIX_LOW 0x100
15#define SIFIVE_L2_DIRECCFIX_HIGH 0x104
16#define SIFIVE_L2_DIRECCFIX_COUNT 0x108
17
18#define SIFIVE_L2_DATECCFIX_LOW 0x140
19#define SIFIVE_L2_DATECCFIX_HIGH 0x144
20#define SIFIVE_L2_DATECCFIX_COUNT 0x148
21
22#define SIFIVE_L2_DATECCFAIL_LOW 0x160
23#define SIFIVE_L2_DATECCFAIL_HIGH 0x164
24#define SIFIVE_L2_DATECCFAIL_COUNT 0x168
25
26#define SIFIVE_L2_CONFIG 0x00
27#define SIFIVE_L2_WAYENABLE 0x08
28#define SIFIVE_L2_ECCINJECTERR 0x40
29
30#define SIFIVE_L2_MAX_ECCINTR 3
31
32static void __iomem *l2_base;
33static int g_irq[SIFIVE_L2_MAX_ECCINTR];
34
35enum {
36 DIR_CORR = 0,
37 DATA_CORR,
38 DATA_UNCORR,
39};
40
41#ifdef CONFIG_DEBUG_FS
42static struct dentry *sifive_test;
43
44static ssize_t l2_write(struct file *file, const char __user *data,
45 size_t count, loff_t *ppos)
46{
47 unsigned int val;
48
49 if (kstrtouint_from_user(data, count, 0, &val))
50 return -EINVAL;
51 if ((val >= 0 && val < 0xFF) || (val >= 0x10000 && val < 0x100FF))
52 writel(val, l2_base + SIFIVE_L2_ECCINJECTERR);
53 else
54 return -EINVAL;
55 return count;
56}
57
58static const struct file_operations l2_fops = {
59 .owner = THIS_MODULE,
60 .open = simple_open,
61 .write = l2_write
62};
63
64static void setup_sifive_debug(void)
65{
66 sifive_test = debugfs_create_dir("sifive_l2_cache", NULL);
67
68 debugfs_create_file("sifive_debug_inject_error", 0200,
69 sifive_test, NULL, &l2_fops);
70}
71#endif
72
73static void l2_config_read(void)
74{
75 u32 regval, val;
76
77 regval = readl(l2_base + SIFIVE_L2_CONFIG);
78 val = regval & 0xFF;
79 pr_info("L2CACHE: No. of Banks in the cache: %d\n", val);
80 val = (regval & 0xFF00) >> 8;
81 pr_info("L2CACHE: No. of ways per bank: %d\n", val);
82 val = (regval & 0xFF0000) >> 16;
83 pr_info("L2CACHE: Sets per bank: %llu\n", (uint64_t)1 << val);
84 val = (regval & 0xFF000000) >> 24;
85 pr_info("L2CACHE: Bytes per cache block: %llu\n", (uint64_t)1 << val);
86
87 regval = readl(l2_base + SIFIVE_L2_WAYENABLE);
88 pr_info("L2CACHE: Index of the largest way enabled: %d\n", regval);
89}
90
91static const struct of_device_id sifive_l2_ids[] = {
92 { .compatible = "sifive,fu540-c000-ccache" },
93 { /* end of table */ },
94};
95
96static ATOMIC_NOTIFIER_HEAD(l2_err_chain);
97
98int register_sifive_l2_error_notifier(struct notifier_block *nb)
99{
100 return atomic_notifier_chain_register(&l2_err_chain, nb);
101}
102EXPORT_SYMBOL_GPL(register_sifive_l2_error_notifier);
103
104int unregister_sifive_l2_error_notifier(struct notifier_block *nb)
105{
106 return atomic_notifier_chain_unregister(&l2_err_chain, nb);
107}
108EXPORT_SYMBOL_GPL(unregister_sifive_l2_error_notifier);
109
110static irqreturn_t l2_int_handler(int irq, void *device)
111{
112 unsigned int regval, add_h, add_l;
113
114 if (irq == g_irq[DIR_CORR]) {
115 add_h = readl(l2_base + SIFIVE_L2_DIRECCFIX_HIGH);
116 add_l = readl(l2_base + SIFIVE_L2_DIRECCFIX_LOW);
117 pr_err("L2CACHE: DirError @ 0x%08X.%08X\n", add_h, add_l);
118 regval = readl(l2_base + SIFIVE_L2_DIRECCFIX_COUNT);
119 atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE,
120 "DirECCFix");
121 }
122 if (irq == g_irq[DATA_CORR]) {
123 add_h = readl(l2_base + SIFIVE_L2_DATECCFIX_HIGH);
124 add_l = readl(l2_base + SIFIVE_L2_DATECCFIX_LOW);
125 pr_err("L2CACHE: DataError @ 0x%08X.%08X\n", add_h, add_l);
126 regval = readl(l2_base + SIFIVE_L2_DATECCFIX_COUNT);
127 atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE,
128 "DatECCFix");
129 }
130 if (irq == g_irq[DATA_UNCORR]) {
131 add_h = readl(l2_base + SIFIVE_L2_DATECCFAIL_HIGH);
132 add_l = readl(l2_base + SIFIVE_L2_DATECCFAIL_LOW);
133 pr_err("L2CACHE: DataFail @ 0x%08X.%08X\n", add_h, add_l);
134 regval = readl(l2_base + SIFIVE_L2_DATECCFAIL_COUNT);
135 atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE,
136 "DatECCFail");
137 }
138
139 return IRQ_HANDLED;
140}
141
142int __init sifive_l2_init(void)
143{
144 struct device_node *np;
145 struct resource res;
146 int i, rc;
147
148 np = of_find_matching_node(NULL, sifive_l2_ids);
149 if (!np)
150 return -ENODEV;
151
152 if (of_address_to_resource(np, 0, &res))
153 return -ENODEV;
154
155 l2_base = ioremap(res.start, resource_size(&res));
156 if (!l2_base)
157 return -ENOMEM;
158
159 for (i = 0; i < SIFIVE_L2_MAX_ECCINTR; i++) {
160 g_irq[i] = irq_of_parse_and_map(np, i);
161 rc = request_irq(g_irq[i], l2_int_handler, 0, "l2_ecc", NULL);
162 if (rc) {
163 pr_err("L2CACHE: Could not request IRQ %d\n", g_irq[i]);
164 return rc;
165 }
166 }
167
168 l2_config_read();
169
170#ifdef CONFIG_DEBUG_FS
171 setup_sifive_debug();
172#endif
173 return 0;
174}
175device_initcall(sifive_l2_init);
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 4009bef62fe9..b4a86f27e048 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -191,8 +191,8 @@ cpuincdir-y += cpu-common # Must be last
191drivers-y += arch/sh/drivers/ 191drivers-y += arch/sh/drivers/
192drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/ 192drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/
193 193
194cflags-y += $(foreach d, $(cpuincdir-y), -Iarch/sh/include/$(d)) \ 194cflags-y += $(foreach d, $(cpuincdir-y), -I $(srctree)/arch/sh/include/$(d)) \
195 $(foreach d, $(machdir-y), -Iarch/sh/include/$(d)) 195 $(foreach d, $(machdir-y), -I $(srctree)/arch/sh/include/$(d))
196 196
197KBUILD_CFLAGS += -pipe $(cflags-y) 197KBUILD_CFLAGS += -pipe $(cflags-y)
198KBUILD_CPPFLAGS += $(cflags-y) 198KBUILD_CPPFLAGS += $(cflags-y)
diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore
index 541087d2029c..f50fdd9975c5 100644
--- a/arch/sh/boot/.gitignore
+++ b/arch/sh/boot/.gitignore
@@ -1,3 +1,4 @@
1zImage 1zImage
2vmlinux* 2vmlinux*
3uImage* 3uImage*
4!vmlinux.scr
diff --git a/arch/sh/kernel/vsyscall/Makefile b/arch/sh/kernel/vsyscall/Makefile
index 5db6579bc44c..6e8664448048 100644
--- a/arch/sh/kernel/vsyscall/Makefile
+++ b/arch/sh/kernel/vsyscall/Makefile
@@ -15,8 +15,7 @@ quiet_cmd_syscall = SYSCALL $@
15 15
16export CPPFLAGS_vsyscall.lds += -P -C -Ush 16export CPPFLAGS_vsyscall.lds += -P -C -Ush
17 17
18vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \ 18vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 -Wl,--hash-style=sysv
19 $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
20 19
21SYSCFLAGS_vsyscall-trapa.so = $(vsyscall-flags) 20SYSCFLAGS_vsyscall-trapa.so = $(vsyscall-flags)
22 21
diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h
index fca34b2177e2..9f4b4bb78120 100644
--- a/arch/um/include/asm/mmu_context.h
+++ b/arch/um/include/asm/mmu_context.h
@@ -22,7 +22,6 @@ static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
22} 22}
23extern void arch_exit_mmap(struct mm_struct *mm); 23extern void arch_exit_mmap(struct mm_struct *mm);
24static inline void arch_unmap(struct mm_struct *mm, 24static inline void arch_unmap(struct mm_struct *mm,
25 struct vm_area_struct *vma,
26 unsigned long start, unsigned long end) 25 unsigned long start, unsigned long end)
27{ 26{
28} 27}
diff --git a/arch/unicore32/include/asm/mmu_context.h b/arch/unicore32/include/asm/mmu_context.h
index 5c205a9cb5a6..9f06ea5466dd 100644
--- a/arch/unicore32/include/asm/mmu_context.h
+++ b/arch/unicore32/include/asm/mmu_context.h
@@ -88,7 +88,6 @@ static inline int arch_dup_mmap(struct mm_struct *oldmm,
88} 88}
89 89
90static inline void arch_unmap(struct mm_struct *mm, 90static inline void arch_unmap(struct mm_struct *mm,
91 struct vm_area_struct *vma,
92 unsigned long start, unsigned long end) 91 unsigned long start, unsigned long end)
93{ 92{
94} 93}
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 93dff1963337..9024236693d2 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -278,8 +278,8 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm,
278 mpx_mm_init(mm); 278 mpx_mm_init(mm);
279} 279}
280 280
281static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, 281static inline void arch_unmap(struct mm_struct *mm, unsigned long start,
282 unsigned long start, unsigned long end) 282 unsigned long end)
283{ 283{
284 /* 284 /*
285 * mpx_notify_unmap() goes and reads a rarely-hot 285 * mpx_notify_unmap() goes and reads a rarely-hot
@@ -299,7 +299,7 @@ static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
299 * consistently wrong. 299 * consistently wrong.
300 */ 300 */
301 if (unlikely(cpu_feature_enabled(X86_FEATURE_MPX))) 301 if (unlikely(cpu_feature_enabled(X86_FEATURE_MPX)))
302 mpx_notify_unmap(mm, vma, start, end); 302 mpx_notify_unmap(mm, start, end);
303} 303}
304 304
305/* 305/*
diff --git a/arch/x86/include/asm/mpx.h b/arch/x86/include/asm/mpx.h
index d0b1434fb0b6..143a5c193ed3 100644
--- a/arch/x86/include/asm/mpx.h
+++ b/arch/x86/include/asm/mpx.h
@@ -64,12 +64,15 @@ struct mpx_fault_info {
64}; 64};
65 65
66#ifdef CONFIG_X86_INTEL_MPX 66#ifdef CONFIG_X86_INTEL_MPX
67int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs); 67
68int mpx_handle_bd_fault(void); 68extern int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs);
69extern int mpx_handle_bd_fault(void);
70
69static inline int kernel_managing_mpx_tables(struct mm_struct *mm) 71static inline int kernel_managing_mpx_tables(struct mm_struct *mm)
70{ 72{
71 return (mm->context.bd_addr != MPX_INVALID_BOUNDS_DIR); 73 return (mm->context.bd_addr != MPX_INVALID_BOUNDS_DIR);
72} 74}
75
73static inline void mpx_mm_init(struct mm_struct *mm) 76static inline void mpx_mm_init(struct mm_struct *mm)
74{ 77{
75 /* 78 /*
@@ -78,11 +81,10 @@ static inline void mpx_mm_init(struct mm_struct *mm)
78 */ 81 */
79 mm->context.bd_addr = MPX_INVALID_BOUNDS_DIR; 82 mm->context.bd_addr = MPX_INVALID_BOUNDS_DIR;
80} 83}
81void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
82 unsigned long start, unsigned long end);
83 84
84unsigned long mpx_unmapped_area_check(unsigned long addr, unsigned long len, 85extern void mpx_notify_unmap(struct mm_struct *mm, unsigned long start, unsigned long end);
85 unsigned long flags); 86extern unsigned long mpx_unmapped_area_check(unsigned long addr, unsigned long len, unsigned long flags);
87
86#else 88#else
87static inline int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs) 89static inline int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs)
88{ 90{
@@ -100,7 +102,6 @@ static inline void mpx_mm_init(struct mm_struct *mm)
100{ 102{
101} 103}
102static inline void mpx_notify_unmap(struct mm_struct *mm, 104static inline void mpx_notify_unmap(struct mm_struct *mm,
103 struct vm_area_struct *vma,
104 unsigned long start, unsigned long end) 105 unsigned long start, unsigned long end)
105{ 106{
106} 107}
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 00b7e27bc2b7..ce1b5cc360a2 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -42,7 +42,7 @@ endif
42# non-deterministic coverage. 42# non-deterministic coverage.
43KCOV_INSTRUMENT := n 43KCOV_INSTRUMENT := n
44 44
45CFLAGS_irq.o := -I$(src)/../include/asm/trace 45CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace
46 46
47obj-y := process_$(BITS).o signal.o 47obj-y := process_$(BITS).o signal.o
48obj-$(CONFIG_COMPAT) += signal_compat.o 48obj-$(CONFIG_COMPAT) += signal_compat.o
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 4b101dd6e52f..84373dc9b341 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -21,7 +21,7 @@ CFLAGS_physaddr.o := $(nostackp)
21CFLAGS_setup_nx.o := $(nostackp) 21CFLAGS_setup_nx.o := $(nostackp)
22CFLAGS_mem_encrypt_identity.o := $(nostackp) 22CFLAGS_mem_encrypt_identity.o := $(nostackp)
23 23
24CFLAGS_fault.o := -I$(src)/../include/asm/trace 24CFLAGS_fault.o := -I $(srctree)/$(src)/../include/asm/trace
25 25
26obj-$(CONFIG_X86_PAT) += pat_rbtree.o 26obj-$(CONFIG_X86_PAT) += pat_rbtree.o
27 27
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index 59726aaf4671..0d1c47cbbdd6 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -881,9 +881,10 @@ static int mpx_unmap_tables(struct mm_struct *mm,
881 * the virtual address region start...end have already been split if 881 * the virtual address region start...end have already been split if
882 * necessary, and the 'vma' is the first vma in this range (start -> end). 882 * necessary, and the 'vma' is the first vma in this range (start -> end).
883 */ 883 */
884void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma, 884void mpx_notify_unmap(struct mm_struct *mm, unsigned long start,
885 unsigned long start, unsigned long end) 885 unsigned long end)
886{ 886{
887 struct vm_area_struct *vma;
887 int ret; 888 int ret;
888 889
889 /* 890 /*
@@ -902,11 +903,12 @@ void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
902 * which should not occur normally. Being strict about it here 903 * which should not occur normally. Being strict about it here
903 * helps ensure that we do not have an exploitable stack overflow. 904 * helps ensure that we do not have an exploitable stack overflow.
904 */ 905 */
905 do { 906 vma = find_vma(mm, start);
907 while (vma && vma->vm_start < end) {
906 if (vma->vm_flags & VM_MPX) 908 if (vma->vm_flags & VM_MPX)
907 return; 909 return;
908 vma = vma->vm_next; 910 vma = vma->vm_next;
909 } while (vma && vma->vm_start < end); 911 }
910 912
911 ret = mpx_unmap_tables(mm, start, end); 913 ret = mpx_unmap_tables(mm, start, end);
912 if (ret) 914 if (ret)
diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile
index 355127faade1..e3d717c7bfa1 100644
--- a/arch/xtensa/boot/lib/Makefile
+++ b/arch/xtensa/boot/lib/Makefile
@@ -7,7 +7,7 @@ zlib := inffast.c inflate.c inftrees.c
7 7
8lib-y += $(zlib:.c=.o) zmem.o 8lib-y += $(zlib:.c=.o) zmem.o
9 9
10ccflags-y := -Ilib/zlib_inflate 10ccflags-y := -I $(srctree)/lib/zlib_inflate
11ifdef CONFIG_FUNCTION_TRACER 11ifdef CONFIG_FUNCTION_TRACER
12CFLAGS_REMOVE_inflate.o = -pg 12CFLAGS_REMOVE_inflate.o = -pg
13CFLAGS_REMOVE_zmem.o = -pg 13CFLAGS_REMOVE_zmem.o = -pg
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
index 35f83c4bf239..f1686d919178 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -27,7 +27,6 @@ generic-y += preempt.h
27generic-y += qrwlock.h 27generic-y += qrwlock.h
28generic-y += qspinlock.h 28generic-y += qspinlock.h
29generic-y += sections.h 29generic-y += sections.h
30generic-y += socket.h
31generic-y += topology.h 30generic-y += topology.h
32generic-y += trace_clock.h 31generic-y += trace_clock.h
33generic-y += vga.h 32generic-y += vga.h
diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c
index b0b688c481e8..3751d811be39 100644
--- a/drivers/amba/tegra-ahb.c
+++ b/drivers/amba/tegra-ahb.c
@@ -170,8 +170,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn)
170EXPORT_SYMBOL(tegra_ahb_enable_smmu); 170EXPORT_SYMBOL(tegra_ahb_enable_smmu);
171#endif 171#endif
172 172
173#ifdef CONFIG_PM 173static int __maybe_unused tegra_ahb_suspend(struct device *dev)
174static int tegra_ahb_suspend(struct device *dev)
175{ 174{
176 int i; 175 int i;
177 struct tegra_ahb *ahb = dev_get_drvdata(dev); 176 struct tegra_ahb *ahb = dev_get_drvdata(dev);
@@ -181,7 +180,7 @@ static int tegra_ahb_suspend(struct device *dev)
181 return 0; 180 return 0;
182} 181}
183 182
184static int tegra_ahb_resume(struct device *dev) 183static int __maybe_unused tegra_ahb_resume(struct device *dev)
185{ 184{
186 int i; 185 int i;
187 struct tegra_ahb *ahb = dev_get_drvdata(dev); 186 struct tegra_ahb *ahb = dev_get_drvdata(dev);
@@ -190,7 +189,6 @@ static int tegra_ahb_resume(struct device *dev)
190 gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]); 189 gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]);
191 return 0; 190 return 0;
192} 191}
193#endif
194 192
195static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm, 193static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm,
196 tegra_ahb_suspend, 194 tegra_ahb_suspend,
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 48321488f0fd..6bcaa4e2e72c 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -387,7 +387,7 @@ config ARM_GLOBAL_TIMER
387 This options enables support for the ARM global timer unit 387 This options enables support for the ARM global timer unit
388 388
389config ARM_TIMER_SP804 389config ARM_TIMER_SP804
390 bool "Support for Dual Timer SP804 module" 390 bool "Support for Dual Timer SP804 module" if COMPILE_TEST
391 depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP 391 depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP
392 select CLKSRC_MMIO 392 select CLKSRC_MMIO
393 select TIMER_OF if OF 393 select TIMER_OF if OF
@@ -407,8 +407,11 @@ config ARMV7M_SYSTICK
407 This options enables support for the ARMv7M system timer unit 407 This options enables support for the ARMv7M system timer unit
408 408
409config ATMEL_PIT 409config ATMEL_PIT
410 bool "Atmel PIT support" if COMPILE_TEST
411 depends on HAS_IOMEM
410 select TIMER_OF if OF 412 select TIMER_OF if OF
411 def_bool SOC_AT91SAM9 || SOC_SAMA5 413 help
414 Support for the Periodic Interval Timer found on Atmel SoCs.
412 415
413config ATMEL_ST 416config ATMEL_ST
414 bool "Atmel ST timer support" if COMPILE_TEST 417 bool "Atmel ST timer support" if COMPILE_TEST
@@ -418,6 +421,13 @@ config ATMEL_ST
418 help 421 help
419 Support for the Atmel ST timer. 422 Support for the Atmel ST timer.
420 423
424config ATMEL_TCB_CLKSRC
425 bool "Atmel TC Block timer driver" if COMPILE_TEST
426 depends on HAS_IOMEM
427 select TIMER_OF if OF
428 help
429 Support for Timer Counter Blocks on Atmel SoCs.
430
421config CLKSRC_EXYNOS_MCT 431config CLKSRC_EXYNOS_MCT
422 bool "Exynos multi core timer driver" if COMPILE_TEST 432 bool "Exynos multi core timer driver" if COMPILE_TEST
423 depends on ARM || ARM64 433 depends on ARM || ARM64
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index dba4eff880de..236858fa7fbf 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -3,7 +3,7 @@ obj-$(CONFIG_TIMER_OF) += timer-of.o
3obj-$(CONFIG_TIMER_PROBE) += timer-probe.o 3obj-$(CONFIG_TIMER_PROBE) += timer-probe.o
4obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o 4obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o
5obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o 5obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o
6obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o 6obj-$(CONFIG_ATMEL_TCB_CLKSRC) += timer-atmel-tcb.o
7obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o 7obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
8obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o 8obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
9obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += timer-cs5535.o 9obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += timer-cs5535.o
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/timer-atmel-tcb.c
index f987027ca566..6ed31f9def7e 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/timer-atmel-tcb.c
@@ -9,9 +9,11 @@
9#include <linux/err.h> 9#include <linux/err.h>
10#include <linux/ioport.h> 10#include <linux/ioport.h>
11#include <linux/io.h> 11#include <linux/io.h>
12#include <linux/platform_device.h> 12#include <linux/of_address.h>
13#include <linux/of_irq.h>
14#include <linux/sched_clock.h>
13#include <linux/syscore_ops.h> 15#include <linux/syscore_ops.h>
14#include <linux/atmel_tc.h> 16#include <soc/at91/atmel_tcb.h>
15 17
16 18
17/* 19/*
@@ -28,13 +30,6 @@
28 * source, used in either periodic or oneshot mode. This runs 30 * source, used in either periodic or oneshot mode. This runs
29 * at 32 KiHZ, and can handle delays of up to two seconds. 31 * at 32 KiHZ, and can handle delays of up to two seconds.
30 * 32 *
31 * A boot clocksource and clockevent source are also currently needed,
32 * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so
33 * this code can be used when init_timers() is called, well before most
34 * devices are set up. (Some low end AT91 parts, which can run uClinux,
35 * have only the timers in one TC block... they currently don't support
36 * the tclib code, because of that initialization issue.)
37 *
38 * REVISIT behavior during system suspend states... we should disable 33 * REVISIT behavior during system suspend states... we should disable
39 * all clocks and save the power. Easily done for clockevent devices, 34 * all clocks and save the power. Easily done for clockevent devices,
40 * but clocksources won't necessarily get the needed notifications. 35 * but clocksources won't necessarily get the needed notifications.
@@ -112,7 +107,6 @@ static void tc_clksrc_resume(struct clocksource *cs)
112} 107}
113 108
114static struct clocksource clksrc = { 109static struct clocksource clksrc = {
115 .name = "tcb_clksrc",
116 .rating = 200, 110 .rating = 200,
117 .read = tc_get_cycles, 111 .read = tc_get_cycles,
118 .mask = CLOCKSOURCE_MASK(32), 112 .mask = CLOCKSOURCE_MASK(32),
@@ -121,6 +115,16 @@ static struct clocksource clksrc = {
121 .resume = tc_clksrc_resume, 115 .resume = tc_clksrc_resume,
122}; 116};
123 117
118static u64 notrace tc_sched_clock_read(void)
119{
120 return tc_get_cycles(&clksrc);
121}
122
123static u64 notrace tc_sched_clock_read32(void)
124{
125 return tc_get_cycles32(&clksrc);
126}
127
124#ifdef CONFIG_GENERIC_CLOCKEVENTS 128#ifdef CONFIG_GENERIC_CLOCKEVENTS
125 129
126struct tc_clkevt_device { 130struct tc_clkevt_device {
@@ -214,7 +218,6 @@ static int tc_next_event(unsigned long delta, struct clock_event_device *d)
214 218
215static struct tc_clkevt_device clkevt = { 219static struct tc_clkevt_device clkevt = {
216 .clkevt = { 220 .clkevt = {
217 .name = "tc_clkevt",
218 .features = CLOCK_EVT_FEAT_PERIODIC | 221 .features = CLOCK_EVT_FEAT_PERIODIC |
219 CLOCK_EVT_FEAT_ONESHOT, 222 CLOCK_EVT_FEAT_ONESHOT,
220 /* Should be lower than at91rm9200's system timer */ 223 /* Should be lower than at91rm9200's system timer */
@@ -330,39 +333,74 @@ static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_id
330 writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); 333 writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR);
331} 334}
332 335
333static int __init tcb_clksrc_init(void) 336static const u8 atmel_tcb_divisors[5] = { 2, 8, 32, 128, 0, };
334{ 337
335 static char bootinfo[] __initdata 338static const struct of_device_id atmel_tcb_of_match[] = {
336 = KERN_DEBUG "%s: tc%d at %d.%03d MHz\n"; 339 { .compatible = "atmel,at91rm9200-tcb", .data = (void *)16, },
340 { .compatible = "atmel,at91sam9x5-tcb", .data = (void *)32, },
341 { /* sentinel */ }
342};
337 343
338 struct platform_device *pdev; 344static int __init tcb_clksrc_init(struct device_node *node)
339 struct atmel_tc *tc; 345{
346 struct atmel_tc tc;
340 struct clk *t0_clk; 347 struct clk *t0_clk;
348 const struct of_device_id *match;
349 u64 (*tc_sched_clock)(void);
341 u32 rate, divided_rate = 0; 350 u32 rate, divided_rate = 0;
342 int best_divisor_idx = -1; 351 int best_divisor_idx = -1;
343 int clk32k_divisor_idx = -1; 352 int clk32k_divisor_idx = -1;
353 int bits;
344 int i; 354 int i;
345 int ret; 355 int ret;
346 356
347 tc = atmel_tc_alloc(CONFIG_ATMEL_TCB_CLKSRC_BLOCK); 357 /* Protect against multiple calls */
348 if (!tc) { 358 if (tcaddr)
349 pr_debug("can't alloc TC for clocksource\n"); 359 return 0;
350 return -ENODEV; 360
361 tc.regs = of_iomap(node->parent, 0);
362 if (!tc.regs)
363 return -ENXIO;
364
365 t0_clk = of_clk_get_by_name(node->parent, "t0_clk");
366 if (IS_ERR(t0_clk))
367 return PTR_ERR(t0_clk);
368
369 tc.slow_clk = of_clk_get_by_name(node->parent, "slow_clk");
370 if (IS_ERR(tc.slow_clk))
371 return PTR_ERR(tc.slow_clk);
372
373 tc.clk[0] = t0_clk;
374 tc.clk[1] = of_clk_get_by_name(node->parent, "t1_clk");
375 if (IS_ERR(tc.clk[1]))
376 tc.clk[1] = t0_clk;
377 tc.clk[2] = of_clk_get_by_name(node->parent, "t2_clk");
378 if (IS_ERR(tc.clk[2]))
379 tc.clk[2] = t0_clk;
380
381 tc.irq[2] = of_irq_get(node->parent, 2);
382 if (tc.irq[2] <= 0) {
383 tc.irq[2] = of_irq_get(node->parent, 0);
384 if (tc.irq[2] <= 0)
385 return -EINVAL;
351 } 386 }
352 tcaddr = tc->regs;
353 pdev = tc->pdev;
354 387
355 t0_clk = tc->clk[0]; 388 match = of_match_node(atmel_tcb_of_match, node->parent);
389 bits = (uintptr_t)match->data;
390
391 for (i = 0; i < ARRAY_SIZE(tc.irq); i++)
392 writel(ATMEL_TC_ALL_IRQ, tc.regs + ATMEL_TC_REG(i, IDR));
393
356 ret = clk_prepare_enable(t0_clk); 394 ret = clk_prepare_enable(t0_clk);
357 if (ret) { 395 if (ret) {
358 pr_debug("can't enable T0 clk\n"); 396 pr_debug("can't enable T0 clk\n");
359 goto err_free_tc; 397 return ret;
360 } 398 }
361 399
362 /* How fast will we be counting? Pick something over 5 MHz. */ 400 /* How fast will we be counting? Pick something over 5 MHz. */
363 rate = (u32) clk_get_rate(t0_clk); 401 rate = (u32) clk_get_rate(t0_clk);
364 for (i = 0; i < 5; i++) { 402 for (i = 0; i < ARRAY_SIZE(atmel_tcb_divisors); i++) {
365 unsigned divisor = atmel_tc_divisors[i]; 403 unsigned divisor = atmel_tcb_divisors[i];
366 unsigned tmp; 404 unsigned tmp;
367 405
368 /* remember 32 KiHz clock for later */ 406 /* remember 32 KiHz clock for later */
@@ -381,27 +419,31 @@ static int __init tcb_clksrc_init(void)
381 best_divisor_idx = i; 419 best_divisor_idx = i;
382 } 420 }
383 421
384 422 clksrc.name = kbasename(node->parent->full_name);
385 printk(bootinfo, clksrc.name, CONFIG_ATMEL_TCB_CLKSRC_BLOCK, 423 clkevt.clkevt.name = kbasename(node->parent->full_name);
386 divided_rate / 1000000, 424 pr_debug("%s at %d.%03d MHz\n", clksrc.name, divided_rate / 1000000,
387 ((divided_rate % 1000000) + 500) / 1000); 425 ((divided_rate % 1000000) + 500) / 1000);
388 426
389 if (tc->tcb_config && tc->tcb_config->counter_width == 32) { 427 tcaddr = tc.regs;
428
429 if (bits == 32) {
390 /* use apropriate function to read 32 bit counter */ 430 /* use apropriate function to read 32 bit counter */
391 clksrc.read = tc_get_cycles32; 431 clksrc.read = tc_get_cycles32;
392 /* setup ony channel 0 */ 432 /* setup ony channel 0 */
393 tcb_setup_single_chan(tc, best_divisor_idx); 433 tcb_setup_single_chan(&tc, best_divisor_idx);
434 tc_sched_clock = tc_sched_clock_read32;
394 } else { 435 } else {
395 /* tclib will give us three clocks no matter what the 436 /* we have three clocks no matter what the
396 * underlying platform supports. 437 * underlying platform supports.
397 */ 438 */
398 ret = clk_prepare_enable(tc->clk[1]); 439 ret = clk_prepare_enable(tc.clk[1]);
399 if (ret) { 440 if (ret) {
400 pr_debug("can't enable T1 clk\n"); 441 pr_debug("can't enable T1 clk\n");
401 goto err_disable_t0; 442 goto err_disable_t0;
402 } 443 }
403 /* setup both channel 0 & 1 */ 444 /* setup both channel 0 & 1 */
404 tcb_setup_dual_chan(tc, best_divisor_idx); 445 tcb_setup_dual_chan(&tc, best_divisor_idx);
446 tc_sched_clock = tc_sched_clock_read;
405 } 447 }
406 448
407 /* and away we go! */ 449 /* and away we go! */
@@ -410,24 +452,26 @@ static int __init tcb_clksrc_init(void)
410 goto err_disable_t1; 452 goto err_disable_t1;
411 453
412 /* channel 2: periodic and oneshot timer support */ 454 /* channel 2: periodic and oneshot timer support */
413 ret = setup_clkevents(tc, clk32k_divisor_idx); 455 ret = setup_clkevents(&tc, clk32k_divisor_idx);
414 if (ret) 456 if (ret)
415 goto err_unregister_clksrc; 457 goto err_unregister_clksrc;
416 458
459 sched_clock_register(tc_sched_clock, 32, divided_rate);
460
417 return 0; 461 return 0;
418 462
419err_unregister_clksrc: 463err_unregister_clksrc:
420 clocksource_unregister(&clksrc); 464 clocksource_unregister(&clksrc);
421 465
422err_disable_t1: 466err_disable_t1:
423 if (!tc->tcb_config || tc->tcb_config->counter_width != 32) 467 if (bits != 32)
424 clk_disable_unprepare(tc->clk[1]); 468 clk_disable_unprepare(tc.clk[1]);
425 469
426err_disable_t0: 470err_disable_t0:
427 clk_disable_unprepare(t0_clk); 471 clk_disable_unprepare(t0_clk);
428 472
429err_free_tc: 473 tcaddr = NULL;
430 atmel_tc_free(tc); 474
431 return ret; 475 return ret;
432} 476}
433arch_initcall(tcb_clksrc_init); 477TIMER_OF_DECLARE(atmel_tcb_clksrc, "atmel,tcb-timer", tcb_clksrc_init);
diff --git a/drivers/clocksource/timer-milbeaut.c b/drivers/clocksource/timer-milbeaut.c
index f2019a88e3ee..fa9fb4eacade 100644
--- a/drivers/clocksource/timer-milbeaut.c
+++ b/drivers/clocksource/timer-milbeaut.c
@@ -26,8 +26,8 @@
26#define MLB_TMR_TMCSR_CSL_DIV2 0 26#define MLB_TMR_TMCSR_CSL_DIV2 0
27#define MLB_TMR_DIV_CNT 2 27#define MLB_TMR_DIV_CNT 2
28 28
29#define MLB_TMR_SRC_CH (1) 29#define MLB_TMR_SRC_CH 1
30#define MLB_TMR_EVT_CH (0) 30#define MLB_TMR_EVT_CH 0
31 31
32#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH) 32#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH)
33#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH) 33#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH)
@@ -43,6 +43,8 @@
43#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS) 43#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS)
44 44
45#define MLB_TIMER_RATING 500 45#define MLB_TIMER_RATING 500
46#define MLB_TIMER_ONESHOT 0
47#define MLB_TIMER_PERIODIC 1
46 48
47static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id) 49static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id)
48{ 50{
@@ -59,27 +61,53 @@ static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id)
59 return IRQ_HANDLED; 61 return IRQ_HANDLED;
60} 62}
61 63
62static int mlb_set_state_periodic(struct clock_event_device *clk) 64static void mlb_evt_timer_start(struct timer_of *to, bool periodic)
63{ 65{
64 struct timer_of *to = to_timer_of(clk);
65 u32 val = MLB_TMR_TMCSR_CSL_DIV2; 66 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
66 67
68 val |= MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE;
69 if (periodic)
70 val |= MLB_TMR_TMCSR_RELD;
67 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 71 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
72}
68 73
69 writel_relaxed(to->of_clk.period, timer_of_base(to) + 74static void mlb_evt_timer_stop(struct timer_of *to)
70 MLB_TMR_EVT_TMRLR1_OFS); 75{
71 val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | 76 u32 val = readl_relaxed(timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
72 MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE; 77
78 val &= ~MLB_TMR_TMCSR_CNTE;
73 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 79 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
80}
81
82static void mlb_evt_timer_register_count(struct timer_of *to, unsigned long cnt)
83{
84 writel_relaxed(cnt, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS);
85}
86
87static int mlb_set_state_periodic(struct clock_event_device *clk)
88{
89 struct timer_of *to = to_timer_of(clk);
90
91 mlb_evt_timer_stop(to);
92 mlb_evt_timer_register_count(to, to->of_clk.period);
93 mlb_evt_timer_start(to, MLB_TIMER_PERIODIC);
74 return 0; 94 return 0;
75} 95}
76 96
77static int mlb_set_state_oneshot(struct clock_event_device *clk) 97static int mlb_set_state_oneshot(struct clock_event_device *clk)
78{ 98{
79 struct timer_of *to = to_timer_of(clk); 99 struct timer_of *to = to_timer_of(clk);
80 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
81 100
82 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 101 mlb_evt_timer_stop(to);
102 mlb_evt_timer_start(to, MLB_TIMER_ONESHOT);
103 return 0;
104}
105
106static int mlb_set_state_shutdown(struct clock_event_device *clk)
107{
108 struct timer_of *to = to_timer_of(clk);
109
110 mlb_evt_timer_stop(to);
83 return 0; 111 return 0;
84} 112}
85 113
@@ -88,22 +116,21 @@ static int mlb_clkevt_next_event(unsigned long event,
88{ 116{
89 struct timer_of *to = to_timer_of(clk); 117 struct timer_of *to = to_timer_of(clk);
90 118
91 writel_relaxed(event, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS); 119 mlb_evt_timer_stop(to);
92 writel_relaxed(MLB_TMR_TMCSR_CSL_DIV2 | 120 mlb_evt_timer_register_count(to, event);
93 MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_INTE | 121 mlb_evt_timer_start(to, MLB_TIMER_ONESHOT);
94 MLB_TMR_TMCSR_TRG, timer_of_base(to) +
95 MLB_TMR_EVT_TMCSR_OFS);
96 return 0; 122 return 0;
97} 123}
98 124
99static int mlb_config_clock_source(struct timer_of *to) 125static int mlb_config_clock_source(struct timer_of *to)
100{ 126{
101 writel_relaxed(0, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS); 127 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
102 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMR_OFS); 128
129 writel_relaxed(val, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS);
103 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS); 130 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS);
104 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS); 131 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS);
105 writel_relaxed(BIT(4) | BIT(1) | BIT(0), timer_of_base(to) + 132 val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_TRG;
106 MLB_TMR_SRC_TMCSR_OFS); 133 writel_relaxed(val, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS);
107 return 0; 134 return 0;
108} 135}
109 136
@@ -123,6 +150,7 @@ static struct timer_of to = {
123 .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT, 150 .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT,
124 .set_state_oneshot = mlb_set_state_oneshot, 151 .set_state_oneshot = mlb_set_state_oneshot,
125 .set_state_periodic = mlb_set_state_periodic, 152 .set_state_periodic = mlb_set_state_periodic,
153 .set_state_shutdown = mlb_set_state_shutdown,
126 .set_next_event = mlb_clkevt_next_event, 154 .set_next_event = mlb_clkevt_next_event,
127 }, 155 },
128 156
diff --git a/drivers/clocksource/timer-sun4i.c b/drivers/clocksource/timer-sun4i.c
index 6e0180aaf784..65f38f6ca714 100644
--- a/drivers/clocksource/timer-sun4i.c
+++ b/drivers/clocksource/timer-sun4i.c
@@ -186,7 +186,8 @@ static int __init sun4i_timer_init(struct device_node *node)
186 */ 186 */
187 if (of_machine_is_compatible("allwinner,sun4i-a10") || 187 if (of_machine_is_compatible("allwinner,sun4i-a10") ||
188 of_machine_is_compatible("allwinner,sun5i-a13") || 188 of_machine_is_compatible("allwinner,sun5i-a13") ||
189 of_machine_is_compatible("allwinner,sun5i-a10s")) 189 of_machine_is_compatible("allwinner,sun5i-a10s") ||
190 of_machine_is_compatible("allwinner,suniv-f1c100s"))
190 sched_clock_register(sun4i_timer_sched_read, 32, 191 sched_clock_register(sun4i_timer_sched_read, 32,
191 timer_of_rate(&to)); 192 timer_of_rate(&to));
192 193
@@ -218,3 +219,5 @@ static int __init sun4i_timer_init(struct device_node *node)
218} 219}
219TIMER_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer", 220TIMER_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer",
220 sun4i_timer_init); 221 sun4i_timer_init);
222TIMER_OF_DECLARE(suniv, "allwinner,suniv-f1c100s-timer",
223 sun4i_timer_init);
diff --git a/drivers/clocksource/timer-tegra20.c b/drivers/clocksource/timer-tegra20.c
index fdb3d795a409..919b3568c495 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -60,9 +60,6 @@
60static u32 usec_config; 60static u32 usec_config;
61static void __iomem *timer_reg_base; 61static void __iomem *timer_reg_base;
62#ifdef CONFIG_ARM 62#ifdef CONFIG_ARM
63static void __iomem *rtc_base;
64static struct timespec64 persistent_ts;
65static u64 persistent_ms, last_persistent_ms;
66static struct delay_timer tegra_delay_timer; 63static struct delay_timer tegra_delay_timer;
67#endif 64#endif
68 65
@@ -199,40 +196,30 @@ static unsigned long tegra_delay_timer_read_counter_long(void)
199 return readl(timer_reg_base + TIMERUS_CNTR_1US); 196 return readl(timer_reg_base + TIMERUS_CNTR_1US);
200} 197}
201 198
199static struct timer_of suspend_rtc_to = {
200 .flags = TIMER_OF_BASE | TIMER_OF_CLOCK,
201};
202
202/* 203/*
203 * tegra_rtc_read - Reads the Tegra RTC registers 204 * tegra_rtc_read - Reads the Tegra RTC registers
204 * Care must be taken that this funciton is not called while the 205 * Care must be taken that this funciton is not called while the
205 * tegra_rtc driver could be executing to avoid race conditions 206 * tegra_rtc driver could be executing to avoid race conditions
206 * on the RTC shadow register 207 * on the RTC shadow register
207 */ 208 */
208static u64 tegra_rtc_read_ms(void) 209static u64 tegra_rtc_read_ms(struct clocksource *cs)
209{ 210{
210 u32 ms = readl(rtc_base + RTC_MILLISECONDS); 211 u32 ms = readl(timer_of_base(&suspend_rtc_to) + RTC_MILLISECONDS);
211 u32 s = readl(rtc_base + RTC_SHADOW_SECONDS); 212 u32 s = readl(timer_of_base(&suspend_rtc_to) + RTC_SHADOW_SECONDS);
212 return (u64)s * MSEC_PER_SEC + ms; 213 return (u64)s * MSEC_PER_SEC + ms;
213} 214}
214 215
215/* 216static struct clocksource suspend_rtc_clocksource = {
216 * tegra_read_persistent_clock64 - Return time from a persistent clock. 217 .name = "tegra_suspend_timer",
217 * 218 .rating = 200,
218 * Reads the time from a source which isn't disabled during PM, the 219 .read = tegra_rtc_read_ms,
219 * 32k sync timer. Convert the cycles elapsed since last read into 220 .mask = CLOCKSOURCE_MASK(32),
220 * nsecs and adds to a monotonically increasing timespec64. 221 .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
221 * Care must be taken that this funciton is not called while the 222};
222 * tegra_rtc driver could be executing to avoid race conditions
223 * on the RTC shadow register
224 */
225static void tegra_read_persistent_clock64(struct timespec64 *ts)
226{
227 u64 delta;
228
229 last_persistent_ms = persistent_ms;
230 persistent_ms = tegra_rtc_read_ms();
231 delta = persistent_ms - last_persistent_ms;
232
233 timespec64_add_ns(&persistent_ts, delta * NSEC_PER_MSEC);
234 *ts = persistent_ts;
235}
236#endif 223#endif
237 224
238static int tegra_timer_common_init(struct device_node *np, struct timer_of *to) 225static int tegra_timer_common_init(struct device_node *np, struct timer_of *to)
@@ -385,25 +372,15 @@ out:
385 372
386static int __init tegra20_init_rtc(struct device_node *np) 373static int __init tegra20_init_rtc(struct device_node *np)
387{ 374{
388 struct clk *clk; 375 int ret;
389 376
390 rtc_base = of_iomap(np, 0); 377 ret = timer_of_init(np, &suspend_rtc_to);
391 if (!rtc_base) { 378 if (ret)
392 pr_err("Can't map RTC registers\n"); 379 return ret;
393 return -ENXIO;
394 }
395 380
396 /* 381 clocksource_register_hz(&suspend_rtc_clocksource, 1000);
397 * rtc registers are used by read_persistent_clock, keep the rtc clock
398 * enabled
399 */
400 clk = of_clk_get(np, 0);
401 if (IS_ERR(clk))
402 pr_warn("Unable to get rtc-tegra clock\n");
403 else
404 clk_prepare_enable(clk);
405 382
406 return register_persistent_clock(tegra_read_persistent_clock64); 383 return 0;
407} 384}
408TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc); 385TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
409#endif 386#endif
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 3fbbb61012c4..ef93406ace1b 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -65,18 +65,36 @@ struct ti_sci_xfers_info {
65}; 65};
66 66
67/** 67/**
68 * struct ti_sci_rm_type_map - Structure representing TISCI Resource
69 * management representation of dev_ids.
70 * @dev_id: TISCI device ID
71 * @type: Corresponding id as identified by TISCI RM.
72 *
73 * Note: This is used only as a work around for using RM range apis
74 * for AM654 SoC. For future SoCs dev_id will be used as type
75 * for RM range APIs. In order to maintain ABI backward compatibility
76 * type is not being changed for AM654 SoC.
77 */
78struct ti_sci_rm_type_map {
79 u32 dev_id;
80 u16 type;
81};
82
83/**
68 * struct ti_sci_desc - Description of SoC integration 84 * struct ti_sci_desc - Description of SoC integration
69 * @default_host_id: Host identifier representing the compute entity 85 * @default_host_id: Host identifier representing the compute entity
70 * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds) 86 * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
71 * @max_msgs: Maximum number of messages that can be pending 87 * @max_msgs: Maximum number of messages that can be pending
72 * simultaneously in the system 88 * simultaneously in the system
73 * @max_msg_size: Maximum size of data per message that can be handled. 89 * @max_msg_size: Maximum size of data per message that can be handled.
90 * @rm_type_map: RM resource type mapping structure.
74 */ 91 */
75struct ti_sci_desc { 92struct ti_sci_desc {
76 u8 default_host_id; 93 u8 default_host_id;
77 int max_rx_timeout_ms; 94 int max_rx_timeout_ms;
78 int max_msgs; 95 int max_msgs;
79 int max_msg_size; 96 int max_msg_size;
97 struct ti_sci_rm_type_map *rm_type_map;
80}; 98};
81 99
82/** 100/**
@@ -1600,6 +1618,392 @@ fail:
1600 return ret; 1618 return ret;
1601} 1619}
1602 1620
1621static int ti_sci_get_resource_type(struct ti_sci_info *info, u16 dev_id,
1622 u16 *type)
1623{
1624 struct ti_sci_rm_type_map *rm_type_map = info->desc->rm_type_map;
1625 bool found = false;
1626 int i;
1627
1628 /* If map is not provided then assume dev_id is used as type */
1629 if (!rm_type_map) {
1630 *type = dev_id;
1631 return 0;
1632 }
1633
1634 for (i = 0; rm_type_map[i].dev_id; i++) {
1635 if (rm_type_map[i].dev_id == dev_id) {
1636 *type = rm_type_map[i].type;
1637 found = true;
1638 break;
1639 }
1640 }
1641
1642 if (!found)
1643 return -EINVAL;
1644
1645 return 0;
1646}
1647
1648/**
1649 * ti_sci_get_resource_range - Helper to get a range of resources assigned
1650 * to a host. Resource is uniquely identified by
1651 * type and subtype.
1652 * @handle: Pointer to TISCI handle.
1653 * @dev_id: TISCI device ID.
1654 * @subtype: Resource assignment subtype that is being requested
1655 * from the given device.
1656 * @s_host: Host processor ID to which the resources are allocated
1657 * @range_start: Start index of the resource range
1658 * @range_num: Number of resources in the range
1659 *
1660 * Return: 0 if all went fine, else return appropriate error.
1661 */
1662static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
1663 u32 dev_id, u8 subtype, u8 s_host,
1664 u16 *range_start, u16 *range_num)
1665{
1666 struct ti_sci_msg_resp_get_resource_range *resp;
1667 struct ti_sci_msg_req_get_resource_range *req;
1668 struct ti_sci_xfer *xfer;
1669 struct ti_sci_info *info;
1670 struct device *dev;
1671 u16 type;
1672 int ret = 0;
1673
1674 if (IS_ERR(handle))
1675 return PTR_ERR(handle);
1676 if (!handle)
1677 return -EINVAL;
1678
1679 info = handle_to_ti_sci_info(handle);
1680 dev = info->dev;
1681
1682 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE,
1683 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1684 sizeof(*req), sizeof(*resp));
1685 if (IS_ERR(xfer)) {
1686 ret = PTR_ERR(xfer);
1687 dev_err(dev, "Message alloc failed(%d)\n", ret);
1688 return ret;
1689 }
1690
1691 ret = ti_sci_get_resource_type(info, dev_id, &type);
1692 if (ret) {
1693 dev_err(dev, "rm type lookup failed for %u\n", dev_id);
1694 goto fail;
1695 }
1696
1697 req = (struct ti_sci_msg_req_get_resource_range *)xfer->xfer_buf;
1698 req->secondary_host = s_host;
1699 req->type = type & MSG_RM_RESOURCE_TYPE_MASK;
1700 req->subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
1701
1702 ret = ti_sci_do_xfer(info, xfer);
1703 if (ret) {
1704 dev_err(dev, "Mbox send fail %d\n", ret);
1705 goto fail;
1706 }
1707
1708 resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->xfer_buf;
1709
1710 if (!ti_sci_is_response_ack(resp)) {
1711 ret = -ENODEV;
1712 } else if (!resp->range_start && !resp->range_num) {
1713 ret = -ENODEV;
1714 } else {
1715 *range_start = resp->range_start;
1716 *range_num = resp->range_num;
1717 };
1718
1719fail:
1720 ti_sci_put_one_xfer(&info->minfo, xfer);
1721
1722 return ret;
1723}
1724
1725/**
1726 * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host
1727 * that is same as ti sci interface host.
1728 * @handle: Pointer to TISCI handle.
1729 * @dev_id: TISCI device ID.
1730 * @subtype: Resource assignment subtype that is being requested
1731 * from the given device.
1732 * @range_start: Start index of the resource range
1733 * @range_num: Number of resources in the range
1734 *
1735 * Return: 0 if all went fine, else return appropriate error.
1736 */
1737static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
1738 u32 dev_id, u8 subtype,
1739 u16 *range_start, u16 *range_num)
1740{
1741 return ti_sci_get_resource_range(handle, dev_id, subtype,
1742 TI_SCI_IRQ_SECONDARY_HOST_INVALID,
1743 range_start, range_num);
1744}
1745
1746/**
1747 * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources
1748 * assigned to a specified host.
1749 * @handle: Pointer to TISCI handle.
1750 * @dev_id: TISCI device ID.
1751 * @subtype: Resource assignment subtype that is being requested
1752 * from the given device.
1753 * @s_host: Host processor ID to which the resources are allocated
1754 * @range_start: Start index of the resource range
1755 * @range_num: Number of resources in the range
1756 *
1757 * Return: 0 if all went fine, else return appropriate error.
1758 */
1759static
1760int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
1761 u32 dev_id, u8 subtype, u8 s_host,
1762 u16 *range_start, u16 *range_num)
1763{
1764 return ti_sci_get_resource_range(handle, dev_id, subtype, s_host,
1765 range_start, range_num);
1766}
1767
1768/**
1769 * ti_sci_manage_irq() - Helper api to configure/release the irq route between
1770 * the requested source and destination
1771 * @handle: Pointer to TISCI handle.
1772 * @valid_params: Bit fields defining the validity of certain params
1773 * @src_id: Device ID of the IRQ source
1774 * @src_index: IRQ source index within the source device
1775 * @dst_id: Device ID of the IRQ destination
1776 * @dst_host_irq: IRQ number of the destination device
1777 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1778 * @vint: Virtual interrupt to be used within the IA
1779 * @global_event: Global event number to be used for the requesting event
1780 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1781 * @s_host: Secondary host ID to which the irq/event is being
1782 * requested for.
1783 * @type: Request type irq set or release.
1784 *
1785 * Return: 0 if all went fine, else return appropriate error.
1786 */
1787static int ti_sci_manage_irq(const struct ti_sci_handle *handle,
1788 u32 valid_params, u16 src_id, u16 src_index,
1789 u16 dst_id, u16 dst_host_irq, u16 ia_id, u16 vint,
1790 u16 global_event, u8 vint_status_bit, u8 s_host,
1791 u16 type)
1792{
1793 struct ti_sci_msg_req_manage_irq *req;
1794 struct ti_sci_msg_hdr *resp;
1795 struct ti_sci_xfer *xfer;
1796 struct ti_sci_info *info;
1797 struct device *dev;
1798 int ret = 0;
1799
1800 if (IS_ERR(handle))
1801 return PTR_ERR(handle);
1802 if (!handle)
1803 return -EINVAL;
1804
1805 info = handle_to_ti_sci_info(handle);
1806 dev = info->dev;
1807
1808 xfer = ti_sci_get_one_xfer(info, type, TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1809 sizeof(*req), sizeof(*resp));
1810 if (IS_ERR(xfer)) {
1811 ret = PTR_ERR(xfer);
1812 dev_err(dev, "Message alloc failed(%d)\n", ret);
1813 return ret;
1814 }
1815 req = (struct ti_sci_msg_req_manage_irq *)xfer->xfer_buf;
1816 req->valid_params = valid_params;
1817 req->src_id = src_id;
1818 req->src_index = src_index;
1819 req->dst_id = dst_id;
1820 req->dst_host_irq = dst_host_irq;
1821 req->ia_id = ia_id;
1822 req->vint = vint;
1823 req->global_event = global_event;
1824 req->vint_status_bit = vint_status_bit;
1825 req->secondary_host = s_host;
1826
1827 ret = ti_sci_do_xfer(info, xfer);
1828 if (ret) {
1829 dev_err(dev, "Mbox send fail %d\n", ret);
1830 goto fail;
1831 }
1832
1833 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1834
1835 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
1836
1837fail:
1838 ti_sci_put_one_xfer(&info->minfo, xfer);
1839
1840 return ret;
1841}
1842
1843/**
1844 * ti_sci_set_irq() - Helper api to configure the irq route between the
1845 * requested source and destination
1846 * @handle: Pointer to TISCI handle.
1847 * @valid_params: Bit fields defining the validity of certain params
1848 * @src_id: Device ID of the IRQ source
1849 * @src_index: IRQ source index within the source device
1850 * @dst_id: Device ID of the IRQ destination
1851 * @dst_host_irq: IRQ number of the destination device
1852 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1853 * @vint: Virtual interrupt to be used within the IA
1854 * @global_event: Global event number to be used for the requesting event
1855 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1856 * @s_host: Secondary host ID to which the irq/event is being
1857 * requested for.
1858 *
1859 * Return: 0 if all went fine, else return appropriate error.
1860 */
1861static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params,
1862 u16 src_id, u16 src_index, u16 dst_id,
1863 u16 dst_host_irq, u16 ia_id, u16 vint,
1864 u16 global_event, u8 vint_status_bit, u8 s_host)
1865{
1866 pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
1867 __func__, valid_params, src_id, src_index,
1868 dst_id, dst_host_irq, ia_id, vint, global_event,
1869 vint_status_bit);
1870
1871 return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
1872 dst_id, dst_host_irq, ia_id, vint,
1873 global_event, vint_status_bit, s_host,
1874 TI_SCI_MSG_SET_IRQ);
1875}
1876
1877/**
1878 * ti_sci_free_irq() - Helper api to free the irq route between the
1879 * requested source and destination
1880 * @handle: Pointer to TISCI handle.
1881 * @valid_params: Bit fields defining the validity of certain params
1882 * @src_id: Device ID of the IRQ source
1883 * @src_index: IRQ source index within the source device
1884 * @dst_id: Device ID of the IRQ destination
1885 * @dst_host_irq: IRQ number of the destination device
1886 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1887 * @vint: Virtual interrupt to be used within the IA
1888 * @global_event: Global event number to be used for the requesting event
1889 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1890 * @s_host: Secondary host ID to which the irq/event is being
1891 * requested for.
1892 *
1893 * Return: 0 if all went fine, else return appropriate error.
1894 */
1895static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params,
1896 u16 src_id, u16 src_index, u16 dst_id,
1897 u16 dst_host_irq, u16 ia_id, u16 vint,
1898 u16 global_event, u8 vint_status_bit, u8 s_host)
1899{
1900 pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
1901 __func__, valid_params, src_id, src_index,
1902 dst_id, dst_host_irq, ia_id, vint, global_event,
1903 vint_status_bit);
1904
1905 return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
1906 dst_id, dst_host_irq, ia_id, vint,
1907 global_event, vint_status_bit, s_host,
1908 TI_SCI_MSG_FREE_IRQ);
1909}
1910
1911/**
1912 * ti_sci_cmd_set_irq() - Configure a host irq route between the requested
1913 * source and destination.
1914 * @handle: Pointer to TISCI handle.
1915 * @src_id: Device ID of the IRQ source
1916 * @src_index: IRQ source index within the source device
1917 * @dst_id: Device ID of the IRQ destination
1918 * @dst_host_irq: IRQ number of the destination device
1919 * @vint_irq: Boolean specifying if this interrupt belongs to
1920 * Interrupt Aggregator.
1921 *
1922 * Return: 0 if all went fine, else return appropriate error.
1923 */
1924static int ti_sci_cmd_set_irq(const struct ti_sci_handle *handle, u16 src_id,
1925 u16 src_index, u16 dst_id, u16 dst_host_irq)
1926{
1927 u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
1928
1929 return ti_sci_set_irq(handle, valid_params, src_id, src_index, dst_id,
1930 dst_host_irq, 0, 0, 0, 0, 0);
1931}
1932
1933/**
1934 * ti_sci_cmd_set_event_map() - Configure an event based irq route between the
1935 * requested source and Interrupt Aggregator.
1936 * @handle: Pointer to TISCI handle.
1937 * @src_id: Device ID of the IRQ source
1938 * @src_index: IRQ source index within the source device
1939 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1940 * @vint: Virtual interrupt to be used within the IA
1941 * @global_event: Global event number to be used for the requesting event
1942 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1943 *
1944 * Return: 0 if all went fine, else return appropriate error.
1945 */
1946static int ti_sci_cmd_set_event_map(const struct ti_sci_handle *handle,
1947 u16 src_id, u16 src_index, u16 ia_id,
1948 u16 vint, u16 global_event,
1949 u8 vint_status_bit)
1950{
1951 u32 valid_params = MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID |
1952 MSG_FLAG_GLB_EVNT_VALID |
1953 MSG_FLAG_VINT_STS_BIT_VALID;
1954
1955 return ti_sci_set_irq(handle, valid_params, src_id, src_index, 0, 0,
1956 ia_id, vint, global_event, vint_status_bit, 0);
1957}
1958
1959/**
1960 * ti_sci_cmd_free_irq() - Free a host irq route between the between the
1961 * requested source and destination.
1962 * @handle: Pointer to TISCI handle.
1963 * @src_id: Device ID of the IRQ source
1964 * @src_index: IRQ source index within the source device
1965 * @dst_id: Device ID of the IRQ destination
1966 * @dst_host_irq: IRQ number of the destination device
1967 * @vint_irq: Boolean specifying if this interrupt belongs to
1968 * Interrupt Aggregator.
1969 *
1970 * Return: 0 if all went fine, else return appropriate error.
1971 */
1972static int ti_sci_cmd_free_irq(const struct ti_sci_handle *handle, u16 src_id,
1973 u16 src_index, u16 dst_id, u16 dst_host_irq)
1974{
1975 u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
1976
1977 return ti_sci_free_irq(handle, valid_params, src_id, src_index, dst_id,
1978 dst_host_irq, 0, 0, 0, 0, 0);
1979}
1980
1981/**
1982 * ti_sci_cmd_free_event_map() - Free an event map between the requested source
1983 * and Interrupt Aggregator.
1984 * @handle: Pointer to TISCI handle.
1985 * @src_id: Device ID of the IRQ source
1986 * @src_index: IRQ source index within the source device
1987 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1988 * @vint: Virtual interrupt to be used within the IA
1989 * @global_event: Global event number to be used for the requesting event
1990 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1991 *
1992 * Return: 0 if all went fine, else return appropriate error.
1993 */
1994static int ti_sci_cmd_free_event_map(const struct ti_sci_handle *handle,
1995 u16 src_id, u16 src_index, u16 ia_id,
1996 u16 vint, u16 global_event,
1997 u8 vint_status_bit)
1998{
1999 u32 valid_params = MSG_FLAG_IA_ID_VALID |
2000 MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID |
2001 MSG_FLAG_VINT_STS_BIT_VALID;
2002
2003 return ti_sci_free_irq(handle, valid_params, src_id, src_index, 0, 0,
2004 ia_id, vint, global_event, vint_status_bit, 0);
2005}
2006
1603/* 2007/*
1604 * ti_sci_setup_ops() - Setup the operations structures 2008 * ti_sci_setup_ops() - Setup the operations structures
1605 * @info: pointer to TISCI pointer 2009 * @info: pointer to TISCI pointer
@@ -1610,6 +2014,8 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
1610 struct ti_sci_core_ops *core_ops = &ops->core_ops; 2014 struct ti_sci_core_ops *core_ops = &ops->core_ops;
1611 struct ti_sci_dev_ops *dops = &ops->dev_ops; 2015 struct ti_sci_dev_ops *dops = &ops->dev_ops;
1612 struct ti_sci_clk_ops *cops = &ops->clk_ops; 2016 struct ti_sci_clk_ops *cops = &ops->clk_ops;
2017 struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
2018 struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops;
1613 2019
1614 core_ops->reboot_device = ti_sci_cmd_core_reboot; 2020 core_ops->reboot_device = ti_sci_cmd_core_reboot;
1615 2021
@@ -1640,6 +2046,15 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
1640 cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq; 2046 cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
1641 cops->set_freq = ti_sci_cmd_clk_set_freq; 2047 cops->set_freq = ti_sci_cmd_clk_set_freq;
1642 cops->get_freq = ti_sci_cmd_clk_get_freq; 2048 cops->get_freq = ti_sci_cmd_clk_get_freq;
2049
2050 rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
2051 rm_core_ops->get_range_from_shost =
2052 ti_sci_cmd_get_resource_range_from_shost;
2053
2054 iops->set_irq = ti_sci_cmd_set_irq;
2055 iops->set_event_map = ti_sci_cmd_set_event_map;
2056 iops->free_irq = ti_sci_cmd_free_irq;
2057 iops->free_event_map = ti_sci_cmd_free_event_map;
1643} 2058}
1644 2059
1645/** 2060/**
@@ -1764,6 +2179,219 @@ const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
1764} 2179}
1765EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle); 2180EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle);
1766 2181
2182/**
2183 * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle
2184 * @np: device node
2185 * @property: property name containing phandle on TISCI node
2186 *
2187 * NOTE: The function does not track individual clients of the framework
2188 * and is expected to be maintained by caller of TI SCI protocol library.
2189 * ti_sci_put_handle must be balanced with successful ti_sci_get_by_phandle
2190 * Return: pointer to handle if successful, else:
2191 * -EPROBE_DEFER if the instance is not ready
2192 * -ENODEV if the required node handler is missing
2193 * -EINVAL if invalid conditions are encountered.
2194 */
2195const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
2196 const char *property)
2197{
2198 struct ti_sci_handle *handle = NULL;
2199 struct device_node *ti_sci_np;
2200 struct ti_sci_info *info;
2201 struct list_head *p;
2202
2203 if (!np) {
2204 pr_err("I need a device pointer\n");
2205 return ERR_PTR(-EINVAL);
2206 }
2207
2208 ti_sci_np = of_parse_phandle(np, property, 0);
2209 if (!ti_sci_np)
2210 return ERR_PTR(-ENODEV);
2211
2212 mutex_lock(&ti_sci_list_mutex);
2213 list_for_each(p, &ti_sci_list) {
2214 info = list_entry(p, struct ti_sci_info, node);
2215 if (ti_sci_np == info->dev->of_node) {
2216 handle = &info->handle;
2217 info->users++;
2218 break;
2219 }
2220 }
2221 mutex_unlock(&ti_sci_list_mutex);
2222 of_node_put(ti_sci_np);
2223
2224 if (!handle)
2225 return ERR_PTR(-EPROBE_DEFER);
2226
2227 return handle;
2228}
2229EXPORT_SYMBOL_GPL(ti_sci_get_by_phandle);
2230
2231/**
2232 * devm_ti_sci_get_by_phandle() - Managed get handle using phandle
2233 * @dev: Device pointer requesting TISCI handle
2234 * @property: property name containing phandle on TISCI node
2235 *
2236 * NOTE: This releases the handle once the device resources are
2237 * no longer needed. MUST NOT BE released with ti_sci_put_handle.
2238 * The function does not track individual clients of the framework
2239 * and is expected to be maintained by caller of TI SCI protocol library.
2240 *
2241 * Return: 0 if all went fine, else corresponding error.
2242 */
2243const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
2244 const char *property)
2245{
2246 const struct ti_sci_handle *handle;
2247 const struct ti_sci_handle **ptr;
2248
2249 ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
2250 if (!ptr)
2251 return ERR_PTR(-ENOMEM);
2252 handle = ti_sci_get_by_phandle(dev_of_node(dev), property);
2253
2254 if (!IS_ERR(handle)) {
2255 *ptr = handle;
2256 devres_add(dev, ptr);
2257 } else {
2258 devres_free(ptr);
2259 }
2260
2261 return handle;
2262}
2263EXPORT_SYMBOL_GPL(devm_ti_sci_get_by_phandle);
2264
2265/**
2266 * ti_sci_get_free_resource() - Get a free resource from TISCI resource.
2267 * @res: Pointer to the TISCI resource
2268 *
2269 * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
2270 */
2271u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
2272{
2273 unsigned long flags;
2274 u16 set, free_bit;
2275
2276 raw_spin_lock_irqsave(&res->lock, flags);
2277 for (set = 0; set < res->sets; set++) {
2278 free_bit = find_first_zero_bit(res->desc[set].res_map,
2279 res->desc[set].num);
2280 if (free_bit != res->desc[set].num) {
2281 set_bit(free_bit, res->desc[set].res_map);
2282 raw_spin_unlock_irqrestore(&res->lock, flags);
2283 return res->desc[set].start + free_bit;
2284 }
2285 }
2286 raw_spin_unlock_irqrestore(&res->lock, flags);
2287
2288 return TI_SCI_RESOURCE_NULL;
2289}
2290EXPORT_SYMBOL_GPL(ti_sci_get_free_resource);
2291
2292/**
2293 * ti_sci_release_resource() - Release a resource from TISCI resource.
2294 * @res: Pointer to the TISCI resource
2295 * @id: Resource id to be released.
2296 */
2297void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
2298{
2299 unsigned long flags;
2300 u16 set;
2301
2302 raw_spin_lock_irqsave(&res->lock, flags);
2303 for (set = 0; set < res->sets; set++) {
2304 if (res->desc[set].start <= id &&
2305 (res->desc[set].num + res->desc[set].start) > id)
2306 clear_bit(id - res->desc[set].start,
2307 res->desc[set].res_map);
2308 }
2309 raw_spin_unlock_irqrestore(&res->lock, flags);
2310}
2311EXPORT_SYMBOL_GPL(ti_sci_release_resource);
2312
2313/**
2314 * ti_sci_get_num_resources() - Get the number of resources in TISCI resource
2315 * @res: Pointer to the TISCI resource
2316 *
2317 * Return: Total number of available resources.
2318 */
2319u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
2320{
2321 u32 set, count = 0;
2322
2323 for (set = 0; set < res->sets; set++)
2324 count += res->desc[set].num;
2325
2326 return count;
2327}
2328EXPORT_SYMBOL_GPL(ti_sci_get_num_resources);
2329
2330/**
2331 * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device
2332 * @handle: TISCI handle
2333 * @dev: Device pointer to which the resource is assigned
2334 * @dev_id: TISCI device id to which the resource is assigned
2335 * @of_prop: property name by which the resource are represented
2336 *
2337 * Return: Pointer to ti_sci_resource if all went well else appropriate
2338 * error pointer.
2339 */
2340struct ti_sci_resource *
2341devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
2342 struct device *dev, u32 dev_id, char *of_prop)
2343{
2344 struct ti_sci_resource *res;
2345 u32 resource_subtype;
2346 int i, ret;
2347
2348 res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
2349 if (!res)
2350 return ERR_PTR(-ENOMEM);
2351
2352 res->sets = of_property_count_elems_of_size(dev_of_node(dev), of_prop,
2353 sizeof(u32));
2354 if (res->sets < 0) {
2355 dev_err(dev, "%s resource type ids not available\n", of_prop);
2356 return ERR_PTR(res->sets);
2357 }
2358
2359 res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
2360 GFP_KERNEL);
2361 if (!res->desc)
2362 return ERR_PTR(-ENOMEM);
2363
2364 for (i = 0; i < res->sets; i++) {
2365 ret = of_property_read_u32_index(dev_of_node(dev), of_prop, i,
2366 &resource_subtype);
2367 if (ret)
2368 return ERR_PTR(-EINVAL);
2369
2370 ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
2371 resource_subtype,
2372 &res->desc[i].start,
2373 &res->desc[i].num);
2374 if (ret) {
2375 dev_err(dev, "dev = %d subtype %d not allocated for this host\n",
2376 dev_id, resource_subtype);
2377 return ERR_PTR(ret);
2378 }
2379
2380 dev_dbg(dev, "dev = %d, subtype = %d, start = %d, num = %d\n",
2381 dev_id, resource_subtype, res->desc[i].start,
2382 res->desc[i].num);
2383
2384 res->desc[i].res_map =
2385 devm_kzalloc(dev, BITS_TO_LONGS(res->desc[i].num) *
2386 sizeof(*res->desc[i].res_map), GFP_KERNEL);
2387 if (!res->desc[i].res_map)
2388 return ERR_PTR(-ENOMEM);
2389 }
2390 raw_spin_lock_init(&res->lock);
2391
2392 return res;
2393}
2394
1767static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode, 2395static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
1768 void *cmd) 2396 void *cmd)
1769{ 2397{
@@ -1784,10 +2412,33 @@ static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
1784 /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */ 2412 /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
1785 .max_msgs = 20, 2413 .max_msgs = 20,
1786 .max_msg_size = 64, 2414 .max_msg_size = 64,
2415 .rm_type_map = NULL,
2416};
2417
2418static struct ti_sci_rm_type_map ti_sci_am654_rm_type_map[] = {
2419 {.dev_id = 56, .type = 0x00b}, /* GIC_IRQ */
2420 {.dev_id = 179, .type = 0x000}, /* MAIN_NAV_UDMASS_IA0 */
2421 {.dev_id = 187, .type = 0x009}, /* MAIN_NAV_RA */
2422 {.dev_id = 188, .type = 0x006}, /* MAIN_NAV_UDMAP */
2423 {.dev_id = 194, .type = 0x007}, /* MCU_NAV_UDMAP */
2424 {.dev_id = 195, .type = 0x00a}, /* MCU_NAV_RA */
2425 {.dev_id = 0, .type = 0x000}, /* end of table */
2426};
2427
2428/* Description for AM654 */
2429static const struct ti_sci_desc ti_sci_pmmc_am654_desc = {
2430 .default_host_id = 12,
2431 /* Conservative duration */
2432 .max_rx_timeout_ms = 10000,
2433 /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
2434 .max_msgs = 20,
2435 .max_msg_size = 60,
2436 .rm_type_map = ti_sci_am654_rm_type_map,
1787}; 2437};
1788 2438
1789static const struct of_device_id ti_sci_of_match[] = { 2439static const struct of_device_id ti_sci_of_match[] = {
1790 {.compatible = "ti,k2g-sci", .data = &ti_sci_pmmc_k2g_desc}, 2440 {.compatible = "ti,k2g-sci", .data = &ti_sci_pmmc_k2g_desc},
2441 {.compatible = "ti,am654-sci", .data = &ti_sci_pmmc_am654_desc},
1791 { /* Sentinel */ }, 2442 { /* Sentinel */ },
1792}; 2443};
1793MODULE_DEVICE_TABLE(of, ti_sci_of_match); 2444MODULE_DEVICE_TABLE(of, ti_sci_of_match);
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index 12bf316b68df..4983827151bf 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -35,6 +35,13 @@
35#define TI_SCI_MSG_QUERY_CLOCK_FREQ 0x010d 35#define TI_SCI_MSG_QUERY_CLOCK_FREQ 0x010d
36#define TI_SCI_MSG_GET_CLOCK_FREQ 0x010e 36#define TI_SCI_MSG_GET_CLOCK_FREQ 0x010e
37 37
38/* Resource Management Requests */
39#define TI_SCI_MSG_GET_RESOURCE_RANGE 0x1500
40
41/* IRQ requests */
42#define TI_SCI_MSG_SET_IRQ 0x1000
43#define TI_SCI_MSG_FREE_IRQ 0x1001
44
38/** 45/**
39 * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses 46 * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
40 * @type: Type of messages: One of TI_SCI_MSG* values 47 * @type: Type of messages: One of TI_SCI_MSG* values
@@ -461,4 +468,99 @@ struct ti_sci_msg_resp_get_clock_freq {
461 u64 freq_hz; 468 u64 freq_hz;
462} __packed; 469} __packed;
463 470
471#define TI_SCI_IRQ_SECONDARY_HOST_INVALID 0xff
472
473/**
474 * struct ti_sci_msg_req_get_resource_range - Request to get a host's assigned
475 * range of resources.
476 * @hdr: Generic Header
477 * @type: Unique resource assignment type
478 * @subtype: Resource assignment subtype within the resource type.
479 * @secondary_host: Host processing entity to which the resources are
480 * allocated. This is required only when the destination
481 * host id id different from ti sci interface host id,
482 * else TI_SCI_IRQ_SECONDARY_HOST_INVALID can be passed.
483 *
484 * Request type is TI_SCI_MSG_GET_RESOURCE_RANGE. Responded with requested
485 * resource range which is of type TI_SCI_MSG_GET_RESOURCE_RANGE.
486 */
487struct ti_sci_msg_req_get_resource_range {
488 struct ti_sci_msg_hdr hdr;
489#define MSG_RM_RESOURCE_TYPE_MASK GENMASK(9, 0)
490#define MSG_RM_RESOURCE_SUBTYPE_MASK GENMASK(5, 0)
491 u16 type;
492 u8 subtype;
493 u8 secondary_host;
494} __packed;
495
496/**
497 * struct ti_sci_msg_resp_get_resource_range - Response to resource get range.
498 * @hdr: Generic Header
499 * @range_start: Start index of the resource range.
500 * @range_num: Number of resources in the range.
501 *
502 * Response to request TI_SCI_MSG_GET_RESOURCE_RANGE.
503 */
504struct ti_sci_msg_resp_get_resource_range {
505 struct ti_sci_msg_hdr hdr;
506 u16 range_start;
507 u16 range_num;
508} __packed;
509
510/**
511 * struct ti_sci_msg_req_manage_irq - Request to configure/release the route
512 * between the dev and the host.
513 * @hdr: Generic Header
514 * @valid_params: Bit fields defining the validity of interrupt source
515 * parameters. If a bit is not set, then corresponding
516 * field is not valid and will not be used for route set.
517 * Bit field definitions:
518 * 0 - Valid bit for @dst_id
519 * 1 - Valid bit for @dst_host_irq
520 * 2 - Valid bit for @ia_id
521 * 3 - Valid bit for @vint
522 * 4 - Valid bit for @global_event
523 * 5 - Valid bit for @vint_status_bit_index
524 * 31 - Valid bit for @secondary_host
525 * @src_id: IRQ source peripheral ID.
526 * @src_index: IRQ source index within the peripheral
527 * @dst_id: IRQ Destination ID. Based on the architecture it can be
528 * IRQ controller or host processor ID.
529 * @dst_host_irq: IRQ number of the destination host IRQ controller
530 * @ia_id: Device ID of the interrupt aggregator in which the
531 * vint resides.
532 * @vint: Virtual interrupt number if the interrupt route
533 * is through an interrupt aggregator.
534 * @global_event: Global event that is to be mapped to interrupt
535 * aggregator virtual interrupt status bit.
536 * @vint_status_bit: Virtual interrupt status bit if the interrupt route
537 * utilizes an interrupt aggregator status bit.
538 * @secondary_host: Host ID of the IRQ destination computing entity. This is
539 * required only when destination host id is different
540 * from ti sci interface host id.
541 *
542 * Request type is TI_SCI_MSG_SET/RELEASE_IRQ.
543 * Response is generic ACK / NACK message.
544 */
545struct ti_sci_msg_req_manage_irq {
546 struct ti_sci_msg_hdr hdr;
547#define MSG_FLAG_DST_ID_VALID TI_SCI_MSG_FLAG(0)
548#define MSG_FLAG_DST_HOST_IRQ_VALID TI_SCI_MSG_FLAG(1)
549#define MSG_FLAG_IA_ID_VALID TI_SCI_MSG_FLAG(2)
550#define MSG_FLAG_VINT_VALID TI_SCI_MSG_FLAG(3)
551#define MSG_FLAG_GLB_EVNT_VALID TI_SCI_MSG_FLAG(4)
552#define MSG_FLAG_VINT_STS_BIT_VALID TI_SCI_MSG_FLAG(5)
553#define MSG_FLAG_SHOST_VALID TI_SCI_MSG_FLAG(31)
554 u32 valid_params;
555 u16 src_id;
556 u16 src_index;
557 u16 dst_id;
558 u16 dst_host_irq;
559 u16 ia_id;
560 u16 vint;
561 u16 global_event;
562 u8 vint_status_bit;
563 u8 secondary_host;
564} __packed;
565
464#endif /* __TI_SCI_H */ 566#endif /* __TI_SCI_H */
diff --git a/drivers/gpio/gpio-thunderx.c b/drivers/gpio/gpio-thunderx.c
index 1306722faa5a..715371b5102a 100644
--- a/drivers/gpio/gpio-thunderx.c
+++ b/drivers/gpio/gpio-thunderx.c
@@ -363,22 +363,16 @@ static int thunderx_gpio_irq_request_resources(struct irq_data *data)
363{ 363{
364 struct thunderx_line *txline = irq_data_get_irq_chip_data(data); 364 struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
365 struct thunderx_gpio *txgpio = txline->txgpio; 365 struct thunderx_gpio *txgpio = txline->txgpio;
366 struct irq_data *parent_data = data->parent_data;
367 int r; 366 int r;
368 367
369 r = gpiochip_lock_as_irq(&txgpio->chip, txline->line); 368 r = gpiochip_lock_as_irq(&txgpio->chip, txline->line);
370 if (r) 369 if (r)
371 return r; 370 return r;
372 371
373 if (parent_data && parent_data->chip->irq_request_resources) { 372 r = irq_chip_request_resources_parent(data);
374 r = parent_data->chip->irq_request_resources(parent_data); 373 if (r)
375 if (r) 374 gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
376 goto error;
377 }
378 375
379 return 0;
380error:
381 gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
382 return r; 376 return r;
383} 377}
384 378
@@ -386,10 +380,8 @@ static void thunderx_gpio_irq_release_resources(struct irq_data *data)
386{ 380{
387 struct thunderx_line *txline = irq_data_get_irq_chip_data(data); 381 struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
388 struct thunderx_gpio *txgpio = txline->txgpio; 382 struct thunderx_gpio *txgpio = txline->txgpio;
389 struct irq_data *parent_data = data->parent_data;
390 383
391 if (parent_data && parent_data->chip->irq_release_resources) 384 irq_chip_release_resources_parent(data);
392 parent_data->chip->irq_release_resources(parent_data);
393 385
394 gpiochip_unlock_as_irq(&txgpio->chip, txline->line); 386 gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
395} 387}
diff --git a/drivers/hid/intel-ish-hid/Makefile b/drivers/hid/intel-ish-hid/Makefile
index 2de97e4b7740..f0a82b1c7cb9 100644
--- a/drivers/hid/intel-ish-hid/Makefile
+++ b/drivers/hid/intel-ish-hid/Makefile
@@ -23,4 +23,4 @@ intel-ishtp-hid-objs += ishtp-hid-client.o
23obj-$(CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER) += intel-ishtp-loader.o 23obj-$(CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER) += intel-ishtp-loader.o
24intel-ishtp-loader-objs += ishtp-fw-loader.o 24intel-ishtp-loader-objs += ishtp-fw-loader.o
25 25
26ccflags-y += -Idrivers/hid/intel-ish-hid/ishtp 26ccflags-y += -I $(srctree)/$(src)/ishtp
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 9732a81bb7dd..d389d4fb0623 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -714,7 +714,7 @@ static int i2c_dev_irq_from_resources(const struct resource *resources,
714} 714}
715 715
716/** 716/**
717 * i2c_new_device - instantiate an i2c device 717 * i2c_new_client_device - instantiate an i2c device
718 * @adap: the adapter managing the device 718 * @adap: the adapter managing the device
719 * @info: describes one I2C device; bus_num is ignored 719 * @info: describes one I2C device; bus_num is ignored
720 * Context: can sleep 720 * Context: can sleep
@@ -727,17 +727,17 @@ static int i2c_dev_irq_from_resources(const struct resource *resources,
727 * before any i2c_adapter could exist. 727 * before any i2c_adapter could exist.
728 * 728 *
729 * This returns the new i2c client, which may be saved for later use with 729 * This returns the new i2c client, which may be saved for later use with
730 * i2c_unregister_device(); or NULL to indicate an error. 730 * i2c_unregister_device(); or an ERR_PTR to describe the error.
731 */ 731 */
732struct i2c_client * 732static struct i2c_client *
733i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) 733i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
734{ 734{
735 struct i2c_client *client; 735 struct i2c_client *client;
736 int status; 736 int status;
737 737
738 client = kzalloc(sizeof *client, GFP_KERNEL); 738 client = kzalloc(sizeof *client, GFP_KERNEL);
739 if (!client) 739 if (!client)
740 return NULL; 740 return ERR_PTR(-ENOMEM);
741 741
742 client->adapter = adap; 742 client->adapter = adap;
743 743
@@ -803,7 +803,31 @@ out_err:
803 client->name, client->addr, status); 803 client->name, client->addr, status);
804out_err_silent: 804out_err_silent:
805 kfree(client); 805 kfree(client);
806 return NULL; 806 return ERR_PTR(status);
807}
808EXPORT_SYMBOL_GPL(i2c_new_client_device);
809
810/**
811 * i2c_new_device - instantiate an i2c device
812 * @adap: the adapter managing the device
813 * @info: describes one I2C device; bus_num is ignored
814 * Context: can sleep
815 *
816 * This deprecated function has the same functionality as
817 * @i2c_new_client_device, it just returns NULL instead of an ERR_PTR in case of
818 * an error for compatibility with current I2C API. It will be removed once all
819 * users are converted.
820 *
821 * This returns the new i2c client, which may be saved for later use with
822 * i2c_unregister_device(); or NULL to indicate an error.
823 */
824struct i2c_client *
825i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
826{
827 struct i2c_client *ret;
828
829 ret = i2c_new_client_device(adap, info);
830 return IS_ERR(ret) ? NULL : ret;
807} 831}
808EXPORT_SYMBOL_GPL(i2c_new_device); 832EXPORT_SYMBOL_GPL(i2c_new_device);
809 833
@@ -854,7 +878,7 @@ static struct i2c_driver dummy_driver = {
854}; 878};
855 879
856/** 880/**
857 * i2c_new_dummy - return a new i2c device bound to a dummy driver 881 * i2c_new_dummy_device - return a new i2c device bound to a dummy driver
858 * @adapter: the adapter managing the device 882 * @adapter: the adapter managing the device
859 * @address: seven bit address to be used 883 * @address: seven bit address to be used
860 * Context: can sleep 884 * Context: can sleep
@@ -869,18 +893,86 @@ static struct i2c_driver dummy_driver = {
869 * different driver. 893 * different driver.
870 * 894 *
871 * This returns the new i2c client, which should be saved for later use with 895 * This returns the new i2c client, which should be saved for later use with
872 * i2c_unregister_device(); or NULL to indicate an error. 896 * i2c_unregister_device(); or an ERR_PTR to describe the error.
873 */ 897 */
874struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address) 898static struct i2c_client *
899i2c_new_dummy_device(struct i2c_adapter *adapter, u16 address)
875{ 900{
876 struct i2c_board_info info = { 901 struct i2c_board_info info = {
877 I2C_BOARD_INFO("dummy", address), 902 I2C_BOARD_INFO("dummy", address),
878 }; 903 };
879 904
880 return i2c_new_device(adapter, &info); 905 return i2c_new_client_device(adapter, &info);
906}
907EXPORT_SYMBOL_GPL(i2c_new_dummy_device);
908
909/**
910 * i2c_new_dummy - return a new i2c device bound to a dummy driver
911 * @adapter: the adapter managing the device
912 * @address: seven bit address to be used
913 * Context: can sleep
914 *
915 * This deprecated function has the same functionality as @i2c_new_dummy_device,
916 * it just returns NULL instead of an ERR_PTR in case of an error for
917 * compatibility with current I2C API. It will be removed once all users are
918 * converted.
919 *
920 * This returns the new i2c client, which should be saved for later use with
921 * i2c_unregister_device(); or NULL to indicate an error.
922 */
923struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
924{
925 struct i2c_client *ret;
926
927 ret = i2c_new_dummy_device(adapter, address);
928 return IS_ERR(ret) ? NULL : ret;
881} 929}
882EXPORT_SYMBOL_GPL(i2c_new_dummy); 930EXPORT_SYMBOL_GPL(i2c_new_dummy);
883 931
932struct i2c_dummy_devres {
933 struct i2c_client *client;
934};
935
936static void devm_i2c_release_dummy(struct device *dev, void *res)
937{
938 struct i2c_dummy_devres *this = res;
939
940 i2c_unregister_device(this->client);
941}
942
943/**
944 * devm_i2c_new_dummy_device - return a new i2c device bound to a dummy driver
945 * @dev: device the managed resource is bound to
946 * @adapter: the adapter managing the device
947 * @address: seven bit address to be used
948 * Context: can sleep
949 *
950 * This is the device-managed version of @i2c_new_dummy_device. It returns the
951 * new i2c client or an ERR_PTR in case of an error.
952 */
953struct i2c_client *devm_i2c_new_dummy_device(struct device *dev,
954 struct i2c_adapter *adapter,
955 u16 address)
956{
957 struct i2c_dummy_devres *dr;
958 struct i2c_client *client;
959
960 dr = devres_alloc(devm_i2c_release_dummy, sizeof(*dr), GFP_KERNEL);
961 if (!dr)
962 return ERR_PTR(-ENOMEM);
963
964 client = i2c_new_dummy_device(adapter, address);
965 if (IS_ERR(client)) {
966 devres_free(dr);
967 } else {
968 dr->client = client;
969 devres_add(dev, dr);
970 }
971
972 return client;
973}
974EXPORT_SYMBOL_GPL(devm_i2c_new_dummy_device);
975
884/** 976/**
885 * i2c_new_secondary_device - Helper to get the instantiated secondary address 977 * i2c_new_secondary_device - Helper to get the instantiated secondary address
886 * and create the associated device 978 * and create the associated device
@@ -1000,9 +1092,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
1000 info.flags |= I2C_CLIENT_SLAVE; 1092 info.flags |= I2C_CLIENT_SLAVE;
1001 } 1093 }
1002 1094
1003 client = i2c_new_device(adap, &info); 1095 client = i2c_new_client_device(adap, &info);
1004 if (!client) 1096 if (IS_ERR(client))
1005 return -EINVAL; 1097 return PTR_ERR(client);
1006 1098
1007 /* Keep track of the added device */ 1099 /* Keep track of the added device */
1008 mutex_lock(&adap->userspace_clients_lock); 1100 mutex_lock(&adap->userspace_clients_lock);
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 15b831113ded..e559e43c8ac2 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -94,6 +94,7 @@ config IOMMU_DMA
94 bool 94 bool
95 select IOMMU_API 95 select IOMMU_API
96 select IOMMU_IOVA 96 select IOMMU_IOVA
97 select IRQ_MSI_IOMMU
97 select NEED_SG_DMA_LENGTH 98 select NEED_SG_DMA_LENGTH
98 99
99config FSL_PAMU 100config FSL_PAMU
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 5e898047c390..129c4badf9ae 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -907,17 +907,18 @@ out_free_page:
907 return NULL; 907 return NULL;
908} 908}
909 909
910void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) 910int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr)
911{ 911{
912 struct device *dev = msi_desc_to_dev(irq_get_msi_desc(irq)); 912 struct device *dev = msi_desc_to_dev(desc);
913 struct iommu_domain *domain = iommu_get_domain_for_dev(dev); 913 struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
914 struct iommu_dma_cookie *cookie; 914 struct iommu_dma_cookie *cookie;
915 struct iommu_dma_msi_page *msi_page; 915 struct iommu_dma_msi_page *msi_page;
916 phys_addr_t msi_addr = (u64)msg->address_hi << 32 | msg->address_lo;
917 unsigned long flags; 916 unsigned long flags;
918 917
919 if (!domain || !domain->iova_cookie) 918 if (!domain || !domain->iova_cookie) {
920 return; 919 desc->iommu_cookie = NULL;
920 return 0;
921 }
921 922
922 cookie = domain->iova_cookie; 923 cookie = domain->iova_cookie;
923 924
@@ -930,19 +931,26 @@ void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg)
930 msi_page = iommu_dma_get_msi_page(dev, msi_addr, domain); 931 msi_page = iommu_dma_get_msi_page(dev, msi_addr, domain);
931 spin_unlock_irqrestore(&cookie->msi_lock, flags); 932 spin_unlock_irqrestore(&cookie->msi_lock, flags);
932 933
933 if (WARN_ON(!msi_page)) { 934 msi_desc_set_iommu_cookie(desc, msi_page);
934 /* 935
935 * We're called from a void callback, so the best we can do is 936 if (!msi_page)
936 * 'fail' by filling the message with obviously bogus values. 937 return -ENOMEM;
937 * Since we got this far due to an IOMMU being present, it's 938 return 0;
938 * not like the existing address would have worked anyway... 939}
939 */ 940
940 msg->address_hi = ~0U; 941void iommu_dma_compose_msi_msg(struct msi_desc *desc,
941 msg->address_lo = ~0U; 942 struct msi_msg *msg)
942 msg->data = ~0U; 943{
943 } else { 944 struct device *dev = msi_desc_to_dev(desc);
944 msg->address_hi = upper_32_bits(msi_page->iova); 945 const struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
945 msg->address_lo &= cookie_msi_granule(cookie) - 1; 946 const struct iommu_dma_msi_page *msi_page;
946 msg->address_lo += lower_32_bits(msi_page->iova); 947
947 } 948 msi_page = msi_desc_get_iommu_cookie(desc);
949
950 if (!domain || !domain->iova_cookie || WARN_ON(!msi_page))
951 return;
952
953 msg->address_hi = upper_32_bits(msi_page->iova);
954 msg->address_lo &= cookie_msi_granule(domain->iova_cookie) - 1;
955 msg->address_lo += lower_32_bits(msi_page->iova);
948} 956}
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index cf7984991062..1c1f3f66dfd3 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -6,7 +6,6 @@ config IRQCHIP
6 6
7config ARM_GIC 7config ARM_GIC
8 bool 8 bool
9 select IRQ_DOMAIN
10 select IRQ_DOMAIN_HIERARCHY 9 select IRQ_DOMAIN_HIERARCHY
11 select GENERIC_IRQ_MULTI_HANDLER 10 select GENERIC_IRQ_MULTI_HANDLER
12 select GENERIC_IRQ_EFFECTIVE_AFF_MASK 11 select GENERIC_IRQ_EFFECTIVE_AFF_MASK
@@ -33,7 +32,6 @@ config GIC_NON_BANKED
33 32
34config ARM_GIC_V3 33config ARM_GIC_V3
35 bool 34 bool
36 select IRQ_DOMAIN
37 select GENERIC_IRQ_MULTI_HANDLER 35 select GENERIC_IRQ_MULTI_HANDLER
38 select IRQ_DOMAIN_HIERARCHY 36 select IRQ_DOMAIN_HIERARCHY
39 select PARTITION_PERCPU 37 select PARTITION_PERCPU
@@ -59,7 +57,6 @@ config ARM_GIC_V3_ITS_FSL_MC
59 57
60config ARM_NVIC 58config ARM_NVIC
61 bool 59 bool
62 select IRQ_DOMAIN
63 select IRQ_DOMAIN_HIERARCHY 60 select IRQ_DOMAIN_HIERARCHY
64 select GENERIC_IRQ_CHIP 61 select GENERIC_IRQ_CHIP
65 62
@@ -358,7 +355,6 @@ config STM32_EXTI
358config QCOM_IRQ_COMBINER 355config QCOM_IRQ_COMBINER
359 bool "QCOM IRQ combiner support" 356 bool "QCOM IRQ combiner support"
360 depends on ARCH_QCOM && ACPI 357 depends on ARCH_QCOM && ACPI
361 select IRQ_DOMAIN
362 select IRQ_DOMAIN_HIERARCHY 358 select IRQ_DOMAIN_HIERARCHY
363 help 359 help
364 Say yes here to add support for the IRQ combiner devices embedded 360 Say yes here to add support for the IRQ combiner devices embedded
@@ -375,7 +371,6 @@ config IRQ_UNIPHIER_AIDET
375config MESON_IRQ_GPIO 371config MESON_IRQ_GPIO
376 bool "Meson GPIO Interrupt Multiplexer" 372 bool "Meson GPIO Interrupt Multiplexer"
377 depends on ARCH_MESON 373 depends on ARCH_MESON
378 select IRQ_DOMAIN
379 select IRQ_DOMAIN_HIERARCHY 374 select IRQ_DOMAIN_HIERARCHY
380 help 375 help
381 Support Meson SoC Family GPIO Interrupt Multiplexer 376 Support Meson SoC Family GPIO Interrupt Multiplexer
@@ -391,7 +386,6 @@ config GOLDFISH_PIC
391config QCOM_PDC 386config QCOM_PDC
392 bool "QCOM PDC" 387 bool "QCOM PDC"
393 depends on ARCH_QCOM 388 depends on ARCH_QCOM
394 select IRQ_DOMAIN
395 select IRQ_DOMAIN_HIERARCHY 389 select IRQ_DOMAIN_HIERARCHY
396 help 390 help
397 Power Domain Controller driver to manage and configure wakeup 391 Power Domain Controller driver to manage and configure wakeup
@@ -431,6 +425,27 @@ config LS1X_IRQ
431 help 425 help
432 Support for the Loongson-1 platform Interrupt Controller. 426 Support for the Loongson-1 platform Interrupt Controller.
433 427
428config TI_SCI_INTR_IRQCHIP
429 bool
430 depends on TI_SCI_PROTOCOL
431 select IRQ_DOMAIN_HIERARCHY
432 help
433 This enables the irqchip driver support for K3 Interrupt router
434 over TI System Control Interface available on some new TI's SoCs.
435 If you wish to use interrupt router irq resources managed by the
436 TI System Controller, say Y here. Otherwise, say N.
437
438config TI_SCI_INTA_IRQCHIP
439 bool
440 depends on TI_SCI_PROTOCOL
441 select IRQ_DOMAIN_HIERARCHY
442 select TI_SCI_INTA_MSI_DOMAIN
443 help
444 This enables the irqchip driver support for K3 Interrupt aggregator
445 over TI System Control Interface available on some new TI's SoCs.
446 If you wish to use interrupt aggregator irq resources managed by the
447 TI System Controller, say Y here. Otherwise, say N.
448
434endmenu 449endmenu
435 450
436config SIFIVE_PLIC 451config SIFIVE_PLIC
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f8c66e958a64..606a003a0000 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -98,3 +98,5 @@ obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
98obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o 98obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
99obj-$(CONFIG_MADERA_IRQ) += irq-madera.o 99obj-$(CONFIG_MADERA_IRQ) += irq-madera.o
100obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o 100obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o
101obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o
102obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o
diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
index 0f6e30e9009d..0acebac1920b 100644
--- a/drivers/irqchip/irq-bcm7038-l1.c
+++ b/drivers/irqchip/irq-bcm7038-l1.c
@@ -343,6 +343,9 @@ int __init bcm7038_l1_of_init(struct device_node *dn,
343 goto out_unmap; 343 goto out_unmap;
344 } 344 }
345 345
346 pr_info("registered BCM7038 L1 intc (%pOF, IRQs: %d)\n",
347 dn, IRQS_PER_WORD * intc->n_words);
348
346 return 0; 349 return 0;
347 350
348out_unmap: 351out_unmap:
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c
index 8968e5e93fcb..541bdca9f4af 100644
--- a/drivers/irqchip/irq-bcm7120-l2.c
+++ b/drivers/irqchip/irq-bcm7120-l2.c
@@ -318,6 +318,9 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
318 } 318 }
319 } 319 }
320 320
321 pr_info("registered %s intc (%pOF, parent IRQ(s): %d)\n",
322 intc_name, dn, data->num_parent_irqs);
323
321 return 0; 324 return 0;
322 325
323out_free_domain: 326out_free_domain:
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c
index 5e4ca139e4ea..a0642b59befa 100644
--- a/drivers/irqchip/irq-brcmstb-l2.c
+++ b/drivers/irqchip/irq-brcmstb-l2.c
@@ -264,6 +264,8 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
264 ct->chip.irq_set_wake = irq_gc_set_wake; 264 ct->chip.irq_set_wake = irq_gc_set_wake;
265 } 265 }
266 266
267 pr_info("registered L2 intc (%pOF, parent irq: %d)\n", np, parent_irq);
268
267 return 0; 269 return 0;
268 270
269out_free_domain: 271out_free_domain:
diff --git a/drivers/irqchip/irq-gic-pm.c b/drivers/irqchip/irq-gic-pm.c
index ecafd295c31c..c4aac0977d8a 100644
--- a/drivers/irqchip/irq-gic-pm.c
+++ b/drivers/irqchip/irq-gic-pm.c
@@ -19,7 +19,6 @@
19#include <linux/of_irq.h> 19#include <linux/of_irq.h>
20#include <linux/irqchip/arm-gic.h> 20#include <linux/irqchip/arm-gic.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/pm_clock.h>
23#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25 24
@@ -28,17 +27,27 @@ struct gic_clk_data {
28 const char *const *clocks; 27 const char *const *clocks;
29}; 28};
30 29
30struct gic_chip_pm {
31 struct gic_chip_data *chip_data;
32 const struct gic_clk_data *clk_data;
33 struct clk_bulk_data *clks;
34};
35
31static int gic_runtime_resume(struct device *dev) 36static int gic_runtime_resume(struct device *dev)
32{ 37{
33 struct gic_chip_data *gic = dev_get_drvdata(dev); 38 struct gic_chip_pm *chip_pm = dev_get_drvdata(dev);
39 struct gic_chip_data *gic = chip_pm->chip_data;
40 const struct gic_clk_data *data = chip_pm->clk_data;
34 int ret; 41 int ret;
35 42
36 ret = pm_clk_resume(dev); 43 ret = clk_bulk_prepare_enable(data->num_clocks, chip_pm->clks);
37 if (ret) 44 if (ret) {
45 dev_err(dev, "clk_enable failed: %d\n", ret);
38 return ret; 46 return ret;
47 }
39 48
40 /* 49 /*
41 * On the very first resume, the pointer to the driver data 50 * On the very first resume, the pointer to chip_pm->chip_data
42 * will be NULL and this is intentional, because we do not 51 * will be NULL and this is intentional, because we do not
43 * want to restore the GIC on the very first resume. So if 52 * want to restore the GIC on the very first resume. So if
44 * the pointer is not valid just return. 53 * the pointer is not valid just return.
@@ -54,35 +63,14 @@ static int gic_runtime_resume(struct device *dev)
54 63
55static int gic_runtime_suspend(struct device *dev) 64static int gic_runtime_suspend(struct device *dev)
56{ 65{
57 struct gic_chip_data *gic = dev_get_drvdata(dev); 66 struct gic_chip_pm *chip_pm = dev_get_drvdata(dev);
67 struct gic_chip_data *gic = chip_pm->chip_data;
68 const struct gic_clk_data *data = chip_pm->clk_data;
58 69
59 gic_dist_save(gic); 70 gic_dist_save(gic);
60 gic_cpu_save(gic); 71 gic_cpu_save(gic);
61 72
62 return pm_clk_suspend(dev); 73 clk_bulk_disable_unprepare(data->num_clocks, chip_pm->clks);
63}
64
65static int gic_get_clocks(struct device *dev, const struct gic_clk_data *data)
66{
67 unsigned int i;
68 int ret;
69
70 if (!dev || !data)
71 return -EINVAL;
72
73 ret = pm_clk_create(dev);
74 if (ret)
75 return ret;
76
77 for (i = 0; i < data->num_clocks; i++) {
78 ret = of_pm_clk_add_clk(dev, data->clocks[i]);
79 if (ret) {
80 dev_err(dev, "failed to add clock %s\n",
81 data->clocks[i]);
82 pm_clk_destroy(dev);
83 return ret;
84 }
85 }
86 74
87 return 0; 75 return 0;
88} 76}
@@ -91,8 +79,8 @@ static int gic_probe(struct platform_device *pdev)
91{ 79{
92 struct device *dev = &pdev->dev; 80 struct device *dev = &pdev->dev;
93 const struct gic_clk_data *data; 81 const struct gic_clk_data *data;
94 struct gic_chip_data *gic; 82 struct gic_chip_pm *chip_pm;
95 int ret, irq; 83 int ret, irq, i;
96 84
97 data = of_device_get_match_data(&pdev->dev); 85 data = of_device_get_match_data(&pdev->dev);
98 if (!data) { 86 if (!data) {
@@ -100,28 +88,41 @@ static int gic_probe(struct platform_device *pdev)
100 return -ENODEV; 88 return -ENODEV;
101 } 89 }
102 90
91 chip_pm = devm_kzalloc(dev, sizeof(*chip_pm), GFP_KERNEL);
92 if (!chip_pm)
93 return -ENOMEM;
94
103 irq = irq_of_parse_and_map(dev->of_node, 0); 95 irq = irq_of_parse_and_map(dev->of_node, 0);
104 if (!irq) { 96 if (!irq) {
105 dev_err(dev, "no parent interrupt found!\n"); 97 dev_err(dev, "no parent interrupt found!\n");
106 return -EINVAL; 98 return -EINVAL;
107 } 99 }
108 100
109 ret = gic_get_clocks(dev, data); 101 chip_pm->clks = devm_kcalloc(dev, data->num_clocks,
102 sizeof(*chip_pm->clks), GFP_KERNEL);
103 if (!chip_pm->clks)
104 return -ENOMEM;
105
106 for (i = 0; i < data->num_clocks; i++)
107 chip_pm->clks[i].id = data->clocks[i];
108
109 ret = devm_clk_bulk_get(dev, data->num_clocks, chip_pm->clks);
110 if (ret) 110 if (ret)
111 goto irq_dispose; 111 goto irq_dispose;
112 112
113 chip_pm->clk_data = data;
114 dev_set_drvdata(dev, chip_pm);
115
113 pm_runtime_enable(dev); 116 pm_runtime_enable(dev);
114 117
115 ret = pm_runtime_get_sync(dev); 118 ret = pm_runtime_get_sync(dev);
116 if (ret < 0) 119 if (ret < 0)
117 goto rpm_disable; 120 goto rpm_disable;
118 121
119 ret = gic_of_init_child(dev, &gic, irq); 122 ret = gic_of_init_child(dev, &chip_pm->chip_data, irq);
120 if (ret) 123 if (ret)
121 goto rpm_put; 124 goto rpm_put;
122 125
123 platform_set_drvdata(pdev, gic);
124
125 pm_runtime_put(dev); 126 pm_runtime_put(dev);
126 127
127 dev_info(dev, "GIC IRQ controller registered\n"); 128 dev_info(dev, "GIC IRQ controller registered\n");
@@ -132,7 +133,6 @@ rpm_put:
132 pm_runtime_put_sync(dev); 133 pm_runtime_put_sync(dev);
133rpm_disable: 134rpm_disable:
134 pm_runtime_disable(dev); 135 pm_runtime_disable(dev);
135 pm_clk_destroy(dev);
136irq_dispose: 136irq_dispose:
137 irq_dispose_mapping(irq); 137 irq_dispose_mapping(irq);
138 138
@@ -142,6 +142,8 @@ irq_dispose:
142static const struct dev_pm_ops gic_pm_ops = { 142static const struct dev_pm_ops gic_pm_ops = {
143 SET_RUNTIME_PM_OPS(gic_runtime_suspend, 143 SET_RUNTIME_PM_OPS(gic_runtime_suspend,
144 gic_runtime_resume, NULL) 144 gic_runtime_resume, NULL)
145 SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
146 pm_runtime_force_resume)
145}; 147};
146 148
147static const char * const gic400_clocks[] = { 149static const char * const gic400_clocks[] = {
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index de14e06fd9ec..3c77ab676e54 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -110,7 +110,7 @@ static void gicv2m_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
110 if (v2m->flags & GICV2M_NEEDS_SPI_OFFSET) 110 if (v2m->flags & GICV2M_NEEDS_SPI_OFFSET)
111 msg->data -= v2m->spi_offset; 111 msg->data -= v2m->spi_offset;
112 112
113 iommu_dma_map_msi_msg(data->irq, msg); 113 iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), msg);
114} 114}
115 115
116static struct irq_chip gicv2m_irq_chip = { 116static struct irq_chip gicv2m_irq_chip = {
@@ -167,6 +167,7 @@ static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq,
167static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, 167static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
168 unsigned int nr_irqs, void *args) 168 unsigned int nr_irqs, void *args)
169{ 169{
170 msi_alloc_info_t *info = args;
170 struct v2m_data *v2m = NULL, *tmp; 171 struct v2m_data *v2m = NULL, *tmp;
171 int hwirq, offset, i, err = 0; 172 int hwirq, offset, i, err = 0;
172 173
@@ -186,6 +187,11 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
186 187
187 hwirq = v2m->spi_start + offset; 188 hwirq = v2m->spi_start + offset;
188 189
190 err = iommu_dma_prepare_msi(info->desc,
191 v2m->res.start + V2M_MSI_SETSPI_NS);
192 if (err)
193 return err;
194
189 for (i = 0; i < nr_irqs; i++) { 195 for (i = 0; i < nr_irqs; i++) {
190 err = gicv2m_irq_gic_domain_alloc(domain, virq + i, hwirq + i); 196 err = gicv2m_irq_gic_domain_alloc(domain, virq + i, hwirq + i);
191 if (err) 197 if (err)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 128ac893d7e4..cfb9b4e5f914 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -26,7 +26,6 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/irqdomain.h> 27#include <linux/irqdomain.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/list_sort.h>
30#include <linux/log2.h> 29#include <linux/log2.h>
31#include <linux/memblock.h> 30#include <linux/memblock.h>
32#include <linux/mm.h> 31#include <linux/mm.h>
@@ -1179,7 +1178,7 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
1179 msg->address_hi = upper_32_bits(addr); 1178 msg->address_hi = upper_32_bits(addr);
1180 msg->data = its_get_event_id(d); 1179 msg->data = its_get_event_id(d);
1181 1180
1182 iommu_dma_map_msi_msg(d->irq, msg); 1181 iommu_dma_compose_msi_msg(irq_data_get_msi_desc(d), msg);
1183} 1182}
1184 1183
1185static int its_irq_set_irqchip_state(struct irq_data *d, 1184static int its_irq_set_irqchip_state(struct irq_data *d,
@@ -1465,9 +1464,8 @@ static struct lpi_range *mk_lpi_range(u32 base, u32 span)
1465{ 1464{
1466 struct lpi_range *range; 1465 struct lpi_range *range;
1467 1466
1468 range = kzalloc(sizeof(*range), GFP_KERNEL); 1467 range = kmalloc(sizeof(*range), GFP_KERNEL);
1469 if (range) { 1468 if (range) {
1470 INIT_LIST_HEAD(&range->entry);
1471 range->base_id = base; 1469 range->base_id = base;
1472 range->span = span; 1470 range->span = span;
1473 } 1471 }
@@ -1475,31 +1473,6 @@ static struct lpi_range *mk_lpi_range(u32 base, u32 span)
1475 return range; 1473 return range;
1476} 1474}
1477 1475
1478static int lpi_range_cmp(void *priv, struct list_head *a, struct list_head *b)
1479{
1480 struct lpi_range *ra, *rb;
1481
1482 ra = container_of(a, struct lpi_range, entry);
1483 rb = container_of(b, struct lpi_range, entry);
1484
1485 return ra->base_id - rb->base_id;
1486}
1487
1488static void merge_lpi_ranges(void)
1489{
1490 struct lpi_range *range, *tmp;
1491
1492 list_for_each_entry_safe(range, tmp, &lpi_range_list, entry) {
1493 if (!list_is_last(&range->entry, &lpi_range_list) &&
1494 (tmp->base_id == (range->base_id + range->span))) {
1495 tmp->base_id = range->base_id;
1496 tmp->span += range->span;
1497 list_del(&range->entry);
1498 kfree(range);
1499 }
1500 }
1501}
1502
1503static int alloc_lpi_range(u32 nr_lpis, u32 *base) 1476static int alloc_lpi_range(u32 nr_lpis, u32 *base)
1504{ 1477{
1505 struct lpi_range *range, *tmp; 1478 struct lpi_range *range, *tmp;
@@ -1529,25 +1502,49 @@ static int alloc_lpi_range(u32 nr_lpis, u32 *base)
1529 return err; 1502 return err;
1530} 1503}
1531 1504
1505static void merge_lpi_ranges(struct lpi_range *a, struct lpi_range *b)
1506{
1507 if (&a->entry == &lpi_range_list || &b->entry == &lpi_range_list)
1508 return;
1509 if (a->base_id + a->span != b->base_id)
1510 return;
1511 b->base_id = a->base_id;
1512 b->span += a->span;
1513 list_del(&a->entry);
1514 kfree(a);
1515}
1516
1532static int free_lpi_range(u32 base, u32 nr_lpis) 1517static int free_lpi_range(u32 base, u32 nr_lpis)
1533{ 1518{
1534 struct lpi_range *new; 1519 struct lpi_range *new, *old;
1535 int err = 0; 1520
1521 new = mk_lpi_range(base, nr_lpis);
1522 if (!new)
1523 return -ENOMEM;
1536 1524
1537 mutex_lock(&lpi_range_lock); 1525 mutex_lock(&lpi_range_lock);
1538 1526
1539 new = mk_lpi_range(base, nr_lpis); 1527 list_for_each_entry_reverse(old, &lpi_range_list, entry) {
1540 if (!new) { 1528 if (old->base_id < base)
1541 err = -ENOMEM; 1529 break;
1542 goto out;
1543 } 1530 }
1531 /*
1532 * old is the last element with ->base_id smaller than base,
1533 * so new goes right after it. If there are no elements with
1534 * ->base_id smaller than base, &old->entry ends up pointing
1535 * at the head of the list, and inserting new it the start of
1536 * the list is the right thing to do in that case as well.
1537 */
1538 list_add(&new->entry, &old->entry);
1539 /*
1540 * Now check if we can merge with the preceding and/or
1541 * following ranges.
1542 */
1543 merge_lpi_ranges(old, new);
1544 merge_lpi_ranges(new, list_next_entry(new, entry));
1544 1545
1545 list_add(&new->entry, &lpi_range_list);
1546 list_sort(NULL, &lpi_range_list, lpi_range_cmp);
1547 merge_lpi_ranges();
1548out:
1549 mutex_unlock(&lpi_range_lock); 1546 mutex_unlock(&lpi_range_lock);
1550 return err; 1547 return 0;
1551} 1548}
1552 1549
1553static int __init its_lpi_init(u32 id_bits) 1550static int __init its_lpi_init(u32 id_bits)
@@ -2487,7 +2484,7 @@ static int its_msi_prepare(struct irq_domain *domain, struct device *dev,
2487 int err = 0; 2484 int err = 0;
2488 2485
2489 /* 2486 /*
2490 * We ignore "dev" entierely, and rely on the dev_id that has 2487 * We ignore "dev" entirely, and rely on the dev_id that has
2491 * been passed via the scratchpad. This limits this domain's 2488 * been passed via the scratchpad. This limits this domain's
2492 * usefulness to upper layers that definitely know that they 2489 * usefulness to upper layers that definitely know that they
2493 * are built on top of the ITS. 2490 * are built on top of the ITS.
@@ -2566,6 +2563,7 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
2566{ 2563{
2567 msi_alloc_info_t *info = args; 2564 msi_alloc_info_t *info = args;
2568 struct its_device *its_dev = info->scratchpad[0].ptr; 2565 struct its_device *its_dev = info->scratchpad[0].ptr;
2566 struct its_node *its = its_dev->its;
2569 irq_hw_number_t hwirq; 2567 irq_hw_number_t hwirq;
2570 int err; 2568 int err;
2571 int i; 2569 int i;
@@ -2574,6 +2572,10 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
2574 if (err) 2572 if (err)
2575 return err; 2573 return err;
2576 2574
2575 err = iommu_dma_prepare_msi(info->desc, its->get_msi_base(its_dev));
2576 if (err)
2577 return err;
2578
2577 for (i = 0; i < nr_irqs; i++) { 2579 for (i = 0; i < nr_irqs; i++) {
2578 err = its_irq_gic_domain_alloc(domain, virq + i, hwirq + i); 2580 err = its_irq_gic_domain_alloc(domain, virq + i, hwirq + i);
2579 if (err) 2581 if (err)
diff --git a/drivers/irqchip/irq-gic-v3-mbi.c b/drivers/irqchip/irq-gic-v3-mbi.c
index fbfa7ff6deb1..563a9b366294 100644
--- a/drivers/irqchip/irq-gic-v3-mbi.c
+++ b/drivers/irqchip/irq-gic-v3-mbi.c
@@ -84,6 +84,7 @@ static void mbi_free_msi(struct mbi_range *mbi, unsigned int hwirq,
84static int mbi_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, 84static int mbi_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
85 unsigned int nr_irqs, void *args) 85 unsigned int nr_irqs, void *args)
86{ 86{
87 msi_alloc_info_t *info = args;
87 struct mbi_range *mbi = NULL; 88 struct mbi_range *mbi = NULL;
88 int hwirq, offset, i, err = 0; 89 int hwirq, offset, i, err = 0;
89 90
@@ -104,6 +105,11 @@ static int mbi_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
104 105
105 hwirq = mbi->spi_start + offset; 106 hwirq = mbi->spi_start + offset;
106 107
108 err = iommu_dma_prepare_msi(info->desc,
109 mbi_phys_base + GICD_SETSPI_NSR);
110 if (err)
111 return err;
112
107 for (i = 0; i < nr_irqs; i++) { 113 for (i = 0; i < nr_irqs; i++) {
108 err = mbi_irq_gic_domain_alloc(domain, virq + i, hwirq + i); 114 err = mbi_irq_gic_domain_alloc(domain, virq + i, hwirq + i);
109 if (err) 115 if (err)
@@ -142,7 +148,7 @@ static void mbi_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
142 msg[0].address_lo = lower_32_bits(mbi_phys_base + GICD_SETSPI_NSR); 148 msg[0].address_lo = lower_32_bits(mbi_phys_base + GICD_SETSPI_NSR);
143 msg[0].data = data->parent_data->hwirq; 149 msg[0].data = data->parent_data->hwirq;
144 150
145 iommu_dma_map_msi_msg(data->irq, msg); 151 iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), msg);
146} 152}
147 153
148#ifdef CONFIG_PCI_MSI 154#ifdef CONFIG_PCI_MSI
@@ -202,7 +208,7 @@ static void mbi_compose_mbi_msg(struct irq_data *data, struct msi_msg *msg)
202 msg[1].address_lo = lower_32_bits(mbi_phys_base + GICD_CLRSPI_NSR); 208 msg[1].address_lo = lower_32_bits(mbi_phys_base + GICD_CLRSPI_NSR);
203 msg[1].data = data->parent_data->hwirq; 209 msg[1].data = data->parent_data->hwirq;
204 210
205 iommu_dma_map_msi_msg(data->irq, &msg[1]); 211 iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), &msg[1]);
206} 212}
207 213
208/* Platform-MSI specific irqchip */ 214/* Platform-MSI specific irqchip */
diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
index 88df3d00052c..290531ec3d61 100644
--- a/drivers/irqchip/irq-imx-irqsteer.c
+++ b/drivers/irqchip/irq-imx-irqsteer.c
@@ -144,7 +144,6 @@ static int imx_irqsteer_probe(struct platform_device *pdev)
144{ 144{
145 struct device_node *np = pdev->dev.of_node; 145 struct device_node *np = pdev->dev.of_node;
146 struct irqsteer_data *data; 146 struct irqsteer_data *data;
147 struct resource *res;
148 u32 irqs_num; 147 u32 irqs_num;
149 int i, ret; 148 int i, ret;
150 149
@@ -152,8 +151,7 @@ static int imx_irqsteer_probe(struct platform_device *pdev)
152 if (!data) 151 if (!data)
153 return -ENOMEM; 152 return -ENOMEM;
154 153
155 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 154 data->regs = devm_platform_ioremap_resource(pdev, 0);
156 data->regs = devm_ioremap_resource(&pdev->dev, res);
157 if (IS_ERR(data->regs)) { 155 if (IS_ERR(data->regs)) {
158 dev_err(&pdev->dev, "failed to initialize reg\n"); 156 dev_err(&pdev->dev, "failed to initialize reg\n");
159 return PTR_ERR(data->regs); 157 return PTR_ERR(data->regs);
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index c671b3212010..669d29105772 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -100,7 +100,7 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
100 msg->data |= cpumask_first(mask); 100 msg->data |= cpumask_first(mask);
101 } 101 }
102 102
103 iommu_dma_map_msi_msg(data->irq, msg); 103 iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), msg);
104} 104}
105 105
106static int ls_scfg_msi_set_affinity(struct irq_data *irq_data, 106static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
@@ -141,6 +141,7 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain,
141 unsigned int nr_irqs, 141 unsigned int nr_irqs,
142 void *args) 142 void *args)
143{ 143{
144 msi_alloc_info_t *info = args;
144 struct ls_scfg_msi *msi_data = domain->host_data; 145 struct ls_scfg_msi *msi_data = domain->host_data;
145 int pos, err = 0; 146 int pos, err = 0;
146 147
@@ -157,6 +158,10 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain,
157 if (err) 158 if (err)
158 return err; 159 return err;
159 160
161 err = iommu_dma_prepare_msi(info->desc, msi_data->msiir_addr);
162 if (err)
163 return err;
164
160 irq_domain_set_info(domain, virq, pos, 165 irq_domain_set_info(domain, virq, pos,
161 &ls_scfg_msi_parent_chip, msi_data, 166 &ls_scfg_msi_parent_chip, msi_data,
162 handle_simple_irq, NULL, NULL); 167 handle_simple_irq, NULL, NULL);
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index 8c039525703f..04c05a18600c 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -389,10 +389,8 @@ static int intc_irqpin_probe(struct platform_device *pdev)
389 int k; 389 int k;
390 390
391 p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL); 391 p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL);
392 if (!p) { 392 if (!p)
393 dev_err(dev, "failed to allocate driver data\n");
394 return -ENOMEM; 393 return -ENOMEM;
395 }
396 394
397 /* deal with driver instance configuration */ 395 /* deal with driver instance configuration */
398 of_property_read_u32(dev->of_node, "sense-bitfield-width", 396 of_property_read_u32(dev->of_node, "sense-bitfield-width",
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 7bd1d4cb2e19..e00f2fa27f00 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -14,8 +14,10 @@
14#include <linux/irqchip.h> 14#include <linux/irqchip.h>
15#include <linux/irqchip/chained_irq.h> 15#include <linux/irqchip/chained_irq.h>
16#include <linux/irqdomain.h> 16#include <linux/irqdomain.h>
17#include <linux/module.h>
17#include <linux/of_address.h> 18#include <linux/of_address.h>
18#include <linux/of_irq.h> 19#include <linux/of_irq.h>
20#include <linux/of_platform.h>
19#include <linux/syscore_ops.h> 21#include <linux/syscore_ops.h>
20 22
21#include <dt-bindings/interrupt-controller/arm-gic.h> 23#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -37,12 +39,6 @@ struct stm32_exti_bank {
37 39
38#define UNDEF_REG ~0 40#define UNDEF_REG ~0
39 41
40enum stm32_exti_hwspinlock {
41 HWSPINLOCK_UNKNOWN,
42 HWSPINLOCK_NONE,
43 HWSPINLOCK_READY,
44};
45
46struct stm32_desc_irq { 42struct stm32_desc_irq {
47 u32 exti; 43 u32 exti;
48 u32 irq_parent; 44 u32 irq_parent;
@@ -69,8 +65,6 @@ struct stm32_exti_host_data {
69 void __iomem *base; 65 void __iomem *base;
70 struct stm32_exti_chip_data *chips_data; 66 struct stm32_exti_chip_data *chips_data;
71 const struct stm32_exti_drv_data *drv_data; 67 const struct stm32_exti_drv_data *drv_data;
72 struct device_node *node;
73 enum stm32_exti_hwspinlock hwlock_state;
74 struct hwspinlock *hwlock; 68 struct hwspinlock *hwlock;
75}; 69};
76 70
@@ -285,49 +279,27 @@ static int stm32_exti_set_type(struct irq_data *d,
285 279
286static int stm32_exti_hwspin_lock(struct stm32_exti_chip_data *chip_data) 280static int stm32_exti_hwspin_lock(struct stm32_exti_chip_data *chip_data)
287{ 281{
288 struct stm32_exti_host_data *host_data = chip_data->host_data; 282 int ret, timeout = 0;
289 struct hwspinlock *hwlock;
290 int id, ret = 0, timeout = 0;
291
292 /* first time, check for hwspinlock availability */
293 if (unlikely(host_data->hwlock_state == HWSPINLOCK_UNKNOWN)) {
294 id = of_hwspin_lock_get_id(host_data->node, 0);
295 if (id >= 0) {
296 hwlock = hwspin_lock_request_specific(id);
297 if (hwlock) {
298 /* found valid hwspinlock */
299 host_data->hwlock_state = HWSPINLOCK_READY;
300 host_data->hwlock = hwlock;
301 pr_debug("%s hwspinlock = %d\n", __func__, id);
302 } else {
303 host_data->hwlock_state = HWSPINLOCK_NONE;
304 }
305 } else if (id != -EPROBE_DEFER) {
306 host_data->hwlock_state = HWSPINLOCK_NONE;
307 } else {
308 /* hwspinlock driver shall be ready at that stage */
309 ret = -EPROBE_DEFER;
310 }
311 }
312 283
313 if (likely(host_data->hwlock_state == HWSPINLOCK_READY)) { 284 if (!chip_data->host_data->hwlock)
314 /* 285 return 0;
315 * Use the x_raw API since we are under spin_lock protection. 286
316 * Do not use the x_timeout API because we are under irq_disable 287 /*
317 * mode (see __setup_irq()) 288 * Use the x_raw API since we are under spin_lock protection.
318 */ 289 * Do not use the x_timeout API because we are under irq_disable
319 do { 290 * mode (see __setup_irq())
320 ret = hwspin_trylock_raw(host_data->hwlock); 291 */
321 if (!ret) 292 do {
322 return 0; 293 ret = hwspin_trylock_raw(chip_data->host_data->hwlock);
323 294 if (!ret)
324 udelay(HWSPNLCK_RETRY_DELAY); 295 return 0;
325 timeout += HWSPNLCK_RETRY_DELAY; 296
326 } while (timeout < HWSPNLCK_TIMEOUT); 297 udelay(HWSPNLCK_RETRY_DELAY);
327 298 timeout += HWSPNLCK_RETRY_DELAY;
328 if (ret == -EBUSY) 299 } while (timeout < HWSPNLCK_TIMEOUT);
329 ret = -ETIMEDOUT; 300
330 } 301 if (ret == -EBUSY)
302 ret = -ETIMEDOUT;
331 303
332 if (ret) 304 if (ret)
333 pr_err("%s can't get hwspinlock (%d)\n", __func__, ret); 305 pr_err("%s can't get hwspinlock (%d)\n", __func__, ret);
@@ -337,7 +309,7 @@ static int stm32_exti_hwspin_lock(struct stm32_exti_chip_data *chip_data)
337 309
338static void stm32_exti_hwspin_unlock(struct stm32_exti_chip_data *chip_data) 310static void stm32_exti_hwspin_unlock(struct stm32_exti_chip_data *chip_data)
339{ 311{
340 if (likely(chip_data->host_data->hwlock_state == HWSPINLOCK_READY)) 312 if (chip_data->host_data->hwlock)
341 hwspin_unlock_raw(chip_data->host_data->hwlock); 313 hwspin_unlock_raw(chip_data->host_data->hwlock);
342} 314}
343 315
@@ -586,8 +558,7 @@ static int stm32_exti_h_set_affinity(struct irq_data *d,
586 return -EINVAL; 558 return -EINVAL;
587} 559}
588 560
589#ifdef CONFIG_PM 561static int __maybe_unused stm32_exti_h_suspend(void)
590static int stm32_exti_h_suspend(void)
591{ 562{
592 struct stm32_exti_chip_data *chip_data; 563 struct stm32_exti_chip_data *chip_data;
593 int i; 564 int i;
@@ -602,7 +573,7 @@ static int stm32_exti_h_suspend(void)
602 return 0; 573 return 0;
603} 574}
604 575
605static void stm32_exti_h_resume(void) 576static void __maybe_unused stm32_exti_h_resume(void)
606{ 577{
607 struct stm32_exti_chip_data *chip_data; 578 struct stm32_exti_chip_data *chip_data;
608 int i; 579 int i;
@@ -616,17 +587,22 @@ static void stm32_exti_h_resume(void)
616} 587}
617 588
618static struct syscore_ops stm32_exti_h_syscore_ops = { 589static struct syscore_ops stm32_exti_h_syscore_ops = {
590#ifdef CONFIG_PM_SLEEP
619 .suspend = stm32_exti_h_suspend, 591 .suspend = stm32_exti_h_suspend,
620 .resume = stm32_exti_h_resume, 592 .resume = stm32_exti_h_resume,
593#endif
621}; 594};
622 595
623static void stm32_exti_h_syscore_init(void) 596static void stm32_exti_h_syscore_init(struct stm32_exti_host_data *host_data)
624{ 597{
598 stm32_host_data = host_data;
625 register_syscore_ops(&stm32_exti_h_syscore_ops); 599 register_syscore_ops(&stm32_exti_h_syscore_ops);
626} 600}
627#else 601
628static inline void stm32_exti_h_syscore_init(void) {} 602static void stm32_exti_h_syscore_deinit(void)
629#endif 603{
604 unregister_syscore_ops(&stm32_exti_h_syscore_ops);
605}
630 606
631static struct irq_chip stm32_exti_h_chip = { 607static struct irq_chip stm32_exti_h_chip = {
632 .name = "stm32-exti-h", 608 .name = "stm32-exti-h",
@@ -683,8 +659,6 @@ stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd,
683 return NULL; 659 return NULL;
684 660
685 host_data->drv_data = dd; 661 host_data->drv_data = dd;
686 host_data->node = node;
687 host_data->hwlock_state = HWSPINLOCK_UNKNOWN;
688 host_data->chips_data = kcalloc(dd->bank_nr, 662 host_data->chips_data = kcalloc(dd->bank_nr,
689 sizeof(struct stm32_exti_chip_data), 663 sizeof(struct stm32_exti_chip_data),
690 GFP_KERNEL); 664 GFP_KERNEL);
@@ -711,7 +685,8 @@ free_host_data:
711 685
712static struct 686static struct
713stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data, 687stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data,
714 u32 bank_idx) 688 u32 bank_idx,
689 struct device_node *node)
715{ 690{
716 const struct stm32_exti_bank *stm32_bank; 691 const struct stm32_exti_bank *stm32_bank;
717 struct stm32_exti_chip_data *chip_data; 692 struct stm32_exti_chip_data *chip_data;
@@ -731,7 +706,7 @@ stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data,
731 writel_relaxed(0, base + stm32_bank->imr_ofst); 706 writel_relaxed(0, base + stm32_bank->imr_ofst);
732 writel_relaxed(0, base + stm32_bank->emr_ofst); 707 writel_relaxed(0, base + stm32_bank->emr_ofst);
733 708
734 pr_info("%pOF: bank%d\n", h_data->node, bank_idx); 709 pr_info("%pOF: bank%d\n", node, bank_idx);
735 710
736 return chip_data; 711 return chip_data;
737} 712}
@@ -771,7 +746,7 @@ static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data,
771 struct stm32_exti_chip_data *chip_data; 746 struct stm32_exti_chip_data *chip_data;
772 747
773 stm32_bank = drv_data->exti_banks[i]; 748 stm32_bank = drv_data->exti_banks[i];
774 chip_data = stm32_exti_chip_init(host_data, i); 749 chip_data = stm32_exti_chip_init(host_data, i, node);
775 750
776 gc = irq_get_domain_generic_chip(domain, i * IRQS_PER_BANK); 751 gc = irq_get_domain_generic_chip(domain, i * IRQS_PER_BANK);
777 752
@@ -815,50 +790,130 @@ static const struct irq_domain_ops stm32_exti_h_domain_ops = {
815 .xlate = irq_domain_xlate_twocell, 790 .xlate = irq_domain_xlate_twocell,
816}; 791};
817 792
818static int 793static void stm32_exti_remove_irq(void *data)
819__init stm32_exti_hierarchy_init(const struct stm32_exti_drv_data *drv_data, 794{
820 struct device_node *node, 795 struct irq_domain *domain = data;
821 struct device_node *parent) 796
797 irq_domain_remove(domain);
798}
799
800static int stm32_exti_remove(struct platform_device *pdev)
801{
802 stm32_exti_h_syscore_deinit();
803 return 0;
804}
805
806static int stm32_exti_probe(struct platform_device *pdev)
822{ 807{
808 int ret, i;
809 struct device *dev = &pdev->dev;
810 struct device_node *np = dev->of_node;
823 struct irq_domain *parent_domain, *domain; 811 struct irq_domain *parent_domain, *domain;
824 struct stm32_exti_host_data *host_data; 812 struct stm32_exti_host_data *host_data;
825 int ret, i; 813 const struct stm32_exti_drv_data *drv_data;
814 struct resource *res;
826 815
827 parent_domain = irq_find_host(parent); 816 host_data = devm_kzalloc(dev, sizeof(*host_data), GFP_KERNEL);
828 if (!parent_domain) { 817 if (!host_data)
829 pr_err("interrupt-parent not found\n"); 818 return -ENOMEM;
830 return -EINVAL; 819
820 /* check for optional hwspinlock which may be not available yet */
821 ret = of_hwspin_lock_get_id(np, 0);
822 if (ret == -EPROBE_DEFER)
823 /* hwspinlock framework not yet ready */
824 return ret;
825
826 if (ret >= 0) {
827 host_data->hwlock = devm_hwspin_lock_request_specific(dev, ret);
828 if (!host_data->hwlock) {
829 dev_err(dev, "Failed to request hwspinlock\n");
830 return -EINVAL;
831 }
832 } else if (ret != -ENOENT) {
833 /* note: ENOENT is a valid case (means 'no hwspinlock') */
834 dev_err(dev, "Failed to get hwspinlock\n");
835 return ret;
831 } 836 }
832 837
833 host_data = stm32_exti_host_init(drv_data, node); 838 /* initialize host_data */
834 if (!host_data) 839 drv_data = of_device_get_match_data(dev);
840 if (!drv_data) {
841 dev_err(dev, "no of match data\n");
842 return -ENODEV;
843 }
844 host_data->drv_data = drv_data;
845
846 host_data->chips_data = devm_kcalloc(dev, drv_data->bank_nr,
847 sizeof(*host_data->chips_data),
848 GFP_KERNEL);
849 if (!host_data->chips_data)
835 return -ENOMEM; 850 return -ENOMEM;
836 851
852 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
853 host_data->base = devm_ioremap_resource(dev, res);
854 if (IS_ERR(host_data->base)) {
855 dev_err(dev, "Unable to map registers\n");
856 return PTR_ERR(host_data->base);
857 }
858
837 for (i = 0; i < drv_data->bank_nr; i++) 859 for (i = 0; i < drv_data->bank_nr; i++)
838 stm32_exti_chip_init(host_data, i); 860 stm32_exti_chip_init(host_data, i, np);
861
862 parent_domain = irq_find_host(of_irq_find_parent(np));
863 if (!parent_domain) {
864 dev_err(dev, "GIC interrupt-parent not found\n");
865 return -EINVAL;
866 }
839 867
840 domain = irq_domain_add_hierarchy(parent_domain, 0, 868 domain = irq_domain_add_hierarchy(parent_domain, 0,
841 drv_data->bank_nr * IRQS_PER_BANK, 869 drv_data->bank_nr * IRQS_PER_BANK,
842 node, &stm32_exti_h_domain_ops, 870 np, &stm32_exti_h_domain_ops,
843 host_data); 871 host_data);
844 872
845 if (!domain) { 873 if (!domain) {
846 pr_err("%pOFn: Could not register exti domain.\n", node); 874 dev_err(dev, "Could not register exti domain\n");
847 ret = -ENOMEM; 875 return -ENOMEM;
848 goto out_unmap;
849 } 876 }
850 877
851 stm32_exti_h_syscore_init(); 878 ret = devm_add_action_or_reset(dev, stm32_exti_remove_irq, domain);
879 if (ret)
880 return ret;
881
882 stm32_exti_h_syscore_init(host_data);
852 883
853 return 0; 884 return 0;
885}
854 886
855out_unmap: 887/* platform driver only for MP1 */
856 iounmap(host_data->base); 888static const struct of_device_id stm32_exti_ids[] = {
857 kfree(host_data->chips_data); 889 { .compatible = "st,stm32mp1-exti", .data = &stm32mp1_drv_data},
858 kfree(host_data); 890 {},
859 return ret; 891};
892MODULE_DEVICE_TABLE(of, stm32_exti_ids);
893
894static struct platform_driver stm32_exti_driver = {
895 .probe = stm32_exti_probe,
896 .remove = stm32_exti_remove,
897 .driver = {
898 .name = "stm32_exti",
899 .of_match_table = stm32_exti_ids,
900 },
901};
902
903static int __init stm32_exti_arch_init(void)
904{
905 return platform_driver_register(&stm32_exti_driver);
860} 906}
861 907
908static void __exit stm32_exti_arch_exit(void)
909{
910 return platform_driver_unregister(&stm32_exti_driver);
911}
912
913arch_initcall(stm32_exti_arch_init);
914module_exit(stm32_exti_arch_exit);
915
916/* no platform driver for F4 and H7 */
862static int __init stm32f4_exti_of_init(struct device_node *np, 917static int __init stm32f4_exti_of_init(struct device_node *np,
863 struct device_node *parent) 918 struct device_node *parent)
864{ 919{
@@ -874,11 +929,3 @@ static int __init stm32h7_exti_of_init(struct device_node *np,
874} 929}
875 930
876IRQCHIP_DECLARE(stm32h7_exti, "st,stm32h7-exti", stm32h7_exti_of_init); 931IRQCHIP_DECLARE(stm32h7_exti, "st,stm32h7-exti", stm32h7_exti_of_init);
877
878static int __init stm32mp1_exti_of_init(struct device_node *np,
879 struct device_node *parent)
880{
881 return stm32_exti_hierarchy_init(&stm32mp1_drv_data, np, parent);
882}
883
884IRQCHIP_DECLARE(stm32mp1_exti, "st,stm32mp1-exti", stm32mp1_exti_of_init);
diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c
new file mode 100644
index 000000000000..011b60a49e3f
--- /dev/null
+++ b/drivers/irqchip/irq-ti-sci-inta.c
@@ -0,0 +1,615 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Texas Instruments' K3 Interrupt Aggregator irqchip driver
4 *
5 * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
6 * Lokesh Vutla <lokeshvutla@ti.com>
7 */
8
9#include <linux/err.h>
10#include <linux/io.h>
11#include <linux/irqchip.h>
12#include <linux/irqdomain.h>
13#include <linux/interrupt.h>
14#include <linux/msi.h>
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/of_address.h>
18#include <linux/of_irq.h>
19#include <linux/of_platform.h>
20#include <linux/irqchip/chained_irq.h>
21#include <linux/soc/ti/ti_sci_inta_msi.h>
22#include <linux/soc/ti/ti_sci_protocol.h>
23#include <asm-generic/msi.h>
24
25#define TI_SCI_DEV_ID_MASK 0xffff
26#define TI_SCI_DEV_ID_SHIFT 16
27#define TI_SCI_IRQ_ID_MASK 0xffff
28#define TI_SCI_IRQ_ID_SHIFT 0
29#define HWIRQ_TO_DEVID(hwirq) (((hwirq) >> (TI_SCI_DEV_ID_SHIFT)) & \
30 (TI_SCI_DEV_ID_MASK))
31#define HWIRQ_TO_IRQID(hwirq) ((hwirq) & (TI_SCI_IRQ_ID_MASK))
32#define TO_HWIRQ(dev, index) ((((dev) & TI_SCI_DEV_ID_MASK) << \
33 TI_SCI_DEV_ID_SHIFT) | \
34 ((index) & TI_SCI_IRQ_ID_MASK))
35
36#define MAX_EVENTS_PER_VINT 64
37#define VINT_ENABLE_SET_OFFSET 0x0
38#define VINT_ENABLE_CLR_OFFSET 0x8
39#define VINT_STATUS_OFFSET 0x18
40
41/**
42 * struct ti_sci_inta_event_desc - Description of an event coming to
43 * Interrupt Aggregator. This serves
44 * as a mapping table for global event,
45 * hwirq and vint bit.
46 * @global_event: Global event number corresponding to this event
47 * @hwirq: Hwirq of the incoming interrupt
48 * @vint_bit: Corresponding vint bit to which this event is attached.
49 */
50struct ti_sci_inta_event_desc {
51 u16 global_event;
52 u32 hwirq;
53 u8 vint_bit;
54};
55
56/**
57 * struct ti_sci_inta_vint_desc - Description of a virtual interrupt coming out
58 * of Interrupt Aggregator.
59 * @domain: Pointer to IRQ domain to which this vint belongs.
60 * @list: List entry for the vint list
61 * @event_map: Bitmap to manage the allocation of events to vint.
62 * @events: Array of event descriptors assigned to this vint.
63 * @parent_virq: Linux IRQ number that gets attached to parent
64 * @vint_id: TISCI vint ID
65 */
66struct ti_sci_inta_vint_desc {
67 struct irq_domain *domain;
68 struct list_head list;
69 DECLARE_BITMAP(event_map, MAX_EVENTS_PER_VINT);
70 struct ti_sci_inta_event_desc events[MAX_EVENTS_PER_VINT];
71 unsigned int parent_virq;
72 u16 vint_id;
73};
74
75/**
76 * struct ti_sci_inta_irq_domain - Structure representing a TISCI based
77 * Interrupt Aggregator IRQ domain.
78 * @sci: Pointer to TISCI handle
79 * @vint: TISCI resource pointer representing IA inerrupts.
80 * @global_event: TISCI resource pointer representing global events.
81 * @vint_list: List of the vints active in the system
82 * @vint_mutex: Mutex to protect vint_list
83 * @base: Base address of the memory mapped IO registers
84 * @pdev: Pointer to platform device.
85 */
86struct ti_sci_inta_irq_domain {
87 const struct ti_sci_handle *sci;
88 struct ti_sci_resource *vint;
89 struct ti_sci_resource *global_event;
90 struct list_head vint_list;
91 /* Mutex to protect vint list */
92 struct mutex vint_mutex;
93 void __iomem *base;
94 struct platform_device *pdev;
95};
96
97#define to_vint_desc(e, i) container_of(e, struct ti_sci_inta_vint_desc, \
98 events[i])
99
100/**
101 * ti_sci_inta_irq_handler() - Chained IRQ handler for the vint irqs
102 * @desc: Pointer to irq_desc corresponding to the irq
103 */
104static void ti_sci_inta_irq_handler(struct irq_desc *desc)
105{
106 struct ti_sci_inta_vint_desc *vint_desc;
107 struct ti_sci_inta_irq_domain *inta;
108 struct irq_domain *domain;
109 unsigned int virq, bit;
110 unsigned long val;
111
112 vint_desc = irq_desc_get_handler_data(desc);
113 domain = vint_desc->domain;
114 inta = domain->host_data;
115
116 chained_irq_enter(irq_desc_get_chip(desc), desc);
117
118 val = readq_relaxed(inta->base + vint_desc->vint_id * 0x1000 +
119 VINT_STATUS_OFFSET);
120
121 for_each_set_bit(bit, &val, MAX_EVENTS_PER_VINT) {
122 virq = irq_find_mapping(domain, vint_desc->events[bit].hwirq);
123 if (virq)
124 generic_handle_irq(virq);
125 }
126
127 chained_irq_exit(irq_desc_get_chip(desc), desc);
128}
129
130/**
131 * ti_sci_inta_alloc_parent_irq() - Allocate parent irq to Interrupt aggregator
132 * @domain: IRQ domain corresponding to Interrupt Aggregator
133 *
134 * Return 0 if all went well else corresponding error value.
135 */
136static struct ti_sci_inta_vint_desc *ti_sci_inta_alloc_parent_irq(struct irq_domain *domain)
137{
138 struct ti_sci_inta_irq_domain *inta = domain->host_data;
139 struct ti_sci_inta_vint_desc *vint_desc;
140 struct irq_fwspec parent_fwspec;
141 unsigned int parent_virq;
142 u16 vint_id;
143
144 vint_id = ti_sci_get_free_resource(inta->vint);
145 if (vint_id == TI_SCI_RESOURCE_NULL)
146 return ERR_PTR(-EINVAL);
147
148 vint_desc = kzalloc(sizeof(*vint_desc), GFP_KERNEL);
149 if (!vint_desc)
150 return ERR_PTR(-ENOMEM);
151
152 vint_desc->domain = domain;
153 vint_desc->vint_id = vint_id;
154 INIT_LIST_HEAD(&vint_desc->list);
155
156 parent_fwspec.fwnode = of_node_to_fwnode(of_irq_find_parent(dev_of_node(&inta->pdev->dev)));
157 parent_fwspec.param_count = 2;
158 parent_fwspec.param[0] = inta->pdev->id;
159 parent_fwspec.param[1] = vint_desc->vint_id;
160
161 parent_virq = irq_create_fwspec_mapping(&parent_fwspec);
162 if (parent_virq <= 0) {
163 kfree(vint_desc);
164 return ERR_PTR(parent_virq);
165 }
166 vint_desc->parent_virq = parent_virq;
167
168 list_add_tail(&vint_desc->list, &inta->vint_list);
169 irq_set_chained_handler_and_data(vint_desc->parent_virq,
170 ti_sci_inta_irq_handler, vint_desc);
171
172 return vint_desc;
173}
174
175/**
176 * ti_sci_inta_alloc_event() - Attach an event to a IA vint.
177 * @vint_desc: Pointer to vint_desc to which the event gets attached
178 * @free_bit: Bit inside vint to which event gets attached
179 * @hwirq: hwirq of the input event
180 *
181 * Return event_desc pointer if all went ok else appropriate error value.
182 */
183static struct ti_sci_inta_event_desc *ti_sci_inta_alloc_event(struct ti_sci_inta_vint_desc *vint_desc,
184 u16 free_bit,
185 u32 hwirq)
186{
187 struct ti_sci_inta_irq_domain *inta = vint_desc->domain->host_data;
188 struct ti_sci_inta_event_desc *event_desc;
189 u16 dev_id, dev_index;
190 int err;
191
192 dev_id = HWIRQ_TO_DEVID(hwirq);
193 dev_index = HWIRQ_TO_IRQID(hwirq);
194
195 event_desc = &vint_desc->events[free_bit];
196 event_desc->hwirq = hwirq;
197 event_desc->vint_bit = free_bit;
198 event_desc->global_event = ti_sci_get_free_resource(inta->global_event);
199 if (event_desc->global_event == TI_SCI_RESOURCE_NULL)
200 return ERR_PTR(-EINVAL);
201
202 err = inta->sci->ops.rm_irq_ops.set_event_map(inta->sci,
203 dev_id, dev_index,
204 inta->pdev->id,
205 vint_desc->vint_id,
206 event_desc->global_event,
207 free_bit);
208 if (err)
209 goto free_global_event;
210
211 return event_desc;
212free_global_event:
213 ti_sci_release_resource(inta->global_event, event_desc->global_event);
214 return ERR_PTR(err);
215}
216
217/**
218 * ti_sci_inta_alloc_irq() - Allocate an irq within INTA domain
219 * @domain: irq_domain pointer corresponding to INTA
220 * @hwirq: hwirq of the input event
221 *
222 * Note: Allocation happens in the following manner:
223 * - Find a free bit available in any of the vints available in the list.
224 * - If not found, allocate a vint from the vint pool
225 * - Attach the free bit to input hwirq.
226 * Return event_desc if all went ok else appropriate error value.
227 */
228static struct ti_sci_inta_event_desc *ti_sci_inta_alloc_irq(struct irq_domain *domain,
229 u32 hwirq)
230{
231 struct ti_sci_inta_irq_domain *inta = domain->host_data;
232 struct ti_sci_inta_vint_desc *vint_desc = NULL;
233 struct ti_sci_inta_event_desc *event_desc;
234 u16 free_bit;
235
236 mutex_lock(&inta->vint_mutex);
237 list_for_each_entry(vint_desc, &inta->vint_list, list) {
238 free_bit = find_first_zero_bit(vint_desc->event_map,
239 MAX_EVENTS_PER_VINT);
240 if (free_bit != MAX_EVENTS_PER_VINT) {
241 set_bit(free_bit, vint_desc->event_map);
242 goto alloc_event;
243 }
244 }
245
246 /* No free bits available. Allocate a new vint */
247 vint_desc = ti_sci_inta_alloc_parent_irq(domain);
248 if (IS_ERR(vint_desc)) {
249 mutex_unlock(&inta->vint_mutex);
250 return ERR_PTR(PTR_ERR(vint_desc));
251 }
252
253 free_bit = find_first_zero_bit(vint_desc->event_map,
254 MAX_EVENTS_PER_VINT);
255 set_bit(free_bit, vint_desc->event_map);
256
257alloc_event:
258 event_desc = ti_sci_inta_alloc_event(vint_desc, free_bit, hwirq);
259 if (IS_ERR(event_desc))
260 clear_bit(free_bit, vint_desc->event_map);
261
262 mutex_unlock(&inta->vint_mutex);
263 return event_desc;
264}
265
266/**
267 * ti_sci_inta_free_parent_irq() - Free a parent irq to INTA
268 * @inta: Pointer to inta domain.
269 * @vint_desc: Pointer to vint_desc that needs to be freed.
270 */
271static void ti_sci_inta_free_parent_irq(struct ti_sci_inta_irq_domain *inta,
272 struct ti_sci_inta_vint_desc *vint_desc)
273{
274 if (find_first_bit(vint_desc->event_map, MAX_EVENTS_PER_VINT) == MAX_EVENTS_PER_VINT) {
275 list_del(&vint_desc->list);
276 ti_sci_release_resource(inta->vint, vint_desc->vint_id);
277 irq_dispose_mapping(vint_desc->parent_virq);
278 kfree(vint_desc);
279 }
280}
281
282/**
283 * ti_sci_inta_free_irq() - Free an IRQ within INTA domain
284 * @event_desc: Pointer to event_desc that needs to be freed.
285 * @hwirq: Hwirq number within INTA domain that needs to be freed
286 */
287static void ti_sci_inta_free_irq(struct ti_sci_inta_event_desc *event_desc,
288 u32 hwirq)
289{
290 struct ti_sci_inta_vint_desc *vint_desc;
291 struct ti_sci_inta_irq_domain *inta;
292
293 vint_desc = to_vint_desc(event_desc, event_desc->vint_bit);
294 inta = vint_desc->domain->host_data;
295 /* free event irq */
296 mutex_lock(&inta->vint_mutex);
297 inta->sci->ops.rm_irq_ops.free_event_map(inta->sci,
298 HWIRQ_TO_DEVID(hwirq),
299 HWIRQ_TO_IRQID(hwirq),
300 inta->pdev->id,
301 vint_desc->vint_id,
302 event_desc->global_event,
303 event_desc->vint_bit);
304
305 clear_bit(event_desc->vint_bit, vint_desc->event_map);
306 ti_sci_release_resource(inta->global_event, event_desc->global_event);
307 event_desc->global_event = TI_SCI_RESOURCE_NULL;
308 event_desc->hwirq = 0;
309
310 ti_sci_inta_free_parent_irq(inta, vint_desc);
311 mutex_unlock(&inta->vint_mutex);
312}
313
314/**
315 * ti_sci_inta_request_resources() - Allocate resources for input irq
316 * @data: Pointer to corresponding irq_data
317 *
318 * Note: This is the core api where the actual allocation happens for input
319 * hwirq. This allocation involves creating a parent irq for vint.
320 * If this is done in irq_domain_ops.alloc() then a deadlock is reached
321 * for allocation. So this allocation is being done in request_resources()
322 *
323 * Return: 0 if all went well else corresponding error.
324 */
325static int ti_sci_inta_request_resources(struct irq_data *data)
326{
327 struct ti_sci_inta_event_desc *event_desc;
328
329 event_desc = ti_sci_inta_alloc_irq(data->domain, data->hwirq);
330 if (IS_ERR(event_desc))
331 return PTR_ERR(event_desc);
332
333 data->chip_data = event_desc;
334
335 return 0;
336}
337
338/**
339 * ti_sci_inta_release_resources - Release resources for input irq
340 * @data: Pointer to corresponding irq_data
341 *
342 * Note: Corresponding to request_resources(), all the unmapping and deletion
343 * of parent vint irqs happens in this api.
344 */
345static void ti_sci_inta_release_resources(struct irq_data *data)
346{
347 struct ti_sci_inta_event_desc *event_desc;
348
349 event_desc = irq_data_get_irq_chip_data(data);
350 ti_sci_inta_free_irq(event_desc, data->hwirq);
351}
352
353/**
354 * ti_sci_inta_manage_event() - Control the event based on the offset
355 * @data: Pointer to corresponding irq_data
356 * @offset: register offset using which event is controlled.
357 */
358static void ti_sci_inta_manage_event(struct irq_data *data, u32 offset)
359{
360 struct ti_sci_inta_event_desc *event_desc;
361 struct ti_sci_inta_vint_desc *vint_desc;
362 struct ti_sci_inta_irq_domain *inta;
363
364 event_desc = irq_data_get_irq_chip_data(data);
365 vint_desc = to_vint_desc(event_desc, event_desc->vint_bit);
366 inta = data->domain->host_data;
367
368 writeq_relaxed(BIT(event_desc->vint_bit),
369 inta->base + vint_desc->vint_id * 0x1000 + offset);
370}
371
372/**
373 * ti_sci_inta_mask_irq() - Mask an event
374 * @data: Pointer to corresponding irq_data
375 */
376static void ti_sci_inta_mask_irq(struct irq_data *data)
377{
378 ti_sci_inta_manage_event(data, VINT_ENABLE_CLR_OFFSET);
379}
380
381/**
382 * ti_sci_inta_unmask_irq() - Unmask an event
383 * @data: Pointer to corresponding irq_data
384 */
385static void ti_sci_inta_unmask_irq(struct irq_data *data)
386{
387 ti_sci_inta_manage_event(data, VINT_ENABLE_SET_OFFSET);
388}
389
390/**
391 * ti_sci_inta_ack_irq() - Ack an event
392 * @data: Pointer to corresponding irq_data
393 */
394static void ti_sci_inta_ack_irq(struct irq_data *data)
395{
396 /*
397 * Do not clear the event if hardware is capable of sending
398 * a down event.
399 */
400 if (irqd_get_trigger_type(data) != IRQF_TRIGGER_HIGH)
401 ti_sci_inta_manage_event(data, VINT_STATUS_OFFSET);
402}
403
404static int ti_sci_inta_set_affinity(struct irq_data *d,
405 const struct cpumask *mask_val, bool force)
406{
407 return -EINVAL;
408}
409
410/**
411 * ti_sci_inta_set_type() - Update the trigger type of the irq.
412 * @data: Pointer to corresponding irq_data
413 * @type: Trigger type as specified by user
414 *
415 * Note: This updates the handle_irq callback for level msi.
416 *
417 * Return 0 if all went well else appropriate error.
418 */
419static int ti_sci_inta_set_type(struct irq_data *data, unsigned int type)
420{
421 /*
422 * .alloc default sets handle_edge_irq. But if the user specifies
423 * that IRQ is level MSI, then update the handle to handle_level_irq
424 */
425 switch (type & IRQ_TYPE_SENSE_MASK) {
426 case IRQF_TRIGGER_HIGH:
427 irq_set_handler_locked(data, handle_level_irq);
428 return 0;
429 case IRQF_TRIGGER_RISING:
430 return 0;
431 default:
432 return -EINVAL;
433 }
434
435 return -EINVAL;
436}
437
438static struct irq_chip ti_sci_inta_irq_chip = {
439 .name = "INTA",
440 .irq_ack = ti_sci_inta_ack_irq,
441 .irq_mask = ti_sci_inta_mask_irq,
442 .irq_set_type = ti_sci_inta_set_type,
443 .irq_unmask = ti_sci_inta_unmask_irq,
444 .irq_set_affinity = ti_sci_inta_set_affinity,
445 .irq_request_resources = ti_sci_inta_request_resources,
446 .irq_release_resources = ti_sci_inta_release_resources,
447};
448
449/**
450 * ti_sci_inta_irq_domain_free() - Free an IRQ from the IRQ domain
451 * @domain: Domain to which the irqs belong
452 * @virq: base linux virtual IRQ to be freed.
453 * @nr_irqs: Number of continuous irqs to be freed
454 */
455static void ti_sci_inta_irq_domain_free(struct irq_domain *domain,
456 unsigned int virq, unsigned int nr_irqs)
457{
458 struct irq_data *data = irq_domain_get_irq_data(domain, virq);
459
460 irq_domain_reset_irq_data(data);
461}
462
463/**
464 * ti_sci_inta_irq_domain_alloc() - Allocate Interrupt aggregator IRQs
465 * @domain: Point to the interrupt aggregator IRQ domain
466 * @virq: Corresponding Linux virtual IRQ number
467 * @nr_irqs: Continuous irqs to be allocated
468 * @data: Pointer to firmware specifier
469 *
470 * No actual allocation happens here.
471 *
472 * Return 0 if all went well else appropriate error value.
473 */
474static int ti_sci_inta_irq_domain_alloc(struct irq_domain *domain,
475 unsigned int virq, unsigned int nr_irqs,
476 void *data)
477{
478 msi_alloc_info_t *arg = data;
479
480 irq_domain_set_info(domain, virq, arg->hwirq, &ti_sci_inta_irq_chip,
481 NULL, handle_edge_irq, NULL, NULL);
482
483 return 0;
484}
485
486static const struct irq_domain_ops ti_sci_inta_irq_domain_ops = {
487 .free = ti_sci_inta_irq_domain_free,
488 .alloc = ti_sci_inta_irq_domain_alloc,
489};
490
491static struct irq_chip ti_sci_inta_msi_irq_chip = {
492 .name = "MSI-INTA",
493 .flags = IRQCHIP_SUPPORTS_LEVEL_MSI,
494};
495
496static void ti_sci_inta_msi_set_desc(msi_alloc_info_t *arg,
497 struct msi_desc *desc)
498{
499 struct platform_device *pdev = to_platform_device(desc->dev);
500
501 arg->desc = desc;
502 arg->hwirq = TO_HWIRQ(pdev->id, desc->inta.dev_index);
503}
504
505static struct msi_domain_ops ti_sci_inta_msi_ops = {
506 .set_desc = ti_sci_inta_msi_set_desc,
507};
508
509static struct msi_domain_info ti_sci_inta_msi_domain_info = {
510 .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
511 MSI_FLAG_LEVEL_CAPABLE),
512 .ops = &ti_sci_inta_msi_ops,
513 .chip = &ti_sci_inta_msi_irq_chip,
514};
515
516static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
517{
518 struct irq_domain *parent_domain, *domain, *msi_domain;
519 struct device_node *parent_node, *node;
520 struct ti_sci_inta_irq_domain *inta;
521 struct device *dev = &pdev->dev;
522 struct resource *res;
523 int ret;
524
525 node = dev_of_node(dev);
526 parent_node = of_irq_find_parent(node);
527 if (!parent_node) {
528 dev_err(dev, "Failed to get IRQ parent node\n");
529 return -ENODEV;
530 }
531
532 parent_domain = irq_find_host(parent_node);
533 if (!parent_domain)
534 return -EPROBE_DEFER;
535
536 inta = devm_kzalloc(dev, sizeof(*inta), GFP_KERNEL);
537 if (!inta)
538 return -ENOMEM;
539
540 inta->pdev = pdev;
541 inta->sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
542 if (IS_ERR(inta->sci)) {
543 ret = PTR_ERR(inta->sci);
544 if (ret != -EPROBE_DEFER)
545 dev_err(dev, "ti,sci read fail %d\n", ret);
546 inta->sci = NULL;
547 return ret;
548 }
549
550 ret = of_property_read_u32(dev->of_node, "ti,sci-dev-id", &pdev->id);
551 if (ret) {
552 dev_err(dev, "missing 'ti,sci-dev-id' property\n");
553 return -EINVAL;
554 }
555
556 inta->vint = devm_ti_sci_get_of_resource(inta->sci, dev, pdev->id,
557 "ti,sci-rm-range-vint");
558 if (IS_ERR(inta->vint)) {
559 dev_err(dev, "VINT resource allocation failed\n");
560 return PTR_ERR(inta->vint);
561 }
562
563 inta->global_event = devm_ti_sci_get_of_resource(inta->sci, dev, pdev->id,
564 "ti,sci-rm-range-global-event");
565 if (IS_ERR(inta->global_event)) {
566 dev_err(dev, "Global event resource allocation failed\n");
567 return PTR_ERR(inta->global_event);
568 }
569
570 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
571 inta->base = devm_ioremap_resource(dev, res);
572 if (IS_ERR(inta->base))
573 return -ENODEV;
574
575 domain = irq_domain_add_linear(dev_of_node(dev),
576 ti_sci_get_num_resources(inta->vint),
577 &ti_sci_inta_irq_domain_ops, inta);
578 if (!domain) {
579 dev_err(dev, "Failed to allocate IRQ domain\n");
580 return -ENOMEM;
581 }
582
583 msi_domain = ti_sci_inta_msi_create_irq_domain(of_node_to_fwnode(node),
584 &ti_sci_inta_msi_domain_info,
585 domain);
586 if (!msi_domain) {
587 irq_domain_remove(domain);
588 dev_err(dev, "Failed to allocate msi domain\n");
589 return -ENOMEM;
590 }
591
592 INIT_LIST_HEAD(&inta->vint_list);
593 mutex_init(&inta->vint_mutex);
594
595 return 0;
596}
597
598static const struct of_device_id ti_sci_inta_irq_domain_of_match[] = {
599 { .compatible = "ti,sci-inta", },
600 { /* sentinel */ },
601};
602MODULE_DEVICE_TABLE(of, ti_sci_inta_irq_domain_of_match);
603
604static struct platform_driver ti_sci_inta_irq_domain_driver = {
605 .probe = ti_sci_inta_irq_domain_probe,
606 .driver = {
607 .name = "ti-sci-inta",
608 .of_match_table = ti_sci_inta_irq_domain_of_match,
609 },
610};
611module_platform_driver(ti_sci_inta_irq_domain_driver);
612
613MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ticom>");
614MODULE_DESCRIPTION("K3 Interrupt Aggregator driver over TI SCI protocol");
615MODULE_LICENSE("GPL v2");
diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c
new file mode 100644
index 000000000000..59d51a20bbd8
--- /dev/null
+++ b/drivers/irqchip/irq-ti-sci-intr.c
@@ -0,0 +1,275 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Texas Instruments' K3 Interrupt Router irqchip driver
4 *
5 * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
6 * Lokesh Vutla <lokeshvutla@ti.com>
7 */
8
9#include <linux/err.h>
10#include <linux/module.h>
11#include <linux/moduleparam.h>
12#include <linux/io.h>
13#include <linux/irqchip.h>
14#include <linux/irqdomain.h>
15#include <linux/of_platform.h>
16#include <linux/of_address.h>
17#include <linux/of_irq.h>
18#include <linux/soc/ti/ti_sci_protocol.h>
19
20#define TI_SCI_DEV_ID_MASK 0xffff
21#define TI_SCI_DEV_ID_SHIFT 16
22#define TI_SCI_IRQ_ID_MASK 0xffff
23#define TI_SCI_IRQ_ID_SHIFT 0
24#define HWIRQ_TO_DEVID(hwirq) (((hwirq) >> (TI_SCI_DEV_ID_SHIFT)) & \
25 (TI_SCI_DEV_ID_MASK))
26#define HWIRQ_TO_IRQID(hwirq) ((hwirq) & (TI_SCI_IRQ_ID_MASK))
27#define TO_HWIRQ(dev, index) ((((dev) & TI_SCI_DEV_ID_MASK) << \
28 TI_SCI_DEV_ID_SHIFT) | \
29 ((index) & TI_SCI_IRQ_ID_MASK))
30
31/**
32 * struct ti_sci_intr_irq_domain - Structure representing a TISCI based
33 * Interrupt Router IRQ domain.
34 * @sci: Pointer to TISCI handle
35 * @dst_irq: TISCI resource pointer representing GIC irq controller.
36 * @dst_id: TISCI device ID of the GIC irq controller.
37 * @type: Specifies the trigger type supported by this Interrupt Router
38 */
39struct ti_sci_intr_irq_domain {
40 const struct ti_sci_handle *sci;
41 struct ti_sci_resource *dst_irq;
42 u32 dst_id;
43 u32 type;
44};
45
46static struct irq_chip ti_sci_intr_irq_chip = {
47 .name = "INTR",
48 .irq_eoi = irq_chip_eoi_parent,
49 .irq_mask = irq_chip_mask_parent,
50 .irq_unmask = irq_chip_unmask_parent,
51 .irq_set_type = irq_chip_set_type_parent,
52 .irq_retrigger = irq_chip_retrigger_hierarchy,
53 .irq_set_affinity = irq_chip_set_affinity_parent,
54};
55
56/**
57 * ti_sci_intr_irq_domain_translate() - Retrieve hwirq and type from
58 * IRQ firmware specific handler.
59 * @domain: Pointer to IRQ domain
60 * @fwspec: Pointer to IRQ specific firmware structure
61 * @hwirq: IRQ number identified by hardware
62 * @type: IRQ type
63 *
64 * Return 0 if all went ok else appropriate error.
65 */
66static int ti_sci_intr_irq_domain_translate(struct irq_domain *domain,
67 struct irq_fwspec *fwspec,
68 unsigned long *hwirq,
69 unsigned int *type)
70{
71 struct ti_sci_intr_irq_domain *intr = domain->host_data;
72
73 if (fwspec->param_count != 2)
74 return -EINVAL;
75
76 *hwirq = TO_HWIRQ(fwspec->param[0], fwspec->param[1]);
77 *type = intr->type;
78
79 return 0;
80}
81
82/**
83 * ti_sci_intr_irq_domain_free() - Free the specified IRQs from the domain.
84 * @domain: Domain to which the irqs belong
85 * @virq: Linux virtual IRQ to be freed.
86 * @nr_irqs: Number of continuous irqs to be freed
87 */
88static void ti_sci_intr_irq_domain_free(struct irq_domain *domain,
89 unsigned int virq, unsigned int nr_irqs)
90{
91 struct ti_sci_intr_irq_domain *intr = domain->host_data;
92 struct irq_data *data, *parent_data;
93 u16 dev_id, irq_index;
94
95 parent_data = irq_domain_get_irq_data(domain->parent, virq);
96 data = irq_domain_get_irq_data(domain, virq);
97 irq_index = HWIRQ_TO_IRQID(data->hwirq);
98 dev_id = HWIRQ_TO_DEVID(data->hwirq);
99
100 intr->sci->ops.rm_irq_ops.free_irq(intr->sci, dev_id, irq_index,
101 intr->dst_id, parent_data->hwirq);
102 ti_sci_release_resource(intr->dst_irq, parent_data->hwirq);
103 irq_domain_free_irqs_parent(domain, virq, 1);
104 irq_domain_reset_irq_data(data);
105}
106
107/**
108 * ti_sci_intr_alloc_gic_irq() - Allocate GIC specific IRQ
109 * @domain: Pointer to the interrupt router IRQ domain
110 * @virq: Corresponding Linux virtual IRQ number
111 * @hwirq: Corresponding hwirq for the IRQ within this IRQ domain
112 *
113 * Returns 0 if all went well else appropriate error pointer.
114 */
115static int ti_sci_intr_alloc_gic_irq(struct irq_domain *domain,
116 unsigned int virq, u32 hwirq)
117{
118 struct ti_sci_intr_irq_domain *intr = domain->host_data;
119 struct irq_fwspec fwspec;
120 u16 dev_id, irq_index;
121 u16 dst_irq;
122 int err;
123
124 dev_id = HWIRQ_TO_DEVID(hwirq);
125 irq_index = HWIRQ_TO_IRQID(hwirq);
126
127 dst_irq = ti_sci_get_free_resource(intr->dst_irq);
128 if (dst_irq == TI_SCI_RESOURCE_NULL)
129 return -EINVAL;
130
131 fwspec.fwnode = domain->parent->fwnode;
132 fwspec.param_count = 3;
133 fwspec.param[0] = 0; /* SPI */
134 fwspec.param[1] = dst_irq - 32; /* SPI offset */
135 fwspec.param[2] = intr->type;
136
137 err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
138 if (err)
139 goto err_irqs;
140
141 err = intr->sci->ops.rm_irq_ops.set_irq(intr->sci, dev_id, irq_index,
142 intr->dst_id, dst_irq);
143 if (err)
144 goto err_msg;
145
146 return 0;
147
148err_msg:
149 irq_domain_free_irqs_parent(domain, virq, 1);
150err_irqs:
151 ti_sci_release_resource(intr->dst_irq, dst_irq);
152 return err;
153}
154
155/**
156 * ti_sci_intr_irq_domain_alloc() - Allocate Interrupt router IRQs
157 * @domain: Point to the interrupt router IRQ domain
158 * @virq: Corresponding Linux virtual IRQ number
159 * @nr_irqs: Continuous irqs to be allocated
160 * @data: Pointer to firmware specifier
161 *
162 * Return 0 if all went well else appropriate error value.
163 */
164static int ti_sci_intr_irq_domain_alloc(struct irq_domain *domain,
165 unsigned int virq, unsigned int nr_irqs,
166 void *data)
167{
168 struct irq_fwspec *fwspec = data;
169 unsigned long hwirq;
170 unsigned int flags;
171 int err;
172
173 err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &flags);
174 if (err)
175 return err;
176
177 err = ti_sci_intr_alloc_gic_irq(domain, virq, hwirq);
178 if (err)
179 return err;
180
181 irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
182 &ti_sci_intr_irq_chip, NULL);
183
184 return 0;
185}
186
187static const struct irq_domain_ops ti_sci_intr_irq_domain_ops = {
188 .free = ti_sci_intr_irq_domain_free,
189 .alloc = ti_sci_intr_irq_domain_alloc,
190 .translate = ti_sci_intr_irq_domain_translate,
191};
192
193static int ti_sci_intr_irq_domain_probe(struct platform_device *pdev)
194{
195 struct irq_domain *parent_domain, *domain;
196 struct ti_sci_intr_irq_domain *intr;
197 struct device_node *parent_node;
198 struct device *dev = &pdev->dev;
199 int ret;
200
201 parent_node = of_irq_find_parent(dev_of_node(dev));
202 if (!parent_node) {
203 dev_err(dev, "Failed to get IRQ parent node\n");
204 return -ENODEV;
205 }
206
207 parent_domain = irq_find_host(parent_node);
208 if (!parent_domain) {
209 dev_err(dev, "Failed to find IRQ parent domain\n");
210 return -ENODEV;
211 }
212
213 intr = devm_kzalloc(dev, sizeof(*intr), GFP_KERNEL);
214 if (!intr)
215 return -ENOMEM;
216
217 ret = of_property_read_u32(dev_of_node(dev), "ti,intr-trigger-type",
218 &intr->type);
219 if (ret) {
220 dev_err(dev, "missing ti,intr-trigger-type property\n");
221 return -EINVAL;
222 }
223
224 intr->sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
225 if (IS_ERR(intr->sci)) {
226 ret = PTR_ERR(intr->sci);
227 if (ret != -EPROBE_DEFER)
228 dev_err(dev, "ti,sci read fail %d\n", ret);
229 intr->sci = NULL;
230 return ret;
231 }
232
233 ret = of_property_read_u32(dev_of_node(dev), "ti,sci-dst-id",
234 &intr->dst_id);
235 if (ret) {
236 dev_err(dev, "missing 'ti,sci-dst-id' property\n");
237 return -EINVAL;
238 }
239
240 intr->dst_irq = devm_ti_sci_get_of_resource(intr->sci, dev,
241 intr->dst_id,
242 "ti,sci-rm-range-girq");
243 if (IS_ERR(intr->dst_irq)) {
244 dev_err(dev, "Destination irq resource allocation failed\n");
245 return PTR_ERR(intr->dst_irq);
246 }
247
248 domain = irq_domain_add_hierarchy(parent_domain, 0, 0, dev_of_node(dev),
249 &ti_sci_intr_irq_domain_ops, intr);
250 if (!domain) {
251 dev_err(dev, "Failed to allocate IRQ domain\n");
252 return -ENOMEM;
253 }
254
255 return 0;
256}
257
258static const struct of_device_id ti_sci_intr_irq_domain_of_match[] = {
259 { .compatible = "ti,sci-intr", },
260 { /* sentinel */ },
261};
262MODULE_DEVICE_TABLE(of, ti_sci_intr_irq_domain_of_match);
263
264static struct platform_driver ti_sci_intr_irq_domain_driver = {
265 .probe = ti_sci_intr_irq_domain_probe,
266 .driver = {
267 .name = "ti-sci-intr",
268 .of_match_table = ti_sci_intr_irq_domain_of_match,
269 },
270};
271module_platform_driver(ti_sci_intr_irq_domain_driver);
272
273MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ticom>");
274MODULE_DESCRIPTION("K3 Interrupt Router driver over TI SCI protocol");
275MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/common/b2c2/Makefile b/drivers/media/common/b2c2/Makefile
index aa2dc2434ee5..0e32b77f349b 100644
--- a/drivers/media/common/b2c2/Makefile
+++ b/drivers/media/common/b2c2/Makefile
@@ -4,5 +4,5 @@ b2c2-flexcop-objs += flexcop-sram.o flexcop-eeprom.o flexcop-misc.o
4b2c2-flexcop-objs += flexcop-hw-filter.o 4b2c2-flexcop-objs += flexcop-hw-filter.o
5obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o 5obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
6 6
7ccflags-y += -Idrivers/media/dvb-frontends/ 7ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/
8ccflags-y += -Idrivers/media/tuners/ 8ccflags-y += -I $(srctree)/drivers/media/tuners/
diff --git a/drivers/media/dvb-frontends/cxd2880/Makefile b/drivers/media/dvb-frontends/cxd2880/Makefile
index c6baa4caba19..646598b556d5 100644
--- a/drivers/media/dvb-frontends/cxd2880/Makefile
+++ b/drivers/media/dvb-frontends/cxd2880/Makefile
@@ -14,5 +14,3 @@ cxd2880-objs := cxd2880_common.o \
14 cxd2880_top.o 14 cxd2880_top.o
15 15
16obj-$(CONFIG_DVB_CXD2880) += cxd2880.o 16obj-$(CONFIG_DVB_CXD2880) += cxd2880.o
17
18ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/i2c/smiapp/Makefile b/drivers/media/i2c/smiapp/Makefile
index f45a003cbe7e..9f03aefd4fd7 100644
--- a/drivers/media/i2c/smiapp/Makefile
+++ b/drivers/media/i2c/smiapp/Makefile
@@ -2,4 +2,4 @@ smiapp-objs += smiapp-core.o smiapp-regs.o \
2 smiapp-quirk.o smiapp-limits.o 2 smiapp-quirk.o smiapp-limits.o
3obj-$(CONFIG_VIDEO_SMIAPP) += smiapp.o 3obj-$(CONFIG_VIDEO_SMIAPP) += smiapp.o
4 4
5ccflags-y += -Idrivers/media/i2c 5ccflags-y += -I $(srctree)/drivers/media/i2c
diff --git a/drivers/media/mmc/siano/Makefile b/drivers/media/mmc/siano/Makefile
index 5fc345645a80..848548feeb19 100644
--- a/drivers/media/mmc/siano/Makefile
+++ b/drivers/media/mmc/siano/Makefile
@@ -1,4 +1,3 @@
1obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o 1obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
2 2
3ccflags-y += -Idrivers/media/common/siano 3ccflags-y += -I $(srctree)/drivers/media/common/siano
4
diff --git a/drivers/media/pci/b2c2/Makefile b/drivers/media/pci/b2c2/Makefile
index b43b9167db5a..14ed6e441738 100644
--- a/drivers/media/pci/b2c2/Makefile
+++ b/drivers/media/pci/b2c2/Makefile
@@ -6,4 +6,4 @@ endif
6b2c2-flexcop-pci-objs += flexcop-pci.o 6b2c2-flexcop-pci-objs += flexcop-pci.o
7obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o 7obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
8 8
9ccflags-y += -Idrivers/media/common/b2c2/ 9ccflags-y += -I $(srctree)/drivers/media/common/b2c2/
diff --git a/drivers/media/pci/bt8xx/Makefile b/drivers/media/pci/bt8xx/Makefile
index 7f1c3beb1bbc..69bc0d9c478e 100644
--- a/drivers/media/pci/bt8xx/Makefile
+++ b/drivers/media/pci/bt8xx/Makefile
@@ -6,6 +6,5 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
6obj-$(CONFIG_VIDEO_BT848) += bttv.o 6obj-$(CONFIG_VIDEO_BT848) += bttv.o
7obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o 7obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
8 8
9ccflags-y += -Idrivers/media/dvb-frontends 9ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
10ccflags-y += -Idrivers/media/common 10ccflags-y += -I $(srctree)/drivers/media/tuners
11ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/cx18/Makefile b/drivers/media/pci/cx18/Makefile
index 9c82c2df05e1..df00ef8b4521 100644
--- a/drivers/media/pci/cx18/Makefile
+++ b/drivers/media/pci/cx18/Makefile
@@ -9,5 +9,5 @@ cx18-alsa-objs := cx18-alsa-main.o cx18-alsa-pcm.o
9obj-$(CONFIG_VIDEO_CX18) += cx18.o 9obj-$(CONFIG_VIDEO_CX18) += cx18.o
10obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o 10obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
11 11
12ccflags-y += -Idrivers/media/dvb-frontends 12ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
13ccflags-y += -Idrivers/media/tuners 13ccflags-y += -I $(srctree)/drivers/media/tuners
diff --git a/drivers/media/pci/cx23885/Makefile b/drivers/media/pci/cx23885/Makefile
index 130f0aa29ac6..a785169ec368 100644
--- a/drivers/media/pci/cx23885/Makefile
+++ b/drivers/media/pci/cx23885/Makefile
@@ -8,7 +8,7 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
8obj-$(CONFIG_VIDEO_CX23885) += cx23885.o 8obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
9obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o 9obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
10 10
11ccflags-y += -Idrivers/media/tuners 11ccflags-y += -I $(srctree)/drivers/media/tuners
12ccflags-y += -Idrivers/media/dvb-frontends 12ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
13 13
14ccflags-y += $(extra-cflags-y) $(extra-cflags-m) 14ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/pci/cx88/Makefile b/drivers/media/pci/cx88/Makefile
index d0f45d652d6e..c2a015869760 100644
--- a/drivers/media/pci/cx88/Makefile
+++ b/drivers/media/pci/cx88/Makefile
@@ -10,5 +10,5 @@ obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o
10obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o 10obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o
11obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o 11obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
12obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o 12obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
13ccflags-y += -Idrivers/media/tuners 13ccflags-y += -I $(srctree)/drivers/media/tuners
14ccflags-y += -Idrivers/media/dvb-frontends 14ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile
index 5b6d5bbc38af..2b77c8d0eb2e 100644
--- a/drivers/media/pci/ddbridge/Makefile
+++ b/drivers/media/pci/ddbridge/Makefile
@@ -9,5 +9,5 @@ ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-ci.o \
9 9
10obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o 10obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
11 11
12ccflags-y += -Idrivers/media/dvb-frontends/ 12ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/
13ccflags-y += -Idrivers/media/tuners/ 13ccflags-y += -I $(srctree)/drivers/media/tuners/
diff --git a/drivers/media/pci/dm1105/Makefile b/drivers/media/pci/dm1105/Makefile
index d22c2547ee86..87e8e8052cdd 100644
--- a/drivers/media/pci/dm1105/Makefile
+++ b/drivers/media/pci/dm1105/Makefile
@@ -1,3 +1,3 @@
1obj-$(CONFIG_DVB_DM1105) += dm1105.o 1obj-$(CONFIG_DVB_DM1105) += dm1105.o
2 2
3ccflags-y += -Idrivers/media/dvb-frontends 3ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/pci/mantis/Makefile b/drivers/media/pci/mantis/Makefile
index b5ef39692cb0..49e82247b618 100644
--- a/drivers/media/pci/mantis/Makefile
+++ b/drivers/media/pci/mantis/Makefile
@@ -26,4 +26,4 @@ obj-$(CONFIG_MANTIS_CORE) += mantis_core.o
26obj-$(CONFIG_DVB_MANTIS) += mantis.o 26obj-$(CONFIG_DVB_MANTIS) += mantis.o
27obj-$(CONFIG_DVB_HOPPER) += hopper.o 27obj-$(CONFIG_DVB_HOPPER) += hopper.o
28 28
29ccflags-y += -Idrivers/media/dvb-frontends/ 29ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/
diff --git a/drivers/media/pci/netup_unidvb/Makefile b/drivers/media/pci/netup_unidvb/Makefile
index 944c3e164157..215bdafcc279 100644
--- a/drivers/media/pci/netup_unidvb/Makefile
+++ b/drivers/media/pci/netup_unidvb/Makefile
@@ -6,4 +6,4 @@ netup-unidvb-objs += netup_unidvb_spi.o
6 6
7obj-$(CONFIG_DVB_NETUP_UNIDVB) += netup-unidvb.o 7obj-$(CONFIG_DVB_NETUP_UNIDVB) += netup-unidvb.o
8 8
9ccflags-y += -Idrivers/media/dvb-frontends 9ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/pci/ngene/Makefile b/drivers/media/pci/ngene/Makefile
index ec450ad19281..5d16090e0677 100644
--- a/drivers/media/pci/ngene/Makefile
+++ b/drivers/media/pci/ngene/Makefile
@@ -7,5 +7,5 @@ ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o
7 7
8obj-$(CONFIG_DVB_NGENE) += ngene.o 8obj-$(CONFIG_DVB_NGENE) += ngene.o
9 9
10ccflags-y += -Idrivers/media/dvb-frontends/ 10ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/
11ccflags-y += -Idrivers/media/tuners/ 11ccflags-y += -I $(srctree)/drivers/media/tuners/
diff --git a/drivers/media/pci/pluto2/Makefile b/drivers/media/pci/pluto2/Makefile
index 3c2aea1ac752..4d21a2c1544d 100644
--- a/drivers/media/pci/pluto2/Makefile
+++ b/drivers/media/pci/pluto2/Makefile
@@ -1,3 +1,3 @@
1obj-$(CONFIG_DVB_PLUTO2) += pluto2.o 1obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
2 2
3ccflags-y += -Idrivers/media/dvb-frontends/ 3ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/
diff --git a/drivers/media/pci/pt1/Makefile b/drivers/media/pci/pt1/Makefile
index bc491e08dd63..f80a1cd4c0f5 100644
--- a/drivers/media/pci/pt1/Makefile
+++ b/drivers/media/pci/pt1/Makefile
@@ -2,5 +2,5 @@ earth-pt1-objs := pt1.o
2 2
3obj-$(CONFIG_DVB_PT1) += earth-pt1.o 3obj-$(CONFIG_DVB_PT1) += earth-pt1.o
4 4
5ccflags-y += -Idrivers/media/dvb-frontends 5ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
6ccflags-y += -Idrivers/media/tuners 6ccflags-y += -I $(srctree)/drivers/media/tuners
diff --git a/drivers/media/pci/pt3/Makefile b/drivers/media/pci/pt3/Makefile
index 8698d5dfaf52..da6b265f4b39 100644
--- a/drivers/media/pci/pt3/Makefile
+++ b/drivers/media/pci/pt3/Makefile
@@ -4,5 +4,5 @@ earth-pt3-objs += pt3.o pt3_i2c.o pt3_dma.o
4 4
5obj-$(CONFIG_DVB_PT3) += earth-pt3.o 5obj-$(CONFIG_DVB_PT3) += earth-pt3.o
6 6
7ccflags-y += -Idrivers/media/dvb-frontends 7ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
8ccflags-y += -Idrivers/media/tuners 8ccflags-y += -I $(srctree)/drivers/media/tuners
diff --git a/drivers/media/pci/smipcie/Makefile b/drivers/media/pci/smipcie/Makefile
index 214ebfe12cf7..2426b7566553 100644
--- a/drivers/media/pci/smipcie/Makefile
+++ b/drivers/media/pci/smipcie/Makefile
@@ -4,6 +4,5 @@ smipcie-objs := smipcie-main.o smipcie-ir.o
4 4
5obj-$(CONFIG_DVB_SMIPCIE) += smipcie.o 5obj-$(CONFIG_DVB_SMIPCIE) += smipcie.o
6 6
7ccflags-y += -Idrivers/media/tuners 7ccflags-y += -I $(srctree)/drivers/media/tuners
8ccflags-y += -Idrivers/media/dvb-frontends 8ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
9
diff --git a/drivers/media/pci/ttpci/Makefile b/drivers/media/pci/ttpci/Makefile
index 58ca12732aad..9b44c479fcdd 100644
--- a/drivers/media/pci/ttpci/Makefile
+++ b/drivers/media/pci/ttpci/Makefile
@@ -18,5 +18,5 @@ obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o
18obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o 18obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
19obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o 19obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
20 20
21ccflags-y += -Idrivers/media/dvb-frontends/ 21ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/
22ccflags-y += -Idrivers/media/tuners 22ccflags-y += -I $(srctree)/drivers/media/tuners
diff --git a/drivers/media/platform/sti/c8sectpfe/Makefile b/drivers/media/platform/sti/c8sectpfe/Makefile
index 34d69472b6f0..aedfc725cc19 100644
--- a/drivers/media/platform/sti/c8sectpfe/Makefile
+++ b/drivers/media/platform/sti/c8sectpfe/Makefile
@@ -4,6 +4,5 @@ c8sectpfe-y += c8sectpfe-core.o c8sectpfe-common.o c8sectpfe-dvb.o \
4 4
5obj-$(CONFIG_DVB_C8SECTPFE) += c8sectpfe.o 5obj-$(CONFIG_DVB_C8SECTPFE) += c8sectpfe.o
6 6
7ccflags-y += -Idrivers/media/common 7ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/
8ccflags-y += -Idrivers/media/dvb-frontends/ 8ccflags-y += -I $(srctree)/drivers/media/tuners/
9ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 37e6e8255b57..53c7ae135460 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -36,5 +36,3 @@ obj-$(CONFIG_RADIO_TEA575X) += tea575x.o
36obj-$(CONFIG_USB_RAREMONO) += radio-raremono.o 36obj-$(CONFIG_USB_RAREMONO) += radio-raremono.o
37 37
38shark2-objs := radio-shark2.o radio-tea5777.o 38shark2-objs := radio-shark2.o radio-tea5777.o
39
40ccflags-y += -Isound
diff --git a/drivers/media/spi/Makefile b/drivers/media/spi/Makefile
index 9e536777a330..446e6c567e94 100644
--- a/drivers/media/spi/Makefile
+++ b/drivers/media/spi/Makefile
@@ -1,6 +1,4 @@
1obj-$(CONFIG_VIDEO_GS1662) += gs1662.o 1obj-$(CONFIG_VIDEO_GS1662) += gs1662.o
2obj-$(CONFIG_CXD2880_SPI_DRV) += cxd2880-spi.o 2obj-$(CONFIG_CXD2880_SPI_DRV) += cxd2880-spi.o
3 3
4ccflags-y += -Idrivers/media/dvb-core 4ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/cxd2880
5ccflags-y += -Idrivers/media/dvb-frontends
6ccflags-y += -Idrivers/media/dvb-frontends/cxd2880
diff --git a/drivers/media/usb/as102/Makefile b/drivers/media/usb/as102/Makefile
index b0b319622edb..de671aed5dfc 100644
--- a/drivers/media/usb/as102/Makefile
+++ b/drivers/media/usb/as102/Makefile
@@ -4,4 +4,4 @@ dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \
4 4
5obj-$(CONFIG_DVB_AS102) += dvb-as102.o 5obj-$(CONFIG_DVB_AS102) += dvb-as102.o
6 6
7ccflags-y += -Idrivers/media/dvb-frontends 7ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/usb/au0828/Makefile b/drivers/media/usb/au0828/Makefile
index 5691881c56c0..4347812d101a 100644
--- a/drivers/media/usb/au0828/Makefile
+++ b/drivers/media/usb/au0828/Makefile
@@ -11,7 +11,7 @@ endif
11 11
12obj-$(CONFIG_VIDEO_AU0828) += au0828.o 12obj-$(CONFIG_VIDEO_AU0828) += au0828.o
13 13
14ccflags-y += -Idrivers/media/tuners 14ccflags-y += -I $(srctree)/drivers/media/tuners
15ccflags-y += -Idrivers/media/dvb-frontends 15ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
16 16
17ccflags-y += $(extra-cflags-y) $(extra-cflags-m) 17ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/usb/b2c2/Makefile b/drivers/media/usb/b2c2/Makefile
index f3cef05f37b6..e7f949d18fbf 100644
--- a/drivers/media/usb/b2c2/Makefile
+++ b/drivers/media/usb/b2c2/Makefile
@@ -1,4 +1,4 @@
1b2c2-flexcop-usb-objs := flexcop-usb.o 1b2c2-flexcop-usb-objs := flexcop-usb.o
2obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o 2obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
3 3
4ccflags-y += -Idrivers/media/common/b2c2/ 4ccflags-y += -I $(srctree)/drivers/media/common/b2c2/
diff --git a/drivers/media/usb/cx231xx/Makefile b/drivers/media/usb/cx231xx/Makefile
index c023d97407de..8acbbcba7d0c 100644
--- a/drivers/media/usb/cx231xx/Makefile
+++ b/drivers/media/usb/cx231xx/Makefile
@@ -9,6 +9,5 @@ obj-$(CONFIG_VIDEO_CX231XX) += cx231xx.o
9obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o 9obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o
10obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o 10obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o
11 11
12ccflags-y += -Idrivers/media/tuners 12ccflags-y += -I $(srctree)/drivers/media/tuners
13ccflags-y += -Idrivers/media/dvb-frontends 13ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
14ccflags-y += -Idrivers/media/usb/dvb-usb
diff --git a/drivers/media/usb/em28xx/Makefile b/drivers/media/usb/em28xx/Makefile
index 8a224007d755..8c2fc3104561 100644
--- a/drivers/media/usb/em28xx/Makefile
+++ b/drivers/media/usb/em28xx/Makefile
@@ -11,5 +11,5 @@ obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o
11obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o 11obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
12obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o 12obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o
13 13
14ccflags-y += -Idrivers/media/tuners 14ccflags-y += -I $(srctree)/drivers/media/tuners
15ccflags-y += -Idrivers/media/dvb-frontends 15ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/usb/go7007/Makefile b/drivers/media/usb/go7007/Makefile
index 3d95bbc4192c..712a3507f195 100644
--- a/drivers/media/usb/go7007/Makefile
+++ b/drivers/media/usb/go7007/Makefile
@@ -9,4 +9,4 @@ go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
9 9
10s2250-y := s2250-board.o 10s2250-y := s2250-board.o
11 11
12ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/common 12ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -I $(srctree)/drivers/media/common
diff --git a/drivers/media/usb/pvrusb2/Makefile b/drivers/media/usb/pvrusb2/Makefile
index 9facf6873404..2e71afc4f6de 100644
--- a/drivers/media/usb/pvrusb2/Makefile
+++ b/drivers/media/usb/pvrusb2/Makefile
@@ -17,5 +17,5 @@ pvrusb2-objs := pvrusb2-i2c-core.o \
17 17
18obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o 18obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
19 19
20ccflags-y += -Idrivers/media/tuners 20ccflags-y += -I $(srctree)/drivers/media/tuners
21ccflags-y += -Idrivers/media/dvb-frontends 21ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/usb/siano/Makefile b/drivers/media/usb/siano/Makefile
index 7d48864e2782..ba56e9818489 100644
--- a/drivers/media/usb/siano/Makefile
+++ b/drivers/media/usb/siano/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_SMS_USB_DRV) += smsusb.o 1obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
2 2
3ccflags-y += -Idrivers/media/common/siano 3ccflags-y += -I $(srctree)/drivers/media/common/siano
4ccflags-y += $(extra-cflags-y) $(extra-cflags-m) 4ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
5 5
diff --git a/drivers/media/usb/tm6000/Makefile b/drivers/media/usb/tm6000/Makefile
index 744c039e621a..75247a02a485 100644
--- a/drivers/media/usb/tm6000/Makefile
+++ b/drivers/media/usb/tm6000/Makefile
@@ -10,5 +10,5 @@ obj-$(CONFIG_VIDEO_TM6000) += tm6000.o
10obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o 10obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o
11obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o 11obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o
12 12
13ccflags-y += -Idrivers/media/tuners 13ccflags-y += -I $(srctree)/drivers/media/tuners
14ccflags-y += -Idrivers/media/dvb-frontends 14ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/usb/ttusb-budget/Makefile b/drivers/media/usb/ttusb-budget/Makefile
index fe4372dddd0e..37847d773921 100644
--- a/drivers/media/usb/ttusb-budget/Makefile
+++ b/drivers/media/usb/ttusb-budget/Makefile
@@ -1,3 +1,3 @@
1obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o 1obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
2 2
3ccflags-y += -Idrivers/media/dvb-frontends 3ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/usb/usbvision/Makefile b/drivers/media/usb/usbvision/Makefile
index 494d030b4979..e8e5eda08b6f 100644
--- a/drivers/media/usb/usbvision/Makefile
+++ b/drivers/media/usb/usbvision/Makefile
@@ -1,5 +1,3 @@
1usbvision-objs := usbvision-core.o usbvision-video.o usbvision-i2c.o usbvision-cards.o 1usbvision-objs := usbvision-core.o usbvision-video.o usbvision-i2c.o usbvision-cards.o
2 2
3obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o 3obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o
4
5ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b80cb6af0cb4..6a0365b2332c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -59,30 +59,6 @@ config ATMEL_TCLIB
59 blocks found on many Atmel processors. This facilitates using 59 blocks found on many Atmel processors. This facilitates using
60 these blocks by different drivers despite processor differences. 60 these blocks by different drivers despite processor differences.
61 61
62config ATMEL_TCB_CLKSRC
63 bool "TC Block Clocksource"
64 depends on ATMEL_TCLIB
65 default y
66 help
67 Select this to get a high precision clocksource based on a
68 TC block with a 5+ MHz base clock rate. Two timer channels
69 are combined to make a single 32-bit timer.
70
71 When GENERIC_CLOCKEVENTS is defined, the third timer channel
72 may be used as a clock event device supporting oneshot mode
73 (delays of up to two seconds) based on the 32 KiHz clock.
74
75config ATMEL_TCB_CLKSRC_BLOCK
76 int
77 depends on ATMEL_TCB_CLKSRC
78 default 0
79 range 0 1
80 help
81 Some chips provide more than one TC block, so you have the
82 choice of which one to use for the clock framework. The other
83 TC can be used for other purposes, such as PWM generation and
84 interval timing.
85
86config DUMMY_IRQ 62config DUMMY_IRQ
87 tristate "Dummy IRQ handler" 63 tristate "Dummy IRQ handler"
88 default n 64 default n
diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c
index ac24a4bd63f7..2c6850ef0e9c 100644
--- a/drivers/misc/atmel_tclib.c
+++ b/drivers/misc/atmel_tclib.c
@@ -1,4 +1,3 @@
1#include <linux/atmel_tc.h>
2#include <linux/clk.h> 1#include <linux/clk.h>
3#include <linux/err.h> 2#include <linux/err.h>
4#include <linux/init.h> 3#include <linux/init.h>
@@ -10,6 +9,7 @@
10#include <linux/slab.h> 9#include <linux/slab.h>
11#include <linux/export.h> 10#include <linux/export.h>
12#include <linux/of.h> 11#include <linux/of.h>
12#include <soc/at91/atmel_tcb.h>
13 13
14/* 14/*
15 * This is a thin library to solve the problem of how to portably allocate 15 * This is a thin library to solve the problem of how to portably allocate
@@ -111,6 +111,9 @@ static int __init tc_probe(struct platform_device *pdev)
111 struct resource *r; 111 struct resource *r;
112 unsigned int i; 112 unsigned int i;
113 113
114 if (of_get_child_count(pdev->dev.of_node))
115 return -EBUSY;
116
114 irq = platform_get_irq(pdev, 0); 117 irq = platform_get_irq(pdev, 0);
115 if (irq < 0) 118 if (irq < 0)
116 return -EINVAL; 119 return -EINVAL;
diff --git a/drivers/net/ethernet/chelsio/libcxgb/Makefile b/drivers/net/ethernet/chelsio/libcxgb/Makefile
index 2534e30a1560..441913b5221e 100644
--- a/drivers/net/ethernet/chelsio/libcxgb/Makefile
+++ b/drivers/net/ethernet/chelsio/libcxgb/Makefile
@@ -1,4 +1,4 @@
1ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4 1ccflags-y := -I $(srctree)/$(src)/../cxgb4
2 2
3obj-$(CONFIG_CHELSIO_LIB) += libcxgb.o 3obj-$(CONFIG_CHELSIO_LIB) += libcxgb.o
4 4
diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
index 0d0f8376bc35..7da1fdb4d269 100644
--- a/drivers/pwm/pwm-atmel-tcb.c
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -17,10 +17,10 @@
17#include <linux/ioport.h> 17#include <linux/ioport.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/atmel_tc.h>
21#include <linux/pwm.h> 20#include <linux/pwm.h>
22#include <linux/of_device.h> 21#include <linux/of_device.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
23#include <soc/at91/atmel_tcb.h>
24 24
25#define NPWM 6 25#define NPWM 6
26 26
diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c
index 819bed0f5667..51b3a47b5a55 100644
--- a/drivers/soc/fsl/qe/gpio.c
+++ b/drivers/soc/fsl/qe/gpio.c
@@ -179,8 +179,10 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
179 if (err < 0) 179 if (err < 0)
180 goto err0; 180 goto err0;
181 gc = gpio_to_chip(err); 181 gc = gpio_to_chip(err);
182 if (WARN_ON(!gc)) 182 if (WARN_ON(!gc)) {
183 err = -ENODEV;
183 goto err0; 184 goto err0;
185 }
184 186
185 if (!of_device_is_compatible(gc->of_node, "fsl,mpc8323-qe-pario-bank")) { 187 if (!of_device_is_compatible(gc->of_node, "fsl,mpc8323-qe-pario-bank")) {
186 pr_debug("%s: tried to get a non-qe pin\n", __func__); 188 pr_debug("%s: tried to get a non-qe pin\n", __func__);
diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
index 13a8a13c9b01..bb90670ec160 100644
--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -385,8 +385,8 @@ static int ixp4xx_qmgr_probe(struct platform_device *pdev)
385 if (!res) 385 if (!res)
386 return -ENODEV; 386 return -ENODEV;
387 qmgr_regs = devm_ioremap_resource(dev, res); 387 qmgr_regs = devm_ioremap_resource(dev, res);
388 if (!qmgr_regs) 388 if (IS_ERR(qmgr_regs))
389 return -ENOMEM; 389 return PTR_ERR(qmgr_regs);
390 390
391 irq1 = platform_get_irq(pdev, 0); 391 irq1 = platform_get_irq(pdev, 0);
392 if (irq1 <= 0) 392 if (irq1 <= 0)
diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index 57960e92ebe0..dbd6c60b81db 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -74,4 +74,10 @@ config TI_SCI_PM_DOMAINS
74 called ti_sci_pm_domains. Note this is needed early in boot before 74 called ti_sci_pm_domains. Note this is needed early in boot before
75 rootfs may be available. 75 rootfs may be available.
76 76
77config TI_SCI_INTA_MSI_DOMAIN
78 bool
79 select GENERIC_MSI_IRQ_DOMAIN
80 help
81 Driver to enable Interrupt Aggregator specific MSI Domain.
82
77endif # SOC_TI 83endif # SOC_TI
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
index a22edc0b258a..b3868d392d4f 100644
--- a/drivers/soc/ti/Makefile
+++ b/drivers/soc/ti/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA) += knav_dma.o
8obj-$(CONFIG_AMX3_PM) += pm33xx.o 8obj-$(CONFIG_AMX3_PM) += pm33xx.o
9obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o 9obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o
10obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o 10obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o
11obj-$(CONFIG_TI_SCI_INTA_MSI_DOMAIN) += ti_sci_inta_msi.o
diff --git a/drivers/soc/ti/ti_sci_inta_msi.c b/drivers/soc/ti/ti_sci_inta_msi.c
new file mode 100644
index 000000000000..0eb9462f609e
--- /dev/null
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -0,0 +1,146 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Texas Instruments' K3 Interrupt Aggregator MSI bus
4 *
5 * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
6 * Lokesh Vutla <lokeshvutla@ti.com>
7 */
8
9#include <linux/irq.h>
10#include <linux/irqdomain.h>
11#include <linux/msi.h>
12#include <linux/of_address.h>
13#include <linux/of_device.h>
14#include <linux/of_irq.h>
15#include <linux/soc/ti/ti_sci_inta_msi.h>
16#include <linux/soc/ti/ti_sci_protocol.h>
17
18static void ti_sci_inta_msi_write_msg(struct irq_data *data,
19 struct msi_msg *msg)
20{
21 /* Nothing to do */
22}
23
24static void ti_sci_inta_msi_compose_msi_msg(struct irq_data *data,
25 struct msi_msg *msg)
26{
27 /* Nothing to do */
28}
29
30static void ti_sci_inta_msi_update_chip_ops(struct msi_domain_info *info)
31{
32 struct irq_chip *chip = info->chip;
33
34 if (WARN_ON(!chip))
35 return;
36
37 chip->irq_request_resources = irq_chip_request_resources_parent;
38 chip->irq_release_resources = irq_chip_release_resources_parent;
39 chip->irq_compose_msi_msg = ti_sci_inta_msi_compose_msi_msg;
40 chip->irq_write_msi_msg = ti_sci_inta_msi_write_msg;
41 chip->irq_set_type = irq_chip_set_type_parent;
42 chip->irq_unmask = irq_chip_unmask_parent;
43 chip->irq_mask = irq_chip_mask_parent;
44 chip->irq_ack = irq_chip_ack_parent;
45}
46
47struct irq_domain *ti_sci_inta_msi_create_irq_domain(struct fwnode_handle *fwnode,
48 struct msi_domain_info *info,
49 struct irq_domain *parent)
50{
51 struct irq_domain *domain;
52
53 ti_sci_inta_msi_update_chip_ops(info);
54
55 domain = msi_create_irq_domain(fwnode, info, parent);
56 if (domain)
57 irq_domain_update_bus_token(domain, DOMAIN_BUS_TI_SCI_INTA_MSI);
58
59 return domain;
60}
61EXPORT_SYMBOL_GPL(ti_sci_inta_msi_create_irq_domain);
62
63static void ti_sci_inta_msi_free_descs(struct device *dev)
64{
65 struct msi_desc *desc, *tmp;
66
67 list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
68 list_del(&desc->list);
69 free_msi_entry(desc);
70 }
71}
72
73static int ti_sci_inta_msi_alloc_descs(struct device *dev,
74 struct ti_sci_resource *res)
75{
76 struct msi_desc *msi_desc;
77 int set, i, count = 0;
78
79 for (set = 0; set < res->sets; set++) {
80 for (i = 0; i < res->desc[set].num; i++) {
81 msi_desc = alloc_msi_entry(dev, 1, NULL);
82 if (!msi_desc) {
83 ti_sci_inta_msi_free_descs(dev);
84 return -ENOMEM;
85 }
86
87 msi_desc->inta.dev_index = res->desc[set].start + i;
88 INIT_LIST_HEAD(&msi_desc->list);
89 list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
90 count++;
91 }
92 }
93
94 return count;
95}
96
97int ti_sci_inta_msi_domain_alloc_irqs(struct device *dev,
98 struct ti_sci_resource *res)
99{
100 struct platform_device *pdev = to_platform_device(dev);
101 struct irq_domain *msi_domain;
102 int ret, nvec;
103
104 msi_domain = dev_get_msi_domain(dev);
105 if (!msi_domain)
106 return -EINVAL;
107
108 if (pdev->id < 0)
109 return -ENODEV;
110
111 nvec = ti_sci_inta_msi_alloc_descs(dev, res);
112 if (nvec <= 0)
113 return nvec;
114
115 ret = msi_domain_alloc_irqs(msi_domain, dev, nvec);
116 if (ret) {
117 dev_err(dev, "Failed to allocate IRQs %d\n", ret);
118 goto cleanup;
119 }
120
121 return 0;
122
123cleanup:
124 ti_sci_inta_msi_free_descs(&pdev->dev);
125 return ret;
126}
127EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_alloc_irqs);
128
129void ti_sci_inta_msi_domain_free_irqs(struct device *dev)
130{
131 msi_domain_free_irqs(dev->msi_domain, dev);
132 ti_sci_inta_msi_free_descs(dev);
133}
134EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_free_irqs);
135
136unsigned int ti_sci_inta_msi_get_virq(struct device *dev, u32 dev_index)
137{
138 struct msi_desc *desc;
139
140 for_each_msi_entry(desc, dev)
141 if (desc->inta.dev_index == dev_index)
142 return desc->irq;
143
144 return -ENODEV;
145}
146EXPORT_SYMBOL_GPL(ti_sci_inta_msi_get_virq);
diff --git a/drivers/target/iscsi/cxgbit/Makefile b/drivers/target/iscsi/cxgbit/Makefile
index d16aaae7ba2a..0dcaf2006f78 100644
--- a/drivers/target/iscsi/cxgbit/Makefile
+++ b/drivers/target/iscsi/cxgbit/Makefile
@@ -1,7 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4 2ccflags-y := -I $(srctree)/drivers/net/ethernet/chelsio/cxgb4
3ccflags-y += -Idrivers/net/ethernet/chelsio/libcxgb 3ccflags-y += -I $(srctree)/drivers/net/ethernet/chelsio/libcxgb
4ccflags-y += -Idrivers/target/iscsi 4ccflags-y += -I $(srctree)/drivers/target/iscsi
5 5
6obj-$(CONFIG_ISCSI_TARGET_CXGB4) += cxgbit.o 6obj-$(CONFIG_ISCSI_TARGET_CXGB4) += cxgbit.o
7 7
diff --git a/drivers/tty/hvc/hvc_riscv_sbi.c b/drivers/tty/hvc/hvc_riscv_sbi.c
index 75155bde2b88..31f53fa77e4a 100644
--- a/drivers/tty/hvc/hvc_riscv_sbi.c
+++ b/drivers/tty/hvc/hvc_riscv_sbi.c
@@ -53,7 +53,6 @@ device_initcall(hvc_sbi_init);
53static int __init hvc_sbi_console_init(void) 53static int __init hvc_sbi_console_init(void)
54{ 54{
55 hvc_instantiate(0, 0, &hvc_sbi_ops); 55 hvc_instantiate(0, 0, &hvc_sbi_ops);
56 add_preferred_console("hvc", 0, NULL);
57 56
58 return 0; 57 return 0;
59} 58}
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index c5126a4cd954..a67ddcbb4e24 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -6,7 +6,7 @@
6# Rewritten to use lists instead of if-statements. 6# Rewritten to use lists instead of if-statements.
7# 7#
8 8
9ccflags-y := -Idrivers/scsi 9ccflags-y := -I $(srctree)/drivers/scsi
10 10
11obj-$(CONFIG_USB_UAS) += uas.o 11obj-$(CONFIG_USB_UAS) += uas.o
12obj-$(CONFIG_USB_STORAGE) += usb-storage.o 12obj-$(CONFIG_USB_STORAGE) += usb-storage.o
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index 9e529cc2b4ff..9f39f0c360e0 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -477,8 +477,12 @@ static int efifb_probe(struct platform_device *dev)
477 * If the UEFI memory map covers the efifb region, we may only 477 * If the UEFI memory map covers the efifb region, we may only
478 * remap it using the attributes the memory map prescribes. 478 * remap it using the attributes the memory map prescribes.
479 */ 479 */
480 mem_flags |= EFI_MEMORY_WT | EFI_MEMORY_WB; 480 md.attribute &= EFI_MEMORY_UC | EFI_MEMORY_WC |
481 mem_flags &= md.attribute; 481 EFI_MEMORY_WT | EFI_MEMORY_WB;
482 if (md.attribute) {
483 mem_flags |= EFI_MEMORY_WT | EFI_MEMORY_WB;
484 mem_flags &= md.attribute;
485 }
482 } 486 }
483 if (mem_flags & EFI_MEMORY_WC) 487 if (mem_flags & EFI_MEMORY_WC)
484 info->screen_base = ioremap_wc(efifb_fix.smem_start, 488 info->screen_base = ioremap_wc(efifb_fix.smem_start,
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 6a69f11aacf7..45e74da40f3a 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -380,6 +380,8 @@ skip_rdma:
380 atomic_read(&server->in_send), 380 atomic_read(&server->in_send),
381 atomic_read(&server->num_waiters)); 381 atomic_read(&server->num_waiters));
382#endif 382#endif
383 /* dump session id helpful for use with network trace */
384 seq_printf(m, " SessionId: 0x%llx", ses->Suid);
383 if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) 385 if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
384 seq_puts(m, " encrypted"); 386 seq_puts(m, " encrypted");
385 if (ses->sign) 387 if (ses->sign)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index b1a5fcfa3ce1..f5fcd6360056 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -878,6 +878,9 @@ out:
878 878
879static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) 879static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
880{ 880{
881 struct cifsFileInfo *cfile = file->private_data;
882 struct cifs_tcon *tcon;
883
881 /* 884 /*
882 * whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate 885 * whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
883 * the cached file length 886 * the cached file length
@@ -909,6 +912,12 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
909 if (rc < 0) 912 if (rc < 0)
910 return (loff_t)rc; 913 return (loff_t)rc;
911 } 914 }
915 if (cfile && cfile->tlink) {
916 tcon = tlink_tcon(cfile->tlink);
917 if (tcon->ses->server->ops->llseek)
918 return tcon->ses->server->ops->llseek(file, tcon,
919 offset, whence);
920 }
912 return generic_file_llseek(file, offset, whence); 921 return generic_file_llseek(file, offset, whence);
913} 922}
914 923
@@ -1070,11 +1079,6 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
1070 1079
1071 cifs_dbg(FYI, "copychunk range\n"); 1080 cifs_dbg(FYI, "copychunk range\n");
1072 1081
1073 if (src_inode == target_inode) {
1074 rc = -EINVAL;
1075 goto out;
1076 }
1077
1078 if (!src_file->private_data || !dst_file->private_data) { 1082 if (!src_file->private_data || !dst_file->private_data) {
1079 rc = -EBADF; 1083 rc = -EBADF;
1080 cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n"); 1084 cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 33c251b408aa..334ff5f9c3f3 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -497,6 +497,8 @@ struct smb_version_operations {
497 /* version specific fiemap implementation */ 497 /* version specific fiemap implementation */
498 int (*fiemap)(struct cifs_tcon *tcon, struct cifsFileInfo *, 498 int (*fiemap)(struct cifs_tcon *tcon, struct cifsFileInfo *,
499 struct fiemap_extent_info *, u64, u64); 499 struct fiemap_extent_info *, u64, u64);
500 /* version specific llseek implementation */
501 loff_t (*llseek)(struct file *, struct cifs_tcon *, loff_t, int);
500}; 502};
501 503
502struct smb_version_values { 504struct smb_version_values {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 084756cfdaee..8c4121da624e 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -528,6 +528,21 @@ cifs_reconnect(struct TCP_Server_Info *server)
528 /* do not want to be sending data on a socket we are freeing */ 528 /* do not want to be sending data on a socket we are freeing */
529 cifs_dbg(FYI, "%s: tearing down socket\n", __func__); 529 cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
530 mutex_lock(&server->srv_mutex); 530 mutex_lock(&server->srv_mutex);
531 if (server->ssocket) {
532 cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
533 server->ssocket->state, server->ssocket->flags);
534 kernel_sock_shutdown(server->ssocket, SHUT_WR);
535 cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
536 server->ssocket->state, server->ssocket->flags);
537 sock_release(server->ssocket);
538 server->ssocket = NULL;
539 }
540 server->sequence_number = 0;
541 server->session_estab = false;
542 kfree(server->session_key.response);
543 server->session_key.response = NULL;
544 server->session_key.len = 0;
545 server->lstrp = jiffies;
531 546
532 /* mark submitted MIDs for retry and issue callback */ 547 /* mark submitted MIDs for retry and issue callback */
533 INIT_LIST_HEAD(&retry_list); 548 INIT_LIST_HEAD(&retry_list);
@@ -540,6 +555,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
540 list_move(&mid_entry->qhead, &retry_list); 555 list_move(&mid_entry->qhead, &retry_list);
541 } 556 }
542 spin_unlock(&GlobalMid_Lock); 557 spin_unlock(&GlobalMid_Lock);
558 mutex_unlock(&server->srv_mutex);
543 559
544 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__); 560 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
545 list_for_each_safe(tmp, tmp2, &retry_list) { 561 list_for_each_safe(tmp, tmp2, &retry_list) {
@@ -548,24 +564,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
548 mid_entry->callback(mid_entry); 564 mid_entry->callback(mid_entry);
549 } 565 }
550 566
551 if (server->ssocket) { 567 if (cifs_rdma_enabled(server)) {
552 cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n", 568 mutex_lock(&server->srv_mutex);
553 server->ssocket->state, server->ssocket->flags);
554 kernel_sock_shutdown(server->ssocket, SHUT_WR);
555 cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
556 server->ssocket->state, server->ssocket->flags);
557 sock_release(server->ssocket);
558 server->ssocket = NULL;
559 } else if (cifs_rdma_enabled(server))
560 smbd_destroy(server); 569 smbd_destroy(server);
561 server->sequence_number = 0; 570 mutex_unlock(&server->srv_mutex);
562 server->session_estab = false; 571 }
563 kfree(server->session_key.response);
564 server->session_key.response = NULL;
565 server->session_key.len = 0;
566 server->lstrp = jiffies;
567
568 mutex_unlock(&server->srv_mutex);
569 572
570 do { 573 do {
571 try_to_freeze(); 574 try_to_freeze();
@@ -2443,6 +2446,10 @@ match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
2443{ 2446{
2444 __be16 port, *sport; 2447 __be16 port, *sport;
2445 2448
2449 /* SMBDirect manages its own ports, don't match it here */
2450 if (server->rdma)
2451 return true;
2452
2446 switch (addr->sa_family) { 2453 switch (addr->sa_family) {
2447 case AF_INET: 2454 case AF_INET:
2448 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port; 2455 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index a930c8965e5c..e921e6511728 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * SMB2 version specific operations 3 * SMB2 version specific operations
3 * 4 *
@@ -282,7 +283,7 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
282 __u64 wire_mid = le64_to_cpu(shdr->MessageId); 283 __u64 wire_mid = le64_to_cpu(shdr->MessageId);
283 284
284 if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) { 285 if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
285 cifs_dbg(VFS, "encrypted frame parsing not supported yet"); 286 cifs_dbg(VFS, "Encrypted frame parsing not supported yet\n");
286 return NULL; 287 return NULL;
287 } 288 }
288 289
@@ -324,6 +325,7 @@ static int
324smb2_negotiate(const unsigned int xid, struct cifs_ses *ses) 325smb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
325{ 326{
326 int rc; 327 int rc;
328
327 ses->server->CurrentMid = 0; 329 ses->server->CurrentMid = 0;
328 rc = SMB2_negotiate(xid, ses); 330 rc = SMB2_negotiate(xid, ses);
329 /* BB we probably don't need to retry with modern servers */ 331 /* BB we probably don't need to retry with modern servers */
@@ -789,8 +791,6 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
789 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 791 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
790 else 792 else
791 close_shroot(&tcon->crfid); 793 close_shroot(&tcon->crfid);
792
793 return;
794} 794}
795 795
796static void 796static void
@@ -818,7 +818,6 @@ smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
818 SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, 818 SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
819 FS_DEVICE_INFORMATION); 819 FS_DEVICE_INFORMATION);
820 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 820 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
821 return;
822} 821}
823 822
824static int 823static int
@@ -906,9 +905,8 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
906 value = &src->ea_data[src->ea_name_length + 1]; 905 value = &src->ea_data[src->ea_name_length + 1];
907 value_len = (size_t)le16_to_cpu(src->ea_value_length); 906 value_len = (size_t)le16_to_cpu(src->ea_value_length);
908 907
909 if (name_len == 0) { 908 if (name_len == 0)
910 break; 909 break;
911 }
912 910
913 if (src_size < 8 + name_len + 1 + value_len) { 911 if (src_size < 8 + name_len + 1 + value_len) {
914 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 912 cifs_dbg(FYI, "EA entry goes beyond length of list\n");
@@ -1161,6 +1159,7 @@ static void
1161smb2_clear_stats(struct cifs_tcon *tcon) 1159smb2_clear_stats(struct cifs_tcon *tcon)
1162{ 1160{
1163 int i; 1161 int i;
1162
1164 for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) { 1163 for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
1165 atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0); 1164 atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
1166 atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0); 1165 atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
@@ -1529,7 +1528,7 @@ smb2_copychunk_range(const unsigned int xid,
1529 if (pcchunk == NULL) 1528 if (pcchunk == NULL)
1530 return -ENOMEM; 1529 return -ENOMEM;
1531 1530
1532 cifs_dbg(FYI, "in smb2_copychunk_range - about to call request res key\n"); 1531 cifs_dbg(FYI, "%s: about to call request res key\n", __func__);
1533 /* Request a key from the server to identify the source of the copy */ 1532 /* Request a key from the server to identify the source of the copy */
1534 rc = SMB2_request_res_key(xid, tlink_tcon(srcfile->tlink), 1533 rc = SMB2_request_res_key(xid, tlink_tcon(srcfile->tlink),
1535 srcfile->fid.persistent_fid, 1534 srcfile->fid.persistent_fid,
@@ -1649,6 +1648,7 @@ static unsigned int
1649smb2_read_data_offset(char *buf) 1648smb2_read_data_offset(char *buf)
1650{ 1649{
1651 struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf; 1650 struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
1651
1652 return rsp->DataOffset; 1652 return rsp->DataOffset;
1653} 1653}
1654 1654
@@ -1777,7 +1777,7 @@ smb2_duplicate_extents(const unsigned int xid,
1777 dup_ext_buf.SourceFileOffset = cpu_to_le64(src_off); 1777 dup_ext_buf.SourceFileOffset = cpu_to_le64(src_off);
1778 dup_ext_buf.TargetFileOffset = cpu_to_le64(dest_off); 1778 dup_ext_buf.TargetFileOffset = cpu_to_le64(dest_off);
1779 dup_ext_buf.ByteCount = cpu_to_le64(len); 1779 dup_ext_buf.ByteCount = cpu_to_le64(len);
1780 cifs_dbg(FYI, "duplicate extents: src off %lld dst off %lld len %lld", 1780 cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n",
1781 src_off, dest_off, len); 1781 src_off, dest_off, len);
1782 1782
1783 rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false); 1783 rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
@@ -1794,7 +1794,7 @@ smb2_duplicate_extents(const unsigned int xid,
1794 &ret_data_len); 1794 &ret_data_len);
1795 1795
1796 if (ret_data_len > 0) 1796 if (ret_data_len > 0)
1797 cifs_dbg(FYI, "non-zero response length in duplicate extents"); 1797 cifs_dbg(FYI, "Non-zero response length in duplicate extents\n");
1798 1798
1799duplicate_extents_out: 1799duplicate_extents_out:
1800 return rc; 1800 return rc;
@@ -1983,9 +1983,9 @@ smb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
1983} 1983}
1984 1984
1985/* 1985/*
1986* If we negotiate SMB2 protocol and get STATUS_PENDING - update 1986 * If we negotiate SMB2 protocol and get STATUS_PENDING - update
1987* the number of credits and return true. Otherwise - return false. 1987 * the number of credits and return true. Otherwise - return false.
1988*/ 1988 */
1989static bool 1989static bool
1990smb2_is_status_pending(char *buf, struct TCP_Server_Info *server) 1990smb2_is_status_pending(char *buf, struct TCP_Server_Info *server)
1991{ 1991{
@@ -2306,7 +2306,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
2306 struct get_dfs_referral_rsp *dfs_rsp = NULL; 2306 struct get_dfs_referral_rsp *dfs_rsp = NULL;
2307 u32 dfs_req_size = 0, dfs_rsp_size = 0; 2307 u32 dfs_req_size = 0, dfs_rsp_size = 0;
2308 2308
2309 cifs_dbg(FYI, "smb2_get_dfs_refer path <%s>\n", search_name); 2309 cifs_dbg(FYI, "%s: path: %s\n", __func__, search_name);
2310 2310
2311 /* 2311 /*
2312 * Try to use the IPC tcon, otherwise just use any 2312 * Try to use the IPC tcon, otherwise just use any
@@ -2360,7 +2360,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
2360 2360
2361 if (rc) { 2361 if (rc) {
2362 if ((rc != -ENOENT) && (rc != -EOPNOTSUPP)) 2362 if ((rc != -ENOENT) && (rc != -EOPNOTSUPP))
2363 cifs_dbg(VFS, "ioctl error in smb2_get_dfs_refer rc=%d\n", rc); 2363 cifs_dbg(VFS, "ioctl error in %s rc=%d\n", __func__, rc);
2364 goto out; 2364 goto out;
2365 } 2365 }
2366 2366
@@ -2369,7 +2369,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
2369 nls_codepage, remap, search_name, 2369 nls_codepage, remap, search_name,
2370 true /* is_unicode */); 2370 true /* is_unicode */);
2371 if (rc) { 2371 if (rc) {
2372 cifs_dbg(VFS, "parse error in smb2_get_dfs_refer rc=%d\n", rc); 2372 cifs_dbg(VFS, "parse error in %s rc=%d\n", __func__, rc);
2373 goto out; 2373 goto out;
2374 } 2374 }
2375 2375
@@ -2745,7 +2745,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
2745 inode = d_inode(cfile->dentry); 2745 inode = d_inode(cfile->dentry);
2746 cifsi = CIFS_I(inode); 2746 cifsi = CIFS_I(inode);
2747 2747
2748 trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid, 2748 trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid,
2749 ses->Suid, offset, len); 2749 ses->Suid, offset, len);
2750 2750
2751 2751
@@ -2759,7 +2759,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
2759 return rc; 2759 return rc;
2760 } 2760 }
2761 2761
2762 cifs_dbg(FYI, "offset %lld len %lld", offset, len); 2762 cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
2763 2763
2764 fsctl_buf.FileOffset = cpu_to_le64(offset); 2764 fsctl_buf.FileOffset = cpu_to_le64(offset);
2765 fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len); 2765 fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len);
@@ -2816,7 +2816,7 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
2816 return rc; 2816 return rc;
2817 } 2817 }
2818 2818
2819 cifs_dbg(FYI, "offset %lld len %lld", offset, len); 2819 cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
2820 2820
2821 fsctl_buf.FileOffset = cpu_to_le64(offset); 2821 fsctl_buf.FileOffset = cpu_to_le64(offset);
2822 fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len); 2822 fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len);
@@ -2922,6 +2922,90 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
2922 return rc; 2922 return rc;
2923} 2923}
2924 2924
2925static loff_t smb3_llseek(struct file *file, struct cifs_tcon *tcon, loff_t offset, int whence)
2926{
2927 struct cifsFileInfo *wrcfile, *cfile = file->private_data;
2928 struct cifsInodeInfo *cifsi;
2929 struct inode *inode;
2930 int rc = 0;
2931 struct file_allocated_range_buffer in_data, *out_data = NULL;
2932 u32 out_data_len;
2933 unsigned int xid;
2934
2935 if (whence != SEEK_HOLE && whence != SEEK_DATA)
2936 return generic_file_llseek(file, offset, whence);
2937
2938 inode = d_inode(cfile->dentry);
2939 cifsi = CIFS_I(inode);
2940
2941 if (offset < 0 || offset >= i_size_read(inode))
2942 return -ENXIO;
2943
2944 xid = get_xid();
2945 /*
2946 * We need to be sure that all dirty pages are written as they
2947 * might fill holes on the server.
2948 * Note that we also MUST flush any written pages since at least
2949 * some servers (Windows2016) will not reflect recent writes in
2950 * QUERY_ALLOCATED_RANGES until SMB2_flush is called.
2951 */
2952 wrcfile = find_writable_file(cifsi, false);
2953 if (wrcfile) {
2954 filemap_write_and_wait(inode->i_mapping);
2955 smb2_flush_file(xid, tcon, &wrcfile->fid);
2956 cifsFileInfo_put(wrcfile);
2957 }
2958
2959 if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)) {
2960 if (whence == SEEK_HOLE)
2961 offset = i_size_read(inode);
2962 goto lseek_exit;
2963 }
2964
2965 in_data.file_offset = cpu_to_le64(offset);
2966 in_data.length = cpu_to_le64(i_size_read(inode));
2967
2968 rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
2969 cfile->fid.volatile_fid,
2970 FSCTL_QUERY_ALLOCATED_RANGES, true,
2971 (char *)&in_data, sizeof(in_data),
2972 sizeof(struct file_allocated_range_buffer),
2973 (char **)&out_data, &out_data_len);
2974 if (rc == -E2BIG)
2975 rc = 0;
2976 if (rc)
2977 goto lseek_exit;
2978
2979 if (whence == SEEK_HOLE && out_data_len == 0)
2980 goto lseek_exit;
2981
2982 if (whence == SEEK_DATA && out_data_len == 0) {
2983 rc = -ENXIO;
2984 goto lseek_exit;
2985 }
2986
2987 if (out_data_len < sizeof(struct file_allocated_range_buffer)) {
2988 rc = -EINVAL;
2989 goto lseek_exit;
2990 }
2991 if (whence == SEEK_DATA) {
2992 offset = le64_to_cpu(out_data->file_offset);
2993 goto lseek_exit;
2994 }
2995 if (offset < le64_to_cpu(out_data->file_offset))
2996 goto lseek_exit;
2997
2998 offset = le64_to_cpu(out_data->file_offset) + le64_to_cpu(out_data->length);
2999
3000 lseek_exit:
3001 free_xid(xid);
3002 kfree(out_data);
3003 if (!rc)
3004 return vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
3005 else
3006 return rc;
3007}
3008
2925static int smb3_fiemap(struct cifs_tcon *tcon, 3009static int smb3_fiemap(struct cifs_tcon *tcon,
2926 struct cifsFileInfo *cfile, 3010 struct cifsFileInfo *cfile,
2927 struct fiemap_extent_info *fei, u64 start, u64 len) 3011 struct fiemap_extent_info *fei, u64 start, u64 len)
@@ -3384,7 +3468,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
3384 3468
3385 req = aead_request_alloc(tfm, GFP_KERNEL); 3469 req = aead_request_alloc(tfm, GFP_KERNEL);
3386 if (!req) { 3470 if (!req) {
3387 cifs_dbg(VFS, "%s: Failed to alloc aead request", __func__); 3471 cifs_dbg(VFS, "%s: Failed to alloc aead request\n", __func__);
3388 return -ENOMEM; 3472 return -ENOMEM;
3389 } 3473 }
3390 3474
@@ -3395,7 +3479,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
3395 3479
3396 sg = init_sg(num_rqst, rqst, sign); 3480 sg = init_sg(num_rqst, rqst, sign);
3397 if (!sg) { 3481 if (!sg) {
3398 cifs_dbg(VFS, "%s: Failed to init sg", __func__); 3482 cifs_dbg(VFS, "%s: Failed to init sg\n", __func__);
3399 rc = -ENOMEM; 3483 rc = -ENOMEM;
3400 goto free_req; 3484 goto free_req;
3401 } 3485 }
@@ -3403,7 +3487,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
3403 iv_len = crypto_aead_ivsize(tfm); 3487 iv_len = crypto_aead_ivsize(tfm);
3404 iv = kzalloc(iv_len, GFP_KERNEL); 3488 iv = kzalloc(iv_len, GFP_KERNEL);
3405 if (!iv) { 3489 if (!iv) {
3406 cifs_dbg(VFS, "%s: Failed to alloc IV", __func__); 3490 cifs_dbg(VFS, "%s: Failed to alloc iv\n", __func__);
3407 rc = -ENOMEM; 3491 rc = -ENOMEM;
3408 goto free_sg; 3492 goto free_sg;
3409 } 3493 }
@@ -3511,7 +3595,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
3511 fill_transform_hdr(tr_hdr, orig_len, old_rq); 3595 fill_transform_hdr(tr_hdr, orig_len, old_rq);
3512 3596
3513 rc = crypt_message(server, num_rqst, new_rq, 1); 3597 rc = crypt_message(server, num_rqst, new_rq, 1);
3514 cifs_dbg(FYI, "encrypt message returned %d", rc); 3598 cifs_dbg(FYI, "Encrypt message returned %d\n", rc);
3515 if (rc) 3599 if (rc)
3516 goto err_free; 3600 goto err_free;
3517 3601
@@ -3552,7 +3636,7 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
3552 rqst.rq_tailsz = (page_data_size % PAGE_SIZE) ? : PAGE_SIZE; 3636 rqst.rq_tailsz = (page_data_size % PAGE_SIZE) ? : PAGE_SIZE;
3553 3637
3554 rc = crypt_message(server, 1, &rqst, 0); 3638 rc = crypt_message(server, 1, &rqst, 0);
3555 cifs_dbg(FYI, "decrypt message returned %d\n", rc); 3639 cifs_dbg(FYI, "Decrypt message returned %d\n", rc);
3556 3640
3557 if (rc) 3641 if (rc)
3558 return rc; 3642 return rc;
@@ -4166,6 +4250,7 @@ struct smb_version_operations smb20_operations = {
4166 .ioctl_query_info = smb2_ioctl_query_info, 4250 .ioctl_query_info = smb2_ioctl_query_info,
4167 .make_node = smb2_make_node, 4251 .make_node = smb2_make_node,
4168 .fiemap = smb3_fiemap, 4252 .fiemap = smb3_fiemap,
4253 .llseek = smb3_llseek,
4169}; 4254};
4170 4255
4171struct smb_version_operations smb21_operations = { 4256struct smb_version_operations smb21_operations = {
@@ -4266,6 +4351,7 @@ struct smb_version_operations smb21_operations = {
4266 .ioctl_query_info = smb2_ioctl_query_info, 4351 .ioctl_query_info = smb2_ioctl_query_info,
4267 .make_node = smb2_make_node, 4352 .make_node = smb2_make_node,
4268 .fiemap = smb3_fiemap, 4353 .fiemap = smb3_fiemap,
4354 .llseek = smb3_llseek,
4269}; 4355};
4270 4356
4271struct smb_version_operations smb30_operations = { 4357struct smb_version_operations smb30_operations = {
@@ -4375,6 +4461,7 @@ struct smb_version_operations smb30_operations = {
4375 .ioctl_query_info = smb2_ioctl_query_info, 4461 .ioctl_query_info = smb2_ioctl_query_info,
4376 .make_node = smb2_make_node, 4462 .make_node = smb2_make_node,
4377 .fiemap = smb3_fiemap, 4463 .fiemap = smb3_fiemap,
4464 .llseek = smb3_llseek,
4378}; 4465};
4379 4466
4380struct smb_version_operations smb311_operations = { 4467struct smb_version_operations smb311_operations = {
@@ -4485,6 +4572,7 @@ struct smb_version_operations smb311_operations = {
4485 .ioctl_query_info = smb2_ioctl_query_info, 4572 .ioctl_query_info = smb2_ioctl_query_info,
4486 .make_node = smb2_make_node, 4573 .make_node = smb2_make_node,
4487 .fiemap = smb3_fiemap, 4574 .fiemap = smb3_fiemap,
4575 .llseek = smb3_llseek,
4488}; 4576};
4489 4577
4490struct smb_version_values smb20_values = { 4578struct smb_version_values smb20_values = {
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 29f011d8d8e2..710ceb875161 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -2538,11 +2538,25 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
2538 struct kvec *iov = rqst->rq_iov; 2538 struct kvec *iov = rqst->rq_iov;
2539 unsigned int total_len; 2539 unsigned int total_len;
2540 int rc; 2540 int rc;
2541 char *in_data_buf;
2541 2542
2542 rc = smb2_plain_req_init(SMB2_IOCTL, tcon, (void **) &req, &total_len); 2543 rc = smb2_plain_req_init(SMB2_IOCTL, tcon, (void **) &req, &total_len);
2543 if (rc) 2544 if (rc)
2544 return rc; 2545 return rc;
2545 2546
2547 if (indatalen) {
2548 /*
2549 * indatalen is usually small at a couple of bytes max, so
2550 * just allocate through generic pool
2551 */
2552 in_data_buf = kmalloc(indatalen, GFP_NOFS);
2553 if (!in_data_buf) {
2554 cifs_small_buf_release(req);
2555 return -ENOMEM;
2556 }
2557 memcpy(in_data_buf, in_data, indatalen);
2558 }
2559
2546 req->CtlCode = cpu_to_le32(opcode); 2560 req->CtlCode = cpu_to_le32(opcode);
2547 req->PersistentFileId = persistent_fid; 2561 req->PersistentFileId = persistent_fid;
2548 req->VolatileFileId = volatile_fid; 2562 req->VolatileFileId = volatile_fid;
@@ -2563,7 +2577,7 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
2563 cpu_to_le32(offsetof(struct smb2_ioctl_req, Buffer)); 2577 cpu_to_le32(offsetof(struct smb2_ioctl_req, Buffer));
2564 rqst->rq_nvec = 2; 2578 rqst->rq_nvec = 2;
2565 iov[0].iov_len = total_len - 1; 2579 iov[0].iov_len = total_len - 1;
2566 iov[1].iov_base = in_data; 2580 iov[1].iov_base = in_data_buf;
2567 iov[1].iov_len = indatalen; 2581 iov[1].iov_len = indatalen;
2568 } else { 2582 } else {
2569 rqst->rq_nvec = 1; 2583 rqst->rq_nvec = 1;
@@ -2605,8 +2619,11 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
2605void 2619void
2606SMB2_ioctl_free(struct smb_rqst *rqst) 2620SMB2_ioctl_free(struct smb_rqst *rqst)
2607{ 2621{
2608 if (rqst && rqst->rq_iov) 2622 if (rqst && rqst->rq_iov) {
2609 cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ 2623 cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
2624 if (rqst->rq_iov[1].iov_len)
2625 kfree(rqst->rq_iov[1].iov_base);
2626 }
2610} 2627}
2611 2628
2612 2629
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index 251ef1223206..caac37b1de8c 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -903,7 +903,7 @@ static int smbd_create_header(struct smbd_connection *info,
903 request->sge[0].addr = ib_dma_map_single(info->id->device, 903 request->sge[0].addr = ib_dma_map_single(info->id->device,
904 (void *)packet, 904 (void *)packet,
905 header_length, 905 header_length,
906 DMA_BIDIRECTIONAL); 906 DMA_TO_DEVICE);
907 if (ib_dma_mapping_error(info->id->device, request->sge[0].addr)) { 907 if (ib_dma_mapping_error(info->id->device, request->sge[0].addr)) {
908 mempool_free(request, info->request_mempool); 908 mempool_free(request, info->request_mempool);
909 rc = -EIO; 909 rc = -EIO;
@@ -1005,7 +1005,7 @@ static int smbd_post_send_sgl(struct smbd_connection *info,
1005 for_each_sg(sgl, sg, num_sgs, i) { 1005 for_each_sg(sgl, sg, num_sgs, i) {
1006 request->sge[i+1].addr = 1006 request->sge[i+1].addr =
1007 ib_dma_map_page(info->id->device, sg_page(sg), 1007 ib_dma_map_page(info->id->device, sg_page(sg),
1008 sg->offset, sg->length, DMA_BIDIRECTIONAL); 1008 sg->offset, sg->length, DMA_TO_DEVICE);
1009 if (ib_dma_mapping_error( 1009 if (ib_dma_mapping_error(
1010 info->id->device, request->sge[i+1].addr)) { 1010 info->id->device, request->sge[i+1].addr)) {
1011 rc = -EIO; 1011 rc = -EIO;
@@ -2110,8 +2110,10 @@ int smbd_send(struct TCP_Server_Info *server,
2110 goto done; 2110 goto done;
2111 } 2111 }
2112 2112
2113 rqst_idx = 0; 2113 log_write(INFO, "num_rqst=%d total length=%u\n",
2114 num_rqst, remaining_data_length);
2114 2115
2116 rqst_idx = 0;
2115next_rqst: 2117next_rqst:
2116 rqst = &rqst_array[rqst_idx]; 2118 rqst = &rqst_array[rqst_idx];
2117 iov = rqst->rq_iov; 2119 iov = rqst->rq_iov;
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 9a16ff4b9f5e..60661b3f983a 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -33,7 +33,7 @@
33#include <linux/uaccess.h> 33#include <linux/uaccess.h>
34#include <asm/processor.h> 34#include <asm/processor.h>
35#include <linux/mempool.h> 35#include <linux/mempool.h>
36#include <linux/signal.h> 36#include <linux/sched/signal.h>
37#include "cifspdu.h" 37#include "cifspdu.h"
38#include "cifsglob.h" 38#include "cifsglob.h"
39#include "cifsproto.h" 39#include "cifsproto.h"
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
index 968f163b5feb..8e83741b02e0 100644
--- a/fs/ext4/block_validity.c
+++ b/fs/ext4/block_validity.c
@@ -142,7 +142,8 @@ static int ext4_protect_reserved_inode(struct super_block *sb, u32 ino)
142 struct inode *inode; 142 struct inode *inode;
143 struct ext4_sb_info *sbi = EXT4_SB(sb); 143 struct ext4_sb_info *sbi = EXT4_SB(sb);
144 struct ext4_map_blocks map; 144 struct ext4_map_blocks map;
145 u32 i = 0, err = 0, num, n; 145 u32 i = 0, num;
146 int err = 0, n;
146 147
147 if ((ino < EXT4_ROOT_INO) || 148 if ((ino < EXT4_ROOT_INO) ||
148 (ino > le32_to_cpu(sbi->s_es->s_inodes_count))) 149 (ino > le32_to_cpu(sbi->s_es->s_inodes_count)))
@@ -276,6 +277,11 @@ int ext4_check_blockref(const char *function, unsigned int line,
276 __le32 *bref = p; 277 __le32 *bref = p;
277 unsigned int blk; 278 unsigned int blk;
278 279
280 if (ext4_has_feature_journal(inode->i_sb) &&
281 (inode->i_ino ==
282 le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
283 return 0;
284
279 while (bref < p+max) { 285 while (bref < p+max) {
280 blk = le32_to_cpu(*bref++); 286 blk = le32_to_cpu(*bref++);
281 if (blk && 287 if (blk &&
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 0f89f5190cd7..f2c62e2a0c98 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1035,6 +1035,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
1035 __le32 border; 1035 __le32 border;
1036 ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */ 1036 ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
1037 int err = 0; 1037 int err = 0;
1038 size_t ext_size = 0;
1038 1039
1039 /* make decision: where to split? */ 1040 /* make decision: where to split? */
1040 /* FIXME: now decision is simplest: at current extent */ 1041 /* FIXME: now decision is simplest: at current extent */
@@ -1126,6 +1127,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
1126 le16_add_cpu(&neh->eh_entries, m); 1127 le16_add_cpu(&neh->eh_entries, m);
1127 } 1128 }
1128 1129
1130 /* zero out unused area in the extent block */
1131 ext_size = sizeof(struct ext4_extent_header) +
1132 sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries);
1133 memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
1129 ext4_extent_block_csum_set(inode, neh); 1134 ext4_extent_block_csum_set(inode, neh);
1130 set_buffer_uptodate(bh); 1135 set_buffer_uptodate(bh);
1131 unlock_buffer(bh); 1136 unlock_buffer(bh);
@@ -1205,6 +1210,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
1205 sizeof(struct ext4_extent_idx) * m); 1210 sizeof(struct ext4_extent_idx) * m);
1206 le16_add_cpu(&neh->eh_entries, m); 1211 le16_add_cpu(&neh->eh_entries, m);
1207 } 1212 }
1213 /* zero out unused area in the extent block */
1214 ext_size = sizeof(struct ext4_extent_header) +
1215 (sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries));
1216 memset(bh->b_data + ext_size, 0,
1217 inode->i_sb->s_blocksize - ext_size);
1208 ext4_extent_block_csum_set(inode, neh); 1218 ext4_extent_block_csum_set(inode, neh);
1209 set_buffer_uptodate(bh); 1219 set_buffer_uptodate(bh);
1210 unlock_buffer(bh); 1220 unlock_buffer(bh);
@@ -1270,6 +1280,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1270 ext4_fsblk_t newblock, goal = 0; 1280 ext4_fsblk_t newblock, goal = 0;
1271 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; 1281 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
1272 int err = 0; 1282 int err = 0;
1283 size_t ext_size = 0;
1273 1284
1274 /* Try to prepend new index to old one */ 1285 /* Try to prepend new index to old one */
1275 if (ext_depth(inode)) 1286 if (ext_depth(inode))
@@ -1295,9 +1306,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1295 goto out; 1306 goto out;
1296 } 1307 }
1297 1308
1309 ext_size = sizeof(EXT4_I(inode)->i_data);
1298 /* move top-level index/leaf into new block */ 1310 /* move top-level index/leaf into new block */
1299 memmove(bh->b_data, EXT4_I(inode)->i_data, 1311 memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size);
1300 sizeof(EXT4_I(inode)->i_data)); 1312 /* zero out unused area in the extent block */
1313 memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
1301 1314
1302 /* set size of new block */ 1315 /* set size of new block */
1303 neh = ext_block_hdr(bh); 1316 neh = ext_block_hdr(bh);
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 98ec11f69cd4..2c5baa5e8291 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -264,6 +264,13 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
264 } 264 }
265 265
266 ret = __generic_file_write_iter(iocb, from); 266 ret = __generic_file_write_iter(iocb, from);
267 /*
268 * Unaligned direct AIO must be the only IO in flight. Otherwise
269 * overlapping aligned IO after unaligned might result in data
270 * corruption.
271 */
272 if (ret == -EIOCBQUEUED && unaligned_aio)
273 ext4_unwritten_wait(inode);
267 inode_unlock(inode); 274 inode_unlock(inode);
268 275
269 if (ret > 0) 276 if (ret > 0)
diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c
index 4b99e2db95b8..dbccf46f1770 100644
--- a/fs/ext4/fsmap.c
+++ b/fs/ext4/fsmap.c
@@ -626,7 +626,7 @@ int ext4_getfsmap(struct super_block *sb, struct ext4_fsmap_head *head,
626{ 626{
627 struct ext4_fsmap dkeys[2]; /* per-dev keys */ 627 struct ext4_fsmap dkeys[2]; /* per-dev keys */
628 struct ext4_getfsmap_dev handlers[EXT4_GETFSMAP_DEVS]; 628 struct ext4_getfsmap_dev handlers[EXT4_GETFSMAP_DEVS];
629 struct ext4_getfsmap_info info = {0}; 629 struct ext4_getfsmap_info info = { NULL };
630 int i; 630 int i;
631 int error = 0; 631 int error = 0;
632 632
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 7e85ecf0b849..e486e49b31ed 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -608,7 +608,7 @@ static int ext4_getfsmap_format(struct ext4_fsmap *xfm, void *priv)
608static int ext4_ioc_getfsmap(struct super_block *sb, 608static int ext4_ioc_getfsmap(struct super_block *sb,
609 struct fsmap_head __user *arg) 609 struct fsmap_head __user *arg)
610{ 610{
611 struct getfsmap_info info = {0}; 611 struct getfsmap_info info = { NULL };
612 struct ext4_fsmap_head xhead = {0}; 612 struct ext4_fsmap_head xhead = {0};
613 struct fsmap_head head; 613 struct fsmap_head head;
614 bool aborted = false; 614 bool aborted = false;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 6d50f53b7a15..cd01c4a67ffb 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -872,12 +872,15 @@ static void dx_release(struct dx_frame *frames)
872{ 872{
873 struct dx_root_info *info; 873 struct dx_root_info *info;
874 int i; 874 int i;
875 unsigned int indirect_levels;
875 876
876 if (frames[0].bh == NULL) 877 if (frames[0].bh == NULL)
877 return; 878 return;
878 879
879 info = &((struct dx_root *)frames[0].bh->b_data)->info; 880 info = &((struct dx_root *)frames[0].bh->b_data)->info;
880 for (i = 0; i <= info->indirect_levels; i++) { 881 /* save local copy, "info" may be freed after brelse() */
882 indirect_levels = info->indirect_levels;
883 for (i = 0; i <= indirect_levels; i++) {
881 if (frames[i].bh == NULL) 884 if (frames[i].bh == NULL)
882 break; 885 break;
883 brelse(frames[i].bh); 886 brelse(frames[i].bh);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index f71b5254a990..4079605d437a 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -699,7 +699,7 @@ void __ext4_abort(struct super_block *sb, const char *function,
699 jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); 699 jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
700 save_error_info(sb, function, line); 700 save_error_info(sb, function, line);
701 } 701 }
702 if (test_opt(sb, ERRORS_PANIC)) { 702 if (test_opt(sb, ERRORS_PANIC) && !system_going_down()) {
703 if (EXT4_SB(sb)->s_journal && 703 if (EXT4_SB(sb)->s_journal &&
704 !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR)) 704 !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
705 return; 705 return;
@@ -4661,7 +4661,7 @@ failed_mount:
4661 4661
4662#ifdef CONFIG_QUOTA 4662#ifdef CONFIG_QUOTA
4663 for (i = 0; i < EXT4_MAXQUOTAS; i++) 4663 for (i = 0; i < EXT4_MAXQUOTAS; i++)
4664 kfree(sbi->s_qf_names[i]); 4664 kfree(get_qf_name(sb, sbi, i));
4665#endif 4665#endif
4666 ext4_blkdev_remove(sbi); 4666 ext4_blkdev_remove(sbi);
4667 brelse(bh); 4667 brelse(bh);
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 37e16d969925..43df0c943229 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -2375,22 +2375,19 @@ static struct kmem_cache *jbd2_journal_head_cache;
2375static atomic_t nr_journal_heads = ATOMIC_INIT(0); 2375static atomic_t nr_journal_heads = ATOMIC_INIT(0);
2376#endif 2376#endif
2377 2377
2378static int jbd2_journal_init_journal_head_cache(void) 2378static int __init jbd2_journal_init_journal_head_cache(void)
2379{ 2379{
2380 int retval; 2380 J_ASSERT(!jbd2_journal_head_cache);
2381
2382 J_ASSERT(jbd2_journal_head_cache == NULL);
2383 jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head", 2381 jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head",
2384 sizeof(struct journal_head), 2382 sizeof(struct journal_head),
2385 0, /* offset */ 2383 0, /* offset */
2386 SLAB_TEMPORARY | SLAB_TYPESAFE_BY_RCU, 2384 SLAB_TEMPORARY | SLAB_TYPESAFE_BY_RCU,
2387 NULL); /* ctor */ 2385 NULL); /* ctor */
2388 retval = 0;
2389 if (!jbd2_journal_head_cache) { 2386 if (!jbd2_journal_head_cache) {
2390 retval = -ENOMEM;
2391 printk(KERN_EMERG "JBD2: no memory for journal_head cache\n"); 2387 printk(KERN_EMERG "JBD2: no memory for journal_head cache\n");
2388 return -ENOMEM;
2392 } 2389 }
2393 return retval; 2390 return 0;
2394} 2391}
2395 2392
2396static void jbd2_journal_destroy_journal_head_cache(void) 2393static void jbd2_journal_destroy_journal_head_cache(void)
@@ -2636,28 +2633,38 @@ static void __exit jbd2_remove_jbd_stats_proc_entry(void)
2636 2633
2637struct kmem_cache *jbd2_handle_cache, *jbd2_inode_cache; 2634struct kmem_cache *jbd2_handle_cache, *jbd2_inode_cache;
2638 2635
2636static int __init jbd2_journal_init_inode_cache(void)
2637{
2638 J_ASSERT(!jbd2_inode_cache);
2639 jbd2_inode_cache = KMEM_CACHE(jbd2_inode, 0);
2640 if (!jbd2_inode_cache) {
2641 pr_emerg("JBD2: failed to create inode cache\n");
2642 return -ENOMEM;
2643 }
2644 return 0;
2645}
2646
2639static int __init jbd2_journal_init_handle_cache(void) 2647static int __init jbd2_journal_init_handle_cache(void)
2640{ 2648{
2649 J_ASSERT(!jbd2_handle_cache);
2641 jbd2_handle_cache = KMEM_CACHE(jbd2_journal_handle, SLAB_TEMPORARY); 2650 jbd2_handle_cache = KMEM_CACHE(jbd2_journal_handle, SLAB_TEMPORARY);
2642 if (jbd2_handle_cache == NULL) { 2651 if (!jbd2_handle_cache) {
2643 printk(KERN_EMERG "JBD2: failed to create handle cache\n"); 2652 printk(KERN_EMERG "JBD2: failed to create handle cache\n");
2644 return -ENOMEM; 2653 return -ENOMEM;
2645 } 2654 }
2646 jbd2_inode_cache = KMEM_CACHE(jbd2_inode, 0);
2647 if (jbd2_inode_cache == NULL) {
2648 printk(KERN_EMERG "JBD2: failed to create inode cache\n");
2649 kmem_cache_destroy(jbd2_handle_cache);
2650 return -ENOMEM;
2651 }
2652 return 0; 2655 return 0;
2653} 2656}
2654 2657
2658static void jbd2_journal_destroy_inode_cache(void)
2659{
2660 kmem_cache_destroy(jbd2_inode_cache);
2661 jbd2_inode_cache = NULL;
2662}
2663
2655static void jbd2_journal_destroy_handle_cache(void) 2664static void jbd2_journal_destroy_handle_cache(void)
2656{ 2665{
2657 kmem_cache_destroy(jbd2_handle_cache); 2666 kmem_cache_destroy(jbd2_handle_cache);
2658 jbd2_handle_cache = NULL; 2667 jbd2_handle_cache = NULL;
2659 kmem_cache_destroy(jbd2_inode_cache);
2660 jbd2_inode_cache = NULL;
2661} 2668}
2662 2669
2663/* 2670/*
@@ -2668,21 +2675,27 @@ static int __init journal_init_caches(void)
2668{ 2675{
2669 int ret; 2676 int ret;
2670 2677
2671 ret = jbd2_journal_init_revoke_caches(); 2678 ret = jbd2_journal_init_revoke_record_cache();
2679 if (ret == 0)
2680 ret = jbd2_journal_init_revoke_table_cache();
2672 if (ret == 0) 2681 if (ret == 0)
2673 ret = jbd2_journal_init_journal_head_cache(); 2682 ret = jbd2_journal_init_journal_head_cache();
2674 if (ret == 0) 2683 if (ret == 0)
2675 ret = jbd2_journal_init_handle_cache(); 2684 ret = jbd2_journal_init_handle_cache();
2676 if (ret == 0) 2685 if (ret == 0)
2686 ret = jbd2_journal_init_inode_cache();
2687 if (ret == 0)
2677 ret = jbd2_journal_init_transaction_cache(); 2688 ret = jbd2_journal_init_transaction_cache();
2678 return ret; 2689 return ret;
2679} 2690}
2680 2691
2681static void jbd2_journal_destroy_caches(void) 2692static void jbd2_journal_destroy_caches(void)
2682{ 2693{
2683 jbd2_journal_destroy_revoke_caches(); 2694 jbd2_journal_destroy_revoke_record_cache();
2695 jbd2_journal_destroy_revoke_table_cache();
2684 jbd2_journal_destroy_journal_head_cache(); 2696 jbd2_journal_destroy_journal_head_cache();
2685 jbd2_journal_destroy_handle_cache(); 2697 jbd2_journal_destroy_handle_cache();
2698 jbd2_journal_destroy_inode_cache();
2686 jbd2_journal_destroy_transaction_cache(); 2699 jbd2_journal_destroy_transaction_cache();
2687 jbd2_journal_destroy_slabs(); 2700 jbd2_journal_destroy_slabs();
2688} 2701}
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index a1143e57a718..69b9bc329964 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -178,33 +178,41 @@ static struct jbd2_revoke_record_s *find_revoke_record(journal_t *journal,
178 return NULL; 178 return NULL;
179} 179}
180 180
181void jbd2_journal_destroy_revoke_caches(void) 181void jbd2_journal_destroy_revoke_record_cache(void)
182{ 182{
183 kmem_cache_destroy(jbd2_revoke_record_cache); 183 kmem_cache_destroy(jbd2_revoke_record_cache);
184 jbd2_revoke_record_cache = NULL; 184 jbd2_revoke_record_cache = NULL;
185}
186
187void jbd2_journal_destroy_revoke_table_cache(void)
188{
185 kmem_cache_destroy(jbd2_revoke_table_cache); 189 kmem_cache_destroy(jbd2_revoke_table_cache);
186 jbd2_revoke_table_cache = NULL; 190 jbd2_revoke_table_cache = NULL;
187} 191}
188 192
189int __init jbd2_journal_init_revoke_caches(void) 193int __init jbd2_journal_init_revoke_record_cache(void)
190{ 194{
191 J_ASSERT(!jbd2_revoke_record_cache); 195 J_ASSERT(!jbd2_revoke_record_cache);
192 J_ASSERT(!jbd2_revoke_table_cache);
193
194 jbd2_revoke_record_cache = KMEM_CACHE(jbd2_revoke_record_s, 196 jbd2_revoke_record_cache = KMEM_CACHE(jbd2_revoke_record_s,
195 SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY); 197 SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY);
196 if (!jbd2_revoke_record_cache)
197 goto record_cache_failure;
198 198
199 if (!jbd2_revoke_record_cache) {
200 pr_emerg("JBD2: failed to create revoke_record cache\n");
201 return -ENOMEM;
202 }
203 return 0;
204}
205
206int __init jbd2_journal_init_revoke_table_cache(void)
207{
208 J_ASSERT(!jbd2_revoke_table_cache);
199 jbd2_revoke_table_cache = KMEM_CACHE(jbd2_revoke_table_s, 209 jbd2_revoke_table_cache = KMEM_CACHE(jbd2_revoke_table_s,
200 SLAB_TEMPORARY); 210 SLAB_TEMPORARY);
201 if (!jbd2_revoke_table_cache) 211 if (!jbd2_revoke_table_cache) {
202 goto table_cache_failure; 212 pr_emerg("JBD2: failed to create revoke_table cache\n");
203 return 0;
204table_cache_failure:
205 jbd2_journal_destroy_revoke_caches();
206record_cache_failure:
207 return -ENOMEM; 213 return -ENOMEM;
214 }
215 return 0;
208} 216}
209 217
210static struct jbd2_revoke_table_s *jbd2_journal_init_revoke_table(int hash_size) 218static struct jbd2_revoke_table_s *jbd2_journal_init_revoke_table(int hash_size)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index f940d31c2adc..8ca4fddc705f 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -42,9 +42,11 @@ int __init jbd2_journal_init_transaction_cache(void)
42 0, 42 0,
43 SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY, 43 SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
44 NULL); 44 NULL);
45 if (transaction_cache) 45 if (!transaction_cache) {
46 return 0; 46 pr_emerg("JBD2: failed to create transaction cache\n");
47 return -ENOMEM; 47 return -ENOMEM;
48 }
49 return 0;
48} 50}
49 51
50void jbd2_journal_destroy_transaction_cache(void) 52void jbd2_journal_destroy_transaction_cache(void)
diff --git a/fs/ocfs2/dlm/Makefile b/fs/ocfs2/dlm/Makefile
index ef2854422a6e..3d4041f0431e 100644
--- a/fs/ocfs2/dlm/Makefile
+++ b/fs/ocfs2/dlm/Makefile
@@ -1,7 +1,6 @@
1ccflags-y := -I$(src)/.. 1ccflags-y := -I $(srctree)/$(src)/..
2 2
3obj-$(CONFIG_OCFS2_FS_O2CB) += ocfs2_dlm.o 3obj-$(CONFIG_OCFS2_FS_O2CB) += ocfs2_dlm.o
4 4
5ocfs2_dlm-objs := dlmdomain.o dlmdebug.o dlmthread.o dlmrecovery.o \ 5ocfs2_dlm-objs := dlmdomain.o dlmdebug.o dlmthread.o dlmrecovery.o \
6 dlmmaster.o dlmast.o dlmconvert.o dlmlock.o dlmunlock.o 6 dlmmaster.o dlmast.o dlmconvert.o dlmlock.o dlmunlock.o
7
diff --git a/fs/ocfs2/dlmfs/Makefile b/fs/ocfs2/dlmfs/Makefile
index 33431a0296a3..0a0b93d940fe 100644
--- a/fs/ocfs2/dlmfs/Makefile
+++ b/fs/ocfs2/dlmfs/Makefile
@@ -1,4 +1,4 @@
1ccflags-y := -I$(src)/.. 1ccflags-y := -I $(srctree)/$(src)/..
2 2
3obj-$(CONFIG_OCFS2_FS) += ocfs2_dlmfs.o 3obj-$(CONFIG_OCFS2_FS) += ocfs2_dlmfs.o
4 4
diff --git a/fs/unicode/README.utf8data b/fs/unicode/README.utf8data
index 9307cf0727de..c73786807d3b 100644
--- a/fs/unicode/README.utf8data
+++ b/fs/unicode/README.utf8data
@@ -5,29 +5,15 @@ The full set of files can be found here:
5 5
6 http://www.unicode.org/Public/12.1.0/ucd/ 6 http://www.unicode.org/Public/12.1.0/ucd/
7 7
8Note!
9
10The URL's listed below are not stable. That's because Unicode 12.1.0
11has not been officially released yet; it is scheduled to be released
12on May 8, 2019. We taking Unicode 12.1.0 a few weeks early because it
13contains a new Japanese character which is required in order to
14specify Japenese dates after May 1, 2019, when Crown Prince Naruhito
15ascends to the Chrysanthemum Throne. (Isn't internationalization fun?
16The abdication of Emperor Akihito of Japan is requiring dozens of
17software packages to be updated with only a month's notice. :-)
18
19We will update the URL's (and any needed changes to the checksums)
20after the final Unicode 12.1.0 is released.
21
22Individual source links: 8Individual source links:
23 9
24 https://www.unicode.org/Public/12.1.0/ucd/CaseFolding-12.1.0d2.txt 10 https://www.unicode.org/Public/12.1.0/ucd/CaseFolding.txt
25 https://www.unicode.org/Public/12.1.0/ucd/DerivedAge-12.1.0d3.txt 11 https://www.unicode.org/Public/12.1.0/ucd/DerivedAge.txt
26 https://www.unicode.org/Public/12.1.0/ucd/extracted/DerivedCombiningClass-12.1.0d2.txt 12 https://www.unicode.org/Public/12.1.0/ucd/extracted/DerivedCombiningClass.txt
27 https://www.unicode.org/Public/12.1.0/ucd/DerivedCoreProperties-12.1.0d2.txt 13 https://www.unicode.org/Public/12.1.0/ucd/DerivedCoreProperties.txt
28 https://www.unicode.org/Public/12.1.0/ucd/NormalizationCorrections-12.1.0d1.txt 14 https://www.unicode.org/Public/12.1.0/ucd/NormalizationCorrections.txt
29 https://www.unicode.org/Public/12.1.0/ucd/NormalizationTest-12.1.0d3.txt 15 https://www.unicode.org/Public/12.1.0/ucd/NormalizationTest.txt
30 https://www.unicode.org/Public/12.1.0/ucd/UnicodeData-12.1.0d2.txt 16 https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt
31 17
32md5sums (verify by running "md5sum -c README.utf8data"): 18md5sums (verify by running "md5sum -c README.utf8data"):
33 19
diff --git a/fs/unicode/utf8-norm.c b/fs/unicode/utf8-norm.c
index 20d440c3f2db..801ed6d2ea37 100644
--- a/fs/unicode/utf8-norm.c
+++ b/fs/unicode/utf8-norm.c
@@ -714,6 +714,8 @@ int utf8byte(struct utf8cursor *u8c)
714 } 714 }
715 715
716 leaf = utf8lookup(u8c->data, u8c->hangul, u8c->s); 716 leaf = utf8lookup(u8c->data, u8c->hangul, u8c->s);
717 if (!leaf)
718 return -1;
717 ccc = LEAF_CCC(leaf); 719 ccc = LEAF_CCC(leaf);
718 } 720 }
719 721
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 1dfc6df2e2bd..91831975363b 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -4,8 +4,8 @@
4# All Rights Reserved. 4# All Rights Reserved.
5# 5#
6 6
7ccflags-y += -I$(src) # needed for trace events 7ccflags-y += -I $(srctree)/$(src) # needed for trace events
8ccflags-y += -I$(src)/libxfs 8ccflags-y += -I $(srctree)/$(src)/libxfs
9 9
10ccflags-$(CONFIG_XFS_DEBUG) += -g 10ccflags-$(CONFIG_XFS_DEBUG) += -g
11 11
diff --git a/include/asm-generic/mm_hooks.h b/include/asm-generic/mm_hooks.h
index 8ac4e68a12f0..6736ed2f632b 100644
--- a/include/asm-generic/mm_hooks.h
+++ b/include/asm-generic/mm_hooks.h
@@ -18,7 +18,6 @@ static inline void arch_exit_mmap(struct mm_struct *mm)
18} 18}
19 19
20static inline void arch_unmap(struct mm_struct *mm, 20static inline void arch_unmap(struct mm_struct *mm,
21 struct vm_area_struct *vma,
22 unsigned long start, unsigned long end) 21 unsigned long start, unsigned long end)
23{ 22{
24} 23}
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 0c53f26ae3d3..44e8fc30b889 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -161,6 +161,7 @@
161 161
162#define AT91_PMC_FSMR 0x70 /* Fast Startup Mode Register */ 162#define AT91_PMC_FSMR 0x70 /* Fast Startup Mode Register */
163#define AT91_PMC_FSTT(n) BIT(n) 163#define AT91_PMC_FSTT(n) BIT(n)
164#define AT91_PMC_RTTAL BIT(16)
164#define AT91_PMC_RTCAL BIT(17) /* RTC Alarm Enable */ 165#define AT91_PMC_RTCAL BIT(17) /* RTC Alarm Enable */
165#define AT91_PMC_USBAL BIT(18) /* USB Resume Enable */ 166#define AT91_PMC_USBAL BIT(18) /* USB Resume Enable */
166#define AT91_PMC_SDMMC_CD BIT(19) /* SDMMC Card Detect Enable */ 167#define AT91_PMC_SDMMC_CD BIT(19) /* SDMMC Card Detect Enable */
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index e760dc5d1fa8..476e0c54de2d 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -71,12 +71,25 @@ void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle,
71 size_t size, enum dma_data_direction dir, unsigned long attrs); 71 size_t size, enum dma_data_direction dir, unsigned long attrs);
72 72
73/* The DMA API isn't _quite_ the whole story, though... */ 73/* The DMA API isn't _quite_ the whole story, though... */
74void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg); 74/*
75 * iommu_dma_prepare_msi() - Map the MSI page in the IOMMU device
76 *
77 * The MSI page will be stored in @desc.
78 *
79 * Return: 0 on success otherwise an error describing the failure.
80 */
81int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr);
82
83/* Update the MSI message if required. */
84void iommu_dma_compose_msi_msg(struct msi_desc *desc,
85 struct msi_msg *msg);
86
75void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list); 87void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
76 88
77#else 89#else
78 90
79struct iommu_domain; 91struct iommu_domain;
92struct msi_desc;
80struct msi_msg; 93struct msi_msg;
81struct device; 94struct device;
82 95
@@ -99,7 +112,14 @@ static inline void iommu_put_dma_cookie(struct iommu_domain *domain)
99{ 112{
100} 113}
101 114
102static inline void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) 115static inline int iommu_dma_prepare_msi(struct msi_desc *desc,
116 phys_addr_t msi_addr)
117{
118 return 0;
119}
120
121static inline void iommu_dma_compose_msi_msg(struct msi_desc *desc,
122 struct msi_msg *msg)
103{ 123{
104} 124}
105 125
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index be27062f8ed1..6c4db54714f6 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -470,6 +470,9 @@ extern struct i2c_client *
470i2c_new_dummy(struct i2c_adapter *adap, u16 address); 470i2c_new_dummy(struct i2c_adapter *adap, u16 address);
471 471
472extern struct i2c_client * 472extern struct i2c_client *
473devm_i2c_new_dummy_device(struct device *dev, struct i2c_adapter *adap, u16 address);
474
475extern struct i2c_client *
473i2c_new_secondary_device(struct i2c_client *client, 476i2c_new_secondary_device(struct i2c_client *client,
474 const char *name, 477 const char *name,
475 u16 default_addr); 478 u16 default_addr);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 7ae8de5ad0f2..fb301cf29148 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -625,6 +625,8 @@ extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
625extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, 625extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data,
626 void *vcpu_info); 626 void *vcpu_info);
627extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type); 627extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type);
628extern int irq_chip_request_resources_parent(struct irq_data *data);
629extern void irq_chip_release_resources_parent(struct irq_data *data);
628#endif 630#endif
629 631
630/* Handling of unhandled and spurious interrupts: */ 632/* Handling of unhandled and spurious interrupts: */
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index c848a7cc502e..c7e3e39224c6 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -165,7 +165,7 @@
165#define GICR_PROPBASER_nCnB GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, nCnB) 165#define GICR_PROPBASER_nCnB GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, nCnB)
166#define GICR_PROPBASER_nC GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, nC) 166#define GICR_PROPBASER_nC GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, nC)
167#define GICR_PROPBASER_RaWt GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RaWt) 167#define GICR_PROPBASER_RaWt GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RaWt)
168#define GICR_PROPBASER_RaWb GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RaWt) 168#define GICR_PROPBASER_RaWb GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RaWb)
169#define GICR_PROPBASER_WaWt GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, WaWt) 169#define GICR_PROPBASER_WaWt GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, WaWt)
170#define GICR_PROPBASER_WaWb GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, WaWb) 170#define GICR_PROPBASER_WaWb GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, WaWb)
171#define GICR_PROPBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RaWaWt) 171#define GICR_PROPBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RaWaWt)
@@ -192,7 +192,7 @@
192#define GICR_PENDBASER_nCnB GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, nCnB) 192#define GICR_PENDBASER_nCnB GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, nCnB)
193#define GICR_PENDBASER_nC GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, nC) 193#define GICR_PENDBASER_nC GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, nC)
194#define GICR_PENDBASER_RaWt GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RaWt) 194#define GICR_PENDBASER_RaWt GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RaWt)
195#define GICR_PENDBASER_RaWb GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RaWt) 195#define GICR_PENDBASER_RaWb GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RaWb)
196#define GICR_PENDBASER_WaWt GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, WaWt) 196#define GICR_PENDBASER_WaWt GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, WaWt)
197#define GICR_PENDBASER_WaWb GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, WaWb) 197#define GICR_PENDBASER_WaWb GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, WaWb)
198#define GICR_PENDBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RaWaWt) 198#define GICR_PENDBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RaWaWt)
@@ -251,7 +251,7 @@
251#define GICR_VPROPBASER_nCnB GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nCnB) 251#define GICR_VPROPBASER_nCnB GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nCnB)
252#define GICR_VPROPBASER_nC GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nC) 252#define GICR_VPROPBASER_nC GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nC)
253#define GICR_VPROPBASER_RaWt GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWt) 253#define GICR_VPROPBASER_RaWt GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWt)
254#define GICR_VPROPBASER_RaWb GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWt) 254#define GICR_VPROPBASER_RaWb GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWb)
255#define GICR_VPROPBASER_WaWt GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWt) 255#define GICR_VPROPBASER_WaWt GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWt)
256#define GICR_VPROPBASER_WaWb GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWb) 256#define GICR_VPROPBASER_WaWb GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWb)
257#define GICR_VPROPBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWaWt) 257#define GICR_VPROPBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWaWt)
@@ -277,7 +277,7 @@
277#define GICR_VPENDBASER_nCnB GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nCnB) 277#define GICR_VPENDBASER_nCnB GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nCnB)
278#define GICR_VPENDBASER_nC GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nC) 278#define GICR_VPENDBASER_nC GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nC)
279#define GICR_VPENDBASER_RaWt GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWt) 279#define GICR_VPENDBASER_RaWt GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWt)
280#define GICR_VPENDBASER_RaWb GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWt) 280#define GICR_VPENDBASER_RaWb GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWb)
281#define GICR_VPENDBASER_WaWt GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWt) 281#define GICR_VPENDBASER_WaWt GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWt)
282#define GICR_VPENDBASER_WaWb GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWb) 282#define GICR_VPENDBASER_WaWb GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWb)
283#define GICR_VPENDBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWaWt) 283#define GICR_VPENDBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWaWt)
@@ -351,7 +351,7 @@
351#define GITS_CBASER_nCnB GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, nCnB) 351#define GITS_CBASER_nCnB GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, nCnB)
352#define GITS_CBASER_nC GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, nC) 352#define GITS_CBASER_nC GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, nC)
353#define GITS_CBASER_RaWt GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, RaWt) 353#define GITS_CBASER_RaWt GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, RaWt)
354#define GITS_CBASER_RaWb GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, RaWt) 354#define GITS_CBASER_RaWb GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, RaWb)
355#define GITS_CBASER_WaWt GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, WaWt) 355#define GITS_CBASER_WaWt GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, WaWt)
356#define GITS_CBASER_WaWb GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, WaWb) 356#define GITS_CBASER_WaWb GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, WaWb)
357#define GITS_CBASER_RaWaWt GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, RaWaWt) 357#define GITS_CBASER_RaWaWt GIC_BASER_CACHEABILITY(GITS_CBASER, INNER, RaWaWt)
@@ -377,7 +377,7 @@
377#define GITS_BASER_nCnB GIC_BASER_CACHEABILITY(GITS_BASER, INNER, nCnB) 377#define GITS_BASER_nCnB GIC_BASER_CACHEABILITY(GITS_BASER, INNER, nCnB)
378#define GITS_BASER_nC GIC_BASER_CACHEABILITY(GITS_BASER, INNER, nC) 378#define GITS_BASER_nC GIC_BASER_CACHEABILITY(GITS_BASER, INNER, nC)
379#define GITS_BASER_RaWt GIC_BASER_CACHEABILITY(GITS_BASER, INNER, RaWt) 379#define GITS_BASER_RaWt GIC_BASER_CACHEABILITY(GITS_BASER, INNER, RaWt)
380#define GITS_BASER_RaWb GIC_BASER_CACHEABILITY(GITS_BASER, INNER, RaWt) 380#define GITS_BASER_RaWb GIC_BASER_CACHEABILITY(GITS_BASER, INNER, RaWb)
381#define GITS_BASER_WaWt GIC_BASER_CACHEABILITY(GITS_BASER, INNER, WaWt) 381#define GITS_BASER_WaWt GIC_BASER_CACHEABILITY(GITS_BASER, INNER, WaWt)
382#define GITS_BASER_WaWb GIC_BASER_CACHEABILITY(GITS_BASER, INNER, WaWb) 382#define GITS_BASER_WaWb GIC_BASER_CACHEABILITY(GITS_BASER, INNER, WaWb)
383#define GITS_BASER_RaWaWt GIC_BASER_CACHEABILITY(GITS_BASER, INNER, RaWaWt) 383#define GITS_BASER_RaWaWt GIC_BASER_CACHEABILITY(GITS_BASER, INNER, RaWaWt)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 61706b430907..07ec8b390161 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -82,6 +82,7 @@ enum irq_domain_bus_token {
82 DOMAIN_BUS_NEXUS, 82 DOMAIN_BUS_NEXUS,
83 DOMAIN_BUS_IPI, 83 DOMAIN_BUS_IPI,
84 DOMAIN_BUS_FSL_MC_MSI, 84 DOMAIN_BUS_FSL_MC_MSI,
85 DOMAIN_BUS_TI_SCI_INTA_MSI,
85}; 86};
86 87
87/** 88/**
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index c2ffff5f9ae2..6c9870e16b19 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1318,7 +1318,7 @@ extern void __wait_on_journal (journal_t *);
1318 1318
1319/* Transaction cache support */ 1319/* Transaction cache support */
1320extern void jbd2_journal_destroy_transaction_cache(void); 1320extern void jbd2_journal_destroy_transaction_cache(void);
1321extern int jbd2_journal_init_transaction_cache(void); 1321extern int __init jbd2_journal_init_transaction_cache(void);
1322extern void jbd2_journal_free_transaction(transaction_t *); 1322extern void jbd2_journal_free_transaction(transaction_t *);
1323 1323
1324/* 1324/*
@@ -1446,8 +1446,10 @@ static inline void jbd2_free_inode(struct jbd2_inode *jinode)
1446/* Primary revoke support */ 1446/* Primary revoke support */
1447#define JOURNAL_REVOKE_DEFAULT_HASH 256 1447#define JOURNAL_REVOKE_DEFAULT_HASH 256
1448extern int jbd2_journal_init_revoke(journal_t *, int); 1448extern int jbd2_journal_init_revoke(journal_t *, int);
1449extern void jbd2_journal_destroy_revoke_caches(void); 1449extern void jbd2_journal_destroy_revoke_record_cache(void);
1450extern int jbd2_journal_init_revoke_caches(void); 1450extern void jbd2_journal_destroy_revoke_table_cache(void);
1451extern int __init jbd2_journal_init_revoke_record_cache(void);
1452extern int __init jbd2_journal_init_revoke_table_cache(void);
1451 1453
1452extern void jbd2_journal_destroy_revoke(journal_t *); 1454extern void jbd2_journal_destroy_revoke(journal_t *);
1453extern int jbd2_journal_revoke (handle_t *, unsigned long long, struct buffer_head *); 1455extern int jbd2_journal_revoke (handle_t *, unsigned long long, struct buffer_head *);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 052f04fcf953..d48e919d55ae 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -48,6 +48,14 @@ struct fsl_mc_msi_desc {
48}; 48};
49 49
50/** 50/**
51 * ti_sci_inta_msi_desc - TISCI based INTA specific msi descriptor data
52 * @dev_index: TISCI device index
53 */
54struct ti_sci_inta_msi_desc {
55 u16 dev_index;
56};
57
58/**
51 * struct msi_desc - Descriptor structure for MSI based interrupts 59 * struct msi_desc - Descriptor structure for MSI based interrupts
52 * @list: List head for management 60 * @list: List head for management
53 * @irq: The base interrupt number 61 * @irq: The base interrupt number
@@ -68,6 +76,7 @@ struct fsl_mc_msi_desc {
68 * @mask_base: [PCI MSI-X] Mask register base address 76 * @mask_base: [PCI MSI-X] Mask register base address
69 * @platform: [platform] Platform device specific msi descriptor data 77 * @platform: [platform] Platform device specific msi descriptor data
70 * @fsl_mc: [fsl-mc] FSL MC device specific msi descriptor data 78 * @fsl_mc: [fsl-mc] FSL MC device specific msi descriptor data
79 * @inta: [INTA] TISCI based INTA specific msi descriptor data
71 */ 80 */
72struct msi_desc { 81struct msi_desc {
73 /* Shared device/bus type independent data */ 82 /* Shared device/bus type independent data */
@@ -77,6 +86,9 @@ struct msi_desc {
77 struct device *dev; 86 struct device *dev;
78 struct msi_msg msg; 87 struct msi_msg msg;
79 struct irq_affinity_desc *affinity; 88 struct irq_affinity_desc *affinity;
89#ifdef CONFIG_IRQ_MSI_IOMMU
90 const void *iommu_cookie;
91#endif
80 92
81 union { 93 union {
82 /* PCI MSI/X specific data */ 94 /* PCI MSI/X specific data */
@@ -106,6 +118,7 @@ struct msi_desc {
106 */ 118 */
107 struct platform_msi_desc platform; 119 struct platform_msi_desc platform;
108 struct fsl_mc_msi_desc fsl_mc; 120 struct fsl_mc_msi_desc fsl_mc;
121 struct ti_sci_inta_msi_desc inta;
109 }; 122 };
110}; 123};
111 124
@@ -119,6 +132,29 @@ struct msi_desc {
119#define for_each_msi_entry_safe(desc, tmp, dev) \ 132#define for_each_msi_entry_safe(desc, tmp, dev) \
120 list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list) 133 list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list)
121 134
135#ifdef CONFIG_IRQ_MSI_IOMMU
136static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)
137{
138 return desc->iommu_cookie;
139}
140
141static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc,
142 const void *iommu_cookie)
143{
144 desc->iommu_cookie = iommu_cookie;
145}
146#else
147static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)
148{
149 return NULL;
150}
151
152static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc,
153 const void *iommu_cookie)
154{
155}
156#endif
157
122#ifdef CONFIG_PCI_MSI 158#ifdef CONFIG_PCI_MSI
123#define first_pci_msi_entry(pdev) first_msi_entry(&(pdev)->dev) 159#define first_pci_msi_entry(pdev) first_msi_entry(&(pdev)->dev)
124#define for_each_pci_msi_entry(desc, pdev) \ 160#define for_each_pci_msi_entry(desc, pdev) \
diff --git a/include/linux/platform_data/xtalk-bridge.h b/include/linux/platform_data/xtalk-bridge.h
new file mode 100644
index 000000000000..51e5001f2c05
--- /dev/null
+++ b/include/linux/platform_data/xtalk-bridge.h
@@ -0,0 +1,22 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * SGI PCI Xtalk Bridge
4 */
5
6#ifndef PLATFORM_DATA_XTALK_BRIDGE_H
7#define PLATFORM_DATA_XTALK_BRIDGE_H
8
9#include <asm/sn/types.h>
10
11struct xtalk_bridge_platform_data {
12 struct resource mem;
13 struct resource io;
14 unsigned long bridge_addr;
15 unsigned long intr_addr;
16 unsigned long mem_offset;
17 unsigned long io_offset;
18 nasid_t nasid;
19 int masterwid;
20};
21
22#endif /* PLATFORM_DATA_XTALK_BRIDGE_H */
diff --git a/include/linux/soc/ti/ti_sci_inta_msi.h b/include/linux/soc/ti/ti_sci_inta_msi.h
new file mode 100644
index 000000000000..11fb5048f5f6
--- /dev/null
+++ b/include/linux/soc/ti/ti_sci_inta_msi.h
@@ -0,0 +1,23 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Texas Instruments' K3 TI SCI INTA MSI helper
4 *
5 * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
6 * Lokesh Vutla <lokeshvutla@ti.com>
7 */
8
9#ifndef __INCLUDE_LINUX_TI_SCI_INTA_MSI_H
10#define __INCLUDE_LINUX_TI_SCI_INTA_MSI_H
11
12#include <linux/msi.h>
13#include <linux/soc/ti/ti_sci_protocol.h>
14
15struct irq_domain
16*ti_sci_inta_msi_create_irq_domain(struct fwnode_handle *fwnode,
17 struct msi_domain_info *info,
18 struct irq_domain *parent);
19int ti_sci_inta_msi_domain_alloc_irqs(struct device *dev,
20 struct ti_sci_resource *res);
21unsigned int ti_sci_inta_msi_get_virq(struct device *dev, u32 index);
22void ti_sci_inta_msi_domain_free_irqs(struct device *dev);
23#endif /* __INCLUDE_LINUX_IRQCHIP_TI_SCI_INTA_H */
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index 18435e5c6364..568722a041bf 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -193,14 +193,67 @@ struct ti_sci_clk_ops {
193}; 193};
194 194
195/** 195/**
196 * struct ti_sci_rm_core_ops - Resource management core operations
197 * @get_range: Get a range of resources belonging to ti sci host.
198 * @get_rage_from_shost: Get a range of resources belonging to
199 * specified host id.
200 * - s_host: Host processing entity to which the
201 * resources are allocated
202 *
203 * NOTE: for these functions, all the parameters are consolidated and defined
204 * as below:
205 * - handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
206 * - dev_id: TISCI device ID.
207 * - subtype: Resource assignment subtype that is being requested
208 * from the given device.
209 * - range_start: Start index of the resource range
210 * - range_end: Number of resources in the range
211 */
212struct ti_sci_rm_core_ops {
213 int (*get_range)(const struct ti_sci_handle *handle, u32 dev_id,
214 u8 subtype, u16 *range_start, u16 *range_num);
215 int (*get_range_from_shost)(const struct ti_sci_handle *handle,
216 u32 dev_id, u8 subtype, u8 s_host,
217 u16 *range_start, u16 *range_num);
218};
219
220/**
221 * struct ti_sci_rm_irq_ops: IRQ management operations
222 * @set_irq: Set an IRQ route between the requested source
223 * and destination
224 * @set_event_map: Set an Event based peripheral irq to Interrupt
225 * Aggregator.
226 * @free_irq: Free an an IRQ route between the requested source
227 * destination.
228 * @free_event_map: Free an event based peripheral irq to Interrupt
229 * Aggregator.
230 */
231struct ti_sci_rm_irq_ops {
232 int (*set_irq)(const struct ti_sci_handle *handle, u16 src_id,
233 u16 src_index, u16 dst_id, u16 dst_host_irq);
234 int (*set_event_map)(const struct ti_sci_handle *handle, u16 src_id,
235 u16 src_index, u16 ia_id, u16 vint,
236 u16 global_event, u8 vint_status_bit);
237 int (*free_irq)(const struct ti_sci_handle *handle, u16 src_id,
238 u16 src_index, u16 dst_id, u16 dst_host_irq);
239 int (*free_event_map)(const struct ti_sci_handle *handle, u16 src_id,
240 u16 src_index, u16 ia_id, u16 vint,
241 u16 global_event, u8 vint_status_bit);
242};
243
244/**
196 * struct ti_sci_ops - Function support for TI SCI 245 * struct ti_sci_ops - Function support for TI SCI
197 * @dev_ops: Device specific operations 246 * @dev_ops: Device specific operations
198 * @clk_ops: Clock specific operations 247 * @clk_ops: Clock specific operations
248 * @rm_core_ops: Resource management core operations.
249 * @rm_irq_ops: IRQ management specific operations
199 */ 250 */
200struct ti_sci_ops { 251struct ti_sci_ops {
201 struct ti_sci_core_ops core_ops; 252 struct ti_sci_core_ops core_ops;
202 struct ti_sci_dev_ops dev_ops; 253 struct ti_sci_dev_ops dev_ops;
203 struct ti_sci_clk_ops clk_ops; 254 struct ti_sci_clk_ops clk_ops;
255 struct ti_sci_rm_core_ops rm_core_ops;
256 struct ti_sci_rm_irq_ops rm_irq_ops;
204}; 257};
205 258
206/** 259/**
@@ -213,10 +266,47 @@ struct ti_sci_handle {
213 struct ti_sci_ops ops; 266 struct ti_sci_ops ops;
214}; 267};
215 268
269#define TI_SCI_RESOURCE_NULL 0xffff
270
271/**
272 * struct ti_sci_resource_desc - Description of TI SCI resource instance range.
273 * @start: Start index of the resource.
274 * @num: Number of resources.
275 * @res_map: Bitmap to manage the allocation of these resources.
276 */
277struct ti_sci_resource_desc {
278 u16 start;
279 u16 num;
280 unsigned long *res_map;
281};
282
283/**
284 * struct ti_sci_resource - Structure representing a resource assigned
285 * to a device.
286 * @sets: Number of sets available from this resource type
287 * @lock: Lock to guard the res map in each set.
288 * @desc: Array of resource descriptors.
289 */
290struct ti_sci_resource {
291 u16 sets;
292 raw_spinlock_t lock;
293 struct ti_sci_resource_desc *desc;
294};
295
216#if IS_ENABLED(CONFIG_TI_SCI_PROTOCOL) 296#if IS_ENABLED(CONFIG_TI_SCI_PROTOCOL)
217const struct ti_sci_handle *ti_sci_get_handle(struct device *dev); 297const struct ti_sci_handle *ti_sci_get_handle(struct device *dev);
218int ti_sci_put_handle(const struct ti_sci_handle *handle); 298int ti_sci_put_handle(const struct ti_sci_handle *handle);
219const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev); 299const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev);
300const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
301 const char *property);
302const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
303 const char *property);
304u16 ti_sci_get_free_resource(struct ti_sci_resource *res);
305void ti_sci_release_resource(struct ti_sci_resource *res, u16 id);
306u32 ti_sci_get_num_resources(struct ti_sci_resource *res);
307struct ti_sci_resource *
308devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
309 struct device *dev, u32 dev_id, char *of_prop);
220 310
221#else /* CONFIG_TI_SCI_PROTOCOL */ 311#else /* CONFIG_TI_SCI_PROTOCOL */
222 312
@@ -236,6 +326,40 @@ const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
236 return ERR_PTR(-EINVAL); 326 return ERR_PTR(-EINVAL);
237} 327}
238 328
329static inline
330const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
331 const char *property)
332{
333 return ERR_PTR(-EINVAL);
334}
335
336static inline
337const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
338 const char *property)
339{
340 return ERR_PTR(-EINVAL);
341}
342
343static inline u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
344{
345 return TI_SCI_RESOURCE_NULL;
346}
347
348static inline void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
349{
350}
351
352static inline u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
353{
354 return 0;
355}
356
357static inline struct ti_sci_resource *
358devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
359 struct device *dev, u32 dev_id, char *of_prop)
360{
361 return ERR_PTR(-EINVAL);
362}
239#endif /* CONFIG_TI_SCI_PROTOCOL */ 363#endif /* CONFIG_TI_SCI_PROTOCOL */
240 364
241#endif /* __TISCI_PROTOCOL_H */ 365#endif /* __TISCI_PROTOCOL_H */
diff --git a/include/linux/atmel_tc.h b/include/soc/at91/atmel_tcb.h
index 468fdfa643f0..c3c7200ce151 100644
--- a/include/linux/atmel_tc.h
+++ b/include/soc/at91/atmel_tcb.h
@@ -7,8 +7,8 @@
7 * (at your option) any later version. 7 * (at your option) any later version.
8 */ 8 */
9 9
10#ifndef ATMEL_TC_H 10#ifndef __SOC_ATMEL_TCB_H
11#define ATMEL_TC_H 11#define __SOC_ATMEL_TCB_H
12 12
13#include <linux/compiler.h> 13#include <linux/compiler.h>
14#include <linux/list.h> 14#include <linux/list.h>
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 896c3f45503b..e8346784cf3f 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -81,6 +81,7 @@ struct hdac_device {
81 atomic_t in_pm; /* suspend/resume being performed */ 81 atomic_t in_pm; /* suspend/resume being performed */
82 82
83 /* sysfs */ 83 /* sysfs */
84 struct mutex widget_lock;
84 struct hdac_widget_tree *widgets; 85 struct hdac_widget_tree *widgets;
85 86
86 /* regmap */ 87 /* regmap */
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 5f3e2baefca9..8fee06625c37 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -91,6 +91,9 @@ config GENERIC_MSI_IRQ_DOMAIN
91 select IRQ_DOMAIN_HIERARCHY 91 select IRQ_DOMAIN_HIERARCHY
92 select GENERIC_MSI_IRQ 92 select GENERIC_MSI_IRQ
93 93
94config IRQ_MSI_IOMMU
95 bool
96
94config HANDLE_DOMAIN_IRQ 97config HANDLE_DOMAIN_IRQ
95 bool 98 bool
96 99
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 51128bea3846..29d6c7d070b4 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1459,6 +1459,33 @@ int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
1459 return -ENOSYS; 1459 return -ENOSYS;
1460} 1460}
1461EXPORT_SYMBOL_GPL(irq_chip_set_wake_parent); 1461EXPORT_SYMBOL_GPL(irq_chip_set_wake_parent);
1462
1463/**
1464 * irq_chip_request_resources_parent - Request resources on the parent interrupt
1465 * @data: Pointer to interrupt specific data
1466 */
1467int irq_chip_request_resources_parent(struct irq_data *data)
1468{
1469 data = data->parent_data;
1470
1471 if (data->chip->irq_request_resources)
1472 return data->chip->irq_request_resources(data);
1473
1474 return -ENOSYS;
1475}
1476EXPORT_SYMBOL_GPL(irq_chip_request_resources_parent);
1477
1478/**
1479 * irq_chip_release_resources_parent - Release resources on the parent interrupt
1480 * @data: Pointer to interrupt specific data
1481 */
1482void irq_chip_release_resources_parent(struct irq_data *data)
1483{
1484 data = data->parent_data;
1485 if (data->chip->irq_release_resources)
1486 data->chip->irq_release_resources(data);
1487}
1488EXPORT_SYMBOL_GPL(irq_chip_release_resources_parent);
1462#endif 1489#endif
1463 1490
1464/** 1491/**
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 9ed29e4a7dbf..a453e229f99c 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1297,7 +1297,7 @@ int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain,
1297/** 1297/**
1298 * __irq_domain_alloc_irqs - Allocate IRQs from domain 1298 * __irq_domain_alloc_irqs - Allocate IRQs from domain
1299 * @domain: domain to allocate from 1299 * @domain: domain to allocate from
1300 * @irq_base: allocate specified IRQ nubmer if irq_base >= 0 1300 * @irq_base: allocate specified IRQ number if irq_base >= 0
1301 * @nr_irqs: number of IRQs to allocate 1301 * @nr_irqs: number of IRQs to allocate
1302 * @node: NUMA node id for memory allocation 1302 * @node: NUMA node id for memory allocation
1303 * @arg: domain specific argument 1303 * @arg: domain specific argument
diff --git a/mm/mmap.c b/mm/mmap.c
index bd7b9f293b39..2d6a6662edb9 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2735,9 +2735,17 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
2735 return -EINVAL; 2735 return -EINVAL;
2736 2736
2737 len = PAGE_ALIGN(len); 2737 len = PAGE_ALIGN(len);
2738 end = start + len;
2738 if (len == 0) 2739 if (len == 0)
2739 return -EINVAL; 2740 return -EINVAL;
2740 2741
2742 /*
2743 * arch_unmap() might do unmaps itself. It must be called
2744 * and finish any rbtree manipulation before this code
2745 * runs and also starts to manipulate the rbtree.
2746 */
2747 arch_unmap(mm, start, end);
2748
2741 /* Find the first overlapping VMA */ 2749 /* Find the first overlapping VMA */
2742 vma = find_vma(mm, start); 2750 vma = find_vma(mm, start);
2743 if (!vma) 2751 if (!vma)
@@ -2746,7 +2754,6 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
2746 /* we have start < vma->vm_end */ 2754 /* we have start < vma->vm_end */
2747 2755
2748 /* if it doesn't overlap, we have nothing.. */ 2756 /* if it doesn't overlap, we have nothing.. */
2749 end = start + len;
2750 if (vma->vm_start >= end) 2757 if (vma->vm_start >= end)
2751 return 0; 2758 return 0;
2752 2759
@@ -2816,12 +2823,6 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
2816 /* Detach vmas from rbtree */ 2823 /* Detach vmas from rbtree */
2817 detach_vmas_to_be_unmapped(mm, vma, prev, end); 2824 detach_vmas_to_be_unmapped(mm, vma, prev, end);
2818 2825
2819 /*
2820 * mpx unmap needs to be called with mmap_sem held for write.
2821 * It is safe to call it before unmap_region().
2822 */
2823 arch_unmap(mm, vma, start, end);
2824
2825 if (downgrade) 2826 if (downgrade)
2826 downgrade_write(&mm->mmap_sem); 2827 downgrade_write(&mm->mmap_sem);
2827 2828
diff --git a/net/bpfilter/Makefile b/net/bpfilter/Makefile
index 854395fb98cd..aa945ab5b655 100644
--- a/net/bpfilter/Makefile
+++ b/net/bpfilter/Makefile
@@ -5,7 +5,7 @@
5 5
6hostprogs-y := bpfilter_umh 6hostprogs-y := bpfilter_umh
7bpfilter_umh-objs := main.o 7bpfilter_umh-objs := main.o
8KBUILD_HOSTCFLAGS += -Itools/include/ -Itools/include/uapi 8KBUILD_HOSTCFLAGS += -I $(srctree)/tools/include/ -I $(srctree)/tools/include/uapi
9HOSTCC := $(CC) 9HOSTCC := $(CC)
10 10
11ifeq ($(CONFIG_BPFILTER_UMH), y) 11ifeq ($(CONFIG_BPFILTER_UMH), y)
diff --git a/samples/Makefile b/samples/Makefile
index 8e096e0d45d1..debf8925f06f 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,6 +1,22 @@
1# SPDX-License-Identifier: GPL-2.0
1# Makefile for Linux samples code 2# Makefile for Linux samples code
2 3
3obj-y += kobject/ kprobes/ trace_events/ livepatch/ \ 4obj-$(CONFIG_SAMPLE_ANDROID_BINDERFS) += binderfs/
4 hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \ 5obj-$(CONFIG_SAMPLE_CONFIGFS) += configfs/
5 configfs/ connector/ v4l/ trace_printk/ \ 6obj-$(CONFIG_SAMPLE_CONNECTOR) += connector/
6 vfio-mdev/ vfs/ qmi/ binderfs/ pidfd/ 7subdir-y += hidraw
8obj-$(CONFIG_SAMPLE_HW_BREAKPOINT) += hw_breakpoint/
9obj-$(CONFIG_SAMPLE_KDB) += kdb/
10obj-$(CONFIG_SAMPLE_KFIFO) += kfifo/
11obj-$(CONFIG_SAMPLE_KOBJECT) += kobject/
12obj-$(CONFIG_SAMPLE_KPROBES) += kprobes/
13obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch/
14subdir-y += pidfd
15obj-$(CONFIG_SAMPLE_QMI_CLIENT) += qmi/
16obj-$(CONFIG_SAMPLE_RPMSG_CLIENT) += rpmsg/
17subdir-$(CONFIG_SAMPLE_SECCOMP) += seccomp
18obj-$(CONFIG_SAMPLE_TRACE_EVENTS) += trace_events/
19obj-$(CONFIG_SAMPLE_TRACE_PRINTK) += trace_printk/
20obj-$(CONFIG_VIDEO_PCI_SKELETON) += v4l/
21obj-y += vfio-mdev/
22subdir-$(CONFIG_SAMPLE_VFS) += vfs
diff --git a/samples/seccomp/Makefile b/samples/seccomp/Makefile
index 00e0b5e90bd0..009775b52538 100644
--- a/samples/seccomp/Makefile
+++ b/samples/seccomp/Makefile
@@ -1,6 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2ifndef CROSS_COMPILE 2ifndef CROSS_COMPILE
3hostprogs-$(CONFIG_SAMPLE_SECCOMP) := bpf-fancy dropper bpf-direct user-trap 3hostprogs-y := bpf-fancy dropper bpf-direct user-trap
4 4
5HOSTCFLAGS_bpf-fancy.o += -I$(objtree)/usr/include 5HOSTCFLAGS_bpf-fancy.o += -I$(objtree)/usr/include
6HOSTCFLAGS_bpf-fancy.o += -idirafter $(objtree)/include 6HOSTCFLAGS_bpf-fancy.o += -idirafter $(objtree)/include
diff --git a/samples/vfs/Makefile b/samples/vfs/Makefile
index 4ac9690fb3c4..a3e4ffd4c773 100644
--- a/samples/vfs/Makefile
+++ b/samples/vfs/Makefile
@@ -1,5 +1,5 @@
1# List of programs to build 1# List of programs to build
2hostprogs-$(CONFIG_SAMPLE_VFS) := \ 2hostprogs-y := \
3 test-fsmount \ 3 test-fsmount \
4 test-statx 4 test-statx
5 5
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 7484b9d8272f..a675ce11a573 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -192,14 +192,6 @@ clean := -f $(srctree)/scripts/Makefile.clean obj
192# $(Q)$(MAKE) $(hdr-inst)=dir 192# $(Q)$(MAKE) $(hdr-inst)=dir
193hdr-inst := -f $(srctree)/scripts/Makefile.headersinst obj 193hdr-inst := -f $(srctree)/scripts/Makefile.headersinst obj
194 194
195# Prefix -I with $(srctree) if it is not an absolute path.
196# skip if -I has no parameter
197addtree = $(if $(patsubst -I%,%,$(1)), \
198$(if $(filter-out -I/% -I./% -I../%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1)),$(1))
199
200# Find all -I options and call addtree
201flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
202
203# echo command. 195# echo command.
204# Short version is used, if $(quiet) equals `quiet_', otherwise full one. 196# Short version is used, if $(quiet) equals `quiet_', otherwise full one.
205echo-cmd = $(if $($(quiet)cmd_$(1)),\ 197echo-cmd = $(if $($(quiet)cmd_$(1)),\
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include
index 87ff1dcc6bd5..0b267fb27f07 100644
--- a/scripts/Kconfig.include
+++ b/scripts/Kconfig.include
@@ -18,6 +18,10 @@ if-success = $(shell,{ $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)")
18# Return y if <command> exits with 0, n otherwise 18# Return y if <command> exits with 0, n otherwise
19success = $(if-success,$(1),y,n) 19success = $(if-success,$(1),y,n)
20 20
21# $(failure,<command>)
22# Return n if <command> exits with 0, y otherwise
23failure = $(if-success,$(1),n,y)
24
21# $(cc-option,<flag>) 25# $(cc-option,<flag>)
22# Return y if the compiler supports <flag>, n otherwise 26# Return y if the compiler supports <flag>, n otherwise
23cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null) 27cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null)
@@ -26,5 +30,9 @@ cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null)
26# Return y if the linker supports <flag>, n otherwise 30# Return y if the linker supports <flag>, n otherwise
27ld-option = $(success,$(LD) -v $(1)) 31ld-option = $(success,$(LD) -v $(1))
28 32
33# check if $(CC) and $(LD) exist
34$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found)
35$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)
36
29# gcc version including patch level 37# gcc version including patch level
30gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh $(CC)) 38gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh $(CC))
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index 768306add591..3ab8d1a303cd 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -23,15 +23,16 @@ warning- := $(empty)
23warning-1 := -Wextra -Wunused -Wno-unused-parameter 23warning-1 := -Wextra -Wunused -Wno-unused-parameter
24warning-1 += -Wmissing-declarations 24warning-1 += -Wmissing-declarations
25warning-1 += -Wmissing-format-attribute 25warning-1 += -Wmissing-format-attribute
26warning-1 += $(call cc-option, -Wmissing-prototypes) 26warning-1 += -Wmissing-prototypes
27warning-1 += -Wold-style-definition 27warning-1 += -Wold-style-definition
28warning-1 += $(call cc-option, -Wmissing-include-dirs) 28warning-1 += -Wmissing-include-dirs
29warning-1 += $(call cc-option, -Wunused-but-set-variable) 29warning-1 += $(call cc-option, -Wunused-but-set-variable)
30warning-1 += $(call cc-option, -Wunused-const-variable) 30warning-1 += $(call cc-option, -Wunused-const-variable)
31warning-1 += $(call cc-option, -Wpacked-not-aligned) 31warning-1 += $(call cc-option, -Wpacked-not-aligned)
32warning-1 += $(call cc-option, -Wstringop-truncation) 32warning-1 += $(call cc-option, -Wstringop-truncation)
33warning-1 += $(call cc-disable-warning, missing-field-initializers) 33# The following turn off the warnings enabled by -Wextra
34warning-1 += $(call cc-disable-warning, sign-compare) 34warning-1 += -Wno-missing-field-initializers
35warning-1 += -Wno-sign-compare
35 36
36warning-2 := -Waggregate-return 37warning-2 := -Waggregate-return
37warning-2 += -Wcast-align 38warning-2 += -Wcast-align
@@ -39,8 +40,8 @@ warning-2 += -Wdisabled-optimization
39warning-2 += -Wnested-externs 40warning-2 += -Wnested-externs
40warning-2 += -Wshadow 41warning-2 += -Wshadow
41warning-2 += $(call cc-option, -Wlogical-op) 42warning-2 += $(call cc-option, -Wlogical-op)
42warning-2 += $(call cc-option, -Wmissing-field-initializers) 43warning-2 += -Wmissing-field-initializers
43warning-2 += $(call cc-option, -Wsign-compare) 44warning-2 += -Wsign-compare
44warning-2 += $(call cc-option, -Wmaybe-uninitialized) 45warning-2 += $(call cc-option, -Wmaybe-uninitialized)
45warning-2 += $(call cc-option, -Wunused-macros) 46warning-2 += $(call cc-option, -Wunused-macros)
46 47
@@ -66,11 +67,11 @@ KBUILD_CFLAGS += $(warning)
66else 67else
67 68
68ifdef CONFIG_CC_IS_CLANG 69ifdef CONFIG_CC_IS_CLANG
69KBUILD_CFLAGS += $(call cc-disable-warning, initializer-overrides) 70KBUILD_CFLAGS += -Wno-initializer-overrides
70KBUILD_CFLAGS += $(call cc-disable-warning, unused-value) 71KBUILD_CFLAGS += -Wno-unused-value
71KBUILD_CFLAGS += $(call cc-disable-warning, format) 72KBUILD_CFLAGS += -Wno-format
72KBUILD_CFLAGS += $(call cc-disable-warning, sign-compare) 73KBUILD_CFLAGS += -Wno-sign-compare
73KBUILD_CFLAGS += $(call cc-disable-warning, format-zero-length) 74KBUILD_CFLAGS += -Wno-format-zero-length
74KBUILD_CFLAGS += $(call cc-disable-warning, uninitialized) 75KBUILD_CFLAGS += -Wno-uninitialized
75endif 76endif
76endif 77endif
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 73b804197fca..b6a54bdf0965 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -67,18 +67,16 @@ _hostc_flags = $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
67_hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ 67_hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
68 $(HOSTCXXFLAGS_$(basetarget).o) 68 $(HOSTCXXFLAGS_$(basetarget).o)
69 69
70__hostc_flags = $(_hostc_flags) 70# $(objtree)/$(obj) for including generated headers from checkin source files
71__hostcxx_flags = $(_hostcxx_flags)
72
73ifeq ($(KBUILD_EXTMOD),) 71ifeq ($(KBUILD_EXTMOD),)
74ifneq ($(srctree),.) 72ifneq ($(srctree),.)
75__hostc_flags = -I$(obj) $(call flags,_hostc_flags) 73_hostc_flags += -I $(objtree)/$(obj)
76__hostcxx_flags = -I$(obj) $(call flags,_hostcxx_flags) 74_hostcxx_flags += -I $(objtree)/$(obj)
77endif 75endif
78endif 76endif
79 77
80hostc_flags = -Wp,-MD,$(depfile) $(__hostc_flags) 78hostc_flags = -Wp,-MD,$(depfile) $(_hostc_flags)
81hostcxx_flags = -Wp,-MD,$(depfile) $(__hostcxx_flags) 79hostcxx_flags = -Wp,-MD,$(depfile) $(_hostcxx_flags)
82 80
83##### 81#####
84# Compile programs on the host 82# Compile programs on the host
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 41e98fa66b91..1b412d4394ae 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -137,36 +137,26 @@ _c_flags += $(if $(patsubst n%,, \
137 $(CFLAGS_KCOV)) 137 $(CFLAGS_KCOV))
138endif 138endif
139 139
140__c_flags = $(_c_flags) 140# $(srctree)/$(src) for including checkin headers from generated source files
141__a_flags = $(_a_flags) 141# $(objtree)/$(obj) for including generated headers from checkin source files
142__cpp_flags = $(_cpp_flags)
143
144# If building the kernel in a separate objtree expand all occurrences
145# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
146ifeq ($(KBUILD_EXTMOD),) 142ifeq ($(KBUILD_EXTMOD),)
147ifneq ($(srctree),.) 143ifneq ($(srctree),.)
148 144_c_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj)
149# -I$(obj) locates generated .h files 145_a_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj)
150# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files 146_cpp_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj)
151# and locates generated .h files
152# FIXME: Replace both with specific CFLAGS* statements in the makefiles
153__c_flags = $(if $(obj),$(call addtree,-I$(src)) -I$(obj)) \
154 $(call flags,_c_flags)
155__a_flags = $(call flags,_a_flags)
156__cpp_flags = $(call flags,_cpp_flags)
157endif 147endif
158endif 148endif
159 149
160c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 150c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
161 -include $(srctree)/include/linux/compiler_types.h \ 151 -include $(srctree)/include/linux/compiler_types.h \
162 $(__c_flags) $(modkern_cflags) \ 152 $(_c_flags) $(modkern_cflags) \
163 $(basename_flags) $(modname_flags) 153 $(basename_flags) $(modname_flags)
164 154
165a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 155a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
166 $(__a_flags) $(modkern_aflags) 156 $(_a_flags) $(modkern_aflags)
167 157
168cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 158cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
169 $(__cpp_flags) 159 $(_cpp_flags)
170 160
171ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) 161ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
172 162
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 5f227d8d39d8..82160808765c 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -9,7 +9,7 @@ dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
9dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o 9dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
10 10
11# Source files need to get at the userspace version of libfdt_env.h to compile 11# Source files need to get at the userspace version of libfdt_env.h to compile
12HOST_EXTRACFLAGS := -I$(src)/libfdt 12HOST_EXTRACFLAGS := -I $(srctree)/$(src)/libfdt
13 13
14ifeq ($(wildcard /usr/include/yaml.h),) 14ifeq ($(wildcard /usr/include/yaml.h),)
15ifneq ($(CHECK_DTBS),) 15ifneq ($(CHECK_DTBS),)
@@ -23,8 +23,8 @@ HOSTLDLIBS_dtc := -lyaml
23endif 23endif
24 24
25# Generated files need one more search path to include headers in source tree 25# Generated files need one more search path to include headers in source tree
26HOSTCFLAGS_dtc-lexer.lex.o := -I$(src) 26HOSTCFLAGS_dtc-lexer.lex.o := -I $(srctree)/$(src)
27HOSTCFLAGS_dtc-parser.tab.o := -I$(src) 27HOSTCFLAGS_dtc-parser.tab.o := -I $(srctree)/$(src)
28 28
29# dependencies on generated files need to be listed explicitly 29# dependencies on generated files need to be listed explicitly
30$(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h 30$(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h
diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile
index 03b7ce97de14..66c314bc5933 100644
--- a/scripts/genksyms/Makefile
+++ b/scripts/genksyms/Makefile
@@ -31,8 +31,8 @@ $(obj)/parse.tab.h: $(src)/parse.y FORCE
31endif 31endif
32 32
33# -I needed for generated C source (shipped source) 33# -I needed for generated C source (shipped source)
34HOSTCFLAGS_parse.tab.o := -I$(src) 34HOSTCFLAGS_parse.tab.o := -I $(srctree)/$(src)
35HOSTCFLAGS_lex.lex.o := -I$(src) 35HOSTCFLAGS_lex.lex.o := -I $(srctree)/$(src)
36 36
37# dependencies on generated files need to be listed explicitly 37# dependencies on generated files need to be listed explicitly
38$(obj)/lex.lex.o: $(obj)/parse.tab.h 38$(obj)/lex.lex.o: $(obj)/parse.tab.h
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 7c5dc31c1d95..3f327e21f60e 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -76,15 +76,13 @@ savedefconfig: $(obj)/conf
76defconfig: $(obj)/conf 76defconfig: $(obj)/conf
77ifeq ($(KBUILD_DEFCONFIG),) 77ifeq ($(KBUILD_DEFCONFIG),)
78 $< $(silent) --defconfig $(Kconfig) 78 $< $(silent) --defconfig $(Kconfig)
79else 79else ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),)
80ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),)
81 @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" 80 @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
82 $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) 81 $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
83else 82else
84 @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'" 83 @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'"
85 $(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) 84 $(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG)
86endif 85endif
87endif
88 86
89%_defconfig: $(obj)/conf 87%_defconfig: $(obj)/conf
90 $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) 88 $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
@@ -147,8 +145,8 @@ common-objs := confdata.o expr.o lexer.lex.o parser.tab.o preprocess.o \
147 symbol.o 145 symbol.o
148 146
149$(obj)/lexer.lex.o: $(obj)/parser.tab.h 147$(obj)/lexer.lex.o: $(obj)/parser.tab.h
150HOSTCFLAGS_lexer.lex.o := -I$(src) 148HOSTCFLAGS_lexer.lex.o := -I $(srctree)/$(src)
151HOSTCFLAGS_parser.tab.o := -I$(src) 149HOSTCFLAGS_parser.tab.o := -I $(srctree)/$(src)
152 150
153# conf: Used for defconfig, oldconfig and related targets 151# conf: Used for defconfig, oldconfig and related targets
154hostprogs-y += conf 152hostprogs-y += conf
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 492ac3410147..6006154d36bd 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -867,6 +867,7 @@ int conf_write(const char *name)
867 const char *str; 867 const char *str;
868 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; 868 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
869 char *env; 869 char *env;
870 bool need_newline = false;
870 871
871 if (!name) 872 if (!name)
872 name = conf_get_configname(); 873 name = conf_get_configname();
@@ -912,12 +913,16 @@ int conf_write(const char *name)
912 "#\n" 913 "#\n"
913 "# %s\n" 914 "# %s\n"
914 "#\n", str); 915 "#\n", str);
916 need_newline = false;
915 } else if (!(sym->flags & SYMBOL_CHOICE)) { 917 } else if (!(sym->flags & SYMBOL_CHOICE)) {
916 sym_calc_value(sym); 918 sym_calc_value(sym);
917 if (!(sym->flags & SYMBOL_WRITE)) 919 if (!(sym->flags & SYMBOL_WRITE))
918 goto next; 920 goto next;
921 if (need_newline) {
922 fprintf(out, "\n");
923 need_newline = false;
924 }
919 sym->flags &= ~SYMBOL_WRITE; 925 sym->flags &= ~SYMBOL_WRITE;
920
921 conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); 926 conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
922 } 927 }
923 928
@@ -929,6 +934,12 @@ next:
929 if (menu->next) 934 if (menu->next)
930 menu = menu->next; 935 menu = menu->next;
931 else while ((menu = menu->parent)) { 936 else while ((menu = menu->parent)) {
937 if (!menu->sym && menu_is_visible(menu) &&
938 menu != &rootmenu) {
939 str = menu_get_prompt(menu);
940 fprintf(out, "# end of %s\n", str);
941 need_newline = true;
942 }
932 if (menu->next) { 943 if (menu->next) {
933 menu = menu->next; 944 menu = menu->next;
934 break; 945 break;
diff --git a/scripts/modules-check.sh b/scripts/modules-check.sh
new file mode 100755
index 000000000000..2f659530e1ec
--- /dev/null
+++ b/scripts/modules-check.sh
@@ -0,0 +1,16 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3
4set -e
5
6# Check uniqueness of module names
7check_same_name_modules()
8{
9 for m in $(sed 's:.*/::' modules.order modules.builtin | sort | uniq -d)
10 do
11 echo "warning: same basename if the following are built as modules:" >&2
12 sed "/\/$m/!d;s:^kernel/: :" modules.order modules.builtin >&2
13 done
14}
15
16check_same_name_modules
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index 95b073ee4b32..4769f4c03e14 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -55,6 +55,7 @@ int snd_hdac_device_init(struct hdac_device *codec, struct hdac_bus *bus,
55 codec->bus = bus; 55 codec->bus = bus;
56 codec->addr = addr; 56 codec->addr = addr;
57 codec->type = HDA_DEV_CORE; 57 codec->type = HDA_DEV_CORE;
58 mutex_init(&codec->widget_lock);
58 pm_runtime_set_active(&codec->dev); 59 pm_runtime_set_active(&codec->dev);
59 pm_runtime_get_noresume(&codec->dev); 60 pm_runtime_get_noresume(&codec->dev);
60 atomic_set(&codec->in_pm, 0); 61 atomic_set(&codec->in_pm, 0);
@@ -141,7 +142,9 @@ int snd_hdac_device_register(struct hdac_device *codec)
141 err = device_add(&codec->dev); 142 err = device_add(&codec->dev);
142 if (err < 0) 143 if (err < 0)
143 return err; 144 return err;
145 mutex_lock(&codec->widget_lock);
144 err = hda_widget_sysfs_init(codec); 146 err = hda_widget_sysfs_init(codec);
147 mutex_unlock(&codec->widget_lock);
145 if (err < 0) { 148 if (err < 0) {
146 device_del(&codec->dev); 149 device_del(&codec->dev);
147 return err; 150 return err;
@@ -158,7 +161,9 @@ EXPORT_SYMBOL_GPL(snd_hdac_device_register);
158void snd_hdac_device_unregister(struct hdac_device *codec) 161void snd_hdac_device_unregister(struct hdac_device *codec)
159{ 162{
160 if (device_is_registered(&codec->dev)) { 163 if (device_is_registered(&codec->dev)) {
164 mutex_lock(&codec->widget_lock);
161 hda_widget_sysfs_exit(codec); 165 hda_widget_sysfs_exit(codec);
166 mutex_unlock(&codec->widget_lock);
162 device_del(&codec->dev); 167 device_del(&codec->dev);
163 snd_hdac_bus_remove_device(codec->bus, codec); 168 snd_hdac_bus_remove_device(codec->bus, codec);
164 } 169 }
@@ -404,7 +409,9 @@ int snd_hdac_refresh_widgets(struct hdac_device *codec, bool sysfs)
404 } 409 }
405 410
406 if (sysfs) { 411 if (sysfs) {
412 mutex_lock(&codec->widget_lock);
407 err = hda_widget_sysfs_reinit(codec, start_nid, nums); 413 err = hda_widget_sysfs_reinit(codec, start_nid, nums);
414 mutex_unlock(&codec->widget_lock);
408 if (err < 0) 415 if (err < 0)
409 return err; 416 return err;
410 } 417 }
diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c
index fb2aa344981e..909d5ef1179c 100644
--- a/sound/hda/hdac_sysfs.c
+++ b/sound/hda/hdac_sysfs.c
@@ -395,6 +395,7 @@ static int widget_tree_create(struct hdac_device *codec)
395 return 0; 395 return 0;
396} 396}
397 397
398/* call with codec->widget_lock held */
398int hda_widget_sysfs_init(struct hdac_device *codec) 399int hda_widget_sysfs_init(struct hdac_device *codec)
399{ 400{
400 int err; 401 int err;
@@ -411,11 +412,13 @@ int hda_widget_sysfs_init(struct hdac_device *codec)
411 return 0; 412 return 0;
412} 413}
413 414
415/* call with codec->widget_lock held */
414void hda_widget_sysfs_exit(struct hdac_device *codec) 416void hda_widget_sysfs_exit(struct hdac_device *codec)
415{ 417{
416 widget_tree_free(codec); 418 widget_tree_free(codec);
417} 419}
418 420
421/* call with codec->widget_lock held */
419int hda_widget_sysfs_reinit(struct hdac_device *codec, 422int hda_widget_sysfs_reinit(struct hdac_device *codec,
420 hda_nid_t start_nid, int num_nodes) 423 hda_nid_t start_nid, int num_nodes)
421{ 424{
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c53ca589c930..f83f21d64dd4 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -478,12 +478,45 @@ static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
478 set_eapd(codec, *p, on); 478 set_eapd(codec, *p, on);
479} 479}
480 480
481static int find_ext_mic_pin(struct hda_codec *codec);
482
483static void alc_headset_mic_no_shutup(struct hda_codec *codec)
484{
485 const struct hda_pincfg *pin;
486 int mic_pin = find_ext_mic_pin(codec);
487 int i;
488
489 /* don't shut up pins when unloading the driver; otherwise it breaks
490 * the default pin setup at the next load of the driver
491 */
492 if (codec->bus->shutdown)
493 return;
494
495 snd_array_for_each(&codec->init_pins, i, pin) {
496 /* use read here for syncing after issuing each verb */
497 if (pin->nid != mic_pin)
498 snd_hda_codec_read(codec, pin->nid, 0,
499 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
500 }
501
502 codec->pins_shutup = 1;
503}
504
481static void alc_shutup_pins(struct hda_codec *codec) 505static void alc_shutup_pins(struct hda_codec *codec)
482{ 506{
483 struct alc_spec *spec = codec->spec; 507 struct alc_spec *spec = codec->spec;
484 508
485 if (!spec->no_shutup_pins) 509 switch (codec->core.vendor_id) {
486 snd_hda_shutup_pins(codec); 510 case 0x10ec0286:
511 case 0x10ec0288:
512 case 0x10ec0298:
513 alc_headset_mic_no_shutup(codec);
514 break;
515 default:
516 if (!spec->no_shutup_pins)
517 snd_hda_shutup_pins(codec);
518 break;
519 }
487} 520}
488 521
489/* generic shutup callback; 522/* generic shutup callback;
@@ -502,7 +535,6 @@ static void alc_eapd_shutup(struct hda_codec *codec)
502/* generic EAPD initialization */ 535/* generic EAPD initialization */
503static void alc_auto_init_amp(struct hda_codec *codec, int type) 536static void alc_auto_init_amp(struct hda_codec *codec, int type)
504{ 537{
505 alc_fill_eapd_coef(codec);
506 alc_auto_setup_eapd(codec, true); 538 alc_auto_setup_eapd(codec, true);
507 alc_write_gpio(codec); 539 alc_write_gpio(codec);
508 switch (type) { 540 switch (type) {
@@ -797,10 +829,22 @@ static int alc_build_controls(struct hda_codec *codec)
797 * Common callbacks 829 * Common callbacks
798 */ 830 */
799 831
832static void alc_pre_init(struct hda_codec *codec)
833{
834 alc_fill_eapd_coef(codec);
835}
836
837#define is_s4_resume(codec) \
838 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
839
800static int alc_init(struct hda_codec *codec) 840static int alc_init(struct hda_codec *codec)
801{ 841{
802 struct alc_spec *spec = codec->spec; 842 struct alc_spec *spec = codec->spec;
803 843
844 /* hibernation resume needs the full chip initialization */
845 if (is_s4_resume(codec))
846 alc_pre_init(codec);
847
804 if (spec->init_hook) 848 if (spec->init_hook)
805 spec->init_hook(codec); 849 spec->init_hook(codec);
806 850
@@ -1538,6 +1582,8 @@ static int patch_alc880(struct hda_codec *codec)
1538 1582
1539 codec->patch_ops.unsol_event = alc880_unsol_event; 1583 codec->patch_ops.unsol_event = alc880_unsol_event;
1540 1584
1585 alc_pre_init(codec);
1586
1541 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, 1587 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
1542 alc880_fixups); 1588 alc880_fixups);
1543 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1589 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -1789,6 +1835,8 @@ static int patch_alc260(struct hda_codec *codec)
1789 1835
1790 spec->shutup = alc_eapd_shutup; 1836 spec->shutup = alc_eapd_shutup;
1791 1837
1838 alc_pre_init(codec);
1839
1792 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, 1840 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1793 alc260_fixups); 1841 alc260_fixups);
1794 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1842 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -2492,6 +2540,8 @@ static int patch_alc882(struct hda_codec *codec)
2492 break; 2540 break;
2493 } 2541 }
2494 2542
2543 alc_pre_init(codec);
2544
2495 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, 2545 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
2496 alc882_fixups); 2546 alc882_fixups);
2497 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 2547 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -2666,6 +2716,8 @@ static int patch_alc262(struct hda_codec *codec)
2666#endif 2716#endif
2667 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 2717 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2668 2718
2719 alc_pre_init(codec);
2720
2669 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, 2721 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
2670 alc262_fixups); 2722 alc262_fixups);
2671 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 2723 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -2810,6 +2862,8 @@ static int patch_alc268(struct hda_codec *codec)
2810 2862
2811 spec->shutup = alc_eapd_shutup; 2863 spec->shutup = alc_eapd_shutup;
2812 2864
2865 alc_pre_init(codec);
2866
2813 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); 2867 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2814 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 2868 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2815 2869
@@ -2924,27 +2978,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
2924 return alc_parse_auto_config(codec, alc269_ignore, ssids); 2978 return alc_parse_auto_config(codec, alc269_ignore, ssids);
2925} 2979}
2926 2980
2927static int find_ext_mic_pin(struct hda_codec *codec);
2928
2929static void alc286_shutup(struct hda_codec *codec)
2930{
2931 const struct hda_pincfg *pin;
2932 int i;
2933 int mic_pin = find_ext_mic_pin(codec);
2934 /* don't shut up pins when unloading the driver; otherwise it breaks
2935 * the default pin setup at the next load of the driver
2936 */
2937 if (codec->bus->shutdown)
2938 return;
2939 snd_array_for_each(&codec->init_pins, i, pin) {
2940 /* use read here for syncing after issuing each verb */
2941 if (pin->nid != mic_pin)
2942 snd_hda_codec_read(codec, pin->nid, 0,
2943 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2944 }
2945 codec->pins_shutup = 1;
2946}
2947
2948static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) 2981static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
2949{ 2982{
2950 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0); 2983 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
@@ -6964,7 +6997,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6964 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), 6997 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
6965 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 6998 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
6966 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 6999 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
6967 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 7000 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7001 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7002 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
6968 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), 7003 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
6969 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 7004 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
6970 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 7005 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
@@ -7007,7 +7042,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
7007 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), 7042 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
7008 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), 7043 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
7009 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), 7044 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
7010 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), 7045 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
7011 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 7046 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
7012 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), 7047 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
7013 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK), 7048 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
@@ -7736,7 +7771,6 @@ static int patch_alc269(struct hda_codec *codec)
7736 case 0x10ec0286: 7771 case 0x10ec0286:
7737 case 0x10ec0288: 7772 case 0x10ec0288:
7738 spec->codec_variant = ALC269_TYPE_ALC286; 7773 spec->codec_variant = ALC269_TYPE_ALC286;
7739 spec->shutup = alc286_shutup;
7740 break; 7774 break;
7741 case 0x10ec0298: 7775 case 0x10ec0298:
7742 spec->codec_variant = ALC269_TYPE_ALC298; 7776 spec->codec_variant = ALC269_TYPE_ALC298;
@@ -7805,6 +7839,8 @@ static int patch_alc269(struct hda_codec *codec)
7805 spec->init_hook = alc5505_dsp_init; 7839 spec->init_hook = alc5505_dsp_init;
7806 } 7840 }
7807 7841
7842 alc_pre_init(codec);
7843
7808 snd_hda_pick_fixup(codec, alc269_fixup_models, 7844 snd_hda_pick_fixup(codec, alc269_fixup_models,
7809 alc269_fixup_tbl, alc269_fixups); 7845 alc269_fixup_tbl, alc269_fixups);
7810 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups); 7846 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
@@ -7947,6 +7983,8 @@ static int patch_alc861(struct hda_codec *codec)
7947 spec->power_hook = alc_power_eapd; 7983 spec->power_hook = alc_power_eapd;
7948#endif 7984#endif
7949 7985
7986 alc_pre_init(codec);
7987
7950 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 7988 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
7951 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 7989 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7952 7990
@@ -8044,6 +8082,8 @@ static int patch_alc861vd(struct hda_codec *codec)
8044 8082
8045 spec->shutup = alc_eapd_shutup; 8083 spec->shutup = alc_eapd_shutup;
8046 8084
8085 alc_pre_init(codec);
8086
8047 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 8087 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8048 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 8088 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8049 8089
@@ -8779,6 +8819,8 @@ static int patch_alc662(struct hda_codec *codec)
8779 break; 8819 break;
8780 } 8820 }
8781 8821
8822 alc_pre_init(codec);
8823
8782 snd_hda_pick_fixup(codec, alc662_fixup_models, 8824 snd_hda_pick_fixup(codec, alc662_fixup_models,
8783 alc662_fixup_tbl, alc662_fixups); 8825 alc662_fixup_tbl, alc662_fixups);
8784 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups); 8826 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include/uapi/asm/kvm.h
index dabfcf7c3941..7a0e64ccd6ff 100644
--- a/tools/arch/x86/include/uapi/asm/kvm.h
+++ b/tools/arch/x86/include/uapi/asm/kvm.h
@@ -381,6 +381,7 @@ struct kvm_sync_regs {
381#define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0) 381#define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0)
382#define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1) 382#define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1)
383#define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) 383#define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2)
384#define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3)
384 385
385#define KVM_STATE_NESTED_GUEST_MODE 0x00000001 386#define KVM_STATE_NESTED_GUEST_MODE 0x00000001
386#define KVM_STATE_NESTED_RUN_PENDING 0x00000002 387#define KVM_STATE_NESTED_RUN_PENDING 0x00000002
diff --git a/tools/arch/x86/include/uapi/asm/perf_regs.h b/tools/arch/x86/include/uapi/asm/perf_regs.h
index f3329cabce5c..ac67bbea10ca 100644
--- a/tools/arch/x86/include/uapi/asm/perf_regs.h
+++ b/tools/arch/x86/include/uapi/asm/perf_regs.h
@@ -27,8 +27,29 @@ enum perf_event_x86_regs {
27 PERF_REG_X86_R13, 27 PERF_REG_X86_R13,
28 PERF_REG_X86_R14, 28 PERF_REG_X86_R14,
29 PERF_REG_X86_R15, 29 PERF_REG_X86_R15,
30 30 /* These are the limits for the GPRs. */
31 PERF_REG_X86_32_MAX = PERF_REG_X86_GS + 1, 31 PERF_REG_X86_32_MAX = PERF_REG_X86_GS + 1,
32 PERF_REG_X86_64_MAX = PERF_REG_X86_R15 + 1, 32 PERF_REG_X86_64_MAX = PERF_REG_X86_R15 + 1,
33
34 /* These all need two bits set because they are 128bit */
35 PERF_REG_X86_XMM0 = 32,
36 PERF_REG_X86_XMM1 = 34,
37 PERF_REG_X86_XMM2 = 36,
38 PERF_REG_X86_XMM3 = 38,
39 PERF_REG_X86_XMM4 = 40,
40 PERF_REG_X86_XMM5 = 42,
41 PERF_REG_X86_XMM6 = 44,
42 PERF_REG_X86_XMM7 = 46,
43 PERF_REG_X86_XMM8 = 48,
44 PERF_REG_X86_XMM9 = 50,
45 PERF_REG_X86_XMM10 = 52,
46 PERF_REG_X86_XMM11 = 54,
47 PERF_REG_X86_XMM12 = 56,
48 PERF_REG_X86_XMM13 = 58,
49 PERF_REG_X86_XMM14 = 60,
50 PERF_REG_X86_XMM15 = 62,
51
52 /* These include both GPRs and XMMX registers */
53 PERF_REG_X86_XMM_MAX = PERF_REG_X86_XMM15 + 2,
33}; 54};
34#endif /* _ASM_X86_PERF_REGS_H */ 55#endif /* _ASM_X86_PERF_REGS_H */
diff --git a/tools/arch/x86/lib/memcpy_64.S b/tools/arch/x86/lib/memcpy_64.S
index 3b24dc05251c..9d05572370ed 100644
--- a/tools/arch/x86/lib/memcpy_64.S
+++ b/tools/arch/x86/lib/memcpy_64.S
@@ -257,6 +257,7 @@ ENTRY(__memcpy_mcsafe)
257 /* Copy successful. Return zero */ 257 /* Copy successful. Return zero */
258.L_done_memcpy_trap: 258.L_done_memcpy_trap:
259 xorl %eax, %eax 259 xorl %eax, %eax
260.L_done:
260 ret 261 ret
261ENDPROC(__memcpy_mcsafe) 262ENDPROC(__memcpy_mcsafe)
262EXPORT_SYMBOL_GPL(__memcpy_mcsafe) 263EXPORT_SYMBOL_GPL(__memcpy_mcsafe)
@@ -273,7 +274,7 @@ EXPORT_SYMBOL_GPL(__memcpy_mcsafe)
273 addl %edx, %ecx 274 addl %edx, %ecx
274.E_trailing_bytes: 275.E_trailing_bytes:
275 mov %ecx, %eax 276 mov %ecx, %eax
276 ret 277 jmp .L_done
277 278
278 /* 279 /*
279 * For write fault handling, given the destination is unaligned, 280 * For write fault handling, given the destination is unaligned,
diff --git a/tools/lib/traceevent/Documentation/Makefile b/tools/lib/traceevent/Documentation/Makefile
new file mode 100644
index 000000000000..aa72ab96c3c1
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/Makefile
@@ -0,0 +1,207 @@
1include ../../../scripts/Makefile.include
2include ../../../scripts/utilities.mak
3
4# This Makefile and manpage XSL files were taken from tools/perf/Documentation
5# and modified for libtraceevent.
6
7MAN3_TXT= \
8 $(wildcard libtraceevent-*.txt) \
9 libtraceevent.txt
10
11MAN_TXT = $(MAN3_TXT)
12_MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
13_MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT))
14_DOC_MAN3=$(patsubst %.txt,%.3,$(MAN3_TXT))
15
16MAN_XML=$(addprefix $(OUTPUT),$(_MAN_XML))
17MAN_HTML=$(addprefix $(OUTPUT),$(_MAN_HTML))
18DOC_MAN3=$(addprefix $(OUTPUT),$(_DOC_MAN3))
19
20# Make the path relative to DESTDIR, not prefix
21ifndef DESTDIR
22prefix?=$(HOME)
23endif
24bindir?=$(prefix)/bin
25htmldir?=$(prefix)/share/doc/libtraceevent-doc
26pdfdir?=$(prefix)/share/doc/libtraceevent-doc
27mandir?=$(prefix)/share/man
28man3dir=$(mandir)/man3
29
30ASCIIDOC=asciidoc
31ASCIIDOC_EXTRA = --unsafe -f asciidoc.conf
32ASCIIDOC_HTML = xhtml11
33MANPAGE_XSL = manpage-normal.xsl
34XMLTO_EXTRA =
35INSTALL?=install
36RM ?= rm -f
37
38ifdef USE_ASCIIDOCTOR
39ASCIIDOC = asciidoctor
40ASCIIDOC_EXTRA = -a compat-mode
41ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions
42ASCIIDOC_EXTRA += -a mansource="libtraceevent" -a manmanual="libtraceevent Manual"
43ASCIIDOC_HTML = xhtml5
44endif
45
46XMLTO=xmlto
47
48_tmp_tool_path := $(call get-executable,$(ASCIIDOC))
49ifeq ($(_tmp_tool_path),)
50 missing_tools = $(ASCIIDOC)
51endif
52
53ifndef USE_ASCIIDOCTOR
54_tmp_tool_path := $(call get-executable,$(XMLTO))
55ifeq ($(_tmp_tool_path),)
56 missing_tools += $(XMLTO)
57endif
58endif
59
60#
61# For asciidoc ...
62# -7.1.2, no extra settings are needed.
63# 8.0-, set ASCIIDOC8.
64#
65
66#
67# For docbook-xsl ...
68# -1.68.1, set ASCIIDOC_NO_ROFF? (based on changelog from 1.73.0)
69# 1.69.0, no extra settings are needed?
70# 1.69.1-1.71.0, set DOCBOOK_SUPPRESS_SP?
71# 1.71.1, no extra settings are needed?
72# 1.72.0, set DOCBOOK_XSL_172.
73# 1.73.0-, set ASCIIDOC_NO_ROFF
74#
75
76#
77# If you had been using DOCBOOK_XSL_172 in an attempt to get rid
78# of 'the ".ft C" problem' in your generated manpages, and you
79# instead ended up with weird characters around callouts, try
80# using ASCIIDOC_NO_ROFF instead (it works fine with ASCIIDOC8).
81#
82
83ifdef ASCIIDOC8
84ASCIIDOC_EXTRA += -a asciidoc7compatible
85endif
86ifdef DOCBOOK_XSL_172
87ASCIIDOC_EXTRA += -a libtraceevent-asciidoc-no-roff
88MANPAGE_XSL = manpage-1.72.xsl
89else
90 ifdef ASCIIDOC_NO_ROFF
91 # docbook-xsl after 1.72 needs the regular XSL, but will not
92 # pass-thru raw roff codes from asciidoc.conf, so turn them off.
93 ASCIIDOC_EXTRA += -a libtraceevent-asciidoc-no-roff
94 endif
95endif
96ifdef MAN_BOLD_LITERAL
97XMLTO_EXTRA += -m manpage-bold-literal.xsl
98endif
99ifdef DOCBOOK_SUPPRESS_SP
100XMLTO_EXTRA += -m manpage-suppress-sp.xsl
101endif
102
103SHELL_PATH ?= $(SHELL)
104# Shell quote;
105SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
106
107DESTDIR ?=
108DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
109
110export DESTDIR DESTDIR_SQ
111
112#
113# Please note that there is a minor bug in asciidoc.
114# The version after 6.0.3 _will_ include the patch found here:
115# http://marc.theaimsgroup.com/?l=libtraceevent&m=111558757202243&w=2
116#
117# Until that version is released you may have to apply the patch
118# yourself - yes, all 6 characters of it!
119#
120QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
121QUIET_SUBDIR1 =
122
123ifneq ($(findstring $(MAKEFLAGS),w),w)
124PRINT_DIR = --no-print-directory
125else # "make -w"
126NO_SUBDIR = :
127endif
128
129ifneq ($(findstring $(MAKEFLAGS),s),s)
130ifneq ($(V),1)
131 QUIET_ASCIIDOC = @echo ' ASCIIDOC '$@;
132 QUIET_XMLTO = @echo ' XMLTO '$@;
133 QUIET_SUBDIR0 = +@subdir=
134 QUIET_SUBDIR1 = ;$(NO_SUBDIR) \
135 echo ' SUBDIR ' $$subdir; \
136 $(MAKE) $(PRINT_DIR) -C $$subdir
137 export V
138endif
139endif
140
141all: html man
142
143man: man3
144man3: $(DOC_MAN3)
145
146html: $(MAN_HTML)
147
148$(MAN_HTML) $(DOC_MAN3): asciidoc.conf
149
150install: install-man
151
152check-man-tools:
153ifdef missing_tools
154 $(error "You need to install $(missing_tools) for man pages")
155endif
156
157do-install-man: man
158 $(call QUIET_INSTALL, Documentation-man) \
159 $(INSTALL) -d -m 755 $(DESTDIR)$(man3dir); \
160 $(INSTALL) -m 644 $(DOC_MAN3) $(DESTDIR)$(man3dir);
161
162install-man: check-man-tools man do-install-man
163
164uninstall: uninstall-man
165
166uninstall-man:
167 $(call QUIET_UNINST, Documentation-man) \
168 $(Q)$(RM) $(addprefix $(DESTDIR)$(man3dir)/,$(DOC_MAN3))
169
170
171ifdef missing_tools
172 DO_INSTALL_MAN = $(warning Please install $(missing_tools) to have the man pages installed)
173else
174 DO_INSTALL_MAN = do-install-man
175endif
176
177CLEAN_FILES = \
178 $(MAN_XML) $(addsuffix +,$(MAN_XML)) \
179 $(MAN_HTML) $(addsuffix +,$(MAN_HTML)) \
180 $(DOC_MAN3) *.3
181
182clean:
183 $(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES)
184
185ifdef USE_ASCIIDOCTOR
186$(OUTPUT)%.3 : $(OUTPUT)%.txt
187 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
188 $(ASCIIDOC) -b manpage -d manpage \
189 $(ASCIIDOC_EXTRA) -alibtraceevent_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \
190 mv $@+ $@
191endif
192
193$(OUTPUT)%.3 : $(OUTPUT)%.xml
194 $(QUIET_XMLTO)$(RM) $@ && \
195 $(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
196
197$(OUTPUT)%.xml : %.txt
198 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
199 $(ASCIIDOC) -b docbook -d manpage \
200 $(ASCIIDOC_EXTRA) -alibtraceevent_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \
201 mv $@+ $@
202
203$(MAN_HTML): $(OUTPUT)%.html : %.txt
204 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
205 $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage \
206 $(ASCIIDOC_EXTRA) -aperf_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \
207 mv $@+ $@
diff --git a/tools/lib/traceevent/Documentation/asciidoc.conf b/tools/lib/traceevent/Documentation/asciidoc.conf
new file mode 100644
index 000000000000..07595717f06e
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/asciidoc.conf
@@ -0,0 +1,120 @@
1## linktep: macro
2#
3# Usage: linktep:command[manpage-section]
4#
5# Note, {0} is the manpage section, while {target} is the command.
6#
7# Show TEP link as: <command>(<section>); if section is defined, else just show
8# the command.
9
10[macros]
11(?su)[\\]?(?P<name>linktep):(?P<target>\S*?)\[(?P<attrlist>.*?)\]=
12
13[attributes]
14asterisk=&#42;
15plus=&#43;
16caret=&#94;
17startsb=&#91;
18endsb=&#93;
19tilde=&#126;
20
21ifdef::backend-docbook[]
22[linktep-inlinemacro]
23{0%{target}}
24{0#<citerefentry>}
25{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
26{0#</citerefentry>}
27endif::backend-docbook[]
28
29ifdef::backend-docbook[]
30ifndef::tep-asciidoc-no-roff[]
31# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this.
32# v1.72 breaks with this because it replaces dots not in roff requests.
33[listingblock]
34<example><title>{title}</title>
35<literallayout>
36ifdef::doctype-manpage[]
37&#10;.ft C&#10;
38endif::doctype-manpage[]
39|
40ifdef::doctype-manpage[]
41&#10;.ft&#10;
42endif::doctype-manpage[]
43</literallayout>
44{title#}</example>
45endif::tep-asciidoc-no-roff[]
46
47ifdef::tep-asciidoc-no-roff[]
48ifdef::doctype-manpage[]
49# The following two small workarounds insert a simple paragraph after screen
50[listingblock]
51<example><title>{title}</title>
52<literallayout>
53|
54</literallayout><simpara></simpara>
55{title#}</example>
56
57[verseblock]
58<formalpara{id? id="{id}"}><title>{title}</title><para>
59{title%}<literallayout{id? id="{id}"}>
60{title#}<literallayout>
61|
62</literallayout>
63{title#}</para></formalpara>
64{title%}<simpara></simpara>
65endif::doctype-manpage[]
66endif::tep-asciidoc-no-roff[]
67endif::backend-docbook[]
68
69ifdef::doctype-manpage[]
70ifdef::backend-docbook[]
71[header]
72template::[header-declarations]
73<refentry>
74<refmeta>
75<refentrytitle>{mantitle}</refentrytitle>
76<manvolnum>{manvolnum}</manvolnum>
77<refmiscinfo class="source">libtraceevent</refmiscinfo>
78<refmiscinfo class="version">{libtraceevent_version}</refmiscinfo>
79<refmiscinfo class="manual">libtraceevent Manual</refmiscinfo>
80</refmeta>
81<refnamediv>
82 <refname>{manname1}</refname>
83 <refname>{manname2}</refname>
84 <refname>{manname3}</refname>
85 <refname>{manname4}</refname>
86 <refname>{manname5}</refname>
87 <refname>{manname6}</refname>
88 <refname>{manname7}</refname>
89 <refname>{manname8}</refname>
90 <refname>{manname9}</refname>
91 <refname>{manname10}</refname>
92 <refname>{manname11}</refname>
93 <refname>{manname12}</refname>
94 <refname>{manname13}</refname>
95 <refname>{manname14}</refname>
96 <refname>{manname15}</refname>
97 <refname>{manname16}</refname>
98 <refname>{manname17}</refname>
99 <refname>{manname18}</refname>
100 <refname>{manname19}</refname>
101 <refname>{manname20}</refname>
102 <refname>{manname21}</refname>
103 <refname>{manname22}</refname>
104 <refname>{manname23}</refname>
105 <refname>{manname24}</refname>
106 <refname>{manname25}</refname>
107 <refname>{manname26}</refname>
108 <refname>{manname27}</refname>
109 <refname>{manname28}</refname>
110 <refname>{manname29}</refname>
111 <refname>{manname30}</refname>
112 <refpurpose>{manpurpose}</refpurpose>
113</refnamediv>
114endif::backend-docbook[]
115endif::doctype-manpage[]
116
117ifdef::backend-xhtml11[]
118[linktep-inlinemacro]
119<a href="{target}.html">{target}{0?({0})}</a>
120endif::backend-xhtml11[]
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-commands.txt b/tools/lib/traceevent/Documentation/libtraceevent-commands.txt
new file mode 100644
index 000000000000..bec552001f8e
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-commands.txt
@@ -0,0 +1,153 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_register_comm, tep_override_comm, tep_pid_is_registered,
7tep_data_comm_from_pid, tep_data_pid_from_comm, tep_cmdline_pid -
8Manage pid to process name mappings.
9
10SYNOPSIS
11--------
12[verse]
13--
14*#include <event-parse.h>*
15
16int *tep_register_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_);
17int *tep_override_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_);
18bool *tep_is_pid_registered*(struct tep_handle pass:[*]_tep_, int _pid_);
19const char pass:[*]*tep_data_comm_from_pid*(struct tep_handle pass:[*]_pevent_, int _pid_);
20struct cmdline pass:[*]*tep_data_pid_from_comm*(struct tep_handle pass:[*]_pevent_, const char pass:[*]_comm_, struct cmdline pass:[*]_next_);
21int *tep_cmdline_pid*(struct tep_handle pass:[*]_pevent_, struct cmdline pass:[*]_cmdline_);
22--
23
24DESCRIPTION
25-----------
26These functions can be used to handle the mapping between pid and process name.
27The library builds a cache of these mappings, which is used to display the name
28of the process, instead of its pid. This information can be retrieved from
29tracefs/saved_cmdlines file.
30
31The _tep_register_comm()_ function registers a _pid_ / process name mapping.
32If a command with the same _pid_ is already registered, an error is returned.
33The _pid_ argument is the process ID, the _comm_ argument is the process name,
34_tep_ is the event context. The _comm_ is duplicated internally.
35
36The _tep_override_comm()_ function registers a _pid_ / process name mapping.
37If a process with the same pid is already registered, the process name string is
38udapted with the new one. The _pid_ argument is the process ID, the _comm_
39argument is the process name, _tep_ is the event context. The _comm_ is
40duplicated internally.
41
42The _tep_is_pid_registered()_ function checks if a pid has a process name
43mapping registered. The _pid_ argument is the process ID, _tep_ is the event
44context.
45
46The _tep_data_comm_from_pid()_ function returns the process name for a given
47pid. The _pid_ argument is the process ID, _tep_ is the event context.
48The returned string should not be freed, but will be freed when the _tep_
49handler is closed.
50
51The _tep_data_pid_from_comm()_ function returns a pid for a given process name.
52The _comm_ argument is the process name, _tep_ is the event context.
53The argument _next_ is the cmdline structure to search for the next pid.
54As there may be more than one pid for a given process, the result of this call
55can be passed back into a recurring call in the _next_ parameter, to search for
56the next pid. If _next_ is NULL, it will return the first pid associated with
57the _comm_. The function performs a linear search, so it may be slow.
58
59The _tep_cmdline_pid()_ function returns the pid associated with a given
60_cmdline_. The _tep_ argument is the event context.
61
62RETURN VALUE
63------------
64_tep_register_comm()_ function returns 0 on success. In case of an error -1 is
65returned and errno is set to indicate the cause of the problem: ENOMEM, if there
66is not enough memory to duplicate the _comm_ or EEXIST if a mapping for this
67_pid_ is already registered.
68
69_tep_override_comm()_ function returns 0 on success. In case of an error -1 is
70returned and errno is set to indicate the cause of the problem: ENOMEM, if there
71is not enough memory to duplicate the _comm_.
72
73_tep_is_pid_registered()_ function returns true if the _pid_ has a process name
74mapped to it, false otherwise.
75
76_tep_data_comm_from_pid()_ function returns the process name as string, or the
77string "<...>" if there is no mapping for the given pid.
78
79_tep_data_pid_from_comm()_ function returns a pointer to a struct cmdline, that
80holds a pid for a given process, or NULL if none is found. This result can be
81passed back into a recurring call as the _next_ parameter of the function.
82
83_tep_cmdline_pid()_ functions returns the pid for the give cmdline. If _cmdline_
84 is NULL, then -1 is returned.
85
86EXAMPLE
87-------
88The following example registers pid for command "ls", in context of event _tep_
89and performs various searches for pid / process name mappings:
90[source,c]
91--
92#include <event-parse.h>
93...
94int ret;
95int ls_pid = 1021;
96struct tep_handle *tep = tep_alloc();
97...
98 ret = tep_register_comm(tep, "ls", ls_pid);
99 if (ret != 0 && errno == EEXIST)
100 ret = tep_override_comm(tep, "ls", ls_pid);
101 if (ret != 0) {
102 /* Failed to register pid / command mapping */
103 }
104...
105 if (tep_is_pid_registered(tep, ls_pid) == 0) {
106 /* Command mapping for ls_pid is not registered */
107 }
108...
109 const char *comm = tep_data_comm_from_pid(tep, ls_pid);
110 if (comm) {
111 /* Found process name for ls_pid */
112 }
113...
114 int pid;
115 struct cmdline *cmd = tep_data_pid_from_comm(tep, "ls", NULL);
116 while (cmd) {
117 pid = tep_cmdline_pid(tep, cmd);
118 /* Found pid for process "ls" */
119 cmd = tep_data_pid_from_comm(tep, "ls", cmd);
120 }
121--
122FILES
123-----
124[verse]
125--
126*event-parse.h*
127 Header file to include in order to have access to the library APIs.
128*-ltraceevent*
129 Linker switch to add when building a program that uses the library.
130--
131
132SEE ALSO
133--------
134_libtraceevent(3)_, _trace-cmd(1)_
135
136AUTHOR
137------
138[verse]
139--
140*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
141*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
142--
143REPORTING BUGS
144--------------
145Report bugs to <linux-trace-devel@vger.kernel.org>
146
147LICENSE
148-------
149libtraceevent is Free Software licensed under the GNU LGPL 2.1
150
151RESOURCES
152---------
153https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-cpus.txt b/tools/lib/traceevent/Documentation/libtraceevent-cpus.txt
new file mode 100644
index 000000000000..5ad70e43b752
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-cpus.txt
@@ -0,0 +1,77 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_get_cpus, tep_set_cpus - Get / set the number of CPUs, which have a tracing
7buffer representing it. Note, the buffer may be empty.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15int *tep_get_cpus*(struct tep_handle pass:[*]_tep_);
16void *tep_set_cpus*(struct tep_handle pass:[*]_tep_, int _cpus_);
17--
18
19DESCRIPTION
20-----------
21The _tep_get_cpus()_ function gets the number of CPUs, which have a tracing
22buffer representing it. The _tep_ argument is trace event parser context.
23
24The _tep_set_cpus()_ function sets the number of CPUs, which have a tracing
25buffer representing it. The _tep_ argument is trace event parser context.
26The _cpu_ argument is the number of CPUs with tracing data.
27
28RETURN VALUE
29------------
30The _tep_get_cpus()_ functions returns the number of CPUs, which have tracing
31data recorded.
32
33EXAMPLE
34-------
35[source,c]
36--
37#include <event-parse.h>
38...
39struct tep_handle *tep = tep_alloc();
40...
41 tep_set_cpus(tep, 5);
42...
43 printf("We have tracing data for %d CPUs", tep_get_cpus(tep));
44--
45
46FILES
47-----
48[verse]
49--
50*event-parse.h*
51 Header file to include in order to have access to the library APIs.
52*-ltraceevent*
53 Linker switch to add when building a program that uses the library.
54--
55
56SEE ALSO
57--------
58_libtraceevent(3)_, _trace-cmd(1)_
59
60AUTHOR
61------
62[verse]
63--
64*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
65*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
66--
67REPORTING BUGS
68--------------
69Report bugs to <linux-trace-devel@vger.kernel.org>
70
71LICENSE
72-------
73libtraceevent is Free Software licensed under the GNU LGPL 2.1
74
75RESOURCES
76---------
77https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt b/tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt
new file mode 100644
index 000000000000..e64851b6e189
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt
@@ -0,0 +1,78 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_read_number - Reads a number from raw data.
7
8SYNOPSIS
9--------
10[verse]
11--
12*#include <event-parse.h>*
13
14unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, const void pass:[*]_ptr_, int _size_);
15--
16
17DESCRIPTION
18-----------
19The _tep_read_number()_ function reads an integer from raw data, taking into
20account the endianness of the raw data and the current host. The _tep_ argument
21is the trace event parser context. The _ptr_ is a pointer to the raw data, where
22the integer is, and the _size_ is the size of the integer.
23
24RETURN VALUE
25------------
26The _tep_read_number()_ function returns the integer in the byte order of
27the current host. In case of an error, 0 is returned.
28
29EXAMPLE
30-------
31[source,c]
32--
33#include <event-parse.h>
34...
35struct tep_handle *tep = tep_alloc();
36...
37void process_record(struct tep_record *record)
38{
39 int offset = 24;
40 int data = tep_read_number(tep, record->data + offset, 4);
41
42 /* Read the 4 bytes at the offset 24 of data as an integer */
43}
44...
45--
46
47FILES
48-----
49[verse]
50--
51*event-parse.h*
52 Header file to include in order to have access to the library APIs.
53*-ltraceevent*
54 Linker switch to add when building a program that uses the library.
55--
56
57SEE ALSO
58--------
59_libtraceevent(3)_, _trace-cmd(1)_
60
61AUTHOR
62------
63[verse]
64--
65*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
66*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
67--
68REPORTING BUGS
69--------------
70Report bugs to <linux-trace-devel@vger.kernel.org>
71
72LICENSE
73-------
74libtraceevent is Free Software licensed under the GNU LGPL 2.1
75
76RESOURCES
77---------
78https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_find.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_find.txt
new file mode 100644
index 000000000000..7bc062c9f76f
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-event_find.txt
@@ -0,0 +1,103 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_find_event,tep_find_event_by_name,tep_find_event_by_record -
7Find events by given key.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_);
16struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_);
17struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_);
18--
19
20DESCRIPTION
21-----------
22This set of functions can be used to search for an event, based on a given
23criteria. All functions require a pointer to a _tep_, trace event parser
24context.
25
26The _tep_find_event()_ function searches for an event by given event _id_. The
27event ID is assigned dynamically and can be viewed in event's format file,
28"ID" field.
29
30The tep_find_event_by_name()_ function searches for an event by given
31event _name_, under the system _sys_. If the _sys_ is NULL (not specified),
32the first event with _name_ is returned.
33
34The tep_find_event_by_record()_ function searches for an event from a given
35_record_.
36
37RETURN VALUE
38------------
39All these functions return a pointer to the found event, or NULL if there is no
40such event.
41
42EXAMPLE
43-------
44[source,c]
45--
46#include <event-parse.h>
47...
48struct tep_handle *tep = tep_alloc();
49...
50struct tep_event *event;
51
52event = tep_find_event(tep, 1857);
53if (event == NULL) {
54 /* There is no event with ID 1857 */
55}
56
57event = tep_find_event_by_name(tep, "kvm", "kvm_exit");
58if (event == NULL) {
59 /* There is no kvm_exit event, from kvm system */
60}
61
62void event_from_record(struct tep_record *record)
63{
64 struct tep_event *event = tep_find_event_by_record(tep, record);
65 if (event == NULL) {
66 /* There is no event from given record */
67 }
68}
69...
70--
71
72FILES
73-----
74[verse]
75--
76*event-parse.h*
77 Header file to include in order to have access to the library APIs.
78*-ltraceevent*
79 Linker switch to add when building a program that uses the library.
80--
81
82SEE ALSO
83--------
84_libtraceevent(3)_, _trace-cmd(1)_
85
86AUTHOR
87------
88[verse]
89--
90*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
91*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
92--
93REPORTING BUGS
94--------------
95Report bugs to <linux-trace-devel@vger.kernel.org>
96
97LICENSE
98-------
99libtraceevent is Free Software licensed under the GNU LGPL 2.1
100
101RESOURCES
102---------
103https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_get.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_get.txt
new file mode 100644
index 000000000000..6525092fc417
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-event_get.txt
@@ -0,0 +1,99 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_get_event, tep_get_first_event, tep_get_events_count - Access events.
7
8SYNOPSIS
9--------
10[verse]
11--
12*#include <event-parse.h>*
13
14struct tep_event pass:[*]*tep_get_event*(struct tep_handle pass:[*]_tep_, int _index_);
15struct tep_event pass:[*]*tep_get_first_event*(struct tep_handle pass:[*]_tep_);
16int *tep_get_events_count*(struct tep_handle pass:[*]_tep_);
17--
18
19DESCRIPTION
20-----------
21The _tep_get_event()_ function returns a pointer to event at the given _index_.
22The _tep_ argument is trace event parser context, the _index_ is the index of
23the requested event.
24
25The _tep_get_first_event()_ function returns a pointer to the first event.
26As events are stored in an array, this function returns the pointer to the
27beginning of the array. The _tep_ argument is trace event parser context.
28
29The _tep_get_events_count()_ function returns the number of the events
30in the array. The _tep_ argument is trace event parser context.
31
32RETURN VALUE
33------------
34The _tep_get_event()_ returns a pointer to the event located at _index_.
35NULL is returned in case of error, in case there are no events or _index_ is
36out of range.
37
38The _tep_get_first_event()_ returns a pointer to the first event. NULL is
39returned in case of error, or in case there are no events.
40
41The _tep_get_events_count()_ returns the number of the events. 0 is
42returned in case of error, or in case there are no events.
43
44EXAMPLE
45-------
46[source,c]
47--
48#include <event-parse.h>
49...
50struct tep_handle *tep = tep_alloc();
51...
52int i,count = tep_get_events_count(tep);
53struct tep_event *event, *events = tep_get_first_event(tep);
54
55if (events == NULL) {
56 /* There are no events */
57} else {
58 for (i = 0; i < count; i++) {
59 event = (events+i);
60 /* process events[i] */
61 }
62
63 /* Get the last event */
64 event = tep_get_event(tep, count-1);
65}
66--
67
68FILES
69-----
70[verse]
71--
72*event-parse.h*
73 Header file to include in order to have access to the library APIs.
74*-ltraceevent*
75 Linker switch to add when building a program that uses the library.
76--
77
78SEE ALSO
79--------
80_libtraceevent(3)_, _trace-cmd(1)_
81
82AUTHOR
83------
84[verse]
85--
86*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
87*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
88--
89REPORTING BUGS
90--------------
91Report bugs to <linux-trace-devel@vger.kernel.org>
92
93LICENSE
94-------
95libtraceevent is Free Software licensed under the GNU LGPL 2.1
96
97RESOURCES
98---------
99https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_list.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_list.txt
new file mode 100644
index 000000000000..fba350e5a4cb
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-event_list.txt
@@ -0,0 +1,122 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_list_events, tep_list_events_copy -
7Get list of events, sorted by given criteria.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15enum *tep_event_sort_type* {
16 _TEP_EVENT_SORT_ID_,
17 _TEP_EVENT_SORT_NAME_,
18 _TEP_EVENT_SORT_SYSTEM_,
19};
20
21struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_);
22struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_);
23--
24
25DESCRIPTION
26-----------
27The _tep_list_events()_ function returns an array of pointers to the events,
28sorted by the _sort_type_ criteria. The last element of the array is NULL.
29The returned memory must not be freed, it is managed by the library.
30The function is not thread safe. The _tep_ argument is trace event parser
31context. The _sort_type_ argument is the required sort criteria:
32[verse]
33--
34 _TEP_EVENT_SORT_ID_ - sort by the event ID.
35 _TEP_EVENT_SORT_NAME_ - sort by the event (name, system, id) triplet.
36 _TEP_EVENT_SORT_SYSTEM_ - sort by the event (system, name, id) triplet.
37--
38
39The _tep_list_events_copy()_ is a thread safe version of _tep_list_events()_.
40It has the same behavior, but the returned array is allocated internally and
41must be freed by the caller. Note that the content of the array must not be
42freed (see the EXAMPLE below).
43
44RETURN VALUE
45------------
46The _tep_list_events()_ function returns an array of pointers to events.
47In case of an error, NULL is returned. The returned array must not be freed,
48it is managed by the library.
49
50The _tep_list_events_copy()_ function returns an array of pointers to events.
51In case of an error, NULL is returned. The returned array must be freed by
52the caller.
53
54EXAMPLE
55-------
56[source,c]
57--
58#include <event-parse.h>
59...
60struct tep_handle *tep = tep_alloc();
61...
62int i;
63struct tep_event_format **events;
64
65i=0;
66events = tep_list_events(tep, TEP_EVENT_SORT_ID);
67if (events == NULL) {
68 /* Failed to get the events, sorted by ID */
69} else {
70 while(events[i]) {
71 /* walk through the list of the events, sorted by ID */
72 i++;
73 }
74}
75
76i=0;
77events = tep_list_events_copy(tep, TEP_EVENT_SORT_NAME);
78if (events == NULL) {
79 /* Failed to get the events, sorted by name */
80} else {
81 while(events[i]) {
82 /* walk through the list of the events, sorted by name */
83 i++;
84 }
85 free(events);
86}
87
88...
89--
90
91FILES
92-----
93[verse]
94--
95*event-parse.h*
96 Header file to include in order to have access to the library APIs.
97*-ltraceevent*
98 Linker switch to add when building a program that uses the library.
99--
100
101SEE ALSO
102--------
103_libtraceevent(3)_, _trace-cmd(1)_
104
105AUTHOR
106------
107[verse]
108--
109*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
110*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
111--
112REPORTING BUGS
113--------------
114Report bugs to <linux-trace-devel@vger.kernel.org>
115
116LICENSE
117-------
118libtraceevent is Free Software licensed under the GNU LGPL 2.1
119
120RESOURCES
121---------
122https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_find.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_find.txt
new file mode 100644
index 000000000000..0896af5b9eff
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-field_find.txt
@@ -0,0 +1,118 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_find_common_field, tep_find_field, tep_find_any_field -
7Search for a field in an event.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15struct tep_format_field pass:[*]*tep_find_common_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_);
16struct tep_format_field pass:[*]*tep_find_field*(struct tep_event_ormat pass:[*]_event_, const char pass:[*]_name_);
17struct tep_format_field pass:[*]*tep_find_any_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_);
18--
19
20DESCRIPTION
21-----------
22These functions search for a field with given name in an event. The field
23returned can be used to find the field content from within a data record.
24
25The _tep_find_common_field()_ function searches for a common field with _name_
26in the _event_.
27
28The _tep_find_field()_ function searches for an event specific field with
29_name_ in the _event_.
30
31The _tep_find_any_field()_ function searches for any field with _name_ in the
32_event_.
33
34RETURN VALUE
35------------
36The _tep_find_common_field(), _tep_find_field()_ and _tep_find_any_field()_
37functions return a pointer to the found field, or NULL in case there is no field
38with the requested name.
39
40EXAMPLE
41-------
42[source,c]
43--
44#include <event-parse.h>
45...
46void get_htimer_info(struct tep_handle *tep, struct tep_record *record)
47{
48 struct tep_format_field *field;
49 struct tep_event *event;
50 long long softexpires;
51 int mode;
52 int pid;
53
54 event = tep_find_event_by_name(tep, "timer", "hrtimer_start");
55
56 field = tep_find_common_field(event, "common_pid");
57 if (field == NULL) {
58 /* Cannot find "common_pid" field in the event */
59 } else {
60 /* Get pid from the data record */
61 pid = tep_read_number(tep, record->data + field->offset,
62 field->size);
63 }
64
65 field = tep_find_field(event, "softexpires");
66 if (field == NULL) {
67 /* Cannot find "softexpires" event specific field in the event */
68 } else {
69 /* Get softexpires parameter from the data record */
70 softexpires = tep_read_number(tep, record->data + field->offset,
71 field->size);
72 }
73
74 field = tep_find_any_field(event, "mode");
75 if (field == NULL) {
76 /* Cannot find "mode" field in the event */
77 } else
78 {
79 /* Get mode parameter from the data record */
80 mode = tep_read_number(tep, record->data + field->offset,
81 field->size);
82 }
83}
84...
85--
86
87FILES
88-----
89[verse]
90--
91*event-parse.h*
92 Header file to include in order to have access to the library APIs.
93*-ltraceevent*
94 Linker switch to add when building a program that uses the library.
95--
96
97SEE ALSO
98--------
99_libtraceevent(3)_, _trace-cmd(1)_
100
101AUTHOR
102------
103[verse]
104--
105*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
106*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
107--
108REPORTING BUGS
109--------------
110Report bugs to <linux-trace-devel@vger.kernel.org>
111
112LICENSE
113-------
114libtraceevent is Free Software licensed under the GNU LGPL 2.1
115
116RESOURCES
117---------
118https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt
new file mode 100644
index 000000000000..6324f0d48aeb
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt
@@ -0,0 +1,122 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_get_any_field_val, tep_get_common_field_val, tep_get_field_val,
7tep_get_field_raw - Get value of a field.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14*#include <trace-seq.h>*
15
16int *tep_get_any_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_);
17int *tep_get_common_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_);
18int *tep_get_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_);
19void pass:[*]*tep_get_field_raw*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int pass:[*]_len_, int _err_);
20--
21
22DESCRIPTION
23-----------
24These functions can be used to find a field and retrieve its value.
25
26The _tep_get_any_field_val()_ function searches in the _record_ for a field
27with _name_, part of the _event_. If the field is found, its value is stored in
28_val_. If there is an error and _err_ is not zero, then an error string is
29written into _s_.
30
31The _tep_get_common_field_val()_ function does the same as
32_tep_get_any_field_val()_, but searches only in the common fields. This works
33for any event as all events include the common fields.
34
35The _tep_get_field_val()_ function does the same as _tep_get_any_field_val()_,
36but searches only in the event specific fields.
37
38The _tep_get_field_raw()_ function searches in the _record_ for a field with
39_name_, part of the _event_. If the field is found, a pointer to where the field
40exists in the record's raw data is returned. The size of the data is stored in
41_len_. If there is an error and _err_ is not zero, then an error string is
42written into _s_.
43
44RETURN VALUE
45------------
46The _tep_get_any_field_val()_, _tep_get_common_field_val()_ and
47_tep_get_field_val()_ functions return 0 on success, or -1 in case of an error.
48
49The _tep_get_field_raw()_ function returns a pointer to field's raw data, and
50places the length of this data in _len_. In case of an error NULL is returned.
51
52EXAMPLE
53-------
54[source,c]
55--
56#include <event-parse.h>
57#include <trace-seq.h>
58...
59struct tep_handle *tep = tep_alloc();
60...
61struct tep_event *event = tep_find_event_by_name(tep, "kvm", "kvm_exit");
62...
63void process_record(struct tep_record *record)
64{
65 int len;
66 char *comm;
67 struct tep_event_format *event;
68 unsigned long long val;
69
70 event = tep_find_event_by_record(pevent, record);
71 if (event != NULL) {
72 if (tep_get_common_field_val(NULL, event, "common_type",
73 record, &val, 0) == 0) {
74 /* Got the value of common type field */
75 }
76 if (tep_get_field_val(NULL, event, "pid", record, &val, 0) == 0) {
77 /* Got the value of pid specific field */
78 }
79 comm = tep_get_field_raw(NULL, event, "comm", record, &len, 0);
80 if (comm != NULL) {
81 /* Got a pointer to the comm event specific field */
82 }
83 }
84}
85--
86
87FILES
88-----
89[verse]
90--
91*event-parse.h*
92 Header file to include in order to have access to the library APIs.
93*trace-seq.h*
94 Header file to include in order to have access to trace sequences
95 related APIs. Trace sequences are used to allow a function to call
96 several other functions to create a string of data to use.
97*-ltraceevent*
98 Linker switch to add when building a program that uses the library.
99--
100
101SEE ALSO
102--------
103_libtraceevent(3)_, _trace-cmd(1)_
104
105AUTHOR
106------
107[verse]
108--
109*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
110*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
111--
112REPORTING BUGS
113--------------
114Report bugs to <linux-trace-devel@vger.kernel.org>
115
116LICENSE
117-------
118libtraceevent is Free Software licensed under the GNU LGPL 2.1
119
120RESOURCES
121---------
122https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_print.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_print.txt
new file mode 100644
index 000000000000..9a9df98ac44d
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-field_print.txt
@@ -0,0 +1,126 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_print_field, tep_print_fields, tep_print_num_field, tep_print_func_field -
7Print the field content.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14*#include <trace-seq.h>*
15
16void *tep_print_field*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, struct tep_format_field pass:[*]_field_);
17void *tep_print_fields*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int _size_, struct tep_event pass:[*]_event_);
18int *tep_print_num_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_);
19int *tep_print_func_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_);
20--
21
22DESCRIPTION
23-----------
24These functions print recorded field's data, according to the field's type.
25
26The _tep_print_field()_ function extracts from the recorded raw _data_ value of
27the _field_ and prints it into _s_, according to the field type.
28
29The _tep_print_fields()_ prints each field name followed by the record's field
30value according to the field's type:
31[verse]
32--
33"field1_name=field1_value field2_name=field2_value ..."
34--
35It iterates all fields of the _event_, and calls _tep_print_field()_ for each of
36them.
37
38The _tep_print_num_field()_ function prints a numeric field with given format
39string. A search is performed in the _event_ for a field with _name_. If such
40field is found, its value is extracted from the _record_ and is printed in the
41_s_, according to the given format string _fmt_. If the argument _err_ is
42non-zero, and an error occures - it is printed in the _s_.
43
44The _tep_print_func_field()_ function prints a function field with given format
45string. A search is performed in the _event_ for a field with _name_. If such
46field is found, its value is extracted from the _record_. The value is assumed
47to be a function address, and a search is perform to find the name of this
48function. The function name (if found) and its address are printed in the _s_,
49according to the given format string _fmt_. If the argument _err_ is non-zero,
50and an error occures - it is printed in _s_.
51
52RETURN VALUE
53------------
54The _tep_print_num_field()_ and _tep_print_func_field()_ functions return 1
55on success, -1 in case of an error or 0 if the print buffer _s_ is full.
56
57EXAMPLE
58-------
59[source,c]
60--
61#include <event-parse.h>
62#include <trace-seq.h>
63...
64struct tep_handle *tep = tep_alloc();
65...
66struct trace_seq seq;
67trace_seq_init(&seq);
68struct tep_event *event = tep_find_event_by_name(tep, "timer", "hrtimer_start");
69...
70void process_record(struct tep_record *record)
71{
72 struct tep_format_field *field_pid = tep_find_common_field(event, "common_pid");
73
74 trace_seq_reset(&seq);
75
76 /* Print the value of "common_pid" */
77 tep_print_field(&seq, record->data, field_pid);
78
79 /* Print all fields of the "hrtimer_start" event */
80 tep_print_fields(&seq, record->data, record->size, event);
81
82 /* Print the value of "expires" field with custom format string */
83 tep_print_num_field(&seq, " timer expires in %llu ", event, "expires", record, 0);
84
85 /* Print the address and the name of "function" field with custom format string */
86 tep_print_func_field(&seq, " timer function is %s ", event, "function", record, 0);
87 }
88 ...
89--
90
91FILES
92-----
93[verse]
94--
95*event-parse.h*
96 Header file to include in order to have access to the library APIs.
97*trace-seq.h*
98 Header file to include in order to have access to trace sequences related APIs.
99 Trace sequences are used to allow a function to call several other functions
100 to create a string of data to use.
101*-ltraceevent*
102 Linker switch to add when building a program that uses the library.
103--
104
105SEE ALSO
106--------
107_libtraceevent(3)_, _trace-cmd(1)_
108
109AUTHOR
110------
111[verse]
112--
113*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
114*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
115--
116REPORTING BUGS
117--------------
118Report bugs to <linux-trace-devel@vger.kernel.org>
119
120LICENSE
121-------
122libtraceevent is Free Software licensed under the GNU LGPL 2.1
123
124RESOURCES
125---------
126https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_read.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_read.txt
new file mode 100644
index 000000000000..64e9e25d3fd9
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-field_read.txt
@@ -0,0 +1,81 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_read_number_field - Reads a number from raw data.
7
8SYNOPSIS
9--------
10[verse]
11--
12*#include <event-parse.h>*
13
14int *tep_read_number_field*(struct tep_format_field pass:[*]_field_, const void pass:[*]_data_, unsigned long long pass:[*]_value_);
15--
16
17DESCRIPTION
18-----------
19The _tep_read_number_field()_ function reads the value of the _field_ from the
20raw _data_ and stores it in the _value_. The function sets the _value_ according
21to the endianness of the raw data and the current machine and stores it in
22_value_.
23
24RETURN VALUE
25------------
26The _tep_read_number_field()_ function retunrs 0 in case of success, or -1 in
27case of an error.
28
29EXAMPLE
30-------
31[source,c]
32--
33#include <event-parse.h>
34...
35struct tep_handle *tep = tep_alloc();
36...
37struct tep_event *event = tep_find_event_by_name(tep, "timer", "hrtimer_start");
38...
39void process_record(struct tep_record *record)
40{
41 unsigned long long pid;
42 struct tep_format_field *field_pid = tep_find_common_field(event, "common_pid");
43
44 if (tep_read_number_field(field_pid, record->data, &pid) != 0) {
45 /* Failed to get "common_pid" value */
46 }
47}
48...
49--
50FILES
51-----
52[verse]
53--
54*event-parse.h*
55 Header file to include in order to have access to the library APIs.
56*-ltraceevent*
57 Linker switch to add when building a program that uses the library.
58--
59
60SEE ALSO
61--------
62_libtraceevent(3)_, _trace-cmd(1)_
63
64AUTHOR
65------
66[verse]
67--
68*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
69*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
70--
71REPORTING BUGS
72--------------
73Report bugs to <linux-trace-devel@vger.kernel.org>
74
75LICENSE
76-------
77libtraceevent is Free Software licensed under the GNU LGPL 2.1
78
79RESOURCES
80---------
81https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-fields.txt b/tools/lib/traceevent/Documentation/libtraceevent-fields.txt
new file mode 100644
index 000000000000..1ccb531d5114
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-fields.txt
@@ -0,0 +1,105 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_event_common_fields, tep_event_fields - Get a list of fields for an event.
7
8SYNOPSIS
9--------
10[verse]
11--
12*#include <event-parse.h>*
13
14struct tep_format_field pass:[*]pass:[*]*tep_event_common_fields*(struct tep_event pass:[*]_event_);
15struct tep_format_field pass:[*]pass:[*]*tep_event_fields*(struct tep_event pass:[*]_event_);
16--
17
18DESCRIPTION
19-----------
20The _tep_event_common_fields()_ function returns an array of pointers to common
21fields for the _event_. The array is allocated in the function and must be freed
22by free(). The last element of the array is NULL.
23
24The _tep_event_fields()_ function returns an array of pointers to event specific
25fields for the _event_. The array is allocated in the function and must be freed
26by free(). The last element of the array is NULL.
27
28RETURN VALUE
29------------
30Both _tep_event_common_fields()_ and _tep_event_fields()_ functions return
31an array of pointers to tep_format_field structures in case of success, or
32NULL in case of an error.
33
34EXAMPLE
35-------
36[source,c]
37--
38#include <event-parse.h>
39...
40struct tep_handle *tep = tep_alloc();
41...
42int i;
43struct tep_format_field **fields;
44struct tep_event *event = tep_find_event_by_name(tep, "kvm", "kvm_exit");
45if (event != NULL) {
46 fields = tep_event_common_fields(event);
47 if (fields != NULL) {
48 i = 0;
49 while (fields[i]) {
50 /*
51 walk through the list of the common fields
52 of the kvm_exit event
53 */
54 i++;
55 }
56 free(fields);
57 }
58 fields = tep_event_fields(event);
59 if (fields != NULL) {
60 i = 0;
61 while (fields[i]) {
62 /*
63 walk through the list of the event specific
64 fields of the kvm_exit event
65 */
66 i++;
67 }
68 free(fields);
69 }
70}
71...
72--
73
74FILES
75-----
76[verse]
77--
78*event-parse.h*
79 Header file to include in order to have access to the library APIs.
80*-ltraceevent*
81 Linker switch to add when building a program that uses the library.
82--
83
84SEE ALSO
85--------
86_libtraceevent(3)_, _trace-cmd(1)_
87
88AUTHOR
89------
90[verse]
91--
92*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
93*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
94--
95REPORTING BUGS
96--------------
97Report bugs to <linux-trace-devel@vger.kernel.org>
98
99LICENSE
100-------
101libtraceevent is Free Software licensed under the GNU LGPL 2.1
102
103RESOURCES
104---------
105https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt b/tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt
new file mode 100644
index 000000000000..f401ad311047
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt
@@ -0,0 +1,91 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_is_file_bigendian, tep_set_file_bigendian - Get / set the endianness of the
7raw data being accessed by the tep handler.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15enum *tep_endian* {
16 TEP_LITTLE_ENDIAN = 0,
17 TEP_BIG_ENDIAN
18};
19
20bool *tep_is_file_bigendian*(struct tep_handle pass:[*]_tep_);
21void *tep_set_file_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_);
22
23--
24DESCRIPTION
25-----------
26The _tep_is_file_bigendian()_ function gets the endianness of the raw data,
27being accessed by the tep handler. The _tep_ argument is trace event parser
28context.
29
30The _tep_set_file_bigendian()_ function sets the endianness of raw data being
31accessed by the tep handler. The _tep_ argument is trace event parser context.
32[verse]
33--
34The _endian_ argument is the endianness:
35 _TEP_LITTLE_ENDIAN_ - the raw data is in little endian format,
36 _TEP_BIG_ENDIAN_ - the raw data is in big endian format.
37--
38RETURN VALUE
39------------
40The _tep_is_file_bigendian()_ function returns true if the data is in bigendian
41format, false otherwise.
42
43EXAMPLE
44-------
45[source,c]
46--
47#include <event-parse.h>
48...
49struct tep_handle *tep = tep_alloc();
50...
51 tep_set_file_bigendian(tep, TEP_LITTLE_ENDIAN);
52...
53 if (tep_is_file_bigendian(tep)) {
54 /* The raw data is in big endian */
55 } else {
56 /* The raw data is in little endian */
57 }
58--
59
60FILES
61-----
62[verse]
63--
64*event-parse.h*
65 Header file to include in order to have access to the library APIs.
66*-ltraceevent*
67 Linker switch to add when building a program that uses the library.
68--
69
70SEE ALSO
71--------
72_libtraceevent(3)_, _trace-cmd(1)_
73
74AUTHOR
75------
76[verse]
77--
78*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
79*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
80--
81REPORTING BUGS
82--------------
83Report bugs to <linux-trace-devel@vger.kernel.org>
84
85LICENSE
86-------
87libtraceevent is Free Software licensed under the GNU LGPL 2.1
88
89RESOURCES
90---------
91https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-filter.txt b/tools/lib/traceevent/Documentation/libtraceevent-filter.txt
new file mode 100644
index 000000000000..4a9962d8cb59
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-filter.txt
@@ -0,0 +1,209 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_filter_alloc, tep_filter_free, tep_filter_reset, tep_filter_make_string,
7tep_filter_copy, tep_filter_compare, tep_filter_match, tep_event_filtered,
8tep_filter_remove_event, tep_filter_strerror, tep_filter_add_filter_str -
9Event filter related APIs.
10
11SYNOPSIS
12--------
13[verse]
14--
15*#include <event-parse.h>*
16
17struct tep_event_filter pass:[*]*tep_filter_alloc*(struct tep_handle pass:[*]_tep_);
18void *tep_filter_free*(struct tep_event_filter pass:[*]_filter_);
19void *tep_filter_reset*(struct tep_event_filter pass:[*]_filter_);
20enum tep_errno *tep_filter_add_filter_str*(struct tep_event_filter pass:[*]_filter_, const char pass:[*]_filter_str_);
21int *tep_event_filtered*(struct tep_event_filter pass:[*]_filter_, int _event_id_);
22int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, int _event_id_);
23enum tep_errno *tep_filter_match*(struct tep_event_filter pass:[*]_filter_, struct tep_record pass:[*]_record_);
24int *tep_filter_copy*(struct tep_event_filter pass:[*]_dest_, struct tep_event_filter pass:[*]_source_);
25int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_);
26char pass:[*]*tep_filter_make_string*(struct tep_event_filter pass:[*]_filter_, int _event_id_);
27int *tep_filter_strerror*(struct tep_event_filter pass:[*]_filter_, enum tep_errno _err_, char pass:[*]buf, size_t _buflen_);
28--
29
30DESCRIPTION
31-----------
32Filters can be attached to traced events. They can be used to filter out various
33events when outputting them. Each event can be filtered based on its parameters,
34described in the event's format file. This set of functions can be used to
35create, delete, modify and attach event filters.
36
37The _tep_filter_alloc()_ function creates a new event filter. The _tep_ argument
38is the trace event parser context.
39
40The _tep_filter_free()_ function frees an event filter and all resources that it
41had used.
42
43The _tep_filter_reset()_ function removes all rules from an event filter and
44resets it.
45
46The _tep_filter_add_filter_str()_ function adds a new rule to the _filter_. The
47_filter_str_ argument is the filter string, that contains the rule.
48
49The _tep_event_filtered()_ function checks if the event with _event_id_ has
50_filter_.
51
52The _tep_filter_remove_event()_ function removes a _filter_ for an event with
53_event_id_.
54
55The _tep_filter_match()_ function tests if a _record_ matches given _filter_.
56
57The _tep_filter_copy()_ function copies a _source_ filter into a _dest_ filter.
58
59The _tep_filter_compare()_ function compares two filers - _filter1_ and _filter2_.
60
61The _tep_filter_make_string()_ function constructs a string, displaying
62the _filter_ contents for given _event_id_.
63
64The _tep_filter_strerror()_ function copies the _filter_ error buffer into the
65given _buf_ with the size _buflen_. If the error buffer is empty, in the _buf_
66is copied a string, describing the error _err_.
67
68RETURN VALUE
69------------
70The _tep_filter_alloc()_ function returns a pointer to the newly created event
71filter, or NULL in case of an error.
72
73The _tep_filter_add_filter_str()_ function returns 0 if the rule was
74successfully added or a negative error code. Use _tep_filter_strerror()_ to see
75actual error message in case of an error.
76
77The _tep_event_filtered()_ function returns 1 if the filter is found for given
78event, or 0 otherwise.
79
80The _tep_filter_remove_event()_ function returns 1 if the vent was removed, or
810 if the event was not found.
82
83The _tep_filter_match()_ function returns _tep_errno_, according to the result:
84[verse]
85--
86_pass:[TEP_ERRNO__FILTER_MATCH]_ - filter found for event, the record matches.
87_pass:[TEP_ERRNO__FILTER_MISS]_ - filter found for event, the record does not match.
88_pass:[TEP_ERRNO__FILTER_NOT_FOUND]_ - no filter found for record's event.
89_pass:[TEP_ERRNO__NO_FILTER]_ - no rules in the filter.
90--
91or any other _tep_errno_, if an error occurred during the test.
92
93The _tep_filter_copy()_ function returns 0 on success or -1 if not all rules
94 were copied.
95
96The _tep_filter_compare()_ function returns 1 if the two filters hold the same
97content, or 0 if they do not.
98
99The _tep_filter_make_string()_ function returns a string, which must be freed
100with free(), or NULL in case of an error.
101
102The _tep_filter_strerror()_ function returns 0 if message was filled
103successfully, or -1 in case of an error.
104
105EXAMPLE
106-------
107[source,c]
108--
109#include <event-parse.h>
110...
111struct tep_handle *tep = tep_alloc();
112...
113char errstr[200];
114int ret;
115
116struct tep_event_filter *filter = tep_filter_alloc(tep);
117struct tep_event_filter *filter1 = tep_filter_alloc(tep);
118ret = tep_filter_add_filter_str(filter, "sched/sched_wakeup:target_cpu==1");
119if(ret < 0) {
120 tep_filter_strerror(filter, ret, errstr, sizeof(errstr));
121 /* Failed to add a new rule to the filter, the error string is in errstr */
122}
123if (tep_filter_copy(filter1, filter) != 0) {
124 /* Failed to copy filter in filter1 */
125}
126...
127if (tep_filter_compare(filter, filter1) != 1) {
128 /* Both filters are different */
129}
130...
131void process_record(struct tep_handle *tep, struct tep_record *record)
132{
133 struct tep_event *event;
134 char *fstring;
135
136 event = tep_find_event_by_record(tep, record);
137
138 if (tep_event_filtered(filter, event->id) == 1) {
139 /* The event has filter */
140 fstring = tep_filter_make_string(filter, event->id);
141 if (fstring != NULL) {
142 /* The filter for the event is in fstring */
143 free(fstring);
144 }
145 }
146
147 switch (tep_filter_match(filter, record)) {
148 case TEP_ERRNO__FILTER_MATCH:
149 /* The filter matches the record */
150 break;
151 case TEP_ERRNO__FILTER_MISS:
152 /* The filter does not match the record */
153 break;
154 case TEP_ERRNO__FILTER_NOT_FOUND:
155 /* No filter found for record's event */
156 break;
157 case TEP_ERRNO__NO_FILTER:
158 /* There are no rules in the filter */
159 break
160 default:
161 /* An error occurred during the test */
162 break;
163 }
164
165 if (tep_filter_remove_event(filter, event->id) == 1) {
166 /* The event was removed from the filter */
167 }
168}
169
170...
171tep_filter_reset(filter);
172...
173tep_filter_free(filter);
174tep_filter_free(filter1);
175...
176--
177
178FILES
179-----
180[verse]
181--
182*event-parse.h*
183 Header file to include in order to have access to the library APIs.
184*-ltraceevent*
185 Linker switch to add when building a program that uses the library.
186--
187
188SEE ALSO
189--------
190_libtraceevent(3)_, _trace-cmd(1)_
191
192AUTHOR
193------
194[verse]
195--
196*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
197*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
198--
199REPORTING BUGS
200--------------
201Report bugs to <linux-trace-devel@vger.kernel.org>
202
203LICENSE
204-------
205libtraceevent is Free Software licensed under the GNU LGPL 2.1
206
207RESOURCES
208---------
209https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt b/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt
new file mode 100644
index 000000000000..38bfea30a5f6
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt
@@ -0,0 +1,183 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_find_function, tep_find_function_address, tep_set_function_resolver,
7tep_reset_function_resolver, tep_register_function, tep_register_print_string -
8function related tep APIs
9
10SYNOPSIS
11--------
12[verse]
13--
14*#include <event-parse.h>*
15
16typedef char pass:[*](*tep_func_resolver_t*)(void pass:[*]_priv_, unsigned long long pass:[*]_addrp_, char pass:[**]_modp_);
17int *tep_set_function_resolver*(struct tep_handle pass:[*]_tep_, tep_func_resolver_t pass:[*]_func_, void pass:[*]_priv_);
18void *tep_reset_function_resolver*(struct tep_handle pass:[*]_tep_);
19const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_);
20unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_);
21int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_);
22int *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const char pass:[*]_fmt_, unsigned long long _addr_);
23--
24
25DESCRIPTION
26-----------
27Some tools may have already a way to resolve the kernel functions. These APIs
28allow them to keep using it instead of duplicating all the entries inside.
29
30The _tep_func_resolver_t_ type is the prototype of the alternative kernel
31functions resolver. This function receives a pointer to its custom context
32(set with the _tep_set_function_resolver()_ call ) and the address of a kernel
33function, which has to be resolved. In case of success, it should return
34the name of the function and its module (if any) in _modp_.
35
36The _tep_set_function_resolver()_ function registers _func_ as an alternative
37kernel functions resolver. The _tep_ argument is trace event parser context.
38The _priv_ argument is a custom context of the _func_ function. The function
39resolver is used by the APIs _tep_find_function()_,
40_tep_find_function_address()_, and _tep_print_func_field()_ to resolve
41a function address to a function name.
42
43The _tep_reset_function_resolver()_ function resets the kernel functions
44resolver to the default function. The _tep_ argument is trace event parser
45context.
46
47
48These APIs can be used to find function name and start address, by given
49address. The given address does not have to be exact, it will select
50the function that would contain it.
51
52The _tep_find_function()_ function returns the function name, which contains the
53given address _addr_. The _tep_ argument is the trace event parser context.
54
55The _tep_find_function_address()_ function returns the function start address,
56by given address _addr_. The _addr_ does not have to be exact, it will select
57the function that would contain it. The _tep_ argument is the trace event
58parser context.
59
60The _tep_register_function()_ function registers a function name mapped to an
61address and (optional) module. This mapping is used in case the function tracer
62or events have "%pF" or "%pS" parameter in its format string. It is common to
63pass in the kallsyms function names with their corresponding addresses with this
64function. The _tep_ argument is the trace event parser context. The _name_ is
65the name of the function, the string is copied internally. The _addr_ is
66the start address of the function. The _mod_ is the kernel module
67the function may be in (NULL for none).
68
69The _tep_register_print_string()_ function registers a string by the address
70it was stored in the kernel. Some strings internal to the kernel with static
71address are passed to certain events. The "%s" in the event's format field
72which has an address needs to know what string would be at that address. The
73tep_register_print_string() supplies the parsing with the mapping between kernel
74addresses and those strings. The _tep_ argument is the trace event parser
75context. The _fmt_ is the string to register, it is copied internally.
76The _addr_ is the address the string was located at.
77
78
79RETURN VALUE
80------------
81The _tep_set_function_resolver()_ function returns 0 in case of success, or -1
82in case of an error.
83
84The _tep_find_function()_ function returns the function name, or NULL in case
85it cannot be found.
86
87The _tep_find_function_address()_ function returns the function start address,
88or 0 in case it cannot be found.
89
90The _tep_register_function()_ function returns 0 in case of success. In case of
91an error -1 is returned, and errno is set to the appropriate error number.
92
93The _tep_register_print_string()_ function returns 0 in case of success. In case
94of an error -1 is returned, and errno is set to the appropriate error number.
95
96EXAMPLE
97-------
98[source,c]
99--
100#include <event-parse.h>
101...
102struct tep_handle *tep = tep_alloc();
103...
104char *my_resolve_kernel_addr(void *context,
105 unsigned long long *addrp, char **modp)
106{
107 struct db *function_database = context;
108 struct symbol *sym = sql_lookup(function_database, *addrp);
109
110 if (!sym)
111 return NULL;
112
113 *modp = sym->module_name;
114 return sym->name;
115}
116
117void show_function( unsigned long long addr)
118{
119 unsigned long long fstart;
120 const char *fname;
121
122 if (tep_set_function_resolver(tep, my_resolve_kernel_addr,
123 function_database) != 0) {
124 /* failed to register my_resolve_kernel_addr */
125 }
126
127 /* These APIs use my_resolve_kernel_addr() to resolve the addr */
128 fname = tep_find_function(tep, addr);
129 fstart = tep_find_function_address(tep, addr);
130
131 /*
132 addr is in function named fname, starting at fstart address,
133 at offset (addr - fstart)
134 */
135
136 tep_reset_function_resolver(tep);
137
138}
139...
140 if (tep_register_function(tep, "kvm_exit",
141 (unsigned long long) 0x12345678, "kvm") != 0) {
142 /* Failed to register kvm_exit address mapping */
143 }
144...
145 if (tep_register_print_string(tep, "print string",
146 (unsigned long long) 0x87654321, NULL) != 0) {
147 /* Failed to register "print string" address mapping */
148 }
149...
150--
151
152FILES
153-----
154[verse]
155--
156*event-parse.h*
157 Header file to include in order to have access to the library APIs.
158*-ltraceevent*
159 Linker switch to add when building a program that uses the library.
160--
161
162SEE ALSO
163--------
164_libtraceevent(3)_, _trace-cmd(1)_
165
166AUTHOR
167------
168[verse]
169--
170*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
171*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
172--
173REPORTING BUGS
174--------------
175Report bugs to <linux-trace-devel@vger.kernel.org>
176
177LICENSE
178-------
179libtraceevent is Free Software licensed under the GNU LGPL 2.1
180
181RESOURCES
182---------
183https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-func_find.txt b/tools/lib/traceevent/Documentation/libtraceevent-func_find.txt
new file mode 100644
index 000000000000..04840e244445
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-func_find.txt
@@ -0,0 +1,88 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_find_function,tep_find_function_address - Find function name / start address.
7
8SYNOPSIS
9--------
10[verse]
11--
12*#include <event-parse.h>*
13
14const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_);
15unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_);
16--
17
18DESCRIPTION
19-----------
20These functions can be used to find function name and start address, by given
21address. The given address does not have to be exact, it will select the function
22that would contain it.
23
24The _tep_find_function()_ function returns the function name, which contains the
25given address _addr_. The _tep_ argument is the trace event parser context.
26
27The _tep_find_function_address()_ function returns the function start address,
28by given address _addr_. The _addr_ does not have to be exact, it will select the
29function that would contain it. The _tep_ argument is the trace event parser context.
30
31RETURN VALUE
32------------
33The _tep_find_function()_ function returns the function name, or NULL in case
34it cannot be found.
35
36The _tep_find_function_address()_ function returns the function start address,
37or 0 in case it cannot be found.
38
39EXAMPLE
40-------
41[source,c]
42--
43#include <event-parse.h>
44...
45struct tep_handle *tep = tep_alloc();
46...
47void show_function( unsigned long long addr)
48{
49 const char *fname = tep_find_function(tep, addr);
50 unsigned long long fstart = tep_find_function_address(tep, addr);
51
52 /* addr is in function named fname, starting at fstart address, at offset (addr - fstart) */
53}
54...
55--
56
57FILES
58-----
59[verse]
60--
61*event-parse.h*
62 Header file to include in order to have access to the library APIs.
63*-ltraceevent*
64 Linker switch to add when building a program that uses the library.
65--
66
67SEE ALSO
68--------
69_libtraceevent(3)_, _trace-cmd(1)_
70
71AUTHOR
72------
73[verse]
74--
75*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
76*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
77--
78REPORTING BUGS
79--------------
80Report bugs to <linux-trace-devel@vger.kernel.org>
81
82LICENSE
83-------
84libtraceevent is Free Software licensed under the GNU LGPL 2.1
85
86RESOURCES
87---------
88https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-handle.txt b/tools/lib/traceevent/Documentation/libtraceevent-handle.txt
new file mode 100644
index 000000000000..8d568316847d
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-handle.txt
@@ -0,0 +1,101 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_alloc, tep_free,tep_ref, tep_unref,tep_ref_get - Create, destroy, manage
7references of trace event parser context.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15struct tep_handle pass:[*]*tep_alloc*(void);
16void *tep_free*(struct tep_handle pass:[*]_tep_);
17void *tep_ref*(struct tep_handle pass:[*]_tep_);
18void *tep_unref*(struct tep_handle pass:[*]_tep_);
19int *tep_ref_get*(struct tep_handle pass:[*]_tep_);
20--
21
22DESCRIPTION
23-----------
24These are the main functions to create and destroy tep_handle - the main
25structure, representing the trace event parser context. This context is used as
26the input parameter of most library APIs.
27
28The _tep_alloc()_ function allocates and initializes the tep context.
29
30The _tep_free()_ function will decrement the reference of the _tep_ handler.
31When there is no more references, then it will free the handler, as well
32as clean up all its resources that it had used. The argument _tep_ is
33the pointer to the trace event parser context.
34
35The _tep_ref()_ function adds a reference to the _tep_ handler.
36
37The _tep_unref()_ function removes a reference from the _tep_ handler. When
38the last reference is removed, the _tep_ is destroyed, and all resources that
39it had used are cleaned up.
40
41The _tep_ref_get()_ functions gets the current references of the _tep_ handler.
42
43RETURN VALUE
44------------
45_tep_alloc()_ returns a pointer to a newly created tep_handle structure.
46NULL is returned in case there is not enough free memory to allocate it.
47
48_tep_ref_get()_ returns the current references of _tep_.
49If _tep_ is NULL, 0 is returned.
50
51EXAMPLE
52-------
53[source,c]
54--
55#include <event-parse.h>
56
57...
58struct tep_handle *tep = tep_alloc();
59...
60int ref = tep_ref_get(tep);
61tep_ref(tep);
62if ( (ref+1) != tep_ref_get(tep)) {
63 /* Something wrong happened, the counter is not incremented by 1 */
64}
65tep_unref(tep);
66...
67tep_free(tep);
68...
69--
70FILES
71-----
72[verse]
73--
74*event-parse.h*
75 Header file to include in order to have access to the library APIs.
76*-ltraceevent*
77 Linker switch to add when building a program that uses the library.
78--
79
80SEE ALSO
81--------
82_libtraceevent(3)_, _trace-cmd(1)_
83
84AUTHOR
85------
86[verse]
87--
88*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
89*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
90--
91REPORTING BUGS
92--------------
93Report bugs to <linux-trace-devel@vger.kernel.org>
94
95LICENSE
96-------
97libtraceevent is Free Software licensed under the GNU LGPL 2.1
98
99RESOURCES
100---------
101https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-header_page.txt b/tools/lib/traceevent/Documentation/libtraceevent-header_page.txt
new file mode 100644
index 000000000000..615d117dc39f
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-header_page.txt
@@ -0,0 +1,102 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_get_header_page_size, tep_get_header_timestamp_size, tep_is_old_format -
7Get the data stored in the header page, in kernel context.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_);
16int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_);
17bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_);
18--
19DESCRIPTION
20-----------
21These functions retrieve information from kernel context, stored in tracefs
22events/header_page. Old kernels do not have header page info, so default values
23from user space context are used.
24
25The _tep_get_header_page_size()_ function returns the size of a long integer,
26in kernel context. The _tep_ argument is trace event parser context.
27This information is retrieved from tracefs events/header_page, "commit" field.
28
29The _tep_get_header_timestamp_size()_ function returns the size of timestamps,
30in kernel context. The _tep_ argument is trace event parser context. This
31information is retrieved from tracefs events/header_page, "timestamp" field.
32
33The _tep_is_old_format()_ function returns true if the kernel predates
34the addition of events/header_page, otherwise it returns false.
35
36RETURN VALUE
37------------
38The _tep_get_header_page_size()_ function returns the size of a long integer,
39in bytes.
40
41The _tep_get_header_timestamp_size()_ function returns the size of timestamps,
42in bytes.
43
44The _tep_is_old_format()_ function returns true, if an old kernel is used to
45generate the tracing data, which has no event/header_page. If the kernel is new,
46or _tep_ is NULL, false is returned.
47
48EXAMPLE
49-------
50[source,c]
51--
52#include <event-parse.h>
53...
54struct tep_handle *tep = tep_alloc();
55...
56 int longsize;
57 int timesize;
58 bool old;
59
60 longsize = tep_get_header_page_size(tep);
61 timesize = tep_get_header_timestamp_size(tep);
62 old = tep_is_old_format(tep);
63
64 printf ("%s kernel is used to generate the tracing data.\n",
65 old?"Old":"New");
66 printf("The size of a long integer is %d bytes.\n", longsize);
67 printf("The timestamps size is %d bytes.\n", timesize);
68...
69--
70
71FILES
72-----
73[verse]
74--
75*event-parse.h*
76 Header file to include in order to have access to the library APIs.
77*-ltraceevent*
78 Linker switch to add when building a program that uses the library.
79--
80
81SEE ALSO
82--------
83_libtraceevent(3)_, _trace-cmd(1)_
84
85AUTHOR
86------
87[verse]
88--
89*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
90*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
91--
92REPORTING BUGS
93--------------
94Report bugs to <linux-trace-devel@vger.kernel.org>
95
96LICENSE
97-------
98libtraceevent is Free Software licensed under the GNU LGPL 2.1
99
100RESOURCES
101---------
102https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt b/tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt
new file mode 100644
index 000000000000..d5d375eb8d1e
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt
@@ -0,0 +1,104 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_is_bigendian, tep_is_local_bigendian, tep_set_local_bigendian - Get / set
7the endianness of the local machine.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15enum *tep_endian* {
16 TEP_LITTLE_ENDIAN = 0,
17 TEP_BIG_ENDIAN
18};
19
20int *tep_is_bigendian*(void);
21bool *tep_is_local_bigendian*(struct tep_handle pass:[*]_tep_);
22void *tep_set_local_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_);
23--
24
25DESCRIPTION
26-----------
27
28The _tep_is_bigendian()_ gets the endianness of the machine, executing
29the function.
30
31The _tep_is_local_bigendian()_ function gets the endianness of the local
32machine, saved in the _tep_ handler. The _tep_ argument is the trace event
33parser context. This API is a bit faster than _tep_is_bigendian()_, as it
34returns cached endianness of the local machine instead of checking it each time.
35
36The _tep_set_local_bigendian()_ function sets the endianness of the local
37machine in the _tep_ handler. The _tep_ argument is trace event parser context.
38The _endian_ argument is the endianness:
39[verse]
40--
41 _TEP_LITTLE_ENDIAN_ - the machine is little endian,
42 _TEP_BIG_ENDIAN_ - the machine is big endian.
43--
44
45RETURN VALUE
46------------
47The _tep_is_bigendian()_ function returns non zero if the endianness of the
48machine, executing the code, is big endian and zero otherwise.
49
50The _tep_is_local_bigendian()_ function returns true, if the endianness of the
51local machine, saved in the _tep_ handler, is big endian, or false otherwise.
52
53EXAMPLE
54-------
55[source,c]
56--
57#include <event-parse.h>
58...
59struct tep_handle *tep = tep_alloc();
60...
61 if (tep_is_bigendian())
62 tep_set_local_bigendian(tep, TEP_BIG_ENDIAN);
63 else
64 tep_set_local_bigendian(tep, TEP_LITTLE_ENDIAN);
65...
66 if (tep_is_local_bigendian(tep))
67 printf("This machine you are running on is bigendian\n");
68 else
69 printf("This machine you are running on is little endian\n");
70
71--
72
73FILES
74-----
75[verse]
76--
77*event-parse.h*
78 Header file to include in order to have access to the library APIs.
79*-ltraceevent*
80 Linker switch to add when building a program that uses the library.
81--
82
83SEE ALSO
84--------
85_libtraceevent(3)_, _trace-cmd(1)_
86
87AUTHOR
88------
89[verse]
90--
91*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
92*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
93--
94REPORTING BUGS
95--------------
96Report bugs to <linux-trace-devel@vger.kernel.org>
97
98LICENSE
99-------
100libtraceevent is Free Software licensed under the GNU LGPL 2.1
101
102RESOURCES
103---------
104https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-long_size.txt b/tools/lib/traceevent/Documentation/libtraceevent-long_size.txt
new file mode 100644
index 000000000000..01d78ea2519a
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-long_size.txt
@@ -0,0 +1,78 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_get_long_size, tep_set_long_size - Get / set the size of a long integer on
7the machine, where the trace is generated, in bytes
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15int *tep_get_long_size*(strucqt tep_handle pass:[*]_tep_);
16void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_);
17--
18
19DESCRIPTION
20-----------
21The _tep_get_long_size()_ function returns the size of a long integer on the machine,
22where the trace is generated. The _tep_ argument is trace event parser context.
23
24The _tep_set_long_size()_ function sets the size of a long integer on the machine,
25where the trace is generated. The _tep_ argument is trace event parser context.
26The _long_size_ is the size of a long integer, in bytes.
27
28RETURN VALUE
29------------
30The _tep_get_long_size()_ function returns the size of a long integer on the machine,
31where the trace is generated, in bytes.
32
33EXAMPLE
34-------
35[source,c]
36--
37#include <event-parse.h>
38...
39struct tep_handle *tep = tep_alloc();
40...
41tep_set_long_size(tep, 4);
42...
43int long_size = tep_get_long_size(tep);
44...
45--
46
47FILES
48-----
49[verse]
50--
51*event-parse.h*
52 Header file to include in order to have access to the library APIs.
53*-ltraceevent*
54 Linker switch to add when building a program that uses the library.
55--
56
57SEE ALSO
58--------
59_libtraceevent(3)_, _trace-cmd(1)_
60
61AUTHOR
62------
63[verse]
64--
65*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
66*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
67--
68REPORTING BUGS
69--------------
70Report bugs to <linux-trace-devel@vger.kernel.org>
71
72LICENSE
73-------
74libtraceevent is Free Software licensed under the GNU LGPL 2.1
75
76RESOURCES
77---------
78https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-page_size.txt b/tools/lib/traceevent/Documentation/libtraceevent-page_size.txt
new file mode 100644
index 000000000000..452c0cfa1822
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-page_size.txt
@@ -0,0 +1,82 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_get_page_size, tep_set_page_size - Get / set the size of a memory page on
7the machine, where the trace is generated
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15int *tep_get_page_size*(struct tep_handle pass:[*]_tep_);
16void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_);
17--
18
19DESCRIPTION
20-----------
21The _tep_get_page_size()_ function returns the size of a memory page on
22the machine, where the trace is generated. The _tep_ argument is trace
23event parser context.
24
25The _tep_set_page_size()_ function stores in the _tep_ context the size of a
26memory page on the machine, where the trace is generated.
27The _tep_ argument is trace event parser context.
28The _page_size_ argument is the size of a memory page, in bytes.
29
30RETURN VALUE
31------------
32The _tep_get_page_size()_ function returns size of the memory page, in bytes.
33
34EXAMPLE
35-------
36[source,c]
37--
38#include <unistd.h>
39#include <event-parse.h>
40...
41struct tep_handle *tep = tep_alloc();
42...
43 int page_size = getpagesize();
44
45 tep_set_page_size(tep, page_size);
46
47 printf("The page size for this machine is %d\n", tep_get_page_size(tep));
48
49--
50
51FILES
52-----
53[verse]
54--
55*event-parse.h*
56 Header file to include in order to have access to the library APIs.
57*-ltraceevent*
58 Linker switch to add when building a program that uses the library.
59--
60
61SEE ALSO
62--------
63_libtraceevent(3)_, _trace-cmd(1)_
64
65AUTHOR
66------
67[verse]
68--
69*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
70*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
71--
72REPORTING BUGS
73--------------
74Report bugs to <linux-trace-devel@vger.kernel.org>
75
76LICENSE
77-------
78libtraceevent is Free Software licensed under the GNU LGPL 2.1
79
80RESOURCES
81---------
82https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt b/tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt
new file mode 100644
index 000000000000..f248114ca1ff
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt
@@ -0,0 +1,90 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_parse_event, tep_parse_format - Parse the event format information
7
8SYNOPSIS
9--------
10[verse]
11--
12*#include <event-parse.h>*
13
14enum tep_errno *tep_parse_event*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_);
15enum tep_errno *tep_parse_format*(struct tep_handle pass:[*]_tep_, struct tep_event pass:[*]pass:[*]_eventp_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_);
16--
17
18DESCRIPTION
19-----------
20The _tep_parse_event()_ function parses the event format and creates an event
21structure to quickly parse raw data for a given event. The _tep_ argument is
22the trace event parser context. The created event structure is stored in the
23_tep_ context. The _buf_ argument is a buffer with _size_, where the event
24format data is. The event format data can be taken from
25tracefs/events/.../.../format files. The _sys_ argument is the system of
26the event.
27
28The _tep_parse_format()_ function does the same as _tep_parse_event()_. The only
29difference is in the extra _eventp_ argument, where the newly created event
30structure is returned.
31
32RETURN VALUE
33------------
34Both _tep_parse_event()_ and _tep_parse_format()_ functions return 0 on success,
35or TEP_ERRNO__... in case of an error.
36
37EXAMPLE
38-------
39[source,c]
40--
41#include <event-parse.h>
42...
43struct tep_handle *tep = tep_alloc();
44...
45char *buf;
46int size;
47struct tep_event *event = NULL;
48buf = read_file("/sys/kernel/tracing/events/ftrace/print/format", &size);
49if (tep_parse_event(tep, buf, size, "ftrace") != 0) {
50 /* Failed to parse the ftrace print format */
51}
52
53if (tep_parse_format(tep, &event, buf, size, "ftrace") != 0) {
54 /* Failed to parse the ftrace print format */
55}
56...
57--
58
59FILES
60-----
61[verse]
62--
63*event-parse.h*
64 Header file to include in order to have access to the library APIs.
65*-ltraceevent*
66 Linker switch to add when building a program that uses the library.
67--
68
69SEE ALSO
70--------
71_libtraceevent(3)_, _trace-cmd(1)_
72
73AUTHOR
74------
75[verse]
76--
77*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
78*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
79--
80REPORTING BUGS
81--------------
82Report bugs to <linux-trace-devel@vger.kernel.org>
83
84LICENSE
85-------
86libtraceevent is Free Software licensed under the GNU LGPL 2.1
87
88RESOURCES
89---------
90https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt b/tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt
new file mode 100644
index 000000000000..c90f16c7d8e6
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt
@@ -0,0 +1,82 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_parse_header_page - Parses the data stored in the header page.
7
8SYNOPSIS
9--------
10[verse]
11--
12*#include <event-parse.h>*
13
14int *tep_parse_header_page*(struct tep_handle pass:[*]_tep_, char pass:[*]_buf_, unsigned long _size_, int _long_size_);
15--
16
17DESCRIPTION
18-----------
19The _tep_parse_header_page()_ function parses the header page data from _buf_,
20and initializes the _tep_, trace event parser context, with it. The buffer
21_buf_ is with _size_, and is supposed to be copied from
22tracefs/events/header_page.
23
24Some old kernels do not have header page info, in this case the
25_tep_parse_header_page()_ function can be called with _size_ equal to 0. The
26_tep_ context is initialized with default values. The _long_size_ can be used in
27this use case, to set the size of a long integer to be used.
28
29RETURN VALUE
30------------
31The _tep_parse_header_page()_ function returns 0 in case of success, or -1
32in case of an error.
33
34EXAMPLE
35-------
36[source,c]
37--
38#include <event-parse.h>
39...
40struct tep_handle *tep = tep_alloc();
41...
42char *buf;
43int size;
44buf = read_file("/sys/kernel/tracing/events/header_page", &size);
45if (tep_parse_header_page(tep, buf, size, sizeof(unsigned long)) != 0) {
46 /* Failed to parse the header page */
47}
48...
49--
50
51FILES
52-----
53[verse]
54--
55*event-parse.h*
56 Header file to include in order to have access to the library APIs.
57*-ltraceevent*
58 Linker switch to add when building a program that uses the library.
59--
60
61SEE ALSO
62--------
63_libtraceevent(3)_, _trace-cmd(1)_
64
65AUTHOR
66------
67[verse]
68--
69*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
70*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
71--
72REPORTING BUGS
73--------------
74Report bugs to <linux-trace-devel@vger.kernel.org>
75
76LICENSE
77-------
78libtraceevent is Free Software licensed under the GNU LGPL 2.1
79
80RESOURCES
81---------
82https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt b/tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt
new file mode 100644
index 000000000000..e9a69116c78b
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt
@@ -0,0 +1,137 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_data_type, tep_data_pid,tep_data_preempt_count, tep_data_flags -
7Extract common fields from a record.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15enum *trace_flag_type* {
16 _TRACE_FLAG_IRQS_OFF_,
17 _TRACE_FLAG_IRQS_NOSUPPORT_,
18 _TRACE_FLAG_NEED_RESCHED_,
19 _TRACE_FLAG_HARDIRQ_,
20 _TRACE_FLAG_SOFTIRQ_,
21};
22
23int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
24int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
25int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
26int *tep_data_flags*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
27--
28
29DESCRIPTION
30-----------
31This set of functions can be used to extract common fields from a record.
32
33The _tep_data_type()_ function gets the event id from the record _rec_.
34It reads the "common_type" field. The _tep_ argument is the trace event parser
35context.
36
37The _tep_data_pid()_ function gets the process id from the record _rec_.
38It reads the "common_pid" field. The _tep_ argument is the trace event parser
39context.
40
41The _tep_data_preempt_count()_ function gets the preemption count from the
42record _rec_. It reads the "common_preempt_count" field. The _tep_ argument is
43the trace event parser context.
44
45The _tep_data_flags()_ function gets the latency flags from the record _rec_.
46It reads the "common_flags" field. The _tep_ argument is the trace event parser
47context. Supported latency flags are:
48[verse]
49--
50 _TRACE_FLAG_IRQS_OFF_, Interrupts are disabled.
51 _TRACE_FLAG_IRQS_NOSUPPORT_, Reading IRQ flag is not supported by the architecture.
52 _TRACE_FLAG_NEED_RESCHED_, Task needs rescheduling.
53 _TRACE_FLAG_HARDIRQ_, Hard IRQ is running.
54 _TRACE_FLAG_SOFTIRQ_, Soft IRQ is running.
55--
56
57RETURN VALUE
58------------
59The _tep_data_type()_ function returns an integer, representing the event id.
60
61The _tep_data_pid()_ function returns an integer, representing the process id
62
63The _tep_data_preempt_count()_ function returns an integer, representing the
64preemption count.
65
66The _tep_data_flags()_ function returns an integer, representing the latency
67flags. Look at the _trace_flag_type_ enum for supported flags.
68
69All these functions in case of an error return a negative integer.
70
71EXAMPLE
72-------
73[source,c]
74--
75#include <event-parse.h>
76...
77struct tep_handle *tep = tep_alloc();
78...
79void process_record(struct tep_record *record)
80{
81 int data;
82
83 data = tep_data_type(tep, record);
84 if (data >= 0) {
85 /* Got the ID of the event */
86 }
87
88 data = tep_data_pid(tep, record);
89 if (data >= 0) {
90 /* Got the process ID */
91 }
92
93 data = tep_data_preempt_count(tep, record);
94 if (data >= 0) {
95 /* Got the preemption count */
96 }
97
98 data = tep_data_flags(tep, record);
99 if (data >= 0) {
100 /* Got the latency flags */
101 }
102}
103...
104--
105
106FILES
107-----
108[verse]
109--
110*event-parse.h*
111 Header file to include in order to have access to the library APIs.
112*-ltraceevent*
113 Linker switch to add when building a program that uses the library.
114--
115
116SEE ALSO
117--------
118_libtraceevent(3)_, _trace-cmd(1)_
119
120AUTHOR
121------
122[verse]
123--
124*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
125*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
126--
127REPORTING BUGS
128--------------
129Report bugs to <linux-trace-devel@vger.kernel.org>
130
131LICENSE
132-------
133libtraceevent is Free Software licensed under the GNU LGPL 2.1
134
135RESOURCES
136---------
137https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt b/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt
new file mode 100644
index 000000000000..53d37d72a1c1
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt
@@ -0,0 +1,156 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_register_event_handler, tep_unregister_event_handler - Register /
7unregisters a callback function to parse an event information.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15enum *tep_reg_handler* {
16 _TEP_REGISTER_SUCCESS_,
17 _TEP_REGISTER_SUCCESS_OVERWRITE_,
18};
19
20int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_);
21int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_);
22
23typedef int (*pass:[*]tep_event_handler_func*)(struct trace_seq pass:[*]s, struct tep_record pass:[*]record, struct tep_event pass:[*]event, void pass:[*]context);
24--
25
26DESCRIPTION
27-----------
28The _tep_register_event_handler()_ function registers a handler function,
29which is going to be called to parse the information for a given event.
30The _tep_ argument is the trace event parser context. The _id_ argument is
31the id of the event. The _sys_name_ argument is the name of the system,
32the event belongs to. The _event_name_ argument is the name of the event.
33If _id_ is >= 0, it is used to find the event, otherwise _sys_name_ and
34_event_name_ are used. The _func_ is a pointer to the function, which is going
35to be called to parse the event information. The _context_ argument is a pointer
36to the context data, which will be passed to the _func_. If a handler function
37for the same event is already registered, it will be overridden with the new
38one. This mechanism allows a developer to override the parsing of a given event.
39If for some reason the default print format is not sufficient, the developer
40can register a function for an event to be used to parse the data instead.
41
42The _tep_unregister_event_handler()_ function unregisters the handler function,
43previously registered with _tep_register_event_handler()_. The _tep_ argument
44is the trace event parser context. The _id_, _sys_name_, _event_name_, _func_,
45and _context_ are the same arguments, as when the callback function _func_ was
46registered.
47
48The _tep_event_handler_func_ is the type of the custom event handler
49function. The _s_ argument is the trace sequence, it can be used to create a
50custom string, describing the event. A _record_ to get the event from is passed
51as input parameter and also the _event_ - the handle to the record's event. The
52_context_ is custom context, set when the custom event handler is registered.
53
54RETURN VALUE
55------------
56The _tep_register_event_handler()_ function returns _TEP_REGISTER_SUCCESS_
57if the new handler is registered successfully or
58_TEP_REGISTER_SUCCESS_OVERWRITE_ if an existing handler is overwritten.
59If there is not enough memory to complete the registration,
60TEP_ERRNO__MEM_ALLOC_FAILED is returned.
61
62The _tep_unregister_event_handler()_ function returns 0 if _func_ was removed
63successful or, -1 if the event was not found.
64
65The _tep_event_handler_func_ should return -1 in case of an error,
66or 0 otherwise.
67
68EXAMPLE
69-------
70[source,c]
71--
72#include <event-parse.h>
73#include <trace-seq.h>
74...
75struct tep_handle *tep = tep_alloc();
76...
77int timer_expire_handler(struct trace_seq *s, struct tep_record *record,
78 struct tep_event *event, void *context)
79{
80 trace_seq_printf(s, "hrtimer=");
81
82 if (tep_print_num_field(s, "0x%llx", event, "timer", record, 0) == -1)
83 tep_print_num_field(s, "0x%llx", event, "hrtimer", record, 1);
84
85 trace_seq_printf(s, " now=");
86
87 tep_print_num_field(s, "%llu", event, "now", record, 1);
88
89 tep_print_func_field(s, " function=%s", event, "function", record, 0);
90
91 return 0;
92}
93...
94 int ret;
95
96 ret = tep_register_event_handler(tep, -1, "timer", "hrtimer_expire_entry",
97 timer_expire_handler, NULL);
98 if (ret < 0) {
99 char buf[32];
100
101 tep_strerror(tep, ret, buf, 32)
102 printf("Failed to register handler for hrtimer_expire_entry: %s\n", buf);
103 } else {
104 switch (ret) {
105 case TEP_REGISTER_SUCCESS:
106 printf ("Registered handler for hrtimer_expire_entry\n");
107 break;
108 case TEP_REGISTER_SUCCESS_OVERWRITE:
109 printf ("Overwrote handler for hrtimer_expire_entry\n");
110 break;
111 }
112 }
113...
114 ret = tep_unregister_event_handler(tep, -1, "timer", "hrtimer_expire_entry",
115 timer_expire_handler, NULL);
116 if ( ret )
117 printf ("Failed to unregister handler for hrtimer_expire_entry\n");
118
119--
120
121FILES
122-----
123[verse]
124--
125*event-parse.h*
126 Header file to include in order to have access to the library APIs.
127*trace-seq.h*
128 Header file to include in order to have access to trace sequences
129 related APIs. Trace sequences are used to allow a function to call
130 several other functions to create a string of data to use.
131*-ltraceevent*
132 Linker switch to add when building a program that uses the library.
133--
134
135SEE ALSO
136--------
137_libtraceevent(3)_, _trace-cmd(1)_
138
139AUTHOR
140------
141[verse]
142--
143*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
144*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
145--
146REPORTING BUGS
147--------------
148Report bugs to <linux-trace-devel@vger.kernel.org>
149
150LICENSE
151-------
152libtraceevent is Free Software licensed under the GNU LGPL 2.1
153
154RESOURCES
155---------
156https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt b/tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt
new file mode 100644
index 000000000000..708dce91ebd8
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt
@@ -0,0 +1,155 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_register_print_function,tep_unregister_print_function -
7Registers / Unregisters a helper function.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15enum *tep_func_arg_type* {
16 TEP_FUNC_ARG_VOID,
17 TEP_FUNC_ARG_INT,
18 TEP_FUNC_ARG_LONG,
19 TEP_FUNC_ARG_STRING,
20 TEP_FUNC_ARG_PTR,
21 TEP_FUNC_ARG_MAX_TYPES
22};
23
24typedef unsigned long long (*pass:[*]tep_func_handler*)(struct trace_seq pass:[*]s, unsigned long long pass:[*]args);
25
26int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, enum tep_func_arg_type _ret_type_, char pass:[*]_name_, _..._);
27int *tep_unregister_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, char pass:[*]_name_);
28--
29
30DESCRIPTION
31-----------
32Some events may have helper functions in the print format arguments.
33This allows a plugin to dynamically create a way to process one of
34these functions.
35
36The _tep_register_print_function()_ registers such helper function. The _tep_
37argument is the trace event parser context. The _func_ argument is a pointer
38to the helper function. The _ret_type_ argument is the return type of the
39helper function, value from the _tep_func_arg_type_ enum. The _name_ is the name
40of the helper function, as seen in the print format arguments. The _..._ is a
41variable list of _tep_func_arg_type_ enums, the _func_ function arguments.
42This list must end with _TEP_FUNC_ARG_VOID_. See 'EXAMPLE' section.
43
44The _tep_unregister_print_function()_ unregisters a helper function, previously
45registered with _tep_register_print_function()_. The _tep_ argument is the
46trace event parser context. The _func_ and _name_ arguments are the same, used
47when the helper function was registered.
48
49The _tep_func_handler_ is the type of the helper function. The _s_ argument is
50the trace sequence, it can be used to create a custom string.
51The _args_ is a list of arguments, defined when the helper function was
52registered.
53
54RETURN VALUE
55------------
56The _tep_register_print_function()_ function returns 0 in case of success.
57In case of an error, TEP_ERRNO_... code is returned.
58
59The _tep_unregister_print_function()_ returns 0 in case of success, or -1 in
60case of an error.
61
62EXAMPLE
63-------
64Some events have internal functions calls, that appear in the print format
65output. For example "tracefs/events/i915/g4x_wm/format" has:
66[source,c]
67--
68print fmt: "pipe %c, frame=%u, scanline=%u, wm %d/%d/%d, sr %s/%d/%d/%d, hpll %s/%d/%d/%d, fbc %s",
69 ((REC->pipe) + 'A'), REC->frame, REC->scanline, REC->primary,
70 REC->sprite, REC->cursor, yesno(REC->cxsr), REC->sr_plane,
71 REC->sr_cursor, REC->sr_fbc, yesno(REC->hpll), REC->hpll_plane,
72 REC->hpll_cursor, REC->hpll_fbc, yesno(REC->fbc)
73--
74Notice the call to function _yesno()_ in the print arguments. In the kernel
75context, this function has the following implementation:
76[source,c]
77--
78static const char *yesno(int x)
79{
80 static const char *yes = "yes";
81 static const char *no = "no";
82
83 return x ? yes : no;
84}
85--
86The user space event parser has no idea how to handle this _yesno()_ function.
87The _tep_register_print_function()_ API can be used to register a user space
88helper function, mapped to the kernel's _yesno()_:
89[source,c]
90--
91#include <event-parse.h>
92#include <trace-seq.h>
93...
94struct tep_handle *tep = tep_alloc();
95...
96static const char *yes_no_helper(int x)
97{
98 return x ? "yes" : "no";
99}
100...
101 if ( tep_register_print_function(tep,
102 yes_no_helper,
103 TEP_FUNC_ARG_STRING,
104 "yesno",
105 TEP_FUNC_ARG_INT,
106 TEP_FUNC_ARG_VOID) != 0) {
107 /* Failed to register yes_no_helper function */
108 }
109
110/*
111 Now, when the event parser encounters this yesno() function, it will know
112 how to handle it.
113*/
114...
115 if (tep_unregister_print_function(tep, yes_no_helper, "yesno") != 0) {
116 /* Failed to unregister yes_no_helper function */
117 }
118--
119
120FILES
121-----
122[verse]
123--
124*event-parse.h*
125 Header file to include in order to have access to the library APIs.
126*trace-seq.h*
127 Header file to include in order to have access to trace sequences
128 related APIs. Trace sequences are used to allow a function to call
129 several other functions to create a string of data to use.
130*-ltraceevent*
131 Linker switch to add when building a program that uses the library.
132--
133
134SEE ALSO
135--------
136_libtraceevent(3)_, _trace-cmd(1)_
137
138AUTHOR
139------
140[verse]
141--
142*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
143*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
144--
145REPORTING BUGS
146--------------
147Report bugs to <linux-trace-devel@vger.kernel.org>
148
149LICENSE
150-------
151libtraceevent is Free Software licensed under the GNU LGPL 2.1
152
153RESOURCES
154---------
155https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt b/tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt
new file mode 100644
index 000000000000..b0599780b9a6
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt
@@ -0,0 +1,104 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_set_flag, tep_clear_flag, tep_test_flag -
7Manage flags of trace event parser context.
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <event-parse.h>*
14
15enum *tep_flag* {
16 _TEP_NSEC_OUTPUT_,
17 _TEP_DISABLE_SYS_PLUGINS_,
18 _TEP_DISABLE_PLUGINS_
19};
20void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
21void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
22bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
23--
24
25DESCRIPTION
26-----------
27Trace event parser context flags are defined in *enum tep_flag*:
28[verse]
29--
30_TEP_NSEC_OUTPUT_ - print event's timestamp in nano seconds, instead of micro seconds.
31_TEP_DISABLE_SYS_PLUGINS_ - disable plugins, located in system's plugin
32 directory. This directory is defined at library compile
33 time, and usually depends on library installation
34 prefix: (install_preffix)/lib/traceevent/plugins
35_TEP_DISABLE_PLUGINS_ - disable all library plugins:
36 - in system's plugin directory
37 - in directory, defined by the environment variable _TRACEEVENT_PLUGIN_DIR_
38 - in user's home directory, _~/.traceevent/plugins_
39--
40Note: plugin related flags must me set before calling _tep_load_plugins()_ API.
41
42The _tep_set_flag()_ function sets _flag_ to _tep_ context.
43
44The _tep_clear_flag()_ function clears _flag_ from _tep_ context.
45
46The _tep_test_flag()_ function tests if _flag_ is set to _tep_ context.
47
48RETURN VALUE
49------------
50_tep_test_flag()_ function returns true if _flag_ is set, false otherwise.
51
52EXAMPLE
53-------
54[source,c]
55--
56#include <event-parse.h>
57...
58struct tep_handle *tep = tep_alloc();
59...
60/* Print timestamps in nanoseconds */
61tep_set_flag(tep, TEP_NSEC_OUTPUT);
62...
63if (tep_test_flag(tep, TEP_NSEC_OUTPUT)) {
64 /* print timestamps in nanoseconds */
65} else {
66 /* print timestamps in microseconds */
67}
68...
69/* Print timestamps in microseconds */
70tep_clear_flag(tep, TEP_NSEC_OUTPUT);
71...
72--
73FILES
74-----
75[verse]
76--
77*event-parse.h*
78 Header file to include in order to have access to the library APIs.
79*-ltraceevent*
80 Linker switch to add when building a program that uses the library.
81--
82
83SEE ALSO
84--------
85_libtraceevent(3)_, _trace-cmd(1)_
86
87AUTHOR
88------
89[verse]
90--
91*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
92*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
93--
94REPORTING BUGS
95--------------
96Report bugs to <linux-trace-devel@vger.kernel.org>
97
98LICENSE
99-------
100libtraceevent is Free Software licensed under the GNU LGPL 2.1
101
102RESOURCES
103---------
104https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-strerror.txt b/tools/lib/traceevent/Documentation/libtraceevent-strerror.txt
new file mode 100644
index 000000000000..ee4062a00c9f
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-strerror.txt
@@ -0,0 +1,85 @@
1libtraceevent(3)
2================
3
4NAME
5----
6tep_strerror - Returns a string describing regular errno and tep error number.
7
8SYNOPSIS
9--------
10[verse]
11--
12*#include <event-parse.h>*
13
14int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_);
15
16--
17DESCRIPTION
18-----------
19The _tep_strerror()_ function converts tep error number into a human
20readable string.
21The _tep_ argument is trace event parser context. The _errnum_ is a regular
22errno, defined in errno.h, or a tep error number. The string, describing this
23error number is copied in the _buf_ argument. The _buflen_ argument is
24the size of the _buf_.
25
26It as a thread safe wrapper around strerror_r(). The library function has two
27different behaviors - POSIX and GNU specific. The _tep_strerror()_ API always
28behaves as the POSIX version - the error string is copied in the user supplied
29buffer.
30
31RETURN VALUE
32------------
33The _tep_strerror()_ function returns 0, if a valid _errnum_ is passed and the
34string is copied into _buf_. If _errnum_ is not a valid error number,
35-1 is returned and _buf_ is not modified.
36
37EXAMPLE
38-------
39[source,c]
40--
41#include <event-parse.h>
42...
43struct tep_handle *tep = tep_alloc();
44...
45char buf[32];
46char *pool = calloc(1, 128);
47if (tep == NULL) {
48 tep_strerror(tep, TEP_ERRNO__MEM_ALLOC_FAILED, buf, 32);
49 printf ("The pool is not initialized, %s", buf);
50}
51...
52--
53
54FILES
55-----
56[verse]
57--
58*event-parse.h*
59 Header file to include in order to have access to the library APIs.
60*-ltraceevent*
61 Linker switch to add when building a program that uses the library.
62--
63
64SEE ALSO
65--------
66_libtraceevent(3)_, _trace-cmd(1)_
67
68AUTHOR
69------
70[verse]
71--
72*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
73*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
74--
75REPORTING BUGS
76--------------
77Report bugs to <linux-trace-devel@vger.kernel.org>
78
79LICENSE
80-------
81libtraceevent is Free Software licensed under the GNU LGPL 2.1
82
83RESOURCES
84---------
85https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-tseq.txt b/tools/lib/traceevent/Documentation/libtraceevent-tseq.txt
new file mode 100644
index 000000000000..8ac6aa174e12
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent-tseq.txt
@@ -0,0 +1,158 @@
1libtraceevent(3)
2================
3
4NAME
5----
6trace_seq_init, trace_seq_destroy, trace_seq_reset, trace_seq_terminate,
7trace_seq_putc, trace_seq_puts, trace_seq_printf, trace_seq_vprintf,
8trace_seq_do_fprintf, trace_seq_do_printf -
9Initialize / destroy a trace sequence.
10
11SYNOPSIS
12--------
13[verse]
14--
15*#include <event-parse.h>*
16*#include <trace-seq.h>*
17
18void *trace_seq_init*(struct trace_seq pass:[*]_s_);
19void *trace_seq_destroy*(struct trace_seq pass:[*]_s_);
20void *trace_seq_reset*(struct trace_seq pass:[*]_s_);
21void *trace_seq_terminate*(struct trace_seq pass:[*]_s_);
22int *trace_seq_putc*(struct trace_seq pass:[*]_s_, unsigned char _c_);
23int *trace_seq_puts*(struct trace_seq pass:[*]_s_, const char pass:[*]_str_);
24int *trace_seq_printf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, _..._);
25int *trace_seq_vprintf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, va_list _args_);
26int *trace_seq_do_printf*(struct trace_seq pass:[*]_s_);
27int *trace_seq_do_fprintf*(struct trace_seq pass:[*]_s_, FILE pass:[*]_fp_);
28--
29
30DESCRIPTION
31-----------
32Trace sequences are used to allow a function to call several other functions
33to create a string of data to use.
34
35The _trace_seq_init()_ function initializes the trace sequence _s_.
36
37The _trace_seq_destroy()_ function destroys the trace sequence _s_ and frees
38all its resources that it had used.
39
40The _trace_seq_reset()_ function re-initializes the trace sequence _s_. All
41characters already written in _s_ will be deleted.
42
43The _trace_seq_terminate()_ function terminates the trace sequence _s_. It puts
44the null character pass:['\0'] at the end of the buffer.
45
46The _trace_seq_putc()_ function puts a single character _c_ in the trace
47sequence _s_.
48
49The _trace_seq_puts()_ function puts a NULL terminated string _str_ in the
50trace sequence _s_.
51
52The _trace_seq_printf()_ function puts a formated string _fmt _with
53variable arguments _..._ in the trace sequence _s_.
54
55The _trace_seq_vprintf()_ function puts a formated string _fmt _with
56list of arguments _args_ in the trace sequence _s_.
57
58The _trace_seq_do_printf()_ function prints the buffer of trace sequence _s_ to
59the standard output stdout.
60
61The _trace_seq_do_fprintf()_ function prints the buffer of trace sequence _s_
62to the given file _fp_.
63
64RETURN VALUE
65------------
66Both _trace_seq_putc()_ and _trace_seq_puts()_ functions return the number of
67characters put in the trace sequence, or 0 in case of an error
68
69Both _trace_seq_printf()_ and _trace_seq_vprintf()_ functions return 0 if the
70trace oversizes the buffer's free space, the number of characters printed, or
71a negative value in case of an error.
72
73Both _trace_seq_do_printf()_ and _trace_seq_do_fprintf()_ functions return the
74number of printed characters, or -1 in case of an error.
75
76EXAMPLE
77-------
78[source,c]
79--
80#include <event-parse.h>
81#include <trace-seq.h>
82...
83struct trace_seq seq;
84trace_seq_init(&seq);
85...
86void foo_seq_print(struct trace_seq *tseq, char *format, ...)
87{
88 va_list ap;
89 va_start(ap, format);
90 if (trace_seq_vprintf(tseq, format, ap) <= 0) {
91 /* Failed to print in the trace sequence */
92 }
93 va_end(ap);
94}
95
96trace_seq_reset(&seq);
97
98char *str = " MAN page example";
99if (trace_seq_puts(&seq, str) != strlen(str)) {
100 /* Failed to put str in the trace sequence */
101}
102if (trace_seq_putc(&seq, ':') != 1) {
103 /* Failed to put ':' in the trace sequence */
104}
105if (trace_seq_printf(&seq, " trace sequence: %d", 1) <= 0) {
106 /* Failed to print in the trace sequence */
107}
108foo_seq_print( &seq, " %d\n", 2);
109
110trace_seq_terminate(&seq);
111...
112
113if (trace_seq_do_printf(&seq) < 0 ) {
114 /* Failed to print the sequence buffer to the standard output */
115}
116FILE *fp = fopen("trace.txt", "w");
117if (trace_seq_do_fprintf(&seq, fp) < 0 ) [
118 /* Failed to print the sequence buffer to the trace.txt file */
119}
120
121trace_seq_destroy(&seq);
122...
123--
124
125FILES
126-----
127[verse]
128--
129*event-parse.h*
130 Header file to include in order to have access to the library APIs.
131*trace-seq.h*
132 Header file to include in order to have access to trace sequences related APIs.
133*-ltraceevent*
134 Linker switch to add when building a program that uses the library.
135--
136
137SEE ALSO
138--------
139_libtraceevent(3)_, _trace-cmd(1)_
140
141AUTHOR
142------
143[verse]
144--
145*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
146*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
147--
148REPORTING BUGS
149--------------
150Report bugs to <linux-trace-devel@vger.kernel.org>
151
152LICENSE
153-------
154libtraceevent is Free Software licensed under the GNU LGPL 2.1
155
156RESOURCES
157---------
158https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/libtraceevent.txt b/tools/lib/traceevent/Documentation/libtraceevent.txt
new file mode 100644
index 000000000000..fbd977b47de1
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/libtraceevent.txt
@@ -0,0 +1,203 @@
1libtraceevent(3)
2================
3
4NAME
5----
6libtraceevent - Linux kernel trace event library
7
8SYNOPSIS
9--------
10[verse]
11--
12*#include <event-parse.h>*
13
14Management of tep handler data structure and access of its members:
15 struct tep_handle pass:[*]*tep_alloc*(void);
16 void *tep_free*(struct tep_handle pass:[*]_tep_);
17 void *tep_ref*(struct tep_handle pass:[*]_tep_);
18 void *tep_unref*(struct tep_handle pass:[*]_tep_);
19 int *tep_ref_get*(struct tep_handle pass:[*]_tep_);
20 void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
21 void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
22 bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flags_);
23 int *tep_get_cpus*(struct tep_handle pass:[*]_tep_);
24 void *tep_set_cpus*(struct tep_handle pass:[*]_tep_, int _cpus_);
25 int *tep_get_long_size*(strucqt tep_handle pass:[*]_tep_);
26 void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_);
27 int *tep_get_page_size*(struct tep_handle pass:[*]_tep_);
28 void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_);
29 bool *tep_is_latency_format*(struct tep_handle pass:[*]_tep_);
30 void *tep_set_latency_format*(struct tep_handle pass:[*]_tep_, int _lat_);
31 int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_);
32 int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_);
33 bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_);
34 int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_);
35
36Register / unregister APIs:
37 int *tep_register_trace_clock*(struct tep_handle pass:[*]_tep_, const char pass:[*]_trace_clock_);
38 int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_);
39 int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_);
40 int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_);
41 int *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const char pass:[*]_fmt_, unsigned long long _addr_);
42 int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, enum tep_func_arg_type _ret_type_, char pass:[*]_name_, _..._);
43 int *tep_unregister_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, char pass:[*]_name_);
44
45Plugins management:
46 struct tep_plugin_list pass:[*]*tep_load_plugins*(struct tep_handle pass:[*]_tep_);
47 void *tep_unload_plugins*(struct tep_plugin_list pass:[*]_plugin_list_, struct tep_handle pass:[*]_tep_);
48 char pass:[*]pass:[*]*tep_plugin_list_options*(void);
49 void *tep_plugin_free_options_list*(char pass:[*]pass:[*]_list_);
50 int *tep_plugin_add_options*(const char pass:[*]_name_, struct tep_plugin_option pass:[*]_options_);
51 void *tep_plugin_remove_options*(struct tep_plugin_option pass:[*]_options_);
52 void *tep_print_plugins*(struct trace_seq pass:[*]_s_, const char pass:[*]_prefix_, const char pass:[*]_suffix_, const struct tep_plugin_list pass:[*]_list_);
53
54Event related APIs:
55 struct tep_event pass:[*]*tep_get_event*(struct tep_handle pass:[*]_tep_, int _index_);
56 struct tep_event pass:[*]*tep_get_first_event*(struct tep_handle pass:[*]_tep_);
57 int *tep_get_events_count*(struct tep_handle pass:[*]_tep_);
58 struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_);
59 struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_);
60
61Event printing:
62 void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, bool _use_trace_clock_);
63 void *tep_print_event_data*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]_record_);
64 void *tep_event_info*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]_record_);
65 void *tep_print_event_task*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]_record_);
66 void *tep_print_event_time*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]record, bool _use_trace_clock_);
67 void *tep_set_print_raw*(struct tep_handle pass:[*]_tep_, int _print_raw_);
68
69Event finding:
70 struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_);
71 struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_);
72 struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_);
73
74Parsing of event files:
75 int *tep_parse_header_page*(struct tep_handle pass:[*]_tep_, char pass:[*]_buf_, unsigned long _size_, int _long_size_);
76 enum tep_errno *tep_parse_event*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_);
77 enum tep_errno *tep_parse_format*(struct tep_handle pass:[*]_tep_, struct tep_event pass:[*]pass:[*]_eventp_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_);
78
79APIs related to fields from event's format files:
80 struct tep_format_field pass:[*]pass:[*]*tep_event_common_fields*(struct tep_event pass:[*]_event_);
81 struct tep_format_field pass:[*]pass:[*]*tep_event_fields*(struct tep_event pass:[*]_event_);
82 void pass:[*]*tep_get_field_raw*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int pass:[*]_len_, int _err_);
83 int *tep_get_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_);
84 int *tep_get_common_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_);
85 int *tep_get_any_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_);
86 int *tep_read_number_field*(struct tep_format_field pass:[*]_field_, const void pass:[*]_data_, unsigned long long pass:[*]_value_);
87
88Event fields printing:
89 void *tep_print_field*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, struct tep_format_field pass:[*]_field_);
90 void *tep_print_fields*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int _size_, struct tep_event pass:[*]_event_);
91 int *tep_print_num_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_);
92 int *tep_print_func_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_);
93
94Event fields finding:
95 struct tep_format_field pass:[*]*tep_find_common_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_);
96 struct tep_format_field pass:[*]*tep_find_field*(struct tep_event_ormat pass:[*]_event_, const char pass:[*]_name_);
97 struct tep_format_field pass:[*]*tep_find_any_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_);
98
99Functions resolver:
100 int *tep_set_function_resolver*(struct tep_handle pass:[*]_tep_, tep_func_resolver_t pass:[*]_func_, void pass:[*]_priv_);
101 void *tep_reset_function_resolver*(struct tep_handle pass:[*]_tep_);
102 const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_);
103 unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_);
104
105Filter management:
106 struct tep_event_filter pass:[*]*tep_filter_alloc*(struct tep_handle pass:[*]_tep_);
107 enum tep_errno *tep_filter_add_filter_str*(struct tep_event_filter pass:[*]_filter_, const char pass:[*]_filter_str_);
108 enum tep_errno *tep_filter_match*(struct tep_event_filter pass:[*]_filter_, struct tep_record pass:[*]_record_);
109 int *tep_filter_strerror*(struct tep_event_filter pass:[*]_filter_, enum tep_errno _err_, char pass:[*]buf, size_t _buflen_);
110 int *tep_event_filtered*(struct tep_event_filter pass:[*]_filter_, int _event_id_);
111 void *tep_filter_reset*(struct tep_event_filter pass:[*]_filter_);
112 void *tep_filter_free*(struct tep_event_filter pass:[*]_filter_);
113 char pass:[*]*tep_filter_make_string*(struct tep_event_filter pass:[*]_filter_, int _event_id_);
114 int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, int _event_id_);
115 int *tep_filter_copy*(struct tep_event_filter pass:[*]_dest_, struct tep_event_filter pass:[*]_source_);
116 int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_);
117
118Parsing various data from the records:
119 void *tep_data_latency_format*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_);
120 int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
121 int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
122 int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
123 int *tep_data_flags*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
124
125Command and task related APIs:
126 const char pass:[*]*tep_data_comm_from_pid*(struct tep_handle pass:[*]_tep_, int _pid_);
127 struct cmdline pass:[*]*tep_data_pid_from_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, struct cmdline pass:[*]_next_);
128 int *tep_register_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_);
129 int *tep_override_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_);
130 bool *tep_is_pid_registered*(struct tep_handle pass:[*]_tep_, int _pid_);
131 int *tep_cmdline_pid*(struct tep_handle pass:[*]_tep_, struct cmdline pass:[*]_cmdline_);
132
133Endian related APIs:
134 int *tep_is_bigendian*(void);
135 unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, const void pass:[*]_ptr_, int _size_);
136 bool *tep_is_file_bigendian*(struct tep_handle pass:[*]_tep_);
137 void *tep_set_file_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_);
138 bool *tep_is_local_bigendian*(struct tep_handle pass:[*]_tep_);
139 void *tep_set_local_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_);
140
141Trace sequences:
142*#include <trace-seq.h>*
143 void *trace_seq_init*(struct trace_seq pass:[*]_s_);
144 void *trace_seq_reset*(struct trace_seq pass:[*]_s_);
145 void *trace_seq_destroy*(struct trace_seq pass:[*]_s_);
146 int *trace_seq_printf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, ...);
147 int *trace_seq_vprintf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, va_list _args_);
148 int *trace_seq_puts*(struct trace_seq pass:[*]_s_, const char pass:[*]_str_);
149 int *trace_seq_putc*(struct trace_seq pass:[*]_s_, unsigned char _c_);
150 void *trace_seq_terminate*(struct trace_seq pass:[*]_s_);
151 int *trace_seq_do_fprintf*(struct trace_seq pass:[*]_s_, FILE pass:[*]_fp_);
152 int *trace_seq_do_printf*(struct trace_seq pass:[*]_s_);
153--
154
155DESCRIPTION
156-----------
157The libtraceevent(3) library provides APIs to access kernel tracepoint events,
158located in the tracefs file system under the events directory.
159
160ENVIRONMENT
161-----------
162[verse]
163--
164TRACEEVENT_PLUGIN_DIR
165 Additional plugin directory. All shared object files, located in this directory will be loaded as traceevent plugins.
166--
167
168FILES
169-----
170[verse]
171--
172*event-parse.h*
173 Header file to include in order to have access to the library APIs.
174*trace-seq.h*
175 Header file to include in order to have access to trace sequences related APIs.
176 Trace sequences are used to allow a function to call several other functions
177 to create a string of data to use.
178*-ltraceevent*
179 Linker switch to add when building a program that uses the library.
180--
181
182SEE ALSO
183--------
184_trace-cmd(1)_
185
186AUTHOR
187------
188[verse]
189--
190*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
191*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
192--
193REPORTING BUGS
194--------------
195Report bugs to <linux-trace-devel@vger.kernel.org>
196
197LICENSE
198-------
199libtraceevent is Free Software licensed under the GNU LGPL 2.1
200
201RESOURCES
202---------
203https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/lib/traceevent/Documentation/manpage-1.72.xsl b/tools/lib/traceevent/Documentation/manpage-1.72.xsl
new file mode 100644
index 000000000000..b4d315cb8c47
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/manpage-1.72.xsl
@@ -0,0 +1,14 @@
1<!-- manpage-1.72.xsl:
2 special settings for manpages rendered from asciidoc+docbook
3 handles peculiarities in docbook-xsl 1.72.0 -->
4<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5 version="1.0">
6
7<xsl:import href="manpage-base.xsl"/>
8
9<!-- these are the special values for the roff control characters
10 needed for docbook-xsl 1.72.0 -->
11<xsl:param name="git.docbook.backslash">&#x2593;</xsl:param>
12<xsl:param name="git.docbook.dot" >&#x2302;</xsl:param>
13
14</xsl:stylesheet>
diff --git a/tools/lib/traceevent/Documentation/manpage-base.xsl b/tools/lib/traceevent/Documentation/manpage-base.xsl
new file mode 100644
index 000000000000..a264fa616093
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/manpage-base.xsl
@@ -0,0 +1,35 @@
1<!-- manpage-base.xsl:
2 special formatting for manpages rendered from asciidoc+docbook -->
3<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4 version="1.0">
5
6<!-- these params silence some output from xmlto -->
7<xsl:param name="man.output.quietly" select="1"/>
8<xsl:param name="refentry.meta.get.quietly" select="1"/>
9
10<!-- convert asciidoc callouts to man page format;
11 git.docbook.backslash and git.docbook.dot params
12 must be supplied by another XSL file or other means -->
13<xsl:template match="co">
14 <xsl:value-of select="concat(
15 $git.docbook.backslash,'fB(',
16 substring-after(@id,'-'),')',
17 $git.docbook.backslash,'fR')"/>
18</xsl:template>
19<xsl:template match="calloutlist">
20 <xsl:value-of select="$git.docbook.dot"/>
21 <xsl:text>sp&#10;</xsl:text>
22 <xsl:apply-templates/>
23 <xsl:text>&#10;</xsl:text>
24</xsl:template>
25<xsl:template match="callout">
26 <xsl:value-of select="concat(
27 $git.docbook.backslash,'fB',
28 substring-after(@arearefs,'-'),
29 '. ',$git.docbook.backslash,'fR')"/>
30 <xsl:apply-templates/>
31 <xsl:value-of select="$git.docbook.dot"/>
32 <xsl:text>br&#10;</xsl:text>
33</xsl:template>
34
35</xsl:stylesheet>
diff --git a/tools/lib/traceevent/Documentation/manpage-bold-literal.xsl b/tools/lib/traceevent/Documentation/manpage-bold-literal.xsl
new file mode 100644
index 000000000000..608eb5df6281
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/manpage-bold-literal.xsl
@@ -0,0 +1,17 @@
1<!-- manpage-bold-literal.xsl:
2 special formatting for manpages rendered from asciidoc+docbook -->
3<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4 version="1.0">
5
6<!-- render literal text as bold (instead of plain or monospace);
7 this makes literal text easier to distinguish in manpages
8 viewed on a tty -->
9<xsl:template match="literal">
10 <xsl:value-of select="$git.docbook.backslash"/>
11 <xsl:text>fB</xsl:text>
12 <xsl:apply-templates/>
13 <xsl:value-of select="$git.docbook.backslash"/>
14 <xsl:text>fR</xsl:text>
15</xsl:template>
16
17</xsl:stylesheet>
diff --git a/tools/lib/traceevent/Documentation/manpage-normal.xsl b/tools/lib/traceevent/Documentation/manpage-normal.xsl
new file mode 100644
index 000000000000..a48f5b11f3dc
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/manpage-normal.xsl
@@ -0,0 +1,13 @@
1<!-- manpage-normal.xsl:
2 special settings for manpages rendered from asciidoc+docbook
3 handles anything we want to keep away from docbook-xsl 1.72.0 -->
4<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5 version="1.0">
6
7<xsl:import href="manpage-base.xsl"/>
8
9<!-- these are the normal values for the roff control characters -->
10<xsl:param name="git.docbook.backslash">\</xsl:param>
11<xsl:param name="git.docbook.dot" >.</xsl:param>
12
13</xsl:stylesheet>
diff --git a/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl b/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl
new file mode 100644
index 000000000000..a63c7632a87d
--- /dev/null
+++ b/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl
@@ -0,0 +1,21 @@
1<!-- manpage-suppress-sp.xsl:
2 special settings for manpages rendered from asciidoc+docbook
3 handles erroneous, inline .sp in manpage output of some
4 versions of docbook-xsl -->
5<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
6 version="1.0">
7
8<!-- attempt to work around spurious .sp at the tail of the line
9 that some versions of docbook stylesheets seem to add -->
10<xsl:template match="simpara">
11 <xsl:variable name="content">
12 <xsl:apply-templates/>
13 </xsl:variable>
14 <xsl:value-of select="normalize-space($content)"/>
15 <xsl:if test="not(ancestor::authorblurb) and
16 not(ancestor::personblurb)">
17 <xsl:text>&#10;&#10;</xsl:text>
18 </xsl:if>
19</xsl:template>
20
21</xsl:stylesheet>
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 941761d9923d..3292c290654f 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -50,9 +50,13 @@ man_dir = $(prefix)/share/man
50man_dir_SQ = '$(subst ','\'',$(man_dir))' 50man_dir_SQ = '$(subst ','\'',$(man_dir))'
51pkgconfig_dir ?= $(word 1,$(shell $(PKG_CONFIG) \ 51pkgconfig_dir ?= $(word 1,$(shell $(PKG_CONFIG) \
52 --variable pc_path pkg-config | tr ":" " ")) 52 --variable pc_path pkg-config | tr ":" " "))
53includedir_relative = traceevent
54includedir = $(prefix)/include/$(includedir_relative)
55includedir_SQ = '$(subst ','\'',$(includedir))'
53 56
54export man_dir man_dir_SQ INSTALL 57export man_dir man_dir_SQ INSTALL
55export DESTDIR DESTDIR_SQ 58export DESTDIR DESTDIR_SQ
59export EVENT_PARSE_VERSION
56 60
57set_plugin_dir := 1 61set_plugin_dir := 1
58 62
@@ -279,6 +283,8 @@ define do_install_pkgconfig_file
279 cp -f ${PKG_CONFIG_FILE}.template ${PKG_CONFIG_FILE}; \ 283 cp -f ${PKG_CONFIG_FILE}.template ${PKG_CONFIG_FILE}; \
280 sed -i "s|INSTALL_PREFIX|${1}|g" ${PKG_CONFIG_FILE}; \ 284 sed -i "s|INSTALL_PREFIX|${1}|g" ${PKG_CONFIG_FILE}; \
281 sed -i "s|LIB_VERSION|${EVENT_PARSE_VERSION}|g" ${PKG_CONFIG_FILE}; \ 285 sed -i "s|LIB_VERSION|${EVENT_PARSE_VERSION}|g" ${PKG_CONFIG_FILE}; \
286 sed -i "s|LIB_DIR|${libdir}|g" ${PKG_CONFIG_FILE}; \
287 sed -i "s|HEADER_DIR|$(includedir)|g" ${PKG_CONFIG_FILE}; \
282 $(call do_install,$(PKG_CONFIG_FILE),$(pkgconfig_dir),644); \ 288 $(call do_install,$(PKG_CONFIG_FILE),$(pkgconfig_dir),644); \
283 else \ 289 else \
284 (echo Failed to locate pkg-config directory) 1>&2; \ 290 (echo Failed to locate pkg-config directory) 1>&2; \
@@ -300,10 +306,10 @@ install_pkgconfig:
300 306
301install_headers: 307install_headers:
302 $(call QUIET_INSTALL, headers) \ 308 $(call QUIET_INSTALL, headers) \
303 $(call do_install,event-parse.h,$(prefix)/include/traceevent,644); \ 309 $(call do_install,event-parse.h,$(DESTDIR)$(includedir_SQ),644); \
304 $(call do_install,event-utils.h,$(prefix)/include/traceevent,644); \ 310 $(call do_install,event-utils.h,$(DESTDIR)$(includedir_SQ),644); \
305 $(call do_install,trace-seq.h,$(prefix)/include/traceevent,644); \ 311 $(call do_install,trace-seq.h,$(DESTDIR)$(includedir_SQ),644); \
306 $(call do_install,kbuffer.h,$(prefix)/include/traceevent,644) 312 $(call do_install,kbuffer.h,$(DESTDIR)$(includedir_SQ),644)
307 313
308install: install_lib 314install: install_lib
309 315
@@ -313,6 +319,38 @@ clean:
313 $(RM) TRACEEVENT-CFLAGS tags TAGS; \ 319 $(RM) TRACEEVENT-CFLAGS tags TAGS; \
314 $(RM) $(PKG_CONFIG_FILE) 320 $(RM) $(PKG_CONFIG_FILE)
315 321
322PHONY += doc
323doc:
324 $(call descend,Documentation)
325
326PHONY += doc-clean
327doc-clean:
328 $(call descend,Documentation,clean)
329
330PHONY += doc-install
331doc-install:
332 $(call descend,Documentation,install)
333
334PHONY += doc-uninstall
335doc-uninstall:
336 $(call descend,Documentation,uninstall)
337
338PHONY += help
339help:
340 @echo 'Possible targets:'
341 @echo''
342 @echo ' all - default, compile the library and the'\
343 'plugins'
344 @echo ' plugins - compile the plugins'
345 @echo ' install - install the library, the plugins,'\
346 'the header and pkgconfig files'
347 @echo ' clean - clean the library and the plugins object files'
348 @echo ' doc - compile the documentation files - man'\
349 'and html pages, in the Documentation directory'
350 @echo ' doc-clean - clean the documentation files'
351 @echo ' doc-install - install the man pages'
352 @echo ' doc-uninstall - uninstall the man pages'
353 @echo''
316PHONY += force plugins 354PHONY += force plugins
317force: 355force:
318 356
diff --git a/tools/lib/traceevent/libtraceevent.pc.template b/tools/lib/traceevent/libtraceevent.pc.template
index 42e4d6cb6b9e..86384fcd57f1 100644
--- a/tools/lib/traceevent/libtraceevent.pc.template
+++ b/tools/lib/traceevent/libtraceevent.pc.template
@@ -1,6 +1,6 @@
1prefix=INSTALL_PREFIX 1prefix=INSTALL_PREFIX
2libdir=${prefix}/lib64 2libdir=LIB_DIR
3includedir=${prefix}/include/traceevent 3includedir=HEADER_DIR
4 4
5Name: libtraceevent 5Name: libtraceevent
6URL: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 6URL: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 53f8be0f4a1f..88158239622b 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -7,11 +7,12 @@ ARCH := x86
7endif 7endif
8 8
9# always use the host compiler 9# always use the host compiler
10HOSTAR ?= ar
10HOSTCC ?= gcc 11HOSTCC ?= gcc
11HOSTLD ?= ld 12HOSTLD ?= ld
13AR = $(HOSTAR)
12CC = $(HOSTCC) 14CC = $(HOSTCC)
13LD = $(HOSTLD) 15LD = $(HOSTLD)
14AR = ar
15 16
16ifeq ($(srctree),) 17ifeq ($(srctree),)
17srctree := $(patsubst %/,%,$(dir $(CURDIR))) 18srctree := $(patsubst %/,%,$(dir $(CURDIR)))
diff --git a/tools/pci/Makefile b/tools/pci/Makefile
index 9b7534457060..6876ee4bd78c 100644
--- a/tools/pci/Makefile
+++ b/tools/pci/Makefile
@@ -47,7 +47,7 @@ clean:
47 47
48install: $(ALL_PROGRAMS) 48install: $(ALL_PROGRAMS)
49 install -d -m 755 $(DESTDIR)$(bindir); \ 49 install -d -m 755 $(DESTDIR)$(bindir); \
50 for program in $(ALL_PROGRAMS); do \ 50 for program in $(ALL_PROGRAMS) pcitest.sh; do \
51 install $$program $(DESTDIR)$(bindir); \ 51 install $$program $(DESTDIR)$(bindir); \
52 done; \ 52 done; \
53 for script in $(ALL_SCRIPTS); do \ 53 for script in $(ALL_SCRIPTS); do \
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index 138fb6e94b3c..18ed1b0fceb3 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -199,6 +199,18 @@ also be supplied. For example:
199 199
200 perf stat -C 0 -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ... 200 perf stat -C 0 -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ...
201 201
202EVENT QUALIFIERS:
203
204It is also possible to add extra qualifiers to an event:
205
206percore:
207
208Sums up the event counts for all hardware threads in a core, e.g.:
209
210
211 perf stat -e cpu/event=0,umask=0x3,percore=1/
212
213
202EVENT GROUPS 214EVENT GROUPS
203------------ 215------------
204 216
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 58986f4cc190..de269430720a 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -406,7 +406,8 @@ symbolic names, e.g. on x86, ax, si. To list the available registers use
406--intr-regs=ax,bx. The list of register is architecture dependent. 406--intr-regs=ax,bx. The list of register is architecture dependent.
407 407
408--user-regs:: 408--user-regs::
409Capture user registers at sample time. Same arguments as -I. 409Similar to -I, but capture user registers at sample time. To list the available
410user registers use --user-regs=\?.
410 411
411--running-time:: 412--running-time::
412Record running and enabled time for read events (:S) 413Record running and enabled time for read events (:S)
@@ -478,6 +479,11 @@ Also at some cases executing less output write syscalls with bigger data size
478can take less time than executing more output write syscalls with smaller data 479can take less time than executing more output write syscalls with smaller data
479size thus lowering runtime profiling overhead. 480size thus lowering runtime profiling overhead.
480 481
482-z::
483--compression-level[=n]::
484Produce compressed trace using specified level n (default: 1 - fastest compression,
48522 - smallest trace)
486
481--all-kernel:: 487--all-kernel::
482Configure all used events to run in kernel space. 488Configure all used events to run in kernel space.
483 489
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 39c05f89104e..1e312c2672e4 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -43,6 +43,10 @@ report::
43 param1 and param2 are defined as formats for the PMU in 43 param1 and param2 are defined as formats for the PMU in
44 /sys/bus/event_source/devices/<pmu>/format/* 44 /sys/bus/event_source/devices/<pmu>/format/*
45 45
46 'percore' is a event qualifier that sums up the event counts for both
47 hardware threads in a core. For example:
48 perf stat -A -a -e cpu/event,percore=1/,otherevent ...
49
46 - a symbolically formed event like 'pmu/config=M,config1=N,config2=K/' 50 - a symbolically formed event like 'pmu/config=M,config1=N,config2=K/'
47 where M, N, K are numbers (in decimal, hex, octal format). 51 where M, N, K are numbers (in decimal, hex, octal format).
48 Acceptable values for each of 'config', 'config1' and 'config2' 52 Acceptable values for each of 'config', 'config1' and 'config2'
diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt
index 593ef49b273c..6967e9b02be5 100644
--- a/tools/perf/Documentation/perf.data-file-format.txt
+++ b/tools/perf/Documentation/perf.data-file-format.txt
@@ -272,6 +272,19 @@ struct {
272 272
273Two uint64_t for the time of first sample and the time of last sample. 273Two uint64_t for the time of first sample and the time of last sample.
274 274
275 HEADER_COMPRESSED = 27,
276
277struct {
278 u32 version;
279 u32 type;
280 u32 level;
281 u32 ratio;
282 u32 mmap_len;
283};
284
285Indicates that trace contains records of PERF_RECORD_COMPRESSED type
286that have perf_events records in compressed form.
287
275 other bits are reserved and should ignored for now 288 other bits are reserved and should ignored for now
276 HEADER_FEAT_BITS = 256, 289 HEADER_FEAT_BITS = 256,
277 290
@@ -437,6 +450,17 @@ struct auxtrace_error_event {
437Describes a header feature. These are records used in pipe-mode that 450Describes a header feature. These are records used in pipe-mode that
438contain information that otherwise would be in perf.data file's header. 451contain information that otherwise would be in perf.data file's header.
439 452
453 PERF_RECORD_COMPRESSED = 81,
454
455struct compressed_event {
456 struct perf_event_header header;
457 char data[];
458};
459
460The header is followed by compressed data frame that can be decompressed
461into array of perf trace records. The size of the entire compressed event
462record including the header is limited by the max value of header.size.
463
440Event types 464Event types
441 465
442Define the event attributes with their IDs. 466Define the event attributes with their IDs.
diff --git a/tools/perf/Documentation/perf.txt b/tools/perf/Documentation/perf.txt
index 864e37597252..401f0ed67439 100644
--- a/tools/perf/Documentation/perf.txt
+++ b/tools/perf/Documentation/perf.txt
@@ -22,6 +22,8 @@ OPTIONS
22 verbose - general debug messages 22 verbose - general debug messages
23 ordered-events - ordered events object debug messages 23 ordered-events - ordered events object debug messages
24 data-convert - data convert command debug messages 24 data-convert - data convert command debug messages
25 stderr - write debug output (option -v) to stderr
26 in browser mode
25 27
26--buildid-dir:: 28--buildid-dir::
27 Setup buildid cache directory. It has higher priority than 29 Setup buildid cache directory. It has higher priority than
diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h
index 7f6d538f8a89..b7cd91a9014f 100644
--- a/tools/perf/arch/x86/include/perf_regs.h
+++ b/tools/perf/arch/x86/include/perf_regs.h
@@ -8,9 +8,10 @@
8 8
9void perf_regs_load(u64 *regs); 9void perf_regs_load(u64 *regs);
10 10
11#define PERF_REGS_MAX PERF_REG_X86_XMM_MAX
12#define PERF_XMM_REGS_MASK (~((1ULL << PERF_REG_X86_XMM0) - 1))
11#ifndef HAVE_ARCH_X86_64_SUPPORT 13#ifndef HAVE_ARCH_X86_64_SUPPORT
12#define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1) 14#define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
13#define PERF_REGS_MAX PERF_REG_X86_32_MAX
14#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32 15#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
15#else 16#else
16#define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \ 17#define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
@@ -18,7 +19,6 @@ void perf_regs_load(u64 *regs);
18 (1ULL << PERF_REG_X86_FS) | \ 19 (1ULL << PERF_REG_X86_FS) | \
19 (1ULL << PERF_REG_X86_GS)) 20 (1ULL << PERF_REG_X86_GS))
20#define PERF_REGS_MASK (((1ULL << PERF_REG_X86_64_MAX) - 1) & ~REG_NOSUPPORT) 21#define PERF_REGS_MASK (((1ULL << PERF_REG_X86_64_MAX) - 1) & ~REG_NOSUPPORT)
21#define PERF_REGS_MAX PERF_REG_X86_64_MAX
22#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 22#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
23#endif 23#endif
24#define PERF_REG_IP PERF_REG_X86_IP 24#define PERF_REG_IP PERF_REG_X86_IP
@@ -77,6 +77,28 @@ static inline const char *perf_reg_name(int id)
77 case PERF_REG_X86_R15: 77 case PERF_REG_X86_R15:
78 return "R15"; 78 return "R15";
79#endif /* HAVE_ARCH_X86_64_SUPPORT */ 79#endif /* HAVE_ARCH_X86_64_SUPPORT */
80
81#define XMM(x) \
82 case PERF_REG_X86_XMM ## x: \
83 case PERF_REG_X86_XMM ## x + 1: \
84 return "XMM" #x;
85 XMM(0)
86 XMM(1)
87 XMM(2)
88 XMM(3)
89 XMM(4)
90 XMM(5)
91 XMM(6)
92 XMM(7)
93 XMM(8)
94 XMM(9)
95 XMM(10)
96 XMM(11)
97 XMM(12)
98 XMM(13)
99 XMM(14)
100 XMM(15)
101#undef XMM
80 default: 102 default:
81 return NULL; 103 return NULL;
82 } 104 }
diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c
index fead6b3b4206..7886ca5263e3 100644
--- a/tools/perf/arch/x86/util/perf_regs.c
+++ b/tools/perf/arch/x86/util/perf_regs.c
@@ -31,6 +31,22 @@ const struct sample_reg sample_reg_masks[] = {
31 SMPL_REG(R14, PERF_REG_X86_R14), 31 SMPL_REG(R14, PERF_REG_X86_R14),
32 SMPL_REG(R15, PERF_REG_X86_R15), 32 SMPL_REG(R15, PERF_REG_X86_R15),
33#endif 33#endif
34 SMPL_REG2(XMM0, PERF_REG_X86_XMM0),
35 SMPL_REG2(XMM1, PERF_REG_X86_XMM1),
36 SMPL_REG2(XMM2, PERF_REG_X86_XMM2),
37 SMPL_REG2(XMM3, PERF_REG_X86_XMM3),
38 SMPL_REG2(XMM4, PERF_REG_X86_XMM4),
39 SMPL_REG2(XMM5, PERF_REG_X86_XMM5),
40 SMPL_REG2(XMM6, PERF_REG_X86_XMM6),
41 SMPL_REG2(XMM7, PERF_REG_X86_XMM7),
42 SMPL_REG2(XMM8, PERF_REG_X86_XMM8),
43 SMPL_REG2(XMM9, PERF_REG_X86_XMM9),
44 SMPL_REG2(XMM10, PERF_REG_X86_XMM10),
45 SMPL_REG2(XMM11, PERF_REG_X86_XMM11),
46 SMPL_REG2(XMM12, PERF_REG_X86_XMM12),
47 SMPL_REG2(XMM13, PERF_REG_X86_XMM13),
48 SMPL_REG2(XMM14, PERF_REG_X86_XMM14),
49 SMPL_REG2(XMM15, PERF_REG_X86_XMM15),
34 SMPL_REG_END 50 SMPL_REG_END
35}; 51};
36 52
@@ -254,3 +270,31 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
254 270
255 return SDT_ARG_VALID; 271 return SDT_ARG_VALID;
256} 272}
273
274uint64_t arch__intr_reg_mask(void)
275{
276 struct perf_event_attr attr = {
277 .type = PERF_TYPE_HARDWARE,
278 .config = PERF_COUNT_HW_CPU_CYCLES,
279 .sample_type = PERF_SAMPLE_REGS_INTR,
280 .sample_regs_intr = PERF_XMM_REGS_MASK,
281 .precise_ip = 1,
282 .disabled = 1,
283 .exclude_kernel = 1,
284 };
285 int fd;
286 /*
287 * In an unnamed union, init it here to build on older gcc versions
288 */
289 attr.sample_period = 1;
290
291 event_attr_init(&attr);
292
293 fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
294 if (fd != -1) {
295 close(fd);
296 return (PERF_XMM_REGS_MASK | PERF_REGS_MASK);
297 }
298
299 return PERF_REGS_MASK;
300}
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 67f9d9ffacfb..77deb3a40596 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -159,8 +159,6 @@ static int hist_iter__branch_callback(struct hist_entry_iter *iter,
159 struct perf_evsel *evsel = iter->evsel; 159 struct perf_evsel *evsel = iter->evsel;
160 int err; 160 int err;
161 161
162 hist__account_cycles(sample->branch_stack, al, sample, false);
163
164 bi = he->branch_info; 162 bi = he->branch_info;
165 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel); 163 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
166 164
@@ -199,6 +197,8 @@ static int process_branch_callback(struct perf_evsel *evsel,
199 if (a.map != NULL) 197 if (a.map != NULL)
200 a.map->dso->hit = 1; 198 a.map->dso->hit = 1;
201 199
200 hist__account_cycles(sample->branch_stack, al, sample, false);
201
202 ret = hist_entry_iter__add(&iter, &a, PERF_MAX_STACK_DEPTH, ann); 202 ret = hist_entry_iter__add(&iter, &a, PERF_MAX_STACK_DEPTH, ann);
203 return ret; 203 return ret;
204} 204}
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 24086b7f1b14..8e0e06d3edfc 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -837,6 +837,9 @@ int cmd_inject(int argc, const char **argv)
837 if (inject.session == NULL) 837 if (inject.session == NULL)
838 return -1; 838 return -1;
839 839
840 if (zstd_init(&(inject.session->zstd_data), 0) < 0)
841 pr_warning("Decompression initialization failed.\n");
842
840 if (inject.build_ids) { 843 if (inject.build_ids) {
841 /* 844 /*
842 * to make sure the mmap records are ordered correctly 845 * to make sure the mmap records are ordered correctly
@@ -867,6 +870,7 @@ int cmd_inject(int argc, const char **argv)
867 ret = __cmd_inject(&inject); 870 ret = __cmd_inject(&inject);
868 871
869out_delete: 872out_delete:
873 zstd_fini(&(inject.session->zstd_data));
870 perf_session__delete(inject.session); 874 perf_session__delete(inject.session);
871 return ret; 875 return ret;
872} 876}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index c5e10552776a..e2c3a585a61e 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -133,6 +133,11 @@ static int record__write(struct record *rec, struct perf_mmap *map __maybe_unuse
133 return 0; 133 return 0;
134} 134}
135 135
136static int record__aio_enabled(struct record *rec);
137static int record__comp_enabled(struct record *rec);
138static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_size,
139 void *src, size_t src_size);
140
136#ifdef HAVE_AIO_SUPPORT 141#ifdef HAVE_AIO_SUPPORT
137static int record__aio_write(struct aiocb *cblock, int trace_fd, 142static int record__aio_write(struct aiocb *cblock, int trace_fd,
138 void *buf, size_t size, off_t off) 143 void *buf, size_t size, off_t off)
@@ -183,9 +188,9 @@ static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock)
183 if (rem_size == 0) { 188 if (rem_size == 0) {
184 cblock->aio_fildes = -1; 189 cblock->aio_fildes = -1;
185 /* 190 /*
186 * md->refcount is incremented in perf_mmap__push() for 191 * md->refcount is incremented in record__aio_pushfn() for
187 * every enqueued aio write request so decrement it because 192 * every aio write request started in record__aio_push() so
188 * the request is now complete. 193 * decrement it because the request is now complete.
189 */ 194 */
190 perf_mmap__put(md); 195 perf_mmap__put(md);
191 rc = 1; 196 rc = 1;
@@ -240,18 +245,89 @@ static int record__aio_sync(struct perf_mmap *md, bool sync_all)
240 } while (1); 245 } while (1);
241} 246}
242 247
243static int record__aio_pushfn(void *to, struct aiocb *cblock, void *bf, size_t size, off_t off) 248struct record_aio {
249 struct record *rec;
250 void *data;
251 size_t size;
252};
253
254static int record__aio_pushfn(struct perf_mmap *map, void *to, void *buf, size_t size)
244{ 255{
245 struct record *rec = to; 256 struct record_aio *aio = to;
246 int ret, trace_fd = rec->session->data->file.fd;
247 257
248 rec->samples++; 258 /*
259 * map->base data pointed by buf is copied into free map->aio.data[] buffer
260 * to release space in the kernel buffer as fast as possible, calling
261 * perf_mmap__consume() from perf_mmap__push() function.
262 *
263 * That lets the kernel to proceed with storing more profiling data into
264 * the kernel buffer earlier than other per-cpu kernel buffers are handled.
265 *
266 * Coping can be done in two steps in case the chunk of profiling data
267 * crosses the upper bound of the kernel buffer. In this case we first move
268 * part of data from map->start till the upper bound and then the reminder
269 * from the beginning of the kernel buffer till the end of the data chunk.
270 */
271
272 if (record__comp_enabled(aio->rec)) {
273 size = zstd_compress(aio->rec->session, aio->data + aio->size,
274 perf_mmap__mmap_len(map) - aio->size,
275 buf, size);
276 } else {
277 memcpy(aio->data + aio->size, buf, size);
278 }
279
280 if (!aio->size) {
281 /*
282 * Increment map->refcount to guard map->aio.data[] buffer
283 * from premature deallocation because map object can be
284 * released earlier than aio write request started on
285 * map->aio.data[] buffer is complete.
286 *
287 * perf_mmap__put() is done at record__aio_complete()
288 * after started aio request completion or at record__aio_push()
289 * if the request failed to start.
290 */
291 perf_mmap__get(map);
292 }
293
294 aio->size += size;
295
296 return size;
297}
249 298
250 ret = record__aio_write(cblock, trace_fd, bf, size, off); 299static int record__aio_push(struct record *rec, struct perf_mmap *map, off_t *off)
300{
301 int ret, idx;
302 int trace_fd = rec->session->data->file.fd;
303 struct record_aio aio = { .rec = rec, .size = 0 };
304
305 /*
306 * Call record__aio_sync() to wait till map->aio.data[] buffer
307 * becomes available after previous aio write operation.
308 */
309
310 idx = record__aio_sync(map, false);
311 aio.data = map->aio.data[idx];
312 ret = perf_mmap__push(map, &aio, record__aio_pushfn);
313 if (ret != 0) /* ret > 0 - no data, ret < 0 - error */
314 return ret;
315
316 rec->samples++;
317 ret = record__aio_write(&(map->aio.cblocks[idx]), trace_fd, aio.data, aio.size, *off);
251 if (!ret) { 318 if (!ret) {
252 rec->bytes_written += size; 319 *off += aio.size;
320 rec->bytes_written += aio.size;
253 if (switch_output_size(rec)) 321 if (switch_output_size(rec))
254 trigger_hit(&switch_output_trigger); 322 trigger_hit(&switch_output_trigger);
323 } else {
324 /*
325 * Decrement map->refcount incremented in record__aio_pushfn()
326 * back if record__aio_write() operation failed to start, otherwise
327 * map->refcount is decremented in record__aio_complete() after
328 * aio write operation finishes successfully.
329 */
330 perf_mmap__put(map);
255 } 331 }
256 332
257 return ret; 333 return ret;
@@ -273,7 +349,7 @@ static void record__aio_mmap_read_sync(struct record *rec)
273 struct perf_evlist *evlist = rec->evlist; 349 struct perf_evlist *evlist = rec->evlist;
274 struct perf_mmap *maps = evlist->mmap; 350 struct perf_mmap *maps = evlist->mmap;
275 351
276 if (!rec->opts.nr_cblocks) 352 if (!record__aio_enabled(rec))
277 return; 353 return;
278 354
279 for (i = 0; i < evlist->nr_mmaps; i++) { 355 for (i = 0; i < evlist->nr_mmaps; i++) {
@@ -307,13 +383,8 @@ static int record__aio_parse(const struct option *opt,
307#else /* HAVE_AIO_SUPPORT */ 383#else /* HAVE_AIO_SUPPORT */
308static int nr_cblocks_max = 0; 384static int nr_cblocks_max = 0;
309 385
310static int record__aio_sync(struct perf_mmap *md __maybe_unused, bool sync_all __maybe_unused) 386static int record__aio_push(struct record *rec __maybe_unused, struct perf_mmap *map __maybe_unused,
311{ 387 off_t *off __maybe_unused)
312 return -1;
313}
314
315static int record__aio_pushfn(void *to __maybe_unused, struct aiocb *cblock __maybe_unused,
316 void *bf __maybe_unused, size_t size __maybe_unused, off_t off __maybe_unused)
317{ 388{
318 return -1; 389 return -1;
319} 390}
@@ -372,6 +443,32 @@ static int record__mmap_flush_parse(const struct option *opt,
372 return 0; 443 return 0;
373} 444}
374 445
446#ifdef HAVE_ZSTD_SUPPORT
447static unsigned int comp_level_default = 1;
448
449static int record__parse_comp_level(const struct option *opt, const char *str, int unset)
450{
451 struct record_opts *opts = opt->value;
452
453 if (unset) {
454 opts->comp_level = 0;
455 } else {
456 if (str)
457 opts->comp_level = strtol(str, NULL, 0);
458 if (!opts->comp_level)
459 opts->comp_level = comp_level_default;
460 }
461
462 return 0;
463}
464#endif
465static unsigned int comp_level_max = 22;
466
467static int record__comp_enabled(struct record *rec)
468{
469 return rec->opts.comp_level > 0;
470}
471
375static int process_synthesized_event(struct perf_tool *tool, 472static int process_synthesized_event(struct perf_tool *tool,
376 union perf_event *event, 473 union perf_event *event,
377 struct perf_sample *sample __maybe_unused, 474 struct perf_sample *sample __maybe_unused,
@@ -385,6 +482,11 @@ static int record__pushfn(struct perf_mmap *map, void *to, void *bf, size_t size
385{ 482{
386 struct record *rec = to; 483 struct record *rec = to;
387 484
485 if (record__comp_enabled(rec)) {
486 size = zstd_compress(rec->session, map->data, perf_mmap__mmap_len(map), bf, size);
487 bf = map->data;
488 }
489
388 rec->samples++; 490 rec->samples++;
389 return record__write(rec, map, bf, size); 491 return record__write(rec, map, bf, size);
390} 492}
@@ -582,7 +684,7 @@ static int record__mmap_evlist(struct record *rec,
582 opts->auxtrace_mmap_pages, 684 opts->auxtrace_mmap_pages,
583 opts->auxtrace_snapshot_mode, 685 opts->auxtrace_snapshot_mode,
584 opts->nr_cblocks, opts->affinity, 686 opts->nr_cblocks, opts->affinity,
585 opts->mmap_flush) < 0) { 687 opts->mmap_flush, opts->comp_level) < 0) {
586 if (errno == EPERM) { 688 if (errno == EPERM) {
587 pr_err("Permission error mapping pages.\n" 689 pr_err("Permission error mapping pages.\n"
588 "Consider increasing " 690 "Consider increasing "
@@ -771,6 +873,37 @@ static void record__adjust_affinity(struct record *rec, struct perf_mmap *map)
771 } 873 }
772} 874}
773 875
876static size_t process_comp_header(void *record, size_t increment)
877{
878 struct compressed_event *event = record;
879 size_t size = sizeof(*event);
880
881 if (increment) {
882 event->header.size += increment;
883 return increment;
884 }
885
886 event->header.type = PERF_RECORD_COMPRESSED;
887 event->header.size = size;
888
889 return size;
890}
891
892static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_size,
893 void *src, size_t src_size)
894{
895 size_t compressed;
896 size_t max_record_size = PERF_SAMPLE_MAX_SIZE - sizeof(struct compressed_event) - 1;
897
898 compressed = zstd_compress_stream_to_records(&session->zstd_data, dst, dst_size, src, src_size,
899 max_record_size, process_comp_header);
900
901 session->bytes_transferred += src_size;
902 session->bytes_compressed += compressed;
903
904 return compressed;
905}
906
774static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist, 907static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist,
775 bool overwrite, bool synch) 908 bool overwrite, bool synch)
776{ 909{
@@ -779,7 +912,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli
779 int rc = 0; 912 int rc = 0;
780 struct perf_mmap *maps; 913 struct perf_mmap *maps;
781 int trace_fd = rec->data.file.fd; 914 int trace_fd = rec->data.file.fd;
782 off_t off; 915 off_t off = 0;
783 916
784 if (!evlist) 917 if (!evlist)
785 return 0; 918 return 0;
@@ -805,20 +938,14 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli
805 map->flush = 1; 938 map->flush = 1;
806 } 939 }
807 if (!record__aio_enabled(rec)) { 940 if (!record__aio_enabled(rec)) {
808 if (perf_mmap__push(map, rec, record__pushfn) != 0) { 941 if (perf_mmap__push(map, rec, record__pushfn) < 0) {
809 if (synch) 942 if (synch)
810 map->flush = flush; 943 map->flush = flush;
811 rc = -1; 944 rc = -1;
812 goto out; 945 goto out;
813 } 946 }
814 } else { 947 } else {
815 int idx; 948 if (record__aio_push(rec, map, &off) < 0) {
816 /*
817 * Call record__aio_sync() to wait till map->data buffer
818 * becomes available after previous aio write request.
819 */
820 idx = record__aio_sync(map, false);
821 if (perf_mmap__aio_push(map, rec, idx, record__aio_pushfn, &off) != 0) {
822 record__aio_set_pos(trace_fd, off); 949 record__aio_set_pos(trace_fd, off);
823 if (synch) 950 if (synch)
824 map->flush = flush; 951 map->flush = flush;
@@ -888,6 +1015,8 @@ static void record__init_features(struct record *rec)
888 perf_header__clear_feat(&session->header, HEADER_CLOCKID); 1015 perf_header__clear_feat(&session->header, HEADER_CLOCKID);
889 1016
890 perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT); 1017 perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
1018 if (!record__comp_enabled(rec))
1019 perf_header__clear_feat(&session->header, HEADER_COMPRESSED);
891 1020
892 perf_header__clear_feat(&session->header, HEADER_STAT); 1021 perf_header__clear_feat(&session->header, HEADER_STAT);
893} 1022}
@@ -1186,6 +1315,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
1186 bool disabled = false, draining = false; 1315 bool disabled = false, draining = false;
1187 struct perf_evlist *sb_evlist = NULL; 1316 struct perf_evlist *sb_evlist = NULL;
1188 int fd; 1317 int fd;
1318 float ratio = 0;
1189 1319
1190 atexit(record__sig_exit); 1320 atexit(record__sig_exit);
1191 signal(SIGCHLD, sig_handler); 1321 signal(SIGCHLD, sig_handler);
@@ -1215,6 +1345,14 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
1215 fd = perf_data__fd(data); 1345 fd = perf_data__fd(data);
1216 rec->session = session; 1346 rec->session = session;
1217 1347
1348 if (zstd_init(&session->zstd_data, rec->opts.comp_level) < 0) {
1349 pr_err("Compression initialization failed.\n");
1350 return -1;
1351 }
1352
1353 session->header.env.comp_type = PERF_COMP_ZSTD;
1354 session->header.env.comp_level = rec->opts.comp_level;
1355
1218 record__init_features(rec); 1356 record__init_features(rec);
1219 1357
1220 if (rec->opts.use_clockid && rec->opts.clockid_res_ns) 1358 if (rec->opts.use_clockid && rec->opts.clockid_res_ns)
@@ -1244,6 +1382,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
1244 err = -1; 1382 err = -1;
1245 goto out_child; 1383 goto out_child;
1246 } 1384 }
1385 session->header.env.comp_mmap_len = session->evlist->mmap_len;
1247 1386
1248 err = bpf__apply_obj_config(); 1387 err = bpf__apply_obj_config();
1249 if (err) { 1388 if (err) {
@@ -1491,6 +1630,11 @@ out_child:
1491 record__mmap_read_all(rec, true); 1630 record__mmap_read_all(rec, true);
1492 record__aio_mmap_read_sync(rec); 1631 record__aio_mmap_read_sync(rec);
1493 1632
1633 if (rec->session->bytes_transferred && rec->session->bytes_compressed) {
1634 ratio = (float)rec->session->bytes_transferred/(float)rec->session->bytes_compressed;
1635 session->header.env.comp_ratio = ratio + 0.5;
1636 }
1637
1494 if (forks) { 1638 if (forks) {
1495 int exit_status; 1639 int exit_status;
1496 1640
@@ -1537,12 +1681,19 @@ out_child:
1537 else 1681 else
1538 samples[0] = '\0'; 1682 samples[0] = '\0';
1539 1683
1540 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n", 1684 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s",
1541 perf_data__size(data) / 1024.0 / 1024.0, 1685 perf_data__size(data) / 1024.0 / 1024.0,
1542 data->path, postfix, samples); 1686 data->path, postfix, samples);
1687 if (ratio) {
1688 fprintf(stderr, ", compressed (original %.3f MB, ratio is %.3f)",
1689 rec->session->bytes_transferred / 1024.0 / 1024.0,
1690 ratio);
1691 }
1692 fprintf(stderr, " ]\n");
1543 } 1693 }
1544 1694
1545out_delete_session: 1695out_delete_session:
1696 zstd_fini(&session->zstd_data);
1546 perf_session__delete(session); 1697 perf_session__delete(session);
1547 1698
1548 if (!opts->no_bpf_event) 1699 if (!opts->no_bpf_event)
@@ -2017,10 +2168,10 @@ static struct option __record_options[] = {
2017 "use per-thread mmaps"), 2168 "use per-thread mmaps"),
2018 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register", 2169 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
2019 "sample selected machine registers on interrupt," 2170 "sample selected machine registers on interrupt,"
2020 " use -I ? to list register names", parse_regs), 2171 " use '-I?' to list register names", parse_intr_regs),
2021 OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register", 2172 OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register",
2022 "sample selected machine registers on interrupt," 2173 "sample selected machine registers on interrupt,"
2023 " use -I ? to list register names", parse_regs), 2174 " use '--user-regs=?' to list register names", parse_user_regs),
2024 OPT_BOOLEAN(0, "running-time", &record.opts.running_time, 2175 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
2025 "Record running/enabled time of read (:S) events"), 2176 "Record running/enabled time of read (:S) events"),
2026 OPT_CALLBACK('k', "clockid", &record.opts, 2177 OPT_CALLBACK('k', "clockid", &record.opts,
@@ -2068,6 +2219,11 @@ static struct option __record_options[] = {
2068 OPT_CALLBACK(0, "affinity", &record.opts, "node|cpu", 2219 OPT_CALLBACK(0, "affinity", &record.opts, "node|cpu",
2069 "Set affinity mask of trace reading thread to NUMA node cpu mask or cpu of processed mmap buffer", 2220 "Set affinity mask of trace reading thread to NUMA node cpu mask or cpu of processed mmap buffer",
2070 record__parse_affinity), 2221 record__parse_affinity),
2222#ifdef HAVE_ZSTD_SUPPORT
2223 OPT_CALLBACK_OPTARG('z', "compression-level", &record.opts, &comp_level_default,
2224 "n", "Compressed records using specified level (default: 1 - fastest compression, 22 - greatest compression)",
2225 record__parse_comp_level),
2226#endif
2071 OPT_END() 2227 OPT_END()
2072}; 2228};
2073 2229
@@ -2127,6 +2283,12 @@ int cmd_record(int argc, const char **argv)
2127 "cgroup monitoring only available in system-wide mode"); 2283 "cgroup monitoring only available in system-wide mode");
2128 2284
2129 } 2285 }
2286
2287 if (rec->opts.comp_level != 0) {
2288 pr_debug("Compression enabled, disabling build id collection at the end of the session.\n");
2289 rec->no_buildid = true;
2290 }
2291
2130 if (rec->opts.record_switch_events && 2292 if (rec->opts.record_switch_events &&
2131 !perf_can_record_switch_events()) { 2293 !perf_can_record_switch_events()) {
2132 ui__error("kernel does not support recording context switch events\n"); 2294 ui__error("kernel does not support recording context switch events\n");
@@ -2272,12 +2434,15 @@ int cmd_record(int argc, const char **argv)
2272 2434
2273 if (rec->opts.nr_cblocks > nr_cblocks_max) 2435 if (rec->opts.nr_cblocks > nr_cblocks_max)
2274 rec->opts.nr_cblocks = nr_cblocks_max; 2436 rec->opts.nr_cblocks = nr_cblocks_max;
2275 if (verbose > 0) 2437 pr_debug("nr_cblocks: %d\n", rec->opts.nr_cblocks);
2276 pr_info("nr_cblocks: %d\n", rec->opts.nr_cblocks);
2277 2438
2278 pr_debug("affinity: %s\n", affinity_tags[rec->opts.affinity]); 2439 pr_debug("affinity: %s\n", affinity_tags[rec->opts.affinity]);
2279 pr_debug("mmap flush: %d\n", rec->opts.mmap_flush); 2440 pr_debug("mmap flush: %d\n", rec->opts.mmap_flush);
2280 2441
2442 if (rec->opts.comp_level > comp_level_max)
2443 rec->opts.comp_level = comp_level_max;
2444 pr_debug("comp level: %d\n", rec->opts.comp_level);
2445
2281 err = __cmd_record(&record, argc, argv); 2446 err = __cmd_record(&record, argc, argv);
2282out: 2447out:
2283 perf_evlist__delete(rec->evlist); 2448 perf_evlist__delete(rec->evlist);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 4054eb1f98ac..1ca533f06a4c 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -136,9 +136,6 @@ static int hist_iter__report_callback(struct hist_entry_iter *iter,
136 if (!ui__has_annotation() && !rep->symbol_ipc) 136 if (!ui__has_annotation() && !rep->symbol_ipc)
137 return 0; 137 return 0;
138 138
139 hist__account_cycles(sample->branch_stack, al, sample,
140 rep->nonany_branch_mode);
141
142 if (sort__mode == SORT_MODE__BRANCH) { 139 if (sort__mode == SORT_MODE__BRANCH) {
143 bi = he->branch_info; 140 bi = he->branch_info;
144 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel); 141 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
@@ -181,9 +178,6 @@ static int hist_iter__branch_callback(struct hist_entry_iter *iter,
181 if (!ui__has_annotation() && !rep->symbol_ipc) 178 if (!ui__has_annotation() && !rep->symbol_ipc)
182 return 0; 179 return 0;
183 180
184 hist__account_cycles(sample->branch_stack, al, sample,
185 rep->nonany_branch_mode);
186
187 bi = he->branch_info; 181 bi = he->branch_info;
188 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel); 182 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
189 if (err) 183 if (err)
@@ -282,6 +276,11 @@ static int process_sample_event(struct perf_tool *tool,
282 if (al.map != NULL) 276 if (al.map != NULL)
283 al.map->dso->hit = 1; 277 al.map->dso->hit = 1;
284 278
279 if (ui__has_annotation() || rep->symbol_ipc) {
280 hist__account_cycles(sample->branch_stack, &al, sample,
281 rep->nonany_branch_mode);
282 }
283
285 ret = hist_entry_iter__add(&iter, &al, rep->max_stack, rep); 284 ret = hist_entry_iter__add(&iter, &al, rep->max_stack, rep);
286 if (ret < 0) 285 if (ret < 0)
287 pr_debug("problem adding hist entry, skipping event\n"); 286 pr_debug("problem adding hist entry, skipping event\n");
@@ -1259,6 +1258,9 @@ repeat:
1259 if (session == NULL) 1258 if (session == NULL)
1260 return -1; 1259 return -1;
1261 1260
1261 if (zstd_init(&(session->zstd_data), 0) < 0)
1262 pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");
1263
1262 if (report.queue_size) { 1264 if (report.queue_size) {
1263 ordered_events__set_alloc_size(&session->ordered_events, 1265 ordered_events__set_alloc_size(&session->ordered_events,
1264 report.queue_size); 1266 report.queue_size);
@@ -1449,7 +1451,7 @@ repeat:
1449error: 1451error:
1450 if (report.ptime_range) 1452 if (report.ptime_range)
1451 zfree(&report.ptime_range); 1453 zfree(&report.ptime_range);
1452 1454 zstd_fini(&(session->zstd_data));
1453 perf_session__delete(session); 1455 perf_session__delete(session);
1454 return ret; 1456 return ret;
1455} 1457}
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a3c060878faa..24b8e690fb69 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -847,6 +847,18 @@ static int perf_stat__get_core_cached(struct perf_stat_config *config,
847 return perf_stat__get_aggr(config, perf_stat__get_core, map, idx); 847 return perf_stat__get_aggr(config, perf_stat__get_core, map, idx);
848} 848}
849 849
850static bool term_percore_set(void)
851{
852 struct perf_evsel *counter;
853
854 evlist__for_each_entry(evsel_list, counter) {
855 if (counter->percore)
856 return true;
857 }
858
859 return false;
860}
861
850static int perf_stat_init_aggr_mode(void) 862static int perf_stat_init_aggr_mode(void)
851{ 863{
852 int nr; 864 int nr;
@@ -867,6 +879,15 @@ static int perf_stat_init_aggr_mode(void)
867 stat_config.aggr_get_id = perf_stat__get_core_cached; 879 stat_config.aggr_get_id = perf_stat__get_core_cached;
868 break; 880 break;
869 case AGGR_NONE: 881 case AGGR_NONE:
882 if (term_percore_set()) {
883 if (cpu_map__build_core_map(evsel_list->cpus,
884 &stat_config.aggr_map)) {
885 perror("cannot build core map");
886 return -1;
887 }
888 stat_config.aggr_get_id = perf_stat__get_core_cached;
889 }
890 break;
870 case AGGR_GLOBAL: 891 case AGGR_GLOBAL:
871 case AGGR_THREAD: 892 case AGGR_THREAD:
872 case AGGR_UNSET: 893 case AGGR_UNSET:
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 369eae61068d..d59dee61b64d 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -86,6 +86,7 @@ struct record_opts {
86 int nr_cblocks; 86 int nr_cblocks;
87 int affinity; 87 int affinity;
88 int mmap_flush; 88 int mmap_flush;
89 unsigned int comp_level;
89}; 90};
90 91
91enum perf_affinity { 92enum perf_affinity {
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a57-a72/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a57-a72/core-imp-def.json
new file mode 100644
index 000000000000..0ac9b7927450
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a57-a72/core-imp-def.json
@@ -0,0 +1,179 @@
1[
2 {
3 "ArchStdEvent": "L1D_CACHE_RD",
4 },
5 {
6 "ArchStdEvent": "L1D_CACHE_WR",
7 },
8 {
9 "ArchStdEvent": "L1D_CACHE_REFILL_RD",
10 },
11 {
12 "ArchStdEvent": "L1D_CACHE_REFILL_WR",
13 },
14 {
15 "ArchStdEvent": "L1D_CACHE_WB_VICTIM",
16 },
17 {
18 "ArchStdEvent": "L1D_CACHE_WB_CLEAN",
19 },
20 {
21 "ArchStdEvent": "L1D_CACHE_INVAL",
22 },
23 {
24 "ArchStdEvent": "L1D_TLB_REFILL_RD",
25 },
26 {
27 "ArchStdEvent": "L1D_TLB_REFILL_WR",
28 },
29 {
30 "ArchStdEvent": "L2D_CACHE_RD",
31 },
32 {
33 "ArchStdEvent": "L2D_CACHE_WR",
34 },
35 {
36 "ArchStdEvent": "L2D_CACHE_REFILL_RD",
37 },
38 {
39 "ArchStdEvent": "L2D_CACHE_REFILL_WR",
40 },
41 {
42 "ArchStdEvent": "L2D_CACHE_WB_VICTIM",
43 },
44 {
45 "ArchStdEvent": "L2D_CACHE_WB_CLEAN",
46 },
47 {
48 "ArchStdEvent": "L2D_CACHE_INVAL",
49 },
50 {
51 "ArchStdEvent": "BUS_ACCESS_RD",
52 },
53 {
54 "ArchStdEvent": "BUS_ACCESS_WR",
55 },
56 {
57 "ArchStdEvent": "BUS_ACCESS_SHARED",
58 },
59 {
60 "ArchStdEvent": "BUS_ACCESS_NOT_SHARED",
61 },
62 {
63 "ArchStdEvent": "BUS_ACCESS_NORMAL",
64 },
65 {
66 "ArchStdEvent": "BUS_ACCESS_PERIPH",
67 },
68 {
69 "ArchStdEvent": "MEM_ACCESS_RD",
70 },
71 {
72 "ArchStdEvent": "MEM_ACCESS_WR",
73 },
74 {
75 "ArchStdEvent": "UNALIGNED_LD_SPEC",
76 },
77 {
78 "ArchStdEvent": "UNALIGNED_ST_SPEC",
79 },
80 {
81 "ArchStdEvent": "UNALIGNED_LDST_SPEC",
82 },
83 {
84 "ArchStdEvent": "LDREX_SPEC",
85 },
86 {
87 "ArchStdEvent": "STREX_PASS_SPEC",
88 },
89 {
90 "ArchStdEvent": "STREX_FAIL_SPEC",
91 },
92 {
93 "ArchStdEvent": "LD_SPEC",
94 },
95 {
96 "ArchStdEvent": "ST_SPEC",
97 },
98 {
99 "ArchStdEvent": "LDST_SPEC",
100 },
101 {
102 "ArchStdEvent": "DP_SPEC",
103 },
104 {
105 "ArchStdEvent": "ASE_SPEC",
106 },
107 {
108 "ArchStdEvent": "VFP_SPEC",
109 },
110 {
111 "ArchStdEvent": "PC_WRITE_SPEC",
112 },
113 {
114 "ArchStdEvent": "CRYPTO_SPEC",
115 },
116 {
117 "ArchStdEvent": "BR_IMMED_SPEC",
118 },
119 {
120 "ArchStdEvent": "BR_RETURN_SPEC",
121 },
122 {
123 "ArchStdEvent": "BR_INDIRECT_SPEC",
124 },
125 {
126 "ArchStdEvent": "ISB_SPEC",
127 },
128 {
129 "ArchStdEvent": "DSB_SPEC",
130 },
131 {
132 "ArchStdEvent": "DMB_SPEC",
133 },
134 {
135 "ArchStdEvent": "EXC_UNDEF",
136 },
137 {
138 "ArchStdEvent": "EXC_SVC",
139 },
140 {
141 "ArchStdEvent": "EXC_PABORT",
142 },
143 {
144 "ArchStdEvent": "EXC_DABORT",
145 },
146 {
147 "ArchStdEvent": "EXC_IRQ",
148 },
149 {
150 "ArchStdEvent": "EXC_FIQ",
151 },
152 {
153 "ArchStdEvent": "EXC_SMC",
154 },
155 {
156 "ArchStdEvent": "EXC_HVC",
157 },
158 {
159 "ArchStdEvent": "EXC_TRAP_PABORT",
160 },
161 {
162 "ArchStdEvent": "EXC_TRAP_DABORT",
163 },
164 {
165 "ArchStdEvent": "EXC_TRAP_OTHER",
166 },
167 {
168 "ArchStdEvent": "EXC_TRAP_IRQ",
169 },
170 {
171 "ArchStdEvent": "EXC_TRAP_FIQ",
172 },
173 {
174 "ArchStdEvent": "RC_LD_SPEC",
175 },
176 {
177 "ArchStdEvent": "RC_ST_SPEC",
178 },
179]
diff --git a/tools/perf/pmu-events/arch/arm64/mapfile.csv b/tools/perf/pmu-events/arch/arm64/mapfile.csv
index 59cd8604b0bd..927fcddcb4aa 100644
--- a/tools/perf/pmu-events/arch/arm64/mapfile.csv
+++ b/tools/perf/pmu-events/arch/arm64/mapfile.csv
@@ -12,7 +12,10 @@
12# 12#
13# 13#
14#Family-model,Version,Filename,EventType 14#Family-model,Version,Filename,EventType
150x00000000410fd03[[:xdigit:]],v1,arm/cortex-a53,core 150x00000000410fd030,v1,arm/cortex-a53,core
160x00000000420f1000,v1,arm/cortex-a53,core
170x00000000410fd070,v1,arm/cortex-a57-a72,core
180x00000000410fd080,v1,arm/cortex-a57-a72,core
160x00000000420f5160,v1,cavium/thunderx2,core 190x00000000420f5160,v1,cavium/thunderx2,core
170x00000000430f0af0,v1,cavium/thunderx2,core 200x00000000430f0af0,v1,cavium/thunderx2,core
180x00000000480fd010,v1,hisilicon/hip08,core 210x00000000480fd010,v1,hisilicon/hip08,core
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 68c92bb599ee..58f77fd0f59f 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -235,6 +235,7 @@ static struct map {
235 { "iMPH-U", "uncore_arb" }, 235 { "iMPH-U", "uncore_arb" },
236 { "CPU-M-CF", "cpum_cf" }, 236 { "CPU-M-CF", "cpum_cf" },
237 { "CPU-M-SF", "cpum_sf" }, 237 { "CPU-M-SF", "cpum_sf" },
238 { "UPI LL", "uncore_upi" },
238 {} 239 {}
239}; 240};
240 241
@@ -414,7 +415,6 @@ static int save_arch_std_events(void *data, char *name, char *event,
414 char *metric_name, char *metric_group) 415 char *metric_name, char *metric_group)
415{ 416{
416 struct event_struct *es; 417 struct event_struct *es;
417 struct stat *sb = data;
418 418
419 es = malloc(sizeof(*es)); 419 es = malloc(sizeof(*es));
420 if (!es) 420 if (!es)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index 74ef92f1d19a..affed7d149be 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -456,6 +456,10 @@ class CallGraphLevelItemBase(object):
456 self.query_done = False; 456 self.query_done = False;
457 self.child_count = 0 457 self.child_count = 0
458 self.child_items = [] 458 self.child_items = []
459 if parent_item:
460 self.level = parent_item.level + 1
461 else:
462 self.level = 0
459 463
460 def getChildItem(self, row): 464 def getChildItem(self, row):
461 return self.child_items[row] 465 return self.child_items[row]
@@ -877,9 +881,14 @@ class TreeWindowBase(QMdiSubWindow):
877 super(TreeWindowBase, self).__init__(parent) 881 super(TreeWindowBase, self).__init__(parent)
878 882
879 self.model = None 883 self.model = None
880 self.view = None
881 self.find_bar = None 884 self.find_bar = None
882 885
886 self.view = QTreeView()
887 self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
888 self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
889
890 self.context_menu = TreeContextMenu(self.view)
891
883 def DisplayFound(self, ids): 892 def DisplayFound(self, ids):
884 if not len(ids): 893 if not len(ids):
885 return False 894 return False
@@ -921,7 +930,6 @@ class CallGraphWindow(TreeWindowBase):
921 930
922 self.model = LookupCreateModel("Context-Sensitive Call Graph", lambda x=glb: CallGraphModel(x)) 931 self.model = LookupCreateModel("Context-Sensitive Call Graph", lambda x=glb: CallGraphModel(x))
923 932
924 self.view = QTreeView()
925 self.view.setModel(self.model) 933 self.view.setModel(self.model)
926 934
927 for c, w in ((0, 250), (1, 100), (2, 60), (3, 70), (4, 70), (5, 100)): 935 for c, w in ((0, 250), (1, 100), (2, 60), (3, 70), (4, 70), (5, 100)):
@@ -944,7 +952,6 @@ class CallTreeWindow(TreeWindowBase):
944 952
945 self.model = LookupCreateModel("Call Tree", lambda x=glb: CallTreeModel(x)) 953 self.model = LookupCreateModel("Call Tree", lambda x=glb: CallTreeModel(x))
946 954
947 self.view = QTreeView()
948 self.view.setModel(self.model) 955 self.view.setModel(self.model)
949 956
950 for c, w in ((0, 230), (1, 100), (2, 100), (3, 70), (4, 70), (5, 100)): 957 for c, w in ((0, 230), (1, 100), (2, 100), (3, 70), (4, 70), (5, 100)):
@@ -1649,10 +1656,14 @@ class BranchWindow(QMdiSubWindow):
1649 1656
1650 self.view = QTreeView() 1657 self.view = QTreeView()
1651 self.view.setUniformRowHeights(True) 1658 self.view.setUniformRowHeights(True)
1659 self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
1660 self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
1652 self.view.setModel(self.model) 1661 self.view.setModel(self.model)
1653 1662
1654 self.ResizeColumnsToContents() 1663 self.ResizeColumnsToContents()
1655 1664
1665 self.context_menu = TreeContextMenu(self.view)
1666
1656 self.find_bar = FindBar(self, self, True) 1667 self.find_bar = FindBar(self, self, True)
1657 1668
1658 self.finder = ChildDataItemFinder(self.model.root) 1669 self.finder = ChildDataItemFinder(self.model.root)
@@ -2261,6 +2272,240 @@ class ResizeColumnsToContentsBase(QObject):
2261 self.data_model.rowsInserted.disconnect(self.UpdateColumnWidths) 2272 self.data_model.rowsInserted.disconnect(self.UpdateColumnWidths)
2262 self.ResizeColumnsToContents() 2273 self.ResizeColumnsToContents()
2263 2274
2275# Convert value to CSV
2276
2277def ToCSValue(val):
2278 if '"' in val:
2279 val = val.replace('"', '""')
2280 if "," in val or '"' in val:
2281 val = '"' + val + '"'
2282 return val
2283
2284# Key to sort table model indexes by row / column, assuming fewer than 1000 columns
2285
2286glb_max_cols = 1000
2287
2288def RowColumnKey(a):
2289 return a.row() * glb_max_cols + a.column()
2290
2291# Copy selected table cells to clipboard
2292
2293def CopyTableCellsToClipboard(view, as_csv=False, with_hdr=False):
2294 indexes = sorted(view.selectedIndexes(), key=RowColumnKey)
2295 idx_cnt = len(indexes)
2296 if not idx_cnt:
2297 return
2298 if idx_cnt == 1:
2299 with_hdr=False
2300 min_row = indexes[0].row()
2301 max_row = indexes[0].row()
2302 min_col = indexes[0].column()
2303 max_col = indexes[0].column()
2304 for i in indexes:
2305 min_row = min(min_row, i.row())
2306 max_row = max(max_row, i.row())
2307 min_col = min(min_col, i.column())
2308 max_col = max(max_col, i.column())
2309 if max_col > glb_max_cols:
2310 raise RuntimeError("glb_max_cols is too low")
2311 max_width = [0] * (1 + max_col - min_col)
2312 for i in indexes:
2313 c = i.column() - min_col
2314 max_width[c] = max(max_width[c], len(str(i.data())))
2315 text = ""
2316 pad = ""
2317 sep = ""
2318 if with_hdr:
2319 model = indexes[0].model()
2320 for col in range(min_col, max_col + 1):
2321 val = model.headerData(col, Qt.Horizontal)
2322 if as_csv:
2323 text += sep + ToCSValue(val)
2324 sep = ","
2325 else:
2326 c = col - min_col
2327 max_width[c] = max(max_width[c], len(val))
2328 width = max_width[c]
2329 align = model.headerData(col, Qt.Horizontal, Qt.TextAlignmentRole)
2330 if align & Qt.AlignRight:
2331 val = val.rjust(width)
2332 text += pad + sep + val
2333 pad = " " * (width - len(val))
2334 sep = " "
2335 text += "\n"
2336 pad = ""
2337 sep = ""
2338 last_row = min_row
2339 for i in indexes:
2340 if i.row() > last_row:
2341 last_row = i.row()
2342 text += "\n"
2343 pad = ""
2344 sep = ""
2345 if as_csv:
2346 text += sep + ToCSValue(str(i.data()))
2347 sep = ","
2348 else:
2349 width = max_width[i.column() - min_col]
2350 if i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
2351 val = str(i.data()).rjust(width)
2352 else:
2353 val = str(i.data())
2354 text += pad + sep + val
2355 pad = " " * (width - len(val))
2356 sep = " "
2357 QApplication.clipboard().setText(text)
2358
2359def CopyTreeCellsToClipboard(view, as_csv=False, with_hdr=False):
2360 indexes = view.selectedIndexes()
2361 if not len(indexes):
2362 return
2363
2364 selection = view.selectionModel()
2365
2366 first = None
2367 for i in indexes:
2368 above = view.indexAbove(i)
2369 if not selection.isSelected(above):
2370 first = i
2371 break
2372
2373 if first is None:
2374 raise RuntimeError("CopyTreeCellsToClipboard internal error")
2375
2376 model = first.model()
2377 row_cnt = 0
2378 col_cnt = model.columnCount(first)
2379 max_width = [0] * col_cnt
2380
2381 indent_sz = 2
2382 indent_str = " " * indent_sz
2383
2384 expanded_mark_sz = 2
2385 if sys.version_info[0] == 3:
2386 expanded_mark = "\u25BC "
2387 not_expanded_mark = "\u25B6 "
2388 else:
2389 expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xBC) + " ", "utf-8")
2390 not_expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xB6) + " ", "utf-8")
2391 leaf_mark = " "
2392
2393 if not as_csv:
2394 pos = first
2395 while True:
2396 row_cnt += 1
2397 row = pos.row()
2398 for c in range(col_cnt):
2399 i = pos.sibling(row, c)
2400 if c:
2401 n = len(str(i.data()))
2402 else:
2403 n = len(str(i.data()).strip())
2404 n += (i.internalPointer().level - 1) * indent_sz
2405 n += expanded_mark_sz
2406 max_width[c] = max(max_width[c], n)
2407 pos = view.indexBelow(pos)
2408 if not selection.isSelected(pos):
2409 break
2410
2411 text = ""
2412 pad = ""
2413 sep = ""
2414 if with_hdr:
2415 for c in range(col_cnt):
2416 val = model.headerData(c, Qt.Horizontal, Qt.DisplayRole).strip()
2417 if as_csv:
2418 text += sep + ToCSValue(val)
2419 sep = ","
2420 else:
2421 max_width[c] = max(max_width[c], len(val))
2422 width = max_width[c]
2423 align = model.headerData(c, Qt.Horizontal, Qt.TextAlignmentRole)
2424 if align & Qt.AlignRight:
2425 val = val.rjust(width)
2426 text += pad + sep + val
2427 pad = " " * (width - len(val))
2428 sep = " "
2429 text += "\n"
2430 pad = ""
2431 sep = ""
2432
2433 pos = first
2434 while True:
2435 row = pos.row()
2436 for c in range(col_cnt):
2437 i = pos.sibling(row, c)
2438 val = str(i.data())
2439 if not c:
2440 if model.hasChildren(i):
2441 if view.isExpanded(i):
2442 mark = expanded_mark
2443 else:
2444 mark = not_expanded_mark
2445 else:
2446 mark = leaf_mark
2447 val = indent_str * (i.internalPointer().level - 1) + mark + val.strip()
2448 if as_csv:
2449 text += sep + ToCSValue(val)
2450 sep = ","
2451 else:
2452 width = max_width[c]
2453 if c and i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
2454 val = val.rjust(width)
2455 text += pad + sep + val
2456 pad = " " * (width - len(val))
2457 sep = " "
2458 pos = view.indexBelow(pos)
2459 if not selection.isSelected(pos):
2460 break
2461 text = text.rstrip() + "\n"
2462 pad = ""
2463 sep = ""
2464
2465 QApplication.clipboard().setText(text)
2466
2467def CopyCellsToClipboard(view, as_csv=False, with_hdr=False):
2468 view.CopyCellsToClipboard(view, as_csv, with_hdr)
2469
2470def CopyCellsToClipboardHdr(view):
2471 CopyCellsToClipboard(view, False, True)
2472
2473def CopyCellsToClipboardCSV(view):
2474 CopyCellsToClipboard(view, True, True)
2475
2476# Context menu
2477
2478class ContextMenu(object):
2479
2480 def __init__(self, view):
2481 self.view = view
2482 self.view.setContextMenuPolicy(Qt.CustomContextMenu)
2483 self.view.customContextMenuRequested.connect(self.ShowContextMenu)
2484
2485 def ShowContextMenu(self, pos):
2486 menu = QMenu(self.view)
2487 self.AddActions(menu)
2488 menu.exec_(self.view.mapToGlobal(pos))
2489
2490 def AddCopy(self, menu):
2491 menu.addAction(CreateAction("&Copy selection", "Copy to clipboard", lambda: CopyCellsToClipboardHdr(self.view), self.view))
2492 menu.addAction(CreateAction("Copy selection as CS&V", "Copy to clipboard as CSV", lambda: CopyCellsToClipboardCSV(self.view), self.view))
2493
2494 def AddActions(self, menu):
2495 self.AddCopy(menu)
2496
2497class TreeContextMenu(ContextMenu):
2498
2499 def __init__(self, view):
2500 super(TreeContextMenu, self).__init__(view)
2501
2502 def AddActions(self, menu):
2503 i = self.view.currentIndex()
2504 text = str(i.data()).strip()
2505 if len(text):
2506 menu.addAction(CreateAction('Copy "' + text + '"', "Copy to clipboard", lambda: QApplication.clipboard().setText(text), self.view))
2507 self.AddCopy(menu)
2508
2264# Table window 2509# Table window
2265 2510
2266class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase): 2511class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
@@ -2279,9 +2524,13 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
2279 self.view.verticalHeader().setVisible(False) 2524 self.view.verticalHeader().setVisible(False)
2280 self.view.sortByColumn(-1, Qt.AscendingOrder) 2525 self.view.sortByColumn(-1, Qt.AscendingOrder)
2281 self.view.setSortingEnabled(True) 2526 self.view.setSortingEnabled(True)
2527 self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
2528 self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
2282 2529
2283 self.ResizeColumnsToContents() 2530 self.ResizeColumnsToContents()
2284 2531
2532 self.context_menu = ContextMenu(self.view)
2533
2285 self.find_bar = FindBar(self, self, True) 2534 self.find_bar = FindBar(self, self, True)
2286 2535
2287 self.finder = ChildDataItemFinder(self.data_model) 2536 self.finder = ChildDataItemFinder(self.data_model)
@@ -2395,6 +2644,10 @@ class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
2395 self.view.setModel(self.model) 2644 self.view.setModel(self.model)
2396 self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) 2645 self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
2397 self.view.verticalHeader().setVisible(False) 2646 self.view.verticalHeader().setVisible(False)
2647 self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
2648 self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
2649
2650 self.context_menu = ContextMenu(self.view)
2398 2651
2399 self.ResizeColumnsToContents() 2652 self.ResizeColumnsToContents()
2400 2653
@@ -2660,6 +2913,60 @@ class HelpOnlyWindow(QMainWindow):
2660 2913
2661 self.setCentralWidget(self.text) 2914 self.setCentralWidget(self.text)
2662 2915
2916# PostqreSQL server version
2917
2918def PostqreSQLServerVersion(db):
2919 query = QSqlQuery(db)
2920 QueryExec(query, "SELECT VERSION()")
2921 if query.next():
2922 v_str = query.value(0)
2923 v_list = v_str.strip().split(" ")
2924 if v_list[0] == "PostgreSQL" and v_list[2] == "on":
2925 return v_list[1]
2926 return v_str
2927 return "Unknown"
2928
2929# SQLite version
2930
2931def SQLiteVersion(db):
2932 query = QSqlQuery(db)
2933 QueryExec(query, "SELECT sqlite_version()")
2934 if query.next():
2935 return query.value(0)
2936 return "Unknown"
2937
2938# About dialog
2939
2940class AboutDialog(QDialog):
2941
2942 def __init__(self, glb, parent=None):
2943 super(AboutDialog, self).__init__(parent)
2944
2945 self.setWindowTitle("About Exported SQL Viewer")
2946 self.setMinimumWidth(300)
2947
2948 pyside_version = "1" if pyside_version_1 else "2"
2949
2950 text = "<pre>"
2951 text += "Python version: " + sys.version.split(" ")[0] + "\n"
2952 text += "PySide version: " + pyside_version + "\n"
2953 text += "Qt version: " + qVersion() + "\n"
2954 if glb.dbref.is_sqlite3:
2955 text += "SQLite version: " + SQLiteVersion(glb.db) + "\n"
2956 else:
2957 text += "PostqreSQL version: " + PostqreSQLServerVersion(glb.db) + "\n"
2958 text += "</pre>"
2959
2960 self.text = QTextBrowser()
2961 self.text.setHtml(text)
2962 self.text.setReadOnly(True)
2963 self.text.setOpenExternalLinks(True)
2964
2965 self.vbox = QVBoxLayout()
2966 self.vbox.addWidget(self.text)
2967
2968 self.setLayout(self.vbox);
2969
2663# Font resize 2970# Font resize
2664 2971
2665def ResizeFont(widget, diff): 2972def ResizeFont(widget, diff):
@@ -2732,6 +3039,8 @@ class MainWindow(QMainWindow):
2732 file_menu.addAction(CreateExitAction(glb.app, self)) 3039 file_menu.addAction(CreateExitAction(glb.app, self))
2733 3040
2734 edit_menu = menu.addMenu("&Edit") 3041 edit_menu = menu.addMenu("&Edit")
3042 edit_menu.addAction(CreateAction("&Copy", "Copy to clipboard", self.CopyToClipboard, self, QKeySequence.Copy))
3043 edit_menu.addAction(CreateAction("Copy as CS&V", "Copy to clipboard as CSV", self.CopyToClipboardCSV, self))
2735 edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find)) 3044 edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find))
2736 edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)])) 3045 edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)]))
2737 edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")])) 3046 edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")]))
@@ -2755,6 +3064,21 @@ class MainWindow(QMainWindow):
2755 3064
2756 help_menu = menu.addMenu("&Help") 3065 help_menu = menu.addMenu("&Help")
2757 help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents)) 3066 help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
3067 help_menu.addAction(CreateAction("&About Exported SQL Viewer", "About this application", self.About, self))
3068
3069 def Try(self, fn):
3070 win = self.mdi_area.activeSubWindow()
3071 if win:
3072 try:
3073 fn(win.view)
3074 except:
3075 pass
3076
3077 def CopyToClipboard(self):
3078 self.Try(CopyCellsToClipboardHdr)
3079
3080 def CopyToClipboardCSV(self):
3081 self.Try(CopyCellsToClipboardCSV)
2758 3082
2759 def Find(self): 3083 def Find(self):
2760 win = self.mdi_area.activeSubWindow() 3084 win = self.mdi_area.activeSubWindow()
@@ -2773,12 +3097,10 @@ class MainWindow(QMainWindow):
2773 pass 3097 pass
2774 3098
2775 def ShrinkFont(self): 3099 def ShrinkFont(self):
2776 win = self.mdi_area.activeSubWindow() 3100 self.Try(ShrinkFont)
2777 ShrinkFont(win.view)
2778 3101
2779 def EnlargeFont(self): 3102 def EnlargeFont(self):
2780 win = self.mdi_area.activeSubWindow() 3103 self.Try(EnlargeFont)
2781 EnlargeFont(win.view)
2782 3104
2783 def EventMenu(self, events, reports_menu): 3105 def EventMenu(self, events, reports_menu):
2784 branches_events = 0 3106 branches_events = 0
@@ -2828,6 +3150,10 @@ class MainWindow(QMainWindow):
2828 def Help(self): 3150 def Help(self):
2829 HelpWindow(self.glb, self) 3151 HelpWindow(self.glb, self)
2830 3152
3153 def About(self):
3154 dialog = AboutDialog(self.glb, self)
3155 dialog.exec_()
3156
2831# XED Disassembler 3157# XED Disassembler
2832 3158
2833class xed_state_t(Structure): 3159class xed_state_t(Structure):
diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c
index 7f6c52021e41..946ab4b63acd 100644
--- a/tools/perf/tests/dso-data.c
+++ b/tools/perf/tests/dso-data.c
@@ -304,7 +304,7 @@ int test__dso_data_cache(struct test *test __maybe_unused, int subtest __maybe_u
304 /* Make sure we did not leak any file descriptor. */ 304 /* Make sure we did not leak any file descriptor. */
305 nr_end = open_files_cnt(); 305 nr_end = open_files_cnt();
306 pr_debug("nr start %ld, nr stop %ld\n", nr, nr_end); 306 pr_debug("nr start %ld, nr stop %ld\n", nr, nr_end);
307 TEST_ASSERT_VAL("failed leadking files", nr == nr_end); 307 TEST_ASSERT_VAL("failed leaking files", nr == nr_end);
308 return 0; 308 return 0;
309} 309}
310 310
@@ -380,6 +380,6 @@ int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_
380 /* Make sure we did not leak any file descriptor. */ 380 /* Make sure we did not leak any file descriptor. */
381 nr_end = open_files_cnt(); 381 nr_end = open_files_cnt();
382 pr_debug("nr start %ld, nr stop %ld\n", nr, nr_end); 382 pr_debug("nr start %ld, nr stop %ld\n", nr, nr_end);
383 TEST_ASSERT_VAL("failed leadking files", nr == nr_end); 383 TEST_ASSERT_VAL("failed leaking files", nr == nr_end);
384 return 0; 384 return 0;
385} 385}
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index e46723568516..5363a12a8b9b 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -107,7 +107,7 @@ make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
107make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 107make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
108make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 108make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
109make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 109make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
110make_minimal += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 110make_minimal += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
111 111
112# $(run) contains all available tests 112# $(run) contains all available tests
113run := make_pure 113run := make_pure
diff --git a/tools/perf/tests/shell/record+zstd_comp_decomp.sh b/tools/perf/tests/shell/record+zstd_comp_decomp.sh
new file mode 100755
index 000000000000..5dcba800109f
--- /dev/null
+++ b/tools/perf/tests/shell/record+zstd_comp_decomp.sh
@@ -0,0 +1,34 @@
1#!/bin/sh
2# Zstd perf.data compression/decompression
3
4trace_file=$(mktemp /tmp/perf.data.XXX)
5perf_tool=perf
6
7skip_if_no_z_record() {
8 $perf_tool record -h 2>&1 | grep -q '\-z, \-\-compression\-level'
9}
10
11collect_z_record() {
12 echo "Collecting compressed record file:"
13 $perf_tool record -o $trace_file -g -z -F 5000 -- \
14 dd count=500 if=/dev/random of=/dev/null
15}
16
17check_compressed_stats() {
18 echo "Checking compressed events stats:"
19 $perf_tool report -i $trace_file --header --stats | \
20 grep -E "(# compressed : Zstd,)|(COMPRESSED events:)"
21}
22
23check_compressed_output() {
24 $perf_tool inject -i $trace_file -o $trace_file.decomp &&
25 $perf_tool report -i $trace_file --stdio | head -n -3 > $trace_file.comp.output &&
26 $perf_tool report -i $trace_file.decomp --stdio | head -n -3 > $trace_file.decomp.output &&
27 diff $trace_file.comp.output $trace_file.decomp.output
28}
29
30skip_if_no_z_record || exit 2
31collect_z_record && check_compressed_stats && check_compressed_output
32err=$?
33rm -f $trace_file*
34exit $err
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 8dd3102301ea..6d5bbc8b589b 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -145,6 +145,8 @@ perf-y += scripting-engines/
145 145
146perf-$(CONFIG_ZLIB) += zlib.o 146perf-$(CONFIG_ZLIB) += zlib.o
147perf-$(CONFIG_LZMA) += lzma.o 147perf-$(CONFIG_LZMA) += lzma.o
148perf-$(CONFIG_ZSTD) += zstd.o
149
148perf-y += demangle-java.o 150perf-y += demangle-java.o
149perf-y += demangle-rust.o 151perf-y += demangle-rust.o
150 152
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 09762985c713..0b8573fd9b05 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1021,7 +1021,7 @@ static void annotation__count_and_fill(struct annotation *notes, u64 start, u64
1021 float ipc = n_insn / ((double)ch->cycles / (double)ch->num); 1021 float ipc = n_insn / ((double)ch->cycles / (double)ch->num);
1022 1022
1023 /* Hide data when there are too many overlaps. */ 1023 /* Hide data when there are too many overlaps. */
1024 if (ch->reset >= 0x7fff || ch->reset >= ch->num / 2) 1024 if (ch->reset >= 0x7fff)
1025 return; 1025 return;
1026 1026
1027 for (offset = start; offset <= end; offset++) { 1027 for (offset = start; offset <= end; offset++) {
diff --git a/tools/perf/util/compress.h b/tools/perf/util/compress.h
index 892e92e7e7fc..0cd3369af2a4 100644
--- a/tools/perf/util/compress.h
+++ b/tools/perf/util/compress.h
@@ -2,6 +2,11 @@
2#ifndef PERF_COMPRESS_H 2#ifndef PERF_COMPRESS_H
3#define PERF_COMPRESS_H 3#define PERF_COMPRESS_H
4 4
5#include <stdbool.h>
6#ifdef HAVE_ZSTD_SUPPORT
7#include <zstd.h>
8#endif
9
5#ifdef HAVE_ZLIB_SUPPORT 10#ifdef HAVE_ZLIB_SUPPORT
6int gzip_decompress_to_file(const char *input, int output_fd); 11int gzip_decompress_to_file(const char *input, int output_fd);
7bool gzip_is_compressed(const char *input); 12bool gzip_is_compressed(const char *input);
@@ -12,4 +17,52 @@ int lzma_decompress_to_file(const char *input, int output_fd);
12bool lzma_is_compressed(const char *input); 17bool lzma_is_compressed(const char *input);
13#endif 18#endif
14 19
20struct zstd_data {
21#ifdef HAVE_ZSTD_SUPPORT
22 ZSTD_CStream *cstream;
23 ZSTD_DStream *dstream;
24#endif
25};
26
27#ifdef HAVE_ZSTD_SUPPORT
28
29int zstd_init(struct zstd_data *data, int level);
30int zstd_fini(struct zstd_data *data);
31
32size_t zstd_compress_stream_to_records(struct zstd_data *data, void *dst, size_t dst_size,
33 void *src, size_t src_size, size_t max_record_size,
34 size_t process_header(void *record, size_t increment));
35
36size_t zstd_decompress_stream(struct zstd_data *data, void *src, size_t src_size,
37 void *dst, size_t dst_size);
38#else /* !HAVE_ZSTD_SUPPORT */
39
40static inline int zstd_init(struct zstd_data *data __maybe_unused, int level __maybe_unused)
41{
42 return 0;
43}
44
45static inline int zstd_fini(struct zstd_data *data __maybe_unused)
46{
47 return 0;
48}
49
50static inline
51size_t zstd_compress_stream_to_records(struct zstd_data *data __maybe_unused,
52 void *dst __maybe_unused, size_t dst_size __maybe_unused,
53 void *src __maybe_unused, size_t src_size __maybe_unused,
54 size_t max_record_size __maybe_unused,
55 size_t process_header(void *record, size_t increment) __maybe_unused)
56{
57 return 0;
58}
59
60static inline size_t zstd_decompress_stream(struct zstd_data *data __maybe_unused, void *src __maybe_unused,
61 size_t src_size __maybe_unused, void *dst __maybe_unused,
62 size_t dst_size __maybe_unused)
63{
64 return 0;
65}
66#endif
67
15#endif /* PERF_COMPRESS_H */ 68#endif /* PERF_COMPRESS_H */
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 4f8e2b485c01..271a90b326c4 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -62,6 +62,11 @@ struct perf_env {
62 struct cpu_topology_map *cpu; 62 struct cpu_topology_map *cpu;
63 struct cpu_cache_level *caches; 63 struct cpu_cache_level *caches;
64 int caches_cnt; 64 int caches_cnt;
65 u32 comp_ratio;
66 u32 comp_ver;
67 u32 comp_type;
68 u32 comp_level;
69 u32 comp_mmap_len;
65 struct numa_node *numa_nodes; 70 struct numa_node *numa_nodes;
66 struct memory_node *memory_nodes; 71 struct memory_node *memory_nodes;
67 unsigned long long memory_bsize; 72 unsigned long long memory_bsize;
@@ -80,6 +85,12 @@ struct perf_env {
80 } bpf_progs; 85 } bpf_progs;
81}; 86};
82 87
88enum perf_compress_type {
89 PERF_COMP_NONE = 0,
90 PERF_COMP_ZSTD,
91 PERF_COMP_MAX
92};
93
83struct bpf_prog_info_node; 94struct bpf_prog_info_node;
84struct btf_node; 95struct btf_node;
85 96
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index ba7be74fad6e..d1ad6c419724 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -68,6 +68,7 @@ static const char *perf_event__names[] = {
68 [PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE", 68 [PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE",
69 [PERF_RECORD_TIME_CONV] = "TIME_CONV", 69 [PERF_RECORD_TIME_CONV] = "TIME_CONV",
70 [PERF_RECORD_HEADER_FEATURE] = "FEATURE", 70 [PERF_RECORD_HEADER_FEATURE] = "FEATURE",
71 [PERF_RECORD_COMPRESSED] = "COMPRESSED",
71}; 72};
72 73
73static const char *perf_ns__names[] = { 74static const char *perf_ns__names[] = {
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 4e908ec1ef64..9e999550f247 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -255,6 +255,7 @@ enum perf_user_event_type { /* above any possible kernel type */
255 PERF_RECORD_EVENT_UPDATE = 78, 255 PERF_RECORD_EVENT_UPDATE = 78,
256 PERF_RECORD_TIME_CONV = 79, 256 PERF_RECORD_TIME_CONV = 79,
257 PERF_RECORD_HEADER_FEATURE = 80, 257 PERF_RECORD_HEADER_FEATURE = 80,
258 PERF_RECORD_COMPRESSED = 81,
258 PERF_RECORD_HEADER_MAX 259 PERF_RECORD_HEADER_MAX
259}; 260};
260 261
@@ -627,6 +628,11 @@ struct feature_event {
627 char data[]; 628 char data[];
628}; 629};
629 630
631struct compressed_event {
632 struct perf_event_header header;
633 char data[];
634};
635
630union perf_event { 636union perf_event {
631 struct perf_event_header header; 637 struct perf_event_header header;
632 struct mmap_event mmap; 638 struct mmap_event mmap;
@@ -660,6 +666,7 @@ union perf_event {
660 struct feature_event feat; 666 struct feature_event feat;
661 struct ksymbol_event ksymbol_event; 667 struct ksymbol_event ksymbol_event;
662 struct bpf_event bpf_event; 668 struct bpf_event bpf_event;
669 struct compressed_event pack;
663}; 670};
664 671
665void perf_event__print_totals(void); 672void perf_event__print_totals(void);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 4b6783ff5813..69d0fa8ab16f 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1009,7 +1009,8 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
1009 */ 1009 */
1010int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, 1010int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
1011 unsigned int auxtrace_pages, 1011 unsigned int auxtrace_pages,
1012 bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush) 1012 bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush,
1013 int comp_level)
1013{ 1014{
1014 struct perf_evsel *evsel; 1015 struct perf_evsel *evsel;
1015 const struct cpu_map *cpus = evlist->cpus; 1016 const struct cpu_map *cpus = evlist->cpus;
@@ -1019,7 +1020,8 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
1019 * Its value is decided by evsel's write_backward. 1020 * Its value is decided by evsel's write_backward.
1020 * So &mp should not be passed through const pointer. 1021 * So &mp should not be passed through const pointer.
1021 */ 1022 */
1022 struct mmap_params mp = { .nr_cblocks = nr_cblocks, .affinity = affinity, .flush = flush }; 1023 struct mmap_params mp = { .nr_cblocks = nr_cblocks, .affinity = affinity, .flush = flush,
1024 .comp_level = comp_level };
1023 1025
1024 if (!evlist->mmap) 1026 if (!evlist->mmap)
1025 evlist->mmap = perf_evlist__alloc_mmap(evlist, false); 1027 evlist->mmap = perf_evlist__alloc_mmap(evlist, false);
@@ -1051,7 +1053,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
1051 1053
1052int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages) 1054int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages)
1053{ 1055{
1054 return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1); 1056 return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1, 0);
1055} 1057}
1056 1058
1057int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) 1059int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index c9a0f72677fd..49354fe24d5f 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -178,7 +178,7 @@ unsigned long perf_event_mlock_kb_in_pages(void);
178int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, 178int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
179 unsigned int auxtrace_pages, 179 unsigned int auxtrace_pages,
180 bool auxtrace_overwrite, int nr_cblocks, 180 bool auxtrace_overwrite, int nr_cblocks,
181 int affinity, int flush); 181 int affinity, int flush, int comp_level);
182int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages); 182int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages);
183void perf_evlist__munmap(struct perf_evlist *evlist); 183void perf_evlist__munmap(struct perf_evlist *evlist);
184 184
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index a10cf4cde920..a6f572a40deb 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -813,6 +813,8 @@ static void apply_config_terms(struct perf_evsel *evsel,
813 break; 813 break;
814 case PERF_EVSEL__CONFIG_TERM_DRV_CFG: 814 case PERF_EVSEL__CONFIG_TERM_DRV_CFG:
815 break; 815 break;
816 case PERF_EVSEL__CONFIG_TERM_PERCORE:
817 break;
816 default: 818 default:
817 break; 819 break;
818 } 820 }
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 6d190cbf1070..cad54e8ba522 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -50,6 +50,7 @@ enum term_type {
50 PERF_EVSEL__CONFIG_TERM_OVERWRITE, 50 PERF_EVSEL__CONFIG_TERM_OVERWRITE,
51 PERF_EVSEL__CONFIG_TERM_DRV_CFG, 51 PERF_EVSEL__CONFIG_TERM_DRV_CFG,
52 PERF_EVSEL__CONFIG_TERM_BRANCH, 52 PERF_EVSEL__CONFIG_TERM_BRANCH,
53 PERF_EVSEL__CONFIG_TERM_PERCORE,
53}; 54};
54 55
55struct perf_evsel_config_term { 56struct perf_evsel_config_term {
@@ -67,6 +68,7 @@ struct perf_evsel_config_term {
67 bool overwrite; 68 bool overwrite;
68 char *branch; 69 char *branch;
69 unsigned long max_events; 70 unsigned long max_events;
71 bool percore;
70 } val; 72 } val;
71 bool weak; 73 bool weak;
72}; 74};
@@ -158,6 +160,7 @@ struct perf_evsel {
158 struct perf_evsel **metric_events; 160 struct perf_evsel **metric_events;
159 bool collect_stat; 161 bool collect_stat;
160 bool weak_group; 162 bool weak_group;
163 bool percore;
161 const char *pmu_name; 164 const char *pmu_name;
162 struct { 165 struct {
163 perf_evsel__sb_cb_t *cb; 166 perf_evsel__sb_cb_t *cb;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 2d2af2ac2b1e..847ae51a524b 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1344,6 +1344,30 @@ out:
1344 return ret; 1344 return ret;
1345} 1345}
1346 1346
1347static int write_compressed(struct feat_fd *ff __maybe_unused,
1348 struct perf_evlist *evlist __maybe_unused)
1349{
1350 int ret;
1351
1352 ret = do_write(ff, &(ff->ph->env.comp_ver), sizeof(ff->ph->env.comp_ver));
1353 if (ret)
1354 return ret;
1355
1356 ret = do_write(ff, &(ff->ph->env.comp_type), sizeof(ff->ph->env.comp_type));
1357 if (ret)
1358 return ret;
1359
1360 ret = do_write(ff, &(ff->ph->env.comp_level), sizeof(ff->ph->env.comp_level));
1361 if (ret)
1362 return ret;
1363
1364 ret = do_write(ff, &(ff->ph->env.comp_ratio), sizeof(ff->ph->env.comp_ratio));
1365 if (ret)
1366 return ret;
1367
1368 return do_write(ff, &(ff->ph->env.comp_mmap_len), sizeof(ff->ph->env.comp_mmap_len));
1369}
1370
1347static void print_hostname(struct feat_fd *ff, FILE *fp) 1371static void print_hostname(struct feat_fd *ff, FILE *fp)
1348{ 1372{
1349 fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname); 1373 fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname);
@@ -1688,6 +1712,13 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
1688 } 1712 }
1689} 1713}
1690 1714
1715static void print_compressed(struct feat_fd *ff, FILE *fp)
1716{
1717 fprintf(fp, "# compressed : %s, level = %d, ratio = %d\n",
1718 ff->ph->env.comp_type == PERF_COMP_ZSTD ? "Zstd" : "Unknown",
1719 ff->ph->env.comp_level, ff->ph->env.comp_ratio);
1720}
1721
1691static void print_pmu_mappings(struct feat_fd *ff, FILE *fp) 1722static void print_pmu_mappings(struct feat_fd *ff, FILE *fp)
1692{ 1723{
1693 const char *delimiter = "# pmu mappings: "; 1724 const char *delimiter = "# pmu mappings: ";
@@ -2667,6 +2698,27 @@ out:
2667 return err; 2698 return err;
2668} 2699}
2669 2700
2701static int process_compressed(struct feat_fd *ff,
2702 void *data __maybe_unused)
2703{
2704 if (do_read_u32(ff, &(ff->ph->env.comp_ver)))
2705 return -1;
2706
2707 if (do_read_u32(ff, &(ff->ph->env.comp_type)))
2708 return -1;
2709
2710 if (do_read_u32(ff, &(ff->ph->env.comp_level)))
2711 return -1;
2712
2713 if (do_read_u32(ff, &(ff->ph->env.comp_ratio)))
2714 return -1;
2715
2716 if (do_read_u32(ff, &(ff->ph->env.comp_mmap_len)))
2717 return -1;
2718
2719 return 0;
2720}
2721
2670struct feature_ops { 2722struct feature_ops {
2671 int (*write)(struct feat_fd *ff, struct perf_evlist *evlist); 2723 int (*write)(struct feat_fd *ff, struct perf_evlist *evlist);
2672 void (*print)(struct feat_fd *ff, FILE *fp); 2724 void (*print)(struct feat_fd *ff, FILE *fp);
@@ -2730,6 +2782,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
2730 FEAT_OPN(DIR_FORMAT, dir_format, false), 2782 FEAT_OPN(DIR_FORMAT, dir_format, false),
2731 FEAT_OPR(BPF_PROG_INFO, bpf_prog_info, false), 2783 FEAT_OPR(BPF_PROG_INFO, bpf_prog_info, false),
2732 FEAT_OPR(BPF_BTF, bpf_btf, false), 2784 FEAT_OPR(BPF_BTF, bpf_btf, false),
2785 FEAT_OPR(COMPRESSED, compressed, false),
2733}; 2786};
2734 2787
2735struct header_print_data { 2788struct header_print_data {
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 386da49e1bfa..5b3abe4172e2 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -42,6 +42,7 @@ enum {
42 HEADER_DIR_FORMAT, 42 HEADER_DIR_FORMAT,
43 HEADER_BPF_PROG_INFO, 43 HEADER_BPF_PROG_INFO,
44 HEADER_BPF_BTF, 44 HEADER_BPF_BTF,
45 HEADER_COMPRESSED,
45 HEADER_LAST_FEATURE, 46 HEADER_LAST_FEATURE,
46 HEADER_FEAT_BITS = 256, 47 HEADER_FEAT_BITS = 256,
47}; 48};
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 872fab163585..f4c3c84b090f 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -58,6 +58,7 @@ enum intel_pt_pkt_state {
58 INTEL_PT_STATE_NO_IP, 58 INTEL_PT_STATE_NO_IP,
59 INTEL_PT_STATE_ERR_RESYNC, 59 INTEL_PT_STATE_ERR_RESYNC,
60 INTEL_PT_STATE_IN_SYNC, 60 INTEL_PT_STATE_IN_SYNC,
61 INTEL_PT_STATE_TNT_CONT,
61 INTEL_PT_STATE_TNT, 62 INTEL_PT_STATE_TNT,
62 INTEL_PT_STATE_TIP, 63 INTEL_PT_STATE_TIP,
63 INTEL_PT_STATE_TIP_PGD, 64 INTEL_PT_STATE_TIP_PGD,
@@ -72,8 +73,9 @@ static inline bool intel_pt_sample_time(enum intel_pt_pkt_state pkt_state)
72 case INTEL_PT_STATE_NO_IP: 73 case INTEL_PT_STATE_NO_IP:
73 case INTEL_PT_STATE_ERR_RESYNC: 74 case INTEL_PT_STATE_ERR_RESYNC:
74 case INTEL_PT_STATE_IN_SYNC: 75 case INTEL_PT_STATE_IN_SYNC:
75 case INTEL_PT_STATE_TNT: 76 case INTEL_PT_STATE_TNT_CONT:
76 return true; 77 return true;
78 case INTEL_PT_STATE_TNT:
77 case INTEL_PT_STATE_TIP: 79 case INTEL_PT_STATE_TIP:
78 case INTEL_PT_STATE_TIP_PGD: 80 case INTEL_PT_STATE_TIP_PGD:
79 case INTEL_PT_STATE_FUP: 81 case INTEL_PT_STATE_FUP:
@@ -888,16 +890,20 @@ static uint64_t intel_pt_next_period(struct intel_pt_decoder *decoder)
888 timestamp = decoder->timestamp + decoder->timestamp_insn_cnt; 890 timestamp = decoder->timestamp + decoder->timestamp_insn_cnt;
889 masked_timestamp = timestamp & decoder->period_mask; 891 masked_timestamp = timestamp & decoder->period_mask;
890 if (decoder->continuous_period) { 892 if (decoder->continuous_period) {
891 if (masked_timestamp != decoder->last_masked_timestamp) 893 if (masked_timestamp > decoder->last_masked_timestamp)
892 return 1; 894 return 1;
893 } else { 895 } else {
894 timestamp += 1; 896 timestamp += 1;
895 masked_timestamp = timestamp & decoder->period_mask; 897 masked_timestamp = timestamp & decoder->period_mask;
896 if (masked_timestamp != decoder->last_masked_timestamp) { 898 if (masked_timestamp > decoder->last_masked_timestamp) {
897 decoder->last_masked_timestamp = masked_timestamp; 899 decoder->last_masked_timestamp = masked_timestamp;
898 decoder->continuous_period = true; 900 decoder->continuous_period = true;
899 } 901 }
900 } 902 }
903
904 if (masked_timestamp < decoder->last_masked_timestamp)
905 return decoder->period_ticks;
906
901 return decoder->period_ticks - (timestamp - masked_timestamp); 907 return decoder->period_ticks - (timestamp - masked_timestamp);
902} 908}
903 909
@@ -926,7 +932,10 @@ static void intel_pt_sample_insn(struct intel_pt_decoder *decoder)
926 case INTEL_PT_PERIOD_TICKS: 932 case INTEL_PT_PERIOD_TICKS:
927 timestamp = decoder->timestamp + decoder->timestamp_insn_cnt; 933 timestamp = decoder->timestamp + decoder->timestamp_insn_cnt;
928 masked_timestamp = timestamp & decoder->period_mask; 934 masked_timestamp = timestamp & decoder->period_mask;
929 decoder->last_masked_timestamp = masked_timestamp; 935 if (masked_timestamp > decoder->last_masked_timestamp)
936 decoder->last_masked_timestamp = masked_timestamp;
937 else
938 decoder->last_masked_timestamp += decoder->period_ticks;
930 break; 939 break;
931 case INTEL_PT_PERIOD_NONE: 940 case INTEL_PT_PERIOD_NONE:
932 case INTEL_PT_PERIOD_MTC: 941 case INTEL_PT_PERIOD_MTC:
@@ -1254,7 +1263,9 @@ static int intel_pt_walk_tnt(struct intel_pt_decoder *decoder)
1254 return -ENOENT; 1263 return -ENOENT;
1255 } 1264 }
1256 decoder->tnt.count -= 1; 1265 decoder->tnt.count -= 1;
1257 if (!decoder->tnt.count) 1266 if (decoder->tnt.count)
1267 decoder->pkt_state = INTEL_PT_STATE_TNT_CONT;
1268 else
1258 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; 1269 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1259 decoder->tnt.payload <<= 1; 1270 decoder->tnt.payload <<= 1;
1260 decoder->state.from_ip = decoder->ip; 1271 decoder->state.from_ip = decoder->ip;
@@ -1285,7 +1296,9 @@ static int intel_pt_walk_tnt(struct intel_pt_decoder *decoder)
1285 1296
1286 if (intel_pt_insn.branch == INTEL_PT_BR_CONDITIONAL) { 1297 if (intel_pt_insn.branch == INTEL_PT_BR_CONDITIONAL) {
1287 decoder->tnt.count -= 1; 1298 decoder->tnt.count -= 1;
1288 if (!decoder->tnt.count) 1299 if (decoder->tnt.count)
1300 decoder->pkt_state = INTEL_PT_STATE_TNT_CONT;
1301 else
1289 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; 1302 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1290 if (decoder->tnt.payload & BIT63) { 1303 if (decoder->tnt.payload & BIT63) {
1291 decoder->tnt.payload <<= 1; 1304 decoder->tnt.payload <<= 1;
@@ -1305,8 +1318,11 @@ static int intel_pt_walk_tnt(struct intel_pt_decoder *decoder)
1305 return 0; 1318 return 0;
1306 } 1319 }
1307 decoder->ip += intel_pt_insn.length; 1320 decoder->ip += intel_pt_insn.length;
1308 if (!decoder->tnt.count) 1321 if (!decoder->tnt.count) {
1322 decoder->sample_timestamp = decoder->timestamp;
1323 decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
1309 return -EAGAIN; 1324 return -EAGAIN;
1325 }
1310 decoder->tnt.payload <<= 1; 1326 decoder->tnt.payload <<= 1;
1311 continue; 1327 continue;
1312 } 1328 }
@@ -2365,6 +2381,7 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
2365 err = intel_pt_walk_trace(decoder); 2381 err = intel_pt_walk_trace(decoder);
2366 break; 2382 break;
2367 case INTEL_PT_STATE_TNT: 2383 case INTEL_PT_STATE_TNT:
2384 case INTEL_PT_STATE_TNT_CONT:
2368 err = intel_pt_walk_tnt(decoder); 2385 err = intel_pt_walk_tnt(decoder);
2369 if (err == -EAGAIN) 2386 if (err == -EAGAIN)
2370 err = intel_pt_walk_trace(decoder); 2387 err = intel_pt_walk_trace(decoder);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 3c520baa198c..28a9541c4835 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1234,8 +1234,9 @@ static char *get_kernel_version(const char *root_dir)
1234 if (!file) 1234 if (!file)
1235 return NULL; 1235 return NULL;
1236 1236
1237 version[0] = '\0';
1238 tmp = fgets(version, sizeof(version), file); 1237 tmp = fgets(version, sizeof(version), file);
1238 if (!tmp)
1239 *version = '\0';
1239 fclose(file); 1240 fclose(file);
1240 1241
1241 name = strstr(version, prefix); 1242 name = strstr(version, prefix);
diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c
index ef3d79b2c90b..868c0b0e909c 100644
--- a/tools/perf/util/mmap.c
+++ b/tools/perf/util/mmap.c
@@ -157,6 +157,10 @@ void __weak auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp __mayb
157} 157}
158 158
159#ifdef HAVE_AIO_SUPPORT 159#ifdef HAVE_AIO_SUPPORT
160static int perf_mmap__aio_enabled(struct perf_mmap *map)
161{
162 return map->aio.nr_cblocks > 0;
163}
160 164
161#ifdef HAVE_LIBNUMA_SUPPORT 165#ifdef HAVE_LIBNUMA_SUPPORT
162static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx) 166static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx)
@@ -198,7 +202,7 @@ static int perf_mmap__aio_bind(struct perf_mmap *map, int idx, int cpu, int affi
198 202
199 return 0; 203 return 0;
200} 204}
201#else 205#else /* !HAVE_LIBNUMA_SUPPORT */
202static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx) 206static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx)
203{ 207{
204 map->aio.data[idx] = malloc(perf_mmap__mmap_len(map)); 208 map->aio.data[idx] = malloc(perf_mmap__mmap_len(map));
@@ -285,81 +289,12 @@ static void perf_mmap__aio_munmap(struct perf_mmap *map)
285 zfree(&map->aio.cblocks); 289 zfree(&map->aio.cblocks);
286 zfree(&map->aio.aiocb); 290 zfree(&map->aio.aiocb);
287} 291}
288 292#else /* !HAVE_AIO_SUPPORT */
289int perf_mmap__aio_push(struct perf_mmap *md, void *to, int idx, 293static int perf_mmap__aio_enabled(struct perf_mmap *map __maybe_unused)
290 int push(void *to, struct aiocb *cblock, void *buf, size_t size, off_t off),
291 off_t *off)
292{ 294{
293 u64 head = perf_mmap__read_head(md); 295 return 0;
294 unsigned char *data = md->base + page_size;
295 unsigned long size, size0 = 0;
296 void *buf;
297 int rc = 0;
298
299 rc = perf_mmap__read_init(md);
300 if (rc < 0)
301 return (rc == -EAGAIN) ? 0 : -1;
302
303 /*
304 * md->base data is copied into md->data[idx] buffer to
305 * release space in the kernel buffer as fast as possible,
306 * thru perf_mmap__consume() below.
307 *
308 * That lets the kernel to proceed with storing more
309 * profiling data into the kernel buffer earlier than other
310 * per-cpu kernel buffers are handled.
311 *
312 * Coping can be done in two steps in case the chunk of
313 * profiling data crosses the upper bound of the kernel buffer.
314 * In this case we first move part of data from md->start
315 * till the upper bound and then the reminder from the
316 * beginning of the kernel buffer till the end of
317 * the data chunk.
318 */
319
320 size = md->end - md->start;
321
322 if ((md->start & md->mask) + size != (md->end & md->mask)) {
323 buf = &data[md->start & md->mask];
324 size = md->mask + 1 - (md->start & md->mask);
325 md->start += size;
326 memcpy(md->aio.data[idx], buf, size);
327 size0 = size;
328 }
329
330 buf = &data[md->start & md->mask];
331 size = md->end - md->start;
332 md->start += size;
333 memcpy(md->aio.data[idx] + size0, buf, size);
334
335 /*
336 * Increment md->refcount to guard md->data[idx] buffer
337 * from premature deallocation because md object can be
338 * released earlier than aio write request started
339 * on mmap->data[idx] is complete.
340 *
341 * perf_mmap__put() is done at record__aio_complete()
342 * after started request completion.
343 */
344 perf_mmap__get(md);
345
346 md->prev = head;
347 perf_mmap__consume(md);
348
349 rc = push(to, &md->aio.cblocks[idx], md->aio.data[idx], size0 + size, *off);
350 if (!rc) {
351 *off += size0 + size;
352 } else {
353 /*
354 * Decrement md->refcount back if aio write
355 * operation failed to start.
356 */
357 perf_mmap__put(md);
358 }
359
360 return rc;
361} 296}
362#else 297
363static int perf_mmap__aio_mmap(struct perf_mmap *map __maybe_unused, 298static int perf_mmap__aio_mmap(struct perf_mmap *map __maybe_unused,
364 struct mmap_params *mp __maybe_unused) 299 struct mmap_params *mp __maybe_unused)
365{ 300{
@@ -374,6 +309,10 @@ static void perf_mmap__aio_munmap(struct perf_mmap *map __maybe_unused)
374void perf_mmap__munmap(struct perf_mmap *map) 309void perf_mmap__munmap(struct perf_mmap *map)
375{ 310{
376 perf_mmap__aio_munmap(map); 311 perf_mmap__aio_munmap(map);
312 if (map->data != NULL) {
313 munmap(map->data, perf_mmap__mmap_len(map));
314 map->data = NULL;
315 }
377 if (map->base != NULL) { 316 if (map->base != NULL) {
378 munmap(map->base, perf_mmap__mmap_len(map)); 317 munmap(map->base, perf_mmap__mmap_len(map));
379 map->base = NULL; 318 map->base = NULL;
@@ -442,6 +381,19 @@ int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int c
442 381
443 map->flush = mp->flush; 382 map->flush = mp->flush;
444 383
384 map->comp_level = mp->comp_level;
385
386 if (map->comp_level && !perf_mmap__aio_enabled(map)) {
387 map->data = mmap(NULL, perf_mmap__mmap_len(map), PROT_READ|PROT_WRITE,
388 MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
389 if (map->data == MAP_FAILED) {
390 pr_debug2("failed to mmap data buffer, error %d\n",
391 errno);
392 map->data = NULL;
393 return -1;
394 }
395 }
396
445 if (auxtrace_mmap__mmap(&map->auxtrace_mmap, 397 if (auxtrace_mmap__mmap(&map->auxtrace_mmap,
446 &mp->auxtrace_mp, map->base, fd)) 398 &mp->auxtrace_mp, map->base, fd))
447 return -1; 399 return -1;
@@ -540,7 +492,7 @@ int perf_mmap__push(struct perf_mmap *md, void *to,
540 492
541 rc = perf_mmap__read_init(md); 493 rc = perf_mmap__read_init(md);
542 if (rc < 0) 494 if (rc < 0)
543 return (rc == -EAGAIN) ? 0 : -1; 495 return (rc == -EAGAIN) ? 1 : -1;
544 496
545 size = md->end - md->start; 497 size = md->end - md->start;
546 498
diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h
index b82f8c2d55c4..274ce389cd84 100644
--- a/tools/perf/util/mmap.h
+++ b/tools/perf/util/mmap.h
@@ -40,6 +40,8 @@ struct perf_mmap {
40#endif 40#endif
41 cpu_set_t affinity_mask; 41 cpu_set_t affinity_mask;
42 u64 flush; 42 u64 flush;
43 void *data;
44 int comp_level;
43}; 45};
44 46
45/* 47/*
@@ -71,7 +73,7 @@ enum bkw_mmap_state {
71}; 73};
72 74
73struct mmap_params { 75struct mmap_params {
74 int prot, mask, nr_cblocks, affinity, flush; 76 int prot, mask, nr_cblocks, affinity, flush, comp_level;
75 struct auxtrace_mmap_params auxtrace_mp; 77 struct auxtrace_mmap_params auxtrace_mp;
76}; 78};
77 79
@@ -99,18 +101,6 @@ union perf_event *perf_mmap__read_event(struct perf_mmap *map);
99 101
100int perf_mmap__push(struct perf_mmap *md, void *to, 102int perf_mmap__push(struct perf_mmap *md, void *to,
101 int push(struct perf_mmap *map, void *to, void *buf, size_t size)); 103 int push(struct perf_mmap *map, void *to, void *buf, size_t size));
102#ifdef HAVE_AIO_SUPPORT
103int perf_mmap__aio_push(struct perf_mmap *md, void *to, int idx,
104 int push(void *to, struct aiocb *cblock, void *buf, size_t size, off_t off),
105 off_t *off);
106#else
107static inline int perf_mmap__aio_push(struct perf_mmap *md __maybe_unused, void *to __maybe_unused, int idx __maybe_unused,
108 int push(void *to, struct aiocb *cblock, void *buf, size_t size, off_t off) __maybe_unused,
109 off_t *off __maybe_unused)
110{
111 return 0;
112}
113#endif
114 104
115size_t perf_mmap__mmap_len(struct perf_mmap *map); 105size_t perf_mmap__mmap_len(struct perf_mmap *map);
116 106
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 4432bfe039fd..cf0b9b81c5aa 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -950,6 +950,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
950 [PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite", 950 [PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite",
951 [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite", 951 [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite",
952 [PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config", 952 [PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config",
953 [PARSE_EVENTS__TERM_TYPE_PERCORE] = "percore",
953}; 954};
954 955
955static bool config_term_shrinked; 956static bool config_term_shrinked;
@@ -970,6 +971,7 @@ config_term_avail(int term_type, struct parse_events_error *err)
970 case PARSE_EVENTS__TERM_TYPE_CONFIG2: 971 case PARSE_EVENTS__TERM_TYPE_CONFIG2:
971 case PARSE_EVENTS__TERM_TYPE_NAME: 972 case PARSE_EVENTS__TERM_TYPE_NAME:
972 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 973 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
974 case PARSE_EVENTS__TERM_TYPE_PERCORE:
973 return true; 975 return true;
974 default: 976 default:
975 if (!err) 977 if (!err)
@@ -1061,6 +1063,14 @@ do { \
1061 case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS: 1063 case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
1062 CHECK_TYPE_VAL(NUM); 1064 CHECK_TYPE_VAL(NUM);
1063 break; 1065 break;
1066 case PARSE_EVENTS__TERM_TYPE_PERCORE:
1067 CHECK_TYPE_VAL(NUM);
1068 if ((unsigned int)term->val.num > 1) {
1069 err->str = strdup("expected 0 or 1");
1070 err->idx = term->err_val;
1071 return -EINVAL;
1072 }
1073 break;
1064 default: 1074 default:
1065 err->str = strdup("unknown term"); 1075 err->str = strdup("unknown term");
1066 err->idx = term->err_term; 1076 err->idx = term->err_term;
@@ -1199,6 +1209,10 @@ do { \
1199 case PARSE_EVENTS__TERM_TYPE_DRV_CFG: 1209 case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
1200 ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str); 1210 ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str);
1201 break; 1211 break;
1212 case PARSE_EVENTS__TERM_TYPE_PERCORE:
1213 ADD_CONFIG_TERM(PERCORE, percore,
1214 term->val.num ? true : false);
1215 break;
1202 default: 1216 default:
1203 break; 1217 break;
1204 } 1218 }
@@ -1260,6 +1274,18 @@ int parse_events_add_tool(struct parse_events_state *parse_state,
1260 return add_event_tool(list, &parse_state->idx, tool_event); 1274 return add_event_tool(list, &parse_state->idx, tool_event);
1261} 1275}
1262 1276
1277static bool config_term_percore(struct list_head *config_terms)
1278{
1279 struct perf_evsel_config_term *term;
1280
1281 list_for_each_entry(term, config_terms, list) {
1282 if (term->type == PERF_EVSEL__CONFIG_TERM_PERCORE)
1283 return term->val.percore;
1284 }
1285
1286 return false;
1287}
1288
1263int parse_events_add_pmu(struct parse_events_state *parse_state, 1289int parse_events_add_pmu(struct parse_events_state *parse_state,
1264 struct list_head *list, char *name, 1290 struct list_head *list, char *name,
1265 struct list_head *head_config, 1291 struct list_head *head_config,
@@ -1333,6 +1359,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
1333 evsel->metric_name = info.metric_name; 1359 evsel->metric_name = info.metric_name;
1334 evsel->pmu_name = name; 1360 evsel->pmu_name = name;
1335 evsel->use_uncore_alias = use_uncore_alias; 1361 evsel->use_uncore_alias = use_uncore_alias;
1362 evsel->percore = config_term_percore(&evsel->config_terms);
1336 } 1363 }
1337 1364
1338 return evsel ? 0 : -ENOMEM; 1365 return evsel ? 0 : -ENOMEM;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index a052cd6ac63e..f7139e1a2fd3 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -75,6 +75,7 @@ enum {
75 PARSE_EVENTS__TERM_TYPE_NOOVERWRITE, 75 PARSE_EVENTS__TERM_TYPE_NOOVERWRITE,
76 PARSE_EVENTS__TERM_TYPE_OVERWRITE, 76 PARSE_EVENTS__TERM_TYPE_OVERWRITE,
77 PARSE_EVENTS__TERM_TYPE_DRV_CFG, 77 PARSE_EVENTS__TERM_TYPE_DRV_CFG,
78 PARSE_EVENTS__TERM_TYPE_PERCORE,
78 __PARSE_EVENTS__TERM_TYPE_NR, 79 __PARSE_EVENTS__TERM_TYPE_NR,
79}; 80};
80 81
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index c54bfe88626c..ca6098874fe2 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -283,6 +283,7 @@ inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); }
283no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); } 283no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
284overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); } 284overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); }
285no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); } 285no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); }
286percore { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_PERCORE); }
286, { return ','; } 287, { return ','; }
287"/" { BEGIN(INITIAL); return '/'; } 288"/" { BEGIN(INITIAL); return '/'; }
288{name_minus} { return str(yyscanner, PE_NAME); } 289{name_minus} { return str(yyscanner, PE_NAME); }
diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
index e6599e290f46..08581e276225 100644
--- a/tools/perf/util/parse-regs-options.c
+++ b/tools/perf/util/parse-regs-options.c
@@ -5,13 +5,14 @@
5#include <subcmd/parse-options.h> 5#include <subcmd/parse-options.h>
6#include "util/parse-regs-options.h" 6#include "util/parse-regs-options.h"
7 7
8int 8static int
9parse_regs(const struct option *opt, const char *str, int unset) 9__parse_regs(const struct option *opt, const char *str, int unset, bool intr)
10{ 10{
11 uint64_t *mode = (uint64_t *)opt->value; 11 uint64_t *mode = (uint64_t *)opt->value;
12 const struct sample_reg *r; 12 const struct sample_reg *r;
13 char *s, *os = NULL, *p; 13 char *s, *os = NULL, *p;
14 int ret = -1; 14 int ret = -1;
15 uint64_t mask;
15 16
16 if (unset) 17 if (unset)
17 return 0; 18 return 0;
@@ -22,6 +23,11 @@ parse_regs(const struct option *opt, const char *str, int unset)
22 if (*mode) 23 if (*mode)
23 return -1; 24 return -1;
24 25
26 if (intr)
27 mask = arch__intr_reg_mask();
28 else
29 mask = arch__user_reg_mask();
30
25 /* str may be NULL in case no arg is passed to -I */ 31 /* str may be NULL in case no arg is passed to -I */
26 if (str) { 32 if (str) {
27 /* because str is read-only */ 33 /* because str is read-only */
@@ -37,19 +43,20 @@ parse_regs(const struct option *opt, const char *str, int unset)
37 if (!strcmp(s, "?")) { 43 if (!strcmp(s, "?")) {
38 fprintf(stderr, "available registers: "); 44 fprintf(stderr, "available registers: ");
39 for (r = sample_reg_masks; r->name; r++) { 45 for (r = sample_reg_masks; r->name; r++) {
40 fprintf(stderr, "%s ", r->name); 46 if (r->mask & mask)
47 fprintf(stderr, "%s ", r->name);
41 } 48 }
42 fputc('\n', stderr); 49 fputc('\n', stderr);
43 /* just printing available regs */ 50 /* just printing available regs */
44 return -1; 51 return -1;
45 } 52 }
46 for (r = sample_reg_masks; r->name; r++) { 53 for (r = sample_reg_masks; r->name; r++) {
47 if (!strcasecmp(s, r->name)) 54 if ((r->mask & mask) && !strcasecmp(s, r->name))
48 break; 55 break;
49 } 56 }
50 if (!r->name) { 57 if (!r->name) {
51 ui__warning("unknown register %s," 58 ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n",
52 " check man page\n", s); 59 s, intr ? "-I" : "--user-regs=");
53 goto error; 60 goto error;
54 } 61 }
55 62
@@ -65,8 +72,20 @@ parse_regs(const struct option *opt, const char *str, int unset)
65 72
66 /* default to all possible regs */ 73 /* default to all possible regs */
67 if (*mode == 0) 74 if (*mode == 0)
68 *mode = PERF_REGS_MASK; 75 *mode = mask;
69error: 76error:
70 free(os); 77 free(os);
71 return ret; 78 return ret;
72} 79}
80
81int
82parse_user_regs(const struct option *opt, const char *str, int unset)
83{
84 return __parse_regs(opt, str, unset, false);
85}
86
87int
88parse_intr_regs(const struct option *opt, const char *str, int unset)
89{
90 return __parse_regs(opt, str, unset, true);
91}
diff --git a/tools/perf/util/parse-regs-options.h b/tools/perf/util/parse-regs-options.h
index cdefb1acf6be..2b23d25c6394 100644
--- a/tools/perf/util/parse-regs-options.h
+++ b/tools/perf/util/parse-regs-options.h
@@ -2,5 +2,6 @@
2#ifndef _PERF_PARSE_REGS_OPTIONS_H 2#ifndef _PERF_PARSE_REGS_OPTIONS_H
3#define _PERF_PARSE_REGS_OPTIONS_H 1 3#define _PERF_PARSE_REGS_OPTIONS_H 1
4struct option; 4struct option;
5int parse_regs(const struct option *opt, const char *str, int unset); 5int parse_user_regs(const struct option *opt, const char *str, int unset);
6int parse_intr_regs(const struct option *opt, const char *str, int unset);
6#endif /* _PERF_PARSE_REGS_OPTIONS_H */ 7#endif /* _PERF_PARSE_REGS_OPTIONS_H */
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
index 2acfcc527cac..2774cec1f15f 100644
--- a/tools/perf/util/perf_regs.c
+++ b/tools/perf/util/perf_regs.c
@@ -13,6 +13,16 @@ int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused,
13 return SDT_ARG_SKIP; 13 return SDT_ARG_SKIP;
14} 14}
15 15
16uint64_t __weak arch__intr_reg_mask(void)
17{
18 return PERF_REGS_MASK;
19}
20
21uint64_t __weak arch__user_reg_mask(void)
22{
23 return PERF_REGS_MASK;
24}
25
16#ifdef HAVE_PERF_REGS_SUPPORT 26#ifdef HAVE_PERF_REGS_SUPPORT
17int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) 27int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
18{ 28{
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
index c9319f8d17a6..cb9c246c8962 100644
--- a/tools/perf/util/perf_regs.h
+++ b/tools/perf/util/perf_regs.h
@@ -12,6 +12,7 @@ struct sample_reg {
12 uint64_t mask; 12 uint64_t mask;
13}; 13};
14#define SMPL_REG(n, b) { .name = #n, .mask = 1ULL << (b) } 14#define SMPL_REG(n, b) { .name = #n, .mask = 1ULL << (b) }
15#define SMPL_REG2(n, b) { .name = #n, .mask = 3ULL << (b) }
15#define SMPL_REG_END { .name = NULL } 16#define SMPL_REG_END { .name = NULL }
16 17
17extern const struct sample_reg sample_reg_masks[]; 18extern const struct sample_reg sample_reg_masks[];
@@ -22,6 +23,8 @@ enum {
22}; 23};
23 24
24int arch_sdt_arg_parse_op(char *old_op, char **new_op); 25int arch_sdt_arg_parse_op(char *old_op, char **new_op);
26uint64_t arch__intr_reg_mask(void);
27uint64_t arch__user_reg_mask(void);
25 28
26#ifdef HAVE_PERF_REGS_SUPPORT 29#ifdef HAVE_PERF_REGS_SUPPORT
27#include <perf_regs.h> 30#include <perf_regs.h>
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index bad5f87ae001..2310a1752983 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -29,6 +29,61 @@
29#include "stat.h" 29#include "stat.h"
30#include "arch/common.h" 30#include "arch/common.h"
31 31
32#ifdef HAVE_ZSTD_SUPPORT
33static int perf_session__process_compressed_event(struct perf_session *session,
34 union perf_event *event, u64 file_offset)
35{
36 void *src;
37 size_t decomp_size, src_size;
38 u64 decomp_last_rem = 0;
39 size_t decomp_len = session->header.env.comp_mmap_len;
40 struct decomp *decomp, *decomp_last = session->decomp_last;
41
42 decomp = mmap(NULL, sizeof(struct decomp) + decomp_len, PROT_READ|PROT_WRITE,
43 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
44 if (decomp == MAP_FAILED) {
45 pr_err("Couldn't allocate memory for decompression\n");
46 return -1;
47 }
48
49 decomp->file_pos = file_offset;
50 decomp->head = 0;
51
52 if (decomp_last) {
53 decomp_last_rem = decomp_last->size - decomp_last->head;
54 memcpy(decomp->data, &(decomp_last->data[decomp_last->head]), decomp_last_rem);
55 decomp->size = decomp_last_rem;
56 }
57
58 src = (void *)event + sizeof(struct compressed_event);
59 src_size = event->pack.header.size - sizeof(struct compressed_event);
60
61 decomp_size = zstd_decompress_stream(&(session->zstd_data), src, src_size,
62 &(decomp->data[decomp_last_rem]), decomp_len - decomp_last_rem);
63 if (!decomp_size) {
64 munmap(decomp, sizeof(struct decomp) + decomp_len);
65 pr_err("Couldn't decompress data\n");
66 return -1;
67 }
68
69 decomp->size += decomp_size;
70
71 if (session->decomp == NULL) {
72 session->decomp = decomp;
73 session->decomp_last = decomp;
74 } else {
75 session->decomp_last->next = decomp;
76 session->decomp_last = decomp;
77 }
78
79 pr_debug("decomp (B): %ld to %ld\n", src_size, decomp_size);
80
81 return 0;
82}
83#else /* !HAVE_ZSTD_SUPPORT */
84#define perf_session__process_compressed_event perf_session__process_compressed_event_stub
85#endif
86
32static int perf_session__deliver_event(struct perf_session *session, 87static int perf_session__deliver_event(struct perf_session *session,
33 union perf_event *event, 88 union perf_event *event,
34 struct perf_tool *tool, 89 struct perf_tool *tool,
@@ -197,6 +252,21 @@ static void perf_session__delete_threads(struct perf_session *session)
197 machine__delete_threads(&session->machines.host); 252 machine__delete_threads(&session->machines.host);
198} 253}
199 254
255static void perf_session__release_decomp_events(struct perf_session *session)
256{
257 struct decomp *next, *decomp;
258 size_t decomp_len;
259 next = session->decomp;
260 decomp_len = session->header.env.comp_mmap_len;
261 do {
262 decomp = next;
263 if (decomp == NULL)
264 break;
265 next = decomp->next;
266 munmap(decomp, decomp_len + sizeof(struct decomp));
267 } while (1);
268}
269
200void perf_session__delete(struct perf_session *session) 270void perf_session__delete(struct perf_session *session)
201{ 271{
202 if (session == NULL) 272 if (session == NULL)
@@ -205,6 +275,7 @@ void perf_session__delete(struct perf_session *session)
205 auxtrace_index__free(&session->auxtrace_index); 275 auxtrace_index__free(&session->auxtrace_index);
206 perf_session__destroy_kernel_maps(session); 276 perf_session__destroy_kernel_maps(session);
207 perf_session__delete_threads(session); 277 perf_session__delete_threads(session);
278 perf_session__release_decomp_events(session);
208 perf_env__exit(&session->header.env); 279 perf_env__exit(&session->header.env);
209 machines__exit(&session->machines); 280 machines__exit(&session->machines);
210 if (session->data) 281 if (session->data)
@@ -358,6 +429,14 @@ static int process_stat_round_stub(struct perf_session *perf_session __maybe_unu
358 return 0; 429 return 0;
359} 430}
360 431
432static int perf_session__process_compressed_event_stub(struct perf_session *session __maybe_unused,
433 union perf_event *event __maybe_unused,
434 u64 file_offset __maybe_unused)
435{
436 dump_printf(": unhandled!\n");
437 return 0;
438}
439
361void perf_tool__fill_defaults(struct perf_tool *tool) 440void perf_tool__fill_defaults(struct perf_tool *tool)
362{ 441{
363 if (tool->sample == NULL) 442 if (tool->sample == NULL)
@@ -430,6 +509,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
430 tool->time_conv = process_event_op2_stub; 509 tool->time_conv = process_event_op2_stub;
431 if (tool->feature == NULL) 510 if (tool->feature == NULL)
432 tool->feature = process_event_op2_stub; 511 tool->feature = process_event_op2_stub;
512 if (tool->compressed == NULL)
513 tool->compressed = perf_session__process_compressed_event;
433} 514}
434 515
435static void swap_sample_id_all(union perf_event *event, void *data) 516static void swap_sample_id_all(union perf_event *event, void *data)
@@ -1373,7 +1454,9 @@ static s64 perf_session__process_user_event(struct perf_session *session,
1373 int fd = perf_data__fd(session->data); 1454 int fd = perf_data__fd(session->data);
1374 int err; 1455 int err;
1375 1456
1376 dump_event(session->evlist, event, file_offset, &sample); 1457 if (event->header.type != PERF_RECORD_COMPRESSED ||
1458 tool->compressed == perf_session__process_compressed_event_stub)
1459 dump_event(session->evlist, event, file_offset, &sample);
1377 1460
1378 /* These events are processed right away */ 1461 /* These events are processed right away */
1379 switch (event->header.type) { 1462 switch (event->header.type) {
@@ -1426,6 +1509,11 @@ static s64 perf_session__process_user_event(struct perf_session *session,
1426 return tool->time_conv(session, event); 1509 return tool->time_conv(session, event);
1427 case PERF_RECORD_HEADER_FEATURE: 1510 case PERF_RECORD_HEADER_FEATURE:
1428 return tool->feature(session, event); 1511 return tool->feature(session, event);
1512 case PERF_RECORD_COMPRESSED:
1513 err = tool->compressed(session, event, file_offset);
1514 if (err)
1515 dump_event(session->evlist, event, file_offset, &sample);
1516 return err;
1429 default: 1517 default:
1430 return -EINVAL; 1518 return -EINVAL;
1431 } 1519 }
@@ -1708,6 +1796,8 @@ static int perf_session__flush_thread_stacks(struct perf_session *session)
1708 1796
1709volatile int session_done; 1797volatile int session_done;
1710 1798
1799static int __perf_session__process_decomp_events(struct perf_session *session);
1800
1711static int __perf_session__process_pipe_events(struct perf_session *session) 1801static int __perf_session__process_pipe_events(struct perf_session *session)
1712{ 1802{
1713 struct ordered_events *oe = &session->ordered_events; 1803 struct ordered_events *oe = &session->ordered_events;
@@ -1788,6 +1878,10 @@ more:
1788 if (skip > 0) 1878 if (skip > 0)
1789 head += skip; 1879 head += skip;
1790 1880
1881 err = __perf_session__process_decomp_events(session);
1882 if (err)
1883 goto out_err;
1884
1791 if (!session_done()) 1885 if (!session_done())
1792 goto more; 1886 goto more;
1793done: 1887done:
@@ -1836,6 +1930,39 @@ fetch_mmaped_event(struct perf_session *session,
1836 return event; 1930 return event;
1837} 1931}
1838 1932
1933static int __perf_session__process_decomp_events(struct perf_session *session)
1934{
1935 s64 skip;
1936 u64 size, file_pos = 0;
1937 struct decomp *decomp = session->decomp_last;
1938
1939 if (!decomp)
1940 return 0;
1941
1942 while (decomp->head < decomp->size && !session_done()) {
1943 union perf_event *event = fetch_mmaped_event(session, decomp->head, decomp->size, decomp->data);
1944
1945 if (!event)
1946 break;
1947
1948 size = event->header.size;
1949
1950 if (size < sizeof(struct perf_event_header) ||
1951 (skip = perf_session__process_event(session, event, file_pos)) < 0) {
1952 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
1953 decomp->file_pos + decomp->head, event->header.size, event->header.type);
1954 return -EINVAL;
1955 }
1956
1957 if (skip)
1958 size += skip;
1959
1960 decomp->head += size;
1961 }
1962
1963 return 0;
1964}
1965
1839/* 1966/*
1840 * On 64bit we can mmap the data file in one go. No need for tiny mmap 1967 * On 64bit we can mmap the data file in one go. No need for tiny mmap
1841 * slices. On 32bit we use 32MB. 1968 * slices. On 32bit we use 32MB.
@@ -1945,6 +2072,10 @@ more:
1945 head += size; 2072 head += size;
1946 file_pos += size; 2073 file_pos += size;
1947 2074
2075 err = __perf_session__process_decomp_events(session);
2076 if (err)
2077 goto out;
2078
1948 ui_progress__update(prog, size); 2079 ui_progress__update(prog, size);
1949 2080
1950 if (session_done()) 2081 if (session_done())
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index d96eccd7d27f..dd8920b745bc 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -8,6 +8,7 @@
8#include "machine.h" 8#include "machine.h"
9#include "data.h" 9#include "data.h"
10#include "ordered-events.h" 10#include "ordered-events.h"
11#include "util/compress.h"
11#include <linux/kernel.h> 12#include <linux/kernel.h>
12#include <linux/rbtree.h> 13#include <linux/rbtree.h>
13#include <linux/perf_event.h> 14#include <linux/perf_event.h>
@@ -35,6 +36,19 @@ struct perf_session {
35 struct ordered_events ordered_events; 36 struct ordered_events ordered_events;
36 struct perf_data *data; 37 struct perf_data *data;
37 struct perf_tool *tool; 38 struct perf_tool *tool;
39 u64 bytes_transferred;
40 u64 bytes_compressed;
41 struct zstd_data zstd_data;
42 struct decomp *decomp;
43 struct decomp *decomp_last;
44};
45
46struct decomp {
47 struct decomp *next;
48 u64 file_pos;
49 u64 head;
50 size_t size;
51 char data[];
38}; 52};
39 53
40struct perf_tool; 54struct perf_tool;
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 3324f23c7efc..4c53bae5644b 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -88,9 +88,17 @@ static void aggr_printout(struct perf_stat_config *config,
88 config->csv_sep); 88 config->csv_sep);
89 break; 89 break;
90 case AGGR_NONE: 90 case AGGR_NONE:
91 fprintf(config->output, "CPU%*d%s", 91 if (evsel->percore) {
92 config->csv_output ? 0 : -4, 92 fprintf(config->output, "S%d-C%*d%s",
93 perf_evsel__cpus(evsel)->map[id], config->csv_sep); 93 cpu_map__id_to_socket(id),
94 config->csv_output ? 0 : -5,
95 cpu_map__id_to_cpu(id), config->csv_sep);
96 } else {
97 fprintf(config->output, "CPU%*d%s ",
98 config->csv_output ? 0 : -5,
99 perf_evsel__cpus(evsel)->map[id],
100 config->csv_sep);
101 }
94 break; 102 break;
95 case AGGR_THREAD: 103 case AGGR_THREAD:
96 fprintf(config->output, "%*s-%*d%s", 104 fprintf(config->output, "%*s-%*d%s",
@@ -594,6 +602,41 @@ static void aggr_cb(struct perf_stat_config *config,
594 } 602 }
595} 603}
596 604
605static void print_counter_aggrdata(struct perf_stat_config *config,
606 struct perf_evsel *counter, int s,
607 char *prefix, bool metric_only,
608 bool *first)
609{
610 struct aggr_data ad;
611 FILE *output = config->output;
612 u64 ena, run, val;
613 int id, nr;
614 double uval;
615
616 ad.id = id = config->aggr_map->map[s];
617 ad.val = ad.ena = ad.run = 0;
618 ad.nr = 0;
619 if (!collect_data(config, counter, aggr_cb, &ad))
620 return;
621
622 nr = ad.nr;
623 ena = ad.ena;
624 run = ad.run;
625 val = ad.val;
626 if (*first && metric_only) {
627 *first = false;
628 aggr_printout(config, counter, id, nr);
629 }
630 if (prefix && !metric_only)
631 fprintf(output, "%s", prefix);
632
633 uval = val * counter->scale;
634 printout(config, id, nr, counter, uval, prefix,
635 run, ena, 1.0, &rt_stat);
636 if (!metric_only)
637 fputc('\n', output);
638}
639
597static void print_aggr(struct perf_stat_config *config, 640static void print_aggr(struct perf_stat_config *config,
598 struct perf_evlist *evlist, 641 struct perf_evlist *evlist,
599 char *prefix) 642 char *prefix)
@@ -601,9 +644,7 @@ static void print_aggr(struct perf_stat_config *config,
601 bool metric_only = config->metric_only; 644 bool metric_only = config->metric_only;
602 FILE *output = config->output; 645 FILE *output = config->output;
603 struct perf_evsel *counter; 646 struct perf_evsel *counter;
604 int s, id, nr; 647 int s;
605 double uval;
606 u64 ena, run, val;
607 bool first; 648 bool first;
608 649
609 if (!(config->aggr_map || config->aggr_get_id)) 650 if (!(config->aggr_map || config->aggr_get_id))
@@ -616,33 +657,14 @@ static void print_aggr(struct perf_stat_config *config,
616 * Without each counter has its own line. 657 * Without each counter has its own line.
617 */ 658 */
618 for (s = 0; s < config->aggr_map->nr; s++) { 659 for (s = 0; s < config->aggr_map->nr; s++) {
619 struct aggr_data ad;
620 if (prefix && metric_only) 660 if (prefix && metric_only)
621 fprintf(output, "%s", prefix); 661 fprintf(output, "%s", prefix);
622 662
623 ad.id = id = config->aggr_map->map[s];
624 first = true; 663 first = true;
625 evlist__for_each_entry(evlist, counter) { 664 evlist__for_each_entry(evlist, counter) {
626 ad.val = ad.ena = ad.run = 0; 665 print_counter_aggrdata(config, counter, s,
627 ad.nr = 0; 666 prefix, metric_only,
628 if (!collect_data(config, counter, aggr_cb, &ad)) 667 &first);
629 continue;
630 nr = ad.nr;
631 ena = ad.ena;
632 run = ad.run;
633 val = ad.val;
634 if (first && metric_only) {
635 first = false;
636 aggr_printout(config, counter, id, nr);
637 }
638 if (prefix && !metric_only)
639 fprintf(output, "%s", prefix);
640
641 uval = val * counter->scale;
642 printout(config, id, nr, counter, uval, prefix,
643 run, ena, 1.0, &rt_stat);
644 if (!metric_only)
645 fputc('\n', output);
646 } 668 }
647 if (metric_only) 669 if (metric_only)
648 fputc('\n', output); 670 fputc('\n', output);
@@ -1089,6 +1111,30 @@ static void print_footer(struct perf_stat_config *config)
1089 "the same PMU. Try reorganizing the group.\n"); 1111 "the same PMU. Try reorganizing the group.\n");
1090} 1112}
1091 1113
1114static void print_percore(struct perf_stat_config *config,
1115 struct perf_evsel *counter, char *prefix)
1116{
1117 bool metric_only = config->metric_only;
1118 FILE *output = config->output;
1119 int s;
1120 bool first = true;
1121
1122 if (!(config->aggr_map || config->aggr_get_id))
1123 return;
1124
1125 for (s = 0; s < config->aggr_map->nr; s++) {
1126 if (prefix && metric_only)
1127 fprintf(output, "%s", prefix);
1128
1129 print_counter_aggrdata(config, counter, s,
1130 prefix, metric_only,
1131 &first);
1132 }
1133
1134 if (metric_only)
1135 fputc('\n', output);
1136}
1137
1092void 1138void
1093perf_evlist__print_counters(struct perf_evlist *evlist, 1139perf_evlist__print_counters(struct perf_evlist *evlist,
1094 struct perf_stat_config *config, 1140 struct perf_stat_config *config,
@@ -1139,7 +1185,10 @@ perf_evlist__print_counters(struct perf_evlist *evlist,
1139 print_no_aggr_metric(config, evlist, prefix); 1185 print_no_aggr_metric(config, evlist, prefix);
1140 else { 1186 else {
1141 evlist__for_each_entry(evlist, counter) { 1187 evlist__for_each_entry(evlist, counter) {
1142 print_counter(config, counter, prefix); 1188 if (counter->percore)
1189 print_percore(config, counter, prefix);
1190 else
1191 print_counter(config, counter, prefix);
1143 } 1192 }
1144 } 1193 }
1145 break; 1194 break;
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 2856cc9d5a31..c3115d939b0b 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -277,9 +277,11 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel
277 if (!evsel->snapshot) 277 if (!evsel->snapshot)
278 perf_evsel__compute_deltas(evsel, cpu, thread, count); 278 perf_evsel__compute_deltas(evsel, cpu, thread, count);
279 perf_counts_values__scale(count, config->scale, NULL); 279 perf_counts_values__scale(count, config->scale, NULL);
280 if (config->aggr_mode == AGGR_NONE) 280 if ((config->aggr_mode == AGGR_NONE) && (!evsel->percore)) {
281 perf_stat__update_shadow_stats(evsel, count->val, cpu, 281 perf_stat__update_shadow_stats(evsel, count->val,
282 &rt_stat); 282 cpu, &rt_stat);
283 }
284
283 if (config->aggr_mode == AGGR_THREAD) { 285 if (config->aggr_mode == AGGR_THREAD) {
284 if (config->stats) 286 if (config->stats)
285 perf_stat__update_shadow_stats(evsel, 287 perf_stat__update_shadow_stats(evsel,
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 50678d318185..403045a2bbea 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -15,6 +15,7 @@
15#include "map.h" 15#include "map.h"
16#include "symbol.h" 16#include "symbol.h"
17#include "unwind.h" 17#include "unwind.h"
18#include "callchain.h"
18 19
19#include <api/fs/fs.h> 20#include <api/fs/fs.h>
20 21
@@ -327,7 +328,7 @@ static int thread__prepare_access(struct thread *thread)
327{ 328{
328 int err = 0; 329 int err = 0;
329 330
330 if (symbol_conf.use_callchain) 331 if (dwarf_callchain_users)
331 err = __thread__prepare_access(thread); 332 err = __thread__prepare_access(thread);
332 333
333 return err; 334 return err;
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index 250391672f9f..9096a6e3de59 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -28,6 +28,7 @@ typedef int (*event_attr_op)(struct perf_tool *tool,
28 28
29typedef int (*event_op2)(struct perf_session *session, union perf_event *event); 29typedef int (*event_op2)(struct perf_session *session, union perf_event *event);
30typedef s64 (*event_op3)(struct perf_session *session, union perf_event *event); 30typedef s64 (*event_op3)(struct perf_session *session, union perf_event *event);
31typedef int (*event_op4)(struct perf_session *session, union perf_event *event, u64 data);
31 32
32typedef int (*event_oe)(struct perf_tool *tool, union perf_event *event, 33typedef int (*event_oe)(struct perf_tool *tool, union perf_event *event,
33 struct ordered_events *oe); 34 struct ordered_events *oe);
@@ -72,6 +73,7 @@ struct perf_tool {
72 stat, 73 stat,
73 stat_round, 74 stat_round,
74 feature; 75 feature;
76 event_op4 compressed;
75 event_op3 auxtrace; 77 event_op3 auxtrace;
76 bool ordered_events; 78 bool ordered_events;
77 bool ordering_requires_timestamps; 79 bool ordering_requires_timestamps;
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index f3c666a84e4d..25e1406b1f8b 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -617,8 +617,6 @@ static unw_accessors_t accessors = {
617 617
618static int _unwind__prepare_access(struct thread *thread) 618static int _unwind__prepare_access(struct thread *thread)
619{ 619{
620 if (!dwarf_callchain_users)
621 return 0;
622 thread->addr_space = unw_create_addr_space(&accessors, 0); 620 thread->addr_space = unw_create_addr_space(&accessors, 0);
623 if (!thread->addr_space) { 621 if (!thread->addr_space) {
624 pr_err("unwind: Can't create unwind address space.\n"); 622 pr_err("unwind: Can't create unwind address space.\n");
@@ -631,15 +629,11 @@ static int _unwind__prepare_access(struct thread *thread)
631 629
632static void _unwind__flush_access(struct thread *thread) 630static void _unwind__flush_access(struct thread *thread)
633{ 631{
634 if (!dwarf_callchain_users)
635 return;
636 unw_flush_cache(thread->addr_space, 0, 0); 632 unw_flush_cache(thread->addr_space, 0, 0);
637} 633}
638 634
639static void _unwind__finish_access(struct thread *thread) 635static void _unwind__finish_access(struct thread *thread)
640{ 636{
641 if (!dwarf_callchain_users)
642 return;
643 unw_destroy_addr_space(thread->addr_space); 637 unw_destroy_addr_space(thread->addr_space);
644} 638}
645 639
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 9778b3133b77..c0811977d7d5 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -5,6 +5,7 @@
5#include "session.h" 5#include "session.h"
6#include "debug.h" 6#include "debug.h"
7#include "env.h" 7#include "env.h"
8#include "callchain.h"
8 9
9struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops; 10struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops;
10struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops; 11struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops;
@@ -24,6 +25,9 @@ int unwind__prepare_access(struct thread *thread, struct map *map,
24 struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops; 25 struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops;
25 int err; 26 int err;
26 27
28 if (!dwarf_callchain_users)
29 return 0;
30
27 if (thread->addr_space) { 31 if (thread->addr_space) {
28 pr_debug("unwind: thread map already set, dso=%s\n", 32 pr_debug("unwind: thread map already set, dso=%s\n",
29 map->dso->name); 33 map->dso->name);
@@ -65,12 +69,18 @@ out_register:
65 69
66void unwind__flush_access(struct thread *thread) 70void unwind__flush_access(struct thread *thread)
67{ 71{
72 if (!dwarf_callchain_users)
73 return;
74
68 if (thread->unwind_libunwind_ops) 75 if (thread->unwind_libunwind_ops)
69 thread->unwind_libunwind_ops->flush_access(thread); 76 thread->unwind_libunwind_ops->flush_access(thread);
70} 77}
71 78
72void unwind__finish_access(struct thread *thread) 79void unwind__finish_access(struct thread *thread)
73{ 80{
81 if (!dwarf_callchain_users)
82 return;
83
74 if (thread->unwind_libunwind_ops) 84 if (thread->unwind_libunwind_ops)
75 thread->unwind_libunwind_ops->finish_access(thread); 85 thread->unwind_libunwind_ops->finish_access(thread);
76} 86}
diff --git a/tools/perf/util/zstd.c b/tools/perf/util/zstd.c
new file mode 100644
index 000000000000..23bdb9884576
--- /dev/null
+++ b/tools/perf/util/zstd.c
@@ -0,0 +1,111 @@
1// SPDX-License-Identifier: GPL-2.0
2
3#include <string.h>
4
5#include "util/compress.h"
6#include "util/debug.h"
7
8int zstd_init(struct zstd_data *data, int level)
9{
10 size_t ret;
11
12 data->dstream = ZSTD_createDStream();
13 if (data->dstream == NULL) {
14 pr_err("Couldn't create decompression stream.\n");
15 return -1;
16 }
17
18 ret = ZSTD_initDStream(data->dstream);
19 if (ZSTD_isError(ret)) {
20 pr_err("Failed to initialize decompression stream: %s\n", ZSTD_getErrorName(ret));
21 return -1;
22 }
23
24 if (!level)
25 return 0;
26
27 data->cstream = ZSTD_createCStream();
28 if (data->cstream == NULL) {
29 pr_err("Couldn't create compression stream.\n");
30 return -1;
31 }
32
33 ret = ZSTD_initCStream(data->cstream, level);
34 if (ZSTD_isError(ret)) {
35 pr_err("Failed to initialize compression stream: %s\n", ZSTD_getErrorName(ret));
36 return -1;
37 }
38
39 return 0;
40}
41
42int zstd_fini(struct zstd_data *data)
43{
44 if (data->dstream) {
45 ZSTD_freeDStream(data->dstream);
46 data->dstream = NULL;
47 }
48
49 if (data->cstream) {
50 ZSTD_freeCStream(data->cstream);
51 data->cstream = NULL;
52 }
53
54 return 0;
55}
56
57size_t zstd_compress_stream_to_records(struct zstd_data *data, void *dst, size_t dst_size,
58 void *src, size_t src_size, size_t max_record_size,
59 size_t process_header(void *record, size_t increment))
60{
61 size_t ret, size, compressed = 0;
62 ZSTD_inBuffer input = { src, src_size, 0 };
63 ZSTD_outBuffer output;
64 void *record;
65
66 while (input.pos < input.size) {
67 record = dst;
68 size = process_header(record, 0);
69 compressed += size;
70 dst += size;
71 dst_size -= size;
72 output = (ZSTD_outBuffer){ dst, (dst_size > max_record_size) ?
73 max_record_size : dst_size, 0 };
74 ret = ZSTD_compressStream(data->cstream, &output, &input);
75 ZSTD_flushStream(data->cstream, &output);
76 if (ZSTD_isError(ret)) {
77 pr_err("failed to compress %ld bytes: %s\n",
78 (long)src_size, ZSTD_getErrorName(ret));
79 memcpy(dst, src, src_size);
80 return src_size;
81 }
82 size = output.pos;
83 size = process_header(record, size);
84 compressed += size;
85 dst += size;
86 dst_size -= size;
87 }
88
89 return compressed;
90}
91
92size_t zstd_decompress_stream(struct zstd_data *data, void *src, size_t src_size,
93 void *dst, size_t dst_size)
94{
95 size_t ret;
96 ZSTD_inBuffer input = { src, src_size, 0 };
97 ZSTD_outBuffer output = { dst, dst_size, 0 };
98
99 while (input.pos < input.size) {
100 ret = ZSTD_decompressStream(data->dstream, &output, &input);
101 if (ZSTD_isError(ret)) {
102 pr_err("failed to decompress (B): %ld -> %ld : %s\n",
103 src_size, output.size, ZSTD_getErrorName(ret));
104 break;
105 }
106 output.dst = dst + output.pos;
107 output.size = dst_size - output.pos;
108 }
109
110 return output.pos;
111}